From 3ec13237f00d3b06a2fd1d228da16390803eb238 Mon Sep 17 00:00:00 2001 From: Todd Short Date: Sat, 5 Mar 2016 09:47:46 -0500 Subject: [PATCH] Add cipher query functions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add functions to determine authentication, key-exchange, FIPS and AEAD. Reviewed-by: Emilia Käsper Reviewed-by: Rich Salz --- CHANGES | 3 ++ crypto/objects/obj_dat.h | 57 +++++++++++++++++++++++++-- crypto/objects/obj_mac.num | 19 +++++++++ crypto/objects/objects.txt | 22 +++++++++++ doc/ssl/SSL_CIPHER_get_name.pod | 22 +++++++++++ include/openssl/obj_mac.h | 68 +++++++++++++++++++++++++++++++++ include/openssl/ssl.h | 3 ++ ssl/ssl_ciph.c | 52 +++++++++++++++++++++++-- util/libssl.num | 3 ++ 9 files changed, 242 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 9ff84fc185..9f32b9adfd 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,9 @@ callback, such that updates to the SSL_CTX affect ALPN. [Todd Short] + *) Add SSL_CIPHER queries for authentication and key-exchange. + [Todd Short] + *) Changes to the DEFAULT cipherlist: - Prefer (EC)DHE handshakes over plain RSA. - Prefer AEAD ciphers over legacy ciphers. diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 0528dfb9cb..8cd3b2071e 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -60,9 +60,9 @@ * [including the GNU Public Licence.] */ -#define NUM_NID 1037 -#define NUM_SN 1030 -#define NUM_LN 1030 +#define NUM_NID 1054 +#define NUM_SN 1047 +#define NUM_LN 1047 #define NUM_OBJ 951 static const unsigned char lvalues[6722]={ @@ -2705,6 +2705,23 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={ {"X25519","X25519",NID_X25519,9,&(lvalues[6703]),0}, {"X448","X448",NID_X448,9,&(lvalues[6712]),0}, {"HKDF","hkdf",NID_hkdf,0,NULL,0}, +{"KxRSA","kx-rsa",NID_kx_rsa,0,NULL,0}, +{"KxECDHE","kx-ecdhe",NID_kx_ecdhe,0,NULL,0}, +{"KxDHE","kx-dhe",NID_kx_dhe,0,NULL,0}, +{"KxECDHE-PSK","kx-ecdhe-psk",NID_kx_ecdhe_psk,0,NULL,0}, +{"KxDHE-PSK","kx-dhe-psk",NID_kx_dhe_psk,0,NULL,0}, +{"KxRSA_PSK","kx-rsa-psk",NID_kx_rsa_psk,0,NULL,0}, +{"KxPSK","kx-psk",NID_kx_psk,0,NULL,0}, +{"KxSRP","kx-srp",NID_kx_srp,0,NULL,0}, +{"KxGOST","kx-gost",NID_kx_gost,0,NULL,0}, +{"AuthRSA","auth-rsa",NID_auth_rsa,0,NULL,0}, +{"AuthECDSA","auth-ecdsa",NID_auth_ecdsa,0,NULL,0}, +{"AuthPSK","auth-psk",NID_auth_psk,0,NULL,0}, +{"AuthDSS","auth-dss",NID_auth_dss,0,NULL,0}, +{"AuthGOST01","auth-gost01",NID_auth_gost01,0,NULL,0}, +{"AuthGOST12","auth-gost12",NID_auth_gost12,0,NULL,0}, +{"AuthSRP","auth-srp",NID_auth_srp,0,NULL,0}, +{"AuthNULL","auth-null",NID_auth_null,0,NULL,0}, }; static const unsigned int sn_objs[NUM_SN]={ @@ -2741,6 +2758,14 @@ static const unsigned int sn_objs[NUM_SN]={ 960, /* "AES-256-OCB" */ 428, /* "AES-256-OFB" */ 914, /* "AES-256-XTS" */ +1049, /* "AuthDSS" */ +1047, /* "AuthECDSA" */ +1050, /* "AuthGOST01" */ +1051, /* "AuthGOST12" */ +1053, /* "AuthNULL" */ +1048, /* "AuthPSK" */ +1046, /* "AuthRSA" */ +1052, /* "AuthSRP" */ 91, /* "BF-CBC" */ 93, /* "BF-CFB" */ 92, /* "BF-ECB" */ @@ -2829,6 +2854,15 @@ static const unsigned int sn_objs[NUM_SN]={ 645, /* "ITU-T" */ 646, /* "JOINT-ISO-ITU-T" */ 773, /* "KISA" */ +1039, /* "KxDHE" */ +1041, /* "KxDHE-PSK" */ +1038, /* "KxECDHE" */ +1040, /* "KxECDHE-PSK" */ +1045, /* "KxGOST" */ +1043, /* "KxPSK" */ +1037, /* "KxRSA" */ +1042, /* "KxRSA_PSK" */ +1044, /* "KxSRP" */ 15, /* "L" */ 856, /* "LocalKeySet" */ 3, /* "MD2" */ @@ -3961,6 +3995,14 @@ static const unsigned int ln_objs[NUM_LN]={ 484, /* "associatedDomain" */ 485, /* "associatedName" */ 501, /* "audio" */ +1049, /* "auth-dss" */ +1047, /* "auth-ecdsa" */ +1050, /* "auth-gost01" */ +1051, /* "auth-gost12" */ +1053, /* "auth-null" */ +1048, /* "auth-psk" */ +1046, /* "auth-rsa" */ +1052, /* "auth-srp" */ 882, /* "authorityRevocationList" */ 91, /* "bf-cbc" */ 93, /* "bf-cfb" */ @@ -4421,6 +4463,15 @@ static const unsigned int ln_objs[NUM_LN]={ 956, /* "jurisdictionStateOrProvinceName" */ 150, /* "keyBag" */ 773, /* "kisa" */ +1039, /* "kx-dhe" */ +1041, /* "kx-dhe-psk" */ +1038, /* "kx-ecdhe" */ +1040, /* "kx-ecdhe-psk" */ +1045, /* "kx-gost" */ +1043, /* "kx-psk" */ +1037, /* "kx-rsa" */ +1042, /* "kx-rsa-psk" */ +1044, /* "kx-srp" */ 477, /* "lastModifiedBy" */ 476, /* "lastModifiedTime" */ 157, /* "localKeyID" */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index ce8e8ec28a..2a80d9d0c9 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1034,3 +1034,22 @@ pkInitKDC 1033 X25519 1034 X448 1035 hkdf 1036 +kx_rsa 1037 +kx_ecdhe 1038 +kx_dhe 1039 +kx_ecdhe_psk 1040 +kx_dhe_psk 1041 +kx_rsa_psk 1042 +kx_psk 1043 +kx_srp 1044 +kx_gost 1045 +auth_rsa 1046 +auth_ecdsa 1047 +auth_psk 1048 +auth_dss 1049 +auth_gost01 1050 +auth_gost12 1051 +auth_srp 1052 +auth_null 1053 +fips_none 1054 +fips_140_2 1055 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 9d04a63431..a79968b85a 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -1456,3 +1456,25 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response 1 3 6 1 4 1 11591 15 1 : X25519 1 3 6 1 4 1 11591 15 2 : X448 + +# NIDs for cipher key exchange + : KxRSA : kx-rsa + : KxECDHE : kx-ecdhe + : KxDHE : kx-dhe + : KxECDHE-PSK : kx-ecdhe-psk + : KxDHE-PSK : kx-dhe-psk + : KxRSA_PSK : kx-rsa-psk + : KxPSK : kx-psk + : KxSRP : kx-srp + : KxGOST : kx-gost + +# NIDs for cipher authentication + : AuthRSA : auth-rsa + : AuthECDSA : auth-ecdsa + : AuthPSK : auth-psk + : AuthDSS : auth-dss + : AuthGOST01 : auth-gost01 + : AuthGOST12 : auth-gost12 + : AuthSRP : auth-srp + : AuthNULL : auth-null + diff --git a/doc/ssl/SSL_CIPHER_get_name.pod b/doc/ssl/SSL_CIPHER_get_name.pod index db0ddaa348..296aa3264f 100644 --- a/doc/ssl/SSL_CIPHER_get_name.pod +++ b/doc/ssl/SSL_CIPHER_get_name.pod @@ -14,6 +14,9 @@ SSL_CIPHER_get_name, SSL_CIPHER_get_bits, SSL_CIPHER_get_version, SSL_CIPHER_des char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int size); int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c); int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c); + int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c); + int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c); + int SSL_CIPHER_is_aead(const SSL_CIPHER *c); =head1 DESCRIPTION @@ -34,6 +37,25 @@ SSL_CIPHER_get_digest_nid() returns the digest NID corresponding to the MAC used by B. If there is no digest (e.g. for AEAD ciphersuites) then B is returned. +SSL_CIPHER_get_kx_nid() returns the key exchange NID corresponding to the method +used by B. If there is no key exchange, then B is returned. Examples (not comprehensive): + + NID_kx_rsa + NID_kx_ecdhe + NID_kx_dhe + NID_kx_psk + +SSL_CIPHER_get_auth_nid() returns the authentication NID corresponding to the method +used by B. If there is no authentication, then B is returned. +Examples (not comprehensive): + + NID_auth_rsa + NID_auth_ecdsa + NID_auth_psk + +SSL_CIPHER_is_aead() returns 1 if the cipher B is AEAD (e.g. GCM or +ChaCha20/Poly1305), and 0 if it is not AEAD. + SSL_CIPHER_description() returns a textual description of the cipher used into the buffer B of length B provided. If B is provided, it must be at least 128 bytes, otherwise a buffer will be allocated using diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index f39d77295d..4725a6c574 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -4536,3 +4536,71 @@ #define SN_X448 "X448" #define NID_X448 1035 #define OBJ_X448 1L,3L,6L,1L,4L,1L,11591L,15L,2L + +#define SN_kx_rsa "KxRSA" +#define LN_kx_rsa "kx-rsa" +#define NID_kx_rsa 1037 + +#define SN_kx_ecdhe "KxECDHE" +#define LN_kx_ecdhe "kx-ecdhe" +#define NID_kx_ecdhe 1038 + +#define SN_kx_dhe "KxDHE" +#define LN_kx_dhe "kx-dhe" +#define NID_kx_dhe 1039 + +#define SN_kx_ecdhe_psk "KxECDHE-PSK" +#define LN_kx_ecdhe_psk "kx-ecdhe-psk" +#define NID_kx_ecdhe_psk 1040 + +#define SN_kx_dhe_psk "KxDHE-PSK" +#define LN_kx_dhe_psk "kx-dhe-psk" +#define NID_kx_dhe_psk 1041 + +#define SN_kx_rsa_psk "KxRSA_PSK" +#define LN_kx_rsa_psk "kx-rsa-psk" +#define NID_kx_rsa_psk 1042 + +#define SN_kx_psk "KxPSK" +#define LN_kx_psk "kx-psk" +#define NID_kx_psk 1043 + +#define SN_kx_srp "KxSRP" +#define LN_kx_srp "kx-srp" +#define NID_kx_srp 1044 + +#define SN_kx_gost "KxGOST" +#define LN_kx_gost "kx-gost" +#define NID_kx_gost 1045 + +#define SN_auth_rsa "AuthRSA" +#define LN_auth_rsa "auth-rsa" +#define NID_auth_rsa 1046 + +#define SN_auth_ecdsa "AuthECDSA" +#define LN_auth_ecdsa "auth-ecdsa" +#define NID_auth_ecdsa 1047 + +#define SN_auth_psk "AuthPSK" +#define LN_auth_psk "auth-psk" +#define NID_auth_psk 1048 + +#define SN_auth_dss "AuthDSS" +#define LN_auth_dss "auth-dss" +#define NID_auth_dss 1049 + +#define SN_auth_gost01 "AuthGOST01" +#define LN_auth_gost01 "auth-gost01" +#define NID_auth_gost01 1050 + +#define SN_auth_gost12 "AuthGOST12" +#define LN_auth_gost12 "auth-gost12" +#define NID_auth_gost12 1051 + +#define SN_auth_srp "AuthSRP" +#define LN_auth_srp "auth-srp" +#define NID_auth_srp 1052 + +#define SN_auth_null "AuthNULL" +#define LN_auth_null "auth-null" +#define NID_auth_null 1053 diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index a1533b6dc0..be2ca2ab37 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1400,6 +1400,9 @@ __owur int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); __owur char *SSL_CIPHER_get_version(const SSL_CIPHER *c); __owur const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); __owur uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c); +__owur int SSL_CIPHER_is_aead(const SSL_CIPHER *c); __owur int SSL_get_fd(const SSL *s); __owur int SSL_get_rfd(const SSL *s); diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index acf5c00dad..5059e93748 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -240,6 +240,29 @@ static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { 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) @@ -2005,10 +2028,10 @@ int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *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; } @@ -2016,9 +2039,30 @@ int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c) { int i; if (c == NULL) - return -1; + return NID_undef; 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_kx, c->algorithm_auth); + if (i == -1) + return NID_undef; + return ssl_cipher_table_kx[i].nid; +} + +int SSL_CIPHER_is_aead(const SSL_CIPHER *c) +{ + return (c->algorithm_mac & SSL_AEAD) ? 1 : 0; +} diff --git a/util/libssl.num b/util/libssl.num index b73962a0e4..7ec5525aa6 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -384,3 +384,6 @@ SSL_CTX_get_ct_validation_callback 383 1_1_0 EXIST::FUNCTION:CT SSL_set_default_read_buffer_len 384 1_1_0 EXIST::FUNCTION: SSL_CTX_set_default_read_buffer_len 385 1_1_0 EXIST::FUNCTION: SSL_has_pending 386 1_1_0 EXIST::FUNCTION: +SSL_CIPHER_get_auth_nid 387 1_1_0 EXIST::FUNCTION: +SSL_CIPHER_get_kx_nid 388 1_1_0 EXIST::FUNCTION: +SSL_CIPHER_is_aead 389 1_1_0 EXIST::FUNCTION: -- 2.25.1