mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 12:44:45 +02:00
OCSP use URL from cert as appropriate
This commit is contained in:
191
src/ocsp.c
191
src/ocsp.c
@@ -91,56 +91,77 @@ void CyaSSL_OCSP_Cleanup(CYASSL_OCSP* ocsp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int decode_url(const char* url, int urlSz,
|
||||||
|
char* outName, char* outPath, int* outPort)
|
||||||
|
{
|
||||||
|
if (outName != NULL && outPath != NULL && outPort != NULL)
|
||||||
|
{
|
||||||
|
if (url == NULL || urlSz == 0)
|
||||||
|
{
|
||||||
|
*outName = 0;
|
||||||
|
*outPath = 0;
|
||||||
|
*outPort = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i, cur, hostname;
|
||||||
|
|
||||||
|
/* need to break the url down into scheme, address, and port */
|
||||||
|
/* "http://example.com:8080/" */
|
||||||
|
if (XSTRNCMP(url, "http://", 7) == 0) {
|
||||||
|
cur = 7;
|
||||||
|
} else cur = 0;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (url[cur] != 0 && url[cur] != ':' && url[cur] != '/') {
|
||||||
|
outName[i++] = url[cur++];
|
||||||
|
}
|
||||||
|
outName[i] = 0;
|
||||||
|
/* Need to pick out the path after the domain name */
|
||||||
|
|
||||||
|
if (cur < urlSz && url[cur] == ':') {
|
||||||
|
char port[6];
|
||||||
|
int j;
|
||||||
|
i = 0;
|
||||||
|
cur++;
|
||||||
|
while (cur < urlSz && url[cur] != 0 && url[cur] != '/' &&
|
||||||
|
i < 6) {
|
||||||
|
port[i++] = url[cur++];
|
||||||
|
}
|
||||||
|
|
||||||
|
*outPort = 0;
|
||||||
|
for (j = 0; j < i; j++) {
|
||||||
|
if (port[j] < '0' || port[j] > '9') return -1;
|
||||||
|
*outPort = (*outPort * 10) + (port[j] - '0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*outPort = 80;
|
||||||
|
|
||||||
|
if (cur < urlSz && url[cur] == '/') {
|
||||||
|
i = 0;
|
||||||
|
while (cur < urlSz && url[cur] != 0 && i < 80) {
|
||||||
|
outPath[i++] = url[cur++];
|
||||||
|
}
|
||||||
|
outPath[i] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
outPath[0] = '/';
|
||||||
|
outPath[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int CyaSSL_OCSP_set_override_url(CYASSL_OCSP* ocsp, const char* url)
|
int CyaSSL_OCSP_set_override_url(CYASSL_OCSP* ocsp, const char* url)
|
||||||
{
|
{
|
||||||
if (ocsp != NULL && url != NULL) {
|
if (ocsp != NULL) {
|
||||||
int i, cur, hostname;
|
int urlSz = strlen(url);
|
||||||
|
decode_url(url, urlSz,
|
||||||
/* need to break the url down into scheme, address, and port */
|
ocsp->overrideName, ocsp->overridePath, &ocsp->overridePort);
|
||||||
/* "http://example.com:8080/" */
|
|
||||||
if (XSTRNCMP(url, "http://", 7) == 0) {
|
|
||||||
cur = 7;
|
|
||||||
} else cur = 0;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (url[cur] != 0 && url[cur] != ':' && url[cur] != '/') {
|
|
||||||
ocsp->overrideName[i++] = url[cur++];
|
|
||||||
}
|
|
||||||
ocsp->overrideName[i] = 0;
|
|
||||||
/* Need to pick out the path after the domain name */
|
|
||||||
|
|
||||||
if (url[cur] == ':') {
|
|
||||||
char port[6];
|
|
||||||
int j;
|
|
||||||
i = 0;
|
|
||||||
cur++;
|
|
||||||
while (url[cur] != 0 && url[cur] != '/' && i < 6) {
|
|
||||||
port[i++] = url[cur++];
|
|
||||||
}
|
|
||||||
|
|
||||||
ocsp->overridePort = 0;
|
|
||||||
for (j = 0; j < i; j++) {
|
|
||||||
if (port[j] < '0' || port[j] > '9') return -1;
|
|
||||||
ocsp->overridePort =
|
|
||||||
(ocsp->overridePort * 10) + (port[j] - '0');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,8 +211,8 @@ static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int build_http_request(CYASSL_OCSP* ocsp, int ocspReqSz,
|
static int build_http_request(const char* domainName, const char* path,
|
||||||
byte* buf, int bufSize)
|
int ocspReqSz, byte* buf, int bufSize)
|
||||||
{
|
{
|
||||||
return snprintf((char*)buf, bufSize,
|
return snprintf((char*)buf, bufSize,
|
||||||
"POST %s HTTP/1.1\r\n"
|
"POST %s HTTP/1.1\r\n"
|
||||||
@@ -199,29 +220,9 @@ static int build_http_request(CYASSL_OCSP* ocsp, int ocspReqSz,
|
|||||||
"Content-Length: %d\r\n"
|
"Content-Length: %d\r\n"
|
||||||
"Content-Type: application/ocsp-request\r\n"
|
"Content-Type: application/ocsp-request\r\n"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
ocsp->overridePath, ocsp->overrideName, ocspReqSz);
|
path, domainName, ocspReqSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static byte* decode_http_response(byte* httpBuf, int httpBufSz, int* ocspRespSz)
|
static byte* decode_http_response(byte* httpBuf, int httpBufSz, int* ocspRespSz)
|
||||||
{
|
{
|
||||||
@@ -290,20 +291,28 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
|
|||||||
byte* ocspReqBuf = &buf[httpBufSz];
|
byte* ocspReqBuf = &buf[httpBufSz];
|
||||||
int ocspReqSz = SCRATCH_BUFFER_SIZE - httpBufSz;
|
int ocspReqSz = SCRATCH_BUFFER_SIZE - httpBufSz;
|
||||||
OcspResponse ocspResponse;
|
OcspResponse ocspResponse;
|
||||||
int result = CERT_UNKNOWN;
|
int result = 0;
|
||||||
|
char domainName[80], path[80];
|
||||||
|
int port;
|
||||||
|
|
||||||
/* If OCSP lookups are disabled, return success. */
|
/* If OCSP lookups are disabled, return success. */
|
||||||
if (!ocsp->enabled) {
|
if (!ocsp->enabled) {
|
||||||
CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
|
CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
|
||||||
return CERT_GOOD;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If OCSP lookups are enabled, but URL Override is disabled, return
|
if (ocsp->useOverrideUrl || cert->extAuthInfo == NULL) {
|
||||||
** a failure. Need to have an override URL for right now. */
|
if (ocsp->overrideName != NULL) {
|
||||||
if (!ocsp->useOverrideUrl || cert == NULL) {
|
XMEMCPY(domainName, ocsp->overrideName, 80);
|
||||||
CYASSL_MSG("OCSP lookup enabled, but URL Override disabled");
|
XMEMCPY(path, ocsp->overridePath, 80);
|
||||||
return CERT_UNKNOWN;
|
port = ocsp->overridePort;
|
||||||
}
|
} else
|
||||||
|
return OCSP_NEED_URL;
|
||||||
|
} else {
|
||||||
|
if (!decode_url((const char*)cert->extAuthInfo, cert->extAuthInfoSz,
|
||||||
|
domainName, path, &port))
|
||||||
|
return OCSP_NEED_URL;
|
||||||
|
}
|
||||||
|
|
||||||
XMEMCPY(ocsp->status[0].issuerHash, cert->issuerHash, SHA_SIZE);
|
XMEMCPY(ocsp->status[0].issuerHash, cert->issuerHash, SHA_SIZE);
|
||||||
XMEMCPY(ocsp->status[0].issuerKeyHash, cert->issuerKeyHash, SHA_SIZE);
|
XMEMCPY(ocsp->status[0].issuerKeyHash, cert->issuerKeyHash, SHA_SIZE);
|
||||||
@@ -311,11 +320,11 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
|
|||||||
ocsp->status[0].serialSz = cert->serialSz;
|
ocsp->status[0].serialSz = cert->serialSz;
|
||||||
ocsp->statusLen = 1;
|
ocsp->statusLen = 1;
|
||||||
|
|
||||||
/*ocspReqSz = build_ocsp_request(ocsp, ocspReqBuf, ocspReqSz);*/
|
|
||||||
ocspReqSz = EncodeOcspRequest(cert, ocspReqBuf, ocspReqSz);
|
ocspReqSz = EncodeOcspRequest(cert, ocspReqBuf, ocspReqSz);
|
||||||
httpBufSz = build_http_request(ocsp, ocspReqSz, httpBuf, httpBufSz);
|
httpBufSz = build_http_request(domainName, path, ocspReqSz,
|
||||||
|
httpBuf, httpBufSz);
|
||||||
|
|
||||||
tcp_connect(&sfd, ocsp->overrideName, ocsp->overridePort);
|
tcp_connect(&sfd, domainName, port);
|
||||||
if (sfd > 0) {
|
if (sfd > 0) {
|
||||||
int written;
|
int written;
|
||||||
written = write(sfd, httpBuf, httpBufSz);
|
written = write(sfd, httpBuf, httpBufSz);
|
||||||
@@ -332,19 +341,31 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
|
|||||||
close(sfd);
|
close(sfd);
|
||||||
if (ocspReqBuf == NULL) {
|
if (ocspReqBuf == NULL) {
|
||||||
CYASSL_MSG("HTTP response was not OK, no OCSP response");
|
CYASSL_MSG("HTTP response was not OK, no OCSP response");
|
||||||
return CERT_UNKNOWN;
|
return OCSP_LOOKUP_FAIL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CYASSL_MSG("OCSP Responder connection failed");
|
CYASSL_MSG("OCSP Responder connection failed");
|
||||||
return CERT_UNKNOWN;
|
return OCSP_LOOKUP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitOcspResponse(&ocspResponse, ocspReqBuf, ocspReqSz, NULL);
|
InitOcspResponse(&ocspResponse, ocspReqBuf, ocspReqSz, NULL);
|
||||||
OcspResponseDecode(&ocspResponse);
|
OcspResponseDecode(&ocspResponse);
|
||||||
|
|
||||||
if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
|
if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
|
||||||
CYASSL_MSG("OCSP Responder failure");
|
CYASSL_MSG("OCSP Responder failure");
|
||||||
|
result = OCSP_LOOKUP_FAIL;
|
||||||
} else {
|
} else {
|
||||||
result = ocspResponse.certStatus[0];
|
switch (ocspResponse.certStatus[0]) {
|
||||||
|
case CERT_GOOD:
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
case CERT_REVOKED:
|
||||||
|
result = OCSP_CERT_REVOKED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = OCSP_CERT_UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FreeOcspResponse(&ocspResponse);
|
FreeOcspResponse(&ocspResponse);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user