diff options
Diffstat (limited to 'ssl/t1_lib.c')
-rw-r--r-- | ssl/t1_lib.c | 8432 |
1 files changed, 4086 insertions, 4346 deletions
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 7101473bc7..fe59e24a9a 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -5,21 +5,21 @@ * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. - * + * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * + * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -34,10 +34,10 @@ * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from + * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * + * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -49,7 +49,7 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence @@ -63,7 +63,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in @@ -116,274 +116,270 @@ #include <openssl/ocsp.h> #include <openssl/rand.h> #ifndef OPENSSL_NO_DH -#include <openssl/dh.h> -#include <openssl/bn.h> +# include <openssl/dh.h> +# include <openssl/bn.h> #endif #include "ssl_locl.h" -const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT; +const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT; #ifndef OPENSSL_NO_TLSEXT static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, - const unsigned char *sess_id, int sesslen, - SSL_SESSION **psess); + const unsigned char *sess_id, int sesslen, + SSL_SESSION **psess); static int ssl_check_clienthello_tlsext_early(SSL *s); int ssl_check_serverhello_tlsext(SSL *s); #endif -SSL3_ENC_METHOD const TLSv1_enc_data={ - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - 0, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write - }; - -SSL3_ENC_METHOD const TLSv1_1_enc_data={ - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_EXPLICIT_IV, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write - }; - -SSL3_ENC_METHOD const TLSv1_2_enc_data={ - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF - |SSL_ENC_FLAG_TLS1_2_CIPHERS, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write - }; +SSL3_ENC_METHOD const TLSv1_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + 0, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write +}; + +SSL3_ENC_METHOD const TLSv1_1_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_EXPLICIT_IV, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write +}; + +SSL3_ENC_METHOD const TLSv1_2_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF + | SSL_ENC_FLAG_TLS1_2_CIPHERS, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write +}; long tls1_default_timeout(void) - { - /* 2 hours, the 24 hours mentioned in the TLSv1 spec - * is way too long for http, the cache would over fill */ - return(60*60*2); - } +{ + /* + * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for + * http, the cache would over fill + */ + return (60 * 60 * 2); +} int tls1_new(SSL *s) - { - if (!ssl3_new(s)) return(0); - s->method->ssl_clear(s); - return(1); - } +{ + if (!ssl3_new(s)) + return (0); + s->method->ssl_clear(s); + return (1); +} void tls1_free(SSL *s) - { +{ #ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_session_ticket) - { - OPENSSL_free(s->tlsext_session_ticket); - } -#endif /* OPENSSL_NO_TLSEXT */ - ssl3_free(s); - } + if (s->tlsext_session_ticket) { + OPENSSL_free(s->tlsext_session_ticket); + } +#endif /* OPENSSL_NO_TLSEXT */ + ssl3_free(s); +} void tls1_clear(SSL *s) - { - ssl3_clear(s); - s->version = s->method->version; - } +{ + ssl3_clear(s); + s->version = s->method->version; +} #ifndef OPENSSL_NO_EC -typedef struct - { - int nid; /* Curve NID */ - int secbits; /* Bits of security (from SP800-57) */ - unsigned int flags; /* Flags: currently just field type */ - } tls_curve_info; - -#define TLS_CURVE_CHAR2 0x1 -#define TLS_CURVE_PRIME 0x0 - -static const tls_curve_info nid_list[] = - { - {NID_sect163k1, 80, TLS_CURVE_CHAR2},/* sect163k1 (1) */ - {NID_sect163r1, 80, TLS_CURVE_CHAR2},/* sect163r1 (2) */ - {NID_sect163r2, 80, TLS_CURVE_CHAR2},/* sect163r2 (3) */ - {NID_sect193r1, 80, TLS_CURVE_CHAR2},/* sect193r1 (4) */ - {NID_sect193r2, 80, TLS_CURVE_CHAR2},/* sect193r2 (5) */ - {NID_sect233k1, 112, TLS_CURVE_CHAR2},/* sect233k1 (6) */ - {NID_sect233r1, 112, TLS_CURVE_CHAR2},/* sect233r1 (7) */ - {NID_sect239k1, 112, TLS_CURVE_CHAR2},/* sect239k1 (8) */ - {NID_sect283k1, 128, TLS_CURVE_CHAR2},/* sect283k1 (9) */ - {NID_sect283r1, 128, TLS_CURVE_CHAR2},/* sect283r1 (10) */ - {NID_sect409k1, 192, TLS_CURVE_CHAR2},/* sect409k1 (11) */ - {NID_sect409r1, 192, TLS_CURVE_CHAR2},/* sect409r1 (12) */ - {NID_sect571k1, 256, TLS_CURVE_CHAR2},/* sect571k1 (13) */ - {NID_sect571r1, 256, TLS_CURVE_CHAR2},/* sect571r1 (14) */ - {NID_secp160k1, 80, TLS_CURVE_PRIME},/* secp160k1 (15) */ - {NID_secp160r1, 80, TLS_CURVE_PRIME},/* secp160r1 (16) */ - {NID_secp160r2, 80, TLS_CURVE_PRIME},/* secp160r2 (17) */ - {NID_secp192k1, 80, TLS_CURVE_PRIME},/* secp192k1 (18) */ - {NID_X9_62_prime192v1, 80, TLS_CURVE_PRIME},/* secp192r1 (19) */ - {NID_secp224k1, 112, TLS_CURVE_PRIME},/* secp224k1 (20) */ - {NID_secp224r1, 112, TLS_CURVE_PRIME},/* secp224r1 (21) */ - {NID_secp256k1, 128, TLS_CURVE_PRIME},/* secp256k1 (22) */ - {NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME},/* secp256r1 (23) */ - {NID_secp384r1, 192, TLS_CURVE_PRIME},/* secp384r1 (24) */ - {NID_secp521r1, 256, TLS_CURVE_PRIME},/* secp521r1 (25) */ - {NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */ - {NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */ - {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME},/* brainpool512r1 (28) */ - }; - - -static const unsigned char ecformats_default[] = - { - TLSEXT_ECPOINTFORMAT_uncompressed, - TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, - TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 - }; - -static const unsigned char eccurves_default[] = - { - 0,14, /* sect571r1 (14) */ - 0,13, /* sect571k1 (13) */ - 0,25, /* secp521r1 (25) */ - 0,28, /* brainpool512r1 (28) */ - 0,11, /* sect409k1 (11) */ - 0,12, /* sect409r1 (12) */ - 0,27, /* brainpoolP384r1 (27) */ - 0,24, /* secp384r1 (24) */ - 0,9, /* sect283k1 (9) */ - 0,10, /* sect283r1 (10) */ - 0,26, /* brainpoolP256r1 (26) */ - 0,22, /* secp256k1 (22) */ - 0,23, /* secp256r1 (23) */ - 0,8, /* sect239k1 (8) */ - 0,6, /* sect233k1 (6) */ - 0,7, /* sect233r1 (7) */ - 0,20, /* secp224k1 (20) */ - 0,21, /* secp224r1 (21) */ - 0,4, /* sect193r1 (4) */ - 0,5, /* sect193r2 (5) */ - 0,18, /* secp192k1 (18) */ - 0,19, /* secp192r1 (19) */ - 0,1, /* sect163k1 (1) */ - 0,2, /* sect163r1 (2) */ - 0,3, /* sect163r2 (3) */ - 0,15, /* secp160k1 (15) */ - 0,16, /* secp160r1 (16) */ - 0,17, /* secp160r2 (17) */ - }; - -static const unsigned char suiteb_curves[] = - { - 0, TLSEXT_curve_P_256, - 0, TLSEXT_curve_P_384 - }; +typedef struct { + int nid; /* Curve NID */ + int secbits; /* Bits of security (from SP800-57) */ + unsigned int flags; /* Flags: currently just field type */ +} tls_curve_info; + +# define TLS_CURVE_CHAR2 0x1 +# define TLS_CURVE_PRIME 0x0 + +static const tls_curve_info nid_list[] = { + {NID_sect163k1, 80, TLS_CURVE_CHAR2}, /* sect163k1 (1) */ + {NID_sect163r1, 80, TLS_CURVE_CHAR2}, /* sect163r1 (2) */ + {NID_sect163r2, 80, TLS_CURVE_CHAR2}, /* sect163r2 (3) */ + {NID_sect193r1, 80, TLS_CURVE_CHAR2}, /* sect193r1 (4) */ + {NID_sect193r2, 80, TLS_CURVE_CHAR2}, /* sect193r2 (5) */ + {NID_sect233k1, 112, TLS_CURVE_CHAR2}, /* sect233k1 (6) */ + {NID_sect233r1, 112, TLS_CURVE_CHAR2}, /* sect233r1 (7) */ + {NID_sect239k1, 112, TLS_CURVE_CHAR2}, /* sect239k1 (8) */ + {NID_sect283k1, 128, TLS_CURVE_CHAR2}, /* sect283k1 (9) */ + {NID_sect283r1, 128, TLS_CURVE_CHAR2}, /* sect283r1 (10) */ + {NID_sect409k1, 192, TLS_CURVE_CHAR2}, /* sect409k1 (11) */ + {NID_sect409r1, 192, TLS_CURVE_CHAR2}, /* sect409r1 (12) */ + {NID_sect571k1, 256, TLS_CURVE_CHAR2}, /* sect571k1 (13) */ + {NID_sect571r1, 256, TLS_CURVE_CHAR2}, /* sect571r1 (14) */ + {NID_secp160k1, 80, TLS_CURVE_PRIME}, /* secp160k1 (15) */ + {NID_secp160r1, 80, TLS_CURVE_PRIME}, /* secp160r1 (16) */ + {NID_secp160r2, 80, TLS_CURVE_PRIME}, /* secp160r2 (17) */ + {NID_secp192k1, 80, TLS_CURVE_PRIME}, /* secp192k1 (18) */ + {NID_X9_62_prime192v1, 80, TLS_CURVE_PRIME}, /* secp192r1 (19) */ + {NID_secp224k1, 112, TLS_CURVE_PRIME}, /* secp224k1 (20) */ + {NID_secp224r1, 112, TLS_CURVE_PRIME}, /* secp224r1 (21) */ + {NID_secp256k1, 128, TLS_CURVE_PRIME}, /* secp256k1 (22) */ + {NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME}, /* secp256r1 (23) */ + {NID_secp384r1, 192, TLS_CURVE_PRIME}, /* secp384r1 (24) */ + {NID_secp521r1, 256, TLS_CURVE_PRIME}, /* secp521r1 (25) */ + {NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */ + {NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */ + {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ +}; + +static const unsigned char ecformats_default[] = { + TLSEXT_ECPOINTFORMAT_uncompressed, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 +}; + +static const unsigned char eccurves_default[] = { + 0, 14, /* sect571r1 (14) */ + 0, 13, /* sect571k1 (13) */ + 0, 25, /* secp521r1 (25) */ + 0, 28, /* brainpool512r1 (28) */ + 0, 11, /* sect409k1 (11) */ + 0, 12, /* sect409r1 (12) */ + 0, 27, /* brainpoolP384r1 (27) */ + 0, 24, /* secp384r1 (24) */ + 0, 9, /* sect283k1 (9) */ + 0, 10, /* sect283r1 (10) */ + 0, 26, /* brainpoolP256r1 (26) */ + 0, 22, /* secp256k1 (22) */ + 0, 23, /* secp256r1 (23) */ + 0, 8, /* sect239k1 (8) */ + 0, 6, /* sect233k1 (6) */ + 0, 7, /* sect233r1 (7) */ + 0, 20, /* secp224k1 (20) */ + 0, 21, /* secp224r1 (21) */ + 0, 4, /* sect193r1 (4) */ + 0, 5, /* sect193r2 (5) */ + 0, 18, /* secp192k1 (18) */ + 0, 19, /* secp192r1 (19) */ + 0, 1, /* sect163k1 (1) */ + 0, 2, /* sect163r1 (2) */ + 0, 3, /* sect163r2 (3) */ + 0, 15, /* secp160k1 (15) */ + 0, 16, /* secp160r1 (16) */ + 0, 17, /* secp160r2 (17) */ +}; + +static const unsigned char suiteb_curves[] = { + 0, TLSEXT_curve_P_256, + 0, TLSEXT_curve_P_384 +}; int tls1_ec_curve_id2nid(int curve_id) - { - /* ECC curves from RFC 4492 and RFC 7027 */ - if ((curve_id < 1) || ((unsigned int)curve_id > - sizeof(nid_list)/sizeof(nid_list[0]))) - return 0; - return nid_list[curve_id-1].nid; - } +{ + /* ECC curves from RFC 4492 and RFC 7027 */ + if ((curve_id < 1) || ((unsigned int)curve_id > + sizeof(nid_list) / sizeof(nid_list[0]))) + return 0; + return nid_list[curve_id - 1].nid; +} int tls1_ec_nid2curve_id(int nid) - { - /* ECC curves from RFC 4492 and RFC 7027 */ - switch (nid) - { - case NID_sect163k1: /* sect163k1 (1) */ - return 1; - case NID_sect163r1: /* sect163r1 (2) */ - return 2; - case NID_sect163r2: /* sect163r2 (3) */ - return 3; - case NID_sect193r1: /* sect193r1 (4) */ - return 4; - case NID_sect193r2: /* sect193r2 (5) */ - return 5; - case NID_sect233k1: /* sect233k1 (6) */ - return 6; - case NID_sect233r1: /* sect233r1 (7) */ - return 7; - case NID_sect239k1: /* sect239k1 (8) */ - return 8; - case NID_sect283k1: /* sect283k1 (9) */ - return 9; - case NID_sect283r1: /* sect283r1 (10) */ - return 10; - case NID_sect409k1: /* sect409k1 (11) */ - return 11; - case NID_sect409r1: /* sect409r1 (12) */ - return 12; - case NID_sect571k1: /* sect571k1 (13) */ - return 13; - case NID_sect571r1: /* sect571r1 (14) */ - return 14; - case NID_secp160k1: /* secp160k1 (15) */ - return 15; - case NID_secp160r1: /* secp160r1 (16) */ - return 16; - case NID_secp160r2: /* secp160r2 (17) */ - return 17; - case NID_secp192k1: /* secp192k1 (18) */ - return 18; - case NID_X9_62_prime192v1: /* secp192r1 (19) */ - return 19; - case NID_secp224k1: /* secp224k1 (20) */ - return 20; - case NID_secp224r1: /* secp224r1 (21) */ - return 21; - case NID_secp256k1: /* secp256k1 (22) */ - return 22; - case NID_X9_62_prime256v1: /* secp256r1 (23) */ - return 23; - case NID_secp384r1: /* secp384r1 (24) */ - return 24; - case NID_secp521r1: /* secp521r1 (25) */ - return 25; - case NID_brainpoolP256r1: /* brainpoolP256r1 (26) */ - return 26; - case NID_brainpoolP384r1: /* brainpoolP384r1 (27) */ - return 27; - case NID_brainpoolP512r1: /* brainpool512r1 (28) */ - return 28; - default: - return 0; - } - } +{ + /* ECC curves from RFC 4492 and RFC 7027 */ + switch (nid) { + case NID_sect163k1: /* sect163k1 (1) */ + return 1; + case NID_sect163r1: /* sect163r1 (2) */ + return 2; + case NID_sect163r2: /* sect163r2 (3) */ + return 3; + case NID_sect193r1: /* sect193r1 (4) */ + return 4; + case NID_sect193r2: /* sect193r2 (5) */ + return 5; + case NID_sect233k1: /* sect233k1 (6) */ + return 6; + case NID_sect233r1: /* sect233r1 (7) */ + return 7; + case NID_sect239k1: /* sect239k1 (8) */ + return 8; + case NID_sect283k1: /* sect283k1 (9) */ + return 9; + case NID_sect283r1: /* sect283r1 (10) */ + return 10; + case NID_sect409k1: /* sect409k1 (11) */ + return 11; + case NID_sect409r1: /* sect409r1 (12) */ + return 12; + case NID_sect571k1: /* sect571k1 (13) */ + return 13; + case NID_sect571r1: /* sect571r1 (14) */ + return 14; + case NID_secp160k1: /* secp160k1 (15) */ + return 15; + case NID_secp160r1: /* secp160r1 (16) */ + return 16; + case NID_secp160r2: /* secp160r2 (17) */ + return 17; + case NID_secp192k1: /* secp192k1 (18) */ + return 18; + case NID_X9_62_prime192v1: /* secp192r1 (19) */ + return 19; + case NID_secp224k1: /* secp224k1 (20) */ + return 20; + case NID_secp224r1: /* secp224r1 (21) */ + return 21; + case NID_secp256k1: /* secp256k1 (22) */ + return 22; + case NID_X9_62_prime256v1: /* secp256r1 (23) */ + return 23; + case NID_secp384r1: /* secp384r1 (24) */ + return 24; + case NID_secp521r1: /* secp521r1 (25) */ + return 25; + case NID_brainpoolP256r1: /* brainpoolP256r1 (26) */ + return 26; + case NID_brainpoolP384r1: /* brainpoolP384r1 (27) */ + return 27; + case NID_brainpoolP512r1: /* brainpool512r1 (28) */ + return 28; + default: + return 0; + } +} + /* * Get curves list, if "sess" is set return client curves otherwise * preferred list. @@ -397,112 +393,98 @@ int tls1_ec_nid2curve_id(int nid) * so cannot happen in the 1.0.x series.) */ static int tls1_get_curvelist(SSL *s, int sess, - const unsigned char **pcurves, - size_t *num_curves) - { - size_t pcurveslen = 0; - if (sess) - { - *pcurves = s->session->tlsext_ellipticcurvelist; - pcurveslen = s->session->tlsext_ellipticcurvelist_length; - } - else - { - /* For Suite B mode only include P-256, P-384 */ - switch (tls1_suiteb(s)) - { - case SSL_CERT_FLAG_SUITEB_128_LOS: - *pcurves = suiteb_curves; - pcurveslen = sizeof(suiteb_curves); - break; - - case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: - *pcurves = suiteb_curves; - pcurveslen = 2; - break; - - case SSL_CERT_FLAG_SUITEB_192_LOS: - *pcurves = suiteb_curves + 2; - pcurveslen = 2; - break; - default: - *pcurves = s->tlsext_ellipticcurvelist; - pcurveslen = s->tlsext_ellipticcurvelist_length; - } - if (!*pcurves) - { - *pcurves = eccurves_default; - pcurveslen = sizeof(eccurves_default); - } - } - - /* We do not allow odd length arrays to enter the system. */ - if (pcurveslen & 1) - { - SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR); - *num_curves = 0; - return 0; - } - else - { - *num_curves = pcurveslen / 2; - return 1; - } - } + const unsigned char **pcurves, + size_t *num_curves) +{ + size_t pcurveslen = 0; + if (sess) { + *pcurves = s->session->tlsext_ellipticcurvelist; + pcurveslen = s->session->tlsext_ellipticcurvelist_length; + } else { + /* For Suite B mode only include P-256, P-384 */ + switch (tls1_suiteb(s)) { + case SSL_CERT_FLAG_SUITEB_128_LOS: + *pcurves = suiteb_curves; + pcurveslen = sizeof(suiteb_curves); + break; + + case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: + *pcurves = suiteb_curves; + pcurveslen = 2; + break; + + case SSL_CERT_FLAG_SUITEB_192_LOS: + *pcurves = suiteb_curves + 2; + pcurveslen = 2; + break; + default: + *pcurves = s->tlsext_ellipticcurvelist; + pcurveslen = s->tlsext_ellipticcurvelist_length; + } + if (!*pcurves) { + *pcurves = eccurves_default; + pcurveslen = sizeof(eccurves_default); + } + } + + /* We do not allow odd length arrays to enter the system. */ + if (pcurveslen & 1) { + SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR); + *num_curves = 0; + return 0; + } else { + *num_curves = pcurveslen / 2; + return 1; + } +} /* See if curve is allowed by security callback */ static int tls_curve_allowed(SSL *s, const unsigned char *curve, int op) - { - const tls_curve_info *cinfo; - if (curve[0]) - return 1; - if ((curve[1] < 1) || ((size_t)curve[1] > - sizeof(nid_list)/sizeof(nid_list[0]))) - return 0; - cinfo = &nid_list[curve[1]-1]; -#ifdef OPENSSL_NO_EC2M - if (cinfo->flags & TLS_CURVE_CHAR2) - return 0; -#endif - return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve); - } +{ + const tls_curve_info *cinfo; + if (curve[0]) + return 1; + if ((curve[1] < 1) || ((size_t)curve[1] > + sizeof(nid_list) / sizeof(nid_list[0]))) + return 0; + cinfo = &nid_list[curve[1] - 1]; +# ifdef OPENSSL_NO_EC2M + if (cinfo->flags & TLS_CURVE_CHAR2) + return 0; +# endif + return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve); +} /* Check a curve is one of our preferences */ int tls1_check_curve(SSL *s, const unsigned char *p, size_t len) - { - const unsigned char *curves; - size_t num_curves, i; - unsigned int suiteb_flags = tls1_suiteb(s); - if (len != 3 || p[0] != NAMED_CURVE_TYPE) - return 0; - /* Check curve matches Suite B preferences */ - if (suiteb_flags) - { - unsigned long cid = s->s3->tmp.new_cipher->id; - if (p[1]) - return 0; - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - { - if (p[2] != TLSEXT_curve_P_256) - return 0; - } - else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - { - if (p[2] != TLSEXT_curve_P_384) - return 0; - } - else /* Should never happen */ - return 0; - } - if (!tls1_get_curvelist(s, 0, &curves, &num_curves)) - return 0; - for (i = 0; i < num_curves; i++, curves += 2) - { - if (p[1] == curves[0] && p[2] == curves[1]) - return tls_curve_allowed(s, p + 1, SSL_SECOP_CURVE_CHECK); - } - return 0; - } +{ + const unsigned char *curves; + size_t num_curves, i; + unsigned int suiteb_flags = tls1_suiteb(s); + if (len != 3 || p[0] != NAMED_CURVE_TYPE) + return 0; + /* Check curve matches Suite B preferences */ + if (suiteb_flags) { + unsigned long cid = s->s3->tmp.new_cipher->id; + if (p[1]) + return 0; + if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { + if (p[2] != TLSEXT_curve_P_256) + return 0; + } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) { + if (p[2] != TLSEXT_curve_P_384) + return 0; + } else /* Should never happen */ + return 0; + } + if (!tls1_get_curvelist(s, 0, &curves, &num_curves)) + return 0; + for (i = 0; i < num_curves; i++, curves += 2) { + if (p[1] == curves[0] && p[2] == curves[1]) + return tls_curve_allowed(s, p + 1, SSL_SECOP_CURVE_CHECK); + } + return 0; +} /*- * Return |nmatch|th shared curve or NID_undef if there is no match. @@ -511,1370 +493,1324 @@ int tls1_check_curve(SSL *s, const unsigned char *p, size_t len) * an EC tmp key, or NID_undef if there is no match. */ int tls1_shared_curve(SSL *s, int nmatch) - { - const unsigned char *pref, *supp; - size_t num_pref, num_supp, i, j; - int k; - /* Can't do anything on client side */ - if (s->server == 0) - return -1; - if (nmatch == -2) - { - if (tls1_suiteb(s)) - { - /* For Suite B ciphersuite determines curve: we - * already know these are acceptable due to previous - * checks. - */ - unsigned long cid = s->s3->tmp.new_cipher->id; - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - return NID_X9_62_prime256v1; /* P-256 */ - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - return NID_secp384r1; /* P-384 */ - /* Should never happen */ - return NID_undef; - } - /* If not Suite B just return first preference shared curve */ - nmatch = 0; - } - /* - * Avoid truncation. tls1_get_curvelist takes an int - * but s->options is a long... - */ - if (!tls1_get_curvelist(s, (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, - &supp, &num_supp)) - /* In practice, NID_undef == 0 but let's be precise. */ - return nmatch == -1 ? 0 : NID_undef; - if(!tls1_get_curvelist(s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), - &pref, &num_pref)) - return nmatch == -1 ? 0 : NID_undef; - k = 0; - for (i = 0; i < num_pref; i++, pref+=2) - { - const unsigned char *tsupp = supp; - for (j = 0; j < num_supp; j++, tsupp+=2) - { - if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) - { - if (!tls_curve_allowed(s, pref, SSL_SECOP_CURVE_SHARED)) - continue; - if (nmatch == k) - { - int id = (pref[0] << 8) | pref[1]; - return tls1_ec_curve_id2nid(id); - } - k++; - } - } - } - if (nmatch == -1) - return k; - /* Out of range (nmatch > k). */ - return NID_undef; - } +{ + const unsigned char *pref, *supp; + size_t num_pref, num_supp, i, j; + int k; + /* Can't do anything on client side */ + if (s->server == 0) + return -1; + if (nmatch == -2) { + if (tls1_suiteb(s)) { + /* + * For Suite B ciphersuite determines curve: we already know + * these are acceptable due to previous checks. + */ + unsigned long cid = s->s3->tmp.new_cipher->id; + if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) + return NID_X9_62_prime256v1; /* P-256 */ + if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) + return NID_secp384r1; /* P-384 */ + /* Should never happen */ + return NID_undef; + } + /* If not Suite B just return first preference shared curve */ + nmatch = 0; + } + /* + * Avoid truncation. tls1_get_curvelist takes an int + * but s->options is a long... + */ + if (!tls1_get_curvelist + (s, (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, &supp, + &num_supp)) + /* In practice, NID_undef == 0 but let's be precise. */ + return nmatch == -1 ? 0 : NID_undef; + if (!tls1_get_curvelist + (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref, + &num_pref)) + return nmatch == -1 ? 0 : NID_undef; + k = 0; + for (i = 0; i < num_pref; i++, pref += 2) { + const unsigned char *tsupp = supp; + for (j = 0; j < num_supp; j++, tsupp += 2) { + if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) { + if (!tls_curve_allowed(s, pref, SSL_SECOP_CURVE_SHARED)) + continue; + if (nmatch == k) { + int id = (pref[0] << 8) | pref[1]; + return tls1_ec_curve_id2nid(id); + } + k++; + } + } + } + if (nmatch == -1) + return k; + /* Out of range (nmatch > k). */ + return NID_undef; +} int tls1_set_curves(unsigned char **pext, size_t *pextlen, - int *curves, size_t ncurves) - { - unsigned char *clist, *p; - size_t i; - /* Bitmap of curves included to detect duplicates: only works - * while curve ids < 32 - */ - unsigned long dup_list = 0; - clist = OPENSSL_malloc(ncurves * 2); - if (!clist) - return 0; - for (i = 0, p = clist; i < ncurves; i++) - { - unsigned long idmask; - int id; - id = tls1_ec_nid2curve_id(curves[i]); - idmask = 1L << id; - if (!id || (dup_list & idmask)) - { - OPENSSL_free(clist); - return 0; - } - dup_list |= idmask; - s2n(id, p); - } - if (*pext) - OPENSSL_free(*pext); - *pext = clist; - *pextlen = ncurves * 2; - return 1; - } - -#define MAX_CURVELIST 28 - -typedef struct - { - size_t nidcnt; - int nid_arr[MAX_CURVELIST]; - } nid_cb_st; + int *curves, size_t ncurves) +{ + unsigned char *clist, *p; + size_t i; + /* + * Bitmap of curves included to detect duplicates: only works while curve + * ids < 32 + */ + unsigned long dup_list = 0; + clist = OPENSSL_malloc(ncurves * 2); + if (!clist) + return 0; + for (i = 0, p = clist; i < ncurves; i++) { + unsigned long idmask; + int id; + id = tls1_ec_nid2curve_id(curves[i]); + idmask = 1L << id; + if (!id || (dup_list & idmask)) { + OPENSSL_free(clist); + return 0; + } + dup_list |= idmask; + s2n(id, p); + } + if (*pext) + OPENSSL_free(*pext); + *pext = clist; + *pextlen = ncurves * 2; + return 1; +} + +# define MAX_CURVELIST 28 + +typedef struct { + size_t nidcnt; + int nid_arr[MAX_CURVELIST]; +} nid_cb_st; static int nid_cb(const char *elem, int len, void *arg) - { - nid_cb_st *narg = arg; - size_t i; - int nid; - char etmp[20]; - if (narg->nidcnt == MAX_CURVELIST) - return 0; - if (len > (int)(sizeof(etmp) - 1)) - return 0; - memcpy(etmp, elem, len); - etmp[len] = 0; - nid = EC_curve_nist2nid(etmp); - if (nid == NID_undef) - nid = OBJ_sn2nid(etmp); - if (nid == NID_undef) - nid = OBJ_ln2nid(etmp); - if (nid == NID_undef) - return 0; - for (i = 0; i < narg->nidcnt; i++) - if (narg->nid_arr[i] == nid) - return 0; - narg->nid_arr[narg->nidcnt++] = nid; - return 1; - } +{ + nid_cb_st *narg = arg; + size_t i; + int nid; + char etmp[20]; + if (narg->nidcnt == MAX_CURVELIST) + return 0; + if (len > (int)(sizeof(etmp) - 1)) + return 0; + memcpy(etmp, elem, len); + etmp[len] = 0; + nid = EC_curve_nist2nid(etmp); + if (nid == NID_undef) + nid = OBJ_sn2nid(etmp); + if (nid == NID_undef) + nid = OBJ_ln2nid(etmp); + if (nid == NID_undef) + return 0; + for (i = 0; i < narg->nidcnt; i++) + if (narg->nid_arr[i] == nid) + return 0; + narg->nid_arr[narg->nidcnt++] = nid; + return 1; +} + /* Set curves based on a colon separate list */ -int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, - const char *str) - { - nid_cb_st ncb; - ncb.nidcnt = 0; - if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) - return 0; - if (pext == NULL) - return 1; - return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt); - } +int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, + const char *str) +{ + nid_cb_st ncb; + ncb.nidcnt = 0; + if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) + return 0; + if (pext == NULL) + return 1; + return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt); +} + /* For an EC key set TLS id and required compression based on parameters */ static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, - EC_KEY *ec) - { - int is_prime, id; - const EC_GROUP *grp; - const EC_METHOD *meth; - if (!ec) - return 0; - /* Determine if it is a prime field */ - grp = EC_KEY_get0_group(ec); - if (!grp) - return 0; - meth = EC_GROUP_method_of(grp); - if (!meth) - return 0; - if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) - is_prime = 1; - else - is_prime = 0; - /* Determine curve ID */ - id = EC_GROUP_get_curve_name(grp); - id = tls1_ec_nid2curve_id(id); - /* If we have an ID set it, otherwise set arbitrary explicit curve */ - if (id) - { - curve_id[0] = 0; - curve_id[1] = (unsigned char)id; - } - else - { - curve_id[0] = 0xff; - if (is_prime) - curve_id[1] = 0x01; - else - curve_id[1] = 0x02; |