159191Skris/* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8280304Sjkim *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15280304Sjkim *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22280304Sjkim *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40280304Sjkim *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52280304Sjkim *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
58109998Smarkm/* ====================================================================
59238405Sjkim * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60109998Smarkm *
61109998Smarkm * Redistribution and use in source and binary forms, with or without
62109998Smarkm * modification, are permitted provided that the following conditions
63109998Smarkm * are met:
64109998Smarkm *
65109998Smarkm * 1. Redistributions of source code must retain the above copyright
66280304Sjkim *    notice, this list of conditions and the following disclaimer.
67109998Smarkm *
68109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright
69109998Smarkm *    notice, this list of conditions and the following disclaimer in
70109998Smarkm *    the documentation and/or other materials provided with the
71109998Smarkm *    distribution.
72109998Smarkm *
73109998Smarkm * 3. All advertising materials mentioning features or use of this
74109998Smarkm *    software must display the following acknowledgment:
75109998Smarkm *    "This product includes software developed by the OpenSSL Project
76109998Smarkm *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77109998Smarkm *
78109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79109998Smarkm *    endorse or promote products derived from this software without
80109998Smarkm *    prior written permission. For written permission, please contact
81109998Smarkm *    openssl-core@openssl.org.
82109998Smarkm *
83109998Smarkm * 5. Products derived from this software may not be called "OpenSSL"
84109998Smarkm *    nor may "OpenSSL" appear in their names without prior written
85109998Smarkm *    permission of the OpenSSL Project.
86109998Smarkm *
87109998Smarkm * 6. Redistributions of any form whatsoever must retain the following
88109998Smarkm *    acknowledgment:
89109998Smarkm *    "This product includes software developed by the OpenSSL Project
90109998Smarkm *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91109998Smarkm *
92109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95109998Smarkm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE.
104109998Smarkm * ====================================================================
105109998Smarkm *
106109998Smarkm * This product includes cryptographic software written by Eric Young
107109998Smarkm * (eay@cryptsoft.com).  This product includes software written by Tim
108109998Smarkm * Hudson (tjh@cryptsoft.com).
109109998Smarkm *
110109998Smarkm */
11155714Skris
11255714Skris#include <stdio.h>
11355714Skris#include <stdlib.h>
114284285Sjkim#include <string.h> /* for memcpy() */
11555714Skris#define USE_SOCKETS
11655714Skris#define NON_MAIN
11755714Skris#include "apps.h"
11855714Skris#undef NON_MAIN
11955714Skris#undef USE_SOCKETS
12055714Skris#include <openssl/err.h>
121205128Ssimon#include <openssl/rand.h>
12255714Skris#include <openssl/x509.h>
12355714Skris#include <openssl/ssl.h>
12455714Skris#include "s_apps.h"
12555714Skris
126280304Sjkim#define COOKIE_SECRET_LENGTH    16
127205128Ssimon
128280304Sjkimint verify_depth = 0;
129280304Sjkimint verify_error = X509_V_OK;
130280304Sjkimint verify_return_error = 0;
131205128Ssimonunsigned char cookie_secret[COOKIE_SECRET_LENGTH];
132280304Sjkimint cookie_initialized = 0;
13355714Skris
13455714Skrisint MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
135280304Sjkim{
136280304Sjkim    X509 *err_cert;
137280304Sjkim    int err, depth;
13855714Skris
139280304Sjkim    err_cert = X509_STORE_CTX_get_current_cert(ctx);
140280304Sjkim    err = X509_STORE_CTX_get_error(ctx);
141280304Sjkim    depth = X509_STORE_CTX_get_error_depth(ctx);
14255714Skris
143280304Sjkim    BIO_printf(bio_err, "depth=%d ", depth);
144280304Sjkim    if (err_cert) {
145280304Sjkim        X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
146280304Sjkim                           0, XN_FLAG_ONELINE);
147280304Sjkim        BIO_puts(bio_err, "\n");
148280304Sjkim    } else
149280304Sjkim        BIO_puts(bio_err, "<no cert>\n");
150280304Sjkim    if (!ok) {
151280304Sjkim        BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
152280304Sjkim                   X509_verify_cert_error_string(err));
153280304Sjkim        if (verify_depth >= depth) {
154280304Sjkim            if (!verify_return_error)
155280304Sjkim                ok = 1;
156280304Sjkim            verify_error = X509_V_OK;
157280304Sjkim        } else {
158280304Sjkim            ok = 0;
159280304Sjkim            verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
160280304Sjkim        }
161280304Sjkim    }
162280304Sjkim    switch (err) {
163280304Sjkim    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
164280304Sjkim        BIO_puts(bio_err, "issuer= ");
165280304Sjkim        X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
166280304Sjkim                           0, XN_FLAG_ONELINE);
167280304Sjkim        BIO_puts(bio_err, "\n");
168280304Sjkim        break;
169280304Sjkim    case X509_V_ERR_CERT_NOT_YET_VALID:
170280304Sjkim    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
171280304Sjkim        BIO_printf(bio_err, "notBefore=");
172280304Sjkim        ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert));
173280304Sjkim        BIO_printf(bio_err, "\n");
174280304Sjkim        break;
175280304Sjkim    case X509_V_ERR_CERT_HAS_EXPIRED:
176280304Sjkim    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
177280304Sjkim        BIO_printf(bio_err, "notAfter=");
178280304Sjkim        ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert));
179280304Sjkim        BIO_printf(bio_err, "\n");
180280304Sjkim        break;
181280304Sjkim    case X509_V_ERR_NO_EXPLICIT_POLICY:
182280304Sjkim        policies_print(bio_err, ctx);
183280304Sjkim        break;
184280304Sjkim    }
185280304Sjkim    if (err == X509_V_OK && ok == 2)
186280304Sjkim        policies_print(bio_err, ctx);
187238405Sjkim
188280304Sjkim    BIO_printf(bio_err, "verify return:%d\n", ok);
189280304Sjkim    return (ok);
190280304Sjkim}
19155714Skris
19255714Skrisint set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
193280304Sjkim{
194280304Sjkim    if (cert_file != NULL) {
195280304Sjkim        /*-
196280304Sjkim        SSL *ssl;
197280304Sjkim        X509 *x509;
198280304Sjkim        */
19955714Skris
200280304Sjkim        if (SSL_CTX_use_certificate_file(ctx, cert_file,
201280304Sjkim                                         SSL_FILETYPE_PEM) <= 0) {
202280304Sjkim            BIO_printf(bio_err, "unable to get certificate from '%s'\n",
203280304Sjkim                       cert_file);
204280304Sjkim            ERR_print_errors(bio_err);
205280304Sjkim            return (0);
206280304Sjkim        }
207280304Sjkim        if (key_file == NULL)
208280304Sjkim            key_file = cert_file;
209280304Sjkim        if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
210280304Sjkim            BIO_printf(bio_err, "unable to get private key from '%s'\n",
211280304Sjkim                       key_file);
212280304Sjkim            ERR_print_errors(bio_err);
213280304Sjkim            return (0);
214280304Sjkim        }
21555714Skris
216280304Sjkim        /*-
217280304Sjkim        In theory this is no longer needed
218280304Sjkim        ssl=SSL_new(ctx);
219280304Sjkim        x509=SSL_get_certificate(ssl);
22055714Skris
221280304Sjkim        if (x509 != NULL) {
222280304Sjkim                EVP_PKEY *pktmp;
223280304Sjkim                pktmp = X509_get_pubkey(x509);
224280304Sjkim                EVP_PKEY_copy_parameters(pktmp,
225280304Sjkim                                        SSL_get_privatekey(ssl));
226280304Sjkim                EVP_PKEY_free(pktmp);
227280304Sjkim        }
228280304Sjkim        SSL_free(ssl);
229280304Sjkim        */
23055714Skris
231280304Sjkim        /*
232280304Sjkim         * If we are using DSA, we can copy the parameters from the private
233280304Sjkim         * key
234280304Sjkim         */
235246772Sjkim
236280304Sjkim        /*
237280304Sjkim         * Now we know that a key and cert have been set against the SSL
238280304Sjkim         * context
239280304Sjkim         */
240280304Sjkim        if (!SSL_CTX_check_private_key(ctx)) {
241280304Sjkim            BIO_printf(bio_err,
242280304Sjkim                       "Private key does not match the certificate public key\n");
243280304Sjkim            return (0);
244280304Sjkim        }
245280304Sjkim    }
246280304Sjkim    return (1);
247280304Sjkim}
248246772Sjkim
249160814Ssimonint set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key)
250280304Sjkim{
251280304Sjkim    if (cert == NULL)
252280304Sjkim        return 1;
253280304Sjkim    if (SSL_CTX_use_certificate(ctx, cert) <= 0) {
254280304Sjkim        BIO_printf(bio_err, "error setting certificate\n");
255280304Sjkim        ERR_print_errors(bio_err);
256280304Sjkim        return 0;
257280304Sjkim    }
258280304Sjkim    if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) {
259280304Sjkim        BIO_printf(bio_err, "error setting private key\n");
260280304Sjkim        ERR_print_errors(bio_err);
261280304Sjkim        return 0;
262280304Sjkim    }
263160814Ssimon
264280304Sjkim    /*
265280304Sjkim     * Now we know that a key and cert have been set against the SSL context
266280304Sjkim     */
267280304Sjkim    if (!SSL_CTX_check_private_key(ctx)) {
268280304Sjkim        BIO_printf(bio_err,
269280304Sjkim                   "Private key does not match the certificate public key\n");
270280304Sjkim        return 0;
271280304Sjkim    }
272280304Sjkim    return 1;
273280304Sjkim}
274160814Ssimon
275160814Ssimonlong MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
276280304Sjkim                                   int argi, long argl, long ret)
277280304Sjkim{
278280304Sjkim    BIO *out;
27955714Skris
280280304Sjkim    out = (BIO *)BIO_get_callback_arg(bio);
281280304Sjkim    if (out == NULL)
282280304Sjkim        return (ret);
28355714Skris
284280304Sjkim    if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
285280304Sjkim        BIO_printf(out, "read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
286280304Sjkim                   (void *)bio, argp, (unsigned long)argi, ret, ret);
287280304Sjkim        BIO_dump(out, argp, (int)ret);
288280304Sjkim        return (ret);
289280304Sjkim    } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
290280304Sjkim        BIO_printf(out, "write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
291280304Sjkim                   (void *)bio, argp, (unsigned long)argi, ret, ret);
292280304Sjkim        BIO_dump(out, argp, (int)ret);
293280304Sjkim    }
294280304Sjkim    return (ret);
295280304Sjkim}
29655714Skris
297109998Smarkmvoid MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret)
298280304Sjkim{
299280304Sjkim    const char *str;
300280304Sjkim    int w;
30155714Skris
302280304Sjkim    w = where & ~SSL_ST_MASK;
30355714Skris
304280304Sjkim    if (w & SSL_ST_CONNECT)
305280304Sjkim        str = "SSL_connect";
306280304Sjkim    else if (w & SSL_ST_ACCEPT)
307280304Sjkim        str = "SSL_accept";
308280304Sjkim    else
309280304Sjkim        str = "undefined";
31055714Skris
311280304Sjkim    if (where & SSL_CB_LOOP) {
312280304Sjkim        BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s));
313280304Sjkim    } else if (where & SSL_CB_ALERT) {
314280304Sjkim        str = (where & SSL_CB_READ) ? "read" : "write";
315280304Sjkim        BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n",
316280304Sjkim                   str,
317280304Sjkim                   SSL_alert_type_string_long(ret),
318280304Sjkim                   SSL_alert_desc_string_long(ret));
319280304Sjkim    } else if (where & SSL_CB_EXIT) {
320280304Sjkim        if (ret == 0)
321280304Sjkim            BIO_printf(bio_err, "%s:failed in %s\n",
322280304Sjkim                       str, SSL_state_string_long(s));
323280304Sjkim        else if (ret < 0) {
324280304Sjkim            BIO_printf(bio_err, "%s:error in %s\n",
325280304Sjkim                       str, SSL_state_string_long(s));
326280304Sjkim        }
327280304Sjkim    }
328280304Sjkim}
32955714Skris
330280304Sjkimvoid MS_CALLBACK msg_cb(int write_p, int version, int content_type,
331280304Sjkim                        const void *buf, size_t len, SSL *ssl, void *arg)
332280304Sjkim{
333280304Sjkim    BIO *bio = arg;
334280304Sjkim    const char *str_write_p, *str_version, *str_content_type =
335280304Sjkim        "", *str_details1 = "", *str_details2 = "";
336109998Smarkm
337280304Sjkim    str_write_p = write_p ? ">>>" : "<<<";
338109998Smarkm
339280304Sjkim    switch (version) {
340280304Sjkim    case SSL2_VERSION:
341280304Sjkim        str_version = "SSL 2.0";
342280304Sjkim        break;
343280304Sjkim    case SSL3_VERSION:
344280304Sjkim        str_version = "SSL 3.0 ";
345280304Sjkim        break;
346280304Sjkim    case TLS1_VERSION:
347280304Sjkim        str_version = "TLS 1.0 ";
348280304Sjkim        break;
349280304Sjkim    case TLS1_1_VERSION:
350280304Sjkim        str_version = "TLS 1.1 ";
351280304Sjkim        break;
352280304Sjkim    case TLS1_2_VERSION:
353280304Sjkim        str_version = "TLS 1.2 ";
354280304Sjkim        break;
355280304Sjkim    case DTLS1_VERSION:
356280304Sjkim        str_version = "DTLS 1.0 ";
357280304Sjkim        break;
358280304Sjkim    case DTLS1_BAD_VER:
359280304Sjkim        str_version = "DTLS 1.0 (bad) ";
360280304Sjkim        break;
361280304Sjkim    default:
362280304Sjkim        str_version = "???";
363280304Sjkim    }
364109998Smarkm
365280304Sjkim    if (version == SSL2_VERSION) {
366280304Sjkim        str_details1 = "???";
367109998Smarkm
368280304Sjkim        if (len > 0) {
369280304Sjkim            switch (((const unsigned char *)buf)[0]) {
370280304Sjkim            case 0:
371280304Sjkim                str_details1 = ", ERROR:";
372280304Sjkim                str_details2 = " ???";
373280304Sjkim                if (len >= 3) {
374280304Sjkim                    unsigned err =
375280304Sjkim                        (((const unsigned char *)buf)[1] << 8) +
376280304Sjkim                        ((const unsigned char *)buf)[2];
377109998Smarkm
378280304Sjkim                    switch (err) {
379280304Sjkim                    case 0x0001:
380280304Sjkim                        str_details2 = " NO-CIPHER-ERROR";
381280304Sjkim                        break;
382280304Sjkim                    case 0x0002:
383280304Sjkim                        str_details2 = " NO-CERTIFICATE-ERROR";
384280304Sjkim                        break;
385280304Sjkim                    case 0x0004:
386280304Sjkim                        str_details2 = " BAD-CERTIFICATE-ERROR";
387280304Sjkim                        break;
388280304Sjkim                    case 0x0006:
389280304Sjkim                        str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
390280304Sjkim                        break;
391280304Sjkim                    }
392280304Sjkim                }
393109998Smarkm
394280304Sjkim                break;
395280304Sjkim            case 1:
396280304Sjkim                str_details1 = ", CLIENT-HELLO";
397280304Sjkim                break;
398280304Sjkim            case 2:
399280304Sjkim                str_details1 = ", CLIENT-MASTER-KEY";
400280304Sjkim                break;
401280304Sjkim            case 3:
402280304Sjkim                str_details1 = ", CLIENT-FINISHED";
403280304Sjkim                break;
404280304Sjkim            case 4:
405280304Sjkim                str_details1 = ", SERVER-HELLO";
406280304Sjkim                break;
407280304Sjkim            case 5:
408280304Sjkim                str_details1 = ", SERVER-VERIFY";
409280304Sjkim                break;
410280304Sjkim            case 6:
411280304Sjkim                str_details1 = ", SERVER-FINISHED";
412280304Sjkim                break;
413280304Sjkim            case 7:
414280304Sjkim                str_details1 = ", REQUEST-CERTIFICATE";
415280304Sjkim                break;
416280304Sjkim            case 8:
417280304Sjkim                str_details1 = ", CLIENT-CERTIFICATE";
418280304Sjkim                break;
419280304Sjkim            }
420280304Sjkim        }
421280304Sjkim    }
422109998Smarkm
423280304Sjkim    if (version == SSL3_VERSION ||
424280304Sjkim        version == TLS1_VERSION ||
425280304Sjkim        version == TLS1_1_VERSION ||
426280304Sjkim        version == TLS1_2_VERSION ||
427280304Sjkim        version == DTLS1_VERSION || version == DTLS1_BAD_VER) {
428280304Sjkim        switch (content_type) {
429280304Sjkim        case 20:
430280304Sjkim            str_content_type = "ChangeCipherSpec";
431280304Sjkim            break;
432280304Sjkim        case 21:
433280304Sjkim            str_content_type = "Alert";
434280304Sjkim            break;
435280304Sjkim        case 22:
436280304Sjkim            str_content_type = "Handshake";
437280304Sjkim            break;
438280304Sjkim        }
439109998Smarkm
440280304Sjkim        if (content_type == 21) { /* Alert */
441280304Sjkim            str_details1 = ", ???";
442109998Smarkm
443280304Sjkim            if (len == 2) {
444280304Sjkim                switch (((const unsigned char *)buf)[0]) {
445280304Sjkim                case 1:
446280304Sjkim                    str_details1 = ", warning";
447280304Sjkim                    break;
448280304Sjkim                case 2:
449280304Sjkim                    str_details1 = ", fatal";
450280304Sjkim                    break;
451280304Sjkim                }
452238405Sjkim
453280304Sjkim                str_details2 = " ???";
454280304Sjkim                switch (((const unsigned char *)buf)[1]) {
455280304Sjkim                case 0:
456280304Sjkim                    str_details2 = " close_notify";
457280304Sjkim                    break;
458280304Sjkim                case 10:
459280304Sjkim                    str_details2 = " unexpected_message";
460280304Sjkim                    break;
461280304Sjkim                case 20:
462280304Sjkim                    str_details2 = " bad_record_mac";
463280304Sjkim                    break;
464280304Sjkim                case 21:
465280304Sjkim                    str_details2 = " decryption_failed";
466280304Sjkim                    break;
467280304Sjkim                case 22:
468280304Sjkim                    str_details2 = " record_overflow";
469280304Sjkim                    break;
470280304Sjkim                case 30:
471280304Sjkim                    str_details2 = " decompression_failure";
472280304Sjkim                    break;
473280304Sjkim                case 40:
474280304Sjkim                    str_details2 = " handshake_failure";
475280304Sjkim                    break;
476280304Sjkim                case 42:
477280304Sjkim                    str_details2 = " bad_certificate";
478280304Sjkim                    break;
479280304Sjkim                case 43:
480280304Sjkim                    str_details2 = " unsupported_certificate";
481280304Sjkim                    break;
482280304Sjkim                case 44:
483280304Sjkim                    str_details2 = " certificate_revoked";
484280304Sjkim                    break;
485280304Sjkim                case 45:
486280304Sjkim                    str_details2 = " certificate_expired";
487280304Sjkim                    break;
488280304Sjkim                case 46:
489280304Sjkim                    str_details2 = " certificate_unknown";
490280304Sjkim                    break;
491280304Sjkim                case 47:
492280304Sjkim                    str_details2 = " illegal_parameter";
493280304Sjkim                    break;
494280304Sjkim                case 48:
495280304Sjkim                    str_details2 = " unknown_ca";
496280304Sjkim                    break;
497280304Sjkim                case 49:
498280304Sjkim                    str_details2 = " access_denied";
499280304Sjkim                    break;
500280304Sjkim                case 50:
501280304Sjkim                    str_details2 = " decode_error";
502280304Sjkim                    break;
503280304Sjkim                case 51:
504280304Sjkim                    str_details2 = " decrypt_error";
505280304Sjkim                    break;
506280304Sjkim                case 60:
507280304Sjkim                    str_details2 = " export_restriction";
508280304Sjkim                    break;
509280304Sjkim                case 70:
510280304Sjkim                    str_details2 = " protocol_version";
511280304Sjkim                    break;
512280304Sjkim                case 71:
513280304Sjkim                    str_details2 = " insufficient_security";
514280304Sjkim                    break;
515280304Sjkim                case 80:
516280304Sjkim                    str_details2 = " internal_error";
517280304Sjkim                    break;
518280304Sjkim                case 90:
519280304Sjkim                    str_details2 = " user_canceled";
520280304Sjkim                    break;
521280304Sjkim                case 100:
522280304Sjkim                    str_details2 = " no_renegotiation";
523280304Sjkim                    break;
524280304Sjkim                case 110:
525280304Sjkim                    str_details2 = " unsupported_extension";
526280304Sjkim                    break;
527280304Sjkim                case 111:
528280304Sjkim                    str_details2 = " certificate_unobtainable";
529280304Sjkim                    break;
530280304Sjkim                case 112:
531280304Sjkim                    str_details2 = " unrecognized_name";
532280304Sjkim                    break;
533280304Sjkim                case 113:
534280304Sjkim                    str_details2 = " bad_certificate_status_response";
535280304Sjkim                    break;
536280304Sjkim                case 114:
537280304Sjkim                    str_details2 = " bad_certificate_hash_value";
538280304Sjkim                    break;
539280304Sjkim                case 115:
540280304Sjkim                    str_details2 = " unknown_psk_identity";
541280304Sjkim                    break;
542280304Sjkim                }
543280304Sjkim            }
544280304Sjkim        }
545280304Sjkim
546280304Sjkim        if (content_type == 22) { /* Handshake */
547280304Sjkim            str_details1 = "???";
548280304Sjkim
549280304Sjkim            if (len > 0) {
550280304Sjkim                switch (((const unsigned char *)buf)[0]) {
551280304Sjkim                case 0:
552280304Sjkim                    str_details1 = ", HelloRequest";
553280304Sjkim                    break;
554280304Sjkim                case 1:
555280304Sjkim                    str_details1 = ", ClientHello";
556280304Sjkim                    break;
557280304Sjkim                case 2:
558280304Sjkim                    str_details1 = ", ServerHello";
559280304Sjkim                    break;
560280304Sjkim                case 3:
561280304Sjkim                    str_details1 = ", HelloVerifyRequest";
562280304Sjkim                    break;
563280304Sjkim                case 11:
564280304Sjkim                    str_details1 = ", Certificate";
565280304Sjkim                    break;
566280304Sjkim                case 12:
567280304Sjkim                    str_details1 = ", ServerKeyExchange";
568280304Sjkim                    break;
569280304Sjkim                case 13:
570280304Sjkim                    str_details1 = ", CertificateRequest";
571280304Sjkim                    break;
572280304Sjkim                case 14:
573280304Sjkim                    str_details1 = ", ServerHelloDone";
574280304Sjkim                    break;
575280304Sjkim                case 15:
576280304Sjkim                    str_details1 = ", CertificateVerify";
577280304Sjkim                    break;
578280304Sjkim                case 16:
579280304Sjkim                    str_details1 = ", ClientKeyExchange";
580280304Sjkim                    break;
581280304Sjkim                case 20:
582280304Sjkim                    str_details1 = ", Finished";
583280304Sjkim                    break;
584280304Sjkim                }
585280304Sjkim            }
586280304Sjkim        }
587238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS
588280304Sjkim        if (content_type == 24) { /* Heartbeat */
589280304Sjkim            str_details1 = ", Heartbeat";
590280304Sjkim
591280304Sjkim            if (len > 0) {
592280304Sjkim                switch (((const unsigned char *)buf)[0]) {
593280304Sjkim                case 1:
594280304Sjkim                    str_details1 = ", HeartbeatRequest";
595280304Sjkim                    break;
596280304Sjkim                case 2:
597280304Sjkim                    str_details1 = ", HeartbeatResponse";
598280304Sjkim                    break;
599280304Sjkim                }
600280304Sjkim            }
601280304Sjkim        }
602238405Sjkim#endif
603280304Sjkim    }
604109998Smarkm
605280304Sjkim    BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version,
606280304Sjkim               str_content_type, (unsigned long)len, str_details1,
607280304Sjkim               str_details2);
608109998Smarkm
609280304Sjkim    if (len > 0) {
610280304Sjkim        size_t num, i;
611280304Sjkim
612280304Sjkim        BIO_printf(bio, "   ");
613280304Sjkim        num = len;
614109998Smarkm#if 0
615280304Sjkim        if (num > 16)
616280304Sjkim            num = 16;
617109998Smarkm#endif
618280304Sjkim        for (i = 0; i < num; i++) {
619280304Sjkim            if (i % 16 == 0 && i > 0)
620280304Sjkim                BIO_printf(bio, "\n   ");
621280304Sjkim            BIO_printf(bio, " %02x", ((const unsigned char *)buf)[i]);
622280304Sjkim        }
623280304Sjkim        if (i < len)
624280304Sjkim            BIO_printf(bio, " ...");
625280304Sjkim        BIO_printf(bio, "\n");
626280304Sjkim    }
627280304Sjkim    (void)BIO_flush(bio);
628280304Sjkim}
629194206Ssimon
630194206Ssimonvoid MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
631280304Sjkim                           unsigned char *data, int len, void *arg)
632280304Sjkim{
633280304Sjkim    BIO *bio = arg;
634280304Sjkim    char *extname;
635194206Ssimon
636280304Sjkim    switch (type) {
637280304Sjkim    case TLSEXT_TYPE_server_name:
638280304Sjkim        extname = "server name";
639280304Sjkim        break;
640194206Ssimon
641280304Sjkim    case TLSEXT_TYPE_max_fragment_length:
642280304Sjkim        extname = "max fragment length";
643280304Sjkim        break;
644194206Ssimon
645280304Sjkim    case TLSEXT_TYPE_client_certificate_url:
646280304Sjkim        extname = "client certificate URL";
647280304Sjkim        break;
648194206Ssimon
649280304Sjkim    case TLSEXT_TYPE_trusted_ca_keys:
650280304Sjkim        extname = "trusted CA keys";
651280304Sjkim        break;
652194206Ssimon
653280304Sjkim    case TLSEXT_TYPE_truncated_hmac:
654280304Sjkim        extname = "truncated HMAC";
655280304Sjkim        break;
656194206Ssimon
657280304Sjkim    case TLSEXT_TYPE_status_request:
658280304Sjkim        extname = "status request";
659280304Sjkim        break;
660194206Ssimon
661280304Sjkim    case TLSEXT_TYPE_user_mapping:
662280304Sjkim        extname = "user mapping";
663280304Sjkim        break;
664238405Sjkim
665280304Sjkim    case TLSEXT_TYPE_client_authz:
666280304Sjkim        extname = "client authz";
667280304Sjkim        break;
668238405Sjkim
669280304Sjkim    case TLSEXT_TYPE_server_authz:
670280304Sjkim        extname = "server authz";
671280304Sjkim        break;
672238405Sjkim
673280304Sjkim    case TLSEXT_TYPE_cert_type:
674280304Sjkim        extname = "cert type";
675280304Sjkim        break;
676238405Sjkim
677280304Sjkim    case TLSEXT_TYPE_elliptic_curves:
678280304Sjkim        extname = "elliptic curves";
679280304Sjkim        break;
680194206Ssimon
681280304Sjkim    case TLSEXT_TYPE_ec_point_formats:
682280304Sjkim        extname = "EC point formats";
683280304Sjkim        break;
684194206Ssimon
685280304Sjkim    case TLSEXT_TYPE_srp:
686280304Sjkim        extname = "SRP";
687280304Sjkim        break;
688238405Sjkim
689280304Sjkim    case TLSEXT_TYPE_signature_algorithms:
690280304Sjkim        extname = "signature algorithms";
691280304Sjkim        break;
692238405Sjkim
693280304Sjkim    case TLSEXT_TYPE_use_srtp:
694280304Sjkim        extname = "use SRTP";
695280304Sjkim        break;
696238405Sjkim
697280304Sjkim    case TLSEXT_TYPE_heartbeat:
698280304Sjkim        extname = "heartbeat";
699280304Sjkim        break;
700238405Sjkim
701280304Sjkim    case TLSEXT_TYPE_session_ticket:
702280304Sjkim        extname = "session ticket";
703280304Sjkim        break;
704194206Ssimon
705280304Sjkim    case TLSEXT_TYPE_renegotiate:
706280304Sjkim        extname = "renegotiation info";
707280304Sjkim        break;
708194206Ssimon
709238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input
710280304Sjkim    case TLSEXT_TYPE_opaque_prf_input:
711280304Sjkim        extname = "opaque PRF input";
712280304Sjkim        break;
713238405Sjkim#endif
714238405Sjkim#ifdef TLSEXT_TYPE_next_proto_neg
715280304Sjkim    case TLSEXT_TYPE_next_proto_neg:
716280304Sjkim        extname = "next protocol";
717280304Sjkim        break;
718238405Sjkim#endif
719238405Sjkim
720280304Sjkim    case TLSEXT_TYPE_padding:
721280304Sjkim        extname = "TLS padding";
722280304Sjkim        break;
723267258Sjkim
724280304Sjkim    default:
725280304Sjkim        extname = "unknown";
726280304Sjkim        break;
727194206Ssimon
728280304Sjkim    }
729205128Ssimon
730280304Sjkim    BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
731280304Sjkim               client_server ? "server" : "client", extname, type, len);
732280304Sjkim    BIO_dump(bio, (char *)data, len);
733280304Sjkim    (void)BIO_flush(bio);
734280304Sjkim}
735280304Sjkim
736280304Sjkimint MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie,
737280304Sjkim                                         unsigned int *cookie_len)
738280304Sjkim{
739280304Sjkim    unsigned char *buffer, result[EVP_MAX_MD_SIZE];
740280304Sjkim    unsigned int length, resultlength;
741280304Sjkim    union {
742280304Sjkim        struct sockaddr sa;
743280304Sjkim        struct sockaddr_in s4;
744238405Sjkim#if OPENSSL_USE_IPV6
745280304Sjkim        struct sockaddr_in6 s6;
746238405Sjkim#endif
747280304Sjkim    } peer;
748238405Sjkim
749280304Sjkim    /* Initialize a random secret */
750280304Sjkim    if (!cookie_initialized) {
751284285Sjkim        if (RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH) <= 0) {
752280304Sjkim            BIO_printf(bio_err, "error setting random cookie secret\n");
753280304Sjkim            return 0;
754280304Sjkim        }
755280304Sjkim        cookie_initialized = 1;
756280304Sjkim    }
757205128Ssimon
758280304Sjkim    /* Read peer information */
759280304Sjkim    (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
760205128Ssimon
761280304Sjkim    /* Create buffer with peer's address and port */
762280304Sjkim    length = 0;
763280304Sjkim    switch (peer.sa.sa_family) {
764280304Sjkim    case AF_INET:
765280304Sjkim        length += sizeof(struct in_addr);
766280304Sjkim        length += sizeof(peer.s4.sin_port);
767280304Sjkim        break;
768238405Sjkim#if OPENSSL_USE_IPV6
769280304Sjkim    case AF_INET6:
770280304Sjkim        length += sizeof(struct in6_addr);
771280304Sjkim        length += sizeof(peer.s6.sin6_port);
772280304Sjkim        break;
773238405Sjkim#endif
774280304Sjkim    default:
775280304Sjkim        OPENSSL_assert(0);
776280304Sjkim        break;
777280304Sjkim    }
778280304Sjkim    buffer = OPENSSL_malloc(length);
779205128Ssimon
780280304Sjkim    if (buffer == NULL) {
781280304Sjkim        BIO_printf(bio_err, "out of memory\n");
782280304Sjkim        return 0;
783280304Sjkim    }
784205128Ssimon
785280304Sjkim    switch (peer.sa.sa_family) {
786280304Sjkim    case AF_INET:
787280304Sjkim        memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
788280304Sjkim        memcpy(buffer + sizeof(peer.s4.sin_port),
789280304Sjkim               &peer.s4.sin_addr, sizeof(struct in_addr));
790280304Sjkim        break;
791238405Sjkim#if OPENSSL_USE_IPV6
792280304Sjkim    case AF_INET6:
793280304Sjkim        memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
794280304Sjkim        memcpy(buffer + sizeof(peer.s6.sin6_port),
795280304Sjkim               &peer.s6.sin6_addr, sizeof(struct in6_addr));
796280304Sjkim        break;
797238405Sjkim#endif
798280304Sjkim    default:
799280304Sjkim        OPENSSL_assert(0);
800280304Sjkim        break;
801280304Sjkim    }
802238405Sjkim
803280304Sjkim    /* Calculate HMAC of buffer using the secret */
804280304Sjkim    HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
805280304Sjkim         buffer, length, result, &resultlength);
806280304Sjkim    OPENSSL_free(buffer);
807205128Ssimon
808280304Sjkim    memcpy(cookie, result, resultlength);
809280304Sjkim    *cookie_len = resultlength;
810205128Ssimon
811280304Sjkim    return 1;
812280304Sjkim}
813205128Ssimon
814280304Sjkimint MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie,
815280304Sjkim                                       unsigned int cookie_len)
816280304Sjkim{
817280304Sjkim    unsigned char *buffer, result[EVP_MAX_MD_SIZE];
818280304Sjkim    unsigned int length, resultlength;
819280304Sjkim    union {
820280304Sjkim        struct sockaddr sa;
821280304Sjkim        struct sockaddr_in s4;
822238405Sjkim#if OPENSSL_USE_IPV6
823280304Sjkim        struct sockaddr_in6 s6;
824238405Sjkim#endif
825280304Sjkim    } peer;
826238405Sjkim
827280304Sjkim    /* If secret isn't initialized yet, the cookie can't be valid */
828280304Sjkim    if (!cookie_initialized)
829280304Sjkim        return 0;
830205128Ssimon
831280304Sjkim    /* Read peer information */
832280304Sjkim    (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
833205128Ssimon
834280304Sjkim    /* Create buffer with peer's address and port */
835280304Sjkim    length = 0;
836280304Sjkim    switch (peer.sa.sa_family) {
837280304Sjkim    case AF_INET:
838280304Sjkim        length += sizeof(struct in_addr);
839280304Sjkim        length += sizeof(peer.s4.sin_port);
840280304Sjkim        break;
841238405Sjkim#if OPENSSL_USE_IPV6
842280304Sjkim    case AF_INET6:
843280304Sjkim        length += sizeof(struct in6_addr);
844280304Sjkim        length += sizeof(peer.s6.sin6_port);
845280304Sjkim        break;
846238405Sjkim#endif
847280304Sjkim    default:
848280304Sjkim        OPENSSL_assert(0);
849280304Sjkim        break;
850280304Sjkim    }
851280304Sjkim    buffer = OPENSSL_malloc(length);
852205128Ssimon
853280304Sjkim    if (buffer == NULL) {
854280304Sjkim        BIO_printf(bio_err, "out of memory\n");
855280304Sjkim        return 0;
856280304Sjkim    }
857280304Sjkim
858280304Sjkim    switch (peer.sa.sa_family) {
859280304Sjkim    case AF_INET:
860280304Sjkim        memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
861280304Sjkim        memcpy(buffer + sizeof(peer.s4.sin_port),
862280304Sjkim               &peer.s4.sin_addr, sizeof(struct in_addr));
863280304Sjkim        break;
864238405Sjkim#if OPENSSL_USE_IPV6
865280304Sjkim    case AF_INET6:
866280304Sjkim        memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
867280304Sjkim        memcpy(buffer + sizeof(peer.s6.sin6_port),
868280304Sjkim               &peer.s6.sin6_addr, sizeof(struct in6_addr));
869280304Sjkim        break;
870238405Sjkim#endif
871280304Sjkim    default:
872280304Sjkim        OPENSSL_assert(0);
873280304Sjkim        break;
874280304Sjkim    }
875238405Sjkim
876280304Sjkim    /* Calculate HMAC of buffer using the secret */
877280304Sjkim    HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
878280304Sjkim         buffer, length, result, &resultlength);
879280304Sjkim    OPENSSL_free(buffer);
880238405Sjkim
881280304Sjkim    if (cookie_len == resultlength
882280304Sjkim        && memcmp(result, cookie, resultlength) == 0)
883280304Sjkim        return 1;
884205128Ssimon
885280304Sjkim    return 0;
886280304Sjkim}
887