1*23cc9d40Stb /* $OpenBSD: s_cb.c,v 1.22 2025/01/02 13:10:03 tb Exp $ */ 2dab3f910Sjsing /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3dab3f910Sjsing * All rights reserved. 4dab3f910Sjsing * 5dab3f910Sjsing * This package is an SSL implementation written 6dab3f910Sjsing * by Eric Young (eay@cryptsoft.com). 7dab3f910Sjsing * The implementation was written so as to conform with Netscapes SSL. 8dab3f910Sjsing * 9dab3f910Sjsing * This library is free for commercial and non-commercial use as long as 10dab3f910Sjsing * the following conditions are aheared to. The following conditions 11dab3f910Sjsing * apply to all code found in this distribution, be it the RC4, RSA, 12dab3f910Sjsing * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13dab3f910Sjsing * included with this distribution is covered by the same copyright terms 14dab3f910Sjsing * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15dab3f910Sjsing * 16dab3f910Sjsing * Copyright remains Eric Young's, and as such any Copyright notices in 17dab3f910Sjsing * the code are not to be removed. 18dab3f910Sjsing * If this package is used in a product, Eric Young should be given attribution 19dab3f910Sjsing * as the author of the parts of the library used. 20dab3f910Sjsing * This can be in the form of a textual message at program startup or 21dab3f910Sjsing * in documentation (online or textual) provided with the package. 22dab3f910Sjsing * 23dab3f910Sjsing * Redistribution and use in source and binary forms, with or without 24dab3f910Sjsing * modification, are permitted provided that the following conditions 25dab3f910Sjsing * are met: 26dab3f910Sjsing * 1. Redistributions of source code must retain the copyright 27dab3f910Sjsing * notice, this list of conditions and the following disclaimer. 28dab3f910Sjsing * 2. Redistributions in binary form must reproduce the above copyright 29dab3f910Sjsing * notice, this list of conditions and the following disclaimer in the 30dab3f910Sjsing * documentation and/or other materials provided with the distribution. 31dab3f910Sjsing * 3. All advertising materials mentioning features or use of this software 32dab3f910Sjsing * must display the following acknowledgement: 33dab3f910Sjsing * "This product includes cryptographic software written by 34dab3f910Sjsing * Eric Young (eay@cryptsoft.com)" 35dab3f910Sjsing * The word 'cryptographic' can be left out if the rouines from the library 36dab3f910Sjsing * being used are not cryptographic related :-). 37dab3f910Sjsing * 4. If you include any Windows specific code (or a derivative thereof) from 38dab3f910Sjsing * the apps directory (application code) you must include an acknowledgement: 39dab3f910Sjsing * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40dab3f910Sjsing * 41dab3f910Sjsing * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42dab3f910Sjsing * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43dab3f910Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44dab3f910Sjsing * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45dab3f910Sjsing * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46dab3f910Sjsing * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47dab3f910Sjsing * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48dab3f910Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49dab3f910Sjsing * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50dab3f910Sjsing * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51dab3f910Sjsing * SUCH DAMAGE. 52dab3f910Sjsing * 53dab3f910Sjsing * The licence and distribution terms for any publically available version or 54dab3f910Sjsing * derivative of this code cannot be changed. i.e. this code cannot simply be 55dab3f910Sjsing * copied and put under another distribution licence 56dab3f910Sjsing * [including the GNU Public Licence.] 57dab3f910Sjsing */ 58dab3f910Sjsing /* ==================================================================== 59dab3f910Sjsing * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 60dab3f910Sjsing * 61dab3f910Sjsing * Redistribution and use in source and binary forms, with or without 62dab3f910Sjsing * modification, are permitted provided that the following conditions 63dab3f910Sjsing * are met: 64dab3f910Sjsing * 65dab3f910Sjsing * 1. Redistributions of source code must retain the above copyright 66dab3f910Sjsing * notice, this list of conditions and the following disclaimer. 67dab3f910Sjsing * 68dab3f910Sjsing * 2. Redistributions in binary form must reproduce the above copyright 69dab3f910Sjsing * notice, this list of conditions and the following disclaimer in 70dab3f910Sjsing * the documentation and/or other materials provided with the 71dab3f910Sjsing * distribution. 72dab3f910Sjsing * 73dab3f910Sjsing * 3. All advertising materials mentioning features or use of this 74dab3f910Sjsing * software must display the following acknowledgment: 75dab3f910Sjsing * "This product includes software developed by the OpenSSL Project 76dab3f910Sjsing * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77dab3f910Sjsing * 78dab3f910Sjsing * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79dab3f910Sjsing * endorse or promote products derived from this software without 80dab3f910Sjsing * prior written permission. For written permission, please contact 81dab3f910Sjsing * openssl-core@openssl.org. 82dab3f910Sjsing * 83dab3f910Sjsing * 5. Products derived from this software may not be called "OpenSSL" 84dab3f910Sjsing * nor may "OpenSSL" appear in their names without prior written 85dab3f910Sjsing * permission of the OpenSSL Project. 86dab3f910Sjsing * 87dab3f910Sjsing * 6. Redistributions of any form whatsoever must retain the following 88dab3f910Sjsing * acknowledgment: 89dab3f910Sjsing * "This product includes software developed by the OpenSSL Project 90dab3f910Sjsing * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91dab3f910Sjsing * 92dab3f910Sjsing * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93dab3f910Sjsing * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94dab3f910Sjsing * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95dab3f910Sjsing * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96dab3f910Sjsing * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97dab3f910Sjsing * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98dab3f910Sjsing * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99dab3f910Sjsing * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100dab3f910Sjsing * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101dab3f910Sjsing * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102dab3f910Sjsing * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103dab3f910Sjsing * OF THE POSSIBILITY OF SUCH DAMAGE. 104dab3f910Sjsing * ==================================================================== 105dab3f910Sjsing * 106dab3f910Sjsing * This product includes cryptographic software written by Eric Young 107dab3f910Sjsing * (eay@cryptsoft.com). This product includes software written by Tim 108dab3f910Sjsing * Hudson (tjh@cryptsoft.com). 109dab3f910Sjsing * 110dab3f910Sjsing */ 111dab3f910Sjsing 112dab3f910Sjsing #include <sys/socket.h> 113dab3f910Sjsing 114dab3f910Sjsing #include <netinet/in.h> 115dab3f910Sjsing 116dab3f910Sjsing #include <netdb.h> 117dab3f910Sjsing #include <stdio.h> 118dab3f910Sjsing #include <stdlib.h> 119dab3f910Sjsing #include <string.h> 120dab3f910Sjsing 121dab3f910Sjsing #include "apps.h" 122dab3f910Sjsing 123dab3f910Sjsing #include <openssl/err.h> 124dab3f910Sjsing #include <openssl/ssl.h> 125dab3f910Sjsing #include <openssl/x509.h> 126dab3f910Sjsing 127dab3f910Sjsing #define COOKIE_SECRET_LENGTH 16 128dab3f910Sjsing 129dab3f910Sjsing int verify_depth = 0; 130dab3f910Sjsing int verify_return_error = 0; 131dab3f910Sjsing unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; 132dab3f910Sjsing int cookie_initialized = 0; 133dab3f910Sjsing 134dab3f910Sjsing int 135dab3f910Sjsing verify_callback(int ok, X509_STORE_CTX * ctx) 136dab3f910Sjsing { 137dab3f910Sjsing X509 *err_cert; 138dab3f910Sjsing int err, depth; 139dab3f910Sjsing 140dab3f910Sjsing err_cert = X509_STORE_CTX_get_current_cert(ctx); 141dab3f910Sjsing err = X509_STORE_CTX_get_error(ctx); 142dab3f910Sjsing depth = X509_STORE_CTX_get_error_depth(ctx); 143dab3f910Sjsing 144dab3f910Sjsing BIO_printf(bio_err, "depth=%d ", depth); 145dab3f910Sjsing if (err_cert) { 146dab3f910Sjsing X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), 147dab3f910Sjsing 0, XN_FLAG_ONELINE); 148dab3f910Sjsing BIO_puts(bio_err, "\n"); 149dab3f910Sjsing } else 150dab3f910Sjsing BIO_puts(bio_err, "<no cert>\n"); 151dab3f910Sjsing if (!ok) { 152dab3f910Sjsing BIO_printf(bio_err, "verify error:num=%d:%s\n", err, 153dab3f910Sjsing X509_verify_cert_error_string(err)); 154dab3f910Sjsing if (verify_depth >= depth) { 155dab3f910Sjsing if (!verify_return_error) 156dab3f910Sjsing ok = 1; 157dab3f910Sjsing } else { 158dab3f910Sjsing ok = 0; 159dab3f910Sjsing } 160dab3f910Sjsing } 161dab3f910Sjsing switch (err) { 162dab3f910Sjsing case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 163dab3f910Sjsing BIO_puts(bio_err, "issuer= "); 1648e101a2aSdoug if (err_cert == NULL) 1658e101a2aSdoug BIO_puts(bio_err, "<error getting cert>"); 1668e101a2aSdoug else 1678e101a2aSdoug X509_NAME_print_ex(bio_err, 1688e101a2aSdoug X509_get_issuer_name(err_cert), 0, XN_FLAG_ONELINE); 169dab3f910Sjsing BIO_puts(bio_err, "\n"); 170dab3f910Sjsing break; 171dab3f910Sjsing case X509_V_ERR_CERT_NOT_YET_VALID: 172dab3f910Sjsing case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 173dab3f910Sjsing BIO_printf(bio_err, "notBefore="); 1748e101a2aSdoug if (err_cert == NULL) 1758e101a2aSdoug BIO_printf(bio_err, " <error getting cert>"); 1768e101a2aSdoug else 177dab3f910Sjsing ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert)); 178dab3f910Sjsing BIO_printf(bio_err, "\n"); 179dab3f910Sjsing break; 180dab3f910Sjsing case X509_V_ERR_CERT_HAS_EXPIRED: 181dab3f910Sjsing case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 182dab3f910Sjsing BIO_printf(bio_err, "notAfter="); 1838e101a2aSdoug if (err_cert == NULL) 1848e101a2aSdoug BIO_printf(bio_err, " <error getting cert>"); 1858e101a2aSdoug else 186dab3f910Sjsing ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert)); 187dab3f910Sjsing BIO_printf(bio_err, "\n"); 188dab3f910Sjsing break; 189dab3f910Sjsing case X509_V_ERR_NO_EXPLICIT_POLICY: 190dab3f910Sjsing break; 191dab3f910Sjsing } 192dab3f910Sjsing 193dab3f910Sjsing BIO_printf(bio_err, "verify return:%d\n", ok); 194dab3f910Sjsing return (ok); 195dab3f910Sjsing } 196dab3f910Sjsing 197dab3f910Sjsing int 198dab3f910Sjsing set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file) 199dab3f910Sjsing { 200e7c1cbcdStb if (cert_file == NULL) 201e7c1cbcdStb return 1; 202e7c1cbcdStb 203e7c1cbcdStb if (key_file == NULL) 204e7c1cbcdStb key_file = cert_file; 205e7c1cbcdStb 206e7c1cbcdStb if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) { 207dab3f910Sjsing BIO_printf(bio_err, 208dab3f910Sjsing "unable to get certificate from '%s'\n", cert_file); 209dab3f910Sjsing ERR_print_errors(bio_err); 210e7c1cbcdStb return 0; 211dab3f910Sjsing } 212e7c1cbcdStb if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) { 213e7c1cbcdStb BIO_printf(bio_err, "unable to get private key from '%s'\n", 214e7c1cbcdStb key_file); 215dab3f910Sjsing ERR_print_errors(bio_err); 216e7c1cbcdStb return 0; 217dab3f910Sjsing } 218dab3f910Sjsing 219e7c1cbcdStb /* Now we know that a key and cert have been set against the context. */ 220dab3f910Sjsing if (!SSL_CTX_check_private_key(ctx)) { 221dab3f910Sjsing BIO_printf(bio_err, 222dab3f910Sjsing "Private key does not match the certificate public key\n"); 223e7c1cbcdStb return 0; 224dab3f910Sjsing } 225e7c1cbcdStb 226e7c1cbcdStb return 1; 227dab3f910Sjsing } 228dab3f910Sjsing 229dab3f910Sjsing int 230dab3f910Sjsing set_cert_key_stuff(SSL_CTX * ctx, X509 * cert, EVP_PKEY * key) 231dab3f910Sjsing { 232dab3f910Sjsing if (cert == NULL) 233dab3f910Sjsing return 1; 234dab3f910Sjsing if (SSL_CTX_use_certificate(ctx, cert) <= 0) { 235dab3f910Sjsing BIO_printf(bio_err, "error setting certificate\n"); 236dab3f910Sjsing ERR_print_errors(bio_err); 237dab3f910Sjsing return 0; 238dab3f910Sjsing } 239dab3f910Sjsing if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) { 240dab3f910Sjsing BIO_printf(bio_err, "error setting private key\n"); 241dab3f910Sjsing ERR_print_errors(bio_err); 242dab3f910Sjsing return 0; 243dab3f910Sjsing } 244dab3f910Sjsing /* 245dab3f910Sjsing * Now we know that a key and cert have been set against the SSL 246dab3f910Sjsing * context 247dab3f910Sjsing */ 248dab3f910Sjsing if (!SSL_CTX_check_private_key(ctx)) { 249dab3f910Sjsing BIO_printf(bio_err, 250dab3f910Sjsing "Private key does not match the certificate public key\n"); 251dab3f910Sjsing return 0; 252dab3f910Sjsing } 253dab3f910Sjsing return 1; 254dab3f910Sjsing } 255dab3f910Sjsing 25657a9ba28Sjsing int 25757a9ba28Sjsing ssl_print_tmp_key(BIO *out, SSL *s) 25857a9ba28Sjsing { 25957a9ba28Sjsing const char *cname; 26057a9ba28Sjsing EVP_PKEY *pkey; 26157a9ba28Sjsing EC_KEY *ec; 262709513a4Stb const EC_GROUP *group; 26357a9ba28Sjsing int nid; 26457a9ba28Sjsing 26557a9ba28Sjsing if (!SSL_get_server_tmp_key(s, &pkey)) 26657a9ba28Sjsing return 0; 26757a9ba28Sjsing 26857a9ba28Sjsing BIO_puts(out, "Server Temp Key: "); 26957a9ba28Sjsing switch (EVP_PKEY_id(pkey)) { 27057a9ba28Sjsing case EVP_PKEY_DH: 27157a9ba28Sjsing BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(pkey)); 27257a9ba28Sjsing break; 27357a9ba28Sjsing 27457a9ba28Sjsing case EVP_PKEY_EC: 275709513a4Stb if ((ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) 276709513a4Stb goto err; 277709513a4Stb if ((group = EC_KEY_get0_group(ec)) == NULL) 278709513a4Stb goto err; 279709513a4Stb 280709513a4Stb nid = EC_GROUP_get_curve_name(group); 28157a9ba28Sjsing 28257a9ba28Sjsing if ((cname = EC_curve_nid2nist(nid)) == NULL) 28357a9ba28Sjsing cname = OBJ_nid2sn(nid); 28457a9ba28Sjsing 28557a9ba28Sjsing BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(pkey)); 28657a9ba28Sjsing break; 28757a9ba28Sjsing 28857a9ba28Sjsing default: 28957a9ba28Sjsing BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(pkey)), 29057a9ba28Sjsing EVP_PKEY_bits(pkey)); 29157a9ba28Sjsing } 29257a9ba28Sjsing 293709513a4Stb err: 29457a9ba28Sjsing EVP_PKEY_free(pkey); 29557a9ba28Sjsing return 1; 29657a9ba28Sjsing } 29757a9ba28Sjsing 298dab3f910Sjsing long 299dab3f910Sjsing bio_dump_callback(BIO * bio, int cmd, const char *argp, 300dab3f910Sjsing int argi, long argl, long ret) 301dab3f910Sjsing { 302dab3f910Sjsing BIO *out; 303dab3f910Sjsing 304dab3f910Sjsing out = (BIO *) BIO_get_callback_arg(bio); 305dab3f910Sjsing if (out == NULL) 306dab3f910Sjsing return (ret); 307dab3f910Sjsing 308dab3f910Sjsing if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { 309dab3f910Sjsing BIO_printf(out, 310dab3f910Sjsing "read from %p [%p] (%lu bytes => %ld (0x%lX))\n", 311dab3f910Sjsing (void *) bio, argp, (unsigned long) argi, ret, ret); 312dab3f910Sjsing BIO_dump(out, argp, (int) ret); 313dab3f910Sjsing return (ret); 314dab3f910Sjsing } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { 315dab3f910Sjsing BIO_printf(out, 316dab3f910Sjsing "write to %p [%p] (%lu bytes => %ld (0x%lX))\n", 317dab3f910Sjsing (void *) bio, argp, (unsigned long) argi, ret, ret); 318dab3f910Sjsing BIO_dump(out, argp, (int) ret); 319dab3f910Sjsing } 320dab3f910Sjsing return (ret); 321dab3f910Sjsing } 322dab3f910Sjsing 323dab3f910Sjsing void 324dab3f910Sjsing apps_ssl_info_callback(const SSL * s, int where, int ret) 325dab3f910Sjsing { 326dab3f910Sjsing const char *str; 327dab3f910Sjsing int w; 328dab3f910Sjsing 329dab3f910Sjsing w = where & ~SSL_ST_MASK; 330dab3f910Sjsing 331dab3f910Sjsing if (w & SSL_ST_CONNECT) 332dab3f910Sjsing str = "SSL_connect"; 333dab3f910Sjsing else if (w & SSL_ST_ACCEPT) 334dab3f910Sjsing str = "SSL_accept"; 335dab3f910Sjsing else 336dab3f910Sjsing str = "undefined"; 337dab3f910Sjsing 338dab3f910Sjsing if (where & SSL_CB_LOOP) { 339dab3f910Sjsing BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s)); 340dab3f910Sjsing } else if (where & SSL_CB_ALERT) { 341dab3f910Sjsing str = (where & SSL_CB_READ) ? "read" : "write"; 342dab3f910Sjsing BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", str, 343dab3f910Sjsing SSL_alert_type_string_long(ret), 344dab3f910Sjsing SSL_alert_desc_string_long(ret)); 345dab3f910Sjsing } else if (where & SSL_CB_EXIT) { 346dab3f910Sjsing if (ret == 0) 347dab3f910Sjsing BIO_printf(bio_err, "%s:failed in %s\n", 348dab3f910Sjsing str, SSL_state_string_long(s)); 349dab3f910Sjsing else if (ret < 0) { 350dab3f910Sjsing BIO_printf(bio_err, "%s:error in %s\n", 351dab3f910Sjsing str, SSL_state_string_long(s)); 352dab3f910Sjsing } 353dab3f910Sjsing } 354dab3f910Sjsing } 355dab3f910Sjsing 356dab3f910Sjsing 357dab3f910Sjsing void 358dab3f910Sjsing msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL * ssl, void *arg) 359dab3f910Sjsing { 360dab3f910Sjsing BIO *bio = arg; 361dab3f910Sjsing const char *str_write_p, *str_version, *str_content_type = "", 362dab3f910Sjsing *str_details1 = "", *str_details2 = ""; 363dab3f910Sjsing 364dab3f910Sjsing str_write_p = write_p ? ">>>" : "<<<"; 365dab3f910Sjsing 36688411e53Stb /* XXX convert to using ssl_get_version */ 367dab3f910Sjsing switch (version) { 368dab3f910Sjsing case SSL2_VERSION: 369dab3f910Sjsing str_version = "SSL 2.0"; 370dab3f910Sjsing break; 371dab3f910Sjsing case SSL3_VERSION: 372dab3f910Sjsing str_version = "SSL 3.0 "; 373dab3f910Sjsing break; 374dab3f910Sjsing case TLS1_VERSION: 375dab3f910Sjsing str_version = "TLS 1.0 "; 376dab3f910Sjsing break; 377dab3f910Sjsing case TLS1_1_VERSION: 378dab3f910Sjsing str_version = "TLS 1.1 "; 379dab3f910Sjsing break; 380dab3f910Sjsing case TLS1_2_VERSION: 381dab3f910Sjsing str_version = "TLS 1.2 "; 382dab3f910Sjsing break; 383654e66e6Stb case TLS1_3_VERSION: 384654e66e6Stb str_version = "TLS 1.3 "; 385654e66e6Stb break; 386dab3f910Sjsing case DTLS1_VERSION: 387dab3f910Sjsing str_version = "DTLS 1.0 "; 388dab3f910Sjsing break; 389e8cca36cSinoguchi case DTLS1_2_VERSION: 390e8cca36cSinoguchi str_version = "DTLS 1.2 "; 391e8cca36cSinoguchi break; 392dab3f910Sjsing default: 393dab3f910Sjsing str_version = "???"; 394dab3f910Sjsing } 395dab3f910Sjsing 396dab3f910Sjsing if (version == SSL2_VERSION) { 397dab3f910Sjsing str_details1 = "???"; 398dab3f910Sjsing 399dab3f910Sjsing if (len > 0) { 40088411e53Stb /* XXX magic numbers */ 401dab3f910Sjsing switch (((const unsigned char *) buf)[0]) { 402dab3f910Sjsing case 0: 403dab3f910Sjsing str_details1 = ", ERROR:"; 404dab3f910Sjsing str_details2 = " ???"; 405dab3f910Sjsing if (len >= 3) { 406dab3f910Sjsing unsigned err = (((const unsigned char *) buf)[1] << 8) + ((const unsigned char *) buf)[2]; 407dab3f910Sjsing 408dab3f910Sjsing switch (err) { 409dab3f910Sjsing case 0x0001: 410dab3f910Sjsing str_details2 = " NO-CIPHER-ERROR"; 411dab3f910Sjsing break; 412dab3f910Sjsing case 0x0002: 413dab3f910Sjsing str_details2 = " NO-CERTIFICATE-ERROR"; 414dab3f910Sjsing break; 415dab3f910Sjsing case 0x0004: 416dab3f910Sjsing str_details2 = " BAD-CERTIFICATE-ERROR"; 417dab3f910Sjsing break; 418dab3f910Sjsing case 0x0006: 419dab3f910Sjsing str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR"; 420dab3f910Sjsing break; 421dab3f910Sjsing } 422dab3f910Sjsing } 423dab3f910Sjsing break; 424dab3f910Sjsing case 1: 425dab3f910Sjsing str_details1 = ", CLIENT-HELLO"; 426dab3f910Sjsing break; 427dab3f910Sjsing case 2: 428dab3f910Sjsing str_details1 = ", CLIENT-MASTER-KEY"; 429dab3f910Sjsing break; 430dab3f910Sjsing case 3: 431dab3f910Sjsing str_details1 = ", CLIENT-FINISHED"; 432dab3f910Sjsing break; 433dab3f910Sjsing case 4: 434dab3f910Sjsing str_details1 = ", SERVER-HELLO"; 435dab3f910Sjsing break; 436dab3f910Sjsing case 5: 437dab3f910Sjsing str_details1 = ", SERVER-VERIFY"; 438dab3f910Sjsing break; 439dab3f910Sjsing case 6: 440dab3f910Sjsing str_details1 = ", SERVER-FINISHED"; 441dab3f910Sjsing break; 442dab3f910Sjsing case 7: 443dab3f910Sjsing str_details1 = ", REQUEST-CERTIFICATE"; 444dab3f910Sjsing break; 445dab3f910Sjsing case 8: 446dab3f910Sjsing str_details1 = ", CLIENT-CERTIFICATE"; 447dab3f910Sjsing break; 448dab3f910Sjsing } 449dab3f910Sjsing } 450dab3f910Sjsing } 451dab3f910Sjsing if (version == SSL3_VERSION || version == TLS1_VERSION || 452dab3f910Sjsing version == TLS1_1_VERSION || version == TLS1_2_VERSION || 453e8cca36cSinoguchi version == TLS1_3_VERSION || version == DTLS1_VERSION || 454e8cca36cSinoguchi version == DTLS1_2_VERSION) { 45588411e53Stb /* XXX magic numbers are in ssl3.h */ 456dab3f910Sjsing switch (content_type) { 457dab3f910Sjsing case 20: 458dab3f910Sjsing str_content_type = "ChangeCipherSpec"; 459dab3f910Sjsing break; 460dab3f910Sjsing case 21: 461dab3f910Sjsing str_content_type = "Alert"; 462dab3f910Sjsing break; 463dab3f910Sjsing case 22: 464dab3f910Sjsing str_content_type = "Handshake"; 465dab3f910Sjsing break; 466dab3f910Sjsing } 467dab3f910Sjsing 468dab3f910Sjsing if (content_type == 21) { /* Alert */ 469dab3f910Sjsing str_details1 = ", ???"; 470dab3f910Sjsing 471dab3f910Sjsing if (len == 2) { 472dab3f910Sjsing switch (((const unsigned char *) buf)[0]) { 473dab3f910Sjsing case 1: 474dab3f910Sjsing str_details1 = ", warning"; 475dab3f910Sjsing break; 476dab3f910Sjsing case 2: 477dab3f910Sjsing str_details1 = ", fatal"; 478dab3f910Sjsing break; 479dab3f910Sjsing } 480dab3f910Sjsing 481dab3f910Sjsing str_details2 = " ???"; 482dab3f910Sjsing switch (((const unsigned char *) buf)[1]) { 483dab3f910Sjsing case 0: 484dab3f910Sjsing str_details2 = " close_notify"; 485dab3f910Sjsing break; 486dab3f910Sjsing case 10: 487dab3f910Sjsing str_details2 = " unexpected_message"; 488dab3f910Sjsing break; 489dab3f910Sjsing case 20: 490dab3f910Sjsing str_details2 = " bad_record_mac"; 491dab3f910Sjsing break; 492dab3f910Sjsing case 21: 493dab3f910Sjsing str_details2 = " decryption_failed"; 494dab3f910Sjsing break; 495dab3f910Sjsing case 22: 496dab3f910Sjsing str_details2 = " record_overflow"; 497dab3f910Sjsing break; 498dab3f910Sjsing case 30: 499dab3f910Sjsing str_details2 = " decompression_failure"; 500dab3f910Sjsing break; 501dab3f910Sjsing case 40: 502dab3f910Sjsing str_details2 = " handshake_failure"; 503dab3f910Sjsing break; 504dab3f910Sjsing case 42: 505dab3f910Sjsing str_details2 = " bad_certificate"; 506dab3f910Sjsing break; 507dab3f910Sjsing case 43: 508dab3f910Sjsing str_details2 = " unsupported_certificate"; 509dab3f910Sjsing break; 510dab3f910Sjsing case 44: 511dab3f910Sjsing str_details2 = " certificate_revoked"; 512dab3f910Sjsing break; 513dab3f910Sjsing case 45: 514dab3f910Sjsing str_details2 = " certificate_expired"; 515dab3f910Sjsing break; 516dab3f910Sjsing case 46: 517dab3f910Sjsing str_details2 = " certificate_unknown"; 518dab3f910Sjsing break; 519dab3f910Sjsing case 47: 520dab3f910Sjsing str_details2 = " illegal_parameter"; 521dab3f910Sjsing break; 522dab3f910Sjsing case 48: 523dab3f910Sjsing str_details2 = " unknown_ca"; 524dab3f910Sjsing break; 525dab3f910Sjsing case 49: 526dab3f910Sjsing str_details2 = " access_denied"; 527dab3f910Sjsing break; 528dab3f910Sjsing case 50: 529dab3f910Sjsing str_details2 = " decode_error"; 530dab3f910Sjsing break; 531dab3f910Sjsing case 51: 532dab3f910Sjsing str_details2 = " decrypt_error"; 533dab3f910Sjsing break; 534dab3f910Sjsing case 60: 535dab3f910Sjsing str_details2 = " export_restriction"; 536dab3f910Sjsing break; 537dab3f910Sjsing case 70: 538dab3f910Sjsing str_details2 = " protocol_version"; 539dab3f910Sjsing break; 540dab3f910Sjsing case 71: 541dab3f910Sjsing str_details2 = " insufficient_security"; 542dab3f910Sjsing break; 543dab3f910Sjsing case 80: 544dab3f910Sjsing str_details2 = " internal_error"; 545dab3f910Sjsing break; 546dab3f910Sjsing case 90: 547dab3f910Sjsing str_details2 = " user_canceled"; 548dab3f910Sjsing break; 549dab3f910Sjsing case 100: 550dab3f910Sjsing str_details2 = " no_renegotiation"; 551dab3f910Sjsing break; 552dab3f910Sjsing case 110: 553dab3f910Sjsing str_details2 = " unsupported_extension"; 554dab3f910Sjsing break; 555dab3f910Sjsing case 111: 556dab3f910Sjsing str_details2 = " certificate_unobtainable"; 557dab3f910Sjsing break; 558dab3f910Sjsing case 112: 559dab3f910Sjsing str_details2 = " unrecognized_name"; 560dab3f910Sjsing break; 561dab3f910Sjsing case 113: 562dab3f910Sjsing str_details2 = " bad_certificate_status_response"; 563dab3f910Sjsing break; 564dab3f910Sjsing case 114: 565dab3f910Sjsing str_details2 = " bad_certificate_hash_value"; 566dab3f910Sjsing break; 567dab3f910Sjsing case 115: 568dab3f910Sjsing str_details2 = " unknown_psk_identity"; 569dab3f910Sjsing break; 570dab3f910Sjsing } 571dab3f910Sjsing } 572dab3f910Sjsing } 573dab3f910Sjsing if (content_type == 22) { /* Handshake */ 574dab3f910Sjsing str_details1 = "???"; 575dab3f910Sjsing 576dab3f910Sjsing if (len > 0) { 577dab3f910Sjsing switch (((const unsigned char *) buf)[0]) { 578dab3f910Sjsing case 0: 579dab3f910Sjsing str_details1 = ", HelloRequest"; 580dab3f910Sjsing break; 581dab3f910Sjsing case 1: 582dab3f910Sjsing str_details1 = ", ClientHello"; 583dab3f910Sjsing break; 584dab3f910Sjsing case 2: 585dab3f910Sjsing str_details1 = ", ServerHello"; 586dab3f910Sjsing break; 587dab3f910Sjsing case 3: 588dab3f910Sjsing str_details1 = ", HelloVerifyRequest"; 589dab3f910Sjsing break; 590654e66e6Stb case 4: 591654e66e6Stb str_details1 = ", NewSessionTicket"; 592654e66e6Stb break; 593654e66e6Stb case 5: 594654e66e6Stb str_details1 = ", EndOfEarlyData"; 595654e66e6Stb break; 596654e66e6Stb case 8: 597654e66e6Stb str_details1 = ", EncryptedExtensions"; 598654e66e6Stb break; 599dab3f910Sjsing case 11: 600dab3f910Sjsing str_details1 = ", Certificate"; 601dab3f910Sjsing break; 602dab3f910Sjsing case 12: 603dab3f910Sjsing str_details1 = ", ServerKeyExchange"; 604dab3f910Sjsing break; 605dab3f910Sjsing case 13: 606dab3f910Sjsing str_details1 = ", CertificateRequest"; 607dab3f910Sjsing break; 608dab3f910Sjsing case 14: 609dab3f910Sjsing str_details1 = ", ServerHelloDone"; 610dab3f910Sjsing break; 611dab3f910Sjsing case 15: 612dab3f910Sjsing str_details1 = ", CertificateVerify"; 613dab3f910Sjsing break; 614dab3f910Sjsing case 16: 615dab3f910Sjsing str_details1 = ", ClientKeyExchange"; 616dab3f910Sjsing break; 617dab3f910Sjsing case 20: 618dab3f910Sjsing str_details1 = ", Finished"; 619dab3f910Sjsing break; 620654e66e6Stb case 24: 621654e66e6Stb str_details1 = ", KeyUpdate"; 622654e66e6Stb break; 623dab3f910Sjsing } 624dab3f910Sjsing } 625dab3f910Sjsing } 626dab3f910Sjsing } 627dab3f910Sjsing BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, 628dab3f910Sjsing str_version, str_content_type, (unsigned long) len, 629dab3f910Sjsing str_details1, str_details2); 630dab3f910Sjsing 631dab3f910Sjsing if (len > 0) { 632dab3f910Sjsing size_t num, i; 633dab3f910Sjsing 634dab3f910Sjsing BIO_printf(bio, " "); 635dab3f910Sjsing num = len; 636275363c2Sdoug 637dab3f910Sjsing for (i = 0; i < num; i++) { 638dab3f910Sjsing if (i % 16 == 0 && i > 0) 639dab3f910Sjsing BIO_printf(bio, "\n "); 640dab3f910Sjsing BIO_printf(bio, " %02x", 641dab3f910Sjsing ((const unsigned char *) buf)[i]); 642dab3f910Sjsing } 643dab3f910Sjsing if (i < len) 644dab3f910Sjsing BIO_printf(bio, " ..."); 645dab3f910Sjsing BIO_printf(bio, "\n"); 646dab3f910Sjsing } 647dab3f910Sjsing (void) BIO_flush(bio); 648dab3f910Sjsing } 649dab3f910Sjsing 650dab3f910Sjsing void 651dab3f910Sjsing tlsext_cb(SSL * s, int client_server, int type, unsigned char *data, int len, 652dab3f910Sjsing void *arg) 653dab3f910Sjsing { 654dab3f910Sjsing BIO *bio = arg; 655dab3f910Sjsing char *extname; 656dab3f910Sjsing 657dab3f910Sjsing switch (type) { 658dab3f910Sjsing case TLSEXT_TYPE_server_name: 659dab3f910Sjsing extname = "server name"; 660dab3f910Sjsing break; 661dab3f910Sjsing 662dab3f910Sjsing case TLSEXT_TYPE_max_fragment_length: 663dab3f910Sjsing extname = "max fragment length"; 664dab3f910Sjsing break; 665dab3f910Sjsing 666dab3f910Sjsing case TLSEXT_TYPE_client_certificate_url: 667dab3f910Sjsing extname = "client certificate URL"; 668dab3f910Sjsing break; 669dab3f910Sjsing 670dab3f910Sjsing case TLSEXT_TYPE_trusted_ca_keys: 671dab3f910Sjsing extname = "trusted CA keys"; 672dab3f910Sjsing break; 673dab3f910Sjsing 674dab3f910Sjsing case TLSEXT_TYPE_truncated_hmac: 675dab3f910Sjsing extname = "truncated HMAC"; 676dab3f910Sjsing break; 677dab3f910Sjsing 678dab3f910Sjsing case TLSEXT_TYPE_status_request: 679dab3f910Sjsing extname = "status request"; 680dab3f910Sjsing break; 681dab3f910Sjsing 682dab3f910Sjsing case TLSEXT_TYPE_user_mapping: 683dab3f910Sjsing extname = "user mapping"; 684dab3f910Sjsing break; 685dab3f910Sjsing 686dab3f910Sjsing case TLSEXT_TYPE_client_authz: 687dab3f910Sjsing extname = "client authz"; 688dab3f910Sjsing break; 689dab3f910Sjsing 690dab3f910Sjsing case TLSEXT_TYPE_server_authz: 691dab3f910Sjsing extname = "server authz"; 692dab3f910Sjsing break; 693dab3f910Sjsing 694dab3f910Sjsing case TLSEXT_TYPE_cert_type: 695dab3f910Sjsing extname = "cert type"; 696dab3f910Sjsing break; 697dab3f910Sjsing 69860717e0aSjsing case TLSEXT_TYPE_supported_groups: 69960717e0aSjsing extname = "supported groups"; 700dab3f910Sjsing break; 701dab3f910Sjsing 702dab3f910Sjsing case TLSEXT_TYPE_ec_point_formats: 703dab3f910Sjsing extname = "EC point formats"; 704dab3f910Sjsing break; 705dab3f910Sjsing 706dab3f910Sjsing case TLSEXT_TYPE_srp: 707dab3f910Sjsing extname = "SRP"; 708dab3f910Sjsing break; 709dab3f910Sjsing 710dab3f910Sjsing case TLSEXT_TYPE_signature_algorithms: 711dab3f910Sjsing extname = "signature algorithms"; 712dab3f910Sjsing break; 713dab3f910Sjsing 714dab3f910Sjsing case TLSEXT_TYPE_use_srtp: 715dab3f910Sjsing extname = "use SRTP"; 716dab3f910Sjsing break; 717dab3f910Sjsing 718dab3f910Sjsing case TLSEXT_TYPE_heartbeat: 719dab3f910Sjsing extname = "heartbeat"; 720dab3f910Sjsing break; 721dab3f910Sjsing 722afd7a2e1Sinoguchi case TLSEXT_TYPE_application_layer_protocol_negotiation: 723afd7a2e1Sinoguchi extname = "application layer protocol negotiation"; 724afd7a2e1Sinoguchi break; 725afd7a2e1Sinoguchi 726afd7a2e1Sinoguchi case TLSEXT_TYPE_padding: 727afd7a2e1Sinoguchi extname = "TLS padding"; 728afd7a2e1Sinoguchi break; 729afd7a2e1Sinoguchi 730e14d36e1Sinoguchi case TLSEXT_TYPE_session_ticket: 731e14d36e1Sinoguchi extname = "session ticket"; 732e14d36e1Sinoguchi break; 733e14d36e1Sinoguchi 734e14d36e1Sinoguchi #if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL) 735e14d36e1Sinoguchi case TLSEXT_TYPE_pre_shared_key: 736e14d36e1Sinoguchi extname = "pre shared key"; 737e14d36e1Sinoguchi break; 738e14d36e1Sinoguchi 739e14d36e1Sinoguchi case TLSEXT_TYPE_early_data: 740e14d36e1Sinoguchi extname = "early data"; 741e14d36e1Sinoguchi break; 742e14d36e1Sinoguchi 743e14d36e1Sinoguchi case TLSEXT_TYPE_supported_versions: 744e14d36e1Sinoguchi extname = "supported versions"; 745e14d36e1Sinoguchi break; 746e14d36e1Sinoguchi 747e14d36e1Sinoguchi case TLSEXT_TYPE_cookie: 748e14d36e1Sinoguchi extname = "cookie"; 749e14d36e1Sinoguchi break; 750e14d36e1Sinoguchi 751e14d36e1Sinoguchi case TLSEXT_TYPE_psk_key_exchange_modes: 752e14d36e1Sinoguchi extname = "PSK key exchange modes"; 753e14d36e1Sinoguchi break; 754e14d36e1Sinoguchi 755e14d36e1Sinoguchi case TLSEXT_TYPE_certificate_authorities: 756e14d36e1Sinoguchi extname = "certificate authorities"; 757e14d36e1Sinoguchi break; 758e14d36e1Sinoguchi 759e14d36e1Sinoguchi case TLSEXT_TYPE_oid_filters: 760e14d36e1Sinoguchi extname = "OID filters"; 761e14d36e1Sinoguchi break; 762e14d36e1Sinoguchi 763e14d36e1Sinoguchi case TLSEXT_TYPE_post_handshake_auth: 764e14d36e1Sinoguchi extname = "post handshake auth"; 765e14d36e1Sinoguchi break; 766e14d36e1Sinoguchi 767e14d36e1Sinoguchi case TLSEXT_TYPE_signature_algorithms_cert: 768e14d36e1Sinoguchi extname = "signature algorithms cert"; 769e14d36e1Sinoguchi break; 770e14d36e1Sinoguchi 771e14d36e1Sinoguchi case TLSEXT_TYPE_key_share: 772e14d36e1Sinoguchi extname = "key share"; 773e14d36e1Sinoguchi break; 774e14d36e1Sinoguchi #endif 775e14d36e1Sinoguchi 776e14d36e1Sinoguchi case TLSEXT_TYPE_renegotiate: 777e14d36e1Sinoguchi extname = "renegotiation info"; 778e14d36e1Sinoguchi break; 779e14d36e1Sinoguchi 780dab3f910Sjsing default: 781dab3f910Sjsing extname = "unknown"; 782dab3f910Sjsing break; 783dab3f910Sjsing 784dab3f910Sjsing } 785dab3f910Sjsing 786dab3f910Sjsing BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", 787dab3f910Sjsing client_server ? "server" : "client", extname, type, len); 788dab3f910Sjsing BIO_dump(bio, (char *) data, len); 789dab3f910Sjsing (void) BIO_flush(bio); 790dab3f910Sjsing } 791dab3f910Sjsing 792dab3f910Sjsing int 793dab3f910Sjsing generate_cookie_callback(SSL * ssl, unsigned char *cookie, 794dab3f910Sjsing unsigned int *cookie_len) 795dab3f910Sjsing { 796dab3f910Sjsing unsigned char *buffer, result[EVP_MAX_MD_SIZE]; 797dab3f910Sjsing unsigned int length, resultlength; 798dab3f910Sjsing union { 799dab3f910Sjsing struct sockaddr sa; 800dab3f910Sjsing struct sockaddr_in s4; 801dab3f910Sjsing struct sockaddr_in6 s6; 802dab3f910Sjsing } peer; 803dab3f910Sjsing 804dab3f910Sjsing /* Initialize a random secret */ 805dab3f910Sjsing if (!cookie_initialized) { 806fd6ab616Sjsing arc4random_buf(cookie_secret, COOKIE_SECRET_LENGTH); 807dab3f910Sjsing cookie_initialized = 1; 808dab3f910Sjsing } 809dab3f910Sjsing /* Read peer information */ 810dab3f910Sjsing (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); 811dab3f910Sjsing 812dab3f910Sjsing /* Create buffer with peer's address and port */ 813dab3f910Sjsing length = 0; 814dab3f910Sjsing switch (peer.sa.sa_family) { 815dab3f910Sjsing case AF_INET: 816dab3f910Sjsing length += sizeof(struct in_addr); 817dab3f910Sjsing length += sizeof(peer.s4.sin_port); 818dab3f910Sjsing break; 819dab3f910Sjsing case AF_INET6: 820dab3f910Sjsing length += sizeof(struct in6_addr); 821dab3f910Sjsing length += sizeof(peer.s6.sin6_port); 822dab3f910Sjsing break; 823dab3f910Sjsing default: 824dab3f910Sjsing OPENSSL_assert(0); 825dab3f910Sjsing break; 826dab3f910Sjsing } 827dab3f910Sjsing buffer = malloc(length); 828dab3f910Sjsing 829dab3f910Sjsing if (buffer == NULL) { 830dab3f910Sjsing BIO_printf(bio_err, "out of memory\n"); 831dab3f910Sjsing return 0; 832dab3f910Sjsing } 833dab3f910Sjsing switch (peer.sa.sa_family) { 834dab3f910Sjsing case AF_INET: 835dab3f910Sjsing memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); 836dab3f910Sjsing memcpy(buffer + sizeof(peer.s4.sin_port), 837dab3f910Sjsing &peer.s4.sin_addr, sizeof(struct in_addr)); 838dab3f910Sjsing break; 839dab3f910Sjsing case AF_INET6: 840dab3f910Sjsing memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); 841dab3f910Sjsing memcpy(buffer + sizeof(peer.s6.sin6_port), 842dab3f910Sjsing &peer.s6.sin6_addr, sizeof(struct in6_addr)); 843dab3f910Sjsing break; 844dab3f910Sjsing default: 845dab3f910Sjsing OPENSSL_assert(0); 846dab3f910Sjsing break; 847dab3f910Sjsing } 848dab3f910Sjsing 849dab3f910Sjsing /* Calculate HMAC of buffer using the secret */ 850dab3f910Sjsing HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, 851dab3f910Sjsing buffer, length, result, &resultlength); 852dab3f910Sjsing free(buffer); 853dab3f910Sjsing 854dab3f910Sjsing memcpy(cookie, result, resultlength); 855dab3f910Sjsing *cookie_len = resultlength; 856dab3f910Sjsing 857dab3f910Sjsing return 1; 858dab3f910Sjsing } 859dab3f910Sjsing 860dab3f910Sjsing int 8611524e5e0Stb verify_cookie_callback(SSL * ssl, const unsigned char *cookie, 8621524e5e0Stb unsigned int cookie_len) 863dab3f910Sjsing { 864dab3f910Sjsing unsigned char *buffer, result[EVP_MAX_MD_SIZE]; 865dab3f910Sjsing unsigned int length, resultlength; 866dab3f910Sjsing union { 867dab3f910Sjsing struct sockaddr sa; 868dab3f910Sjsing struct sockaddr_in s4; 869dab3f910Sjsing struct sockaddr_in6 s6; 870dab3f910Sjsing } peer; 871dab3f910Sjsing 872dab3f910Sjsing /* If secret isn't initialized yet, the cookie can't be valid */ 873dab3f910Sjsing if (!cookie_initialized) 874dab3f910Sjsing return 0; 875dab3f910Sjsing 876dab3f910Sjsing /* Read peer information */ 877dab3f910Sjsing (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); 878dab3f910Sjsing 879dab3f910Sjsing /* Create buffer with peer's address and port */ 880dab3f910Sjsing length = 0; 881dab3f910Sjsing switch (peer.sa.sa_family) { 882dab3f910Sjsing case AF_INET: 883dab3f910Sjsing length += sizeof(struct in_addr); 884dab3f910Sjsing length += sizeof(peer.s4.sin_port); 885dab3f910Sjsing break; 886dab3f910Sjsing case AF_INET6: 887dab3f910Sjsing length += sizeof(struct in6_addr); 888dab3f910Sjsing length += sizeof(peer.s6.sin6_port); 889dab3f910Sjsing break; 890dab3f910Sjsing default: 891dab3f910Sjsing OPENSSL_assert(0); 892dab3f910Sjsing break; 893dab3f910Sjsing } 894dab3f910Sjsing buffer = malloc(length); 895dab3f910Sjsing 896dab3f910Sjsing if (buffer == NULL) { 897dab3f910Sjsing BIO_printf(bio_err, "out of memory\n"); 898dab3f910Sjsing return 0; 899dab3f910Sjsing } 900dab3f910Sjsing switch (peer.sa.sa_family) { 901dab3f910Sjsing case AF_INET: 902dab3f910Sjsing memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); 903dab3f910Sjsing memcpy(buffer + sizeof(peer.s4.sin_port), 904dab3f910Sjsing &peer.s4.sin_addr, sizeof(struct in_addr)); 905dab3f910Sjsing break; 906dab3f910Sjsing case AF_INET6: 907dab3f910Sjsing memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); 908dab3f910Sjsing memcpy(buffer + sizeof(peer.s6.sin6_port), 909dab3f910Sjsing &peer.s6.sin6_addr, sizeof(struct in6_addr)); 910dab3f910Sjsing break; 911dab3f910Sjsing default: 912dab3f910Sjsing OPENSSL_assert(0); 913dab3f910Sjsing break; 914dab3f910Sjsing } 915dab3f910Sjsing 916dab3f910Sjsing /* Calculate HMAC of buffer using the secret */ 9175aef4460Stb if (HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, 9185aef4460Stb buffer, length, result, &resultlength) == NULL) { 9195aef4460Stb free(buffer); 9205aef4460Stb return 0; 9215aef4460Stb } 9225aef4460Stb 923dab3f910Sjsing free(buffer); 924dab3f910Sjsing 925dab3f910Sjsing if (cookie_len == resultlength && 926dab3f910Sjsing memcmp(result, cookie, resultlength) == 0) 927dab3f910Sjsing return 1; 928dab3f910Sjsing 929dab3f910Sjsing return 0; 930dab3f910Sjsing } 931