diff --git a/src/ssl.c b/src/ssl.c index 0c762be6c..48c8af253 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -19143,6 +19143,53 @@ int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx) } return WOLFSSL_FATAL_ERROR; } + + +/* Use the public key to verify the signature. Note: this only verifies + * the certificate signature. + * returns WOLFSSL_SUCCESS on successful signature verification */ +int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey) +{ + int ret; + const byte* der; + int derSz = 0; + int type; + + if (x509 == NULL || pkey == NULL) { + return WOLFSSL_FATAL_ERROR; + } + + der = wolfSSL_X509_get_der(x509, &derSz); + if (der == NULL) { + WOLFSSL_MSG("Error getting WOLFSSL_X509 DER"); + return WOLFSSL_FATAL_ERROR; + } + + switch (pkey->type) { + case EVP_PKEY_RSA: + type = RSAk; + break; + + case EVP_PKEY_EC: + type = ECDSAk; + break; + + case EVP_PKEY_DSA: + type = DSAk; + break; + + default: + WOLFSSL_MSG("Unknown pkey key type"); + return WOLFSSL_FATAL_ERROR; + } + + ret = CheckCertSignaturePubKey(der, derSz, x509->heap, + (unsigned char*)pkey->pkey.ptr, pkey->pkey_sz, type); + if (ret == 0) { + return WOLFSSL_SUCCESS; + } + return WOLFSSL_FAILURE; +} #endif /* NO_CERTS */ #if !defined(NO_FILESYSTEM) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 497074374..39ce6daf9 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -7749,7 +7749,7 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm) } #endif -#ifdef WOLFSSL_SMALL_CERT_VERIFY +#if defined(WOLFSSL_SMALL_CERT_VERIFY) || defined(OPENSSL_EXTRA) /* Only quick step through the certificate to find fields that are then used * in certificate signature verification. * Must use the signature OID from the signed part of the certificate. @@ -7759,7 +7759,8 @@ static Signer* GetCABySubjectAndPubKey(DecodedCert* cert, void* cm) * Doesn't support: * OCSP Only: alt lookup using subject and pub key w/o sig check */ -int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm) +static int CheckCertSignature_ex(const byte* cert, word32 certSz, void* heap, + void* cm, const byte* pubKey, word32 pubKeySz, int pubKeyOID) { #ifndef WOLFSSL_SMALL_STACK SignatureCtx sigCtx[1]; @@ -7963,7 +7964,7 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm) } } - if (ret == 0) { + if (ret == 0 && pubKey == NULL) { if (extAuthKeyIdSet) ca = GetCA(cm, hash); if (ca == NULL) { @@ -7973,13 +7974,13 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm) } } #else - if (ret == 0) { + if (ret == 0 && pubKey == NULL) { ret = CalcHashId(cert + issuerIdx, issuerSz, hash); if (ret == 0) ca = GetCA(cm, hash); } #endif /* !NO_SKID */ - if (ca == NULL) + if (ca == NULL && pubKey == NULL) ret = ASN_NO_SIGNER_E; if (ret == 0) { @@ -7999,9 +8000,18 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm) } if (ret == 0) { - ret = ConfirmSignature(sigCtx, cert + tbsCertIdx, sigIndex - tbsCertIdx, + if (pubKey != NULL) { + ret = ConfirmSignature(sigCtx, cert + tbsCertIdx, + sigIndex - tbsCertIdx, + pubKey, pubKeySz, pubKeyOID, + cert + idx, len, signatureOID); + } + else { + ret = ConfirmSignature(sigCtx, cert + tbsCertIdx, + sigIndex - tbsCertIdx, ca->publicKey, ca->pubKeySize, ca->keyOID, cert + idx, len, signatureOID); + } if (ret != 0) { WOLFSSL_MSG("Confirm signature failed"); } @@ -8014,7 +8024,26 @@ int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm) #endif return ret; } + +#ifdef OPENSSL_EXTRA +/* Call CheckCertSignature_ex using a public key buffer for verification + */ +int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap, + const byte* pubKey, word32 pubKeySz, int pubKeyOID) +{ + return CheckCertSignature_ex(cert, certSz, heap, NULL, + pubKey, pubKeySz, pubKeyOID); +} +#endif /* OPENSSL_EXTRA */ +#ifdef WOLFSSL_SMALL_CERT_VERIFY +/* Call CheckCertSignature_ex using a certificate manager (cm) + */ +int CheckCertSignature(const byte* cert, word32 certSz, void* heap, void* cm) +{ + return CheckCertSignature_ex(cert, certSz, heap, cm, NULL, 0, 0); +} #endif /* WOLFSSL_SMALL_CERT_VERIFY */ +#endif /* WOLFSSL_SMALL_CERT_VERIFY || OPENSSL_EXTRA */ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) { diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index d4fbbeb0c..947ad3992 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -930,6 +930,7 @@ WOLFSSL_API unsigned char* wolfSSL_X509_get_authorityKeyID( WOLFSSL_API unsigned char* wolfSSL_X509_get_subjectKeyID( WOLFSSL_X509*, unsigned char*, int*); +WOLFSSL_API int wolfSSL_X509_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey); WOLFSSL_API int wolfSSL_X509_set_subject_name(WOLFSSL_X509*, WOLFSSL_X509_NAME*); WOLFSSL_API int wolfSSL_X509_set_pubkey(WOLFSSL_X509*, WOLFSSL_EVP_PKEY*); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 33ebd9a4a..99c26007a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -940,6 +940,8 @@ WOLFSSL_ASN_API int ParseCert(DecodedCert*, int type, int verify, void* cm); WOLFSSL_LOCAL int DecodePolicyOID(char *o, word32 oSz, const byte *in, word32 inSz); WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm); +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);