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" if test "$ENABLED_NGINX" = "yes"
then then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NGINX" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NGINX -DWOLFSSL_SIGNER_DER_CERT"
fi fi
if test "$ENABLED_HAPROXY" = "yes" if test "$ENABLED_HAPROXY" = "yes"

View File

@ -604,6 +604,11 @@ int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs,
if (flags & OCSP_NOVERIFY) if (flags & OCSP_NOVERIFY)
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
#ifdef OPENSSL_EXTRA
if (bs->verifyError != OCSP_VERIFY_ERROR_NONE)
return WOLFSSL_FAILURE;
#endif
InitDecodedCert(&cert, bs->cert, bs->certSz, NULL); InitDecodedCert(&cert, bs->cert, bs->certSz, NULL);
if (ParseCertRelative(&cert, CERT_TYPE, VERIFY, st->cm) < 0) if (ParseCertRelative(&cert, CERT_TYPE, VERIFY, st->cm) < 0)
ret = WOLFSSL_FAILURE; 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 AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
{ {
int ret; int ret;
Signer* signer = 0; Signer* signer = NULL;
word32 row; word32 row;
byte* subjectHash; byte* subjectHash;
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
@ -4060,56 +4060,62 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
signer = MakeSigner(cm->heap); signer = MakeSigner(cm->heap);
if (!signer) if (!signer)
ret = MEMORY_ERROR; 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 { else {
signer->keyOID = cert->keyOID; WOLFSSL_MSG("\tCA Mutex Lock failed");
if (cert->pubKeyStored) { ret = BAD_MUTEX_E;
signer->publicKey = cert->publicKey; FreeSigner(signer, cm->heap);
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);
}
} }
} }
@ -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. */ /* Create an empty certificate as CA doesn't have a certificate. */
XMEMSET(*issuer, 0, sizeof(WOLFSSL_X509)); 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(). */ /* 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) 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) if (x->authInfoSz == 0)
return NULL; return NULL;
list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, list = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK) + x->authInfoSz + 1,
DYNAMIC_TYPE_OPENSSL); NULL, DYNAMIC_TYPE_OPENSSL);
if (list == NULL) if (list == NULL)
return 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; list->next = NULL;
return list; return list;

View File

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

View File

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