diff options
Diffstat (limited to 'src/lib/libssl/ssl_tlsext.c')
-rw-r--r-- | src/lib/libssl/ssl_tlsext.c | 143 |
1 files changed, 142 insertions, 1 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c index 18ac98103a..539c380fb9 100644 --- a/src/lib/libssl/ssl_tlsext.c +++ b/src/lib/libssl/ssl_tlsext.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_tlsext.c,v 1.1 2017/07/16 18:14:37 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_tlsext.c,v 1.2 2017/07/24 17:10:31 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -21,6 +21,138 @@ | |||
21 | #include "ssl_tlsext.h" | 21 | #include "ssl_tlsext.h" |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * Renegotiation Indication - RFC 5746. | ||
25 | */ | ||
26 | int | ||
27 | tlsext_ri_clienthello_needs(SSL *s) | ||
28 | { | ||
29 | return (s->internal->renegotiate); | ||
30 | } | ||
31 | |||
32 | int | ||
33 | tlsext_ri_clienthello_build(SSL *s, CBB *cbb) | ||
34 | { | ||
35 | CBB reneg; | ||
36 | |||
37 | if (!CBB_add_u8_length_prefixed(cbb, &reneg)) | ||
38 | return 0; | ||
39 | if (!CBB_add_bytes(&reneg, S3I(s)->previous_client_finished, | ||
40 | S3I(s)->previous_client_finished_len)) | ||
41 | return 0; | ||
42 | if (!CBB_flush(cbb)) | ||
43 | return 0; | ||
44 | |||
45 | return 1; | ||
46 | } | ||
47 | |||
48 | int | ||
49 | tlsext_ri_clienthello_parse(SSL *s, CBS *cbs, int *alert) | ||
50 | { | ||
51 | CBS reneg; | ||
52 | |||
53 | if (!CBS_get_u8_length_prefixed(cbs, &reneg)) | ||
54 | goto err; | ||
55 | if (CBS_len(cbs) != 0) | ||
56 | goto err; | ||
57 | |||
58 | if (!CBS_mem_equal(&reneg, S3I(s)->previous_client_finished, | ||
59 | S3I(s)->previous_client_finished_len)) { | ||
60 | SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); | ||
61 | *alert = SSL_AD_HANDSHAKE_FAILURE; | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | S3I(s)->renegotiate_seen = 1; | ||
66 | S3I(s)->send_connection_binding = 1; | ||
67 | |||
68 | return 1; | ||
69 | |||
70 | err: | ||
71 | SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); | ||
72 | *alert = SSL_AD_DECODE_ERROR; | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | int | ||
77 | tlsext_ri_serverhello_needs(SSL *s) | ||
78 | { | ||
79 | return (S3I(s)->send_connection_binding); | ||
80 | } | ||
81 | |||
82 | int | ||
83 | tlsext_ri_serverhello_build(SSL *s, CBB *cbb) | ||
84 | { | ||
85 | CBB reneg; | ||
86 | |||
87 | if (!CBB_add_u8_length_prefixed(cbb, &reneg)) | ||
88 | return 0; | ||
89 | if (!CBB_add_bytes(&reneg, S3I(s)->previous_client_finished, | ||
90 | S3I(s)->previous_client_finished_len)) | ||
91 | return 0; | ||
92 | if (!CBB_add_bytes(&reneg, S3I(s)->previous_server_finished, | ||
93 | S3I(s)->previous_server_finished_len)) | ||
94 | return 0; | ||
95 | if (!CBB_flush(cbb)) | ||
96 | return 0; | ||
97 | |||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | int | ||
102 | tlsext_ri_serverhello_parse(SSL *s, CBS *cbs, int *alert) | ||
103 | { | ||
104 | CBS reneg, prev_client, prev_server; | ||
105 | |||
106 | /* | ||
107 | * Ensure that the previous client and server values are both not | ||
108 | * present, or that they are both present. | ||
109 | */ | ||
110 | if ((S3I(s)->previous_client_finished_len == 0 && | ||
111 | S3I(s)->previous_server_finished_len != 0) || | ||
112 | (S3I(s)->previous_client_finished_len != 0 && | ||
113 | S3I(s)->previous_server_finished_len == 0)) { | ||
114 | *alert = TLS1_AD_INTERNAL_ERROR; | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | if (!CBS_get_u8_length_prefixed(cbs, &reneg)) | ||
119 | goto err; | ||
120 | if (!CBS_get_bytes(&reneg, &prev_client, | ||
121 | S3I(s)->previous_client_finished_len)) | ||
122 | goto err; | ||
123 | if (!CBS_get_bytes(&reneg, &prev_server, | ||
124 | S3I(s)->previous_server_finished_len)) | ||
125 | goto err; | ||
126 | if (CBS_len(&reneg) != 0) | ||
127 | goto err; | ||
128 | if (CBS_len(cbs) != 0) | ||
129 | goto err; | ||
130 | |||
131 | if (!CBS_mem_equal(&prev_client, S3I(s)->previous_client_finished, | ||
132 | S3I(s)->previous_client_finished_len)) { | ||
133 | SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); | ||
134 | *alert = SSL_AD_HANDSHAKE_FAILURE; | ||
135 | return 0; | ||
136 | } | ||
137 | if (!CBS_mem_equal(&prev_server, S3I(s)->previous_server_finished, | ||
138 | S3I(s)->previous_server_finished_len)) { | ||
139 | SSLerror(s, SSL_R_RENEGOTIATION_MISMATCH); | ||
140 | *alert = SSL_AD_HANDSHAKE_FAILURE; | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | S3I(s)->renegotiate_seen = 1; | ||
145 | S3I(s)->send_connection_binding = 1; | ||
146 | |||
147 | return 1; | ||
148 | |||
149 | err: | ||
150 | SSLerror(s, SSL_R_RENEGOTIATION_ENCODING_ERR); | ||
151 | *alert = SSL_AD_DECODE_ERROR; | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | /* | ||
24 | * Server Name Indication - RFC 6066, section 3. | 156 | * Server Name Indication - RFC 6066, section 3. |
25 | */ | 157 | */ |
26 | int | 158 | int |
@@ -150,6 +282,15 @@ static struct tls_extension tls_extensions[] = { | |||
150 | .serverhello_build = tlsext_sni_serverhello_build, | 282 | .serverhello_build = tlsext_sni_serverhello_build, |
151 | .serverhello_parse = tlsext_sni_serverhello_parse, | 283 | .serverhello_parse = tlsext_sni_serverhello_parse, |
152 | }, | 284 | }, |
285 | { | ||
286 | .type = TLSEXT_TYPE_renegotiate, | ||
287 | .clienthello_needs = tlsext_ri_clienthello_needs, | ||
288 | .clienthello_build = tlsext_ri_clienthello_build, | ||
289 | .clienthello_parse = tlsext_ri_clienthello_parse, | ||
290 | .serverhello_needs = tlsext_ri_serverhello_needs, | ||
291 | .serverhello_build = tlsext_ri_serverhello_build, | ||
292 | .serverhello_parse = tlsext_ri_serverhello_parse, | ||
293 | }, | ||
153 | }; | 294 | }; |
154 | 295 | ||
155 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) | 296 | #define N_TLS_EXTENSIONS (sizeof(tls_extensions) / sizeof(*tls_extensions)) |