diff options
Diffstat (limited to 'src/usr.bin/openssl/s_cb.c')
-rw-r--r-- | src/usr.bin/openssl/s_cb.c | 854 |
1 files changed, 854 insertions, 0 deletions
diff --git a/src/usr.bin/openssl/s_cb.c b/src/usr.bin/openssl/s_cb.c new file mode 100644 index 0000000000..2e00abe7f1 --- /dev/null +++ b/src/usr.bin/openssl/s_cb.c | |||
@@ -0,0 +1,854 @@ | |||
1 | /* $OpenBSD: s_cb.c,v 1.1 2014/08/26 17:47:25 jsing Exp $ */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | /* ==================================================================== | ||
59 | * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. | ||
60 | * | ||
61 | * Redistribution and use in source and binary forms, with or without | ||
62 | * modification, are permitted provided that the following conditions | ||
63 | * are met: | ||
64 | * | ||
65 | * 1. Redistributions of source code must retain the above copyright | ||
66 | * notice, this list of conditions and the following disclaimer. | ||
67 | * | ||
68 | * 2. Redistributions in binary form must reproduce the above copyright | ||
69 | * notice, this list of conditions and the following disclaimer in | ||
70 | * the documentation and/or other materials provided with the | ||
71 | * distribution. | ||
72 | * | ||
73 | * 3. All advertising materials mentioning features or use of this | ||
74 | * software must display the following acknowledgment: | ||
75 | * "This product includes software developed by the OpenSSL Project | ||
76 | * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" | ||
77 | * | ||
78 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
79 | * endorse or promote products derived from this software without | ||
80 | * prior written permission. For written permission, please contact | ||
81 | * openssl-core@openssl.org. | ||
82 | * | ||
83 | * 5. Products derived from this software may not be called "OpenSSL" | ||
84 | * nor may "OpenSSL" appear in their names without prior written | ||
85 | * permission of the OpenSSL Project. | ||
86 | * | ||
87 | * 6. Redistributions of any form whatsoever must retain the following | ||
88 | * acknowledgment: | ||
89 | * "This product includes software developed by the OpenSSL Project | ||
90 | * for use in the OpenSSL Toolkit (http://www.openssl.org/)" | ||
91 | * | ||
92 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
93 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
94 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
95 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
96 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
97 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
98 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
99 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
100 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
101 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
102 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
103 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
104 | * ==================================================================== | ||
105 | * | ||
106 | * This product includes cryptographic software written by Eric Young | ||
107 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
108 | * Hudson (tjh@cryptsoft.com). | ||
109 | * | ||
110 | */ | ||
111 | |||
112 | #include <sys/socket.h> | ||
113 | |||
114 | #include <netinet/in.h> | ||
115 | |||
116 | #include <netdb.h> | ||
117 | #include <stdio.h> | ||
118 | #include <stdlib.h> | ||
119 | #include <string.h> | ||
120 | |||
121 | #include "apps.h" | ||
122 | |||
123 | #include <openssl/err.h> | ||
124 | #include <openssl/rand.h> | ||
125 | #include <openssl/ssl.h> | ||
126 | #include <openssl/x509.h> | ||
127 | |||
128 | #include "s_apps.h" | ||
129 | |||
130 | #define COOKIE_SECRET_LENGTH 16 | ||
131 | |||
132 | int verify_depth = 0; | ||
133 | int verify_error = X509_V_OK; | ||
134 | int verify_return_error = 0; | ||
135 | unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; | ||
136 | int cookie_initialized = 0; | ||
137 | |||
138 | int | ||
139 | verify_callback(int ok, X509_STORE_CTX * ctx) | ||
140 | { | ||
141 | X509 *err_cert; | ||
142 | int err, depth; | ||
143 | |||
144 | err_cert = X509_STORE_CTX_get_current_cert(ctx); | ||
145 | err = X509_STORE_CTX_get_error(ctx); | ||
146 | depth = X509_STORE_CTX_get_error_depth(ctx); | ||
147 | |||
148 | BIO_printf(bio_err, "depth=%d ", depth); | ||
149 | if (err_cert) { | ||
150 | X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), | ||
151 | 0, XN_FLAG_ONELINE); | ||
152 | BIO_puts(bio_err, "\n"); | ||
153 | } else | ||
154 | BIO_puts(bio_err, "<no cert>\n"); | ||
155 | if (!ok) { | ||
156 | BIO_printf(bio_err, "verify error:num=%d:%s\n", err, | ||
157 | X509_verify_cert_error_string(err)); | ||
158 | if (verify_depth >= depth) { | ||
159 | if (!verify_return_error) | ||
160 | ok = 1; | ||
161 | verify_error = X509_V_OK; | ||
162 | } else { | ||
163 | ok = 0; | ||
164 | verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG; | ||
165 | } | ||
166 | } | ||
167 | switch (err) { | ||
168 | case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: | ||
169 | BIO_puts(bio_err, "issuer= "); | ||
170 | X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), | ||
171 | 0, XN_FLAG_ONELINE); | ||
172 | BIO_puts(bio_err, "\n"); | ||
173 | break; | ||
174 | case X509_V_ERR_CERT_NOT_YET_VALID: | ||
175 | case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: | ||
176 | BIO_printf(bio_err, "notBefore="); | ||
177 | ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert)); | ||
178 | BIO_printf(bio_err, "\n"); | ||
179 | break; | ||
180 | case X509_V_ERR_CERT_HAS_EXPIRED: | ||
181 | case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: | ||
182 | BIO_printf(bio_err, "notAfter="); | ||
183 | ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert)); | ||
184 | BIO_printf(bio_err, "\n"); | ||
185 | break; | ||
186 | case X509_V_ERR_NO_EXPLICIT_POLICY: | ||
187 | policies_print(bio_err, ctx); | ||
188 | break; | ||
189 | } | ||
190 | if (err == X509_V_OK && ok == 2) | ||
191 | policies_print(bio_err, ctx); | ||
192 | |||
193 | BIO_printf(bio_err, "verify return:%d\n", ok); | ||
194 | return (ok); | ||
195 | } | ||
196 | |||
197 | int | ||
198 | set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file) | ||
199 | { | ||
200 | if (cert_file != NULL) { | ||
201 | /* | ||
202 | SSL *ssl; | ||
203 | X509 *x509; | ||
204 | */ | ||
205 | |||
206 | if (SSL_CTX_use_certificate_file(ctx, cert_file, | ||
207 | SSL_FILETYPE_PEM) <= 0) { | ||
208 | BIO_printf(bio_err, | ||
209 | "unable to get certificate from '%s'\n", cert_file); | ||
210 | ERR_print_errors(bio_err); | ||
211 | return (0); | ||
212 | } | ||
213 | if (key_file == NULL) | ||
214 | key_file = cert_file; | ||
215 | if (SSL_CTX_use_PrivateKey_file(ctx, key_file, | ||
216 | SSL_FILETYPE_PEM) <= 0) { | ||
217 | BIO_printf(bio_err, | ||
218 | "unable to get private key from '%s'\n", key_file); | ||
219 | ERR_print_errors(bio_err); | ||
220 | return (0); | ||
221 | } | ||
222 | /* | ||
223 | In theory this is no longer needed | ||
224 | ssl=SSL_new(ctx); | ||
225 | x509=SSL_get_certificate(ssl); | ||
226 | |||
227 | if (x509 != NULL) { | ||
228 | EVP_PKEY *pktmp; | ||
229 | pktmp = X509_get_pubkey(x509); | ||
230 | EVP_PKEY_copy_parameters(pktmp, | ||
231 | SSL_get_privatekey(ssl)); | ||
232 | EVP_PKEY_free(pktmp); | ||
233 | } | ||
234 | SSL_free(ssl); | ||
235 | */ | ||
236 | |||
237 | /* | ||
238 | * If we are using DSA, we can copy the parameters from the | ||
239 | * private key | ||
240 | */ | ||
241 | |||
242 | |||
243 | /* | ||
244 | * Now we know that a key and cert have been set against the | ||
245 | * SSL context | ||
246 | */ | ||
247 | if (!SSL_CTX_check_private_key(ctx)) { | ||
248 | BIO_printf(bio_err, | ||
249 | "Private key does not match the certificate public key\n"); | ||
250 | return (0); | ||
251 | } | ||
252 | } | ||
253 | return (1); | ||
254 | } | ||
255 | |||
256 | int | ||
257 | set_cert_key_stuff(SSL_CTX * ctx, X509 * cert, EVP_PKEY * key) | ||
258 | { | ||
259 | if (cert == NULL) | ||
260 | return 1; | ||
261 | if (SSL_CTX_use_certificate(ctx, cert) <= 0) { | ||
262 | BIO_printf(bio_err, "error setting certificate\n"); | ||
263 | ERR_print_errors(bio_err); | ||
264 | return 0; | ||
265 | } | ||
266 | if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) { | ||
267 | BIO_printf(bio_err, "error setting private key\n"); | ||
268 | ERR_print_errors(bio_err); | ||
269 | return 0; | ||
270 | } | ||
271 | /* | ||
272 | * Now we know that a key and cert have been set against the SSL | ||
273 | * context | ||
274 | */ | ||
275 | if (!SSL_CTX_check_private_key(ctx)) { | ||
276 | BIO_printf(bio_err, | ||
277 | "Private key does not match the certificate public key\n"); | ||
278 | return 0; | ||
279 | } | ||
280 | return 1; | ||
281 | } | ||
282 | |||
283 | long | ||
284 | bio_dump_callback(BIO * bio, int cmd, const char *argp, | ||
285 | int argi, long argl, long ret) | ||
286 | { | ||
287 | BIO *out; | ||
288 | |||
289 | out = (BIO *) BIO_get_callback_arg(bio); | ||
290 | if (out == NULL) | ||
291 | return (ret); | ||
292 | |||
293 | if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { | ||
294 | BIO_printf(out, | ||
295 | "read from %p [%p] (%lu bytes => %ld (0x%lX))\n", | ||
296 | (void *) bio, argp, (unsigned long) argi, ret, ret); | ||
297 | BIO_dump(out, argp, (int) ret); | ||
298 | return (ret); | ||
299 | } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { | ||
300 | BIO_printf(out, | ||
301 | "write to %p [%p] (%lu bytes => %ld (0x%lX))\n", | ||
302 | (void *) bio, argp, (unsigned long) argi, ret, ret); | ||
303 | BIO_dump(out, argp, (int) ret); | ||
304 | } | ||
305 | return (ret); | ||
306 | } | ||
307 | |||
308 | void | ||
309 | apps_ssl_info_callback(const SSL * s, int where, int ret) | ||
310 | { | ||
311 | const char *str; | ||
312 | int w; | ||
313 | |||
314 | w = where & ~SSL_ST_MASK; | ||
315 | |||
316 | if (w & SSL_ST_CONNECT) | ||
317 | str = "SSL_connect"; | ||
318 | else if (w & SSL_ST_ACCEPT) | ||
319 | str = "SSL_accept"; | ||
320 | else | ||
321 | str = "undefined"; | ||
322 | |||
323 | if (where & SSL_CB_LOOP) { | ||
324 | BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s)); | ||
325 | } else if (where & SSL_CB_ALERT) { | ||
326 | str = (where & SSL_CB_READ) ? "read" : "write"; | ||
327 | BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", str, | ||
328 | SSL_alert_type_string_long(ret), | ||
329 | SSL_alert_desc_string_long(ret)); | ||
330 | } else if (where & SSL_CB_EXIT) { | ||
331 | if (ret == 0) | ||
332 | BIO_printf(bio_err, "%s:failed in %s\n", | ||
333 | str, SSL_state_string_long(s)); | ||
334 | else if (ret < 0) { | ||
335 | BIO_printf(bio_err, "%s:error in %s\n", | ||
336 | str, SSL_state_string_long(s)); | ||
337 | } | ||
338 | } | ||
339 | } | ||
340 | |||
341 | |||
342 | void | ||
343 | msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL * ssl, void *arg) | ||
344 | { | ||
345 | BIO *bio = arg; | ||
346 | const char *str_write_p, *str_version, *str_content_type = "", | ||
347 | *str_details1 = "", *str_details2 = ""; | ||
348 | |||
349 | str_write_p = write_p ? ">>>" : "<<<"; | ||
350 | |||
351 | switch (version) { | ||
352 | case SSL2_VERSION: | ||
353 | str_version = "SSL 2.0"; | ||
354 | break; | ||
355 | case SSL3_VERSION: | ||
356 | str_version = "SSL 3.0 "; | ||
357 | break; | ||
358 | case TLS1_VERSION: | ||
359 | str_version = "TLS 1.0 "; | ||
360 | break; | ||
361 | case TLS1_1_VERSION: | ||
362 | str_version = "TLS 1.1 "; | ||
363 | break; | ||
364 | case TLS1_2_VERSION: | ||
365 | str_version = "TLS 1.2 "; | ||
366 | break; | ||
367 | case DTLS1_VERSION: | ||
368 | str_version = "DTLS 1.0 "; | ||
369 | break; | ||
370 | case DTLS1_BAD_VER: | ||
371 | str_version = "DTLS 1.0 (bad) "; | ||
372 | break; | ||
373 | default: | ||
374 | str_version = "???"; | ||
375 | } | ||
376 | |||
377 | if (version == SSL2_VERSION) { | ||
378 | str_details1 = "???"; | ||
379 | |||
380 | if (len > 0) { | ||
381 | switch (((const unsigned char *) buf)[0]) { | ||
382 | case 0: | ||
383 | str_details1 = ", ERROR:"; | ||
384 | str_details2 = " ???"; | ||
385 | if (len >= 3) { | ||
386 | unsigned err = (((const unsigned char *) buf)[1] << 8) + ((const unsigned char *) buf)[2]; | ||
387 | |||
388 | switch (err) { | ||
389 | case 0x0001: | ||
390 | str_details2 = " NO-CIPHER-ERROR"; | ||
391 | break; | ||
392 | case 0x0002: | ||
393 | str_details2 = " NO-CERTIFICATE-ERROR"; | ||
394 | break; | ||
395 | case 0x0004: | ||
396 | str_details2 = " BAD-CERTIFICATE-ERROR"; | ||
397 | break; | ||
398 | case 0x0006: | ||
399 | str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR"; | ||
400 | break; | ||
401 | } | ||
402 | } | ||
403 | break; | ||
404 | case 1: | ||
405 | str_details1 = ", CLIENT-HELLO"; | ||
406 | break; | ||
407 | case 2: | ||
408 | str_details1 = ", CLIENT-MASTER-KEY"; | ||
409 | break; | ||
410 | case 3: | ||
411 | str_details1 = ", CLIENT-FINISHED"; | ||
412 | break; | ||
413 | case 4: | ||
414 | str_details1 = ", SERVER-HELLO"; | ||
415 | break; | ||
416 | case 5: | ||
417 | str_details1 = ", SERVER-VERIFY"; | ||
418 | break; | ||
419 | case 6: | ||
420 | str_details1 = ", SERVER-FINISHED"; | ||
421 | break; | ||
422 | case 7: | ||
423 | str_details1 = ", REQUEST-CERTIFICATE"; | ||
424 | break; | ||
425 | case 8: | ||
426 | str_details1 = ", CLIENT-CERTIFICATE"; | ||
427 | break; | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | if (version == SSL3_VERSION || version == TLS1_VERSION || | ||
432 | version == TLS1_1_VERSION || version == TLS1_2_VERSION || | ||
433 | version == DTLS1_VERSION || version == DTLS1_BAD_VER) { | ||
434 | switch (content_type) { | ||
435 | case 20: | ||
436 | str_content_type = "ChangeCipherSpec"; | ||
437 | break; | ||
438 | case 21: | ||
439 | str_content_type = "Alert"; | ||
440 | break; | ||
441 | case 22: | ||
442 | str_content_type = "Handshake"; | ||
443 | break; | ||
444 | } | ||
445 | |||
446 | if (content_type == 21) { /* Alert */ | ||
447 | str_details1 = ", ???"; | ||
448 | |||
449 | if (len == 2) { | ||
450 | switch (((const unsigned char *) buf)[0]) { | ||
451 | case 1: | ||
452 | str_details1 = ", warning"; | ||
453 | break; | ||
454 | case 2: | ||
455 | str_details1 = ", fatal"; | ||
456 | break; | ||
457 | } | ||
458 | |||
459 | str_details2 = " ???"; | ||
460 | switch (((const unsigned char *) buf)[1]) { | ||
461 | case 0: | ||
462 | str_details2 = " close_notify"; | ||
463 | break; | ||
464 | case 10: | ||
465 | str_details2 = " unexpected_message"; | ||
466 | break; | ||
467 | case 20: | ||
468 | str_details2 = " bad_record_mac"; | ||
469 | break; | ||
470 | case 21: | ||
471 | str_details2 = " decryption_failed"; | ||
472 | break; | ||
473 | case 22: | ||
474 | str_details2 = " record_overflow"; | ||
475 | break; | ||
476 | case 30: | ||
477 | str_details2 = " decompression_failure"; | ||
478 | break; | ||
479 | case 40: | ||
480 | str_details2 = " handshake_failure"; | ||
481 | break; | ||
482 | case 42: | ||
483 | str_details2 = " bad_certificate"; | ||
484 | break; | ||
485 | case 43: | ||
486 | str_details2 = " unsupported_certificate"; | ||
487 | break; | ||
488 | case 44: | ||
489 | str_details2 = " certificate_revoked"; | ||
490 | break; | ||
491 | case 45: | ||
492 | str_details2 = " certificate_expired"; | ||
493 | break; | ||
494 | case 46: | ||
495 | str_details2 = " certificate_unknown"; | ||
496 | break; | ||
497 | case 47: | ||
498 | str_details2 = " illegal_parameter"; | ||
499 | break; | ||
500 | case 48: | ||
501 | str_details2 = " unknown_ca"; | ||
502 | break; | ||
503 | case 49: | ||
504 | str_details2 = " access_denied"; | ||
505 | break; | ||
506 | case 50: | ||
507 | str_details2 = " decode_error"; | ||
508 | break; | ||
509 | case 51: | ||
510 | str_details2 = " decrypt_error"; | ||
511 | break; | ||
512 | case 60: | ||
513 | str_details2 = " export_restriction"; | ||
514 | break; | ||
515 | case 70: | ||
516 | str_details2 = " protocol_version"; | ||
517 | break; | ||
518 | case 71: | ||
519 | str_details2 = " insufficient_security"; | ||
520 | break; | ||
521 | case 80: | ||
522 | str_details2 = " internal_error"; | ||
523 | break; | ||
524 | case 90: | ||
525 | str_details2 = " user_canceled"; | ||
526 | break; | ||
527 | case 100: | ||
528 | str_details2 = " no_renegotiation"; | ||
529 | break; | ||
530 | case 110: | ||
531 | str_details2 = " unsupported_extension"; | ||
532 | break; | ||
533 | case 111: | ||
534 | str_details2 = " certificate_unobtainable"; | ||
535 | break; | ||
536 | case 112: | ||
537 | str_details2 = " unrecognized_name"; | ||
538 | break; | ||
539 | case 113: | ||
540 | str_details2 = " bad_certificate_status_response"; | ||
541 | break; | ||
542 | case 114: | ||
543 | str_details2 = " bad_certificate_hash_value"; | ||
544 | break; | ||
545 | case 115: | ||
546 | str_details2 = " unknown_psk_identity"; | ||
547 | break; | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | if (content_type == 22) { /* Handshake */ | ||
552 | str_details1 = "???"; | ||
553 | |||
554 | if (len > 0) { | ||
555 | switch (((const unsigned char *) buf)[0]) { | ||
556 | case 0: | ||
557 | str_details1 = ", HelloRequest"; | ||
558 | break; | ||
559 | case 1: | ||
560 | str_details1 = ", ClientHello"; | ||
561 | break; | ||
562 | case 2: | ||
563 | str_details1 = ", ServerHello"; | ||
564 | break; | ||
565 | case 3: | ||
566 | str_details1 = ", HelloVerifyRequest"; | ||
567 | break; | ||
568 | case 11: | ||
569 | str_details1 = ", Certificate"; | ||
570 | break; | ||
571 | case 12: | ||
572 | str_details1 = ", ServerKeyExchange"; | ||
573 | break; | ||
574 | case 13: | ||
575 | str_details1 = ", CertificateRequest"; | ||
576 | break; | ||
577 | case 14: | ||
578 | str_details1 = ", ServerHelloDone"; | ||
579 | break; | ||
580 | case 15: | ||
581 | str_details1 = ", CertificateVerify"; | ||
582 | break; | ||
583 | case 16: | ||
584 | str_details1 = ", ClientKeyExchange"; | ||
585 | break; | ||
586 | case 20: | ||
587 | str_details1 = ", Finished"; | ||
588 | break; | ||
589 | } | ||
590 | } | ||
591 | } | ||
592 | } | ||
593 | BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, | ||
594 | str_version, str_content_type, (unsigned long) len, | ||
595 | str_details1, str_details2); | ||
596 | |||
597 | if (len > 0) { | ||
598 | size_t num, i; | ||
599 | |||
600 | BIO_printf(bio, " "); | ||
601 | num = len; | ||
602 | #if 0 | ||
603 | if (num > 16) | ||
604 | num = 16; | ||
605 | #endif | ||
606 | for (i = 0; i < num; i++) { | ||
607 | if (i % 16 == 0 && i > 0) | ||
608 | BIO_printf(bio, "\n "); | ||
609 | BIO_printf(bio, " %02x", | ||
610 | ((const unsigned char *) buf)[i]); | ||
611 | } | ||
612 | if (i < len) | ||
613 | BIO_printf(bio, " ..."); | ||
614 | BIO_printf(bio, "\n"); | ||
615 | } | ||
616 | (void) BIO_flush(bio); | ||
617 | } | ||
618 | |||
619 | void | ||
620 | tlsext_cb(SSL * s, int client_server, int type, unsigned char *data, int len, | ||
621 | void *arg) | ||
622 | { | ||
623 | BIO *bio = arg; | ||
624 | char *extname; | ||
625 | |||
626 | switch (type) { | ||
627 | case TLSEXT_TYPE_server_name: | ||
628 | extname = "server name"; | ||
629 | break; | ||
630 | |||
631 | case TLSEXT_TYPE_max_fragment_length: | ||
632 | extname = "max fragment length"; | ||
633 | break; | ||
634 | |||
635 | case TLSEXT_TYPE_client_certificate_url: | ||
636 | extname = "client certificate URL"; | ||
637 | break; | ||
638 | |||
639 | case TLSEXT_TYPE_trusted_ca_keys: | ||
640 | extname = "trusted CA keys"; | ||
641 | break; | ||
642 | |||
643 | case TLSEXT_TYPE_truncated_hmac: | ||
644 | extname = "truncated HMAC"; | ||
645 | break; | ||
646 | |||
647 | case TLSEXT_TYPE_status_request: | ||
648 | extname = "status request"; | ||
649 | break; | ||
650 | |||
651 | case TLSEXT_TYPE_user_mapping: | ||
652 | extname = "user mapping"; | ||
653 | break; | ||
654 | |||
655 | case TLSEXT_TYPE_client_authz: | ||
656 | extname = "client authz"; | ||
657 | break; | ||
658 | |||
659 | case TLSEXT_TYPE_server_authz: | ||
660 | extname = "server authz"; | ||
661 | break; | ||
662 | |||
663 | case TLSEXT_TYPE_cert_type: | ||
664 | extname = "cert type"; | ||
665 | break; | ||
666 | |||
667 | case TLSEXT_TYPE_elliptic_curves: | ||
668 | extname = "elliptic curves"; | ||
669 | break; | ||
670 | |||
671 | case TLSEXT_TYPE_ec_point_formats: | ||
672 | extname = "EC point formats"; | ||
673 | break; | ||
674 | |||
675 | case TLSEXT_TYPE_srp: | ||
676 | extname = "SRP"; | ||
677 | break; | ||
678 | |||
679 | case TLSEXT_TYPE_signature_algorithms: | ||
680 | extname = "signature algorithms"; | ||
681 | break; | ||
682 | |||
683 | case TLSEXT_TYPE_use_srtp: | ||
684 | extname = "use SRTP"; | ||
685 | break; | ||
686 | |||
687 | case TLSEXT_TYPE_heartbeat: | ||
688 | extname = "heartbeat"; | ||
689 | break; | ||
690 | |||
691 | case TLSEXT_TYPE_session_ticket: | ||
692 | extname = "session ticket"; | ||
693 | break; | ||
694 | |||
695 | case TLSEXT_TYPE_renegotiate: | ||
696 | extname = "renegotiation info"; | ||
697 | break; | ||
698 | |||
699 | #ifdef TLSEXT_TYPE_next_proto_neg | ||
700 | case TLSEXT_TYPE_next_proto_neg: | ||
701 | extname = "next protocol"; | ||
702 | break; | ||
703 | #endif | ||
704 | |||
705 | default: | ||
706 | extname = "unknown"; | ||
707 | break; | ||
708 | |||
709 | } | ||
710 | |||
711 | BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", | ||
712 | client_server ? "server" : "client", extname, type, len); | ||
713 | BIO_dump(bio, (char *) data, len); | ||
714 | (void) BIO_flush(bio); | ||
715 | } | ||
716 | |||
717 | int | ||
718 | generate_cookie_callback(SSL * ssl, unsigned char *cookie, | ||
719 | unsigned int *cookie_len) | ||
720 | { | ||
721 | unsigned char *buffer, result[EVP_MAX_MD_SIZE]; | ||
722 | unsigned int length, resultlength; | ||
723 | union { | ||
724 | struct sockaddr sa; | ||
725 | struct sockaddr_in s4; | ||
726 | struct sockaddr_in6 s6; | ||
727 | } peer; | ||
728 | |||
729 | /* Initialize a random secret */ | ||
730 | if (!cookie_initialized) { | ||
731 | if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH)) { | ||
732 | BIO_printf(bio_err, | ||
733 | "error setting random cookie secret\n"); | ||
734 | return 0; | ||
735 | } | ||
736 | cookie_initialized = 1; | ||
737 | } | ||
738 | /* Read peer information */ | ||
739 | (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); | ||
740 | |||
741 | /* Create buffer with peer's address and port */ | ||
742 | length = 0; | ||
743 | switch (peer.sa.sa_family) { | ||
744 | case AF_INET: | ||
745 | length += sizeof(struct in_addr); | ||
746 | length += sizeof(peer.s4.sin_port); | ||
747 | break; | ||
748 | case AF_INET6: | ||
749 | length += sizeof(struct in6_addr); | ||
750 | length += sizeof(peer.s6.sin6_port); | ||
751 | break; | ||
752 | default: | ||
753 | OPENSSL_assert(0); | ||
754 | break; | ||
755 | } | ||
756 | buffer = malloc(length); | ||
757 | |||
758 | if (buffer == NULL) { | ||
759 | BIO_printf(bio_err, "out of memory\n"); | ||
760 | return 0; | ||
761 | } | ||
762 | switch (peer.sa.sa_family) { | ||
763 | case AF_INET: | ||
764 | memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); | ||
765 | memcpy(buffer + sizeof(peer.s4.sin_port), | ||
766 | &peer.s4.sin_addr, sizeof(struct in_addr)); | ||
767 | break; | ||
768 | case AF_INET6: | ||
769 | memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); | ||
770 | memcpy(buffer + sizeof(peer.s6.sin6_port), | ||
771 | &peer.s6.sin6_addr, sizeof(struct in6_addr)); | ||
772 | break; | ||
773 | default: | ||
774 | OPENSSL_assert(0); | ||
775 | break; | ||
776 | } | ||
777 | |||
778 | /* Calculate HMAC of buffer using the secret */ | ||
779 | HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, | ||
780 | buffer, length, result, &resultlength); | ||
781 | free(buffer); | ||
782 | |||
783 | memcpy(cookie, result, resultlength); | ||
784 | *cookie_len = resultlength; | ||
785 | |||
786 | return 1; | ||
787 | } | ||
788 | |||
789 | int | ||
790 | verify_cookie_callback(SSL * ssl, unsigned char *cookie, unsigned int cookie_len) | ||
791 | { | ||
792 | unsigned char *buffer, result[EVP_MAX_MD_SIZE]; | ||
793 | unsigned int length, resultlength; | ||
794 | union { | ||
795 | struct sockaddr sa; | ||
796 | struct sockaddr_in s4; | ||
797 | struct sockaddr_in6 s6; | ||
798 | } peer; | ||
799 | |||
800 | /* If secret isn't initialized yet, the cookie can't be valid */ | ||
801 | if (!cookie_initialized) | ||
802 | return 0; | ||
803 | |||
804 | /* Read peer information */ | ||
805 | (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); | ||
806 | |||
807 | /* Create buffer with peer's address and port */ | ||
808 | length = 0; | ||
809 | switch (peer.sa.sa_family) { | ||
810 | case AF_INET: | ||
811 | length += sizeof(struct in_addr); | ||
812 | length += sizeof(peer.s4.sin_port); | ||
813 | break; | ||
814 | case AF_INET6: | ||
815 | length += sizeof(struct in6_addr); | ||
816 | length += sizeof(peer.s6.sin6_port); | ||
817 | break; | ||
818 | default: | ||
819 | OPENSSL_assert(0); | ||
820 | break; | ||
821 | } | ||
822 | buffer = malloc(length); | ||
823 | |||
824 | if (buffer == NULL) { | ||
825 | BIO_printf(bio_err, "out of memory\n"); | ||
826 | return 0; | ||
827 | } | ||
828 | switch (peer.sa.sa_family) { | ||
829 | case AF_INET: | ||
830 | memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); | ||
831 | memcpy(buffer + sizeof(peer.s4.sin_port), | ||
832 | &peer.s4.sin_addr, sizeof(struct in_addr)); | ||
833 | break; | ||
834 | case AF_INET6: | ||
835 | memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); | ||
836 | memcpy(buffer + sizeof(peer.s6.sin6_port), | ||
837 | &peer.s6.sin6_addr, sizeof(struct in6_addr)); | ||
838 | break; | ||
839 | default: | ||
840 | OPENSSL_assert(0); | ||
841 | break; | ||
842 | } | ||
843 | |||
844 | /* Calculate HMAC of buffer using the secret */ | ||
845 | HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, | ||
846 | buffer, length, result, &resultlength); | ||
847 | free(buffer); | ||
848 | |||
849 | if (cookie_len == resultlength && | ||
850 | memcmp(result, cookie, resultlength) == 0) | ||
851 | return 1; | ||
852 | |||
853 | return 0; | ||
854 | } | ||