#ifndef OPENSSL_NO_ENGINE
# include <openssl/engine.h>
#endif
+#include "internal/threads.h"
#include "ssl_locl.h"
#define SSL_ENC_DES_IDX 0
static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+static CRYPTO_ONCE ssl_load_builtin_comp_once = CRYPTO_ONCE_STATIC_INIT;
+
/*
* Constant SSL_MAX_DIGEST equal to size of digests array should be defined
* in the ssl_locl.h
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
+static const ssl_cipher_table ssl_cipher_table_kx[] = {
+ { SSL_kRSA, NID_kx_rsa },
+ { SSL_kECDHE, NID_kx_ecdhe },
+ { SSL_kDHE, NID_kx_dhe },
+ { SSL_kECDHEPSK, NID_kx_ecdhe_psk },
+ { SSL_kDHEPSK, NID_kx_dhe_psk },
+ { SSL_kRSAPSK, NID_kx_rsa_psk },
+ { SSL_kPSK, NID_kx_psk },
+ { SSL_kSRP, NID_kx_srp },
+ { SSL_kGOST, NID_kx_gost }
+};
+
+static const ssl_cipher_table ssl_cipher_table_auth[] = {
+ { SSL_aRSA, NID_auth_rsa },
+ { SSL_aECDSA, NID_auth_ecdsa },
+ { SSL_aPSK, NID_auth_psk },
+ { SSL_aDSS, NID_auth_dss },
+ { SSL_aGOST01, NID_auth_gost01 },
+ { SSL_aGOST12, NID_auth_gost12 },
+ { SSL_aSRP, NID_auth_srp },
+ { SSL_aNULL, NID_auth_null }
+};
+
/* Utility function for table lookup */
static int ssl_cipher_info_find(const ssl_cipher_table * table,
size_t table_cnt, uint32_t mask)
#define CIPHER_DEL 3
#define CIPHER_ORD 4
#define CIPHER_SPECIAL 5
+/*
+ * Bump the ciphers to the top of the list.
+ * This rule isn't currently supported by the public cipherstring API.
+ */
+#define CIPHER_BUMP 6
typedef struct cipher_order_st {
const SSL_CIPHER *cipher;
static const SSL_CIPHER cipher_aliases[] = {
/* "ALL" doesn't include eNULL (must be specifically enabled) */
- {0, SSL_TXT_ALL, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_ALL, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/* "COMPLEMENTOFALL" */
- {0, SSL_TXT_CMPALL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_CMPALL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/*
* "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in
* ALL!)
*/
- {0, SSL_TXT_CMPDEF, 0, 0, 0, ~SSL_eNULL, 0, 0, SSL_NOT_DEFAULT, 0, 0, 0},
+ {0, SSL_TXT_CMPDEF, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_NOT_DEFAULT, 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. 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_kRSA, 0, SSL_kRSA, 0, 0, 0, 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_kDHE, 0, 0, 0, 0, 0, 0, 0,
- 0},
+ {0, SSL_TXT_kEDH, 0, SSL_kDHE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_kDHE, 0, SSL_kDHE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_DH, 0, SSL_kDHE, 0, 0, 0, 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_kECDHE, 0, 0, 0, 0, 0,
- 0, 0, 0},
+ {0, SSL_TXT_kEECDH, 0, SSL_kECDHE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_kECDHE, 0, SSL_kECDHE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_ECDH, 0, SSL_kECDHE, 0, 0, 0, 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_kRSAPSK, 0, SSL_kRSAPSK, 0, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_kECDHEPSK, 0, SSL_kECDHEPSK, 0, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_kDHEPSK, 0, SSL_kDHEPSK, 0, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_kSRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_kGOST, 0, SSL_kGOST, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_kPSK, 0, SSL_kPSK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_kRSAPSK, 0, SSL_kRSAPSK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_kECDHEPSK, 0, SSL_kECDHEPSK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_kDHEPSK, 0, SSL_kDHEPSK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_kSRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_kGOST, 0, SSL_kGOST, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/* server authentication aliases */
- {0, SSL_TXT_aRSA, 0, 0, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_aDSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_DSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_aNULL, 0, 0, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_aECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_ECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_aPSK, 0, 0, SSL_aPSK, 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_aGOST12, 0, 0, SSL_aGOST12, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_aGOST, 0, 0, SSL_aGOST01 | SSL_aGOST12, 0, 0, 0,
+ {0, SSL_TXT_aRSA, 0, 0, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_aDSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_DSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_aNULL, 0, 0, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_aECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_ECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_aPSK, 0, 0, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_aGOST01, 0, 0, SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_aGOST12, 0, 0, SSL_aGOST12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_aGOST, 0, 0, SSL_aGOST01 | SSL_aGOST12, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0},
- {0, SSL_TXT_aSRP, 0, 0, SSL_aSRP, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_aSRP, 0, 0, SSL_aSRP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/* aliases combining key exchange and server authentication */
- {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_RSA, 0, SSL_kRSA, SSL_aRSA, 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_PSK, 0, 0, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_SRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_EDH, 0, SSL_kDHE, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_DHE, 0, SSL_kDHE, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_EECDH, 0, SSL_kECDHE, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_ECDHE, 0, SSL_kECDHE, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_NULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_RSA, 0, SSL_kRSA, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_ADH, 0, SSL_kDHE, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_AECDH, 0, SSL_kECDHE, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_PSK, 0, SSL_PSK, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_SRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/* symmetric encryption aliases */
- {0, SSL_TXT_DES, 0, 0, 0, SSL_DES, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_3DES, 0, 0, 0, SSL_3DES, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_RC4, 0, 0, 0, SSL_RC4, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_RC2, 0, 0, 0, SSL_RC2, 0, 0, 0, 0, 0, 0},
- {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_3DES, 0, 0, 0, SSL_3DES, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_RC4, 0, 0, 0, SSL_RC4, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_RC2, 0, 0, 0, SSL_RC2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_IDEA, 0, 0, 0, SSL_IDEA, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_SEED, 0, 0, 0, SSL_SEED, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_eNULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_GOST, 0, 0, 0, SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12, 0,
- 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_AES128, 0, 0, 0, SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM | SSL_AES128CCM8, 0,
- 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_AES256, 0, 0, 0, SSL_AES256 | SSL_AES256GCM | SSL_AES256CCM | SSL_AES256CCM8, 0,
- 0, 0, 0, 0, 0},
- {0, SSL_TXT_AES, 0, 0, 0, SSL_AES, 0, 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_AES, 0, 0, 0, SSL_AES, 0, 0, 0, 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_AES_CCM, 0, 0, 0, SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8, 0, 0, 0, 0,
- 0, 0},
+ 0, 0, 0, 0, 0},
+ {0, SSL_TXT_AES_CCM, 0, 0, 0,
+ SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_AES_CCM_8, 0, 0, 0, SSL_AES128CCM8 | SSL_AES256CCM8, 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_CAMELLIA, 0, 0, 0, 0, 0, 0},
- {0, SSL_TXT_CHACHA20, 0, 0, 0, SSL_CHACHA20, 0, 0, 0, 0, 0, 0 },
+ {0, SSL_TXT_CAMELLIA128, 0, 0, 0, SSL_CAMELLIA128, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0},
+ {0, SSL_TXT_CAMELLIA256, 0, 0, 0, SSL_CAMELLIA256, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0},
+ {0, SSL_TXT_CAMELLIA, 0, 0, 0, SSL_CAMELLIA, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_CHACHA20, 0, 0, 0, SSL_CHACHA20, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
/* MAC aliases */
- {0, SSL_TXT_MD5, 0, 0, 0, 0, SSL_MD5, 0, 0, 0, 0, 0},
- {0, SSL_TXT_SHA1, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0},
- {0, SSL_TXT_SHA, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0},
- {0, SSL_TXT_GOST94, 0, 0, 0, 0, SSL_GOST94, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_MD5, 0, 0, 0, 0, SSL_MD5, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_SHA1, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_SHA, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_GOST94, 0, 0, 0, 0, SSL_GOST94, 0, 0, 0, 0, 0, 0, 0, 0},
{0, SSL_TXT_GOST89MAC, 0, 0, 0, 0, SSL_GOST89MAC | SSL_GOST89MAC12, 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},
- {0, SSL_TXT_GOST12, 0, 0, 0, 0, SSL_GOST12_256, 0, 0, 0, 0, 0},
+ 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_SHA256, 0, 0, 0, 0, SSL_SHA256, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_SHA384, 0, 0, 0, 0, SSL_SHA384, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_GOST12, 0, 0, 0, 0, SSL_GOST12_256, 0, 0, 0, 0, 0, 0, 0, 0},
/* protocol version aliases */
- {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_SSLV3, 0, 0, 0, 0},
- {0, "TLSv1.0", 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},
+ {0, SSL_TXT_SSLV3, 0, 0, 0, 0, 0, SSL3_VERSION, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_TLSV1, 0, 0, 0, 0, 0, TLS1_VERSION, 0, 0, 0, 0, 0, 0, 0},
+ {0, "TLSv1.0", 0, 0, 0, 0, 0, TLS1_VERSION, 0, 0, 0, 0, 0, 0, 0},
+ {0, SSL_TXT_TLSV1_2, 0, 0, 0, 0, 0, TLS1_2_VERSION, 0, 0, 0, 0, 0, 0, 0},
/* strength classes */
- {0, SSL_TXT_LOW, 0, 0, 0, 0, 0, 0, SSL_LOW, 0, 0, 0},
- {0, SSL_TXT_MEDIUM, 0, 0, 0, 0, 0, 0, SSL_MEDIUM, 0, 0, 0},
- {0, SSL_TXT_HIGH, 0, 0, 0, 0, 0, 0, SSL_HIGH, 0, 0, 0},
+ {0, SSL_TXT_LOW, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_LOW, 0, 0, 0},
+ {0, SSL_TXT_MEDIUM, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_MEDIUM, 0, 0, 0},
+ {0, SSL_TXT_HIGH, 0, 0, 0, 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},
+ {0, SSL_TXT_FIPS, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, SSL_FIPS, 0, 0, 0},
/* "EDH-" aliases to "DHE-" labels (for backward compatibility) */
{0, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, 0,
- SSL_kDHE, SSL_aDSS, SSL_3DES, SSL_SHA1, SSL_SSLV3,
+ SSL_kDHE, SSL_aDSS, SSL_3DES, SSL_SHA1, 0, 0, 0, 0,
SSL_HIGH | SSL_FIPS, 0, 0, 0,},
{0, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, 0,
- SSL_kDHE, SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3,
+ SSL_kDHE, SSL_aRSA, SSL_3DES, SSL_SHA1, 0, 0, 0, 0,
SSL_HIGH | SSL_FIPS, 0, 0, 0,},
};
ameth) <= 0)
pkey_id = 0;
}
- if (tmpeng)
- ENGINE_finish(tmpeng);
+ ENGINE_finish(tmpeng);
return pkey_id;
}
return ((*a)->id - (*b)->id);
}
-static void load_builtin_compressions(void)
+static void do_load_builtin_compressions(void)
{
- int got_write_lock = 0;
-
- CRYPTO_r_lock(CRYPTO_LOCK_SSL);
- if (ssl_comp_methods == NULL) {
- CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
- CRYPTO_w_lock(CRYPTO_LOCK_SSL);
- got_write_lock = 1;
-
- if (ssl_comp_methods == NULL) {
- SSL_COMP *comp = NULL;
- COMP_METHOD *method = COMP_zlib();
-
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
- ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp);
- if (COMP_get_type(method) != NID_undef
- && ssl_comp_methods != NULL) {
- comp = OPENSSL_malloc(sizeof(*comp));
- if (comp != NULL) {
- comp->method = method;
- comp->id = SSL_COMP_ZLIB_IDX;
- comp->name = COMP_get_name(method);
- sk_SSL_COMP_push(ssl_comp_methods, comp);
- sk_SSL_COMP_sort(ssl_comp_methods);
- }
- }
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+ SSL_COMP *comp = NULL;
+ COMP_METHOD *method = COMP_zlib();
+
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+ ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp);
+
+ if (COMP_get_type(method) != NID_undef && ssl_comp_methods != NULL) {
+ comp = OPENSSL_malloc(sizeof(*comp));
+ if (comp != NULL) {
+ comp->method = method;
+ comp->id = SSL_COMP_ZLIB_IDX;
+ comp->name = COMP_get_name(method);
+ sk_SSL_COMP_push(ssl_comp_methods, comp);
+ sk_SSL_COMP_sort(ssl_comp_methods);
}
}
+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+}
- if (got_write_lock)
- CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
- else
- CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
+static void load_builtin_compressions(void)
+{
+ CRYPTO_THREAD_run_once(&ssl_load_builtin_comp_once,
+ do_load_builtin_compressions);
}
#endif
uint32_t disabled_auth,
uint32_t disabled_enc,
uint32_t disabled_mac,
- uint32_t disabled_ssl,
CIPHER_ORDER *co_list,
CIPHER_ORDER **head_p,
CIPHER_ORDER **tail_p)
!(c->algorithm_mkey & disabled_mkey) &&
!(c->algorithm_auth & disabled_auth) &&
!(c->algorithm_enc & disabled_enc) &&
- !(c->algorithm_mac & disabled_mac) &&
- !(c->algorithm_ssl & disabled_ssl)) {
+ !(c->algorithm_mac & disabled_mac)) {
co_list[co_list_num].cipher = c;
co_list[co_list_num].next = NULL;
co_list[co_list_num].prev = NULL;
uint32_t disabled_auth,
uint32_t disabled_enc,
uint32_t disabled_mac,
- uint32_t disabled_ssl,
CIPHER_ORDER *head)
{
CIPHER_ORDER *ciph_curr;
uint32_t mask_auth = ~disabled_auth;
uint32_t mask_enc = ~disabled_enc;
uint32_t mask_mac = ~disabled_mac;
- uint32_t mask_ssl = ~disabled_ssl;
/*
* First, add the real ciphers as already collected
uint32_t algorithm_auth = cipher_aliases[i].algorithm_auth;
uint32_t algorithm_enc = cipher_aliases[i].algorithm_enc;
uint32_t algorithm_mac = cipher_aliases[i].algorithm_mac;
- uint32_t algorithm_ssl = cipher_aliases[i].algorithm_ssl;
if (algorithm_mkey)
if ((algorithm_mkey & mask_mkey) == 0)
if ((algorithm_mac & mask_mac) == 0)
continue;
- if (algorithm_ssl)
- if ((algorithm_ssl & mask_ssl) == 0)
- continue;
-
*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
ca_curr++;
}
static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey,
uint32_t alg_auth, uint32_t alg_enc,
- uint32_t alg_mac, uint32_t alg_ssl,
+ uint32_t alg_mac, int min_tls,
uint32_t algo_strength, int rule,
int32_t strength_bits, CIPHER_ORDER **head_p,
CIPHER_ORDER **tail_p)
#ifdef CIPHER_DEBUG
fprintf(stderr,
"Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n",
- rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl,
+ rule, alg_mkey, alg_auth, alg_enc, alg_mac, min_tls,
algo_strength, strength_bits);
#endif
- if (rule == CIPHER_DEL)
+ if (rule == CIPHER_DEL || rule == CIPHER_BUMP)
reverse = 1; /* needed to maintain sorting between
* currently deleted ciphers */
continue;
if (alg_mac && !(alg_mac & cp->algorithm_mac))
continue;
- if (alg_ssl && !(alg_ssl & cp->algorithm_ssl))
+ if (min_tls && (min_tls != cp->min_tls))
continue;
if (algo_strength && !(algo_strength & cp->algo_strength))
continue;
ll_append_head(&head, curr, &tail);
curr->active = 0;
}
+ } else if (rule == CIPHER_BUMP) {
+ if (curr->active)
+ ll_append_head(&head, curr, &tail);
} else if (rule == CIPHER_KILL) {
/* reverse == 0 */
if (head == curr)
CIPHER_ORDER **tail_p,
const SSL_CIPHER **ca_list, CERT *c)
{
- uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength;
+ uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, algo_strength;
+ int min_tls;
const char *l, *buf;
int j, multi, found, rule, retval, ok, buflen;
uint32_t cipher_id = 0;
alg_auth = 0;
alg_enc = 0;
alg_mac = 0;
- alg_ssl = 0;
+ min_tls = 0;
algo_strength = 0;
for (;;) {
* protocol version is considered part of the search pattern
*/
- if (ca_list[j]->algorithm_ssl) {
- if (alg_ssl) {
- alg_ssl &= ca_list[j]->algorithm_ssl;
- if (!alg_ssl) {
- found = 0;
- break;
- }
- } else
- alg_ssl = ca_list[j]->algorithm_ssl;
+ if (ca_list[j]->min_tls) {
+ if (min_tls != 0 && min_tls != ca_list[j]->min_tls) {
+ found = 0;
+ break;
+ } else {
+ min_tls = ca_list[j]->min_tls;
+ }
}
}
} else if (found) {
ssl_cipher_apply_rule(cipher_id,
alg_mkey, alg_auth, alg_enc, alg_mac,
- alg_ssl, algo_strength, rule, -1, head_p,
+ min_tls, algo_strength, rule, -1, head_p,
tail_p);
} else {
while ((*l != '\0') && !ITEM_SEP(*l))
const char *rule_str, CERT *c)
{
int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
- uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac,
- disabled_ssl;
+ uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac;
STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
const char *rule_p;
CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
disabled_auth = disabled_auth_mask;
disabled_enc = disabled_enc_mask;
disabled_mac = disabled_mac_mask;
- disabled_ssl = 0;
/*
* Now we have to collect the available ciphers from the compiled
ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
disabled_mkey, disabled_auth, disabled_enc,
- disabled_mac, disabled_ssl, co_list, &head,
+ disabled_mac, co_list, &head,
&tail);
- /* Now arrange all ciphers by preference: */
+ /* Now arrange all ciphers by preference. */
/*
* Everything else being equal, prefer ephemeral ECDH over other key
- * exchange mechanisms
+ * exchange mechanisms.
+ * For consistency, prefer ECDSA over RSA (though this only matters if the
+ * server has both certificates, and is using the DEFAULT, or a client
+ * preference).
*/
+ ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD,
+ -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);
+
+ /* Within each strength group, we prefer GCM over CHACHA... */
+ ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1,
+ &head, &tail);
+
+ /*
+ * ...and generally, our preferred cipher is AES.
+ * Note that AEADs will be bumped to take preference after sorting by
+ * strength.
+ */
+ ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD,
+ -1, &head, &tail);
/* Temporarily enable everything else for sorting */
ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
return NULL;
}
+ /*
+ * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs.
+ * TODO(openssl-team): is there an easier way to accomplish all this?
+ */
+ ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1,
+ &head, &tail);
+
+ /*
+ * Irrespective of strength, enforce the following order:
+ * (EC)DHE + AEAD > (EC)DHE > rest of AEAD > rest.
+ * Within each group, ciphers remain sorted by strength and previous
+ * preference, i.e.,
+ * 1) ECDHE > DHE
+ * 2) GCM > CHACHA
+ * 3) AES > rest
+ * 4) TLS 1.2 > legacy
+ *
+ * Because we now bump ciphers to the top of the list, we proceed in
+ * reverse order of preference.
+ */
+ ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1,
+ &head, &tail);
+ ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0,
+ CIPHER_BUMP, -1, &head, &tail);
+ ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0,
+ CIPHER_BUMP, -1, &head, &tail);
+
/* Now disable everything (maintaining the ordering!) */
ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
}
ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
disabled_mkey, disabled_auth, disabled_enc,
- disabled_mac, disabled_ssl, head);
+ disabled_mac, head);
/*
* If the rule_string begins with DEFAULT, apply the default rule
alg_enc = cipher->algorithm_enc;
alg_mac = cipher->algorithm_mac;
- ver = SSL_CIPHER_get_version(cipher);
+ ver = ssl_protocol_to_string(cipher->min_tls);
switch (alg_mkey) {
case SSL_kRSA:
return (buf);
}
-char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
+const char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
{
- uint32_t alg_ssl;
-
if (c == NULL)
return "(NONE)";
- alg_ssl = c->algorithm_ssl;
-
- if (alg_ssl & SSL_SSLV3)
- return "SSLv3";
- if (alg_ssl & SSL_TLSV1)
- return "TLSv1.0";
- if (alg_ssl & SSL_TLSV1_2)
- return "TLSv1.2";
- return "unknown";
+ return ssl_protocol_to_string(c->min_tls);
}
/* return the actual cipher being used */
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);
+ const SSL_CIPHER *c = ssl->method->get_cipher_by_char(ptr);
+
if (c == NULL || c->valid == 0)
return NULL;
return c;
{
int i;
if (c == NULL)
- return -1;
+ return NID_undef;
i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, c->algorithm_enc);
if (i == -1)
- return -1;
+ return NID_undef;
return ssl_cipher_table_cipher[i].nid;
}
int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c)
{
- int i;
- if (c == NULL)
- return -1;
- i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac);
+ int i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac);
+
if (i == -1)
- return -1;
+ return NID_undef;
return ssl_cipher_table_mac[i].nid;
}
+
+int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c)
+{
+ int i = ssl_cipher_info_lookup(ssl_cipher_table_kx, c->algorithm_mkey);
+
+ if (i == -1)
+ return NID_undef;
+ return ssl_cipher_table_kx[i].nid;
+}
+
+int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c)
+{
+ int i = ssl_cipher_info_lookup(ssl_cipher_table_auth, c->algorithm_auth);
+
+ if (i == -1)
+ return NID_undef;
+ return ssl_cipher_table_auth[i].nid;
+}
+
+int SSL_CIPHER_is_aead(const SSL_CIPHER *c)
+{
+ return (c->algorithm_mac & SSL_AEAD) ? 1 : 0;
+}