From 0d7d8f54e0f6196cfb3ef53206877a3964db1f28 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 16 Oct 2018 16:56:42 -0700 Subject: [PATCH 1/3] Added support for ECC private key with PKCS8 parsing. Fix is to attempt pkcs8 parse for `-----BEGIN EC PRIVATE KEY-----` and if parse fails to treat as normal private key. ZD 4379. --- wolfcrypt/src/asn.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 689896a63..4dca03160 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -8512,12 +8512,20 @@ int PemToDer(const unsigned char* buff, long longSz, int type, der->buffer, &der->length) < 0) return BUFFER_E; - if (header == BEGIN_PRIV_KEY && !encrypted_key) { + if ((header == BEGIN_PRIV_KEY +#ifdef HAVE_ECC + || header == BEGIN_EC_PRIV +#endif + ) && !encrypted_key) + { /* pkcs8 key, convert and adjust length */ - if ((ret = ToTraditional(der->buffer, der->length)) < 0) - return ret; + if ((ret = ToTraditional(der->buffer, der->length)) > 0) { + der->length = ret; + } + else { + /* ignore failure here and assume key is not pkcs8 wrapped */ + } - der->length = ret; return 0; } From 8b529d3d57e79be3f72f68bea126446dd99052d9 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 17 Oct 2018 10:01:29 -0700 Subject: [PATCH 2/3] Add test for ECC private key with PKCS 8 encoding (no crypt) and `-----BEGIN EC PRIVATE KEY-----` header. --- certs/ecc-privkeyPkcs8.pem | 4 ++++ certs/include.am | 1 + tests/api.c | 46 +++++++++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 certs/ecc-privkeyPkcs8.pem diff --git a/certs/ecc-privkeyPkcs8.pem b/certs/ecc-privkeyPkcs8.pem new file mode 100644 index 000000000..7793f7257 --- /dev/null +++ b/certs/ecc-privkeyPkcs8.pem @@ -0,0 +1,4 @@ +-----BEGIN EC PRIVATE KEY----- +MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBFtmkCc5xshaE4W3Lo +6MesxAONUzUE+mwo3DSN4agJjA== +-----END EC PRIVATE KEY----- diff --git a/certs/include.am b/certs/include.am index fd50e9035..cf7a4aa11 100644 --- a/certs/include.am +++ b/certs/include.am @@ -12,6 +12,7 @@ EXTRA_DIST += \ certs/client-relative-uri.pem \ certs/ecc-key.pem \ certs/ecc-privkey.pem \ + certs/ecc-privkeyPkcs8.pem \ certs/ecc-keyPkcs8Enc.pem \ certs/ecc-key-comp.pem \ certs/ecc-keyPkcs8.pem \ diff --git a/tests/api.c b/tests/api.c index c565bdda6..980ae13ec 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3529,24 +3529,33 @@ static WC_INLINE int PKCS8TestCallBack(char* passwd, int sz, int rw, void* userd } #endif + /* Testing functions dealing with PKCS8 */ static void test_wolfSSL_PKCS8(void) { -#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ - !defined(NO_DES3) && !defined(NO_FILESYSTEM) && \ - !defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_RSA) && \ - defined(WOLFSSL_ENCRYPTED_KEYS) +#if !defined(NO_FILESYSTEM) && !defined(NO_ASN) byte buffer[FOURK_BUF]; byte der[FOURK_BUF]; - char file[] = "./certs/server-keyPkcs8Enc.pem"; + const char eccPkcs8PrivKeyFile[] = "./certs/ecc-privkeyPkcs8.pem"; XFILE f; - int flag = 1; - int bytes; + int bytes; +#ifdef HAVE_ECC + ecc_key key; + word32 x = 0; +#endif +#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ + defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && \ + !defined(NO_PWDBASED) && !defined(NO_RSA) + #define TEST_PKCS8_ENC + const char serverKeyPkcs8EncFile[] = "./certs/server-keyPkcs8Enc.pem"; + int flag = 1; WOLFSSL_CTX* ctx; +#endif printf(testingFmt, "wolfSSL_PKCS8()"); - f = XFOPEN(file, "rb"); +#ifdef TEST_PKCS8_ENC + f = XFOPEN(serverKeyPkcs8EncFile, "rb"); AssertTrue((f != XBADFILE)); bytes = (int)XFREAD(buffer, 1, sizeof(buffer), f); XFCLOSE(f); @@ -3579,14 +3588,29 @@ static void test_wolfSSL_PKCS8(void) wolfSSL_CTX_free(ctx); /* decrypt PKCS8 PEM to key in DER format with not using WOLFSSL_CTX */ - AssertIntGT(wc_KeyPemToDer(buffer, bytes, der, FOURK_BUF, "yassl123"), - 0); + AssertIntGT(wc_KeyPemToDer(buffer, bytes, der, FOURK_BUF, "yassl123"), 0); /* test that error value is returned with a bad password */ AssertIntLT(wc_KeyPemToDer(buffer, bytes, der, FOURK_BUF, "bad"), 0); +#endif /* TEST_PKCS8_ENC */ + + /* Test PKCS8 PEM ECC key no crypt */ + f = XFOPEN(eccPkcs8PrivKeyFile, "rb"); + AssertTrue((f != XBADFILE)); + bytes = (int)XFREAD(buffer, 1, sizeof(buffer), f); + XFCLOSE(f); + + /* decrypt PKCS8 PEM to key in DER format with not using WOLFSSL_CTX */ +#ifdef HAVE_ECC + AssertIntGT((bytes = wc_KeyPemToDer(buffer, bytes, der, FOURK_BUF, NULL)), 0); + AssertIntEQ(wc_EccPrivateKeyDecode(der, &x, &key, bytes), 0); +#else + AssertIntEQ((bytes = wc_KeyPemToDer(buffer, bytes, der, FOURK_BUF, NULL)), + ASN_NO_PEM_HEADER); +#endif printf(resultFmt, passed); -#endif /* OPENSSL_EXTRA */ +#endif /* !NO_FILESYSTEM && !NO_ASN */ } /* Testing functions dealing with PKCS5 */ From 7ce236f3af85395c355ab46355ea9c2fe8204aca Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 19 Oct 2018 16:04:02 -0700 Subject: [PATCH 3/3] Fix for new `test_wolfSSL_PKCS8` changes to init/free the ecc_key. --- tests/api.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 980ae13ec..029cb44d2 100644 --- a/tests/api.c +++ b/tests/api.c @@ -3540,6 +3540,7 @@ static void test_wolfSSL_PKCS8(void) XFILE f; int bytes; #ifdef HAVE_ECC + int ret; ecc_key key; word32 x = 0; #endif @@ -3603,7 +3604,12 @@ static void test_wolfSSL_PKCS8(void) /* decrypt PKCS8 PEM to key in DER format with not using WOLFSSL_CTX */ #ifdef HAVE_ECC AssertIntGT((bytes = wc_KeyPemToDer(buffer, bytes, der, FOURK_BUF, NULL)), 0); - AssertIntEQ(wc_EccPrivateKeyDecode(der, &x, &key, bytes), 0); + ret = wc_ecc_init(&key); + if (ret == 0) { + ret = wc_EccPrivateKeyDecode(der, &x, &key, bytes); + wc_ecc_free(&key); + } + AssertIntEQ(ret, 0); #else AssertIntEQ((bytes = wc_KeyPemToDer(buffer, bytes, der, FOURK_BUF, NULL)), ASN_NO_PEM_HEADER);