diff --git a/src/ssl.c b/src/ssl.c index 0d722f4ae09..09733f45a8b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -12050,12 +12050,96 @@ const char* wolfSSL_alert_type_string_long(int alertID) return AlertTypeToString(alertID); } +const char* wolfSSL_alert_type_string(int alertID) +{ + WOLFSSL_ENTER("wolfSSL_alert_type_string"); + + switch (alertID) { + case alert_warning: + return "W"; + case alert_fatal: + return "F"; + default: + return "U"; + } +} + const char* wolfSSL_alert_desc_string_long(int alertID) { WOLFSSL_ENTER("wolfSSL_alert_desc_string_long"); return AlertTypeToString(alertID); } + +const char* wolfSSL_alert_desc_string(int alertID) +{ + WOLFSSL_ENTER("wolfSSL_alert_desc_string"); + + switch (alertID) { + case close_notify: + return "CN"; + case unexpected_message: + return "UM"; + case bad_record_mac: + return "BM"; + case record_overflow: + return "RO"; + case decompression_failure: + return "DF"; + case handshake_failure: + return "HF"; + case no_certificate: + return "NC"; + case bad_certificate: + return "BC"; + case unsupported_certificate: + return "UC"; + case certificate_revoked: + return "CR"; + case certificate_expired: + return "CE"; + case certificate_unknown: + return "CU"; + case illegal_parameter: + return "IP"; + case unknown_ca: + return "CA"; + case access_denied: + return "AD"; + case decode_error: + return "DE"; + case decrypt_error: + return "DC"; + case wolfssl_alert_protocol_version: + return "PV"; + case insufficient_security: + return "IS"; + case internal_error: + return "IE"; + case inappropriate_fallback: + return "IF"; + case user_canceled: + return "US"; + case no_renegotiation: + return "NR"; + case missing_extension: + return "ME"; + case unsupported_extension: + return "UE"; + case unrecognized_name: + return "UN"; + case bad_certificate_status_response: + return "BR"; + case unknown_psk_identity: + return "UP"; + case certificate_required: + return "CQ"; + case no_application_protocol: + return "AP"; + default: + return "UK"; + } +} #endif /* !NO_TLS */ #define STATE_STRINGS_PROTO(s) \ diff --git a/tests/api/test_evp_pkey.c b/tests/api/test_evp_pkey.c index adf381dcade..2e2a5919dbb 100644 --- a/tests/api/test_evp_pkey.c +++ b/tests/api/test_evp_pkey.c @@ -1997,6 +1997,121 @@ int test_wolfSSL_EVP_MD_ecc_signing(void) } +int test_wolfSSL_EVP_DigestSign(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(USE_CERT_BUFFERS_2048) + WOLFSSL_EVP_PKEY* privKey = NULL; + WOLFSSL_EVP_PKEY* pubKey = NULL; + const unsigned char testData[] = "Hi There"; + WOLFSSL_EVP_MD_CTX mdCtx; + int ret; + const unsigned char* cp; + const unsigned char* p; + unsigned char sig[2048/8]; + size_t sigSz; + + cp = client_key_der_2048; + ExpectNotNull((privKey = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL, &cp, + sizeof_client_key_der_2048))); + p = client_keypub_der_2048; + ExpectNotNull((pubKey = wolfSSL_d2i_PUBKEY(NULL, &p, + sizeof_client_keypub_der_2048))); + + /* One-shot sign: query size first */ + wolfSSL_EVP_MD_CTX_init(&mdCtx); + ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, privKey), 1); + sigSz = 0; + ExpectIntEQ(wolfSSL_EVP_DigestSign(&mdCtx, NULL, &sigSz, testData, + (unsigned int)XSTRLEN((const char*)testData)), 1); + ExpectIntGT((int)sigSz, 0); + ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx); + ExpectIntEQ(ret, 1); + + /* One-shot sign: actually produce the signature */ + wolfSSL_EVP_MD_CTX_init(&mdCtx); + ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, privKey), 1); + sigSz = sizeof(sig); + ExpectIntEQ(wolfSSL_EVP_DigestSign(&mdCtx, sig, &sigSz, testData, + (unsigned int)XSTRLEN((const char*)testData)), 1); + ExpectIntGT((int)sigSz, 0); + ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx); + ExpectIntEQ(ret, 1); + + /* One-shot verify */ + wolfSSL_EVP_MD_CTX_init(&mdCtx); + ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, + wolfSSL_EVP_sha256(), NULL, pubKey), 1); + ExpectIntEQ(wolfSSL_EVP_DigestVerify(&mdCtx, sig, sigSz, testData, + (unsigned int)XSTRLEN((const char*)testData)), 1); + ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx); + ExpectIntEQ(ret, 1); + + /* One-shot sign + verify with NULL ctx should fail */ + ExpectIntEQ(wolfSSL_EVP_DigestSign(NULL, sig, &sigSz, testData, + (unsigned int)XSTRLEN((const char*)testData)), + WOLFSSL_FAILURE); + ExpectIntEQ(wolfSSL_EVP_DigestVerify(NULL, sig, sigSz, testData, + (unsigned int)XSTRLEN((const char*)testData)), + WOLFSSL_FAILURE); + + wolfSSL_EVP_PKEY_free(pubKey); + wolfSSL_EVP_PKEY_free(privKey); +#endif + return EXPECT_RESULT(); +} + + +int test_wolfSSL_EVP_DigestSign_ecc(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) + WOLFSSL_EVP_PKEY* privKey = NULL; + WOLFSSL_EVP_PKEY* pubKey = NULL; + const unsigned char testData[] = "ECC one-shot test"; + WOLFSSL_EVP_MD_CTX mdCtx; + int ret; + const unsigned char* cp; + const unsigned char* p; + unsigned char sig[256]; + size_t sigSz; + + cp = ecc_clikey_der_256; + ExpectNotNull(privKey = wolfSSL_d2i_PrivateKey(EVP_PKEY_EC, NULL, &cp, + sizeof_ecc_clikey_der_256)); + p = ecc_clikeypub_der_256; + ExpectNotNull((pubKey = wolfSSL_d2i_PUBKEY(NULL, &p, + sizeof_ecc_clikeypub_der_256))); + + /* One-shot sign */ + wolfSSL_EVP_MD_CTX_init(&mdCtx); + ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(), + NULL, privKey), 1); + sigSz = sizeof(sig); + ExpectIntEQ(wolfSSL_EVP_DigestSign(&mdCtx, sig, &sigSz, testData, + (unsigned int)XSTRLEN((const char*)testData)), 1); + ExpectIntGT((int)sigSz, 0); + ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx); + ExpectIntEQ(ret, 1); + + /* One-shot verify */ + wolfSSL_EVP_MD_CTX_init(&mdCtx); + ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, + wolfSSL_EVP_sha256(), NULL, pubKey), 1); + ExpectIntEQ(wolfSSL_EVP_DigestVerify(&mdCtx, sig, sigSz, testData, + (unsigned int)XSTRLEN((const char*)testData)), 1); + ret = wolfSSL_EVP_MD_CTX_cleanup(&mdCtx); + ExpectIntEQ(ret, 1); + + wolfSSL_EVP_PKEY_free(pubKey); + wolfSSL_EVP_PKEY_free(privKey); +#endif + return EXPECT_RESULT(); +} + + int test_wolfSSL_EVP_PKEY_encrypt(void) { EXPECT_DECLS; diff --git a/tests/api/test_evp_pkey.h b/tests/api/test_evp_pkey.h index 7062e922a26..72c768f09e1 100644 --- a/tests/api/test_evp_pkey.h +++ b/tests/api/test_evp_pkey.h @@ -58,6 +58,8 @@ int test_wolfSSL_EVP_PKEY_sign_verify_ec(void); int test_wolfSSL_EVP_MD_rsa_signing(void); int test_wc_RsaPSS_DigitalSignVerify(void); int test_wolfSSL_EVP_MD_ecc_signing(void); +int test_wolfSSL_EVP_DigestSign(void); +int test_wolfSSL_EVP_DigestSign_ecc(void); int test_wolfSSL_EVP_PKEY_encrypt(void); int test_wolfSSL_EVP_PKEY_derive(void); int test_wolfSSL_EVP_PKEY_print_public(void); @@ -98,6 +100,8 @@ int test_wolfSSL_EVP_PKEY_print_public(void); TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_rsa_signing), \ TEST_DECL_GROUP("evp_pkey", test_wc_RsaPSS_DigitalSignVerify), \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_ecc_signing), \ + TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_DigestSign), \ + TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_DigestSign_ecc), \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_encrypt), \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_derive), \ TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_print_public) diff --git a/tests/api/test_tls.c b/tests/api/test_tls.c index aedae4f7031..7208addfbe4 100644 --- a/tests/api/test_tls.c +++ b/tests/api/test_tls.c @@ -31,6 +31,7 @@ #include #include #include +#include int test_utils_memio_move_message(void) @@ -1062,6 +1063,19 @@ int test_tls12_corrupted_finished(void) return EXPECT_RESULT(); } +int test_wolfSSL_alert_type_string(void) +{ + EXPECT_DECLS; +#if !defined(NO_TLS) && defined(OPENSSL_EXTRA) + ExpectStrEQ(wolfSSL_alert_type_string(alert_warning), "W"); + ExpectStrEQ(wolfSSL_alert_type_string(alert_fatal), "F"); + ExpectStrEQ(wolfSSL_alert_type_string(0), "U"); + ExpectStrEQ(wolfSSL_alert_type_string(-1), "U"); + ExpectStrEQ(wolfSSL_alert_type_string(99), "U"); +#endif + return EXPECT_RESULT(); +} + /* Test the TLS 1.2 peerAuthGood fail-safe checks directly on both sides. * The client branch sets NO_PEER_VERIFY; the server branch returns a generic * fatal error from TICKET_SENT before sending its Finished. */ @@ -1121,3 +1135,43 @@ int test_tls12_peerauth_failsafe(void) #endif return EXPECT_RESULT(); } + +int test_wolfSSL_alert_desc_string(void) +{ + EXPECT_DECLS; +#if !defined(NO_TLS) && defined(OPENSSL_EXTRA) + ExpectStrEQ(wolfSSL_alert_desc_string(close_notify), "CN"); + ExpectStrEQ(wolfSSL_alert_desc_string(unexpected_message), "UM"); + ExpectStrEQ(wolfSSL_alert_desc_string(bad_record_mac), "BM"); + ExpectStrEQ(wolfSSL_alert_desc_string(record_overflow), "RO"); + ExpectStrEQ(wolfSSL_alert_desc_string(decompression_failure), "DF"); + ExpectStrEQ(wolfSSL_alert_desc_string(handshake_failure), "HF"); + ExpectStrEQ(wolfSSL_alert_desc_string(no_certificate), "NC"); + ExpectStrEQ(wolfSSL_alert_desc_string(bad_certificate), "BC"); + ExpectStrEQ(wolfSSL_alert_desc_string(unsupported_certificate), "UC"); + ExpectStrEQ(wolfSSL_alert_desc_string(certificate_revoked), "CR"); + ExpectStrEQ(wolfSSL_alert_desc_string(certificate_expired), "CE"); + ExpectStrEQ(wolfSSL_alert_desc_string(certificate_unknown), "CU"); + ExpectStrEQ(wolfSSL_alert_desc_string(illegal_parameter), "IP"); + ExpectStrEQ(wolfSSL_alert_desc_string(unknown_ca), "CA"); + ExpectStrEQ(wolfSSL_alert_desc_string(access_denied), "AD"); + ExpectStrEQ(wolfSSL_alert_desc_string(decode_error), "DE"); + ExpectStrEQ(wolfSSL_alert_desc_string(decrypt_error), "DC"); + ExpectStrEQ(wolfSSL_alert_desc_string(wolfssl_alert_protocol_version), "PV"); + ExpectStrEQ(wolfSSL_alert_desc_string(insufficient_security), "IS"); + ExpectStrEQ(wolfSSL_alert_desc_string(internal_error), "IE"); + ExpectStrEQ(wolfSSL_alert_desc_string(inappropriate_fallback), "IF"); + ExpectStrEQ(wolfSSL_alert_desc_string(user_canceled), "US"); + ExpectStrEQ(wolfSSL_alert_desc_string(no_renegotiation), "NR"); + ExpectStrEQ(wolfSSL_alert_desc_string(missing_extension), "ME"); + ExpectStrEQ(wolfSSL_alert_desc_string(unsupported_extension), "UE"); + ExpectStrEQ(wolfSSL_alert_desc_string(unrecognized_name), "UN"); + ExpectStrEQ(wolfSSL_alert_desc_string(bad_certificate_status_response), "BR"); + ExpectStrEQ(wolfSSL_alert_desc_string(unknown_psk_identity), "UP"); + ExpectStrEQ(wolfSSL_alert_desc_string(certificate_required), "CQ"); + ExpectStrEQ(wolfSSL_alert_desc_string(no_application_protocol), "AP"); + /* Unknown alert description returns "UK" */ + ExpectStrEQ(wolfSSL_alert_desc_string(255), "UK"); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_tls.h b/tests/api/test_tls.h index c0f74f21505..e5f69aff13d 100644 --- a/tests/api/test_tls.h +++ b/tests/api/test_tls.h @@ -35,6 +35,8 @@ int test_tls12_etm_failed_resumption(void); int test_tls_set_curves_list_ecc_fallback(void); int test_tls12_corrupted_finished(void); int test_tls12_peerauth_failsafe(void); +int test_wolfSSL_alert_type_string(void); +int test_wolfSSL_alert_desc_string(void); #define TEST_TLS_DECLS \ TEST_DECL_GROUP("tls", test_utils_memio_move_message), \ @@ -49,6 +51,8 @@ int test_tls12_peerauth_failsafe(void); TEST_DECL_GROUP("tls", test_tls12_etm_failed_resumption), \ TEST_DECL_GROUP("tls", test_tls_set_curves_list_ecc_fallback), \ TEST_DECL_GROUP("tls", test_tls12_corrupted_finished), \ - TEST_DECL_GROUP("tls", test_tls12_peerauth_failsafe) + TEST_DECL_GROUP("tls", test_tls12_peerauth_failsafe), \ + TEST_DECL_GROUP("tls", test_wolfSSL_alert_type_string), \ + TEST_DECL_GROUP("tls", test_wolfSSL_alert_desc_string) #endif /* TESTS_API_TEST_TLS_H */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index a5ed4eda9d2..6d1009bbfa9 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -4950,6 +4950,25 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, return ret; } +int wolfSSL_EVP_DigestSign(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen, const unsigned char *tbs, + size_t tbslen) +{ + WOLFSSL_ENTER("EVP_DigestSign"); + + if (ctx == NULL || siglen == NULL) + return WOLFSSL_FAILURE; + + if (sigret != NULL) { + if (tbs == NULL) + return WOLFSSL_FAILURE; + if (wolfSSL_EVP_DigestSignUpdate(ctx, tbs, (unsigned int)tbslen) + != WOLFSSL_SUCCESS) + return WOLFSSL_FAILURE; + } + return wolfSSL_EVP_DigestSignFinal(ctx, sigret, siglen); +} + int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx, WOLFSSL_EVP_PKEY_CTX **pctx, const WOLFSSL_EVP_MD *type, @@ -5044,6 +5063,21 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, return WOLFSSL_FAILURE; } +int wolfSSL_EVP_DigestVerify(WOLFSSL_EVP_MD_CTX *ctx, + const unsigned char *sigret, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + WOLFSSL_ENTER("EVP_DigestVerify"); + + if (ctx == NULL || sigret == NULL || tbs == NULL) + return WOLFSSL_FAILURE; + + if (wolfSSL_EVP_DigestVerifyUpdate(ctx, tbs, tbslen) != WOLFSSL_SUCCESS) + return WOLFSSL_FAILURE; + + return wolfSSL_EVP_DigestVerifyFinal(ctx, sigret, siglen); +} + #ifdef WOLFSSL_APACHE_HTTPD #if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32) diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 2117d0be7fc..57f6eac3d17 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -844,11 +844,19 @@ WOLFSSL_API int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d, unsigned int cnt); WOLFSSL_API int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen); +WOLFSSL_API int wolfSSL_EVP_DigestSign(WOLFSSL_EVP_MD_CTX *ctx, + unsigned char *sigret, size_t *siglen, + const unsigned char *tbs, size_t tbslen); WOLFSSL_API int wolfSSL_EVP_DigestVerifyUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d, size_t cnt); WOLFSSL_API int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen); +WOLFSSL_API int wolfSSL_EVP_DigestVerify(WOLFSSL_EVP_MD_CTX *ctx, + const unsigned char *sigret, + size_t siglen, + const unsigned char *tbs, + size_t tbslen); WOLFSSL_API int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type, const WOLFSSL_EVP_MD* md, const byte* salt, @@ -1290,9 +1298,11 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_DigestSignInit wolfSSL_EVP_DigestSignInit #define EVP_DigestSignUpdate wolfSSL_EVP_DigestSignUpdate #define EVP_DigestSignFinal wolfSSL_EVP_DigestSignFinal +#define EVP_DigestSign wolfSSL_EVP_DigestSign #define EVP_DigestVerifyInit wolfSSL_EVP_DigestVerifyInit #define EVP_DigestVerifyUpdate wolfSSL_EVP_DigestVerifyUpdate #define EVP_DigestVerifyFinal wolfSSL_EVP_DigestVerifyFinal +#define EVP_DigestVerify wolfSSL_EVP_DigestVerify #define EVP_BytesToKey wolfSSL_EVP_BytesToKey #define EVP_get_cipherbyname wolfSSL_EVP_get_cipherbyname diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 4e586d5bf8a..46bd3576dec 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2594,7 +2594,9 @@ WOLFSSL_API unsigned long wolfSSL_ERR_peek_error(void); WOLFSSL_API int wolfSSL_GET_REASON(int); WOLFSSL_API const char* wolfSSL_alert_type_string_long(int alertID); +WOLFSSL_API const char* wolfSSL_alert_type_string(int alertID); WOLFSSL_API const char* wolfSSL_alert_desc_string_long(int alertID); +WOLFSSL_API const char* wolfSSL_alert_desc_string(int alertID); WOLFSSL_API const char* wolfSSL_state_string_long(const WOLFSSL* ssl); WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long e,