diff --git a/src/ssl.c b/src/ssl.c index 57348a9ea..0fda7460b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7877,6 +7877,66 @@ 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) + #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION > 2)) + { + DhKey dh; + word32 keyIdx = 0; + + /* test if DH-public key */ + if (wc_InitDhKey(&dh) == 0 && + wc_DhPublicKeyDecode(mem, &keyIdx, &dh, (word32)memSz) == 0) { + wc_FreeDhKey(&dh); + 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; + } + + DhKey* key = (DhKey*)pkey->dh->internal; + + keyIdx = 0; + if (wc_DhPublicKeyDecode(mem, &keyIdx, key, (word32)memSz) == 0) + { + 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) { + wc_FreeDhKey(&dh); + return pkey; + } + } + else { + wolfSSL_EVP_PKEY_free(pkey); + return NULL; + } + } + wolfSSL_EVP_PKEY_free(pkey); + } + } + #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ + #endif /* !NO_DH && OPENSSL_EXTRA */ + if (pkey == NULL) { WOLFSSL_MSG("wolfSSL_d2i_PUBKEY couldn't determine key type"); } @@ -35271,7 +35331,7 @@ const char* wolfSSL_EC_curve_nid2nist(int nid) const WOLF_EC_NIST_NAME* nist_name; for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { if (nist_name->nid == nid) { - return kNistCurves->name; + return nist_name->name; } } return NULL; diff --git a/tests/api.c b/tests/api.c index 6a2283663..f0a29a4ee 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2393,6 +2393,301 @@ 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 }; + int res; + + printf(testingFmt, "wolfSSL_EVP_PKEY_print_public()"); + /* test error cases */ + AssertIntEQ( wolfSSL_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); + + res = wolfSSL_EVP_PKEY_print_public(wbio, pkey,3,NULL); + AssertIntEQ(res,1); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, " RSA Public-Key: (1024 bit)\n", + sizeof(" RSA Public-Key: (1024 bit)\n")); + + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, " Modulus:\n", + sizeof(" Modulus:\n")); + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + " bc:73:0e:a8:49:f3:74:a2:a9:ef:18:a5:da:55:99:\n", + sizeof(" bc:73:0e:a8:49:f3:74:a2:a9:ef:18:a5:da:55:99:\n")); + AssertIntEQ(res,0); + + /* skip to the end of modulus element*/ + for( int i = 0; i < 7 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, " Exponent: 65537 (0x010001)\n", + sizeof(" Exponent: 65537 (0x010001)\n")); + AssertIntEQ(res,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); + + res = wolfSSL_EVP_PKEY_print_public(wbio, pkey,0,NULL); + AssertIntEQ(res,1); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, "DSA Public-Key: (2048 bit)\n", + sizeof("DSA Public-Key: (2048 bit)\n")); + + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, "pub:\n", + sizeof("pub:\n")); + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + " 00:c2:35:2d:ec:83:83:6c:73:13:9e:52:7c:74:c8:\n", + sizeof(" 00:c2:35:2d:ec:83:83:6c:73:13:9e:52:7c:74:c8:\n")); + AssertIntEQ(res,0); + + /* skip to the end of pub element*/ + for( int i = 0; i < 17 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + "P:\n", + sizeof("P:\n")); + AssertIntEQ(res,0); + + /* skip to the end of P element*/ + for( int i = 0; i < 18 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + "Q:\n", + sizeof("Q:\n")); + AssertIntEQ(res,0); + + /* skip to the end of Q element*/ + for( int i = 0; i < 3 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + "G:\n", + sizeof("G:\n")); + AssertIntEQ(res,0); + + /* skip to the end of G element*/ + for( int 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); + + res = wolfSSL_EVP_PKEY_print_public(wbio, pkey,0,NULL); + AssertIntEQ(res,1); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, "Public-Key: (256 bit)\n", + sizeof("Public-Key: (256 bit)\n")); + + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, "pub:\n", + sizeof("pub:\n")); + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + " 04:55:bf:f4:0f:44:50:9a:3d:ce:9b:b7:f0:c5:4d:\n", + sizeof(" 04:55:bf:f4:0f:44:50:9a:3d:ce:9b:b7:f0:c5:4d:\n")); + AssertIntEQ(res,0); + + /* skip to the end of pub element*/ + for( int i = 0; i < 4 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, "ASN1 OID: prime256v1\n", + sizeof("ASN1 OID: prime256v1\n")); + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, "NIST CURVE: P-256\n", + sizeof("NIST CURVE: P-256")); + AssertIntEQ(res,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); + + res = wolfSSL_EVP_PKEY_print_public(wbio, pkey,0,NULL); + AssertIntEQ(res,1); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, "DH Public-Key: (2048 bit)\n", + sizeof("DH Public-Key: (2048 bit)\n")); + + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, "public-key:\n", + sizeof("public-key:\n")); + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + " 34:41:bf:e9:f2:11:bf:05:db:b2:72:a8:29:cc:bd:\n", + sizeof(" 34:41:bf:e9:f2:11:bf:05:db:b2:72:a8:29:cc:bd:\n")); + AssertIntEQ(res,0); + + /* skip to the end of public-key element*/ + for( int i = 0; i < 17 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + "prime:\n", + sizeof("prime:\n")); + AssertIntEQ(res,0); + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + " 00:d3:b2:99:84:5c:0a:4c:e7:37:cc:fc:18:37:01:\n", + sizeof(" 00:d3:b2:99:84:5c:0a:4c:e7:37:cc:fc:18:37:01:\n")); + AssertIntEQ(res,0); + + /* skip to the end of prime element*/ + for( int i = 0; i < 17 ;i++) { + BIO_gets(wbio, line, sizeof(line)); + } + + BIO_gets(wbio, line, sizeof(line)); + res = XSTRNCMP( line, + "generator: 2 (0x02)\n", + sizeof("generator: 2 (0x02)\n")); + AssertIntEQ(res,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 */ + + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA */ +} + /* Test function for wolfSSL_EVP_get_cipherbynid. */ @@ -22232,6 +22527,128 @@ static int test_wc_EccPrivateKeyToDer (void) #endif return ret; }/* End test_wc_EccPrivateKeyToDer*/ +/* + * Testing wc_EccPublicKeyDecode_ex + */ +static int test_wc_EccPublicKeyDecode_ex(void) +{ + int ret = 0; +#if defined(HAVE_ECC) + printf(testingFmt, "test_wc_EccPublicKeyDecode_ex()"); + + if (ret == 0) { + ret = wc_EccPublicKeyDecode_ex(NULL,NULL,NULL,NULL,NULL,0); + if (ret == BAD_FUNC_ARG) + ret = 0; + } +#if defined(USE_CERT_BUFFERS_256) + word32 inOutIdx; + int curveId; + word32 pointIdx; + int pointSz; + + if (ret == 0) { + ret = wc_EccPublicKeyDecode_ex(ecc_clikeypub_der_256, + NULL,NULL,NULL,NULL,0); + if(ret == BAD_FUNC_ARG) + ret = 0; + } + if (ret == 0) { + ret = wc_EccPublicKeyDecode_ex(ecc_clikeypub_der_256, + &inOutIdx,NULL,NULL,NULL,0); + if (ret == BAD_FUNC_ARG) + ret = 0; + } + if (ret == 0) { + ret = wc_EccPublicKeyDecode_ex(ecc_clikeypub_der_256, + &inOutIdx,&curveId,NULL,NULL,0); + if (ret == BAD_FUNC_ARG) + ret = 0; + } + if (ret == 0) { + ret = wc_EccPublicKeyDecode_ex(ecc_clikeypub_der_256, + &inOutIdx,&curveId,&pointIdx,NULL,0); + if(ret == BAD_FUNC_ARG) + ret = 0; + } + if (ret == 0) { + ret = wc_EccPublicKeyDecode_ex(ecc_clikeypub_der_256, + &inOutIdx,&curveId,&pointIdx,&pointSz,0); + if (ret == BAD_FUNC_ARG) + ret = 0; + } + /* pass bad input size */ + if (ret == 0) { + ret = wc_EccPublicKeyDecode_ex(ecc_clikeypub_der_256, + &inOutIdx,&curveId,&pointIdx,&pointSz,sizeof_ecc_clikeypub_der_256 - 3 ); + if (ret < 0 ) + ret = 0; + } + if (ret == 0) { + ret = wc_EccPublicKeyDecode_ex(ecc_clikeypub_der_256, + &inOutIdx,&curveId,&pointIdx,&pointSz,sizeof_ecc_clikeypub_der_256); + if (ret == 0 && inOutIdx == 91 && curveId == 7 && + pointIdx == 26 && pointSz == 65 ) { + ret = 0; + } + else + ret = -1; + } + +#endif /* USE_CERT_BUFFERS_256 */ + + printf(resultFmt, ret == 0 ? passed : failed); +#endif /* HAVE_ECC */ + return ret; +} +/* + * Testing wc_DhPublicKeyDecode + */ +static int test_wc_DhPublicKeyDecode(void) +{ + int ret = 0; +#if defined(WOLFSSL_DH_EXTRA) && defined(USE_CERT_BUFFERS_2048) + printf(testingFmt, "test_wc_DhPublicKeyDecode()"); + + word32 inOutIdx; + DhKey key; + + if (ret == 0) { + ret = wc_DhPublicKeyDecode(NULL,NULL,NULL,0); + if (ret == BAD_FUNC_ARG) + ret = 0; + } + if (ret == 0) { + ret = wc_DhPublicKeyDecode(dh_pub_key_der_2048,NULL,NULL,0); + if(ret == BAD_FUNC_ARG) + ret = 0; + } + if (ret == 0) { + ret = wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,NULL,0); + if (ret == BAD_FUNC_ARG) + ret = 0; + } + if (ret == 0) { + ret = wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,&key,0); + if (ret == BAD_FUNC_ARG) + ret = 0; + } + if (ret == 0) { + ret = wc_DhPublicKeyDecode(dh_pub_key_der_2048,&inOutIdx,&key, + sizeof_dh_pub_key_der_2048); + if (ret == 0 && key.p.used != 0 && key.g.used != 0 && + key.q.used == 0 && key.pub.used != 0 && + key.priv.used == 0 ) { + ret = 0; + } + else + ret = -1; + } + + printf(resultFmt, ret == 0 ? passed : failed); +#endif + return ret; +} /* * Testing wc_Ed25519KeyToDer @@ -31781,6 +32198,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; @@ -40629,6 +41066,7 @@ void ApiTest(void) test_EVP_PKEY_rsa(); test_wolfSSL_EVP_PKEY_encrypt(); test_wolfSSL_EVP_PKEY_sign(); + test_wolfSSL_EVP_PKEY_print_public(); test_EVP_PKEY_ec(); test_EVP_PKEY_cmp(); /* OpenSSL error API tests */ @@ -40963,6 +41401,8 @@ void ApiTest(void) AssertIntEQ(test_ToTraditional(), 0); AssertIntEQ(test_wc_EccPrivateKeyToDer(), 0); + AssertIntEQ(test_wc_EccPublicKeyDecode_ex(), 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 c645e2666..d2894b0a1 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -4515,6 +4515,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 + * + * 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) */ @@ -16221,6 +16275,67 @@ static int EccKeyParamCopy(char** dst, char* src) } #endif /* WOLFSSL_CUSTOM_CURVES */ +int wc_EccPublicKeyDecode_ex(const byte* input, + word32* inOutIdx, int* curveId, + word32* pointIdx, int* pointSz, word32 inSz) +{ + int ret; + int version, length; + word32 oidSum, localIdx; + byte tag; + + if (input == NULL || inOutIdx == NULL || curveId == NULL || + pointIdx == NULL || pointSz == NULL || inSz == 0) + return BAD_FUNC_ARG; + + if (GetSequence(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + if (GetMyVersion(input, inOutIdx, &version, inSz) >= 0) + return ASN_PARSE_E; + + if (GetSequence(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + ret = SkipObjectId(input, inOutIdx, inSz); + if (ret != 0) + return ret; + + if (*inOutIdx >= inSz) { + return BUFFER_E; + } + + localIdx = *inOutIdx; + + if (GetASNTag(input, &localIdx, &tag, inSz) == 0 && + tag == (ASN_SEQUENCE | ASN_CONSTRUCTED)) { + return BAD_FUNC_ARG; /* given key is not a public key*/ + } + + /* ecc params information */ + ret = GetObjectId(input, inOutIdx, &oidSum, oidIgnoreType, inSz); + if (ret != 0) + return ret; + + /* get curve id */ + if ((ret = CheckCurve(oidSum)) < 0) + return ECC_CURVE_OID_E; + else { + *curveId = ret; + } + + /* key header */ + ret = CheckBitString(input, inOutIdx, &length, inSz, 1, NULL); + if (ret != 0) + return ret; + + *pointIdx = *inOutIdx; + *pointSz = length; + *inOutIdx += length; + + return 0; +} + int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, word32 inSz) { diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 8f4471e80..b8a0b6344 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -6803,6 +6803,732 @@ void wolfSSL_EVP_PKEY_free(WOLFSSL_EVP_PKEY* key) } } } +#if defined(OPENSSL_EXTRA) +static int ToHex( byte in, byte* hex ) +{ + if ( hex == NULL ) + return 0; + + byte HexTbl[16] = { '0','1','2','3','4','5','6','7', + '8','9','a','b','c','d','e','f' }; + + byte UpNibble = (in >> 4) & 0x0f; + byte LwNibble = in & 0x0f; + + *hex++ = HexTbl[UpNibble]; + *hex = HexTbl[LwNibble]; + return 2; +} +/* convert input value to upto five digit decimal */ +static int ToDec(word32 in, byte* hex) +{ + if (hex == NULL || in > 99999 ) + return 0; + + byte dgt[5]; + word32 quo = in; + + dgt[4] = quo % 10; + quo = quo / 10; + dgt[3] = quo % 10; + quo = quo / 10; + dgt[2] = quo % 10; + quo = quo / 10; + dgt[1] = quo % 10; + quo = quo / 10; + dgt[0] = quo % 10; + + /* to remove leading zero */ + int i = 0; + if (dgt[0] == 0) { + if (dgt[1] == 0) { + if (dgt[2] == 0) { + if (dgt[3] == 0) { + i = 4; + }else + i = 3; + }else + i = 2; + }else + i = 1; + }else + i = 0; + + int wrote = 5 - i; + + for (; i < 5; i++) { + *hex++ = dgt[i] + '0'; + } + return wrote; +} +static int Indent(int indents, byte* dst ) +{ + if (dst == NULL) + return 0; + + for (int i = indents; i; i--) {*dst++ = ' ';} + return indents; +} +static int DumpElement(WOLFSSL_BIO* out, const byte* input, + int inlen, int indent) +{ + int idx = 0; + int wsz = 0; + byte buff[128] = { 0 }; + + /* print pub element */ + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + const byte* point = input; + word32 len = inlen; + word32 line = len / 15; + word32 left = len % 15; + word32 in = 0; + word32 i; + + while (line) { + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + for (i = 0; i < 15; i++) { /* 15 byte per line*/ + wsz = ToHex(point[in++], buff + idx); + idx += wsz; + XMEMSET(buff + idx, ':', 1); + wsz = 1; + idx += wsz; + } + wsz = 1; + XMEMSET(buff + idx, '\n', wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + idx = 0; + wsz = 0; + line--; + } + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + for (i = 0; i < left; i++) { + wsz = ToHex(point[in++], buff + idx); + idx += wsz; + if (i != left - 1) { + wsz = 1; + XMEMSET(buff + idx, ':', wsz); + idx += wsz; + } + } + wsz = 1; + XMEMSET(buff + idx, '\n', wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + return idx; +} +static int PrintPubKeyRSA(WOLFSSL_BIO* out, const byte* pkey, int pkeySz, + int indent, int bitlen, ASN1_PCTX* pctx) +{ + int res; + byte buff[128] = { 0 }; + + word32 inOutIdx = 0; + word32 nSz = 0; /* size of modulus */ + word32 eSz = 0; /* size of public exponent */ + byte* n = NULL; + byte* e = NULL; /* pointer to modulus/exponent */ + + (void)pctx; + + if ((res = wc_RsaPublicKeyDecode_ex(pkey, &inOutIdx, pkeySz, + (const byte**)&n, &nSz, (const byte**)&e, &eSz)) != 0) { + return WOLFSSL_FAILURE; + } + int idx = 0; + int wsz = 0; + + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("RSA Public-Key: (") - 1; + XSTRNCPY((char*)(buff + idx), "RSA Public-Key: (", wsz ); + idx += wsz; + + wsz = ToDec(bitlen, buff + idx); + idx += wsz; + + wsz = sizeof(" bit)\n") - 1; + XSTRNCPY((char*)(buff + idx), " bit)\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + /* print Modulus */ + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("Modulus:\n") - 1; + XSTRNCPY((char*)(buff + idx), "Modulus:\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + DumpElement(out, n, nSz, indent + 4); + + /* print public Exponent */ + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("Exponent: ") - 1; + XSTRNCPY((char*)(buff + idx), "Exponent: ", wsz); + idx += wsz; + + word32 exponent = 0; + for (word32 i = 0; i < eSz; i++) { + exponent <<= 8; + exponent += e[i]; + } + wsz = ToDec(exponent, buff + idx); + idx += wsz; + + wsz = sizeof(" (0x") - 1; + XSTRNCPY((char*)(buff + idx), " (0x", wsz); + idx += wsz; + + for (word32 i = 0; i < eSz; i++) { + wsz = ToHex(e[i], buff + idx); + idx += wsz; + } + wsz = sizeof(")\n") - 1; + XSTRNCPY((char*)(buff + idx), ")\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + return WOLFSSL_SUCCESS; +} +#if defined(HAVE_ECC) +static int PrintPubKeyEC(WOLFSSL_BIO* out, const byte* pkey, int pkeySz, + int indent, int bitlen, ASN1_PCTX* pctx) +{ + (void)pctx; + + int res = WOLFSSL_SUCCESS; + byte buff[128] = { 0 }; + word32 inOutIdx = 0; + + int curveId; + word32 pointIdx; + int pointSz; + char* OIDName = NULL; + const char* nistCurveName = NULL; + int nid; + WOLFSSL_ObjectInfo* oi = NULL; + + inOutIdx = 0; + res = wc_EccPublicKeyDecode_ex(pkey, &inOutIdx, &curveId, + &pointIdx, &pointSz, pkeySz); + if (res != 0) + return WOLFSSL_FAILURE; + + nid = EccEnumToNID(curveId); + + /* look up object name from object info table */ + + oi = (WOLFSSL_ObjectInfo*)wolfssl_object_info; + OIDName = NULL; + for (size_t i = 0;i < wolfssl_object_info_sz; i++) { + if ( (oi + i)->type == oidCurveType && (oi + i)->nid == nid) { + OIDName = (char*)((oi + i)->sName); + break; + } + } + + /* get NIST curve name */ + nistCurveName = wolfSSL_EC_curve_nid2nist(nid); + + int idx = 0; + int wsz = 0; + + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("Public-Key: (") - 1; + XSTRNCPY((char*)(buff + idx), "Public-Key: (", wsz); + idx += wsz; + + wsz = ToDec(bitlen, buff + idx); + idx += wsz; + + wsz = sizeof(" bit)\n") - 1; + XSTRNCPY((char*)(buff + idx), " bit)\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + /* print pub element */ + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("pub:\n") - 1; + XSTRNCPY((char*)(buff + idx), "pub:\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + DumpElement(out, pkey + pointIdx, pointSz, indent + 4); + + /* print OID in name */ + + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("ASN1 OID: ") - 1; + XSTRNCPY((char*)(buff + idx), "ASN1 OID: ", wsz); + idx += wsz; + + wsz = XSTRLEN(OIDName); + XSTRNCPY((char*)(buff + idx), OIDName, wsz); + idx += wsz; + + wsz = sizeof("\n") - 1; + XSTRNCPY((char*)(buff + idx), "\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + /* print NIST curve name */ + + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("NIST CURVE: ") - 1; + XSTRNCPY((char*)(buff + idx), "NIST CURVE: ", wsz); + idx += wsz; + + wsz = XSTRLEN(nistCurveName); + XSTRNCPY((char*)(buff + idx), nistCurveName, wsz); + idx += wsz; + + wsz = sizeof("\n") - 1; + XSTRNCPY((char*)(buff + idx), "\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + return WOLFSSL_SUCCESS; +} +#endif /* HAVE_ECC */ + +static int PrintPubKeyDSA(WOLFSSL_BIO* out, const byte* pkey, int pkeySz, + int indent, int bitlen, ASN1_PCTX* pctx) +{ + (void)pctx; + int length; + int res; + byte buff[128] = { 0 }; + word32 inOutIdx = 0; + word32 oid; + byte tagFound; + byte *p = NULL, * q = NULL, * g = NULL, * y = NULL; + int pSz, qSz, gSz, ySz; + + inOutIdx = 0; + 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; + + int idx = 0; + int wsz = 0; + + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("DSA Public-Key: (") - 1; + XSTRNCPY((char*)(buff + idx), "DSA Public-Key: (", wsz); + idx += wsz; + + wsz = ToDec(bitlen, buff + idx); + idx += wsz; + + wsz = sizeof(" bit)\n") - 1; + XSTRNCPY((char*)(buff + idx), " bit)\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + /* print pub element */ + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("pub:\n") - 1; + XSTRNCPY((char*)(buff + idx), "pub:\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + DumpElement(out, y, ySz, indent + 4); + + /* print P element */ + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("P:\n") - 1; + XSTRNCPY((char*)(buff + idx), "P:\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + DumpElement(out, p, pSz, indent + 4); + + /* print Q element */ + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("Q:\n") - 1; + XSTRNCPY((char*)(buff + idx), "Q:\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + DumpElement(out, q, qSz, indent + 4); + + /* print G element */ + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("G:\n") - 1; + XSTRNCPY((char*)(buff + idx), "G:\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + DumpElement(out, g, gSz, indent + 4); + + return WOLFSSL_SUCCESS; +} +static int PrintPubKeyDH(WOLFSSL_BIO* out, const byte* pkey, int pkeySz, + int indent, int bitlen, ASN1_PCTX* pctx) +{ + (void)pctx; + word32 length; + byte buff[128] = { 0 }; + word32 inOutIdx = 0; + word32 oid; + byte tagFound; + byte* prime = NULL; + int primeSz; + byte generator; + byte* publicKey = NULL; + int publicKeySz; + + inOutIdx = 0; + 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 */ + int idx = 0; + int wsz = 0; + + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("DH Public-Key: (") - 1; + XSTRNCPY((char*)(buff + idx), "DH Public-Key: (", wsz); + idx += wsz; + + wsz = ToDec(bitlen, buff + idx); + idx += wsz; + + wsz = sizeof(" bit)\n") - 1; + XSTRNCPY((char*)(buff + idx), " bit)\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("public-key:\n") - 1; + XSTRNCPY((char*)(buff + idx), "public-key:\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + DumpElement(out, publicKey, publicKeySz, indent + 4); + + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("prime:\n") - 1; + XSTRNCPY((char*)(buff + idx), "prime:\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + DumpElement(out, prime, primeSz, indent + 4); + + idx = 0; + wsz = Indent(indent, buff + idx); + idx += wsz; + + wsz = sizeof("generator: ") - 1; + XSTRNCPY((char*)(buff + idx), "generator: ", wsz); + idx += wsz; + + wsz = ToDec(generator, buff + idx); + idx += wsz; + + wsz = sizeof(" (0x") - 1; + XSTRNCPY((char*)(buff + idx), " (0x", wsz); + idx += wsz; + + wsz = ToHex(generator, buff + idx); + idx += wsz; + + wsz = sizeof(")\n") - 1; + XSTRNCPY((char*)(buff + idx), ")\n", wsz); + idx += wsz; + + wolfSSL_BIO_write(out, buff, idx); + XMEMSET(buff, 0, sizeof(buff)); + + return WOLFSSL_SUCCESS; +} +/* + * output public key info in human readable format + * returns 1 on success, 0 or negative on error. + * -2 means specified key algo is not supported. + */ +int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, + const WOLFSSL_EVP_PKEY* pkey, int indent, ASN1_PCTX* pctx) +{ + int res = 1; + int keybits; /* bit length of the key */ + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_print_public"); + + if (pkey == NULL || out == NULL) + return 0; + + switch (pkey->type) { + case EVP_PKEY_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 */ + 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 = -2; /* not supported algo */ +#endif + break; + + case EVP_PKEY_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 */ + break; + + case EVP_PKEY_DH: + + 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 */ + break; + + default: + res = -2; /* not supported algo */ + } + 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 9c6fd4a76..fabf967eb 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/openssl/evp.h b/wolfssl/openssl/evp.h index 98cc122f0..5d6261ac4 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -372,6 +372,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; @@ -668,6 +673,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 @@ -898,6 +904,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 0c81c9b77..593cfba11 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1517,6 +1517,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/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 450f845eb..8498a9d03 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -522,6 +522,9 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer); word32* outLen); /* public key helper */ + WOLFSSL_API int wc_EccPublicKeyDecode_ex(const byte* input, + word32* inOutIdx, int* curveId, + word32* pointIdx, int* pointSz, word32 inSz); WOLFSSL_API int wc_EccPublicKeyDecode(const byte*, word32*, ecc_key*, word32); WOLFSSL_API int wc_EccPublicKeyToDer(ecc_key*, byte* output, diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 8bc1dd3d4..8ee18f0a0 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -117,6 +117,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,