1 /* $OpenBSD: ssl_ciphers.c,v 1.4 2020/05/31 18:03:32 jsing Exp $ */ 2 /* 3 * Copyright (c) 2015-2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2015-2018 Joel Sing <jsing@openbsd.org> 5 * Copyright (c) 2019 Theo Buehler <tb@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <openssl/safestack.h> 21 22 #include "bytestring.h" 23 #include "ssl_locl.h" 24 25 int 26 ssl_cipher_is_permitted(const SSL_CIPHER *cipher, uint16_t min_ver, 27 uint16_t max_ver) 28 { 29 /* XXX: We only support DTLSv1 which is effectively TLSv1.1 */ 30 if (min_ver == DTLS1_VERSION || max_ver == DTLS1_VERSION) 31 min_ver = max_ver = TLS1_1_VERSION; 32 33 switch(cipher->algorithm_ssl) { 34 case SSL_SSLV3: 35 if (min_ver <= TLS1_2_VERSION) 36 return 1; 37 break; 38 case SSL_TLSV1_2: 39 if (min_ver <= TLS1_2_VERSION && TLS1_2_VERSION <= max_ver) 40 return 1; 41 break; 42 case SSL_TLSV1_3: 43 if (min_ver <= TLS1_3_VERSION && TLS1_3_VERSION <= max_ver) 44 return 1; 45 break; 46 } 47 48 return 0; 49 } 50 51 int 52 ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb) 53 { 54 SSL_CIPHER *cipher; 55 int num_ciphers = 0; 56 uint16_t min_vers, max_vers; 57 int i; 58 59 if (ciphers == NULL) 60 return 0; 61 62 if (!ssl_supported_version_range(s, &min_vers, &max_vers)) 63 return 0; 64 65 for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { 66 if ((cipher = sk_SSL_CIPHER_value(ciphers, i)) == NULL) 67 return 0; 68 69 if (!ssl_cipher_is_permitted(cipher, min_vers, max_vers)) 70 continue; 71 72 if (!CBB_add_u16(cbb, ssl3_cipher_get_value(cipher))) 73 return 0; 74 75 num_ciphers++; 76 } 77 78 /* Add SCSV if there are other ciphers and we're not renegotiating. */ 79 if (num_ciphers > 0 && !s->internal->renegotiate) { 80 if (!CBB_add_u16(cbb, SSL3_CK_SCSV & SSL3_CK_VALUE_MASK)) 81 return 0; 82 } 83 84 if (!CBB_flush(cbb)) 85 return 0; 86 87 return 1; 88 } 89 90 STACK_OF(SSL_CIPHER) * 91 ssl_bytes_to_cipher_list(SSL *s, CBS *cbs) 92 { 93 STACK_OF(SSL_CIPHER) *ciphers = NULL; 94 const SSL_CIPHER *cipher; 95 uint16_t cipher_value, max_version; 96 unsigned long cipher_id; 97 98 S3I(s)->send_connection_binding = 0; 99 100 if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) { 101 SSLerror(s, ERR_R_MALLOC_FAILURE); 102 goto err; 103 } 104 105 while (CBS_len(cbs) > 0) { 106 if (!CBS_get_u16(cbs, &cipher_value)) { 107 SSLerror(s, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); 108 goto err; 109 } 110 111 cipher_id = SSL3_CK_ID | cipher_value; 112 113 if (cipher_id == SSL3_CK_SCSV) { 114 /* 115 * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is fatal if 116 * renegotiating. 117 */ 118 if (s->internal->renegotiate) { 119 SSLerror(s, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); 120 ssl3_send_alert(s, SSL3_AL_FATAL, 121 SSL_AD_HANDSHAKE_FAILURE); 122 123 goto err; 124 } 125 S3I(s)->send_connection_binding = 1; 126 continue; 127 } 128 129 if (cipher_id == SSL3_CK_FALLBACK_SCSV) { 130 /* 131 * TLS_FALLBACK_SCSV indicates that the client 132 * previously tried a higher protocol version. 133 * Fail if the current version is an unexpected 134 * downgrade. 135 */ 136 if (!ssl_downgrade_max_version(s, &max_version)) 137 goto err; 138 if (s->version < max_version) { 139 SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK); 140 ssl3_send_alert(s, SSL3_AL_FATAL, 141 SSL_AD_INAPPROPRIATE_FALLBACK); 142 goto err; 143 } 144 continue; 145 } 146 147 if ((cipher = ssl3_get_cipher_by_value(cipher_value)) != NULL) { 148 if (!sk_SSL_CIPHER_push(ciphers, cipher)) { 149 SSLerror(s, ERR_R_MALLOC_FAILURE); 150 goto err; 151 } 152 } 153 } 154 155 return (ciphers); 156 157 err: 158 sk_SSL_CIPHER_free(ciphers); 159 160 return (NULL); 161 } 162