diff --git a/src/ssl.c b/src/ssl.c index 8f5beeaf4..84536540c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11884,20 +11884,61 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return WOLFSSL_SUCCESS; } - #ifndef NO_WOLFSSL_STUB - WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long bits, + + /* Generates a RSA key of length len + * + * len length of RSA key i.e. 2048 + * e e to use when generating RSA key + * f callback function for generation details + * data user callback argument + * + * Note: Because of wc_MakeRsaKey an RSA key size generated can be slightly + * rounded down. For example generating a key of size 2999 with e = + * 65537 will make a key of size 374 instead of 375. + * Returns a new RSA key on success and NULL on failure + */ + WOLFSSL_RSA* wolfSSL_RSA_generate_key(int len, unsigned long e, void(*f)(int, int, void*), void* data) { - /* no tmp key needed, actual generation not supported */ - WOLFSSL_STUB("RSA_generate_key"); - WOLFSSL_ENTER("RSA_generate_key"); - (void)len; - (void)bits; + WOLFSSL_RSA* rsa = NULL; + WOLFSSL_BIGNUM* bn = NULL; + + WOLFSSL_ENTER("wolfSSL_RSA_generate_key"); + (void)f; (void)data; - return NULL; + + if (len < 0) { + WOLFSSL_MSG("Bad argument: length was less than 0"); + return NULL; + } + + bn = wolfSSL_BN_new(); + if (bn == NULL) { + WOLFSSL_MSG("Error creating big number"); + return NULL; + } + + if (wolfSSL_BN_set_word(bn, (WOLFSSL_BN_ULONG)e) != SSL_SUCCESS) { + WOLFSSL_MSG("Error using e value"); + wolfSSL_BN_free(bn); + return NULL; + } + + rsa = wolfSSL_RSA_new(); + if (rsa == NULL) { + WOLFSSL_MSG("memory error"); + } + else { + if (wolfSSL_RSA_generate_key_ex(rsa, len, bn, NULL) != SSL_SUCCESS){ + wolfSSL_RSA_free(rsa); + rsa = NULL; + } + } + wolfSSL_BN_free(bn); + + return rsa; } - #endif #ifndef NO_CERTS @@ -21683,6 +21724,33 @@ int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w) return WOLFSSL_SUCCESS; } + +/* Returns the big number as an unsigned long if possible. + * + * bn big number structure to get value from + * + * Returns value or 0xFFFFFFFFL if bigger than unsigned long. + */ +unsigned long wolfSSL_BN_get_word(const WOLFSSL_BIGNUM* bn) +{ + mp_int* mp; + + WOLFSSL_MSG("wolfSSL_BN_get_word"); + + if (bn == NULL) { + WOLFSSL_MSG("Invalid argument"); + return 0; + } + + if (wolfSSL_BN_num_bytes(bn) > (int)sizeof(unsigned long)) { + WOLFSSL_MSG("bignum is larger than unsigned long"); + return 0xFFFFFFFFL; + } + mp = (mp_int*)bn->internal; + + return (unsigned long)(mp->dp[0]); +} + /* return code compliant with OpenSSL : * number length in decimal if success, 0 if error */ @@ -22957,7 +23025,6 @@ int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn, int ret = WOLFSSL_FAILURE; (void)cb; - (void)bn; (void)bits; WOLFSSL_ENTER("wolfSSL_RSA_generate_key_ex"); @@ -22984,8 +23051,8 @@ int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn, if (wc_InitRng(rng) < 0) WOLFSSL_MSG("RNG init failed"); - else if (wc_MakeRsaKey((RsaKey*)rsa->internal, - bits, WC_RSA_EXPONENT, rng) != MP_OKAY) + else if (wc_MakeRsaKey((RsaKey*)rsa->internal, bits, + wolfSSL_BN_get_word(bn), rng) != MP_OKAY) WOLFSSL_MSG("wc_MakeRsaKey failed"); else if (SetRsaExternal(rsa) != WOLFSSL_SUCCESS) WOLFSSL_MSG("SetRsaExternal failed"); @@ -29429,6 +29496,9 @@ int wolfSSL_CIPHER_get_bits(const WOLFSSL_CIPHER *c, int *alg_bits) #endif /* #if defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)) */ +/* stunnel compatibility functions*/ +#if defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)) + int wolfSSL_sk_X509_NAME_num(const WOLF_STACK_OF(WOLFSSL_X509_NAME) *s) { WOLFSSL_ENTER("wolfSSL_sk_X509_NAME_num"); @@ -29448,9 +29518,6 @@ int wolfSSL_sk_X509_num(const WOLF_STACK_OF(WOLFSSL_X509) *s) return (int)s->num; } -/* stunnel compatibility functions*/ -#if defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX)) - int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, int indent, unsigned long flags) { diff --git a/tests/api.c b/tests/api.c index 9142151e6..11eec2114 100644 --- a/tests/api.c +++ b/tests/api.c @@ -14635,6 +14635,13 @@ static void test_wolfSSL_BN(void) AssertIntEQ((int)(value[0] & 0x03), 3); BN_free(val); + AssertIntEQ(BN_set_word(a, 1), SSL_SUCCESS); + AssertIntEQ(BN_set_word(b, 5), SSL_SUCCESS); + AssertIntEQ(BN_sub(c, a, b), SSL_SUCCESS); + AssertNotNull(BN_bn2dec(c)); + AssertIntEQ(XMEMCMP(BN_bn2dec(c), "-4", sizeof("-4")), 0); + AssertIntEQ(BN_get_word(c), 4); + BN_free(a); BN_free(b); BN_free(c); @@ -15900,6 +15907,33 @@ static void test_wolfSSL_MD4(void) #endif } + +static void test_wolfSSL_RSA(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) + RSA* rsa; + + printf(testingFmt, "wolfSSL_RSA()"); + + AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); + AssertIntEQ(RSA_size(rsa), 256); + RSA_free(rsa); + + AssertNotNull(rsa = RSA_generate_key(3072, 17, NULL, NULL)); + AssertIntEQ(RSA_size(rsa), 384); + RSA_free(rsa); + + AssertNotNull(rsa = RSA_generate_key(2999, 65537, NULL, NULL)); + RSA_free(rsa); + + AssertNull(RSA_generate_key(-1, 3, NULL, NULL)); + AssertNull(RSA_generate_key(511, 3, NULL, NULL)); /* RSA_MIN_SIZE - 1 */ + AssertNull(RSA_generate_key(4097, 3, NULL, NULL)); /* RSA_MAX_SIZE + 1 */ + AssertNull(RSA_generate_key(2048, 0, NULL, NULL)); + + printf(resultFmt, passed); +#endif +} static void test_no_op_functions(void) { #if defined(OPENSSL_EXTRA) @@ -16722,6 +16756,7 @@ void ApiTest(void) test_wolfSSL_DES_ecb_encrypt(); test_wolfSSL_sk_GENERAL_NAME(); test_wolfSSL_MD4(); + test_wolfSSL_RSA(); /* test the no op functions for compatibility */ test_no_op_functions(); diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index 90fdba0a8..2572e75ca 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -95,6 +95,7 @@ WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); +WOLFSSL_API unsigned long wolfSSL_BN_get_word(const WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_add(WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*, WOLFSSL_BIGNUM*); @@ -151,6 +152,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_dup wolfSSL_BN_dup #define BN_copy wolfSSL_BN_copy +#define BN_get_word wolfSSL_BN_get_word #define BN_set_word wolfSSL_BN_set_word #define BN_dec2bn wolfSSL_BN_dec2bn