forked from wolfSSL/wolfssl
ecc client certs
This commit is contained in:
54
certs/client-ecc-cert.pem
Normal file
54
certs/client-ecc-cert.pem
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
Certificate:
|
||||||
|
Data:
|
||||||
|
Version: 3 (0x2)
|
||||||
|
Serial Number:
|
||||||
|
bf:cc:cb:7a:0a:07:42:82
|
||||||
|
Signature Algorithm: ecdsa-with-SHA1
|
||||||
|
Issuer: C=US, ST=Oregon, L=Salem, O=Client ECC, OU=Fast, CN=www.yassl.com/emailAddress=info@yassl.com
|
||||||
|
Validity
|
||||||
|
Not Before: May 1 23:51:33 2012 GMT
|
||||||
|
Not After : Jan 26 23:51:33 2015 GMT
|
||||||
|
Subject: C=US, ST=Oregon, L=Salem, O=Client ECC, OU=Fast, CN=www.yassl.com/emailAddress=info@yassl.com
|
||||||
|
Subject Public Key Info:
|
||||||
|
Public Key Algorithm: id-ecPublicKey
|
||||||
|
EC Public Key:
|
||||||
|
pub:
|
||||||
|
04:55:bf:f4:0f:44:50:9a:3d:ce:9b:b7:f0:c5:4d:
|
||||||
|
f5:70:7b:d4:ec:24:8e:19:80:ec:5a:4c:a2:24:03:
|
||||||
|
62:2c:9b:da:ef:a2:35:12:43:84:76:16:c6:56:95:
|
||||||
|
06:cc:01:a9:bd:f6:75:1a:42:f7:bd:a9:b2:36:22:
|
||||||
|
5f:c7:5d:7f:b4
|
||||||
|
ASN1 OID: prime256v1
|
||||||
|
X509v3 extensions:
|
||||||
|
X509v3 Subject Key Identifier:
|
||||||
|
EB:D4:4B:59:6B:95:61:3F:51:57:B6:04:4D:89:41:88:44:5C:AB:F2
|
||||||
|
X509v3 Authority Key Identifier:
|
||||||
|
keyid:EB:D4:4B:59:6B:95:61:3F:51:57:B6:04:4D:89:41:88:44:5C:AB:F2
|
||||||
|
DirName:/C=US/ST=Oregon/L=Salem/O=Client ECC/OU=Fast/CN=www.yassl.com/emailAddress=info@yassl.com
|
||||||
|
serial:BF:CC:CB:7A:0A:07:42:82
|
||||||
|
|
||||||
|
X509v3 Basic Constraints:
|
||||||
|
CA:TRUE
|
||||||
|
Signature Algorithm: ecdsa-with-SHA1
|
||||||
|
30:44:02:20:26:08:44:95:35:2e:fa:9d:20:01:a6:79:60:ed:
|
||||||
|
35:a7:0a:dd:7a:0e:75:c5:80:d2:0b:9f:6a:90:d6:31:76:75:
|
||||||
|
02:20:2d:87:a2:bb:d5:e2:42:61:35:19:59:40:1d:fd:71:4f:
|
||||||
|
28:65:96:99:e6:85:1b:09:ad:d4:58:71:56:63:0b:c7
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIC+jCCAqKgAwIBAgIJAL/My3oKB0KCMAkGByqGSM49BAEwgYkxCzAJBgNVBAYT
|
||||||
|
AlVTMQ8wDQYDVQQIEwZPcmVnb24xDjAMBgNVBAcTBVNhbGVtMRMwEQYDVQQKEwpD
|
||||||
|
bGllbnQgRUNDMQ0wCwYDVQQLEwRGYXN0MRYwFAYDVQQDEw13d3cueWFzc2wuY29t
|
||||||
|
MR0wGwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbTAeFw0xMjA1MDEyMzUxMzNa
|
||||||
|
Fw0xNTAxMjYyMzUxMzNaMIGJMQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29u
|
||||||
|
MQ4wDAYDVQQHEwVTYWxlbTETMBEGA1UEChMKQ2xpZW50IEVDQzENMAsGA1UECxME
|
||||||
|
RmFzdDEWMBQGA1UEAxMNd3d3Lnlhc3NsLmNvbTEdMBsGCSqGSIb3DQEJARYOaW5m
|
||||||
|
b0B5YXNzbC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARVv/QPRFCaPc6b
|
||||||
|
t/DFTfVwe9TsJI4ZgOxaTKIkA2Ism9rvojUSQ4R2FsZWlQbMAam99nUaQve9qbI2
|
||||||
|
Il/HXX+0o4HxMIHuMB0GA1UdDgQWBBTr1EtZa5VhP1FXtgRNiUGIRFyr8jCBvgYD
|
||||||
|
VR0jBIG2MIGzgBTr1EtZa5VhP1FXtgRNiUGIRFyr8qGBj6SBjDCBiTELMAkGA1UE
|
||||||
|
BhMCVVMxDzANBgNVBAgTBk9yZWdvbjEOMAwGA1UEBxMFU2FsZW0xEzARBgNVBAoT
|
||||||
|
CkNsaWVudCBFQ0MxDTALBgNVBAsTBEZhc3QxFjAUBgNVBAMTDXd3dy55YXNzbC5j
|
||||||
|
b20xHTAbBgkqhkiG9w0BCQEWDmluZm9AeWFzc2wuY29tggkAv8zLegoHQoIwDAYD
|
||||||
|
VR0TBAUwAwEB/zAJBgcqhkjOPQQBA0cAMEQCICYIRJU1LvqdIAGmeWDtNacK3XoO
|
||||||
|
dcWA0gufapDWMXZ1AiAth6K71eJCYTUZWUAd/XFPKGWWmeaFGwmt1FhxVmMLxw==
|
||||||
|
-----END CERTIFICATE-----
|
9
certs/ecc-client-key.pem
Normal file
9
certs/ecc-client-key.pem
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
ASN1 OID: prime256v1
|
||||||
|
-----BEGIN EC PARAMETERS-----
|
||||||
|
BggqhkjOPQMBBw==
|
||||||
|
-----END EC PARAMETERS-----
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
MHcCAQEEIPjPkmu9HijxqKuhI08ydBiIUK1+x+yS+I+XTa9WiWXHoAoGCCqGSM49
|
||||||
|
AwEHoUQDQgAEVb/0D0RQmj3Om7fwxU31cHvU7CSOGYDsWkyiJANiLJva76I1EkOE
|
||||||
|
dhbGVpUGzAGpvfZ1GkL3vamyNiJfx11/tA==
|
||||||
|
-----END EC PRIVATE KEY-----
|
@ -107,6 +107,8 @@ static const char* cliKey = "./certs/client-key.pem";
|
|||||||
static const char* ntruCert = "./certs/ntru-cert.pem";
|
static const char* ntruCert = "./certs/ntru-cert.pem";
|
||||||
static const char* ntruKey = "./certs/ntru-key.raw";
|
static const char* ntruKey = "./certs/ntru-key.raw";
|
||||||
static const char* dhParam = "./certs/dh2048.pem";
|
static const char* dhParam = "./certs/dh2048.pem";
|
||||||
|
static const char* cliEccKey = "./certs/ecc-client-key.pem";
|
||||||
|
static const char* cliEccCert = "./certs/client-ecc-cert.pem";
|
||||||
|
|
||||||
typedef struct tcp_ready {
|
typedef struct tcp_ready {
|
||||||
int ready; /* predicate */
|
int ready; /* predicate */
|
||||||
|
@ -146,6 +146,17 @@ void client_test(void* args)
|
|||||||
/* ./client // plain mode */
|
/* ./client // plain mode */
|
||||||
/* for client cert authentication if server requests */
|
/* for client cert authentication if server requests */
|
||||||
#ifndef NO_FILESYSTEM
|
#ifndef NO_FILESYSTEM
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
if (CyaSSL_CTX_use_certificate_file(ctx, cliEccCert, SSL_FILETYPE_PEM)
|
||||||
|
!= SSL_SUCCESS)
|
||||||
|
err_sys("can't load ecc client cert file, "
|
||||||
|
"Please run from CyaSSL home dir");
|
||||||
|
|
||||||
|
if (CyaSSL_CTX_use_PrivateKey_file(ctx, cliEccKey, SSL_FILETYPE_PEM)
|
||||||
|
!= SSL_SUCCESS)
|
||||||
|
err_sys("can't load ecc client key file, "
|
||||||
|
"Please run from CyaSSL home dir");
|
||||||
|
#else
|
||||||
if (CyaSSL_CTX_use_certificate_file(ctx, cliCert, SSL_FILETYPE_PEM)
|
if (CyaSSL_CTX_use_certificate_file(ctx, cliCert, SSL_FILETYPE_PEM)
|
||||||
!= SSL_SUCCESS)
|
!= SSL_SUCCESS)
|
||||||
err_sys("can't load client cert file, "
|
err_sys("can't load client cert file, "
|
||||||
@ -155,6 +166,7 @@ void client_test(void* args)
|
|||||||
!= SSL_SUCCESS)
|
!= SSL_SUCCESS)
|
||||||
err_sys("can't load client key file, "
|
err_sys("can't load client key file, "
|
||||||
"Please run from CyaSSL home dir");
|
"Please run from CyaSSL home dir");
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
#else
|
#else
|
||||||
load_buffer(ctx, cliCert, CYASSL_CERT);
|
load_buffer(ctx, cliCert, CYASSL_CERT);
|
||||||
load_buffer(ctx, cliKey, CYASSL_KEY);
|
load_buffer(ctx, cliKey, CYASSL_KEY);
|
||||||
|
@ -115,6 +115,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||||||
!= SSL_SUCCESS)
|
!= SSL_SUCCESS)
|
||||||
err_sys("can't load server ecc key file, "
|
err_sys("can't load server ecc key file, "
|
||||||
"Please run from CyaSSL home dir");
|
"Please run from CyaSSL home dir");
|
||||||
|
/* for client auth */
|
||||||
|
if (SSL_CTX_load_verify_locations(ctx, cliEccCert, 0) != SSL_SUCCESS)
|
||||||
|
err_sys("can't load ecc ca file, Please run from CyaSSL home dir");
|
||||||
|
|
||||||
#elif HAVE_NTRU
|
#elif HAVE_NTRU
|
||||||
if (SSL_CTX_use_certificate_file(ctx, ntruCert, SSL_FILETYPE_PEM)
|
if (SSL_CTX_use_certificate_file(ctx, ntruCert, SSL_FILETYPE_PEM)
|
||||||
!= SSL_SUCCESS)
|
!= SSL_SUCCESS)
|
||||||
|
103
src/internal.c
103
src/internal.c
@ -4552,7 +4552,12 @@ int SetCipherList(Suites* s, const char* list)
|
|||||||
byte *output;
|
byte *output;
|
||||||
int sendSz = 0, length, ret;
|
int sendSz = 0, length, ret;
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
|
word32 sigOutSz = 0;
|
||||||
RsaKey key;
|
RsaKey key;
|
||||||
|
int usingEcc = 0;
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ecc_key eccKey;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ssl->options.sendVerify == SEND_BLANK_CERT)
|
if (ssl->options.sendVerify == SEND_BLANK_CERT)
|
||||||
return 0; /* sent blank cert, can't verify */
|
return 0; /* sent blank cert, can't verify */
|
||||||
@ -4567,10 +4572,31 @@ int SetCipherList(Suites* s, const char* list)
|
|||||||
|
|
||||||
BuildCertHashes(ssl, &ssl->certHashes);
|
BuildCertHashes(ssl, &ssl->certHashes);
|
||||||
|
|
||||||
/* TODO: when add DSS support check here */
|
#ifdef HAVE_ECC
|
||||||
|
ecc_init(&eccKey);
|
||||||
|
#endif
|
||||||
InitRsaKey(&key, ssl->heap);
|
InitRsaKey(&key, ssl->heap);
|
||||||
ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
|
ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key,
|
||||||
ssl->buffers.key.length);
|
ssl->buffers.key.length);
|
||||||
|
if (ret == 0)
|
||||||
|
sigOutSz = RsaEncryptSize(&key);
|
||||||
|
else {
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
CYASSL_MSG("Trying ECC client cert, RSA didn't work");
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &eccKey,
|
||||||
|
ssl->buffers.key.length);
|
||||||
|
if (ret == 0) {
|
||||||
|
CYASSL_MSG("Using ECC client cert");
|
||||||
|
usingEcc = 1;
|
||||||
|
sigOutSz = ecc_sig_size(&eccKey);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CYASSL_MSG("Bad client cert type");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
byte* verify = (byte*)&output[RECORD_HEADER_SZ +
|
byte* verify = (byte*)&output[RECORD_HEADER_SZ +
|
||||||
HANDSHAKE_HEADER_SZ];
|
HANDSHAKE_HEADER_SZ];
|
||||||
@ -4583,34 +4609,45 @@ int SetCipherList(Suites* s, const char* list)
|
|||||||
if (ssl->options.dtls)
|
if (ssl->options.dtls)
|
||||||
verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
|
verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
|
||||||
#endif
|
#endif
|
||||||
length = RsaEncryptSize(&key);
|
length = sigOutSz;
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
verify[0] = sha_mac;
|
verify[0] = sha_mac;
|
||||||
verify[1] = rsa_sa_algo;
|
verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
|
||||||
extraSz = HASH_SIG_SIZE;
|
extraSz = HASH_SIG_SIZE;
|
||||||
}
|
}
|
||||||
c16toa((word16)length, verify + extraSz); /* prepend verify header*/
|
c16toa((word16)length, verify + extraSz); /* prepend verify header*/
|
||||||
|
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (usingEcc) {
|
||||||
byte* digest;
|
#ifdef HAVE_ECC
|
||||||
int typeH;
|
word32 localSz = sigOutSz;
|
||||||
int digestSz;
|
ret = ecc_sign_hash(signBuffer + MD5_DIGEST_SIZE,
|
||||||
|
SHA_DIGEST_SIZE, verify + extraSz + VERIFY_HEADER,
|
||||||
/* sha1 for now */
|
&localSz, &ssl->rng, &eccKey);
|
||||||
digest = ssl->certHashes.sha;
|
#endif
|
||||||
typeH = SHAh;
|
|
||||||
digestSz = SHA_DIGEST_SIZE;
|
|
||||||
|
|
||||||
signSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
|
|
||||||
signBuffer = encodedSig;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
|
byte* digest;
|
||||||
|
int typeH;
|
||||||
|
int digestSz;
|
||||||
|
|
||||||
ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
|
/* sha1 for now */
|
||||||
VERIFY_HEADER, ENCRYPT_LEN, &key, &ssl->rng);
|
digest = ssl->certHashes.sha;
|
||||||
|
typeH = SHAh;
|
||||||
|
digestSz = SHA_DIGEST_SIZE;
|
||||||
|
|
||||||
if (ret > 0) {
|
signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
|
||||||
ret = 0; /* reset */
|
signBuffer = encodedSig;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
|
||||||
|
VERIFY_HEADER, ENCRYPT_LEN, &key, &ssl->rng);
|
||||||
|
|
||||||
|
if (ret > 0)
|
||||||
|
ret = 0; /* RSA reset */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
AddHeaders(output, length + extraSz + VERIFY_HEADER,
|
AddHeaders(output, length + extraSz + VERIFY_HEADER,
|
||||||
certificate_verify, ssl);
|
certificate_verify, ssl);
|
||||||
|
|
||||||
@ -4625,6 +4662,9 @@ int SetCipherList(Suites* s, const char* list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FreeRsaKey(&key);
|
FreeRsaKey(&key);
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ecc_free(&eccKey);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
@ -5548,8 +5588,11 @@ int SetCipherList(Suites* s, const char* list)
|
|||||||
|
|
||||||
sig = &input[i];
|
sig = &input[i];
|
||||||
*inOutsz = i + sz;
|
*inOutsz = i + sz;
|
||||||
/* TODO: when add DSS support check here */
|
|
||||||
|
/* RSA */
|
||||||
if (ssl->peerRsaKeyPresent != 0) {
|
if (ssl->peerRsaKeyPresent != 0) {
|
||||||
|
CYASSL_MSG("Doing RSA peer cert verify");
|
||||||
|
|
||||||
outLen = RsaSSL_VerifyInline(sig, sz, &out, &ssl->peerRsaKey);
|
outLen = RsaSSL_VerifyInline(sig, sz, &out, &ssl->peerRsaKey);
|
||||||
|
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
@ -5567,14 +5610,28 @@ int SetCipherList(Suites* s, const char* list)
|
|||||||
sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
|
sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
|
||||||
|
|
||||||
if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,sigSz) == 0)
|
if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,sigSz) == 0)
|
||||||
ret = 0;
|
ret = 0; /* verified */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (outLen == sizeof(ssl->certHashes) && XMEMCMP(out,
|
if (outLen == sizeof(ssl->certHashes) && XMEMCMP(out,
|
||||||
ssl->certHashes.md5, sizeof(ssl->certHashes)) == 0)
|
ssl->certHashes.md5, sizeof(ssl->certHashes)) == 0)
|
||||||
ret = 0;
|
ret = 0; /* verified */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
else if (ssl->peerEccDsaKeyPresent) {
|
||||||
|
int verify = 0;
|
||||||
|
int err = -1;
|
||||||
|
|
||||||
|
CYASSL_MSG("Doing ECC peer cert verify");
|
||||||
|
|
||||||
|
err = ecc_verify_hash(sig, sz, ssl->certHashes.sha, SHA_DIGEST_SIZE,
|
||||||
|
&verify, &ssl->peerEccDsaKey);
|
||||||
|
|
||||||
|
if (err == 0 && verify == 1)
|
||||||
|
ret = 0; /* verified */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user