diff --git a/certs/dh-pubkey-2048.der b/certs/dh-pubkey-2048.der new file mode 100644 index 0000000000..d364fce37b Binary files /dev/null and b/certs/dh-pubkey-2048.der differ diff --git a/certs/dsa-pubkey-2048.der b/certs/dsa-pubkey-2048.der new file mode 100644 index 0000000000..222251fda1 Binary files /dev/null and b/certs/dsa-pubkey-2048.der differ diff --git a/certs/include.am b/certs/include.am index c7e70ad1ac..eb930e1dcf 100644 --- a/certs/include.am +++ b/certs/include.am @@ -68,11 +68,13 @@ EXTRA_DIST += \ certs/dh2048.der \ certs/dh3072.der \ certs/dh4096.der \ + certs/dh-pubkey-2048.der \ certs/rsa2048.der \ certs/rsa-pub-2048.pem \ certs/rsa3072.der \ certs/dsa2048.der \ certs/dsa3072.der \ + certs/dsa-pubkey-2048.der \ certs/ecc-client-key.der \ certs/ecc-client-keyPub.der \ certs/ecc-key.der \ diff --git a/gencertbuf.pl b/gencertbuf.pl index 6b71fffad5..d709bb7c89 100755 --- a/gencertbuf.pl +++ b/gencertbuf.pl @@ -67,6 +67,8 @@ my @fileList_2048 = ( [ "./certs/client-keyPub.der", "client_keypub_der_2048" ], [ "./certs/client-cert.der", "client_cert_der_2048" ], [ "./certs/dh2048.der", "dh_key_der_2048" ], + [ "./certs/dh-pubkey-2048.der", "dh_pub_key_der_2048" ], + [ "./certs/dsa-pubkey-2048.der", "dsa_pub_key_der_2048" ], [ "./certs/dsa2048.der", "dsa_key_der_2048" ], [ "./certs/rsa2048.der", "rsa_key_der_2048" ], [ "./certs/ca-key.der", "ca_key_der_2048" ], diff --git a/src/ssl.c b/src/ssl.c index ad8c9797c1..4da12f4b17 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8067,6 +8067,76 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY(WOLFSSL_EVP_PKEY** out, #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */ + #if !defined(NO_DH) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_DH_EXTRA) + #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION > 2)) + { + DhKey dh; + word32 keyIdx = 0; + DhKey* key = NULL; + int ret; + Element_Set elements; + /* test if DH-public key */ + if (wc_InitDhKey(&dh) != 0) + return NULL; + + ret = wc_DhPublicKeyDecode(mem, &keyIdx, &dh, (word32)memSz); + wc_FreeDhKey(&dh); + + if (ret == 0) { + pkey = wolfSSL_EVP_PKEY_new(); + if (pkey != NULL) { + pkey->type = EVP_PKEY_DH; + pkey->pkey_sz = (int)memSz; + pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL, + DYNAMIC_TYPE_PUBLIC_KEY); + if (pkey->pkey.ptr == NULL) { + wolfSSL_EVP_PKEY_free(pkey); + return NULL; + } + XMEMCPY(pkey->pkey.ptr, mem, memSz); + if (out != NULL) { + *out = pkey; + } + pkey->ownDh = 1; + pkey->dh = wolfSSL_DH_new(); + if (pkey->dh == NULL) { + wolfSSL_EVP_PKEY_free(pkey); + return NULL; + } + + key = (DhKey*)pkey->dh->internal; + + keyIdx = 0; + if (wc_DhPublicKeyDecode(mem, &keyIdx, key, (word32)memSz) == 0) + { + elements = ELEMENT_P | ELEMENT_G | ELEMENT_Q | ELEMENT_PUB; + if( SetDhExternal_ex(pkey->dh, elements) + == WOLFSSL_SUCCESS ){ + return pkey; + } + /* + if (SetIndividualExternal(&(pkey->dh->p), &key->p) + == WOLFSSL_SUCCESS && + SetIndividualExternal(&(pkey->dh->g), &key->g) + == WOLFSSL_SUCCESS && + SetIndividualExternal(&(pkey->dh->q), &key->q) + == WOLFSSL_SUCCESS && + SetIndividualExternal(&(pkey->dh->pub_key), &key->pub) + == WOLFSSL_SUCCESS) { + return pkey; + } */ + } + else { + wolfSSL_EVP_PKEY_free(pkey); + return NULL; + } + } + } + } + #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ + #endif /* !NO_DH && OPENSSL_EXTRA && WOLFSSL_DH_EXTRA */ + if (pkey == NULL) { WOLFSSL_MSG("wolfSSL_d2i_PUBKEY couldn't determine key type"); } @@ -33291,7 +33361,7 @@ int SetDhInternal(WOLFSSL_DH* dh) } #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) \ - || defined(WOLFSSL_OPENSSH)) + || defined(WOLFSSL_OPENSSH)) || defined(OPENSSL_EXTRA) #ifdef WOLFSSL_DH_EXTRA WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) @@ -33333,12 +33403,12 @@ WOLFSSL_DH* wolfSSL_DH_dup(WOLFSSL_DH* dh) #endif /* WOLFSSL_DH_EXTRA */ /* Set the members of DhKey into WOLFSSL_DH - * DhKey was populated from wc_DhKeyDecode + * Specify elements to set via the 2nd parmeter */ -int SetDhExternal(WOLFSSL_DH *dh) +int SetDhExternal_ex(WOLFSSL_DH *dh, int elm) { DhKey *key; - WOLFSSL_MSG("Entering SetDhExternal"); + WOLFSSL_MSG("Entering SetDhExternal_ex"); if (dh == NULL || dh->internal == NULL) { WOLFSSL_MSG("dh key NULL error"); @@ -33347,25 +33417,37 @@ int SetDhExternal(WOLFSSL_DH *dh) key = (DhKey*)dh->internal; - if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("dh param p error"); - return WOLFSSL_FATAL_ERROR; + if (elm & ELEMENT_P) { + if (SetIndividualExternal(&dh->p, &key->p) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("dh param p error"); + return WOLFSSL_FATAL_ERROR; + } } - - if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("dh param g error"); - return WOLFSSL_FATAL_ERROR; + if (elm & ELEMENT_Q) { + if (SetIndividualExternal(&dh->q, &key->q) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("dh param q error"); + return WOLFSSL_FATAL_ERROR; + } + } + if (elm & ELEMENT_G) { + if (SetIndividualExternal(&dh->g, &key->g) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("dh param g error"); + return WOLFSSL_FATAL_ERROR; + } } - #ifdef WOLFSSL_DH_EXTRA - if (SetIndividualExternal(&dh->priv_key, &key->priv) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("No DH Private Key"); - return WOLFSSL_FATAL_ERROR; + if (elm & ELEMENT_PRV) { + if (SetIndividualExternal(&dh->priv_key, &key->priv) != + WOLFSSL_SUCCESS) { + WOLFSSL_MSG("No DH Private Key"); + return WOLFSSL_FATAL_ERROR; + } } - - if (SetIndividualExternal(&dh->pub_key, &key->pub) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("No DH Public Key"); - return WOLFSSL_FATAL_ERROR; + if (elm & ELEMENT_PUB) { + if (SetIndividualExternal(&dh->pub_key, &key->pub) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("No DH Public Key"); + return WOLFSSL_FATAL_ERROR; + } } #endif /* WOLFSSL_DH_EXTRA */ @@ -33373,6 +33455,16 @@ int SetDhExternal(WOLFSSL_DH *dh) return WOLFSSL_SUCCESS; } +/* Set the members of DhKey into WOLFSSL_DH + * DhKey was populated from wc_DhKeyDecode + * p, g, pub_key and pri_key are set. + */ +int SetDhExternal(WOLFSSL_DH *dh) +{ + int elements = ELEMENT_P | ELEMENT_G | ELEMENT_PUB | ELEMENT_PRV; + WOLFSSL_MSG("Entering SetDhExternal"); + return SetDhExternal_ex(dh, elements); +} #endif /* !NO_DH && (WOLFSSL_QT || OPENSSL_ALL) */ /* return code compliant with OpenSSL : diff --git a/tests/api.c b/tests/api.c index 6aa52234cd..ad2ad6dc11 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2596,6 +2596,277 @@ static void test_ED448(void) | EVP *----------------------------------------------------------------------------*/ +static void test_wolfSSL_EVP_PKEY_print_public(void) +{ +#if defined(OPENSSL_EXTRA) + + WOLFSSL_BIO* rbio = NULL; + WOLFSSL_BIO* wbio = NULL; + WOLFSSL_EVP_PKEY* pkey = NULL; + char line[256] = { 0 }; + char line1[256] = { 0 }; + int i; + + printf(testingFmt, "EVP_PKEY_print_public()"); + /* test error cases */ + AssertIntEQ( EVP_PKEY_print_public(NULL,NULL,0,NULL),0L); + + /* + * test RSA public key print + * in this test, pass '3' for indent + */ +#if !defined(NO_RSA) && defined(USE_CERT_BUFFERS_1024) + + rbio = BIO_new_mem_buf( client_keypub_der_1024, + sizeof_client_keypub_der_1024); + AssertNotNull(rbio); + + wolfSSL_d2i_PUBKEY_bio(rbio, &pkey); + AssertNotNull(pkey); + + wbio = BIO_new(BIO_s_mem()); + AssertNotNull(wbio); + + AssertIntEQ(EVP_PKEY_print_public(wbio, pkey,3,NULL),1); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, " RSA Public-Key: (1024 bit)\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, " Modulus:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, " 00:BC:73:0E:A8:49:F3:74:A2:A9:EF:18:A5:DA:55:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + + /* skip to the end of modulus element*/ + for( i = 0; i < 8 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, " Exponent: 65537 (0x010001)\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + + /* should reach EOF */ + AssertIntLE(BIO_gets(wbio, line, sizeof(line)) ,0); + + EVP_PKEY_free(pkey); + pkey = NULL; + BIO_free(rbio); + BIO_free(wbio); + rbio = NULL; + wbio = NULL; + +#endif /* !NO_RSA && USE_CERT_BUFFERS_1024*/ + + /* + * test DSA public key print + */ +#if !defined(NO_DSA) && defined(USE_CERT_BUFFERS_2048) + rbio = BIO_new_mem_buf( dsa_pub_key_der_2048, + sizeof_dsa_pub_key_der_2048); + AssertNotNull(rbio); + + wolfSSL_d2i_PUBKEY_bio(rbio, &pkey); + AssertNotNull(pkey); + + wbio = BIO_new(BIO_s_mem()); + AssertNotNull(wbio); + + AssertIntEQ(EVP_PKEY_print_public(wbio, pkey,0,NULL),1); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "DSA Public-Key: (2048 bit)\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "pub:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, + " 00:C2:35:2D:EC:83:83:6C:73:13:9E:52:7C:74:C8:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + /* skip to the end of pub element*/ + for( i = 0; i < 17 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "P:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + /* skip to the end of P element*/ + for( i = 0; i < 18 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "Q:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + /* skip to the end of Q element*/ + for( i = 0; i < 3 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "G:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + /* skip to the end of G element*/ + for( i = 0; i < 18 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + /* should reach EOF */ + AssertIntLE(BIO_gets(wbio, line, sizeof(line)) ,0); + + EVP_PKEY_free(pkey); + pkey = NULL; + BIO_free(rbio); + BIO_free(wbio); + rbio = NULL; + wbio = NULL; + +#endif /* !NO_DSA && USE_CERT_BUFFERS_2048 */ + + /* + * test ECC public key print + */ +#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) + + rbio = BIO_new_mem_buf( ecc_clikeypub_der_256, + sizeof_ecc_clikeypub_der_256); + AssertNotNull(rbio); + + wolfSSL_d2i_PUBKEY_bio(rbio, &pkey); + AssertNotNull(pkey); + + wbio = BIO_new(BIO_s_mem()); + AssertNotNull(wbio); + + AssertIntEQ(EVP_PKEY_print_public(wbio, pkey,0,NULL),1); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "Public-Key: (256 bit)\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "pub:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, + " 04:55:BF:F4:0F:44:50:9A:3D:CE:9B:B7:F0:C5:4D:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + /* skip to the end of pub element*/ + for( i = 0; i < 4 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "ASN1 OID: prime256v1\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "NIST CURVE: P-256\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + + /* should reach EOF */ + AssertIntLE(BIO_gets(wbio, line, sizeof(line)) ,0); + + EVP_PKEY_free(pkey); + pkey = NULL; + BIO_free(rbio); + BIO_free(wbio); + rbio = NULL; + wbio = NULL; + +#endif /* HAVE_ECC && USE_CERT_BUFFERS_256 */ + + /* + * test DH public key print + */ +#if defined(WOLFSSL_DH_EXTRA) && defined(USE_CERT_BUFFERS_2048) + + rbio = BIO_new_mem_buf( dh_pub_key_der_2048, + sizeof_dh_pub_key_der_2048); + AssertNotNull(rbio); + + wolfSSL_d2i_PUBKEY_bio(rbio, &pkey); + AssertNotNull(pkey); + + wbio = BIO_new(BIO_s_mem()); + AssertNotNull(wbio); + + AssertIntEQ(EVP_PKEY_print_public(wbio, pkey,0,NULL),1); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "DH Public-Key: (2048 bit)\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "public-key:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, + " 34:41:BF:E9:F2:11:BF:05:DB:B2:72:A8:29:CC:BD:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + /* skip to the end of public-key element*/ + for( i = 0; i < 17 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "prime:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, + " 00:D3:B2:99:84:5C:0A:4C:E7:37:CC:FC:18:37:01:\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + /* skip to the end of prime element*/ + for( i = 0; i < 17 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + strcpy(line1, "generator: 2 (0x02)\n"); + AssertIntEQ(XSTRNCMP( line, line1, XSTRLEN(line1)), 0); + + /* should reach EOF */ + AssertIntLE(BIO_gets(wbio, line, sizeof(line)) ,0); + + EVP_PKEY_free(pkey); + pkey = NULL; + BIO_free(rbio); + BIO_free(wbio); + rbio = NULL; + wbio = NULL; + +#endif /* WOLFSSL_DH_EXTRA && USE_CERT_BUFFERS_2048 */ + + /* to prevent "unused variable" warning */ + (void)pkey; + (void)wbio; + (void)rbio; + (void)line; + (void)line1; + (void)i; + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA */ +} + /* Test function for wolfSSL_EVP_get_cipherbynid. */ @@ -23103,6 +23374,45 @@ static int test_wc_EccPrivateKeyToDer (void) return ret; }/* End test_wc_EccPrivateKeyToDer*/ +/* + * Testing wc_DhPublicKeyDecode + */ +static int test_wc_DhPublicKeyDecode(void) +{ + int ret = 0; + word32 inOutIdx; + +#if defined(WOLFSSL_DH_EXTRA) && defined(USE_CERT_BUFFERS_2048) + DhKey key; + AssertIntEQ(wc_InitDhKey(&key), 0); + printf(testingFmt, "wc_DhPublicKeyDecode()"); + + AssertIntEQ(wc_DhPublicKeyDecode(NULL,NULL,NULL,0), + BAD_FUNC_ARG); + AssertIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,NULL,NULL,0), + BAD_FUNC_ARG); + AssertIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,NULL,NULL,0), + BAD_FUNC_ARG); + inOutIdx = 0; + AssertIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,NULL, 0), + BAD_FUNC_ARG); + inOutIdx = 0; + AssertIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,&key, 0), + BAD_FUNC_ARG); + inOutIdx = 0; + AssertIntEQ(wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,&key, + sizeof_dh_pub_key_der_2048), 0); + AssertTrue(key.p.used != 0 && key.g.used != 0 && key.q.used == 0 && + key.pub.used != 0 && key.priv.used == 0); + + wc_FreeDhKey(&key); + printf(resultFmt, passed); + +#endif + (void)inOutIdx; + return ret; +} + /* * Testing wc_Ed25519KeyToDer */ @@ -33684,6 +33994,26 @@ static void test_wolfSSL_d2i_PUBKEY(void) EVP_PKEY_free(pkey); #endif +#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_DSA) + /* DSA PUBKEY test */ + AssertIntGT(BIO_write(bio, dsa_pub_key_der_2048, + sizeof_dsa_pub_key_der_2048), 0); + AssertNotNull(pkey = d2i_PUBKEY_bio(bio, NULL)); + EVP_PKEY_free(pkey); +#endif + +#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_DH) && \ +defined(OPENSSL_EXTRA) && defined(WOLFSSL_DH_EXTRA) +#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION > 2)) + /* DH PUBKEY test */ + AssertIntGT(BIO_write(bio, dh_pub_key_der_2048, + sizeof_dh_pub_key_der_2048), 0); + AssertNotNull(pkey = d2i_PUBKEY_bio(bio, NULL)); + EVP_PKEY_free(pkey); +#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ +#endif /* USE_CERT_BUFFERS_2048 && !NO_DH && && OPENSSL_EXTRA */ + BIO_free(bio); (void)pkey; @@ -43968,6 +44298,7 @@ void ApiTest(void) test_wolfSSL_EVP_MD_hmac_signing(); test_wolfSSL_EVP_MD_rsa_signing(); test_wolfSSL_EVP_MD_ecc_signing(); + test_wolfSSL_EVP_PKEY_print_public(); test_wolfSSL_CTX_add_extra_chain_cert(); #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) test_wolfSSL_ERR_peek_last_error_line(); @@ -44576,6 +44907,7 @@ void ApiTest(void) AssertIntEQ(test_ToTraditional(), 0); AssertIntEQ(test_wc_EccPrivateKeyToDer(), 0); + AssertIntEQ(test_wc_DhPublicKeyDecode(), 0); AssertIntEQ(test_wc_Ed25519KeyToDer(), 0); AssertIntEQ(test_wc_Ed25519PrivateKeyToDer(), 0); AssertIntEQ(test_wc_Ed448KeyToDer(), 0); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 64e8147c59..9213486efd 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4686,6 +4686,60 @@ int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, #endif /* !NO_RSA */ #ifndef NO_DH +#if defined(WOLFSSL_DH_EXTRA) +/* + * Decodes DH public key to fill specified DhKey. + * + * return 0 on success, negative on failure + */ +int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx, + DhKey* key, word32 inSz) +{ + int ret = 0; + int length; + word32 oid = 0; + + if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) + return BAD_FUNC_ARG; + + if (GetSequence(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + if (GetSequence(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + ret = GetObjectId(input, inOutIdx, &oid, oidKeyType, inSz); + if (oid != DHk || ret < 0) + return ASN_DH_KEY_E; + + if (GetSequence(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + if (GetInt(&key->p, input, inOutIdx, inSz) < 0) + return ASN_DH_KEY_E; + + if (GetInt(&key->g, input, inOutIdx, inSz) < 0) { + mp_clear(&key->p); + return ASN_DH_KEY_E; + } + ret = (CheckBitString(input, inOutIdx, &length, inSz, 0, NULL) == 0); + if (ret > 0) { + /* Found Bit String WOLFSSL_DH_EXTRA is required to access DhKey.pub */ + if (GetInt(&key->pub, input, inOutIdx, inSz) < 0) { + mp_clear(&key->p); + mp_clear(&key->g); + return ASN_DH_KEY_E; + } + } + else { + mp_clear(&key->p); + mp_clear(&key->g); + return ASN_DH_KEY_E; + } + return 0; +} +#endif /* WOLFSSL_DH_EXTRA */ + /* Supports either: * - DH params G/P (PKCS#3 DH) file or * - DH key file (if WOLFSSL_DH_EXTRA enabled) */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index b4c9cfb9fd..9338a24485 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -44,6 +44,7 @@ #include #include +#include #ifndef NO_AES #ifdef HAVE_AES_CBC @@ -176,6 +177,8 @@ static const char EVP_NULL[] = "NULL"; #define EVP_NULL_SIZE 4 +#define EVP_PKEY_PRINT_LINE_WIDTH_MAX 80 +#define EVP_PKEY_PRINT_DIGITS_PER_LINE 15 static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher); @@ -7145,6 +7148,887 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key) } } } +#if defined(OPENSSL_EXTRA) + +/* Indent writes white spaces of the number specified by "indents" + * to the BIO. The number of white spaces is limited from 0 to + * EVP_PKEY_PRINT_INDENT_MAX. + * returns the amount written to BIO. + */ +static int Indent(WOLFSSL_BIO* out, int indents) +{ + int i; + char space = ' '; + if (out == NULL) { + return 0; + } + if (indents > EVP_PKEY_PRINT_INDENT_MAX) { + indents = EVP_PKEY_PRINT_INDENT_MAX; + } + for (i = 0; i < indents; i++) { + if (wolfSSL_BIO_write(out, &space, 1) < 0) { + break; + } + } + return indents -i; +} +/* PrintHexWithColon dump byte-data specified by "input" to the "out". + * Each line has leading white spaces( "indent" gives the number ) plus + * four spaces, then hex coded 15 byte data with separator ":" follow. + * Each line looks like: + * " 00:e6:ab: --- 9f:ef:" + * Parmeters: + * out bio to output dump data + * input buffer holding data to dump + * inlen input data size + * indent the number of spaces for indent + * Returns 1 on success, 0 on failure. + */ +static int PrintHexWithColon(WOLFSSL_BIO* out, const byte* input, + int inlen, int indent) +{ +#ifdef WOLFSSL_SMALL_STACK + byte* buff = NULL; +#else + byte buff[EVP_PKEY_PRINT_LINE_WIDTH_MAX] = { 0 }; +#endif /* WOLFSSL_SMALL_STACK */ + int ret = WOLFSSL_SUCCESS; + word32 in = 0; + word32 i; + int idx; + const byte* data; + word32 outSz; + byte outHex[3]; + + if (!out || !input || inlen <= 0) { + return WOLFSSL_FAILURE; + } + + if (indent < 0) { + indent = 0; + } + if (indent > EVP_PKEY_PRINT_INDENT_MAX) { + indent = EVP_PKEY_PRINT_INDENT_MAX; + } + + data = input; + +#ifdef WOLFSSL_SMALL_STACK + buff = (byte*)XMALLOC(EVP_PKEY_PRINT_LINE_WIDTH_MAX, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (!buff) { + return WOLFSSL_FAILURE; + } +#endif + + /* print pub element */ + idx = 0; + + for (in = 0; in < (word32)inlen && ret == WOLFSSL_SUCCESS; in += + EVP_PKEY_PRINT_DIGITS_PER_LINE ) { + Indent(out, indent); + for (i = 0; (i < EVP_PKEY_PRINT_DIGITS_PER_LINE) && + (in + i < (word32)inlen); i++) { + + if (ret == WOLFSSL_SUCCESS) { + outSz = sizeof(outHex); + ret = Base16_Encode((const byte*)&data[in + i], 1, + outHex, &outSz) == 0; + } + if (ret == WOLFSSL_SUCCESS) { + XMEMCPY(buff + idx, outHex, 2); + idx += 2; + + if (in + i != (word32)inlen -1) { + XMEMSET(buff + idx, ':', 1); + idx += 1; + } + } + } + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_BIO_write(out, buff, idx) > 0; + } + if (ret == WOLFSSL_SUCCESS) { + ret = wolfSSL_BIO_write(out, "\n", 1) > 0; + } + if (ret == WOLFSSL_SUCCESS) { + XMEMSET(buff, 0, EVP_PKEY_PRINT_LINE_WIDTH_MAX); + idx = 0; + } + } +#ifdef WOLFSSL_SMALL_STACK + XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return ret; +} +#if !defined(NO_RSA) +/* PrintPubKeyRSA is a helper function for wolfSSL_EVP_PKEY_print_public + * to parse a DER format RSA public key specified in the second parameter. + * Parameters: + * out bio to output dump data + * pkey buffer holding public key data + * pkeySz public key data size + * indent the number of spaces for indent + * bitlen bit size of the given key + * pctx context(not used) + * Returns 1 on success, 0 on failure. +*/ +static int PrintPubKeyRSA(WOLFSSL_BIO* out, const byte* pkey, int pkeySz, + int indent, int bitlen, ASN1_PCTX* pctx) +{ + byte buff[8] = { 0 }; + word32 inOutIdx = 0; + word32 nSz; /* size of modulus */ + word32 eSz; /* size of public exponent */ + const byte* n = NULL; + const byte* e = NULL; /* pointer to modulus/exponent */ + int idx; + int wsz; + word32 i; + unsigned long exponent = 0; + mp_int a; + char line[32] = { 0 }; + + (void)pctx; + + if( mp_init(&a) != 0) { + return WOLFSSL_FAILURE; + } + if (indent < 0) { + indent = 0; + } + if (indent > EVP_PKEY_PRINT_INDENT_MAX) { + indent = EVP_PKEY_PRINT_INDENT_MAX; + } + /* parse key to get modulus and exponent */ + if (wc_RsaPublicKeyDecode_ex(pkey, &inOutIdx, pkeySz, + &n, &nSz, &e, &eSz) != 0) { + return WOLFSSL_FAILURE; + } + + /* print out public key elements */ + idx = 0; + XMEMSET(buff, 0, sizeof(buff)); + Indent(out, indent); + XSTRNCPY(line, "RSA Public-Key: (", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (mp_set_int(&a, bitlen) != 0) { + return WOLFSSL_FAILURE; + } + if (mp_todecimal(&a, (char*)buff) != 0) { + return WOLFSSL_FAILURE; + } + wsz = (int)XSTRLEN((const char*)buff); + + if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) { + return WOLFSSL_FAILURE; + } + XSTRNCPY(line, " bit)\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + /* print Modulus */ + Indent(out, indent); + XSTRNCPY(line, "Modulus:\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + + /* print modulus with leading zero if exists */ + if (*n & 0x80 && *(n-1) == 0) { + n--; + nSz++; + } + if (PrintHexWithColon(out, n, nSz, indent + 4) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + /* print public Exponent */ + idx = 0; + Indent(out, indent); + XSTRNCPY(line, "Exponent: ", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + for (i = 0; i < eSz; i++) { + exponent <<= 8; + exponent += e[i]; + } + + XMEMSET(buff, 0, sizeof(buff)); + if (mp_set_int(&a, exponent) != 0) { + return WOLFSSL_FAILURE; + } + if (mp_todecimal(&a, (char*)buff) != 0) { + return WOLFSSL_FAILURE; + } + wsz = (int)XSTRLEN((const char*)buff); + + if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) { + return WOLFSSL_FAILURE; + } + XSTRNCPY(line, " (0x", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + XMEMSET(buff, 0, sizeof(buff)); + if (mp_tohex(&a, (char*)buff) != 0) { + return WOLFSSL_FAILURE; + } + if (wolfSSL_BIO_write(out, buff, (int)XSTRLEN((const char*)buff)) <= 0) { + return WOLFSSL_FAILURE; + } + XSTRNCPY(line, ")\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; +} +#endif /* !NO_RSA */ + +#if defined(HAVE_ECC) +/* PrintPubKeyEC is a helper function for wolfSSL_EVP_PKEY_print_public + * to parse a DER format ECC public key specified in the second parameter. + * Parameters: + * out bio to output dump data + * pkey buffer holding public key data + * pkeySz public key data size + * indent the number of spaces for indent + * bitlen bit size of the given key + * pctx context(not used) + * Returns 1 on success, 0 on failure. +*/ +static int PrintPubKeyEC(WOLFSSL_BIO* out, const byte* pkey, int pkeySz, + int indent, int bitlen, ASN1_PCTX* pctx) +{ + byte* pub = NULL; + word32 pubSz = 0; + byte buff[8] = { 0 }; + int res = WOLFSSL_SUCCESS; + word32 inOutIdx = 0; + int curveId = 0; + const byte* curveOID = NULL; + word32 oidSz = 0; + const char* OIDName = NULL; + const char* nistCurveName = NULL; + int nid; + int idx = 0; + int wsz = 0; + mp_int a; + ecc_key key; + char line[32] = { 0 }; + (void)pctx; + + if( mp_init(&a) != 0) { + return WOLFSSL_FAILURE; + } + if (indent < 0) { + indent = 0; + } + if (indent > EVP_PKEY_PRINT_INDENT_MAX) { + indent = EVP_PKEY_PRINT_INDENT_MAX; + } + + res = wc_ecc_init(&key) == 0; + + if (res == WOLFSSL_SUCCESS) { + res = wc_EccPublicKeyDecode(pkey, &inOutIdx, &key, pkeySz) == 0; + } + + if (res == WOLFSSL_SUCCESS) { + curveId = wc_ecc_get_oid(key.dp->oidSum, &curveOID, &oidSz); + res = curveId > 0 && oidSz > 0; + } + + /* get NIST curve name */ + if (res == WOLFSSL_SUCCESS) { + nid = EccEnumToNID(curveId); + if (nid != -1) { + /* look up object name and nist curve name*/ + OIDName = wolfSSL_OBJ_nid2sn(nid); + nistCurveName = wolfSSL_EC_curve_nid2nist(nid); + res = (nistCurveName != NULL) && (OIDName != NULL); + } + else { + res = WOLFSSL_FAILURE; + } + } + if (res == WOLFSSL_SUCCESS) { + pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_ECC_BUFFER); + if (pub == NULL) { + return WOLFSSL_FAILURE; + } + pubSz = ECC_BUFSIZE; + XMEMSET(pub, 0, ECC_BUFSIZE); + + res = wc_ecc_export_x963(&key, pub, &pubSz) == 0; + } + if (res == WOLFSSL_SUCCESS) { + idx = 0; + res = Indent(out, indent) >= 0; + } + if (res == WOLFSSL_SUCCESS) { + XSTRNCPY(line, "Public-Key: (", sizeof(line)); + res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0; + } + if (res == WOLFSSL_SUCCESS) { + res = mp_set_int(&a, bitlen) == 0; + } + if (res == WOLFSSL_SUCCESS) { + res = mp_todecimal(&a, (char*)buff) == 0; + } + if (res == WOLFSSL_SUCCESS) { + wsz = (int)XSTRLEN((const char*)buff); + } + if (res == WOLFSSL_SUCCESS) { + res = wolfSSL_BIO_write(out, buff + idx, wsz) >= 0; + } + if (res == WOLFSSL_SUCCESS) { + XSTRNCPY(line, " bit)\n", sizeof(line)); + res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0; + } + if (res == WOLFSSL_SUCCESS) { + res = Indent(out, indent) >= 0; + } + if (res == WOLFSSL_SUCCESS) { + /* print pub element */ + XSTRNCPY(line, "pub:\n", sizeof(line)); + res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0; + } + if (res == WOLFSSL_SUCCESS) { + res = PrintHexWithColon(out, pub, pubSz, indent + 4); + } + if (res == WOLFSSL_SUCCESS) { + res = Indent(out, indent) >= 0; + } + if (res == WOLFSSL_SUCCESS) { + /* print OID in name */ + XSTRNCPY(line, "ASN1 OID: ", sizeof(line)); + res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0; + } + if (res == WOLFSSL_SUCCESS) { + res = wolfSSL_BIO_write(out, OIDName, (int)XSTRLEN(OIDName)) > 0; + } + if (res == WOLFSSL_SUCCESS) { + res = wolfSSL_BIO_write(out, "\n", 1) > 0; + } + if (res == WOLFSSL_SUCCESS) { + res = Indent(out, indent) >= 0; + } + if (res == WOLFSSL_SUCCESS) { + /* print NIST curve name */ + XSTRNCPY(line, "NIST CURVE: ", sizeof(line)); + res = wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) > 0; + } + if (res == WOLFSSL_SUCCESS) { + res = wolfSSL_BIO_write(out, nistCurveName, + (int)XSTRLEN(nistCurveName)) > 0; + } + if (res == WOLFSSL_SUCCESS) { + res = wolfSSL_BIO_write(out, "\n", 1) > 0; + } + + if (pub != NULL) { + XFREE(pub, NULL, DYNAMIC_TYPE_ECC_BUFFER); + pub = NULL; + } + + return res; +} +#endif /* HAVE_ECC */ + +#if !defined(NO_DSA) +/* PrintPubKeyDSA is a helper function for wolfSSL_EVP_PKEY_print_public + * to parse a DER format DSA public key specified in the second parameter. + * Parameters: + * out bio to output dump data + * pkey buffer holding public key data + * pkeySz public key data size + * indent the number of spaces for indent + * bitlen bit size of the given key + * pctx context(not used) + * Returns 1 on success, 0 on failure. +*/ +static int PrintPubKeyDSA(WOLFSSL_BIO* out, const byte* pkey, int pkeySz, + int indent, int bitlen, ASN1_PCTX* pctx) +{ + + byte buff[8] = { 0 }; + int length; + int res; + word32 inOutIdx = 0; + word32 oid; + byte tagFound; + byte *p = NULL, * q = NULL, * g = NULL, * y = NULL; + int pSz, qSz, gSz, ySz; + int idx; + int wsz; + mp_int a; + char line[32] = { 0 }; + + if( mp_init(&a) != 0) + return WOLFSSL_FAILURE; + + inOutIdx = 0; + (void)pctx; + + if (indent < 0) { + indent = 0; + } + if (indent > EVP_PKEY_PRINT_INDENT_MAX) { + indent = EVP_PKEY_PRINT_INDENT_MAX; + } + if (GetSequence(pkey, &inOutIdx, &length, pkeySz) < 0) { + return WOLFSSL_FAILURE; + } + if (GetSequence(pkey, &inOutIdx, &length, pkeySz) < 0) { + return WOLFSSL_FAILURE; + } + res = GetObjectId(pkey, &inOutIdx, &oid, oidIgnoreType, pkeySz); + if (res != 0) { + return WOLFSSL_FAILURE; + } + if (GetSequence(pkey, &inOutIdx, &length, pkeySz) < 0) { + return WOLFSSL_FAILURE; + } + /* find P */ + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_INTEGER) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + p = (byte*)(pkey + inOutIdx); + pSz = length; + + if (bitlen == 0) { + if (*p == 0) { + bitlen = (pSz - 1) * 8; /* remove leading zero */ + } + else { + bitlen = pSz * 8; + } + } + + inOutIdx += length; + /* find Q */ + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_INTEGER) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + q = (byte*)(pkey + inOutIdx); + qSz = length; + inOutIdx += length; + + /* find G */ + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_INTEGER) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + g = (byte*)(pkey + inOutIdx); + gSz = length; + inOutIdx += length; + /* find Y */ + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_BIT_STRING) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + inOutIdx++; /* skip the first byte( unused byte number)*/ + + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_INTEGER) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, &length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + y = (byte*)(pkey + inOutIdx); + ySz = length; + + idx = 0; + XMEMSET(buff, 0, sizeof(buff)); + Indent(out, indent); + XSTRNCPY(line, "DSA Public-Key: (", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (mp_set_int(&a, bitlen) != 0) { + return WOLFSSL_FAILURE; + } + if (mp_todecimal(&a, (char*)buff) != 0) { + return WOLFSSL_FAILURE; + } + wsz = (int)XSTRLEN((const char*)buff); + if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) { + return WOLFSSL_FAILURE; + } + XSTRNCPY(line, " bit)\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + /* print pub element */ + Indent(out, indent); + XSTRNCPY(line, "pub:\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (PrintHexWithColon(out, y, ySz, indent + 4) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + /* print P element */ + Indent(out, indent); + XSTRNCPY(line, "P:\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (PrintHexWithColon(out, p, pSz, indent + 4) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + /* print Q element */ + Indent(out, indent); + XSTRNCPY(line, "Q:\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (PrintHexWithColon(out, q, qSz, indent + 4) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + /* print G element */ + Indent(out, indent); + XSTRNCPY(line, "G:\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (PrintHexWithColon(out, g, gSz, indent + 4) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + return WOLFSSL_SUCCESS; +} +#endif /* !NO_DSA */ + +#if defined(WOLFSSL_DH_EXTRA) +/* PrintPubKeyDH is a helper function for wolfSSL_EVP_PKEY_print_public + * to parse a DER format DH public key specified in the second parameter. + * Parameters: + * out bio to output dump data + * pkey buffer holding public key data + * pkeySz public key data size + * indent the number of spaces for indent + * bitlen bit size of the given key + * pctx context(not used) + * Returns 1 on success, 0 on failure. +*/ +static int PrintPubKeyDH(WOLFSSL_BIO* out, const byte* pkey, int pkeySz, + int indent, int bitlen, ASN1_PCTX* pctx) +{ + + byte buff[8] = { 0 }; + word32 length; + word32 inOutIdx; + word32 oid; + byte tagFound; + byte* prime = NULL; + int primeSz; + byte generator; + byte* publicKey = NULL; + int publicKeySz; + int idx; + int wsz; + word32 outSz; + byte outHex[3]; + mp_int a; + char line[32] = { 0 }; + + if( mp_init(&a) != 0) + return WOLFSSL_FAILURE; + + inOutIdx = 0; + (void)pctx; + + if (indent < 0) { + indent = 0; + } + if (indent > EVP_PKEY_PRINT_INDENT_MAX) { + indent = EVP_PKEY_PRINT_INDENT_MAX; + } + if (GetSequence(pkey, &inOutIdx, (int*)&length, pkeySz) < 0) { + return WOLFSSL_FAILURE; + } + if (GetSequence(pkey, &inOutIdx, (int*)&length, pkeySz) < 0) { + return WOLFSSL_FAILURE; + } + if (GetObjectId(pkey, &inOutIdx, &oid, oidIgnoreType, pkeySz) < 0) { + return WOLFSSL_FAILURE; + } + if (GetSequence(pkey, &inOutIdx, (int*)&length, pkeySz) < 0) { + return WOLFSSL_FAILURE; + } + /* get prime element */ + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_INTEGER) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, (int*)&length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + prime = (byte*)(pkey + inOutIdx); + primeSz = length; + inOutIdx += length; + + /* get generator element */ + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_INTEGER) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, (int*)&length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + if (length != 1) { + return WOLFSSL_FAILURE; + } + generator = *(pkey + inOutIdx); + inOutIdx += length; + + /* get public-key element */ + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_BIT_STRING) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, (int*)&length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + inOutIdx ++; + if (GetASNTag(pkey, &inOutIdx, &tagFound, pkeySz) != 0) { + return WOLFSSL_FAILURE; + } + if (tagFound != ASN_INTEGER) { + return WOLFSSL_FAILURE; + } + if (GetLength(pkey, &inOutIdx, (int*)&length, pkeySz) <= 0) { + return WOLFSSL_FAILURE; + } + publicKeySz = length; + publicKey = (byte*)(pkey + inOutIdx); + + if (bitlen == 0) { + if (*publicKey == 0) { + bitlen = (publicKeySz - 1) * 8; + } + else { + bitlen = publicKeySz * 8; + } + } + + /* print elements */ + idx = 0; + Indent(out, indent); + XSTRNCPY(line, "DH Public-Key: (", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (mp_set_int(&a, bitlen) != 0) { + return WOLFSSL_FAILURE; + } + if (mp_todecimal(&a, (char*)buff) != 0) { + return WOLFSSL_FAILURE; + } + wsz = (int)XSTRLEN((const char*)buff); + if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) { + return WOLFSSL_FAILURE; + } + XSTRNCPY(line, " bit)\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + Indent(out, indent); + XSTRNCPY(line, "public-key:\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (PrintHexWithColon(out, publicKey, publicKeySz, indent + 4) + != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + Indent(out, indent); + XSTRNCPY(line, "prime:\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (PrintHexWithColon(out, prime, primeSz, indent + 4) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + idx = 0; + XMEMSET(buff, 0, sizeof(buff)); + Indent(out, indent); + XSTRNCPY(line, "generator: ", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + if (mp_set_int(&a, generator) != 0) { + return WOLFSSL_FAILURE; + } + if (mp_todecimal(&a, (char*)buff) != 0) { + return WOLFSSL_FAILURE; + } + wsz = (int)XSTRLEN((const char*)buff); + if (wolfSSL_BIO_write(out, buff + idx, wsz) <= 0) { + return WOLFSSL_FAILURE; + } + XSTRNCPY(line, " (0x", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + idx = 0; + XMEMSET(buff, 0, sizeof(buff)); + outSz = sizeof(outHex); + if (Base16_Encode((const byte*)&generator, 1, outHex, &outSz ) != 0) { + return WOLFSSL_FAILURE; + } + if (idx + 2 < (int)sizeof(buff) ) { + XMEMCPY(buff + idx, outHex, 2); + idx += 2; + } + if (wolfSSL_BIO_write(out, buff, idx) <= 0 ) { + return WOLFSSL_FAILURE; + } + XSTRNCPY(line, ")\n", sizeof(line)); + if (wolfSSL_BIO_write(out, line, (int)XSTRLEN(line)) <= 0) { + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} +#endif /* WOLFSSL_DH_EXTRA */ + +/* wolfSSL_EVP_PKEY_print_public parses the specified key then + * outputs public key info in human readable format to the specified BIO. + * White spaces of the same number which 'indent" gives, will be added to + * each line to output and ignores pctx parameter. + * Parameters: + * out bio to output dump data + * pkey buffer holding public key data + * indent the number of spaces for indent + * pctx context(not used) + * Returns 1 on success, 0 or negative on error, -2 means specified key + * algo is not supported. + * Can handle RSA, ECC, DSA and DH public keys. + */ +int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, + const WOLFSSL_EVP_PKEY* pkey, int indent, ASN1_PCTX* pctx) +{ + int res; + int keybits; /* bit length of the key */ + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_print_public"); + + if (pkey == NULL || out == NULL) { + return 0; + } + if (indent < 0) { + indent = 0; + } + if (indent > EVP_PKEY_PRINT_INDENT_MAX) { + indent = EVP_PKEY_PRINT_INDENT_MAX; + } + switch (pkey->type) { + case EVP_PKEY_RSA: + +#if !defined(NO_RSA) + keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + res = PrintPubKeyRSA( + out, + (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ + pkey->pkey_sz, /* raw pkey size */ + indent, /* indent size */ + keybits, /* bit length of the key */ + pctx); /* not used */ +#else + res = WOLFSSL_UNKNOWN; /* not supported algo */ +#endif + break; + + case EVP_PKEY_EC: + +#if defined(HAVE_ECC) + keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + res = PrintPubKeyEC( + out, + (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ + pkey->pkey_sz, /* raw pkey size */ + indent, /* indent size */ + keybits, /* bit length of the key */ + pctx); /* not used */ +#else + res = WOLFSSL_UNKNOWN; /* not supported algo */ +#endif + break; + + case EVP_PKEY_DSA: + +#if !defined(NO_DSA) + keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + res = PrintPubKeyDSA( + out, + (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ + pkey->pkey_sz, /* raw pkey size */ + indent, /* indent size */ + keybits, /* bit length of the key */ + pctx); /* not used */ +#else + res = WOLFSSL_UNKNOWN; /* not supported algo */ +#endif + break; + + case EVP_PKEY_DH: + +#if defined(WOLFSSL_DH_EXTRA) + keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + res = PrintPubKeyDH( + out, + (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ + pkey->pkey_sz, /* raw pkey size */ + indent, /* indent size */ + keybits, /* bit length of the key */ + pctx); /* not used */ +#else + res = WOLFSSL_UNKNOWN; /* not supported algo */ +#endif + break; + + default: + res = WOLFSSL_UNKNOWN; /* not supported algo */ + break; + } + return res; +} +#endif /* OPENSSL_EXTRA */ #if !defined(NO_PWDBASED) int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp, diff --git a/wolfssl/certs_test.h b/wolfssl/certs_test.h index 9c6fd4a76d..fabf967eba 100644 --- a/wolfssl/certs_test.h +++ b/wolfssl/certs_test.h @@ -1028,6 +1028,157 @@ static const unsigned char dh_key_der_2048[] = }; static const int sizeof_dh_key_der_2048 = sizeof(dh_key_der_2048); +static const unsigned char dh_pub_key_der_2048[] = +{ + 0x30, 0x82, 0x02, 0x24, 0x30, 0x82, 0x01, 0x17, 0x06, 0x09, + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x03, 0x01, 0x30, + 0x82, 0x01, 0x08, 0x02, 0x82, 0x01, 0x01, 0x00, 0xD3, 0xB2, + 0x99, 0x84, 0x5C, 0x0A, 0x4C, 0xE7, 0x37, 0xCC, 0xFC, 0x18, + 0x37, 0x01, 0x2F, 0x5D, 0xC1, 0x4C, 0xF4, 0x5C, 0xC9, 0x82, + 0x8D, 0xB7, 0xF3, 0xD4, 0xA9, 0x8A, 0x9D, 0x34, 0xD7, 0x76, + 0x57, 0xE5, 0xE5, 0xC3, 0xE5, 0x16, 0x85, 0xCA, 0x4D, 0xD6, + 0x5B, 0xC1, 0xF8, 0xCF, 0x89, 0x26, 0xD0, 0x38, 0x8A, 0xEE, + 0xF3, 0xCD, 0x33, 0xE5, 0x56, 0xBB, 0x90, 0x83, 0x9F, 0x97, + 0x8E, 0x71, 0xFB, 0x27, 0xE4, 0x35, 0x15, 0x45, 0x86, 0x09, + 0x71, 0xA8, 0x9A, 0xB9, 0x3E, 0x0F, 0x51, 0x8A, 0xC2, 0x75, + 0x51, 0x23, 0x12, 0xFB, 0x94, 0x31, 0x44, 0xBF, 0xCE, 0xF6, + 0xED, 0xA6, 0x3A, 0xB7, 0x92, 0xCE, 0x16, 0xA9, 0x14, 0xB3, + 0x88, 0xB7, 0x13, 0x81, 0x71, 0x83, 0x88, 0xCD, 0xB1, 0xA2, + 0x37, 0xE1, 0x59, 0x5C, 0xD0, 0xDC, 0xCA, 0x82, 0x87, 0xFA, + 0x43, 0x44, 0xDD, 0x78, 0x3F, 0xCA, 0x27, 0x7E, 0xE1, 0x6B, + 0x93, 0x19, 0x7C, 0xD9, 0xA6, 0x96, 0x47, 0x0D, 0x12, 0xC1, + 0x13, 0xD7, 0xB9, 0x0A, 0x40, 0xD9, 0x1F, 0xFF, 0xB8, 0xB4, + 0x00, 0xC8, 0xAA, 0x5E, 0xD2, 0x66, 0x4A, 0x05, 0x8E, 0x9E, + 0xF5, 0x34, 0xE7, 0xD7, 0x09, 0x7B, 0x15, 0x49, 0x1D, 0x76, + 0x31, 0xD6, 0x71, 0xEC, 0x13, 0x4E, 0x89, 0x8C, 0x09, 0x22, + 0xD8, 0xE7, 0xA3, 0xE9, 0x7D, 0x21, 0x51, 0x26, 0x6E, 0x9F, + 0x30, 0x8A, 0xBB, 0xBC, 0x74, 0xC1, 0xC3, 0x27, 0x6A, 0xCE, + 0xA3, 0x12, 0x60, 0x68, 0x01, 0xD2, 0x34, 0x07, 0x80, 0xCC, + 0x2D, 0x7F, 0x5C, 0xAE, 0xA2, 0x97, 0x40, 0xC8, 0x3C, 0xAC, + 0xDB, 0x6F, 0xFE, 0x6C, 0x6D, 0xD2, 0x06, 0x1C, 0x43, 0xA2, + 0xB2, 0x2B, 0x82, 0xB7, 0xD0, 0xAB, 0x3F, 0x2C, 0xE7, 0x9C, + 0x19, 0x16, 0xD1, 0x5E, 0x26, 0x86, 0xC7, 0x92, 0xF9, 0x16, + 0x0B, 0xFA, 0x66, 0x83, 0x02, 0x01, 0x02, 0x03, 0x82, 0x01, + 0x05, 0x00, 0x02, 0x82, 0x01, 0x00, 0x34, 0x41, 0xBF, 0xE9, + 0xF2, 0x11, 0xBF, 0x05, 0xDB, 0xB2, 0x72, 0xA8, 0x29, 0xCC, + 0xBD, 0x93, 0xEB, 0x14, 0x5D, 0x2C, 0x6B, 0x84, 0x4E, 0x96, + 0x12, 0xB3, 0x38, 0xBA, 0x8A, 0x46, 0x7C, 0x36, 0xCB, 0xE9, + 0x97, 0x70, 0xC5, 0xC3, 0x85, 0xB5, 0x51, 0xA5, 0x8B, 0x39, + 0xA8, 0xEA, 0x47, 0xD3, 0xD5, 0x11, 0xC0, 0x6D, 0xE3, 0xE3, + 0x9E, 0x00, 0x4C, 0x65, 0x41, 0x9B, 0xF6, 0xD0, 0xAC, 0x26, + 0x88, 0x01, 0xFC, 0x3C, 0x26, 0x5F, 0x67, 0xF7, 0x77, 0xD7, + 0xAC, 0xC5, 0xCA, 0xBB, 0xD8, 0x70, 0x58, 0x41, 0xF5, 0xF1, + 0x21, 0x3B, 0x15, 0xD5, 0x31, 0xF2, 0xC4, 0x8E, 0x0C, 0x38, + 0x01, 0x93, 0xD3, 0x64, 0x63, 0x57, 0xDC, 0x31, 0xE5, 0xFD, + 0x9C, 0x2B, 0xA6, 0xDE, 0x15, 0xB2, 0xC8, 0x8D, 0x65, 0x71, + 0x2E, 0xED, 0xF9, 0x1D, 0x2D, 0xA1, 0x17, 0xDD, 0xA3, 0xDA, + 0xF3, 0x10, 0x81, 0x40, 0xFA, 0x4F, 0x49, 0xB0, 0xDA, 0x16, + 0x64, 0xBE, 0x6F, 0xC5, 0x05, 0xCE, 0xC4, 0x4F, 0x67, 0x80, + 0xB3, 0x8A, 0x81, 0x17, 0xEB, 0xF9, 0x6F, 0x6D, 0x9F, 0x7F, + 0xDE, 0xEE, 0x08, 0xB8, 0xFA, 0x81, 0x68, 0x66, 0xD6, 0xC6, + 0x08, 0x50, 0xAB, 0xF0, 0x29, 0xDE, 0x6B, 0x1D, 0x50, 0x13, + 0x7F, 0x54, 0x31, 0x53, 0x89, 0x5F, 0x48, 0x72, 0x24, 0xD4, + 0xD2, 0x1D, 0x27, 0x7D, 0x74, 0xCF, 0x51, 0x17, 0xF0, 0xC5, + 0x6D, 0x3C, 0x3D, 0x6D, 0x0A, 0x8B, 0xDB, 0xEF, 0x02, 0xD8, + 0xC3, 0xCB, 0xCA, 0x21, 0xCA, 0xD6, 0x9C, 0x18, 0x9E, 0x92, + 0xBE, 0x6E, 0xE2, 0x16, 0x5E, 0x89, 0x9B, 0xAD, 0xD4, 0x04, + 0x5A, 0x24, 0x5A, 0x3F, 0x7C, 0x12, 0xAC, 0xB4, 0x71, 0x51, + 0x25, 0x58, 0x74, 0xE4, 0xB2, 0xD4, 0x45, 0xFC, 0x5F, 0xCD, + 0x81, 0x8F, 0xE7, 0x96, 0x18, 0xD9, 0xE0, 0x97, 0x08, 0x45, + 0x36, 0xC3 +}; +static const int sizeof_dh_pub_key_der_2048 = sizeof(dh_pub_key_der_2048); + +static const unsigned char dsa_pub_key_der_2048[] = +{ + 0x30, 0x82, 0x03, 0x47, 0x30, 0x82, 0x02, 0x39, 0x06, 0x07, + 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01, 0x30, 0x82, 0x02, + 0x2C, 0x02, 0x82, 0x01, 0x01, 0x00, 0xEB, 0x7E, 0x2C, 0x97, + 0x36, 0x67, 0x0E, 0x73, 0x9A, 0xAC, 0xFD, 0xB1, 0x19, 0x03, + 0x52, 0x61, 0x25, 0x12, 0xB2, 0x37, 0x3D, 0xEA, 0xCA, 0x80, + 0x07, 0x5D, 0x2D, 0x33, 0xA2, 0x4E, 0x6B, 0xB7, 0x62, 0xF8, + 0x87, 0x4D, 0x4B, 0x20, 0xDA, 0xEA, 0x6A, 0x96, 0x13, 0xB7, + 0xB9, 0x49, 0xC0, 0x86, 0x14, 0x71, 0xCD, 0x8C, 0x60, 0x61, + 0x94, 0x71, 0x89, 0x95, 0x1A, 0x0F, 0x38, 0xCC, 0x9C, 0x1F, + 0x20, 0xE5, 0xD0, 0x65, 0x75, 0xCD, 0xFE, 0x24, 0x29, 0xE6, + 0x60, 0x97, 0x74, 0xEC, 0x4C, 0x42, 0xE8, 0xBA, 0xE9, 0xC2, + 0xF7, 0xCB, 0x9B, 0xEA, 0x55, 0xD8, 0x40, 0x50, 0x2E, 0xCF, + 0xCD, 0x41, 0x01, 0xA9, 0xE5, 0x29, 0xCA, 0xC3, 0x36, 0x58, + 0x7E, 0x2E, 0x11, 0x96, 0x87, 0xC6, 0xFA, 0xE1, 0x27, 0x53, + 0x3D, 0x60, 0x93, 0x7B, 0xAD, 0xEE, 0xE7, 0xD4, 0xDC, 0xD6, + 0x03, 0x16, 0x92, 0xD4, 0x51, 0x0C, 0xFD, 0xA9, 0x01, 0x3E, + 0x6E, 0x27, 0x67, 0x6E, 0x9F, 0x29, 0x63, 0xFD, 0x51, 0x82, + 0x79, 0x83, 0x2B, 0xCB, 0x12, 0xCD, 0x50, 0x92, 0xAC, 0x16, + 0xC9, 0xEA, 0x9E, 0x68, 0x9E, 0x4B, 0xE1, 0x63, 0xB4, 0x80, + 0xE4, 0xDF, 0x75, 0xBC, 0x27, 0xD1, 0x76, 0x03, 0x48, 0x98, + 0x1D, 0xE3, 0x29, 0x8A, 0x99, 0x59, 0xF3, 0x75, 0x5B, 0xD9, + 0xAC, 0x59, 0x11, 0x52, 0x2F, 0xE0, 0x91, 0x55, 0xB0, 0xF2, + 0x5F, 0x0A, 0xF8, 0xD2, 0x7A, 0xDD, 0x8D, 0xE9, 0x92, 0xE2, + 0xF3, 0xF7, 0x4A, 0xB1, 0x50, 0xD7, 0xFE, 0x07, 0x8D, 0x27, + 0x7D, 0x08, 0x6F, 0x08, 0x7E, 0x25, 0x19, 0x0D, 0xDE, 0x11, + 0xD1, 0x63, 0x31, 0x84, 0x18, 0x25, 0xBE, 0x7D, 0x64, 0x77, + 0xDB, 0x4A, 0x20, 0xC5, 0x51, 0x75, 0xD8, 0xB1, 0x1B, 0xDF, + 0x91, 0x7F, 0xFC, 0x74, 0xBA, 0x9D, 0xD1, 0xFA, 0x8D, 0xBD, + 0x59, 0xFD, 0x02, 0x21, 0x00, 0xFA, 0xF7, 0x62, 0x9A, 0x62, + 0x19, 0x64, 0x6D, 0xC1, 0xF3, 0xC0, 0x9B, 0xAC, 0x90, 0x28, + 0xEA, 0xA1, 0x83, 0xF9, 0xC8, 0xED, 0x31, 0xEE, 0x33, 0x1D, + 0x35, 0x22, 0x00, 0x2B, 0x12, 0x84, 0xFF, 0x02, 0x82, 0x01, + 0x00, 0x73, 0xC9, 0xED, 0x1F, 0xBC, 0xC7, 0xC4, 0xEF, 0x46, + 0x03, 0xD1, 0x72, 0xC3, 0xE5, 0x29, 0xB0, 0x9A, 0x95, 0x13, + 0x5B, 0x4E, 0x59, 0x57, 0x0F, 0x80, 0xEB, 0x74, 0x87, 0x11, + 0x1B, 0xC8, 0x11, 0xB6, 0x97, 0x4C, 0x48, 0x50, 0x3A, 0xB8, + 0x2C, 0x28, 0xF3, 0xB0, 0x9C, 0x7C, 0x3D, 0xFF, 0x8B, 0x43, + 0x43, 0x30, 0x85, 0x5F, 0x97, 0xD2, 0x68, 0x85, 0x35, 0x2E, + 0xD4, 0x61, 0xF6, 0x3E, 0x05, 0xEC, 0xCD, 0x60, 0x13, 0xE2, + 0x16, 0x02, 0x7C, 0x8B, 0x21, 0xCE, 0x36, 0x71, 0xC4, 0xED, + 0x0B, 0x47, 0x76, 0x83, 0x23, 0x2F, 0x98, 0xA4, 0x84, 0x98, + 0x9C, 0xFB, 0xD0, 0xA8, 0xD9, 0xB9, 0xE3, 0xD7, 0x32, 0xD9, + 0xB5, 0x9E, 0x82, 0x93, 0xD0, 0x55, 0x74, 0x5F, 0xDA, 0x87, + 0x91, 0x90, 0x0F, 0x85, 0x74, 0x1A, 0x32, 0x76, 0x4F, 0xCC, + 0x2A, 0x18, 0x11, 0x5B, 0xB4, 0x78, 0x93, 0xB6, 0xE5, 0xF0, + 0xC6, 0x71, 0xE8, 0xD7, 0x31, 0x19, 0x91, 0x27, 0x71, 0x5A, + 0x02, 0x1A, 0x1A, 0x3A, 0x55, 0x95, 0xFF, 0xF8, 0xED, 0xD3, + 0xE1, 0xAE, 0x8A, 0x1D, 0xFF, 0x53, 0x63, 0x79, 0x13, 0xA1, + 0xAD, 0x0A, 0x68, 0x67, 0x43, 0xB2, 0x5B, 0xD5, 0x36, 0xD4, + 0x84, 0xD0, 0xCD, 0x34, 0x82, 0x84, 0xA4, 0x89, 0xAE, 0xA1, + 0x66, 0x57, 0x89, 0x6F, 0xDC, 0x0C, 0x3B, 0x48, 0x14, 0x7C, + 0xCC, 0x63, 0x7C, 0x83, 0x93, 0x55, 0x7D, 0xB4, 0xF3, 0x34, + 0x66, 0x72, 0x85, 0xF5, 0x8D, 0xEF, 0x90, 0x1A, 0x66, 0xF8, + 0x3B, 0xC6, 0xA4, 0x59, 0xB8, 0x25, 0x4E, 0x5D, 0x84, 0xED, + 0x7C, 0x1C, 0xDD, 0x35, 0xA6, 0xBA, 0xED, 0x3B, 0xD6, 0x49, + 0xE6, 0x5A, 0xD1, 0xF8, 0xEA, 0x96, 0x75, 0x92, 0xCF, 0x05, + 0x52, 0x05, 0x3D, 0x78, 0x09, 0xCF, 0xCD, 0xE2, 0x1A, 0x99, + 0xEB, 0x5E, 0xFA, 0x27, 0x73, 0x89, 0x15, 0x03, 0x82, 0x01, + 0x06, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xC2, 0x35, 0x2D, + 0xEC, 0x83, 0x83, 0x6C, 0x73, 0x13, 0x9E, 0x52, 0x7C, 0x74, + 0xC8, 0x7B, 0xEE, 0xDF, 0x39, 0xC0, 0x33, 0xCD, 0x9F, 0xB2, + 0x22, 0x64, 0x9F, 0xC5, 0xE9, 0xFF, 0xF7, 0x09, 0x47, 0x79, + 0x13, 0x96, 0x77, 0x25, 0xF3, 0x5D, 0xAA, 0x9F, 0x97, 0x67, + 0x62, 0xBC, 0x94, 0x1D, 0xAE, 0x22, 0x7E, 0x08, 0x03, 0xBD, + 0x7E, 0x34, 0x29, 0xCB, 0x62, 0xB7, 0x82, 0x1D, 0xE2, 0xFA, + 0x05, 0xC6, 0xC1, 0x68, 0xE7, 0x01, 0x27, 0x63, 0x51, 0x3E, + 0x37, 0x59, 0x42, 0x92, 0x4F, 0x99, 0x60, 0xFD, 0x63, 0x94, + 0xB7, 0xD0, 0xEE, 0xC1, 0xA0, 0xA5, 0x01, 0x74, 0x4D, 0x0E, + 0x14, 0xB2, 0xE2, 0x2C, 0xE7, 0x82, 0x0A, 0x23, 0xC7, 0x39, + 0x45, 0x40, 0xE9, 0xE9, 0x9D, 0x36, 0xE0, 0x52, 0x03, 0x99, + 0xDC, 0x87, 0x7D, 0x6A, 0x90, 0xE4, 0xDD, 0xA9, 0xC2, 0x57, + 0x90, 0xD6, 0xCA, 0xB4, 0x15, 0x80, 0xEE, 0x00, 0xCB, 0x2A, + 0xC9, 0x59, 0x4C, 0xA7, 0x7D, 0x33, 0x0A, 0x3E, 0x4A, 0x76, + 0xEA, 0x27, 0x89, 0xD8, 0x1A, 0xEA, 0x7E, 0xDB, 0x13, 0x92, + 0x93, 0x6A, 0x57, 0x9B, 0x33, 0xFD, 0xCE, 0x09, 0x0A, 0xB0, + 0x35, 0x24, 0xE4, 0x7D, 0xD8, 0x9D, 0xFF, 0x80, 0x65, 0x0F, + 0x61, 0xF7, 0xF7, 0xED, 0x8B, 0xD5, 0x8F, 0xBF, 0xB3, 0x22, + 0x20, 0x39, 0x89, 0x83, 0xB8, 0x83, 0x96, 0x32, 0x20, 0xAD, + 0xA1, 0x5D, 0x73, 0x8F, 0xE3, 0x27, 0xD9, 0x5D, 0xDB, 0x00, + 0x27, 0xF2, 0xBE, 0x89, 0x13, 0xE2, 0x97, 0x79, 0x10, 0x27, + 0x3D, 0xD8, 0x05, 0x96, 0x59, 0x6E, 0xA0, 0xC1, 0x6F, 0x99, + 0x4F, 0x28, 0xFA, 0xA6, 0x0B, 0x5C, 0x16, 0xEE, 0xB0, 0x98, + 0x8A, 0x06, 0x4A, 0xB0, 0x02, 0x2A, 0x6D, 0xCC, 0xE2, 0xC8, + 0x11, 0xF9, 0x1B, 0xF1, 0x3C, 0x68, 0xDF, 0xC2, 0xF4, 0x98, + 0x5F, 0x6C, 0xC8 +}; +static const int sizeof_dsa_pub_key_der_2048 = sizeof(dsa_pub_key_der_2048); + /* ./certs/dsa2048.der, 2048-bit */ static const unsigned char dsa_key_der_2048[] = { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a994293a23..00bf17de9d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4829,6 +4829,15 @@ WOLFSSL_LOCAL int SetDsaExternal(WOLFSSL_DSA* dsa); WOLFSSL_LOCAL int SetRsaExternal(WOLFSSL_RSA* rsa); WOLFSSL_LOCAL int SetRsaInternal(WOLFSSL_RSA* rsa); #endif + +typedef enum elem_set { + ELEMENT_P = 0x01, + ELEMENT_Q = 0x02, + ELEMENT_G = 0x04, + ELEMENT_PUB = 0x08, + ELEMENT_PRV = 0x10, +} Element_Set; +WOLFSSL_LOCAL int SetDhExternal_ex(WOLFSSL_DH *dh, int elm ); WOLFSSL_LOCAL int SetDhInternal(WOLFSSL_DH* dh); WOLFSSL_LOCAL int SetDhExternal(WOLFSSL_DH *dh); diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 6923f15df4..1376de1683 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -373,6 +373,11 @@ struct WOLFSSL_EVP_PKEY_CTX { int nbits; }; +typedef +struct WOLFSSL_ASN1_PCTX { + int dummy; +} WOLFSSL_ASN1_PCTX; + typedef int WOLFSSL_ENGINE ; typedef WOLFSSL_ENGINE ENGINE; typedef WOLFSSL_EVP_PKEY_CTX EVP_PKEY_CTX; @@ -382,6 +387,8 @@ typedef WOLFSSL_EVP_PKEY_CTX EVP_PKEY_CTX; #define EVP_PKEY_OP_DECRYPT (1 << 7) #define EVP_PKEY_OP_DERIVE (1 << 8) +#define EVP_PKEY_PRINT_INDENT_MAX 128 + WOLFSSL_API void wolfSSL_EVP_init(void); WOLFSSL_API int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* md); WOLFSSL_API int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md); @@ -673,6 +680,7 @@ typedef WOLFSSL_EVP_MD EVP_MD; typedef WOLFSSL_EVP_CIPHER EVP_CIPHER; typedef WOLFSSL_EVP_MD_CTX EVP_MD_CTX; typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; +typedef WOLFSSL_ASN1_PCTX ASN1_PCTX; #ifndef NO_MD4 #define EVP_md4 wolfSSL_EVP_md4 @@ -907,6 +915,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG #define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +#define EVP_PKEY_print_public wolfSSL_EVP_PKEY_print_public #define EVP_PKEY_print_private(arg1, arg2, arg3, arg4) #ifndef EVP_MAX_MD_SIZE diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index f61cd9e435..d4f15652fd 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1655,6 +1655,11 @@ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** key, unsigned char** in, long inSz); WOLFSSL_API int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key, unsigned char** der); +#if defined(OPENSSL_EXTRA) +WOLFSSL_API int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, + const WOLFSSL_EVP_PKEY* pkey, + int indent, WOLFSSL_ASN1_PCTX* pctx); +#endif /* OPENSSL_EXTRA */ WOLFSSL_API int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME*); #ifdef OPENSSL_EXTRA WOLFSSL_API int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 64650403a3..1f53f31e8e 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -110,6 +110,8 @@ WOLFSSL_API int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz); #ifdef WOLFSSL_DH_EXTRA +WOLFSSL_API int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx, + DhKey* key, word32 inSz); WOLFSSL_API int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz, const byte* pub, word32 pubSz); WOLFSSL_API int wc_DhExportKeyPair(DhKey* key, byte* priv, word32* pPrivSz,