mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 10:47:28 +02:00
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:
@ -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"
|
||||||
|
@ -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
133
src/ssl.c
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user