diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index c89f4e172..da45ed9a5 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -3837,217 +3837,217 @@ static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid, static int DecodeSingleResponse(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) + word32* ioIndex, OcspResponse* resp, word32 size) { - word32 index = *ioIndex, prevIndex, oid, mpi_len; - int length, remainder, qty = 0; - mp_int mpi; - byte serialTmp[EXTERNAL_SERIAL_SIZE]; + word32 index = *ioIndex, prevIndex, oid, mpi_len; + int length, remainder, qty = 0; + mp_int mpi; + byte serialTmp[EXTERNAL_SERIAL_SIZE]; - /* Outer wrapper of the SEQUENCE OF Single Responses. */ - if (GetSequence(source, &index, &length, size) < 0) - return ASN_PARSE_E; - remainder = length; + /* Outer wrapper of the SEQUENCE OF Single Responses. */ + if (GetSequence(source, &index, &length, size) < 0) + return ASN_PARSE_E; + remainder = length; - /* First Single Response */ - while (remainder != 0 && qty < STATUS_LIST_SIZE) - { - prevIndex = index; - /* Wrapper around the Single Response */ - if (GetSequence(source, &index, &length, size) < 0) - return ASN_PARSE_E; + /* First Single Response */ + while (remainder != 0 && qty < STATUS_LIST_SIZE) + { + prevIndex = index; + /* Wrapper around the Single Response */ + if (GetSequence(source, &index, &length, size) < 0) + return ASN_PARSE_E; - /* Wrapper around the CertID */ - if (GetSequence(source, &index, &length, size) < 0) - return ASN_PARSE_E; - /* Skip the hash algorithm */ - if (GetAlgoId(source, &index, &oid, size) < 0) - return ASN_PARSE_E; - /* Skip the hash of CN */ - if (source[index++] != ASN_OCTET_STRING) - return ASN_PARSE_E; - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; - index += length; - /* Skip the hash of the issuer public key */ - if (source[index++] != ASN_OCTET_STRING) - return ASN_PARSE_E; - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; - index += length; + /* Wrapper around the CertID */ + if (GetSequence(source, &index, &length, size) < 0) + return ASN_PARSE_E; + /* Skip the hash algorithm */ + if (GetAlgoId(source, &index, &oid, size) < 0) + return ASN_PARSE_E; + /* Skip the hash of CN */ + if (source[index++] != ASN_OCTET_STRING) + return ASN_PARSE_E; + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; + index += length; + /* Skip the hash of the issuer public key */ + if (source[index++] != ASN_OCTET_STRING) + return ASN_PARSE_E; + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; + index += length; - /* Read the serial number */ - if (GetInt(&mpi, source, &index, size) < 0) - return ASN_PARSE_E; - mpi_len = mp_unsigned_bin_size(&mpi); - if (mpi_len < (int)sizeof(serialTmp)) { - if (mp_to_unsigned_bin(&mpi, serialTmp) == MP_OKAY) { - if (mpi_len > EXTERNAL_SERIAL_SIZE) - mpi_len = EXTERNAL_SERIAL_SIZE; - XMEMCPY(resp->certSN[qty], serialTmp, mpi_len); - resp->certSNsz[qty] = mpi_len; - } - } - mp_clear(&mpi); + /* Read the serial number */ + if (GetInt(&mpi, source, &index, size) < 0) + return ASN_PARSE_E; + mpi_len = mp_unsigned_bin_size(&mpi); + if (mpi_len < (int)sizeof(serialTmp)) { + if (mp_to_unsigned_bin(&mpi, serialTmp) == MP_OKAY) { + if (mpi_len > EXTERNAL_SERIAL_SIZE) + mpi_len = EXTERNAL_SERIAL_SIZE; + XMEMCPY(resp->certSN[qty], serialTmp, mpi_len); + resp->certSNsz[qty] = mpi_len; + } + } + mp_clear(&mpi); - /* CertStatus */ - switch (source[index++]) - { - case (ASN_CONTEXT_SPECIFIC | CERT_GOOD): - resp->certStatus[qty] = CERT_GOOD; - index++; - break; - case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED): - resp->certStatus[qty] = CERT_REVOKED; - GetLength(source, &index, &length, size); - index += length; - break; - case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_UNKNOWN): - resp->certStatus[qty] = CERT_UNKNOWN; - index++; - break; - default: - return ASN_PARSE_E; - } + /* CertStatus */ + switch (source[index++]) + { + case (ASN_CONTEXT_SPECIFIC | CERT_GOOD): + resp->certStatus[qty] = CERT_GOOD; + index++; + break; + case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED): + resp->certStatus[qty] = CERT_REVOKED; + GetLength(source, &index, &length, size); + index += length; + break; + case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_UNKNOWN): + resp->certStatus[qty] = CERT_UNKNOWN; + index++; + break; + default: + return ASN_PARSE_E; + } - if (source[index++] != ASN_GENERALIZED_TIME) - return ASN_PARSE_E; + if (source[index++] != ASN_GENERALIZED_TIME) + return ASN_PARSE_E; - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; - index += length; + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; + index += length; - remainder = remainder + prevIndex - index; - qty++; - } - resp->certStatusCount = qty; + remainder = remainder + prevIndex - index; + qty++; + } + resp->certStatusCount = qty; - *ioIndex = index; + *ioIndex = index; - return 0; + return 0; } static int DecodeResponseData(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) + word32* ioIndex, OcspResponse* resp, word32 size) { - word32 index = *ioIndex; - int length, result; - int version; - word32 responderId = 0; + word32 index = *ioIndex; + int length, result; + int version; + word32 responderId = 0; - if (GetSequence(source, &index, &length, size) < 0) - return ASN_PARSE_E; - resp->respBegin = index; - resp->respLength = length; + if (GetSequence(source, &index, &length, size) < 0) + return ASN_PARSE_E; + resp->respBegin = index; + resp->respLength = length; - /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this - * item isn't an EXPLICIT[0], then set version to zero and move - * onto the next item. - */ - if (source[index] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) - { - index += 2; /* Eat the value and length */ - if (GetMyVersion(source, &index, &version) < 0) - return ASN_PARSE_E; - } else - version = 0; + /* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this + * item isn't an EXPLICIT[0], then set version to zero and move + * onto the next item. + */ + if (source[index] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) + { + index += 2; /* Eat the value and length */ + if (GetMyVersion(source, &index, &version) < 0) + return ASN_PARSE_E; + } else + version = 0; - responderId = source[index++]; - if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) || - (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))) - { - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; - index += length; - } - else - return ASN_PARSE_E; - - /* Skip GeneralizedTime */ - if (source[index++] != ASN_GENERALIZED_TIME) - return ASN_PARSE_E; - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; - index += length; + responderId = source[index++]; + if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) || + (responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))) + { + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; + index += length; + } + else + return ASN_PARSE_E; + + /* Skip GeneralizedTime */ + if (source[index++] != ASN_GENERALIZED_TIME) + return ASN_PARSE_E; + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; + index += length; - if (DecodeSingleResponse(source, &index, resp, size) < 0) - return ASN_PARSE_E; + if (DecodeSingleResponse(source, &index, resp, size) < 0) + return ASN_PARSE_E; - /* Skip the extensions */ - if (source[index++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) - { - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; - index += length; - } + /* Skip the extensions */ + if (source[index++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) + { + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; + index += length; + } - *ioIndex = index; - return 0; + *ioIndex = index; + return 0; } static int DecodeCerts(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) + word32* ioIndex, OcspResponse* resp, word32 size) { - word32 index = *ioIndex; - if (source[index++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) - { - int length; + word32 index = *ioIndex; + if (source[index++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) + { + int length; - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; - index += length; - } - *ioIndex = index; - return 0; + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; + index += length; + } + *ioIndex = index; + return 0; } static int DecodeBasicOcspResponse(byte* source, - word32* ioIndex, OcspResponse* resp, word32 size) + word32* ioIndex, OcspResponse* resp, word32 size) { - int length; - word32 index = *ioIndex; - word32 end_index; + int length; + word32 index = *ioIndex; + word32 end_index; - if (GetSequence(source, &index, &length, size) < 0) - return ASN_PARSE_E; + if (GetSequence(source, &index, &length, size) < 0) + return ASN_PARSE_E; - if (index + length > size) - return ASN_INPUT_E; - end_index = index + length; + if (index + length > size) + return ASN_INPUT_E; + end_index = index + length; - if (DecodeResponseData(source, &index, resp, size) < 0) - return ASN_PARSE_E; - - /* Get the signature algorithm */ - if (GetAlgoId(source, &index, &resp->sigOID, size) < 0) - return ASN_PARSE_E; + if (DecodeResponseData(source, &index, resp, size) < 0) + return ASN_PARSE_E; + + /* Get the signature algorithm */ + if (GetAlgoId(source, &index, &resp->sigOID, size) < 0) + return ASN_PARSE_E; - /* Obtain pointer to the start of the signature, and save the size */ - if (source[index++] == ASN_BIT_STRING) - { - int sigLength = 0; - if (GetLength(source, &index, &sigLength, size) < 0) - return ASN_PARSE_E; - resp->sigLength = sigLength; - resp->sigIndex = index; - index += sigLength; - } + /* Obtain pointer to the start of the signature, and save the size */ + if (source[index++] == ASN_BIT_STRING) + { + int sigLength = 0; + if (GetLength(source, &index, &sigLength, size) < 0) + return ASN_PARSE_E; + resp->sigLength = sigLength; + resp->sigIndex = index; + index += sigLength; + } - /* - * Check the length of the BasicOcspResponse against the current index to - * see if there are certificates, they are optional. - */ - if (index < end_index) - return DecodeCerts(source, &index, resp, size); + /* + * Check the length of the BasicOcspResponse against the current index to + * see if there are certificates, they are optional. + */ + if (index < end_index) + return DecodeCerts(source, &index, resp, size); - *ioIndex = index; - return 0; + *ioIndex = index; + return 0; } void InitOcspResponse(OcspResponse* resp, byte* source, word32 inSz, void* heap) { - XMEMSET(resp, 0, sizeof(*resp)); + XMEMSET(resp, 0, sizeof(*resp)); resp->source = source; resp->maxIdx = inSz; resp->heap = heap; @@ -4059,55 +4059,67 @@ void FreeOcspResponse(OcspResponse* resp) {} int OcspResponseDecode(OcspResponse* resp) { - int length = 0; - word32 index = 0; - byte* source = resp->source; - word32 size = resp->maxIdx; - word32 oid; + int length = 0; + word32 index = 0; + byte* source = resp->source; + word32 size = resp->maxIdx; + word32 oid; - /* peel the outer SEQUENCE wrapper */ + /* peel the outer SEQUENCE wrapper */ if (GetSequence(source, &index, &length, size) < 0) return ASN_PARSE_E; - - /* First get the responseStatus, an ENUMERATED */ - if (GetEnumerated(source, &index, &resp->responseStatus) < 0) - return ASN_PARSE_E; + + /* First get the responseStatus, an ENUMERATED */ + if (GetEnumerated(source, &index, &resp->responseStatus) < 0) + return ASN_PARSE_E; - if (resp->responseStatus != OCSP_SUCCESSFUL) - return 0; + if (resp->responseStatus != OCSP_SUCCESSFUL) + return 0; - /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */ - if (index >= size) - return ASN_INPUT_E; - if (source[index++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) - return ASN_PARSE_E; - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; + /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */ + if (index >= size) + return ASN_INPUT_E; + if (source[index++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) + return ASN_PARSE_E; + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; - /* Get the responseBytes SEQUENCE */ - if (GetSequence(source, &index, &length, size) < 0) - return ASN_PARSE_E; + /* Get the responseBytes SEQUENCE */ + if (GetSequence(source, &index, &length, size) < 0) + return ASN_PARSE_E; - /* Check ObjectID for the resposeBytes */ - if (GetObjectId(source, &index, &oid, size) < 0) - return ASN_PARSE_E; - if (oid != OCSP_BASIC_OID) - return ASN_PARSE_E; - if (source[index++] != ASN_OCTET_STRING) - return ASN_PARSE_E; + /* Check ObjectID for the resposeBytes */ + if (GetObjectId(source, &index, &oid, size) < 0) + return ASN_PARSE_E; + if (oid != OCSP_BASIC_OID) + return ASN_PARSE_E; + if (source[index++] != ASN_OCTET_STRING) + return ASN_PARSE_E; - if (GetLength(source, &index, &length, size) < 0) - return ASN_PARSE_E; + if (GetLength(source, &index, &length, size) < 0) + return ASN_PARSE_E; - if (DecodeBasicOcspResponse(source, &index, resp, size) < 0) - return ASN_PARSE_E; - - return 0; + if (DecodeBasicOcspResponse(source, &index, resp, size) < 0) + return ASN_PARSE_E; + + return 0; } + +void InitOcspRequest(OcspRequest* req) +{ +} + + +int MakeOcspRequest(OcspRequest* req) +{ + return 0; +} + + int EncodeOcspRequest(void) { - return 0; + return 0; } #endif diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index 930ac7662..c3c1206cd 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -333,6 +333,14 @@ enum Ocsp_Sums { typedef struct OcspResponse OcspResponse; +typedef struct OcspRequest OcspRequest; + + +struct OcspRequest { + byte* serialNumber; /* not owned by us */ + int serialSz; +}; + struct OcspResponse { int responseStatus; /* return code from Responder */ diff --git a/cyassl/internal.h b/cyassl/internal.h index d72fee138..95f0dcf00 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -40,6 +40,9 @@ #ifndef NO_SHA256 #include #endif +#ifdef HAVE_OCSP + #include +#endif #ifdef CYASSL_CALLBACKS #include @@ -642,6 +645,9 @@ struct CYASSL_CTX { pem_password_cb passwd_cb; void* userdata; #endif /* OPENSSL_EXTRA */ +#ifdef HAVE_OCSP + CYASSL_OCSP ocsp; +#endif }; diff --git a/cyassl/ocsp.h b/cyassl/ocsp.h new file mode 100644 index 000000000..0d6b0e236 --- /dev/null +++ b/cyassl/ocsp.h @@ -0,0 +1,71 @@ +/* ssl.h + * + * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + + +/* CyaSSL OCSP API */ + +#ifndef CYASSL_OCSP_H +#define CYASSL_OCSP_H + + +#include + + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct CYASSL_OCSP CYASSL_OCSP; +typedef struct CertStatus CertStatus; + +struct CertStatus { + byte subjectHash[SHA_SIZE]; + byte issuerHash[SHA_SIZE]; + byte serial[EXTERNAL_SERIAL_SIZE]; + int serialSz; + int status; +}; + +struct CYASSL_OCSP { + byte enabled; + byte useOverrideUrl; + char overrideName[80]; + int overridePort; + int statusLen; + CertStatus status[1]; +}; + + + +CYASSL_LOCAL int CyaSSL_OCSP_Init(CYASSL_OCSP*); +CYASSL_LOCAL void CyaSSL_OCSP_Cleanup(CYASSL_OCSP*); +CYASSL_LOCAL int CyaSSL_OCSP_set_override_url(CYASSL_OCSP*, const char*); +CYASSL_LOCAL int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP*, DecodedCert*); + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* CYASSL_OCSP_H */ + + diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 85af1ac1a..5393a66fc 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -508,7 +508,7 @@ CYASSL_API void CyaSSL_ERR_print_errors_fp(FILE*, int err); enum { /* ssl Constants */ SSL_ERROR_NONE = 0, /* for most functions */ SSL_FAILURE = 0, /* for some functions */ - SSL_SUCCESS = 1, + SSL_SUCCESS = 1, SSL_BAD_CERTTYPE = -8, SSL_BAD_STAT = -7, @@ -794,6 +794,13 @@ CYASSL_API int CyaSSL_accept_ex(CYASSL*, HandShakeCallBack, TimeoutCallBack, #endif /* CYASSL_CALLBACKS */ +CYASSL_API long CyaSSL_CTX_OCSP_set_options(CYASSL_CTX*, long); +CYASSL_API int CyaSSL_CTX_OCSP_set_override_url(CYASSL_CTX*, const char*); + +/* OCSP Options */ +#define CYASSL_OCSP_ENABLE 0x0001 /* Enable OCSP lookups */ +#define CYASSL_OCSP_URL_OVERRIDE 0x0002 /* Use the override URL instead of URL + * in certificate */ #ifdef __cplusplus diff --git a/src/internal.c b/src/internal.c index 3dc5d592e..459008e94 100644 --- a/src/internal.c +++ b/src/internal.c @@ -388,6 +388,9 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method) ctx->sendVerify = 0; ctx->quietShutdown = 0; ctx->groupMessages = 0; +#ifdef HAVE_OCSP + CyaSSL_OCSP_Init(&ctx->ocsp); +#endif if (InitMutex(&ctx->countMutex) < 0) { CYASSL_MSG("Mutex error on CTX init"); @@ -408,6 +411,10 @@ void SSL_CtxResourceFree(CYASSL_CTX* ctx) XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD); FreeSigners(ctx->caList, ctx->heap); + +#ifdef HAVE_OCSP + CyaSSL_OCSP_Cleanup(&ctx->ocsp); +#endif } @@ -1624,6 +1631,10 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx) } } +#ifdef HAVE_OCSP + CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert); +#endif + #ifdef OPENSSL_EXTRA /* set X509 format for peer cert even if fatal */ XSTRNCPY(ssl->peerCert.issuer.name, dCert.issuer, ASN_NAME_MAX); diff --git a/src/ocsp.c b/src/ocsp.c index a7407efea..f6961726a 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -24,12 +24,117 @@ #endif #include -#include +#include #ifdef HAVE_OCSP +CYASSL_API int ocsp_test(unsigned char* buf, int sz); +#define CYASSL_OCSP_ENABLE 0x0001 /* Enable OCSP lookups */ +#define CYASSL_OCSP_URL_OVERRIDE 0x0002 /* Use the override URL instead of URL + * in certificate */ + + +int ocsp_test(unsigned char* buf, int sz) +{ + CYASSL_OCSP ocsp; + OcspResponse resp; + int result; + + CyaSSL_OCSP_Init(&ocsp); + InitOcspResponse(&resp, buf, sz, NULL); + + ocsp.enabled = 1; + ocsp.useOverrideUrl = 1; + CyaSSL_OCSP_set_override_url(&ocsp, "http://ocsp.example.com:8080/"); + CyaSSL_OCSP_Lookup_Cert(&ocsp, NULL); + + result = OcspResponseDecode(&resp); + + FreeOcspResponse(&resp); + CyaSSL_OCSP_Cleanup(&ocsp); + + return result; +} + + +int CyaSSL_OCSP_Init(CYASSL_OCSP* ocsp) +{ + if (ocsp != NULL) { + XMEMSET(ocsp, 0, sizeof(*ocsp)); + return 0; + } + + return -1; +} + + +void CyaSSL_OCSP_Cleanup(CYASSL_OCSP* ocsp) +{ + ocsp->enabled = 0; + /* Deallocate memory */ +} + + +int CyaSSL_OCSP_set_override_url(CYASSL_OCSP* ocsp, const char* url) +{ + if (ocsp != NULL && url != NULL) { + 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] != '/') { + ocsp->overrideName[i++] = url[cur++]; + } + ocsp->overrideName[i] = 0; + + 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; + + return 1; + } + + return 0; +} + + +int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) +{ + /* If OCSP lookups are disabled, return success. */ + if (!ocsp->enabled) return 1; + + /* 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; + + 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; + + return 1; +} -void ocsp_stub(void) {} #endif /* HAVE_OCSP */ diff --git a/src/ssl.c b/src/ssl.c index 6ad767c88..943b39ab2 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5379,3 +5379,26 @@ const byte* CyaSSL_get_sessionID(const CYASSL_SESSION* session) #endif /* SESSION_CERTS */ + +#ifdef HAVE_OCSP + +long CyaSSL_CTX_OCSP_set_options(CYASSL_CTX* ctx, long options) +{ + CYASSL_ENTER("CyaSSL_CTX_OCSP_set_options"); + if (ctx != NULL) { + ctx->ocsp.enabled = (options && CYASSL_OCSP_ENABLE) != 0; + ctx->ocsp.useOverrideUrl = (options && CYASSL_OCSP_URL_OVERRIDE) != 0; + return 1; + } + return 0; +} + + +int CyaSSL_CTX_OCSP_set_override_url(CYASSL_CTX* ctx, const char* url) +{ + CYASSL_ENTER("CyaSSL_CTX_OCSP_set_override_url"); + return CyaSSL_OCSP_set_override_url(&ctx->ocsp, url); +} + +#endif +