From 0717135e49e18252ae7e323301f03b861b6baa77 Mon Sep 17 00:00:00 2001 From: Hayden Roche Date: Thu, 7 Apr 2022 13:07:10 -0700 Subject: [PATCH] Add wolfSSL_EC_KEY_print_fp to compat layer. --- src/ssl.c | 184 ++++++++++++++++++++++++++++++------------- tests/api.c | 34 ++++++++ wolfssl/openssl/ec.h | 5 ++ 3 files changed, 170 insertions(+), 53 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index cc7a65aef..14b8941eb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18716,6 +18716,137 @@ WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx) #ifdef OPENSSL_EXTRA +#if defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ + !defined(NO_STDIO_FILESYSTEM) && (!defined(NO_RSA) || !defined(NO_DSA) || \ + defined(HAVE_ECC)) +/* Print the number bn in hex with name field and indentation indent to file fp. + * Used by wolfSSL_DSA_print_fp and wolfSSL_RSA_print_fp to print DSA and RSA + * keys and parameters. + */ +static int PrintBNFieldFp(XFILE fp, int indent, const char* field, + const WOLFSSL_BIGNUM* bn) { + static const int HEX_INDENT = 4; + static const int MAX_DIGITS_PER_LINE = 30; + + int ret = WOLFSSL_SUCCESS; + int i = 0; + char* buf = NULL; + + if (fp == XBADFILE || indent < 0 || field == NULL || bn == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == WOLFSSL_SUCCESS) { + buf = wolfSSL_BN_bn2hex(bn); + if (buf == NULL) { + ret = WOLFSSL_FAILURE; + } + } + if (ret == WOLFSSL_SUCCESS) { + XFPRINTF(fp, "%*s", indent, ""); + XFPRINTF(fp, "%s:\n", field); + XFPRINTF(fp, "%*s", indent + HEX_INDENT, ""); + while (buf[i]) { + if (i != 0) { + if (i % 2 == 0) { + XFPRINTF(fp, ":"); + } + if (i % MAX_DIGITS_PER_LINE == 0) { + XFPRINTF(fp, "\n"); + XFPRINTF(fp, "%*s", indent + HEX_INDENT, ""); + } + } + XFPRINTF(fp, "%c", buf[i++]); + } + XFPRINTF(fp, "\n"); + } + + if (buf != NULL) { + XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL); + } + + return ret; +} +#endif /* XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM && (!NO_DSA || + !NO_RSA || HAVE_ECC)*/ + +#if defined(HAVE_ECC) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ + !defined(NO_STDIO_FILESYSTEM) +int wolfSSL_EC_KEY_print_fp(XFILE fp, WOLFSSL_EC_KEY* key, int indent) +{ + int ret = WOLFSSL_SUCCESS; + int bits = 0; + int priv = 0; + int nid = 0; + const char* curve; + const char* nistName; + WOLFSSL_BIGNUM* pubBn = NULL; + + WOLFSSL_ENTER("wolfSSL_EC_KEY_print_fp"); + + if (fp == XBADFILE || key == NULL || key->group == NULL || indent < 0) { + ret = WOLFSSL_FAILURE; + } + + if (ret == WOLFSSL_SUCCESS) { + bits = wolfSSL_EC_GROUP_order_bits(key->group); + if (bits <= 0) { + WOLFSSL_MSG("Failed to get group order bits."); + ret = WOLFSSL_FAILURE; + } + } + if (ret == WOLFSSL_SUCCESS) { + XFPRINTF(fp, "%*s", indent, ""); + if (key->priv_key != NULL && !wolfSSL_BN_is_zero(key->priv_key)) { + XFPRINTF(fp, "Private-Key: (%d bit)\n", bits); + priv = 1; + } + else { + XFPRINTF(fp, "Public-Key: (%d bit)\n", bits); + } + + if (priv) { + ret = PrintBNFieldFp(fp, indent, "priv", key->priv_key); + } + } + if (ret == WOLFSSL_SUCCESS && key->pub_key != NULL && key->pub_key->exSet) { + pubBn = wolfSSL_EC_POINT_point2bn(key->group, key->pub_key, + POINT_CONVERSION_UNCOMPRESSED, NULL, + NULL); + if (pubBn == NULL) { + WOLFSSL_MSG("wolfSSL_EC_POINT_point2bn failed."); + ret = WOLFSSL_FAILURE; + } + else { + ret = PrintBNFieldFp(fp, indent, "pub", pubBn); + } + } + if (ret == WOLFSSL_SUCCESS) { + nid = wolfSSL_EC_GROUP_get_curve_name(key->group); + if (nid > 0) { + curve = wolfSSL_OBJ_nid2ln(nid); + if (curve != NULL) { + XFPRINTF(fp, "%*s", indent, ""); + XFPRINTF(fp, "ASN1 OID: %s\n", curve); + } + nistName = wolfSSL_EC_curve_nid2nist(nid); + if (nistName != NULL) { + XFPRINTF(fp, "%*s", indent, ""); + XFPRINTF(fp, "NIST CURVE: %s\n", nistName); + } + } + } + + if (pubBn != NULL) { + wolfSSL_BN_free(pubBn); + } + + WOLFSSL_LEAVE("wolfSSL_EC_KEY_print_fp", ret); + + return ret; +} +#endif /* HAVE_ECC && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */ + #if defined(OPENSSL_ALL) void *wolfSSL_lh_retrieve(WOLFSSL_STACK *sk, void *data) @@ -27364,59 +27495,6 @@ WOLFSSL_DH* wolfSSL_DH_get_2048_256(void) #endif /* NO_DH */ #endif /* OPENSSL_EXTRA */ -#if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ - !defined(NO_STDIO_FILESYSTEM) && (!defined(NO_RSA) || !defined(NO_DSA)) -/* Print the number bn in hex with name field and indentation indent to file fp. - * Used by wolfSSL_DSA_print_fp and wolfSSL_RSA_print_fp to print DSA and RSA - * keys and parameters. - */ -static int PrintBNFieldFp(XFILE fp, int indent, const char* field, - const WOLFSSL_BIGNUM* bn) { - static const int HEX_INDENT = 4; - static const int MAX_DIGITS_PER_LINE = 30; - - int ret = WOLFSSL_SUCCESS; - int i = 0; - char* buf = NULL; - - if (fp == XBADFILE || indent < 0 || field == NULL || bn == NULL) { - ret = BAD_FUNC_ARG; - } - - if (ret == WOLFSSL_SUCCESS) { - buf = wolfSSL_BN_bn2hex(bn); - if (buf == NULL) { - ret = WOLFSSL_FAILURE; - } - } - if (ret == WOLFSSL_SUCCESS) { - XFPRINTF(fp, "%*s", indent, ""); - XFPRINTF(fp, "%s:\n", field); - XFPRINTF(fp, "%*s", indent + HEX_INDENT, ""); - while (buf[i]) { - if (i != 0) { - if (i % 2 == 0) { - XFPRINTF(fp, ":"); - } - if (i % MAX_DIGITS_PER_LINE == 0) { - XFPRINTF(fp, "\n"); - XFPRINTF(fp, "%*s", indent + HEX_INDENT, ""); - } - } - XFPRINTF(fp, "%c", buf[i++]); - } - XFPRINTF(fp, "\n"); - } - - if (buf != NULL) { - XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL); - } - - return ret; -} -#endif /* OPENSSL_EXTRA && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM - * && (!NO_DSA || !NO_RSA)*/ - #ifndef NO_DSA #if defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ !defined(NO_STDIO_FILESYSTEM) diff --git a/tests/api.c b/tests/api.c index f59f61364..820c7c082 100644 --- a/tests/api.c +++ b/tests/api.c @@ -45157,6 +45157,39 @@ static void test_wolfSSL_EC_KEY_set_conv_form(void) #endif } +static void test_wolfSSL_EC_KEY_print_fp(void) +{ +#if defined(HAVE_ECC) && ((defined(HAVE_ECC224) && defined(HAVE_ECC256)) || \ + defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256 && \ + defined(OPENSSL_EXTRA) && defined(XFPRINTF) && !defined(NO_FILESYSTEM) && \ + !defined(NO_STDIO_FILESYSTEM) + EC_KEY* key = NULL; + + printf(testingFmt, "test_wolfSSL_EC_KEY_print_fp"); + + /* Bad file pointer. */ + AssertIntEQ(wolfSSL_EC_KEY_print_fp(NULL, key, 0), WOLFSSL_FAILURE); + /* NULL key. */ + AssertIntEQ(wolfSSL_EC_KEY_print_fp(stdout, NULL, 0), WOLFSSL_FAILURE); + AssertNotNull((key = wolfSSL_EC_KEY_new_by_curve_name(NID_secp224r1))); + /* Negative indent. */ + AssertIntEQ(wolfSSL_EC_KEY_print_fp(stdout, key, -1), WOLFSSL_FAILURE); + + AssertIntEQ(wolfSSL_EC_KEY_print_fp(stdout, key, 4), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_EC_KEY_generate_key(key), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_EC_KEY_print_fp(stdout, key, 4), WOLFSSL_SUCCESS); + wolfSSL_EC_KEY_free(key); + + AssertNotNull((key = wolfSSL_EC_KEY_new_by_curve_name( + NID_X9_62_prime256v1))); + AssertIntEQ(wolfSSL_EC_KEY_generate_key(key), WOLFSSL_SUCCESS); + AssertIntEQ(wolfSSL_EC_KEY_print_fp(stdout, key, 4), WOLFSSL_SUCCESS); + wolfSSL_EC_KEY_free(key); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_X509V3_EXT_get(void) { #if !defined(NO_FILESYSTEM) && defined(OPENSSL_ALL) && !defined(NO_RSA) FILE* f; @@ -53781,6 +53814,7 @@ void ApiTest(void) test_ENGINE_cleanup(); test_wolfSSL_EC_KEY_set_group(); test_wolfSSL_EC_KEY_set_conv_form(); + test_wolfSSL_EC_KEY_print_fp(); #if defined(OPENSSL_ALL) test_wolfSSL_X509_PUBKEY_get(); test_wolfSSL_sk_CIPHER_description(); diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 2d79a5925..7ebfce8e0 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -223,6 +223,10 @@ WOLFSSL_API int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, const WOLFSSL_EC_POINT *pub); WOLFSSL_API int wolfSSL_EC_KEY_check_key(const WOLFSSL_EC_KEY *key); +#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) +WOLFSSL_API int wolfSSL_EC_KEY_print_fp(XFILE fp, WOLFSSL_EC_KEY* key, + int indent); +#endif /* !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM */ WOLFSSL_API int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key); WOLFSSL_API int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, int digestSz, unsigned char *sig, @@ -329,6 +333,7 @@ typedef WOLFSSL_EC_BUILTIN_CURVE EC_builtin_curve; #define EC_KEY_set_asn1_flag wolfSSL_EC_KEY_set_asn1_flag #define EC_KEY_set_public_key wolfSSL_EC_KEY_set_public_key #define EC_KEY_check_key wolfSSL_EC_KEY_check_key +#define EC_KEY_print_fp wolfSSL_EC_KEY_print_fp #define ECDSA_size wolfSSL_ECDSA_size #define ECDSA_sign wolfSSL_ECDSA_sign