diff --git a/src/internal.c b/src/internal.c index 42ac8579e..f11b9f329 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1557,6 +1557,54 @@ void FreeX509(WOLFSSL_X509* x509) XFREE(x509, NULL, DYNAMIC_TYPE_X509); } + +#ifndef NO_RSA + +/* Verify RSA signature, 0 on success */ +int VerifyRsaSign(const byte* sig, word32 sigSz, + const byte* plain, word32 plainSz, RsaKey* key) +{ + #ifdef WOLFSSL_SMALL_STACK + byte* verifySig = NULL; + #else + byte verifySig[ENCRYPT_LEN]; + #endif + byte* out = NULL; /* inline result */ + int ret; + + WOLFSSL_ENTER("VerifyRsaSign"); + + if (sigSz > ENCRYPT_LEN) { + WOLFSSL_MSG("Signature buffer too big"); + return BUFFER_E; + } + + #ifdef WOLFSSL_SMALL_STACK + verifySig = (byte*)XMALLOC(ENCRYPT_LEN, NULL, + DYNAMIC_TYPE_SIGNATURE); + if (verifySig == NULL) + return MEMORY_ERROR; + #endif + + XMEMCPY(verifySig, sig, sigSz); + ret = wc_RsaSSL_VerifyInline(verifySig, sigSz, &out, key); + + if (ret != (int)plainSz || !out || XMEMCMP(plain, out, plainSz) != 0) { + WOLFSSL_MSG("RSA Signature verification failed"); + ret = RSA_SIGN_FAULT; + } else { + ret = 0; /* RSA reset */ + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(verifySig, NULL, DYNAMIC_TYPE_SIGNATURE); + #endif + + return ret; +} + +#endif /* NO_RSA */ + #endif /* NO_CERTS */ @@ -8443,6 +8491,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case SNI_ABSENT_ERROR: return "No Server Name Indication extension Error"; + case RSA_SIGN_FAULT: + return "RSA Signature Fault Error"; + default : return "unknown error number"; } @@ -11832,6 +11883,8 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) } #ifndef NO_CERTS + + int SendCertificateVerify(WOLFSSL* ssl) { byte *output; @@ -12104,8 +12157,11 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) VERIFY_HEADER, ENCRYPT_LEN, &key, ssl->rng); } - if (ret > 0) - ret = 0; /* RSA reset */ + if (ret > 0) { + /* check for signature faults */ + ret = VerifyRsaSign(verify + extraSz + VERIFY_HEADER, ret, + signBuffer, signSz, &key); + } } #endif #ifdef WOLFSSL_SMALL_STACK @@ -13147,10 +13203,16 @@ int DoSessionTicket(WOLFSSL* ssl, ssl->RsaSignCtx); #endif /*HAVE_PK_CALLBACKS */ } - else + else { ret = wc_RsaSSL_Sign(signBuffer, signSz, output + idx, sigSz, &rsaKey, ssl->rng); + } + if (ret > 0) { + /* check for signature faults */ + ret = VerifyRsaSign(output + idx, ret, + signBuffer, signSz, &rsaKey); + } wc_FreeRsaKey(&rsaKey); wc_ecc_free(&dsaKey); @@ -13764,6 +13826,12 @@ int DoSessionTicket(WOLFSSL* ssl, sigSz, &rsaKey, ssl->rng); } + if (ret > 0) { + /* check for signature faults */ + ret = VerifyRsaSign(output + idx, ret, + signBuffer, signSz, &rsaKey); + } + wc_FreeRsaKey(&rsaKey); #ifdef WOLFSSL_SMALL_STACK @@ -15527,4 +15595,4 @@ int DoSessionTicket(WOLFSSL* ssl, return 0; } #endif /* HAVE_STUNNEL */ -#endif /* NO_WOLFSSL_SERVER */ \ No newline at end of file +#endif /* NO_WOLFSSL_SERVER */ diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 23e5f4d37..309be9eca 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -135,6 +135,7 @@ enum wolfSSL_ErrorCodes { DH_KEY_SIZE_E = -401, /* DH Key too small */ SNI_ABSENT_ERROR = -402, /* No SNI request. */ + RSA_SIGN_FAULT = -403, /* RSA Sign fault */ /* add strings to SetErrorString !!!!! */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 35762bef4..0e5499cb1 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2572,6 +2572,11 @@ WOLFSSL_LOCAL void ShrinkOutputBuffer(WOLFSSL* ssl); WOLFSSL_LOCAL int VerifyClientSuite(WOLFSSL* ssl); #ifndef NO_CERTS + #ifndef NO_RSA + WOLFSSL_LOCAL int VerifyRsaSign(const byte* sig, word32 sigSz, + const byte* plain, word32 plainSz, + RsaKey* key); + #endif WOLFSSL_LOCAL Signer* GetCA(void* cm, byte* hash); #ifndef NO_SKID WOLFSSL_LOCAL Signer* GetCAByName(void* cm, byte* hash);