ecc client certs

This commit is contained in:
toddouska 2012-05-02 10:30:15 -07:00
parent f49b106aef
commit 1c2b84d3dd
6 changed files with 161 additions and 23 deletions

54
certs/client-ecc-cert.pem Normal file
View 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
View 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-----

View File

@ -107,6 +107,8 @@ static const char* cliKey = "./certs/client-key.pem";
static const char* ntruCert = "./certs/ntru-cert.pem";
static const char* ntruKey = "./certs/ntru-key.raw";
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 {
int ready; /* predicate */

View File

@ -146,6 +146,17 @@ void client_test(void* args)
/* ./client // plain mode */
/* for client cert authentication if server requests */
#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)
!= SSL_SUCCESS)
err_sys("can't load client cert file, "
@ -155,6 +166,7 @@ void client_test(void* args)
!= SSL_SUCCESS)
err_sys("can't load client key file, "
"Please run from CyaSSL home dir");
#endif /* HAVE_ECC */
#else
load_buffer(ctx, cliCert, CYASSL_CERT);
load_buffer(ctx, cliKey, CYASSL_KEY);

View File

@ -115,6 +115,10 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
!= SSL_SUCCESS)
err_sys("can't load server ecc key file, "
"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
if (SSL_CTX_use_certificate_file(ctx, ntruCert, SSL_FILETYPE_PEM)
!= SSL_SUCCESS)

View File

@ -4552,7 +4552,12 @@ int SetCipherList(Suites* s, const char* list)
byte *output;
int sendSz = 0, length, ret;
word32 idx = 0;
word32 sigOutSz = 0;
RsaKey key;
int usingEcc = 0;
#ifdef HAVE_ECC
ecc_key eccKey;
#endif
if (ssl->options.sendVerify == SEND_BLANK_CERT)
return 0; /* sent blank cert, can't verify */
@ -4567,10 +4572,31 @@ int SetCipherList(Suites* s, const char* list)
BuildCertHashes(ssl, &ssl->certHashes);
/* TODO: when add DSS support check here */
#ifdef HAVE_ECC
ecc_init(&eccKey);
#endif
InitRsaKey(&key, ssl->heap);
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) {
byte* verify = (byte*)&output[RECORD_HEADER_SZ +
HANDSHAKE_HEADER_SZ];
@ -4583,34 +4609,45 @@ int SetCipherList(Suites* s, const char* list)
if (ssl->options.dtls)
verify += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA;
#endif
length = RsaEncryptSize(&key);
length = sigOutSz;
if (IsAtLeastTLSv1_2(ssl)) {
verify[0] = sha_mac;
verify[1] = rsa_sa_algo;
verify[1] = usingEcc ? ecc_dsa_sa_algo : rsa_sa_algo;
extraSz = HASH_SIG_SIZE;
}
c16toa((word16)length, verify + extraSz); /* prepend verify header*/
if (IsAtLeastTLSv1_2(ssl)) {
byte* digest;
int typeH;
int digestSz;
/* sha1 for now */
digest = ssl->certHashes.sha;
typeH = SHAh;
digestSz = SHA_DIGEST_SIZE;
signSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
signBuffer = encodedSig;
if (usingEcc) {
#ifdef HAVE_ECC
word32 localSz = sigOutSz;
ret = ecc_sign_hash(signBuffer + MD5_DIGEST_SIZE,
SHA_DIGEST_SIZE, verify + extraSz + VERIFY_HEADER,
&localSz, &ssl->rng, &eccKey);
#endif
}
else {
if (IsAtLeastTLSv1_2(ssl)) {
byte* digest;
int typeH;
int digestSz;
ret = RsaSSL_Sign(signBuffer, signSz, verify + extraSz +
VERIFY_HEADER, ENCRYPT_LEN, &key, &ssl->rng);
/* sha1 for now */
digest = ssl->certHashes.sha;
typeH = SHAh;
digestSz = SHA_DIGEST_SIZE;
if (ret > 0) {
ret = 0; /* reset */
signSz = EncodeSignature(encodedSig, digest,digestSz,typeH);
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,
certificate_verify, ssl);
@ -4625,6 +4662,9 @@ int SetCipherList(Suites* s, const char* list)
}
FreeRsaKey(&key);
#ifdef HAVE_ECC
ecc_free(&eccKey);
#endif
if (ret == 0) {
#ifdef CYASSL_CALLBACKS
@ -5548,8 +5588,11 @@ int SetCipherList(Suites* s, const char* list)
sig = &input[i];
*inOutsz = i + sz;
/* TODO: when add DSS support check here */
/* RSA */
if (ssl->peerRsaKeyPresent != 0) {
CYASSL_MSG("Doing RSA peer cert verify");
outLen = RsaSSL_VerifyInline(sig, sz, &out, &ssl->peerRsaKey);
if (IsAtLeastTLSv1_2(ssl)) {
@ -5567,14 +5610,28 @@ int SetCipherList(Suites* s, const char* list)
sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,sigSz) == 0)
ret = 0;
ret = 0; /* verified */
}
else {
if (outLen == sizeof(ssl->certHashes) && XMEMCMP(out,
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;
}