> 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)
{