> I don't see where the OCSP request is de-base64-ified, and URL-decoded.
> In both cases, d2i_OCSP_REQUEST_bio is called to get the request, but it's 
> done directly on the HTTP request line for a GET.

I forgot to post the updated patch.  Thanks Erwann.

--  
Principal Security Engineer, Akamai Technologies
IM: [email protected] Twitter: RichSalz

diff --git a/apps/ocsp.c b/apps/ocsp.c
index fbc6b3f..073759f 100644
--- a/apps/ocsp.c
+++ b/apps/ocsp.c
@@ -1038,13 +1038,58 @@ static BIO *init_responder(const char *port)
        return NULL;
        }
 
+static int tohex(char c)
+       {
+       switch (c)
+               {
+               case '0': return 0;
+               case '1': return 1;
+               case '2': return 2;
+               case '3': return 3;
+               case '4': return 4;
+               case '5': return 5;
+               case '6': return 6;
+               case '7': return 7;
+               case '8': return 8;
+               case '9': return 9;
+               case 'A': case 'a': return 10;
+               case 'B': case 'b': return 11;
+               case 'C': case 'c': return 12;
+               case 'D': case 'd': return 13;
+               case 'E': case 'e': return 14;
+               case 'F': case 'f': return 15;
+               }
+       return 0;
+       }
+
+static char* urldecode(char* p)
+       {
+       unsigned char* out = (unsigned char *)p;
+       char* save = p;
+
+       for ( ; *p; p++)
+               {
+               if (*p == '+')
+                       *out++ = ' ';
+               else if (*p != '%')
+                       *out++ = *p;
+               else if (p[1] && p[2])
+                       {
+                       *out++ = (tohex(p[1]) << 4) | tohex(p[2]);
+                       p += 2;
+                       }
+               }
+       return save;
+       }
+
 static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
                        const char *port)
        {
-       int have_post = 0, len;
+       int len;
        OCSP_REQUEST *req = NULL;
-       char inbuf[1024];
-       BIO *cbio = NULL;
+       char inbuf[2048];
+       char *p, *q;
+       BIO *cbio = NULL, *getbio = NULL, *b64 = NULL;
 
        if (BIO_do_accept(acbio) <= 0)
                {
@@ -1056,29 +1101,53 @@ static int do_responder(OCSP_REQUEST **preq, BIO 
**pcbio, BIO *acbio,
        cbio = BIO_pop(acbio);
        *pcbio = cbio;
 
+       /* Read the request line. */
+       len = BIO_gets(cbio, inbuf, sizeof inbuf);
+       if (len <= 0)
+               return 1;
+       if (strncmp(inbuf, "GET", 3) == 0)
+               {
+               /* Expecting GET {sp} /URL {sp} HTTP/... */
+               for (p = inbuf + 3; *p == ' ' || *p == '\t'; ++p)
+                       continue;
+               p++;
+               q = strchr(p, ' ');
+               if (q == NULL)
+                       {
+                       BIO_printf(bio_err, "Invalid request\n");
+                       return 1;
+                       }
+               /* URL decode? Really shouldn't be needed. */
+               if (strchr(p, '+') != NULL && strchr(p, '%') != NULL)
+                   p = urldecode(p);
+               getbio = BIO_new_mem_buf(p, strlen(p));
+               b64 = BIO_new(BIO_f_base64());
+               BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+               getbio = BIO_push(b64, getbio);
+               }
+       else if (!strncmp(inbuf, "POST", 4))
+               {
+               BIO_printf(bio_err, "Invalid request\n");
+               return 1;
+               }
        for(;;)
                {
                len = BIO_gets(cbio, inbuf, sizeof inbuf);
                if (len <= 0)
                        return 1;
-               /* Look for "POST" signalling start of query */
-               if (!have_post)
-                       {
-                       if(strncmp(inbuf, "POST", 4))
-                               {
-                               BIO_printf(bio_err, "Invalid request\n");
-                               return 1;
-                               }
-                       have_post = 1;
-                       }
                /* Look for end of headers */
                if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
                        break;
                }
 
        /* Try to read OCSP request */
-
-       req = d2i_OCSP_REQUEST_bio(cbio, NULL);
+       if (getbio)
+               {
+               req = d2i_OCSP_REQUEST_bio(getbio, NULL);
+               BIO_free_all(getbio);
+               }
+       else
+               req = d2i_OCSP_REQUEST_bio(cbio, NULL);
 
        if (!req)
                {

Reply via email to