X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fssl_ciph.c;h=a046c71e2f30b2dac9e459a577c1eccb8842957c;hb=77ff1f3b8bfaa348956c5096a2b829f2e767b4f1;hp=b0542d1b4a90ecb4b68e21406185ee5ad2399ad6;hpb=146e1fc7b3d4bbc6b940b939750d05c72135ae51;p=openssl.git diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index b0542d1b4a..a046c71e2f 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -162,11 +162,13 @@ #define SSL_ENC_CAMELLIA256_IDX 9 #define SSL_ENC_GOST89_IDX 10 #define SSL_ENC_SEED_IDX 11 -#define SSL_ENC_NUM_IDX 12 +#define SSL_ENC_AES128GCM_IDX 12 +#define SSL_ENC_AES256GCM_IDX 13 +#define SSL_ENC_NUM_IDX 14 static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ - NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; #define SSL_COMP_NULL_IDX 0 @@ -180,28 +182,31 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; #define SSL_MD_GOST94_IDX 2 #define SSL_MD_GOST89MAC_IDX 3 #define SSL_MD_SHA256_IDX 4 +#define SSL_MD_SHA384_IDX 5 /*Constant SSL_MAX_DIGEST equal to size of digests array should be * defined in the * ssl_locl.h */ #define SSL_MD_NUM_IDX SSL_MAX_DIGEST static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ - NULL,NULL,NULL,NULL,NULL + NULL,NULL,NULL,NULL,NULL,NULL }; /* PKEY_TYPE for GOST89MAC is known in advance, but, because * implementation is engine-provided, we'll fill it only if * corresponding EVP_PKEY_METHOD is found */ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={ - EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef,EVP_PKEY_HMAC + EVP_PKEY_HMAC,EVP_PKEY_HMAC,EVP_PKEY_HMAC,NID_undef, + EVP_PKEY_HMAC,EVP_PKEY_HMAC }; static int ssl_mac_secret_size[SSL_MD_NUM_IDX]={ - 0,0,0,0,0 + 0,0,0,0,0,0 }; -static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={ +static const int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={ SSL_HANDSHAKE_MAC_MD5,SSL_HANDSHAKE_MAC_SHA, - SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256 + SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA384 }; #define CIPHER_ADD 1 @@ -225,27 +230,29 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_CMPALL,0, 0,0,SSL_eNULL,0,0,0,0,0,0}, /* "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in ALL!) */ - {0,SSL_TXT_CMPDEF,0, SSL_kEDH|SSL_kEECDH,SSL_aNULL,~SSL_eNULL,0,0,0,0,0,0}, + {0,SSL_TXT_CMPDEF,0, SSL_kDHE|SSL_kECDHE,SSL_aNULL,~SSL_eNULL,0,0,0,0,0,0}, /* key exchange aliases * (some of those using only a single bit here combine * multiple key exchange algs according to the RFCs, - * e.g. kEDH combines DHE_DSS and DHE_RSA) */ + * e.g. kDHE combines DHE_DSS and DHE_RSA) */ {0,SSL_TXT_kRSA,0, SSL_kRSA, 0,0,0,0,0,0,0,0}, - {0,SSL_TXT_kDHr,0, SSL_kDHr, 0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */ - {0,SSL_TXT_kDHd,0, SSL_kDHd, 0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */ - {0,SSL_TXT_kDH,0, SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0}, /* no such ciphersuites supported! */ - {0,SSL_TXT_kEDH,0, SSL_kEDH, 0,0,0,0,0,0,0,0}, - {0,SSL_TXT_DH,0, SSL_kDHr|SSL_kDHd|SSL_kEDH,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kDHr,0, SSL_kDHr, 0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kDHd,0, SSL_kDHd, 0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kDH,0, SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kEDH,0, SSL_kDHE, 0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kDHE,0, SSL_kDHE, 0,0,0,0,0,0,0,0}, + {0,SSL_TXT_DH,0, SSL_kDHr|SSL_kDHd|SSL_kDHE,0,0,0,0,0,0,0,0}, {0,SSL_TXT_kKRB5,0, SSL_kKRB5, 0,0,0,0,0,0,0,0}, {0,SSL_TXT_kECDHr,0, SSL_kECDHr,0,0,0,0,0,0,0,0}, {0,SSL_TXT_kECDHe,0, SSL_kECDHe,0,0,0,0,0,0,0,0}, {0,SSL_TXT_kECDH,0, SSL_kECDHr|SSL_kECDHe,0,0,0,0,0,0,0,0}, - {0,SSL_TXT_kEECDH,0, SSL_kEECDH,0,0,0,0,0,0,0,0}, - {0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kEECDH,0, SSL_kECDHE,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_kECDHE,0, SSL_kECDHE,0,0,0,0,0,0,0,0}, + {0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kECDHE,0,0,0,0,0,0,0,0}, {0,SSL_TXT_kPSK,0, SSL_kPSK, 0,0,0,0,0,0,0,0}, {0,SSL_TXT_kSRP,0, SSL_kSRP, 0,0,0,0,0,0,0,0}, @@ -265,15 +272,18 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_aGOST94,0,0,SSL_aGOST94,0,0,0,0,0,0,0}, {0,SSL_TXT_aGOST01,0,0,SSL_aGOST01,0,0,0,0,0,0,0}, {0,SSL_TXT_aGOST,0,0,SSL_aGOST94|SSL_aGOST01,0,0,0,0,0,0,0}, + {0,SSL_TXT_aSRP,0, 0,SSL_aSRP, 0,0,0,0,0,0,0}, /* aliases combining key exchange and server authentication */ - {0,SSL_TXT_EDH,0, SSL_kEDH,~SSL_aNULL,0,0,0,0,0,0,0}, - {0,SSL_TXT_EECDH,0, SSL_kEECDH,~SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_EDH,0, SSL_kDHE,~SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_DHE,0, SSL_kDHE,~SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_EECDH,0, SSL_kECDHE,~SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_ECDHE,0, SSL_kECDHE,~SSL_aNULL,0,0,0,0,0,0,0}, {0,SSL_TXT_NULL,0, 0,0,SSL_eNULL, 0,0,0,0,0,0}, {0,SSL_TXT_KRB5,0, SSL_kKRB5,SSL_aKRB5,0,0,0,0,0,0,0}, {0,SSL_TXT_RSA,0, SSL_kRSA,SSL_aRSA,0,0,0,0,0,0,0}, - {0,SSL_TXT_ADH,0, SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0}, - {0,SSL_TXT_AECDH,0, SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_ADH,0, SSL_kDHE,SSL_aNULL,0,0,0,0,0,0,0}, + {0,SSL_TXT_AECDH,0, SSL_kECDHE,SSL_aNULL,0,0,0,0,0,0,0}, {0,SSL_TXT_PSK,0, SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0}, {0,SSL_TXT_SRP,0, SSL_kSRP,0,0,0,0,0,0,0,0}, @@ -286,9 +296,10 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_IDEA,0, 0,0,SSL_IDEA, 0,0,0,0,0,0}, {0,SSL_TXT_SEED,0, 0,0,SSL_SEED, 0,0,0,0,0,0}, {0,SSL_TXT_eNULL,0, 0,0,SSL_eNULL, 0,0,0,0,0,0}, - {0,SSL_TXT_AES128,0, 0,0,SSL_AES128,0,0,0,0,0,0}, - {0,SSL_TXT_AES256,0, 0,0,SSL_AES256,0,0,0,0,0,0}, - {0,SSL_TXT_AES,0, 0,0,SSL_AES128|SSL_AES256,0,0,0,0,0,0}, + {0,SSL_TXT_AES128,0, 0,0,SSL_AES128|SSL_AES128GCM,0,0,0,0,0,0}, + {0,SSL_TXT_AES256,0, 0,0,SSL_AES256|SSL_AES256GCM,0,0,0,0,0,0}, + {0,SSL_TXT_AES,0, 0,0,SSL_AES,0,0,0,0,0,0}, + {0,SSL_TXT_AES_GCM,0, 0,0,SSL_AES128GCM|SSL_AES256GCM,0,0,0,0,0,0}, {0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0}, {0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0}, {0,SSL_TXT_CAMELLIA ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0}, @@ -300,11 +311,12 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_GOST94,0, 0,0,0,SSL_GOST94, 0,0,0,0,0}, {0,SSL_TXT_GOST89MAC,0, 0,0,0,SSL_GOST89MAC, 0,0,0,0,0}, {0,SSL_TXT_SHA256,0, 0,0,0,SSL_SHA256, 0,0,0,0,0}, + {0,SSL_TXT_SHA384,0, 0,0,0,SSL_SHA384, 0,0,0,0,0}, /* protocol version aliases */ - {0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0}, {0,SSL_TXT_SSLV3,0, 0,0,0,0,SSL_SSLV3, 0,0,0,0}, {0,SSL_TXT_TLSV1,0, 0,0,0,0,SSL_TLSV1, 0,0,0,0}, + {0,SSL_TXT_TLSV1_2,0, 0,0,0,0,SSL_TLSV1_2, 0,0,0,0}, /* export flag */ {0,SSL_TXT_EXP,0, 0,0,0,0,0,SSL_EXPORT,0,0,0}, @@ -318,6 +330,21 @@ static const SSL_CIPHER cipher_aliases[]={ {0,SSL_TXT_HIGH,0, 0,0,0,0,0,SSL_HIGH, 0,0,0}, /* FIPS 140-2 approved ciphersuite */ {0,SSL_TXT_FIPS,0, 0,0,~SSL_eNULL,0,0,SSL_FIPS, 0,0,0}, + + /* "EDH-" aliases to "DHE-" labels (for backward compatibility) */ + {0,SSL3_TXT_EDH_DSS_DES_40_CBC_SHA,0, + SSL_kDHE,SSL_aDSS,SSL_DES,SSL_SHA1,SSL_SSLV3,SSL_EXPORT|SSL_EXP40,0,0,0,}, + {0,SSL3_TXT_EDH_DSS_DES_64_CBC_SHA,0, + SSL_kDHE,SSL_aDSS,SSL_DES,SSL_SHA1,SSL_SSLV3,SSL_NOT_EXP|SSL_LOW,0,0,0,}, + {0,SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA,0, + SSL_kDHE,SSL_aDSS,SSL_3DES,SSL_SHA1,SSL_SSLV3,SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,0,0,0,}, + {0,SSL3_TXT_EDH_RSA_DES_40_CBC_SHA,0, + SSL_kDHE,SSL_aRSA,SSL_DES,SSL_SHA1,SSL_SSLV3,SSL_EXPORT|SSL_EXP40,0,0,0,}, + {0,SSL3_TXT_EDH_RSA_DES_64_CBC_SHA,0, + SSL_kDHE,SSL_aRSA,SSL_DES,SSL_SHA1,SSL_SSLV3,SSL_NOT_EXP|SSL_LOW,0,0,0,}, + {0,SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA,0, + SSL_kDHE,SSL_aRSA,SSL_3DES,SSL_SHA1,SSL_SSLV3,SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,0,0,0,}, + }; /* Search for public key algorithm with given name and * return its pkey_id if it is available. Otherwise return 0 @@ -383,6 +410,11 @@ void ssl_load_ciphers(void) ssl_cipher_methods[SSL_ENC_SEED_IDX]= EVP_get_cipherbyname(SN_seed_cbc); + ssl_cipher_methods[SSL_ENC_AES128GCM_IDX]= + EVP_get_cipherbyname(SN_aes_128_gcm); + ssl_cipher_methods[SSL_ENC_AES256GCM_IDX]= + EVP_get_cipherbyname(SN_aes_256_gcm); + ssl_digest_methods[SSL_MD_MD5_IDX]= EVP_get_digestbyname(SN_md5); ssl_mac_secret_size[SSL_MD_MD5_IDX]= @@ -412,6 +444,10 @@ void ssl_load_ciphers(void) EVP_get_digestbyname(SN_sha256); ssl_mac_secret_size[SSL_MD_SHA256_IDX]= EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); + ssl_digest_methods[SSL_MD_SHA384_IDX]= + EVP_get_digestbyname(SN_sha384); + ssl_mac_secret_size[SSL_MD_SHA384_IDX]= + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); } #ifndef OPENSSL_NO_COMP @@ -454,6 +490,7 @@ static void load_builtin_compressions(void) sk_SSL_COMP_push(ssl_comp_methods,comp); } } + sk_SSL_COMP_sort(ssl_comp_methods); } MemCheck_on(); } @@ -467,7 +504,7 @@ static void load_builtin_compressions(void) #endif int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp) + const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp, int use_etm) { int i; const SSL_CIPHER *c; @@ -533,12 +570,18 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_SEED: i=SSL_ENC_SEED_IDX; break; + case SSL_AES128GCM: + i=SSL_ENC_AES128GCM_IDX; + break; + case SSL_AES256GCM: + i=SSL_ENC_AES256GCM_IDX; + break; default: i= -1; break; } - if ((i < 0) || (i > SSL_ENC_NUM_IDX)) + if ((i < 0) || (i >= SSL_ENC_NUM_IDX)) *enc=NULL; else { @@ -559,6 +602,9 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, case SSL_SHA256: i=SSL_MD_SHA256_IDX; break; + case SSL_SHA384: + i=SSL_MD_SHA384_IDX; + break; case SSL_GOST94: i = SSL_MD_GOST94_IDX; break; @@ -569,19 +615,20 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, i= -1; break; } - if ((i < 0) || (i > SSL_MD_NUM_IDX)) + if ((i < 0) || (i >= SSL_MD_NUM_IDX)) { *md=NULL; if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef; if (mac_secret_size!=NULL) *mac_secret_size = 0; - + if (c->algorithm_mac == SSL_AEAD) + mac_pkey_type = NULL; } else { *md=ssl_digest_methods[i]; if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i]; if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i]; - } + } if ((*enc != NULL) && (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) && @@ -589,21 +636,36 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, { const EVP_CIPHER *evp; - if (s->ssl_version >= TLS1_VERSION && - c->algorithm_enc == SSL_RC4 && + if (use_etm) + return 1; + + if (s->ssl_version>>8 != TLS1_VERSION_MAJOR || + s->ssl_version < TLS1_VERSION) + return 1; + + if (FIPS_mode()) + return 1; + + if (c->algorithm_enc == SSL_RC4 && c->algorithm_mac == SSL_MD5 && (evp=EVP_get_cipherbyname("RC4-HMAC-MD5"))) *enc = evp, *md = NULL; - else if (s->ssl_version >= TLS1_VERSION && - c->algorithm_enc == SSL_AES128 && + else if (c->algorithm_enc == SSL_AES128 && c->algorithm_mac == SSL_SHA1 && (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) *enc = evp, *md = NULL; - else if (s->ssl_version >= TLS1_VERSION && - c->algorithm_enc == SSL_AES256 && + else if (c->algorithm_enc == SSL_AES256 && c->algorithm_mac == SSL_SHA1 && (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES128 && + c->algorithm_mac == SSL_SHA256 && + (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES256 && + c->algorithm_mac == SSL_SHA256 && + (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256"))) + *enc = evp, *md = NULL; return(1); } else @@ -674,10 +736,8 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un #ifdef OPENSSL_NO_DSA *auth |= SSL_aDSS; #endif - *mkey |= SSL_kDHr|SSL_kDHd; /* no such ciphersuites supported! */ - *auth |= SSL_aDH; #ifdef OPENSSL_NO_DH - *mkey |= SSL_kDHr|SSL_kDHd|SSL_kEDH; + *mkey |= SSL_kDHr|SSL_kDHd|SSL_kDHE; *auth |= SSL_aDH; #endif #ifdef OPENSSL_NO_KRB5 @@ -723,6 +783,8 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128:0; *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == NULL) ? SSL_AES128GCM:0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == NULL) ? SSL_AES256GCM:0; *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0; *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0; *enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT:0; @@ -731,6 +793,7 @@ static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, un *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256:0; + *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384:0; *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94:0; *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]==NID_undef)? SSL_GOST89MAC:0; @@ -749,7 +812,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, /* * We have num_of_ciphers descriptions compiled in, depending on the - * method selected (SSLv2 and/or SSLv3, TLSv1 etc). + * method selected (SSLv3, TLSv1 etc). * These will later be sorted in a linked list with at most num * entries. */ @@ -761,9 +824,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, c = ssl_method->get_cipher(i); /* drop those that use any of that is not available */ if ((c != NULL) && c->valid && -#ifdef OPENSSL_FIPS (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) && -#endif !(c->algorithm_mkey & disabled_mkey) && !(c->algorithm_auth & disabled_auth) && !(c->algorithm_enc & disabled_enc) && @@ -776,7 +837,7 @@ static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, co_list[co_list_num].active = 0; co_list_num++; #ifdef KSSL_DEBUG - printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth); + fprintf(stderr,"\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth); #endif /* KSSL_DEBUG */ /* if (!sk_push(ca_list,(char *)c)) goto err; @@ -888,12 +949,12 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id, int rule, int strength_bits, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { - CIPHER_ORDER *head, *tail, *curr, *curr2, *last; + CIPHER_ORDER *head, *tail, *curr, *next, *last; const SSL_CIPHER *cp; int reverse = 0; #ifdef CIPHER_DEBUG - printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n", + fprintf(stderr, "Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n", rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits); #endif @@ -905,21 +966,25 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id, if (reverse) { - curr = tail; + next = tail; last = head; } else { - curr = head; + next = head; last = tail; } - curr2 = curr; + curr = NULL; for (;;) { - if ((curr == NULL) || (curr == last)) break; - curr = curr2; - curr2 = reverse ? curr->prev : curr->next; + if (curr == last) break; + + curr = next; + + if (curr == NULL) break; + + next = reverse ? curr->prev : curr->next; cp = curr->cipher; @@ -935,9 +1000,12 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id, else { #ifdef CIPHER_DEBUG - printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength); + fprintf(stderr, "\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength); +#endif +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + if (cipher_id && cipher_id != cp->id) + continue; #endif - if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) continue; if (alg_auth && !(alg_auth & cp->algorithm_auth)) @@ -955,7 +1023,7 @@ static void ssl_cipher_apply_rule(unsigned long cipher_id, } #ifdef CIPHER_DEBUG - printf("Action = %d\n", rule); + fprintf(stderr, "Action = %d\n", rule); #endif /* add the cipher if it has not been added yet. */ @@ -1065,7 +1133,7 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, static int ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p, - const SSL_CIPHER **ca_list) + const SSL_CIPHER **ca_list, CERT *c) { unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength; const char *l, *buf; @@ -1114,9 +1182,11 @@ static int ssl_cipher_process_rulestr(const char *rule_str, while ( ((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || - (ch == '-')) + (ch == '-') || (ch == '.') || + (ch == '=')) #else - while ( isalnum(ch) || (ch == '-')) + while ( isalnum(ch) || (ch == '-') || (ch == '.') || + (ch == '=')) #endif { ch = *(++l); @@ -1282,6 +1352,20 @@ static int ssl_cipher_process_rulestr(const char *rule_str, if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) ok = ssl_cipher_strength_sort(head_p, tail_p); + else if (buflen == 10 && !strncmp(buf, "SECLEVEL=", 9)) + { + int level = buf[9] - '0'; + if (level < 0 || level > 5) + { + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, + SSL_R_INVALID_COMMAND); + } + else + { + c->sec_level = level; + ok = 1; + } + } else SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); @@ -1312,11 +1396,76 @@ static int ssl_cipher_process_rulestr(const char *rule_str, return(retval); } +#ifndef OPENSSL_NO_EC +static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, + const char **prule_str) + { + unsigned int suiteb_flags = 0, suiteb_comb2 = 0; + if (!strcmp(*prule_str, "SUITEB128")) + suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; + else if (!strcmp(*prule_str, "SUITEB128ONLY")) + suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY; + else if (!strcmp(*prule_str, "SUITEB128C2")) + { + suiteb_comb2 = 1; + suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; + } + else if (!strcmp(*prule_str, "SUITEB192")) + suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS; + + if (suiteb_flags) + { + c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS; + c->cert_flags |= suiteb_flags; + } + else + suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS; + + if (!suiteb_flags) + return 1; + /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */ + + if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) + { + if (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, + SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); + else + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, + SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); + return 0; + } + +#ifndef OPENSSL_NO_ECDH + switch(suiteb_flags) + { + case SSL_CERT_FLAG_SUITEB_128_LOS: + if (suiteb_comb2) + *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384"; + else + *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384"; + break; + case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: + *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256"; + break; + case SSL_CERT_FLAG_SUITEB_192_LOS: + *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384"; + break; + } + /* Set auto ECDH parameter determination */ + c->ecdh_tmp_auto = 1; + return 1; +#else + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE); + return 0; +#endif + } +#endif STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER) **cipher_list, STACK_OF(SSL_CIPHER) **cipher_list_by_id, - const char *rule_str) + const char *rule_str, CERT *c) { int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl; @@ -1330,6 +1479,10 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, */ if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) return NULL; +#ifndef OPENSSL_NO_EC + if (!check_suiteb_cipher_list(ssl_method, c, &rule_str)) + return NULL; +#endif /* * To reduce the work to do we only want to process the compiled @@ -1344,7 +1497,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, */ num_of_ciphers = ssl_method->num_ciphers(); #ifdef KSSL_DEBUG - printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers); + fprintf(stderr,"ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers); #endif /* KSSL_DEBUG */ co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); if (co_list == NULL) @@ -1361,8 +1514,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, /* Now arrange all ciphers by preference: */ /* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */ - ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); - ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); /* AES is our preferred symmetric cipher */ ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); @@ -1430,14 +1583,14 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, if (strncmp(rule_str,"DEFAULT",7) == 0) { ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, - &head, &tail, ca_list); + &head, &tail, ca_list, c); rule_p += 7; if (*rule_p == ':') rule_p++; } if (ok && (strlen(rule_p) > 0)) - ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); + ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list, c); OPENSSL_free((void *)ca_list); /* Not needed anymore */ @@ -1463,15 +1616,16 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, */ for (curr = head; curr != NULL; curr = curr->next) { -#ifdef OPENSSL_FIPS if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) -#else - if (curr->active) -#endif { - sk_SSL_CIPHER_push(cipherstack, curr->cipher); + if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) + { + OPENSSL_free(co_list); + sk_SSL_CIPHER_free(cipherstack); + return NULL; + } #ifdef CIPHER_DEBUG - printf("<%s>\n",curr->cipher->name); + fprintf(stderr, "<%s>\n",curr->cipher->name); #endif } } @@ -1500,7 +1654,7 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) int is_export,pkl,kl; const char *ver,*exp_str; const char *kx,*au,*enc,*mac; - unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2; + unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl; #ifdef KSSL_DEBUG static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n"; #else @@ -1513,17 +1667,15 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) alg_mac = cipher->algorithm_mac; alg_ssl = cipher->algorithm_ssl; - alg2=cipher->algorithm2; - is_export=SSL_C_IS_EXPORT(cipher); pkl=SSL_C_EXPORT_PKEYLENGTH(cipher); kl=SSL_C_EXPORT_KEYLENGTH(cipher); exp_str=is_export?" export":""; - if (alg_ssl & SSL_SSLV2) - ver="SSLv2"; - else if (alg_ssl & SSL_SSLV3) + if (alg_ssl & SSL_SSLV3) ver="SSLv3"; + else if (alg_ssl & SSL_TLSV1_2) + ver="TLSv1.2"; else ver="unknown"; @@ -1541,7 +1693,7 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kKRB5: kx="KRB5"; break; - case SSL_kEDH: + case SSL_kDHE: kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH"; break; case SSL_kECDHr: @@ -1550,7 +1702,7 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kECDHe: kx="ECDH/ECDSA"; break; - case SSL_kEECDH: + case SSL_kECDHE: kx="ECDH"; break; case SSL_kPSK: @@ -1559,6 +1711,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kSRP: kx="SRP"; break; + case SSL_kGOST: + kx="GOST"; + break; default: kx="unknown"; } @@ -1589,6 +1744,15 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_aPSK: au="PSK"; break; + case SSL_aSRP: + au="SRP"; + break; + case SSL_aGOST94: + au="GOST94"; + break; + case SSL_aGOST01: + au="GOST01"; + break; default: au="unknown"; break; @@ -1603,8 +1767,7 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) enc="3DES(168)"; break; case SSL_RC4: - enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)") - :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)"); + enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)"):"RC4(128)"; break; case SSL_RC2: enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)"; @@ -1621,6 +1784,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_AES256: enc="AES(256)"; break; + case SSL_AES128GCM: + enc="AESGCM(128)"; + break; + case SSL_AES256GCM: + enc="AESGCM(256)"; + break; case SSL_CAMELLIA128: enc="Camellia(128)"; break; @@ -1630,6 +1799,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_SEED: enc="SEED(128)"; break; + case SSL_eGOST2814789CNT: + enc="GOST89(256)"; + break; default: enc="unknown"; break; @@ -1646,6 +1818,18 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_SHA256: mac="SHA256"; break; + case SSL_SHA384: + mac="SHA384"; + break; + case SSL_AEAD: + mac="AEAD"; + break; + case SSL_GOST89MAC: + mac="GOST89"; + break; + case SSL_GOST94: + mac="GOST94"; + break; default: mac="unknown"; break; @@ -1676,8 +1860,6 @@ char *SSL_CIPHER_get_version(const SSL_CIPHER *c) i=(int)(c->id>>24L); if (i == 3) return("TLSv1/SSLv3"); - else if (i == 2) - return("SSLv2"); else return("unknown"); } @@ -1745,6 +1927,25 @@ STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) return(ssl_comp_methods); } +STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) *meths) + { + STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods; + ssl_comp_methods = meths; + return old_meths; + } + +static void cmeth_free(SSL_COMP *cm) + { + OPENSSL_free(cm); + } + +void SSL_COMP_free_compression_methods(void) + { + STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods; + ssl_comp_methods = NULL; + sk_SSL_COMP_pop_free(old_meths, cmeth_free); + } + int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { SSL_COMP *comp; @@ -1752,12 +1953,14 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) if (cm == NULL || cm->type == NID_undef) return 1; - /* According to draft-ietf-tls-compression-04.txt, the - compression number ranges should be the following: - - 0 to 63: methods defined by the IETF - 64 to 192: external party methods assigned by IANA - 193 to 255: reserved for private use */ + /*- + * According to draft-ietf-tls-compression-04.txt, the + * compression number ranges should be the following: + * + * 0 to 63: methods defined by the IETF + * 64 to 192: external party methods assigned by IANA + * 193 to 255: reserved for private use + */ if (id < 193 || id > 255) { SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); @@ -1766,6 +1969,13 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) MemCheck_off(); comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp == NULL) + { + MemCheck_on(); + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE); + return(1); + } + comp->id=id; comp->method=cm; load_builtin_compressions(); @@ -1798,5 +2008,60 @@ const char *SSL_COMP_get_name(const COMP_METHOD *comp) return comp->name; return NULL; } - #endif +/* For a cipher return the index corresponding to the certificate type */ +int ssl_cipher_get_cert_index(const SSL_CIPHER *c) + { + unsigned long alg_k, alg_a; + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + + if (alg_k & (SSL_kECDHr|SSL_kECDHe)) + { + /* we don't need to look at SSL_kECDHE + * since no certificate is needed for + * anon ECDH and for authenticated + * ECDHE, the check for the auth + * algorithm will set i correctly + * NOTE: For ECDH-RSA, we need an ECC + * not an RSA cert but for ECDHE-RSA + * we need an RSA cert. Placing the + * checks for SSL_kECDH before RSA + * checks ensures the correct cert is chosen. + */ + return SSL_PKEY_ECC; + } + else if (alg_a & SSL_aECDSA) + return SSL_PKEY_ECC; + else if (alg_k & SSL_kDHr) + return SSL_PKEY_DH_RSA; + else if (alg_k & SSL_kDHd) + return SSL_PKEY_DH_DSA; + else if (alg_a & SSL_aDSS) + return SSL_PKEY_DSA_SIGN; + else if (alg_a & SSL_aRSA) + return SSL_PKEY_RSA_ENC; + else if (alg_a & SSL_aKRB5) + /* VRS something else here? */ + return -1; + else if (alg_a & SSL_aGOST94) + return SSL_PKEY_GOST94; + else if (alg_a & SSL_aGOST01) + return SSL_PKEY_GOST01; + return -1; + } + +const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr) + { + const SSL_CIPHER *c; + c = ssl->method->get_cipher_by_char(ptr); + if (c == NULL || c->valid == 0) + return NULL; + return c; + } + +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr) + { + return ssl->method->get_cipher_by_char(ptr); + }