diff --git a/src/ssl.c b/src/ssl.c index 7cd458880..f33d8051b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15366,19 +15366,63 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) /* Getter function that copies over the DER public key buffer to "buf" and * sets the size in bufSz. If "buf" is NULL then just bufSz is set to needed * buffer size. + * + * Note: this is the X.509 form of key with "header" info. * return WOLFSSL_SUCCESS on success */ int wolfSSL_X509_get_pubkey_buffer(WOLFSSL_X509* x509, unsigned char* buf, int* bufSz) { WOLFSSL_ENTER("wolfSSL_X509_get_pubkey_buffer"); - if (x509 == NULL || bufSz == NULL || (*bufSz < (int)x509->pubKey.length - && buf != NULL)) + if (x509 == NULL || bufSz == NULL) return WOLFSSL_FATAL_ERROR; + /* get pointer into DER for X.509 public key */ + if (x509->pubKeyX509 == NULL) { + #ifdef WOLFSSL_SMALL_STACK + DecodedCert* cert; + #else + DecodedCert cert[1]; + #endif + word32 idx; + const byte* der; + int length = 0; + int ret, derSz = 0; + int badDate = 0; + + #ifdef WOLFSSL_SMALL_STACK + cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), + x509->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (decoded == NULL) + return MEMORY_E; + #endif + + der = wolfSSL_X509_get_der(x509, &derSz); + InitDecodedCert(cert, der, derSz, NULL); + ret = wc_GetPubX509(cert, 0, &badDate); + if (ret >= 0) { + idx = cert->srcIdx; + x509->pubKeyX509 = cert->source + cert->srcIdx; + ret = GetSequence(cert->source, &cert->srcIdx, &length, + cert->maxIdx); + x509->pubKeyX509Sz = length + (cert->srcIdx - idx); + } + + FreeDecodedCert(cert); + #ifdef WOLFSSL_SMALL_STACK + XFREE(cert, x509->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + + if (ret < 0) { + x509->pubKeyX509 = NULL; + x509->pubKeyX509Sz = 0; + return ret; + } + } + if (buf != NULL) - XMEMCPY(buf, x509->pubKey.buffer, x509->pubKey.length); - *bufSz = x509->pubKey.length; + XMEMCPY(buf, x509->pubKeyX509, x509->pubKeyX509Sz); + *bufSz = x509->pubKeyX509Sz; return WOLFSSL_SUCCESS; } @@ -15431,7 +15475,7 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) const unsigned char* wolfSSL_X509_get_tbs(WOLFSSL_X509* x509, int* outSz) { int sz = 0, len; - unsigned int idx = 0; + unsigned int idx = 0, tmpIdx; const unsigned char* der = NULL; const unsigned char* tbs = NULL; @@ -15448,10 +15492,11 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) return NULL; } tbs = der + idx; + tmpIdx = idx; if (GetSequence(der, &idx, &len, sz) < 0) { return NULL; } - *outSz = len; + *outSz = len + (idx - tmpIdx); return tbs; } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 79d4155c2..72ab8393b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5640,12 +5640,20 @@ int wc_GetCertDates(Cert* cert, struct tm* before, struct tm* after) #endif /* WOLFSSL_CERT_GEN && WOLFSSL_ALT_NAMES */ #endif /* !NO_ASN_TIME */ - -int DecodeToKey(DecodedCert* cert, int verify) +/* parses certificate up to point of X.509 public key + * + * if cert date is invalid then badDate gets set to error value, otherwise is 0 + * + * returns a negative value on fail case + */ +int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate) { - int badDate = 0; int ret; + if (cert == NULL || badDate == NULL) + return BAD_FUNC_ARG; + + *badDate = 0; if ( (ret = GetCertHeader(cert)) < 0) return ret; @@ -5661,12 +5669,23 @@ int DecodeToKey(DecodedCert* cert, int verify) return ret; if ( (ret = GetValidity(cert, verify)) < 0) - badDate = ret; + *badDate = ret; if ( (ret = GetName(cert, SUBJECT)) < 0) return ret; WOLFSSL_MSG("Got Subject Name"); + return ret; +} + + +int DecodeToKey(DecodedCert* cert, int verify) +{ + int badDate = 0; + int ret; + + if ( (ret = wc_GetPubX509(cert, verify, &badDate)) < 0) + return ret; /* Determine if self signed */ cert->selfSigned = XMEMCMP(cert->issuerHash, diff --git a/wolfssl/internal.h b/wolfssl/internal.h index c657f299c..4eca1fb6a 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3417,6 +3417,11 @@ struct WOLFSSL_X509 { DNS_entry* altNames; /* alt names list */ buffer pubKey; int pubKeyOID; +#ifdef OPENSSL_EXTRA + const byte* pubKeyX509; /* pointer to internal X509 for where X.509 + * format key starts */ + int pubKeyX509Sz; +#endif DNS_entry* altNamesNext; /* hint for retrieval */ #if defined(HAVE_ECC) || defined(HAVE_ED25519) word32 pkCurveOID; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index bb4cf23d6..38d48717b 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -946,6 +946,7 @@ WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID); WOLFSSL_LOCAL int ParseCertRelative(DecodedCert*,int type,int verify,void* cm); WOLFSSL_LOCAL int DecodeToKey(DecodedCert*, int verify); +WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate); WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz); WOLFSSL_LOCAL Signer* MakeSigner(void*);