updated OCSP, processes response
This commit is contained in:
parent
5aad32eb28
commit
d7d898697a
185
src/ocsp.c
185
src/ocsp.c
@ -129,6 +129,19 @@ int CyaSSL_OCSP_set_override_url(CYASSL_OCSP* ocsp, const char* url)
|
||||
else
|
||||
ocsp->overridePort = 80;
|
||||
|
||||
if (url[cur] == '/') {
|
||||
i = 0;
|
||||
while (url[cur] != 0 && i < 80) {
|
||||
ocsp->overridePath[i++] = url[cur++];
|
||||
}
|
||||
ocsp->overridePath[i] = 0;
|
||||
}
|
||||
else {
|
||||
ocsp->overridePath[0] = '/';
|
||||
ocsp->overridePath[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -178,65 +191,159 @@ static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
|
||||
}
|
||||
|
||||
|
||||
static void close_connection();
|
||||
static int build_http_request(CYASSL_OCSP* ocsp, int ocspReqSz,
|
||||
byte* buf, int bufSize)
|
||||
{
|
||||
return snprintf((char*)buf, bufSize,
|
||||
"POST %s HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"Content-Type: application/ocsp-request\r\n"
|
||||
"\r\n",
|
||||
ocsp->overridePath, ocsp->overrideName, ocspReqSz);
|
||||
}
|
||||
|
||||
const char http_ocsp_pre[] = "POST ";
|
||||
const char http_ocsp_post[] = " HTTP/1.1\r\nHost: ";
|
||||
const char http_ocsp_len[] = "\r\nContent-Length: ";
|
||||
const char http_ocsp_type[] = "\r\nContent-Type: application/ocsp-request"
|
||||
"\r\n\r\n";
|
||||
const char arglebargle[] = "arglebargle";
|
||||
|
||||
static const char foo[] = \
|
||||
"\x30\x81\xB7\x30\x81\xB4\x30\x81\x8C\x30\x44\x30\x42\x30\x09\x06\x05\x2B\x0E\x03" \
|
||||
"\x02\x1A\x05\x00\x04\x14\x49\x2D\x52\x83\x4B\x40\x37\xF5\xA9\x9E\x26\xA2\x3E\x48" \
|
||||
"\x2F\x2E\x37\x34\xC9\x54\x04\x14\x21\xA2\x25\xEE\x57\x38\x34\x5A\x24\x9D\xF3\x7C" \
|
||||
"\x18\x60\x59\x7A\x04\x3D\xF5\x69\x02\x09\x00\x89\x5A\xA2\xBD\xFE\x26\x8B\xEE\x30" \
|
||||
"\x44\x30\x42\x30\x09\x06\x05\x2B\x0E\x03\x02\x1A\x05\x00\x04\x14\x49\x2D\x52\x83" \
|
||||
"\x4B\x40\x37\xF5\xA9\x9E\x26\xA2\x3E\x48\x2F\x2E\x37\x34\xC9\x54\x04\x14\x21\xA2" \
|
||||
"\x25\xEE\x57\x38\x34\x5A\x24\x9D\xF3\x7C\x18\x60\x59\x7A\x04\x3D\xF5\x69\x02\x09" \
|
||||
"\x00\x89\x5A\xA2\xBD\xFE\x26\x8B\xEF\xA2\x23\x30\x21\x30\x1F\x06\x09\x2B\x06\x01" \
|
||||
"\x05\x05\x07\x30\x01\x02\x04\x12\x04\x10\x20\x56\x47\x19\x65\x33\xB6\xB5\xAD\x39" \
|
||||
"\x1F\x21\x65\xE0\x44\x1E";
|
||||
|
||||
|
||||
static int build_ocsp_request(CYASSL_OCSP* ocsp, byte* buf, int bufSz)
|
||||
{
|
||||
memcpy(buf, foo, sizeof(foo));
|
||||
return sizeof(foo) - 1;
|
||||
}
|
||||
|
||||
|
||||
static char* decode_http_response(char* buf, int bufSize, int* ocspRespSize)
|
||||
{
|
||||
int idx = 0;
|
||||
int stop = 0;
|
||||
byte* contentType = NULL;
|
||||
byte* contentLength = NULL;
|
||||
byte* content = NULL;
|
||||
|
||||
if (strncasecmp(buf, "HTTP/1", 6) != 0)
|
||||
return NULL;
|
||||
|
||||
idx = 9; /* sets to the first byte after "HTTP/1.X ", which should be the
|
||||
* HTTP result code */
|
||||
|
||||
if (strncasecmp(&buf[idx], "200 OK", 6) != 0)
|
||||
return NULL;
|
||||
|
||||
idx += 8;
|
||||
|
||||
while (idx < bufSize && !stop) {
|
||||
if (buf[idx] == '\r' && buf[idx+1] == '\n') {
|
||||
stop = 1;
|
||||
idx += 2;
|
||||
}
|
||||
else {
|
||||
if (contentType == NULL &&
|
||||
strncasecmp(&buf[idx], "Content-Type:", 13) == 0) {
|
||||
idx += 13;
|
||||
if (buf[idx] == ' ') idx++;
|
||||
if (strncasecmp(&buf[idx], "application/ocsp-response", 25) != 0)
|
||||
return NULL;
|
||||
idx += 27;
|
||||
} else if (contentLength == NULL &&
|
||||
strncasecmp(&buf[idx], "Content-Length:", 15) == 0) {
|
||||
int len = 0;
|
||||
idx += 15;
|
||||
if (buf[idx] == ' ') idx++;
|
||||
while (buf[idx] > '0' && buf[idx] < '9' && idx < bufSize) {
|
||||
len = (len * 10) + (buf[idx] - '0');
|
||||
idx++;
|
||||
}
|
||||
*ocspRespSize = len;
|
||||
idx += 2; /* skip the crlf */
|
||||
} else {
|
||||
/* Advance idx past the next \r\n */
|
||||
char* end = strstr(&buf[idx], "\r\n");
|
||||
idx = end - buf + 2;
|
||||
stop = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return &buf[idx];
|
||||
}
|
||||
|
||||
|
||||
#define SCRATCH_BUFFER_SIZE 2048
|
||||
|
||||
int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
|
||||
{
|
||||
SOCKET_T sfd = -1;
|
||||
char buf[1024];
|
||||
int bufRemainder = 1023;
|
||||
byte buf[SCRATCH_BUFFER_SIZE];
|
||||
byte* httpBuf = &buf[0];
|
||||
int httpBufSz = SCRATCH_BUFFER_SIZE/4;
|
||||
byte* ocspReqBuf = &buf[httpBufSz];
|
||||
int ocspReqSz = SCRATCH_BUFFER_SIZE - httpBufSz;
|
||||
OcspResponse ocspResponse;
|
||||
int result = CERT_UNKNOWN;
|
||||
|
||||
/* If OCSP lookups are disabled, return success. */
|
||||
if (!ocsp->enabled) return 1;
|
||||
if (!ocsp->enabled) {
|
||||
CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
|
||||
return CERT_GOOD;
|
||||
}
|
||||
|
||||
/* If OCSP lookups are enabled, but URL Override is disabled, return
|
||||
** a failure. Need to have an override URL for right now. */
|
||||
if (!ocsp->useOverrideUrl || cert == NULL) return 0;
|
||||
if (!ocsp->useOverrideUrl || cert == NULL) {
|
||||
CYASSL_MSG("OCSP lookup enabled, but URL Override disabled");
|
||||
return CERT_UNKNOWN;
|
||||
}
|
||||
|
||||
XMEMCPY(ocsp->status[0].subjectHash, cert->subjectHash, SHA_SIZE);
|
||||
XMEMCPY(ocsp->status[0].issuerHash, cert->issuerHash, SHA_SIZE);
|
||||
XMEMCPY(ocsp->status[0].serial, cert->serial, cert->serialSz);
|
||||
ocsp->status[0].serialSz = cert->serialSz;
|
||||
ocsp->statusLen = 1;
|
||||
|
||||
// tcp_connect(&sfd, ocsp->overrideName, ocsp->overridePort);
|
||||
ocspReqSz = build_ocsp_request(ocsp, ocspReqBuf, ocspReqSz);
|
||||
httpBufSz = build_http_request(ocsp, ocspReqSz, httpBuf, httpBufSz);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
tcp_connect(&sfd, ocsp->overrideName, ocsp->overridePort);
|
||||
if (sfd > 0) {
|
||||
int written;
|
||||
written = write(sfd, httpBuf, httpBufSz);
|
||||
written = write(sfd, ocspReqBuf, ocspReqSz);
|
||||
httpBufSz = read(sfd, buf, SCRATCH_BUFFER_SIZE);
|
||||
if (httpBufSz > 0) {
|
||||
ocspReqBuf = decode_http_response(buf, httpBufSz, &ocspReqSz);
|
||||
/* Need to check the lengths. There might be more data waiting. */
|
||||
}
|
||||
close(sfd);
|
||||
if (ocspReqBuf == NULL) {
|
||||
CYASSL_MSG("HTTP response was not OK, no OCSP response");
|
||||
return CERT_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
CYASSL_MSG("OCSP Responder connection failed");
|
||||
return CERT_UNKNOWN;
|
||||
}
|
||||
|
||||
strncat(buf, http_ocsp_pre, bufRemainder);
|
||||
bufRemainder -= strlen(http_ocsp_pre);
|
||||
InitOcspResponse(&ocspResponse, ocspReqBuf, ocspReqSz, NULL);
|
||||
OcspResponseDecode(&ocspResponse);
|
||||
if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
|
||||
CYASSL_MSG("OCSP Responder failure");
|
||||
} else {
|
||||
result = ocspResponse.certStatus[0];
|
||||
}
|
||||
FreeOcspResponse(&ocspResponse);
|
||||
|
||||
strncat(buf, "/", bufRemainder);
|
||||
bufRemainder -= 1;
|
||||
|
||||
strncat(buf, http_ocsp_post, bufRemainder);
|
||||
bufRemainder -= strlen(http_ocsp_post);
|
||||
|
||||
strncat(buf, ocsp->overrideName, bufRemainder);
|
||||
bufRemainder -= strlen(ocsp->overrideName);
|
||||
|
||||
strncat(buf, http_ocsp_len, bufRemainder);
|
||||
bufRemainder -= strlen(http_ocsp_len);
|
||||
|
||||
strncat(buf, "11", bufRemainder);
|
||||
bufRemainder -= 2;
|
||||
|
||||
strncat(buf, http_ocsp_type, bufRemainder);
|
||||
bufRemainder -= strlen(http_ocsp_type);
|
||||
|
||||
strncat(buf, arglebargle, bufRemainder);
|
||||
bufRemainder -= strlen(arglebargle);
|
||||
|
||||
// close(sfd);
|
||||
|
||||
return 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user