From 6298074f937949a2ad298515a34302bef8d942be Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 7 Feb 2019 17:07:19 -0800 Subject: [PATCH] OCSP and ECDSA Signers OCSP uses an identified hash of the issuer's public key to identify the certificate's signer. (Typically this is SHA-1, but can be any SHA hash.) The AKID/SKID for the certificates usually are the SHA-1 hash of the public key, but may be anything. We cannot depend on the AKID for OCSP purposes. For OCSP lookups, wolfSSL calculates the hash of the public key based on the copy saved for use with the handshake signing. For RSA, that was fine. For ECDSA, we use the whole public key including the curve ID, but for OCSP the curve ID isn't hashed. Stored the hash of the public key at the point where we are looking at the key when reading in the certificate, and saving the hash in the signer record. --- src/ssl.c | 4 ++++ wolfcrypt/src/asn.c | 44 ++++++++++++++++++++++------------------- wolfssl/wolfcrypt/asn.h | 4 ++++ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 6aa0a970b..e93863641 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4237,6 +4237,10 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) #endif XMEMCPY(signer->subjectNameHash, cert->subjectHash, SIGNER_DIGEST_SIZE); + #ifdef HAVE_OCSP + XMEMCPY(signer->subjectKeyHash, cert->subjectKeyHash, + KEYID_SIZE); + #endif signer->keyUsage = cert->extKeyUsageSet ? cert->extKeyUsage : 0xFFFF; signer->next = NULL; /* If Key Usage not set, all uses valid. */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 06b8aaf3d..39d4cc46f 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4337,11 +4337,19 @@ static int GetKey(DecodedCert* cert) case RSAk: { int ret; - ret = CheckBitString(cert->source, &cert->srcIdx, NULL, + + ret = CheckBitString(cert->source, &cert->srcIdx, &length, cert->maxIdx, 1, NULL); if (ret != 0) return ret; + #ifdef HAVE_OCSP + ret = CalcHashId(cert->source + cert->srcIdx, length, + cert->subjectKeyHash); + if (ret != 0) + return ret; + #endif + return StoreRsaKey(cert); } @@ -4434,6 +4442,12 @@ static int GetKey(DecodedCert* cert) cert->maxIdx, 1, NULL); if (ret != 0) return ret; + #ifdef HAVE_OCSP + ret = CalcHashId(cert->source + cert->srcIdx, length, + cert->subjectKeyHash); + if (ret != 0) + return ret; + #endif } publicKey = (byte*)XMALLOC(pubLen, cert->heap, @@ -4463,6 +4477,13 @@ static int GetKey(DecodedCert* cert) if (ret != 0) return ret; + #ifdef HAVE_OCSP + ret = CalcHashId(cert->source + cert->srcIdx, length, + cert->subjectKeyHash); + if (ret != 0) + return ret; + #endif + publicKey = (byte*) XMALLOC(length, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); if (publicKey == NULL) @@ -8076,10 +8097,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) #ifdef HAVE_OCSP /* Need the CA's public key hash for OCSP */ - ret = CalcHashId(cert->ca->publicKey, cert->ca->pubKeySize, - cert->issuerKeyHash); - if (ret != 0) - return ret; + XMEMCPY(cert->issuerKeyHash, cert->ca->subjectKeyHash, KEYID_SIZE); #endif /* HAVE_OCSP */ } } @@ -8139,21 +8157,7 @@ Signer* MakeSigner(void* heap) Signer* signer = (Signer*) XMALLOC(sizeof(Signer), heap, DYNAMIC_TYPE_SIGNER); if (signer) { - signer->pubKeySize = 0; - signer->keyOID = 0; - signer->publicKey = NULL; - signer->nameLen = 0; - signer->name = NULL; - #ifndef IGNORE_NAME_CONSTRAINTS - signer->permittedNames = NULL; - signer->excludedNames = NULL; - #endif /* IGNORE_NAME_CONSTRAINTS */ - signer->pathLengthSet = 0; - signer->pathLength = 0; - #ifdef WOLFSSL_SIGNER_DER_CERT - signer->derCert = NULL; - #endif - signer->next = NULL; + XMEMSET(signer, 0, sizeof(Signer)); } (void)heap; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index a9eb70c76..34b14721a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -696,6 +696,7 @@ struct DecodedCert { byte subjectHash[KEYID_SIZE]; /* hash of all Names */ byte issuerHash[KEYID_SIZE]; /* hash of all Names */ #ifdef HAVE_OCSP + byte subjectKeyHash[KEYID_SIZE]; /* hash of the public Key */ byte issuerKeyHash[KEYID_SIZE]; /* hash of the public Key */ #endif /* HAVE_OCSP */ const byte* signature; /* not owned, points into raw cert */ @@ -874,6 +875,9 @@ struct Signer { byte subjectKeyIdHash[SIGNER_DIGEST_SIZE]; /* sha hash of names in certificate */ #endif + #ifdef HAVE_OCSP + byte subjectKeyHash[KEYID_SIZE]; + #endif #ifdef WOLFSSL_SIGNER_DER_CERT DerBuffer* derCert; #endif