diff --git a/cyassl/internal.h b/cyassl/internal.h index c7e4d431a..104a9c1cd 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1187,8 +1187,13 @@ typedef struct EllipticCurve { CYASSL_LOCAL int TLSX_UseEllipticCurve(TLSX** extensions, word16 name); +#ifndef NO_CYASSL_SERVER +CYASSL_LOCAL int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, + byte second); #endif +#endif /* HAVE_ELLIPTIC_CURVES */ + #endif /* HAVE_TLS_EXTENSIONS */ /* CyaSSL context type */ diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 8acebf25e..aa7056246 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -1245,12 +1245,12 @@ CYASSL_API int CyaSSL_CTX_UseTruncatedHMAC(CYASSL_CTX* ctx); #ifdef HAVE_ELLIPTIC_CURVES enum { - CYASSL_ECC_SECP160R1 = 16, - CYASSL_ECC_SECP192R1 = 19, - CYASSL_ECC_SECP224R1 = 21, - CYASSL_ECC_SECP256R1 = 23, - CYASSL_ECC_SECP384R1 = 24, - CYASSL_ECC_SECP521R1 = 25 + CYASSL_ECC_SECP160R1 = 0x10, + CYASSL_ECC_SECP192R1 = 0x13, + CYASSL_ECC_SECP224R1 = 0x15, + CYASSL_ECC_SECP256R1 = 0x17, + CYASSL_ECC_SECP384R1 = 0x18, + CYASSL_ECC_SECP521R1 = 0x19 }; #ifndef NO_CYASSL_CLIENT diff --git a/src/internal.c b/src/internal.c index 7423b59a9..08f7cefa1 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9765,6 +9765,13 @@ static void PickHashSigAlgo(CYASSL* ssl, } } +#ifdef HAVE_ELLIPTIC_CURVES + if (!TLSX_ValidateEllipticCurves(ssl, first, second)) { + CYASSL_MSG("Don't have matching curves"); + return 0; + } +#endif + /* ECCDHE is always supported if ECC on */ return 1; diff --git a/src/tls.c b/src/tls.c index f96bc1035..1a59e6386 100644 --- a/src/tls.c +++ b/src/tls.c @@ -1272,6 +1272,73 @@ static int TLSX_EllipticCurve_Parse(CYASSL* ssl, byte* input, word16 length, return 0; } +int TLSX_ValidateEllipticCurves(CYASSL* ssl, byte first, byte second) { + TLSX* extension = (first == ECC_BYTE) + ? TLSX_Find(ssl->extensions, ELLIPTIC_CURVES) + : NULL; + EllipticCurve* curve = NULL; + word32 oid = 0; + word16 octets = 0; /* acording to 'ecc_set_type ecc_sets[];' */ + + if (!extension) + return 1; /* no suite restriction */ + + for (curve = extension->data; curve; curve = curve->next) { + switch (curve->name) { + case CYASSL_ECC_SECP160R1: oid = ECC_160R1; octets = 20; break; + case CYASSL_ECC_SECP192R1: oid = ECC_192R1; octets = 24; break; + case CYASSL_ECC_SECP224R1: oid = ECC_224R1; octets = 28; break; + case CYASSL_ECC_SECP256R1: oid = ECC_256R1; octets = 32; break; + case CYASSL_ECC_SECP384R1: oid = ECC_384R1; octets = 48; break; + case CYASSL_ECC_SECP521R1: oid = ECC_521R1; octets = 66; break; + } + } + + /* ECDSA */ + switch (second) { + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: + case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: + if (ssl->pkCurveOID != oid) + return 0; + } + + switch (second) { + /* ECDHE */ +#ifndef NO_RSA + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + case TLS_ECDHE_RSA_WITH_RC4_128_SHA: + case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: +#endif + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: + if (ssl->eccTempKeySz != octets) + return 0; + + /* ECDH */ + default: + ; /* not sure how to check yet... */ + } + + return 1; +} + #endif /* NO_CYASSL_SERVER */ int TLSX_UseEllipticCurve(TLSX** extensions, word16 name) @@ -1283,11 +1350,18 @@ int TLSX_UseEllipticCurve(TLSX** extensions, word16 name) if (extensions == NULL) return BAD_FUNC_ARG; - if ( name != CYASSL_ECC_SECP160R1 && - name != CYASSL_ECC_SECP192R1 && - name != CYASSL_ECC_SECP224R1 && - (name < CYASSL_ECC_SECP256R1 || name > CYASSL_ECC_SECP521R1)) - return BAD_FUNC_ARG; + switch (name) { + case CYASSL_ECC_SECP160R1: + case CYASSL_ECC_SECP192R1: + case CYASSL_ECC_SECP224R1: + case CYASSL_ECC_SECP256R1: + case CYASSL_ECC_SECP384R1: + case CYASSL_ECC_SECP521R1: + break; + + default: + return BAD_FUNC_ARG; + } if ((ret = TLSX_EllipticCurve_Append(&curve, name)) != 0) return ret;