Skip to content

Commit

Permalink
ECC key load: fixes
Browse files Browse the repository at this point in the history
asn.c:
  Return the curve OID sum with alg_id for ECC keys.
ssl_load.c:
Don't permanently strip the PKCS#8 information as it contains the
curve OID.
  • Loading branch information
SparkiDev committed Jul 12, 2024
1 parent db4177a commit 753e050
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 20 deletions.
16 changes: 16 additions & 0 deletions certs/ecc/ca-secp256k1-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE-----
MIICkTCCAjagAwIBAgIUcmBIdEUi0WtpofKM3r46Llhv86IwCgYIKoZIzj0EAwIw
gZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdT
ZWF0dGxlMREwDwYDVQQKDAhFbGxpcHRpYzESMBAGA1UECwwJU0VDUDI1NksxMRgw
FgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29s
ZnNzbC5jb20wHhcNMjQwNzEyMDIxODUwWhcNNDQwNzA3MDIxODUwWjCBljELMAkG
A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx
ETAPBgNVBAoMCEVsbGlwdGljMRIwEAYDVQQLDAlTRUNQMjU2SzExGDAWBgNVBAMM
D3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNv
bTBWMBAGByqGSM49AgEGBSuBBAAKA0IABORg5kLTHlkHvjnrRKUTmBXLdhxkdsIC
s0ybo6r3oD6qGjX33FsBHp9nwos93gT7CECrexVlEUrH4wbfMN42+46jYzBhMB0G
A1UdDgQWBBRzL8o6Lcvi46LBqy81zGRTZIwGLTAfBgNVHSMEGDAWgBRzL8o6Lcvi
46LBqy81zGRTZIwGLTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAK
BggqhkjOPQQDAgNJADBGAiEA0dfMbQlfjY+VhKuDfluyBtoAsQA1BqJnV+XBayBx
HYYCIQCJr2YrYRwW4OvtP0yIqUH2fViOq12aqf1ByStksuL3mg==
-----END CERTIFICATE-----
5 changes: 5 additions & 0 deletions certs/ecc/ca-secp256k1-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgoiOQsNn1L/vT3mU0e+Rz
LMlaDEIuKp6RHZhKrPnOJOShRANCAATkYOZC0x5ZB74560SlE5gVy3YcZHbCArNM
m6Oq96A+qho199xbAR6fZ8KLPd4E+whAq3sVZRFKx+MG3zDeNvuO
-----END PRIVATE KEY-----
7 changes: 7 additions & 0 deletions certs/ecc/genecc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ openssl x509 -req -in ./certs/ecc/client-bp256r1-req.pem -days 3650 -extfile ./c
openssl x509 -inform pem -in ./certs/ecc/client-bp256r1-cert.pem -outform der -out ./certs/ecc/client-bp256r1-cert.der
rm ./certs/ecc/client-bp256r1-req.pem

# Create self-signed ECC secp256k1 (Koblitz) certificate
openssl req -config ./certs/ecc/wolfssl.cnf -extensions v3_ca -x509 -nodes -newkey ec:certs/ecc/secp256k1-param.pem -keyout ./certs/ecc/ca-secp256k1-key.pem -out ./certs/ecc/ca-secp256k1-cert.pem -sha256 -days 7300 -batch -subj "/C=US/ST=Washington/L=Seattle/O=Elliptic/OU=SECP256K1/CN=www.wolfssl.com/emailAddress=info@wolfssl.com"
# Create server ECC secp256k1 (Koblitz) certificate
openssl req -config ./certs/ecc/wolfssl.cnf -sha256 -new -key ./certs/ecc/secp256k1-privkey.pem -out ./certs/ecc/server2-secp256k1-req.pem -subj "/C=US/ST=Washington/L=Seattle/O=Elliptic/OU=SECP256K1-SVR/CN=www.wolfssl.com/emailAddress=info@wolfssl.com/"
openssl x509 -req -in ./certs/ecc/server2-secp256k1-req.pem -days 3650 -extfile ./certs/ecc/wolfssl.cnf -extensions server_cert -CAkey ./certs/ecc/ca-secp256k1-key.pem -CA ./certs/ecc/ca-secp256k1-cert.pem -text -out ./certs/ecc/server2-secp256k1-cert.pem
openssl x509 -inform pem -in ./certs/ecc/server2-secp256k1-cert.pem -outform der -out ./certs/ecc/server2-secp256k1-cert.der
rm ./certs/ecc/server2-secp256k1-req.pem

# update bad certificate with last byte in signature changed
cp ./certs/server-ecc.der ./certs/test/server-cert-ecc-badsig.der
Expand Down
7 changes: 7 additions & 0 deletions certs/ecc/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ EXTRA_DIST += \
certs/ecc/server-secp256k1-cert.der \
certs/ecc/server-secp256k1-cert.pem

EXTRA_DIST += \
certs/ecc/ca-secp256k1-cert.pem \
certs/ecc/ca-secp256k1-key.pem \
certs/ecc/secp256k1-param.pem \
certs/ecc/secp256k1-privkey.pem \
certs/ecc/server2-secp256k1-cert.pem

# Brainpool Curves
EXTRA_DIST += \
certs/ecc/bp256r1-key.der \
Expand Down
3 changes: 3 additions & 0 deletions certs/ecc/secp256k1-param.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
Binary file added certs/ecc/secp256k1-privkey.der
Binary file not shown.
5 changes: 5 additions & 0 deletions certs/ecc/secp256k1-privkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQg6rspgXX87ZEhSC11rGc4
RTaVVezDK82eiuFYuqdxBZ2hRANCAAQA/k2l9x5yZrTwZ3Cly7lMJj0JGE76tniN
d6Ibl94meWfexF96fgnb2LuxfUsFkWGfOGz6Cb0EYOu+DNrEuvtU
-----END PRIVATE KEY-----
Binary file added certs/ecc/server2-secp256k1-cert.der
Binary file not shown.
63 changes: 63 additions & 0 deletions certs/ecc/server2-secp256k1-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
66:a7:a6:4f:0f:96:22:01:77:eb:3e:00:7a:13:fc:a0:4f:2f:39:ff
Signature Algorithm: ecdsa-with-SHA256
Issuer: C=US, ST=Washington, L=Seattle, O=Elliptic, OU=SECP256K1, CN=www.wolfssl.com, emailAddress=info@wolfssl.com
Validity
Not Before: Jul 12 02:18:50 2024 GMT
Not After : Jul 10 02:18:50 2034 GMT
Subject: C=US, ST=Washington, L=Seattle, O=Elliptic, OU=SECP256K1-SVR, CN=www.wolfssl.com, emailAddress=info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:00:fe:4d:a5:f7:1e:72:66:b4:f0:67:70:a5:cb:
b9:4c:26:3d:09:18:4e:fa:b6:78:8d:77:a2:1b:97:
de:26:79:67:de:c4:5f:7a:7e:09:db:d8:bb:b1:7d:
4b:05:91:61:9f:38:6c:fa:09:bd:04:60:eb:be:0c:
da:c4:ba:fb:54
ASN1 OID: secp256k1
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Server
X509v3 Subject Key Identifier:
D2:3C:80:8F:B8:86:48:B2:B7:7D:BB:44:41:9C:1A:EF:6D:02:62:4F
X509v3 Authority Key Identifier:
keyid:73:2F:CA:3A:2D:CB:E2:E3:A2:C1:AB:2F:35:CC:64:53:64:8C:06:2D
DirName:/C=US/ST=Washington/L=Seattle/O=Elliptic/OU=SECP256K1/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
serial:72:60:48:74:45:22:D1:6B:69:A1:F2:8C:DE:BE:3A:2E:58:6F:F3:A2
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:44:02:20:32:42:b5:1c:d6:58:ec:f5:87:fe:89:bb:54:34:
ff:00:a6:8e:ad:b5:12:78:fa:d7:4e:f8:b5:11:81:42:eb:e9:
02:20:26:89:1f:ec:60:92:f9:e6:6c:b3:98:ab:8f:ca:60:94:
04:f0:51:e6:51:2e:a9:df:5a:97:1a:37:e5:98:ce:02
-----BEGIN CERTIFICATE-----
MIIDcTCCAxigAwIBAgIUZqemTw+WIgF36z4AehP8oE8vOf8wCgYIKoZIzj0EAwIw
gZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdT
ZWF0dGxlMREwDwYDVQQKDAhFbGxpcHRpYzESMBAGA1UECwwJU0VDUDI1NksxMRgw
FgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29s
ZnNzbC5jb20wHhcNMjQwNzEyMDIxODUwWhcNMzQwNzEwMDIxODUwWjCBmjELMAkG
A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx
ETAPBgNVBAoMCEVsbGlwdGljMRYwFAYDVQQLDA1TRUNQMjU2SzEtU1ZSMRgwFgYD
VQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNz
bC5jb20wVjAQBgcqhkjOPQIBBgUrgQQACgNCAAQA/k2l9x5yZrTwZ3Cly7lMJj0J
GE76tniNd6Ibl94meWfexF96fgnb2LuxfUsFkWGfOGz6Cb0EYOu+DNrEuvtUo4IB
PzCCATswCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwHQYDVR0OBBYEFNI8
gI+4hkiyt327REGcGu9tAmJPMIHWBgNVHSMEgc4wgcuAFHMvyjoty+LjosGrLzXM
ZFNkjAYtoYGcpIGZMIGWMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
bjEQMA4GA1UEBwwHU2VhdHRsZTERMA8GA1UECgwIRWxsaXB0aWMxEjAQBgNVBAsM
CVNFQ1AyNTZLMTEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcN
AQkBFhBpbmZvQHdvbGZzc2wuY29tghRyYEh0RSLRa2mh8ozevjouWG/zojAOBgNV
HQ8BAf8EBAMCA6gwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCgYIKoZIzj0EAwIDRwAw
RAIgMkK1HNZY7PWH/om7VDT/AKaOrbUSePrXTvi1EYFC6+kCICaJH+xgkvnmbLOY
q4/KYJQE8FHmUS6p31qXGjflmM4C
-----END CERTIFICATE-----
14 changes: 0 additions & 14 deletions src/ssl_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -1353,24 +1353,10 @@ static int ProcessBufferPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
int algId)
{
int ret;
#if (defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)) || \
defined(HAVE_PKCS8)
word32 p8AlgId = 0;
#endif

(void)info;
(void)format;

#ifdef HAVE_PKCS8
/* Try and remove PKCS8 header and get algorithm id. */
ret = ToTraditional_ex(der->buffer, der->length, &p8AlgId);
if (ret > 0) {
/* Header stripped inline. */
der->length = (word32)ret;
algId = p8AlgId;
}
#endif

/* Put the data into the SSL or SSL context object. */
ret = ProcessBufferPrivKeyHandleDer(ctx, ssl, &der, type);
if (ret == 0) {
Expand Down
16 changes: 16 additions & 0 deletions tests/test-ecc-cust-curves.conf
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,19 @@
-k ./certs/ecc/bp256r1-key.pem
-A ./certs/ecc/server-bp256r1-cert.pem
-C

# -- SECP256K1 without OID inside PKCS#8 --
# server TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256
-v 3
-l ECDHE-ECDSA-AES128-GCM-SHA256
-c ./certs/ecc/server2-secp256k1-cert.pem
-k ./certs/ecc/secp256k1-privkey.pem
-d

# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256
-v 3
-l ECDHE-ECDSA-AES128-GCM-SHA256
-A ./certs/ecc/ca-secp256k1-cert.pem
-x
-C

50 changes: 44 additions & 6 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -6858,6 +6858,7 @@ enum {
* On out, start of encoded key.
* @param [in] sz Size of data in buffer.
* @param [out] algId Key's algorithm id from PKCS #8 header.
* @param [out] eccOid ECC curve OID.
* @return Length of key data on success.
* @return BAD_FUNC_ARG when input or inOutIdx is NULL.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
Expand All @@ -6867,8 +6868,8 @@ enum {
* @return ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
* non-zero length.
*/
int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
word32* algId)
int ToTraditionalInline_ex2(const byte* input, word32* inOutIdx, word32 sz,
word32* algId, word32* eccOid)
{
#ifndef WOLFSSL_ASN_TEMPLATE
word32 idx;
Expand Down Expand Up @@ -6918,8 +6919,14 @@ int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
#endif /* WC_RSA_PSS && !NO_RSA */

if (tag == ASN_OBJECT_ID) {
if (SkipObjectId(input, &idx, sz) < 0)
return ASN_PARSE_E;
if ((*algId == ECDSAk) && (eccOid != NULL)) {
if (GetObjectId(input, &idx, eccOid, oidCurveType, maxIdx) < 0)
return ASN_PARSE_E;
}
else {
if (SkipObjectId(input, &idx, sz) < 0)
return ASN_PARSE_E;
}
}

ret = GetOctetString(input, &idx, &length, sz);
Expand All @@ -6940,6 +6947,8 @@ int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
byte version = 0;
word32 idx;

(void)eccOid;

/* Check validity of parameters. */
if (input == NULL || inOutIdx == NULL) {
return BAD_FUNC_ARG;
Expand Down Expand Up @@ -7013,6 +7022,11 @@ int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
if (dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) {
ret = ASN_PARSE_E;
}
if (eccOid != NULL) {
ASNGetData* oidCurve =
&dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE];
*eccOid = oidCurve->data.oid.sum;
}
break;
#endif
#ifdef HAVE_ED25519
Expand Down Expand Up @@ -7072,6 +7086,29 @@ int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
#endif
}

/* Remove PKCS #8 header around an RSA, ECDSA, Ed25519, or Ed448.
*
* @param [in] input Buffer holding BER data.
* @param [in, out] inOutIdx On in, start of PKCS #8 encoding.
* On out, start of encoded key.
* @param [in] sz Size of data in buffer.
* @param [out] algId Key's algorithm id from PKCS #8 header.
* @return Length of key data on success.
* @return BAD_FUNC_ARG when input or inOutIdx is NULL.
* @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or
* is invalid.
* @return BUFFER_E when data in buffer is too small.
* @return ASN_OBJECT_ID_E when the expected OBJECT_ID tag is not found.
* @return ASN_EXPECT_0_E when the INTEGER has the MSB set or NULL has a
* non-zero length.
*/
int ToTraditionalInline_ex(const byte* input, word32* inOutIdx, word32 sz,
word32* algId)
{
return ToTraditionalInline_ex2(input, inOutIdx, sz, algId, NULL);
}


/* TODO: test case */
int ToTraditionalInline(const byte* input, word32* inOutIdx, word32 sz)
{
Expand Down Expand Up @@ -33887,6 +33924,7 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
int curve_id = ECC_CURVE_DEF;
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(SM2)
word32 algId = 0;
word32 eccOid = 0;
#endif

/* Validate parameters. */
Expand All @@ -33896,11 +33934,11 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,

#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) || defined(SM2)
/* if has pkcs8 header skip it */
if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
if (ToTraditionalInline_ex2(input, inOutIdx, inSz, &algId, &eccOid) < 0) {
/* ignore error, did not have pkcs8 header */
}
else {
curve_id = wc_ecc_get_oid(algId, NULL, NULL);
curve_id = wc_ecc_get_oid(eccOid, NULL, NULL);
}
#endif

Expand Down
3 changes: 3 additions & 0 deletions wolfssl/wolfcrypt/asn.h
Original file line number Diff line number Diff line change
Expand Up @@ -2216,6 +2216,9 @@ WOLFSSL_LOCAL int ToTraditionalInline(const byte* input, word32* inOutIdx,
word32 length);
WOLFSSL_LOCAL int ToTraditionalInline_ex(const byte* input, word32* inOutIdx,
word32 length, word32* algId);
WOLFSSL_LOCAL int ToTraditionalInline_ex2(const byte* input, word32* inOutIdx,
word32 length, word32* algId,
word32* eccOid);
WOLFSSL_LOCAL int ToTraditionalEnc(byte* input, word32 sz, const char* password,
int passwordSz, word32* algId);
WOLFSSL_ASN_API int UnTraditionalEnc(byte* key, word32 keySz, byte* out,
Expand Down

0 comments on commit 753e050

Please sign in to comment.