Skip to content

Commit

Permalink
Merge pull request #7751 from SparkiDev/ecc_koblitz_ssl
Browse files Browse the repository at this point in the history
ECC key load: fixes
  • Loading branch information
dgarske authored Jul 22, 2024
2 parents a3b6ec4 + dc86dad commit 7c6eb7c
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-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgwdc3WnnD2eX1ti0IbCT5
POy/xb1WDV8/7BgQd37MsWGhRANCAARvf9jvkv6kKKkzhWmk6OM3Rjmivo8mMVkg
itdbdHrKAV5UT9zS0qXbHo7mlPZOOejEsodSk9yvzjAAnHnSSASY
-----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:
23:8d:e3:d0:5a:a6:1f:e6:d3:b6:4c:e0:a2:a1:dd:2f:ee:35:b2:bb
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 15 05:41:52 2024 GMT
Not After : Jul 13 05:41:52 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:6f:7f:d8:ef:92:fe:a4:28:a9:33:85:69:a4:e8:
e3:37:46:39:a2:be:8f:26:31:59:20:8a:d7:5b:74:
7a:ca:01:5e:54:4f:dc:d2:d2:a5:db:1e:8e:e6:94:
f6:4e:39:e8:c4:b2:87:52:93:dc:af:ce:30:00:9c:
79:d2:48:04:98
ASN1 OID: secp256k1
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Server
X509v3 Subject Key Identifier:
F4:A3:FD:34:57:E6:51:1F:0A:96:2F:F0:87:A9:7C:C7:EB:6B:34:8F
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:3d:12:5a:0c:7a:1b:ff:b5:a6:70:8a:70:33:03:
6c:d9:9c:98:8b:80:1b:70:3b:15:3a:85:7e:23:8a:85:f0:76:
02:20:02:ca:71:2c:cc:5a:c2:a8:e2:c5:24:62:06:62:a0:53:
41:2a:bb:2e:88:9f:f0:b4:bd:dc:23:1c:06:4c:18:a2
-----BEGIN CERTIFICATE-----
MIIDcTCCAxigAwIBAgIUI43j0FqmH+bTtkzgoqHdL+41srswCgYIKoZIzj0EAwIw
gZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdT
ZWF0dGxlMREwDwYDVQQKDAhFbGxpcHRpYzESMBAGA1UECwwJU0VDUDI1NksxMRgw
FgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29s
ZnNzbC5jb20wHhcNMjQwNzE1MDU0MTUyWhcNMzQwNzEzMDU0MTUyWjCBmjELMAkG
A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx
ETAPBgNVBAoMCEVsbGlwdGljMRYwFAYDVQQLDA1TRUNQMjU2SzEtU1ZSMRgwFgYD
VQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNz
bC5jb20wVjAQBgcqhkjOPQIBBgUrgQQACgNCAARvf9jvkv6kKKkzhWmk6OM3Rjmi
vo8mMVkgitdbdHrKAV5UT9zS0qXbHo7mlPZOOejEsodSk9yvzjAAnHnSSASYo4IB
PzCCATswCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwHQYDVR0OBBYEFPSj
/TRX5lEfCpYv8IepfMfrazSPMIHWBgNVHSMEgc4wgcuAFHMvyjoty+LjosGrLzXM
ZFNkjAYtoYGcpIGZMIGWMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3Rv
bjEQMA4GA1UEBwwHU2VhdHRsZTERMA8GA1UECgwIRWxsaXB0aWMxEjAQBgNVBAsM
CVNFQ1AyNTZLMTEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcN
AQkBFhBpbmZvQHdvbGZzc2wuY29tghRyYEh0RSLRa2mh8ozevjouWG/zojAOBgNV
HQ8BAf8EBAMCA6gwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCgYIKoZIzj0EAwIDRwAw
RAIgPRJaDHob/7WmcIpwMwNs2ZyYi4AbcDsVOoV+I4qF8HYCIALKcSzMWsKo4sUk
YgZioFNBKrsuiJ/wtL3cIxwGTBii
-----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 @@ -33910,6 +33947,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 @@ -33919,11 +33957,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 @@ -2235,6 +2235,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 7c6eb7c

Please sign in to comment.