diff --git a/certs/client-ecc-cert.pem b/certs/client-ecc-cert.pem new file mode 100644 index 000000000..4d0448fc4 --- /dev/null +++ b/certs/client-ecc-cert.pem @@ -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----- diff --git a/certs/ecc-client-key.pem b/certs/ecc-client-key.pem new file mode 100644 index 000000000..cf9812d80 --- /dev/null +++ b/certs/ecc-client-key.pem @@ -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----- diff --git a/cyassl/openssl/bn.h b/cyassl/openssl/bn.h index a5b86643a..0796bab27 100644 --- a/cyassl/openssl/bn.h +++ b/cyassl/openssl/bn.h @@ -11,7 +11,8 @@ #endif typedef struct CYASSL_BIGNUM { - int neg; /* openssh deference */ + int neg; /* openssh deference */ + void* internal; /* our big num */ } CYASSL_BIGNUM; @@ -50,6 +51,18 @@ CYASSL_API CYASSL_BIGNUM* CyaSSL_BN_bin2bn(const unsigned char*, int len, CYASSL_API int CyaSSL_mask_bits(CYASSL_BIGNUM*, int n); +CYASSL_API int CyaSSL_BN_rand(CYASSL_BIGNUM*, int bits, int top, int bottom); +CYASSL_API int CyaSSL_BN_is_bit_set(const CYASSL_BIGNUM*, int n); +CYASSL_API int CyaSSL_BN_hex2bn(CYASSL_BIGNUM**, const char* str); + +CYASSL_API CYASSL_BIGNUM* CyaSSL_BN_dup(const CYASSL_BIGNUM*); +CYASSL_API CYASSL_BIGNUM* CyaSSL_BN_copy(CYASSL_BIGNUM*, const CYASSL_BIGNUM*); + +CYASSL_API int CyaSSL_BN_set_word(CYASSL_BIGNUM*, unsigned long w); + +CYASSL_API int CyaSSL_BN_dec2bn(CYASSL_BIGNUM**, const char* str); +CYASSL_API char* CyaSSL_BN_bn2dec(const CYASSL_BIGNUM*); + typedef CYASSL_BIGNUM BIGNUM; typedef CYASSL_BN_CTX BN_CTX; @@ -80,6 +93,19 @@ typedef CYASSL_BN_CTX BN_CTX; #define BN_mask_bits CyaSSL_mask_bits +#define BN_rand CyaSSL_BN_rand +#define BN_is_bit_set CyaSSL_BN_is_bit_set +#define BN_hex2bn CyaSSL_BN_hex2bn + +#define BN_dup CyaSSL_BN_dup +#define BN_copy CyaSSL_BN_copy + +#define BN_set_word CyaSSL_BN_set_word + +#define BN_dec2bn CyaSSL_BN_dec2bn +#define BN_bn2dec CyaSSL_BN_bn2dec + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/cyassl/openssl/dh.h b/cyassl/openssl/dh.h index 5730ef8a0..fea4dc69c 100644 --- a/cyassl/openssl/dh.h +++ b/cyassl/openssl/dh.h @@ -17,13 +17,30 @@ typedef struct CYASSL_DH { - BIGNUM* p; - BIGNUM* g; + CYASSL_BIGNUM* p; + CYASSL_BIGNUM* g; + CYASSL_BIGNUM* pub_key; /* openssh deference g^x */ + CYASSL_BIGNUM* priv_key; /* openssh deference x */ } CYASSL_DH; +CYASSL_API CYASSL_DH* CyaSSL_DH_new(void); +CYASSL_API void CyaSSL_DH_free(CYASSL_DH*); + +CYASSL_API int CyaSSL_DH_size(CYASSL_DH*); +CYASSL_API int CyaSSL_DH_generate_key(CYASSL_DH*); +CYASSL_API int CyaSSL_DH_compute_key(unsigned char* key, CYASSL_BIGNUM* pub, + CYASSL_DH*); + typedef CYASSL_DH DH; +#define DH_new CyaSSL_DH_new +#define DH_free CyaSSL_DH_free + +#define DH_size CyaSSL_DH_size +#define DH_generate_key CyaSSL_DH_generate_key +#define DH_compute_key CyaSSL_DH_compute_key + #ifdef __cplusplus } /* extern "C" */ diff --git a/cyassl/openssl/dsa.h b/cyassl/openssl/dsa.h index aa32b9cd9..1b4007d6d 100644 --- a/cyassl/openssl/dsa.h +++ b/cyassl/openssl/dsa.h @@ -16,15 +16,27 @@ struct CYASSL_DSA { - BIGNUM* p; - BIGNUM* q; - BIGNUM* g; - BIGNUM* pub_key; - BIGNUM* priv_key; + CYASSL_BIGNUM* p; + CYASSL_BIGNUM* q; + CYASSL_BIGNUM* g; + CYASSL_BIGNUM* pub_key; + CYASSL_BIGNUM* priv_key; }; +CYASSL_API CYASSL_DSA* CyaSSL_DSA_new(void); +CYASSL_API void CyaSSL_DSA_free(CYASSL_DSA*); +CYASSL_API int CyaSSL_DSA_generate_key(CYASSL_DSA*); +CYASSL_API int CyaSSL_DSA_generate_parameters_ex(CYASSL_DSA*, int bits, + unsigned char* seed, int seedLen, int* counterRet, + unsigned long* hRet, void* cb); + +#define DSA_new CyaSSL_DSA_new +#define DSA_free CyaSSL_DSA_free + +#define DSA_generate_key CyaSSL_DSA_generate_key +#define DSA_generate_parameters_ex CyaSSL_DSA_generate_parameters_ex #ifdef __cplusplus diff --git a/cyassl/openssl/evp.h b/cyassl/openssl/evp.h index a7c98a7a8..879f6ec13 100644 --- a/cyassl/openssl/evp.h +++ b/cyassl/openssl/evp.h @@ -68,6 +68,7 @@ CYASSL_API const CYASSL_EVP_CIPHER* CyaSSL_EVP_aes_256_ctr(void); CYASSL_API const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_cbc(void); CYASSL_API const CYASSL_EVP_CIPHER* CyaSSL_EVP_des_ede3_cbc(void); CYASSL_API const CYASSL_EVP_CIPHER* CyaSSL_EVP_rc4(void); +CYASSL_API const CYASSL_EVP_CIPHER* CyaSSL_EVP_enc_null(void); typedef union { @@ -110,8 +111,9 @@ enum { DES_CBC_TYPE = 7, DES_EDE3_CBC_TYPE = 8, ARC4_TYPE = 9, - EVP_PKEY_RSA = 10, - EVP_PKEY_DSA = 10, + NULL_CIPHER_TYPE = 10, + EVP_PKEY_RSA = 11, + EVP_PKEY_DSA = 12, NID_sha1 = 64, NID_md5 = 4 }; @@ -160,6 +162,8 @@ CYASSL_API int CyaSSL_EVP_Cipher(CYASSL_EVP_CIPHER_CTX* ctx, unsigned char* dst, unsigned char* src, unsigned int len); +CYASSL_API const CYASSL_EVP_MD* CyaSSL_EVP_get_digestbynid(int); + CYASSL_API CYASSL_RSA* CyaSSL_EVP_PKEY_get1_RSA(CYASSL_EVP_PKEY*); CYASSL_API CYASSL_DSA* CyaSSL_EVP_PKEY_get1_DSA(CYASSL_EVP_PKEY*); @@ -195,6 +199,7 @@ typedef CYASSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_des_cbc CyaSSL_EVP_des_cbc #define EVP_des_ede3_cbc CyaSSL_EVP_des_ede3_cbc #define EVP_rc4 CyaSSL_EVP_rc4 +#define EVP_enc_null CyaSSL_EVP_enc_null #define EVP_MD_size CyaSSL_EVP_MD_size #define EVP_MD_CTX_init CyaSSL_EVP_MD_CTX_init @@ -213,6 +218,8 @@ typedef CYASSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_CipherInit CyaSSL_EVP_CipherInit #define EVP_Cipher CyaSSL_EVP_Cipher +#define EVP_get_digestbynid CyaSSL_EVP_get_digestbynid + #define EVP_PKEY_get1_RSA CyaSSL_EVP_PKEY_get1_RSA #define EVP_PKEY_get1_DSA CyaSSL_EVP_PKEY_get1_DSA diff --git a/cyassl/openssl/hmac.h b/cyassl/openssl/hmac.h index 37cd06ab5..1f398dbf8 100644 --- a/cyassl/openssl/hmac.h +++ b/cyassl/openssl/hmac.h @@ -52,13 +52,13 @@ typedef struct CYASSL_HMAC_CTX { } CYASSL_HMAC_CTX; -void CyaSSL_HMAC_Init(CYASSL_HMAC_CTX* ctx, const void* key, int keylen, - const EVP_MD* type); -void CyaSSL_HMAC_Update(CYASSL_HMAC_CTX* ctx, const unsigned char* data, - int len); -void CyaSSL_HMAC_Final(CYASSL_HMAC_CTX* ctx, unsigned char* hash, - unsigned int* len); -void CyaSSL_HMAC_cleanup(CYASSL_HMAC_CTX* ctx); +CYASSL_API void CyaSSL_HMAC_Init(CYASSL_HMAC_CTX* ctx, const void* key, + int keylen, const EVP_MD* type); +CYASSL_API void CyaSSL_HMAC_Update(CYASSL_HMAC_CTX* ctx, + const unsigned char* data, int len); +CYASSL_API void CyaSSL_HMAC_Final(CYASSL_HMAC_CTX* ctx, unsigned char* hash, + unsigned int* len); +CYASSL_API void CyaSSL_HMAC_cleanup(CYASSL_HMAC_CTX* ctx); typedef struct CYASSL_HMAC_CTX HMAC_CTX; diff --git a/cyassl/openssl/pem.h b/cyassl/openssl/pem.h index 4f02947c3..b727862b9 100644 --- a/cyassl/openssl/pem.h +++ b/cyassl/openssl/pem.h @@ -14,17 +14,17 @@ #endif -int CyaSSL_PEM_write_bio_RSAPrivateKey(CYASSL_BIO* bio, RSA* rsa, +CYASSL_API int CyaSSL_PEM_write_bio_RSAPrivateKey(CYASSL_BIO* bio, RSA* rsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, pem_password_cb cb, void* arg); -int CyaSSL_PEM_write_bio_DSAPrivateKey(CYASSL_BIO* bio, DSA* rsa, +CYASSL_API int CyaSSL_PEM_write_bio_DSAPrivateKey(CYASSL_BIO* bio, DSA* rsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, pem_password_cb cb, void* arg); -CYASSL_EVP_PKEY* CyaSSL_PEM_read_bio_PrivateKey(CYASSL_BIO* bio, +CYASSL_API CYASSL_EVP_PKEY* CyaSSL_PEM_read_bio_PrivateKey(CYASSL_BIO* bio, CYASSL_EVP_PKEY**, pem_password_cb cb, void* arg); #define PEM_write_bio_RSAPrivateKey CyaSSL_PEM_write_bio_RSAPrivateKey diff --git a/cyassl/openssl/rsa.h b/cyassl/openssl/rsa.h index 94b0d5209..fb644d648 100644 --- a/cyassl/openssl/rsa.h +++ b/cyassl/openssl/rsa.h @@ -18,28 +18,52 @@ enum { }; struct CYASSL_RSA { - BIGNUM* n; - BIGNUM* e; - BIGNUM* d; - BIGNUM* p; - BIGNUM* q; - BIGNUM* dmp1; - BIGNUM* dmq1; - BIGNUM* iqmp; + CYASSL_BIGNUM* n; + CYASSL_BIGNUM* e; + CYASSL_BIGNUM* d; + CYASSL_BIGNUM* p; + CYASSL_BIGNUM* q; + CYASSL_BIGNUM* dmp1; /* dP */ + CYASSL_BIGNUM* dmq1; /* dQ */ + CYASSL_BIGNUM* iqmp; /* u */ + void* internal; /* our RSA */ }; +CYASSL_API CYASSL_RSA* CyaSSL_RSA_new(void); +CYASSL_API void CyaSSL_RSA_free(CYASSL_RSA*); + +CYASSL_API int CyaSSL_RSA_generate_key_ex(CYASSL_RSA*, int bits, CYASSL_BIGNUM*, + void* cb); + CYASSL_API int CyaSSL_RSA_blinding_on(CYASSL_RSA*, CYASSL_BN_CTX*); CYASSL_API int CyaSSL_RSA_public_encrypt(int len, unsigned char* fr, unsigned char* to, CYASSL_RSA*, int padding); CYASSL_API int CyaSSL_RSA_private_decrypt(int len, unsigned char* fr, unsigned char* to, CYASSL_RSA*, int padding); +CYASSL_API int CyaSSL_RSA_size(const CYASSL_RSA*); +CYASSL_API int CyaSSL_RSA_sign(int type, const unsigned char* m, + unsigned int mLen, unsigned char* sigRet, + unsigned int* sigLen, CYASSL_RSA*); +CYASSL_API int CyaSSL_RSA_public_decrypt(int flen, unsigned char* from, + unsigned char* to, CYASSL_RSA*, int padding); +CYASSL_API int CyaSSL_RSA_GenAdd(CYASSL_RSA*); + + +#define RSA_new CyaSSL_RSA_new +#define RSA_free CyaSSL_RSA_free + +#define RSA_generate_key_ex CyaSSL_RSA_generate_key_ex #define RSA_blinding_on CyaSSL_RSA_blinding_on #define RSA_public_encrypt CyaSSL_RSA_public_encrypt #define RSA_private_decrypt CyaSSL_RSA_private_decrypt +#define RSA_size CyaSSL_RSA_size +#define RSA_sign CyaSSL_RSA_sign +#define RSA_public_decrypt CyaSSL_RSA_public_decrypt + #ifdef __cplusplus } /* extern "C" */ diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 5393a66fc..ca1761b88 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -245,7 +245,7 @@ CYASSL_API CYASSL_SESSION* CyaSSL_get1_session(CYASSL* ssl); /* what's ref count */ CYASSL_API void CyaSSL_X509_free(CYASSL_X509*); -CYASSL_API void CyaSSL_OpenSSL_free(void*); +CYASSL_API void CyaSSL_OPENSSL_free(void*); CYASSL_API int CyaSSL_OCSP_parse_url(char* url, char** host, char** port, char** path, int* ssl); diff --git a/cyassl/test.h b/cyassl/test.h index fbc0852c4..57986f835 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -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 */ diff --git a/examples/client/client.c b/examples/client/client.c index 39f9cd1d9..0f2b72bbd 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -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); diff --git a/examples/server/server.c b/examples/server/server.c index f6a34f3ea..c7fe1f965 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -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) diff --git a/src/internal.c b/src/internal.c index 459008e94..835b967a7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4563,7 +4563,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 */ @@ -4578,10 +4583,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]; @@ -4594,34 +4620,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); @@ -4636,6 +4673,9 @@ int SetCipherList(Suites* s, const char* list) } FreeRsaKey(&key); +#ifdef HAVE_ECC + ecc_free(&eccKey); +#endif if (ret == 0) { #ifdef CYASSL_CALLBACKS @@ -5559,8 +5599,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)) { @@ -5578,14 +5621,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; } diff --git a/src/ssl.c b/src/ssl.c index 943b39ab2..e66ddd0e1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -45,6 +45,8 @@ #include #include #include + #include + #include /* openssl headers end, cyassl internal headers next */ #include #include @@ -2975,7 +2977,7 @@ int CyaSSL_set_compression(CYASSL* ssl) (void)bits; (void)f; (void)data; - return 0; + return NULL; } @@ -3705,6 +3707,14 @@ int CyaSSL_set_compression(CYASSL* ssl) } + const CYASSL_EVP_CIPHER* CyaSSL_EVP_enc_null(void) + { + static const char* type = "NULL"; + CYASSL_ENTER("CyaSSL_EVP_enc_null"); + return type; + } + + int CyaSSL_EVP_MD_CTX_cleanup(CYASSL_EVP_MD_CTX* ctx) { CYASSL_ENTER("EVP_MD_CTX_cleanup"); @@ -3851,6 +3861,11 @@ int CyaSSL_set_compression(CYASSL* ssl) if (key) Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen); } + else if (ctx->cipherType == NULL_CIPHER_TYPE || (type && + XSTRNCMP(type, "NULL", 4) == 0)) { + ctx->cipherType = NULL_CIPHER_TYPE; + ctx->keyLen = 0; + } else return 0; /* failure */ @@ -3919,6 +3934,10 @@ int CyaSSL_set_compression(CYASSL* ssl) Arc4Process(&ctx->cipher.arc4, dst, src, len); break; + case NULL_CIPHER_TYPE : + XMEMCPY(dst, src, len); + break; + default: return 0; /* failure */ } @@ -4936,13 +4955,6 @@ int CyaSSL_set_compression(CYASSL* ssl) } - - void CyaSSL_RSA_free(CYASSL_RSA* rsa) - { - (void)rsa; - } - - int CyaSSL_PEM_def_callback(char* name, int num, int w, void* key) { (void)name; @@ -5277,6 +5289,663 @@ int CyaSSL_set_compression(CYASSL* ssl) } #endif + + CYASSL_BN_CTX* CyaSSL_BN_CTX_new(void) + { + static int ctx; /* ctaocrypt doesn't now need ctx */ + + CYASSL_MSG("CyaSSL_BN_CTX_new"); + + return (CYASSL_BN_CTX*)&ctx; + } + + void CyaSSL_BN_CTX_init(CYASSL_BN_CTX* ctx) + { + CYASSL_MSG("CyaSSL_BN_CTX_init"); + } + + + void CyaSSL_BN_CTX_free(CYASSL_BN_CTX* ctx) + { + CYASSL_MSG("CyaSSL_BN_CTX_free"); + + /* do free since static ctx that does nothing */ + } + + + static void InitCyaSSL_BigNum(CYASSL_BIGNUM* bn) + { + CYASSL_MSG("InitCyaSSL_BigNum"); + if (bn) { + bn->neg = 0; + bn->internal = NULL; + } + } + + + CYASSL_BIGNUM* CyaSSL_BN_new(void) + { + CYASSL_BIGNUM* external; + mp_int* mpi; + + CYASSL_MSG("CyaSSL_BN_new"); + + mpi = (mp_int*) XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (mpi == NULL) { + CYASSL_MSG("CyaSSL_BN_new malloc mpi failure"); + return NULL; + } + + external = (CYASSL_BIGNUM*) XMALLOC(sizeof(CYASSL_BIGNUM), NULL, + DYNAMIC_TYPE_BIGINT); + if (external == NULL) { + CYASSL_MSG("CyaSSL_BN_new malloc CYASSL_BIGNUM failure"); + XFREE(mpi, NULL, DYNAMIC_TYPE_BIGINT); + return NULL; + } + + InitCyaSSL_BigNum(external); + mp_init(mpi); + external->internal = mpi; + + return external; + } + + + void CyaSSL_BN_free(CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_free"); + if (bn) { + if (bn->internal) { + mp_clear(bn->internal); + XFREE(bn->internal, NULL, DYNAMIC_TYPE_BIGINT); + bn->internal = NULL; + } + XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT); + } + } + + + void CyaSSL_BN_clear_free(CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_clear_free"); + + return CyaSSL_BN_free(bn); + } + + + int CyaSSL_BN_sub(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a, + const CYASSL_BIGNUM* b) + { + CYASSL_MSG("CyaSSL_BN_sub"); + + return -1; + } + + + int CyaSSL_BN_mod(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* a, + const CYASSL_BIGNUM* b, const CYASSL_BN_CTX* c) + { + CYASSL_MSG("CyaSSL_BN_mod"); + + return -1; + } + + + const CYASSL_BIGNUM* CyaSSL_BN_value_one(void) + { + CYASSL_MSG("CyaSSL_BN_value_one"); + + return NULL; + } + + + int CyaSSL_BN_num_bytes(const CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_num_bytes"); + + return -1; + } + + + int CyaSSL_BN_num_bits(const CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_num_bits"); + + return -1; + } + + + int CyaSSL_BN_is_zero(const CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_is_zero"); + + return -1; + } + + + int CyaSSL_BN_is_one(const CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_is_one"); + + return -1; + } + + + int CyaSSL_BN_is_odd(const CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_is_odd"); + + return -1; + } + + + int CyaSSL_BN_cmp(const CYASSL_BIGNUM* a, const CYASSL_BIGNUM* b) + { + CYASSL_MSG("CyaSSL_BN_cmp"); + + return -1; + } + + + int CyaSSL_BN_bn2bin(const CYASSL_BIGNUM* bn, unsigned char* r) + { + CYASSL_MSG("CyaSSL_BN_bn2bin"); + + return -1; + } + + + CYASSL_BIGNUM* CyaSSL_BN_bin2bn(const unsigned char* str, int len, + CYASSL_BIGNUM* ret) + { + CYASSL_MSG("CyaSSL_BN_bin2bn"); + + if (ret && ret->internal) { + if (mp_read_unsigned_bin((mp_int*)ret->internal, str, len) != 0) { + CYASSL_MSG("mp_read_unsigned_bin failure"); + return NULL; + } + } + else + CYASSL_MSG("CyaSSL_BN_bin2bn wants return bignum"); + + return ret; + } + + + int CyaSSL_mask_bits(CYASSL_BIGNUM* bn, int n) + { + CYASSL_MSG("CyaSSL_BN_mask_bits"); + + return -1; + } + + + int CyaSSL_BN_rand(CYASSL_BIGNUM* bn, int bits, int top, int bottom) + { + CYASSL_MSG("CyaSSL_BN_rand"); + + return -1; + } + + + int CyaSSL_BN_is_bit_set(const CYASSL_BIGNUM* bn, int n) + { + CYASSL_MSG("CyaSSL_BN_is_bit_set"); + + return -1; + } + + + int CyaSSL_BN_hex2bn(CYASSL_BIGNUM** bn, const char* str) + { + CYASSL_MSG("CyaSSL_BN_hex2bn"); + + return -1; + } + + + CYASSL_BIGNUM* CyaSSL_BN_dup(const CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_dup"); + + return NULL; + } + + + CYASSL_BIGNUM* CyaSSL_BN_copy(CYASSL_BIGNUM* r, const CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_copy"); + + return NULL; + } + + + int CyaSSL_BN_set_word(CYASSL_BIGNUM* bn, unsigned long w) + { + CYASSL_MSG("CyaSSL_BN_set_word"); + + return -1; + } + + + int CyaSSL_BN_dec2bn(CYASSL_BIGNUM** bn, const char* str) + { + CYASSL_MSG("CyaSSL_BN_dec2bn"); + + return -1; + } + + + char* CyaSSL_BN_bn2dec(const CYASSL_BIGNUM* bn) + { + CYASSL_MSG("CyaSSL_BN_bn2dec"); + + return NULL; + } + + + CYASSL_DH* CyaSSL_DH_new(void) + { + CYASSL_MSG("CyaSSL_DH_new"); + + return NULL; + } + + + void CyaSSL_DH_free(CYASSL_DH* dh) + { + CYASSL_MSG("CyaSSL_DH_free"); + } + + + int CyaSSL_DH_size(CYASSL_DH* dh) + { + CYASSL_MSG("CyaSSL_DH_size"); + + return -1; + } + + + int CyaSSL_DH_generate_key(CYASSL_DH* dh) + { + CYASSL_MSG("CyaSSL_DH_generate_key"); + + return -1; + } + + + int CyaSSL_DH_compute_key(unsigned char* key, CYASSL_BIGNUM* pub, + CYASSL_DH* dh) + { + CYASSL_MSG("CyaSSL_DH_compute_key"); + + return -1; + } + + + CYASSL_DSA* CyaSSL_DSA_new(void) + { + CYASSL_MSG("CyaSSL_DSA_new"); + + return NULL; + } + + + void CyaSSL_DSA_free(CYASSL_DSA* dsa) + { + CYASSL_MSG("CyaSSL_DSA_free"); + } + + + int CyaSSL_DSA_generate_key(CYASSL_DSA* dsa) + { + CYASSL_MSG("CyaSSL_DSA_generate_key"); + + return -1; + } + + + int CyaSSL_DSA_generate_parameters_ex(CYASSL_DSA* dsa, int bits, + unsigned char* seed, int seedLen, int* counterRet, + unsigned long* hRet, void* cb) + { + CYASSL_MSG("CyaSSL_DSA_generate_parameters_ex"); + + return -1; + } + + + static void InitCyaSSL_Rsa(CYASSL_RSA* rsa) + { + if (rsa) { + rsa->n = NULL; + rsa->e = NULL; + rsa->d = NULL; + rsa->p = NULL; + rsa->dmp1 = NULL; + rsa->dmq1 = NULL; + rsa->iqmp = NULL; + rsa->internal = NULL; + } + } + + + CYASSL_RSA* CyaSSL_RSA_new(void) + { + CYASSL_RSA* external; + RsaKey* key; + + CYASSL_MSG("CyaSSL_RSA_new"); + + key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA); + if (key == NULL) { + CYASSL_MSG("CyaSSL_RSA_new malloc RsaKey failure"); + return NULL; + } + + external = (CYASSL_RSA*) XMALLOC(sizeof(CYASSL_RSA), NULL, + DYNAMIC_TYPE_RSA); + if (external == NULL) { + CYASSL_MSG("CyaSSL_RSA_new malloc CYASSL_RSA failure"); + XFREE(key, NULL, DYNAMIC_TYPE_RSA); + return NULL; + } + + InitCyaSSL_Rsa(external); + InitRsaKey(key, NULL); + external->internal = key; + + return external; + } + + + void CyaSSL_RSA_free(CYASSL_RSA* rsa) + { + CYASSL_MSG("CyaSSL_RSA_free"); + + if (rsa) { + if (rsa->internal) { + FreeRsaKey(rsa->internal); + XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA); + rsa->internal = NULL; + } + XFREE(rsa, NULL, DYNAMIC_TYPE_RSA); + } + } + + + int CyaSSL_RSA_generate_key_ex(CYASSL_RSA* rsa, int bits, CYASSL_BIGNUM* bn, + void* cb) + { + CYASSL_MSG("CyaSSL_RSA_generate_key_ex"); + + return -1; + } + + + int CyaSSL_RSA_blinding_on(CYASSL_RSA* rsa, CYASSL_BN_CTX* bn) + { + CYASSL_MSG("CyaSSL_RSA_blinding_on"); + + return 1; /* on by default */ + } + + + int CyaSSL_RSA_public_encrypt(int len, unsigned char* fr, + unsigned char* to, CYASSL_RSA* rsa, int padding) + { + CYASSL_MSG("CyaSSL_RSA_public_encrypt"); + + return -1; + } + + + int CyaSSL_RSA_private_decrypt(int len, unsigned char* fr, + unsigned char* to, CYASSL_RSA* rsa, int padding) + { + CYASSL_MSG("CyaSSL_RSA_private_decrypt"); + + return -1; + } + + + int CyaSSL_RSA_size(const CYASSL_RSA* rsa) + { + CYASSL_MSG("CyaSSL_RSA_size"); + + return -1; + } + + + int CyaSSL_RSA_sign(int type, const unsigned char* m, + unsigned int mLen, unsigned char* sigRet, + unsigned int* sigLen, CYASSL_RSA* rsa) + { + CYASSL_MSG("CyaSSL_RSA_sign"); + + return -1; + } + + + int CyaSSL_RSA_public_decrypt(int flen, unsigned char* from, + unsigned char* to, CYASSL_RSA* rsa, int padding) + { + CYASSL_MSG("CyaSSL_RSA_public_decrypt"); + + return -1; + } + + + /* generate p-1 and q-1 */ + int CyaSSL_RSA_GenAdd(CYASSL_RSA* rsa) + { + int err; + mp_int tmp; + + CYASSL_MSG("CyaSSL_RsaGenAdd"); + + if (rsa == NULL || rsa->p == NULL || rsa->q == NULL || rsa->d == NULL || + rsa->dmp1 == NULL || rsa->dmq1 == NULL) { + CYASSL_MSG("rsa no init error"); + return -1; + } + + if (mp_init(&tmp) != MP_OKAY) { + CYASSL_MSG("mp_init error"); + return -1; + } + + err = mp_sub_d((mp_int*)rsa->p->internal, 1, &tmp); + if (err != MP_OKAY) + CYASSL_MSG("mp_sub_d error"); + else + err = mp_mod((mp_int*)rsa->d->internal, &tmp, + (mp_int*)rsa->dmp1->internal); + + if (err != MP_OKAY) + CYASSL_MSG("mp_mod error"); + else + err = mp_sub_d((mp_int*)rsa->q->internal, 1, &tmp); + if (err != MP_OKAY) + CYASSL_MSG("mp_sub_d error"); + else + err = mp_mod((mp_int*)rsa->d->internal, &tmp, + (mp_int*)rsa->dmq1->internal); + + mp_clear(&tmp); + + if (err == MP_OKAY) + return 0; + else + return -1; + } + + + void CyaSSL_HMAC_Init(CYASSL_HMAC_CTX* ctx, const void* key, int keylen, + const EVP_MD* type) + { + CYASSL_MSG("CyaSSL_HMAC_Init"); + } + + + void CyaSSL_HMAC_Update(CYASSL_HMAC_CTX* ctx, const unsigned char* data, + int len) + { + CYASSL_MSG("CyaSSL_HMAC_Update"); + } + + + void CyaSSL_HMAC_Final(CYASSL_HMAC_CTX* ctx, unsigned char* hash, + unsigned int* len) + { + CYASSL_MSG("CyaSSL_HMAC_Final"); + } + + + void CyaSSL_HMAC_cleanup(CYASSL_HMAC_CTX* ctx) + { + CYASSL_MSG("CyaSSL_HMAC_cleanup"); + } + + + const CYASSL_EVP_MD* CyaSSL_EVP_get_digestbynid(int id) + { + CYASSL_MSG("CyaSSL_get_digestbynid"); + + return NULL; + } + + + CYASSL_RSA* CyaSSL_EVP_PKEY_get1_RSA(CYASSL_EVP_PKEY* key) + { + CYASSL_MSG("CyaSSL_EVP_PKEY_get1_RSA"); + + return NULL; + } + + + CYASSL_DSA* CyaSSL_EVP_PKEY_get1_DSA(CYASSL_EVP_PKEY* key) + { + CYASSL_MSG("CyaSSL_EVP_PKEY_get1_DSA"); + + return NULL; + } + + + void* CyaSSL_EVP_X_STATE(const CYASSL_EVP_CIPHER_CTX* ctx) + { + CYASSL_MSG("CyaSSL_EVP_X_STATE"); + + return NULL; + } + + + int CyaSSL_EVP_X_STATE_LEN(const CYASSL_EVP_CIPHER_CTX* ctx) + { + CYASSL_MSG("CyaSSL_EVP_X_STATE_LEN"); + + return -1; + } + + + int CyaSSL_3des_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset, + unsigned char* iv, int len) + { + CYASSL_MSG("CyaSSL_3des_iv"); + + return -1; + } + + + int CyaSSL_aes_ctr_iv(CYASSL_EVP_CIPHER_CTX* ctx, int doset, + unsigned char* iv, int len) + { + CYASSL_MSG("CyaSSL_aes_ctr_iv"); + + return -1; + } + + + const CYASSL_EVP_MD* CyaSSL_EVP_ripemd160(void) + { + CYASSL_MSG("CyaSSL_ripemd160"); + + return NULL; + } + + + int CyaSSL_EVP_MD_size(const CYASSL_EVP_MD* md) + { + CYASSL_MSG("CyaSSL_EVP_MD_size"); + + return -1; + } + + + int CyaSSL_EVP_CIPHER_CTX_iv_length(const CYASSL_EVP_CIPHER_CTX* ctx) + { + CYASSL_MSG("CyaSSL_EVP_CIPHER_CTX_iv_length"); + + return -1; + } + + + void CyaSSL_OPENSSL_free(void* p) + { + CYASSL_MSG("CyaSSL_OPENSSL_free"); + } + + + int CyaSSL_RAND_seed(const void* seed, int len) + { + CYASSL_MSG("CyaSSL_RAND_seed"); + + return -1; + } + + + int CyaSSL_PEM_write_bio_RSAPrivateKey(CYASSL_BIO* bio, RSA* rsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb cb, void* arg) + { + CYASSL_MSG("CyaSSL_PEM_write_bio_RSAPrivateKey"); + + return -1; + } + + + + int CyaSSL_PEM_write_bio_DSAPrivateKey(CYASSL_BIO* bio, DSA* rsa, + const EVP_CIPHER* cipher, + unsigned char* passwd, int len, + pem_password_cb cb, void* arg) + { + CYASSL_MSG("CyaSSL_PEM_write_bio_DSAPrivateKey"); + + return -1; + } + + + + CYASSL_EVP_PKEY* CyaSSL_PEM_read_bio_PrivateKey(CYASSL_BIO* bio, + CYASSL_EVP_PKEY** key, pem_password_cb cb, void* arg) + { + CYASSL_MSG("CyaSSL_PEM_read_bio_PrivateKey"); + + return NULL; + } + + + + + + + + + #endif /* OPENSSL_EXTRA */