Fix support for OCSP and Nginx

Store DER copy of CA certificate with signer when
WOLFSSL_SIGNER_DER_CERT is defined.
Keep the bad issuer error for later when compiling for OpenSSL
compatability.
Authority Info string needs to be passed back with a nul terminator.
This commit is contained in:
Sean Parkinson
2018-06-25 15:24:40 +10:00
parent ac3eb470f9
commit 7fbe1d3049
5 changed files with 108 additions and 57 deletions

View File

@ -2959,7 +2959,7 @@ fi
if test "$ENABLED_NGINX" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NGINX"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NGINX -DWOLFSSL_SIGNER_DER_CERT"
fi
if test "$ENABLED_HAPROXY" = "yes"

View File

@ -604,6 +604,11 @@ int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
if (flags & OCSP_NOVERIFY)
return WOLFSSL_SUCCESS;
#ifdef OPENSSL_EXTRA
if (bs->verifyError != OCSP_VERIFY_ERROR_NONE)
return WOLFSSL_FAILURE;
#endif
InitDecodedCert(&cert, bs->cert, bs->certSz, NULL);
if (ParseCertRelative(&cert, CERT_TYPE, VERIFY, st->cm) < 0)
ret = WOLFSSL_FAILURE;

133
src/ssl.c
View File

@ -3972,7 +3972,7 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify)
int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
{
int ret;
Signer* signer = 0;
Signer* signer = NULL;
word32 row;
byte* subjectHash;
#ifdef WOLFSSL_SMALL_STACK
@ -4060,56 +4060,62 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
signer = MakeSigner(cm->heap);
if (!signer)
ret = MEMORY_ERROR;
}
if (ret == 0 && signer != NULL) {
#ifdef WOLFSSL_SIGNER_DER_CERT
ret = AllocDer(&signer->derCert, der->length, der->type, NULL);
}
if (ret == 0 && signer != NULL) {
XMEMCPY(signer->derCert->buffer, der->buffer, der->length);
#endif
signer->keyOID = cert->keyOID;
if (cert->pubKeyStored) {
signer->publicKey = cert->publicKey;
signer->pubKeySize = cert->pubKeySize;
}
if (cert->subjectCNStored) {
signer->nameLen = cert->subjectCNLen;
signer->name = cert->subjectCN;
}
signer->pathLength = cert->pathLength;
signer->pathLengthSet = cert->pathLengthSet;
#ifndef IGNORE_NAME_CONSTRAINTS
signer->permittedNames = cert->permittedNames;
signer->excludedNames = cert->excludedNames;
#endif
#ifndef NO_SKID
XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
SIGNER_DIGEST_SIZE);
#endif
XMEMCPY(signer->subjectNameHash, cert->subjectHash,
SIGNER_DIGEST_SIZE);
signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
: 0xFFFF;
signer->next = NULL; /* If Key Usage not set, all uses valid. */
cert->publicKey = 0; /* in case lock fails don't free here. */
cert->subjectCN = 0;
#ifndef IGNORE_NAME_CONSTRAINTS
cert->permittedNames = NULL;
cert->excludedNames = NULL;
#endif
#ifndef NO_SKID
row = HashSigner(signer->subjectKeyIdHash);
#else
row = HashSigner(signer->subjectNameHash);
#endif
if (wc_LockMutex(&cm->caLock) == 0) {
signer->next = cm->caTable[row];
cm->caTable[row] = signer; /* takes ownership */
wc_UnLockMutex(&cm->caLock);
if (cm->caCacheCallback)
cm->caCacheCallback(der->buffer, (int)der->length, type);
}
else {
signer->keyOID = cert->keyOID;
if (cert->pubKeyStored) {
signer->publicKey = cert->publicKey;
signer->pubKeySize = cert->pubKeySize;
}
if (cert->subjectCNStored) {
signer->nameLen = cert->subjectCNLen;
signer->name = cert->subjectCN;
}
signer->pathLength = cert->pathLength;
signer->pathLengthSet = cert->pathLengthSet;
#ifndef IGNORE_NAME_CONSTRAINTS
signer->permittedNames = cert->permittedNames;
signer->excludedNames = cert->excludedNames;
#endif
#ifndef NO_SKID
XMEMCPY(signer->subjectKeyIdHash, cert->extSubjKeyId,
SIGNER_DIGEST_SIZE);
#endif
XMEMCPY(signer->subjectNameHash, cert->subjectHash,
SIGNER_DIGEST_SIZE);
signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage
: 0xFFFF;
signer->next = NULL; /* If Key Usage not set, all uses valid. */
cert->publicKey = 0; /* in case lock fails don't free here. */
cert->subjectCN = 0;
#ifndef IGNORE_NAME_CONSTRAINTS
cert->permittedNames = NULL;
cert->excludedNames = NULL;
#endif
#ifndef NO_SKID
row = HashSigner(signer->subjectKeyIdHash);
#else
row = HashSigner(signer->subjectNameHash);
#endif
if (wc_LockMutex(&cm->caLock) == 0) {
signer->next = cm->caTable[row];
cm->caTable[row] = signer; /* takes ownership */
wc_UnLockMutex(&cm->caLock);
if (cm->caCacheCallback)
cm->caCacheCallback(der->buffer, (int)der->length, type);
}
else {
WOLFSSL_MSG("\tCA Mutex Lock failed");
ret = BAD_MUTEX_E;
FreeSigner(signer, cm->heap);
}
WOLFSSL_MSG("\tCA Mutex Lock failed");
ret = BAD_MUTEX_E;
FreeSigner(signer, cm->heap);
}
}
@ -32352,7 +32358,18 @@ int wolfSSL_X509_STORE_CTX_get1_issuer(WOLFSSL_X509 **issuer,
/* Create an empty certificate as CA doesn't have a certificate. */
XMEMSET(*issuer, 0, sizeof(WOLFSSL_X509));
/* TODO: store the full certificate and dup when required. */
(*issuer)->dynamicMemory = 1;
#ifdef WOLFSSL_SIGNER_DER_CERT
if (AllocDer(&(*issuer)->derCert, ca->derCert->length, ca->derCert->type,
NULL) == 0) {
XMEMCPY((*issuer)->derCert->buffer, ca->derCert->buffer,
ca->derCert->length);
}
else {
XFREE(*issuer, 0, DYNAMIC_TYPE_OPENSSL);
return WOLFSSL_FAILURE;
}
#endif
/* Result is ignored when passed to wolfSSL_OCSP_cert_to_id(). */
@ -32373,17 +32390,23 @@ void wolfSSL_X509_email_free(WOLF_STACK_OF(WOLFSSL_STRING) *sk)
WOLF_STACK_OF(WOLFSSL_STRING) *wolfSSL_X509_get1_ocsp(WOLFSSL_X509 *x)
{
WOLFSSL_STACK *list = NULL;
WOLFSSL_STACK* list = NULL;
char* url;
if (x->authInfoSz == 0)
return NULL;
list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
DYNAMIC_TYPE_OPENSSL);
list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK) + x->authInfoSz + 1,
NULL, DYNAMIC_TYPE_OPENSSL);
if (list == NULL)
return NULL;
list->data.string = (char*)x->authInfo;
url = (char*)list;
url += sizeof(WOLFSSL_STACK);
XMEMCPY(url, x->authInfo, x->authInfoSz);
url[x->authInfoSz] = '\0';
list->data.string = url;
list->next = NULL;
return list;

View File

@ -7037,6 +7037,9 @@ Signer* MakeSigner(void* heap)
#endif /* IGNORE_NAME_CONSTRAINTS */
signer->pathLengthSet = 0;
signer->pathLength = 0;
#ifdef WOLFSSL_SIGNER_DER_CERT
signer->derCert = NULL;
#endif
signer->next = NULL;
}
(void)heap;
@ -7055,6 +7058,9 @@ void FreeSigner(Signer* signer, void* heap)
FreeNameSubtrees(signer->permittedNames, heap);
if (signer->excludedNames)
FreeNameSubtrees(signer->excludedNames, heap);
#endif
#ifdef WOLFSSL_SIGNER_DER_CERT
FreeDer(&signer->derCert);
#endif
XFREE(signer, heap, DYNAMIC_TYPE_SIGNER);
@ -12946,9 +12952,12 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex,
}
else {
WOLFSSL_MSG("\tOCSP Responder key usage check failed");
#ifdef OPENSSL_EXTRA
resp->verifyError = OCSP_BAD_ISSUER;
#else
FreeDecodedCert(&cert);
return BAD_OCSP_RESPONDER;
#endif
}
}
#endif

View File

@ -736,6 +736,9 @@ struct Signer {
byte subjectKeyIdHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
#endif
#ifdef WOLFSSL_SIGNER_DER_CERT
DerBuffer* derCert;
#endif
Signer* next;
};
@ -928,6 +931,13 @@ enum Ocsp_Sums {
OCSP_NONCE_OID = 118
};
#ifdef OPENSSL_EXTRA
enum Ocsp_Verify_Error {
OCSP_VERIFY_ERROR_NONE = 0,
OCSP_BAD_ISSUER = 1
};
#endif
typedef struct OcspRequest OcspRequest;
typedef struct OcspResponse OcspResponse;
@ -981,6 +991,10 @@ struct OcspResponse {
byte* source; /* pointer to source buffer, not owned */
word32 maxIdx; /* max offset based on init size */
#ifdef OPENSSL_EXTRA
int verifyError;
#endif
};