summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_ciphers.c
diff options
context:
space:
mode:
authortb <>2019-01-21 14:12:13 +0000
committertb <>2019-01-21 14:12:13 +0000
commitd3d1c2c608615609302386dd2757729ee83092be (patch)
treed91d57f8604ae0900294a1f1c728b95211726bcd /src/lib/libssl/ssl_ciphers.c
parentc06f6f3e478fe1e9e0a1f1601f983e3d55479ed3 (diff)
downloadopenbsd-d3d1c2c608615609302386dd2757729ee83092be.tar.gz
openbsd-d3d1c2c608615609302386dd2757729ee83092be.tar.bz2
openbsd-d3d1c2c608615609302386dd2757729ee83092be.zip
Move ssl_cipher_list_to_bytes() and ssl_bytes_to_cipher_list() to
a more appropriately licenced file. jsing and doug have rewritten these functions (including the comments) over the past years. ok jsing
Diffstat (limited to 'src/lib/libssl/ssl_ciphers.c')
-rw-r--r--src/lib/libssl/ssl_ciphers.c120
1 files changed, 119 insertions, 1 deletions
diff --git a/src/lib/libssl/ssl_ciphers.c b/src/lib/libssl/ssl_ciphers.c
index 081a35ddb2..374cb6684e 100644
--- a/src/lib/libssl/ssl_ciphers.c
+++ b/src/lib/libssl/ssl_ciphers.c
@@ -1,5 +1,7 @@
1/* $OpenBSD: ssl_ciphers.c,v 1.1 2019/01/21 10:28:52 tb Exp $ */ 1/* $OpenBSD: ssl_ciphers.c,v 1.2 2019/01/21 14:12:13 tb Exp $ */
2/* 2/*
3 * Copyright (c) 2015-2017 Doug Hogan <doug@openbsd.org>
4 * Copyright (c) 2015-2018 Joel Sing <jsing@openbsd.org>
3 * Copyright (c) 2019 Theo Buehler <tb@openbsd.org> 5 * Copyright (c) 2019 Theo Buehler <tb@openbsd.org>
4 * 6 *
5 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
@@ -15,6 +17,9 @@
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 18 */
17 19
20#include <openssl/safestack.h>
21
22#include "bytestring.h"
18#include "ssl_locl.h" 23#include "ssl_locl.h"
19 24
20int 25int
@@ -42,3 +47,116 @@ ssl_cipher_is_permitted(const SSL_CIPHER *cipher, uint16_t min_ver,
42 47
43 return 0; 48 return 0;
44} 49}
50
51int
52ssl_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
90STACK_OF(SSL_CIPHER) *
91ssl_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 if (s->s3 != NULL)
99 S3I(s)->send_connection_binding = 0;
100
101 if ((ciphers = sk_SSL_CIPHER_new_null()) == NULL) {
102 SSLerror(s, ERR_R_MALLOC_FAILURE);
103 goto err;
104 }
105
106 while (CBS_len(cbs) > 0) {
107 if (!CBS_get_u16(cbs, &cipher_value)) {
108 SSLerror(s, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
109 goto err;
110 }
111
112 cipher_id = SSL3_CK_ID | cipher_value;
113
114 if (s->s3 != NULL && cipher_id == SSL3_CK_SCSV) {
115 /*
116 * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is fatal if
117 * renegotiating.
118 */
119 if (s->internal->renegotiate) {
120 SSLerror(s, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
121 ssl3_send_alert(s, SSL3_AL_FATAL,
122 SSL_AD_HANDSHAKE_FAILURE);
123
124 goto err;
125 }
126 S3I(s)->send_connection_binding = 1;
127 continue;
128 }
129
130 if (cipher_id == SSL3_CK_FALLBACK_SCSV) {
131 /*
132 * TLS_FALLBACK_SCSV indicates that the client
133 * previously tried a higher protocol version.
134 * Fail if the current version is an unexpected
135 * downgrade.
136 */
137 max_version = ssl_max_server_version(s);
138 if (max_version == 0 || s->version < max_version) {
139 SSLerror(s, SSL_R_INAPPROPRIATE_FALLBACK);
140 if (s->s3 != NULL)
141 ssl3_send_alert(s, SSL3_AL_FATAL,
142 SSL_AD_INAPPROPRIATE_FALLBACK);
143 goto err;
144 }
145 continue;
146 }
147
148 if ((cipher = ssl3_get_cipher_by_value(cipher_value)) != NULL) {
149 if (!sk_SSL_CIPHER_push(ciphers, cipher)) {
150 SSLerror(s, ERR_R_MALLOC_FAILURE);
151 goto err;
152 }
153 }
154 }
155
156 return (ciphers);
157
158 err:
159 sk_SSL_CIPHER_free(ciphers);
160
161 return (NULL);
162}