[BACK]Return to s_cb.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / openssl

Annotation of src/usr.bin/openssl/s_cb.c, Revision 1.1

1.1     ! jsing       1: /* $OpenBSD: s_cb.c,v 1.22 2014/06/13 04:29:13 miod 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: }