s3_enc.c 17.5 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8
 */
R
Rich Salz 已提交
9

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
/* ====================================================================
 * Copyright 2005 Nokia. All rights reserved.
 *
 * The portions of the attached software ("Contribution") is developed by
 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
 * license.
 *
 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
 * support (see RFC 4279) to OpenSSL.
 *
 * No patent licenses or other rights except those expressly stated in
 * the OpenSSL open source license shall be deemed granted or received
 * expressly, by implication, estoppel, or otherwise.
 *
 * No assurances are provided by Nokia that the Contribution does not
 * infringe the patent or other intellectual property rights of any third
 * party or that the license provides you with all the necessary rights
 * to make use of the Contribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
 * OTHERWISE.
 */
36 37 38

#include <stdio.h>
#include "ssl_locl.h"
39
#include <openssl/evp.h>
40
#include <openssl/md5.h>
41

B
Bodo Möller 已提交
42
static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
43
{
44 45
    EVP_MD_CTX *m5;
    EVP_MD_CTX *s1;
46 47 48
    unsigned char buf[16], smd[SHA_DIGEST_LENGTH];
    unsigned char c = 'A';
    unsigned int i, j, k;
49
    int ret = 0;
50

51
#ifdef CHARSET_EBCDIC
52
    c = os_toascii[c];          /* 'A' in ASCII */
53
#endif
54
    k = 0;
55 56
    m5 = EVP_MD_CTX_new();
    s1 = EVP_MD_CTX_new();
57 58 59 60 61
    if (m5 == NULL || s1 == NULL) {
        SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    EVP_MD_CTX_set_flags(m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
62 63 64 65 66 67 68 69 70 71 72
    for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) {
        k++;
        if (k > sizeof buf) {
            /* bug: 'buf' is too small for this ciphersuite */
            SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
            return 0;
        }

        for (j = 0; j < k; j++)
            buf[j] = c;
        c++;
73 74 75
        EVP_DigestInit_ex(s1, EVP_sha1(), NULL);
        EVP_DigestUpdate(s1, buf, k);
        EVP_DigestUpdate(s1, s->session->master_key,
76
                         s->session->master_key_length);
77 78 79
        EVP_DigestUpdate(s1, s->s3->server_random, SSL3_RANDOM_SIZE);
        EVP_DigestUpdate(s1, s->s3->client_random, SSL3_RANDOM_SIZE);
        EVP_DigestFinal_ex(s1, smd, NULL);
80

81 82
        EVP_DigestInit_ex(m5, EVP_md5(), NULL);
        EVP_DigestUpdate(m5, s->session->master_key,
83
                         s->session->master_key_length);
84
        EVP_DigestUpdate(m5, smd, SHA_DIGEST_LENGTH);
85
        if ((int)(i + MD5_DIGEST_LENGTH) > num) {
86
            EVP_DigestFinal_ex(m5, smd, NULL);
87 88
            memcpy(km, smd, (num - i));
        } else
89
            EVP_DigestFinal_ex(m5, km, NULL);
90 91 92

        km += MD5_DIGEST_LENGTH;
    }
R
Rich Salz 已提交
93
    OPENSSL_cleanse(smd, sizeof(smd));
94 95
    ret = 1;
 err:
96 97
    EVP_MD_CTX_free(m5);
    EVP_MD_CTX_free(s1);
98
    return ret;
99
}
100

U
Ulf Möller 已提交
101
int ssl3_change_cipher_state(SSL *s, int which)
102 103 104 105
{
    unsigned char *p, *mac_secret;
    unsigned char exp_key[EVP_MAX_KEY_LENGTH];
    unsigned char exp_iv[EVP_MAX_IV_LENGTH];
106
    unsigned char *ms, *key, *iv;
107 108
    EVP_CIPHER_CTX *dd;
    const EVP_CIPHER *c;
109
#ifndef OPENSSL_NO_COMP
110
    COMP_METHOD *comp;
111
#endif
112
    const EVP_MD *m;
113
    int n, i, j, k, cl;
114 115 116 117 118 119
    int reuse_dd = 0;

    c = s->s3->tmp.new_sym_enc;
    m = s->s3->tmp.new_hash;
    /* m == NULL will lead to a crash later */
    OPENSSL_assert(m);
120
#ifndef OPENSSL_NO_COMP
121 122 123 124
    if (s->s3->tmp.new_compression == NULL)
        comp = NULL;
    else
        comp = s->s3->tmp.new_compression->method;
125
#endif
126

127 128 129
    if (which & SSL3_CC_READ) {
        if (s->enc_read_ctx != NULL)
            reuse_dd = 1;
130
        else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL)
131 132 133
            goto err;
        else
            /*
F
FdaSilvaYY 已提交
134
             * make sure it's initialised in case we exit later with an error
135
             */
136
            EVP_CIPHER_CTX_reset(s->enc_read_ctx);
137 138
        dd = s->enc_read_ctx;

139
        if (ssl_replace_hash(&s->read_hash, m) == NULL) {
M
Matt Caswell 已提交
140 141 142
                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
                goto err2;
        }
143
#ifndef OPENSSL_NO_COMP
144
        /* COMPRESS */
R
Rich Salz 已提交
145 146
        COMP_CTX_free(s->expand);
        s->expand = NULL;
147 148 149 150 151 152 153 154
        if (comp != NULL) {
            s->expand = COMP_CTX_new(comp);
            if (s->expand == NULL) {
                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
                       SSL_R_COMPRESSION_LIBRARY_ERROR);
                goto err2;
            }
        }
155
#endif
156
        RECORD_LAYER_reset_read_sequence(&s->rlayer);
157 158 159 160
        mac_secret = &(s->s3->read_mac_secret[0]);
    } else {
        if (s->enc_write_ctx != NULL)
            reuse_dd = 1;
161
        else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL)
162 163 164
            goto err;
        else
            /*
F
FdaSilvaYY 已提交
165
             * make sure it's initialised in case we exit later with an error
166
             */
167
            EVP_CIPHER_CTX_reset(s->enc_write_ctx);
168
        dd = s->enc_write_ctx;
169
        if (ssl_replace_hash(&s->write_hash, m) == NULL) {
M
Matt Caswell 已提交
170 171 172
                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
                goto err2;
        }
173
#ifndef OPENSSL_NO_COMP
174
        /* COMPRESS */
R
Rich Salz 已提交
175 176
        COMP_CTX_free(s->compress);
        s->compress = NULL;
177 178 179 180 181 182 183 184
        if (comp != NULL) {
            s->compress = COMP_CTX_new(comp);
            if (s->compress == NULL) {
                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
                       SSL_R_COMPRESSION_LIBRARY_ERROR);
                goto err2;
            }
        }
185
#endif
186
        RECORD_LAYER_reset_write_sequence(&s->rlayer);
187 188 189 190
        mac_secret = &(s->s3->write_mac_secret[0]);
    }

    if (reuse_dd)
191
        EVP_CIPHER_CTX_reset(dd);
192 193 194 195 196 197

    p = s->s3->tmp.key_block;
    i = EVP_MD_size(m);
    if (i < 0)
        goto err2;
    cl = EVP_CIPHER_key_length(c);
198
    j = cl;
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
    k = EVP_CIPHER_iv_length(c);
    if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
        (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
        ms = &(p[0]);
        n = i + i;
        key = &(p[n]);
        n += j + j;
        iv = &(p[n]);
        n += k + k;
    } else {
        n = i;
        ms = &(p[n]);
        n += i + j;
        key = &(p[n]);
        n += j + k;
        iv = &(p[n]);
        n += k;
    }

    if (n > s->s3->tmp.key_block_length) {
        SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
        goto err2;
    }

    memcpy(mac_secret, ms, i);

    EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));
226

227
#ifdef OPENSSL_SSL_TRACE_CRYPTO
228 229 230 231 232 233 234 235 236 237 238 239 240 241
    if (s->msg_callback) {

        int wh = which & SSL3_CC_WRITE ?
            TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ;
        s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
                        mac_secret, EVP_MD_size(m), s, s->msg_callback_arg);
        if (c->key_len)
            s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
                            key, c->key_len, s, s->msg_callback_arg);
        if (k) {
            s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV,
                            iv, k, s, s->msg_callback_arg);
        }
    }
242 243
#endif

R
Rich Salz 已提交
244 245
    OPENSSL_cleanse(exp_key, sizeof(exp_key));
    OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
246 247 248 249
    return (1);
 err:
    SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
 err2:
R
Rich Salz 已提交
250 251
    OPENSSL_cleanse(exp_key, sizeof(exp_key));
    OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
252 253
    return (0);
}
254

U
Ulf Möller 已提交
255
int ssl3_setup_key_block(SSL *s)
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
{
    unsigned char *p;
    const EVP_CIPHER *c;
    const EVP_MD *hash;
    int num;
    int ret = 0;
    SSL_COMP *comp;

    if (s->s3->tmp.key_block_length != 0)
        return (1);

    if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp, 0)) {
        SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
        return (0);
    }

    s->s3->tmp.new_sym_enc = c;
    s->s3->tmp.new_hash = hash;
274
#ifdef OPENSSL_NO_COMP
275
    s->s3->tmp.new_compression = NULL;
276
#else
277
    s->s3->tmp.new_compression = comp;
278
#endif
279

280 281 282 283 284 285
    num = EVP_MD_size(hash);
    if (num < 0)
        return 0;

    num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c);
    num *= 2;
286

287
    ssl3_cleanup_key_block(s);
288

289 290
    if ((p = OPENSSL_malloc(num)) == NULL)
        goto err;
291

292 293
    s->s3->tmp.key_block_length = num;
    s->s3->tmp.key_block = p;
294

295
    ret = ssl3_generate_key_block(s, p, num);
296

297 298 299 300 301 302
    if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) {
        /*
         * enable vulnerability countermeasure for CBC ciphers with known-IV
         * problem (http://www.openssl.org/~bodo/tls-cbc.txt)
         */
        s->s3->need_empty_fragments = 1;
303

304 305 306
        if (s->session->cipher != NULL) {
            if (s->session->cipher->algorithm_enc == SSL_eNULL)
                s->s3->need_empty_fragments = 0;
307

308
#ifndef OPENSSL_NO_RC4
309 310
            if (s->session->cipher->algorithm_enc == SSL_RC4)
                s->s3->need_empty_fragments = 0;
311
#endif
312 313
        }
    }
314

315 316 317 318 319 320
    return ret;

 err:
    SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
    return (0);
}
321

U
Ulf Möller 已提交
322
void ssl3_cleanup_key_block(SSL *s)
323
{
R
Rich Salz 已提交
324 325
    OPENSSL_clear_free(s->s3->tmp.key_block, s->s3->tmp.key_block_length);
    s->s3->tmp.key_block = NULL;
326 327
    s->s3->tmp.key_block_length = 0;
}
328

U
Ulf Möller 已提交
329
void ssl3_init_finished_mac(SSL *s)
330
{
331
    ssl3_free_digest_list(s);
332 333 334 335
    s->s3->handshake_buffer = BIO_new(BIO_s_mem());
    (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
}

D
Dr. Stephen Henson 已提交
336 337 338 339 340
/*
 * Free digest list. Also frees handshake buffer since they are always freed
 * together.
 */

341 342
void ssl3_free_digest_list(SSL *s)
{
D
Dr. Stephen Henson 已提交
343 344
    BIO_free(s->s3->handshake_buffer);
    s->s3->handshake_buffer = NULL;
345
    EVP_MD_CTX_free(s->s3->handshake_dgst);
346 347
    s->s3->handshake_dgst = NULL;
}
348

U
Ulf Möller 已提交
349
void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
350
{
351
    if (s->s3->handshake_dgst == NULL)
352
        BIO_write(s->s3->handshake_buffer, (void *)buf, len);
353 354
    else
        EVP_DigestUpdate(s->s3->handshake_dgst, buf, len);
355
}
356

357
int ssl3_digest_cached_records(SSL *s, int keep)
358 359 360 361 362 363
{
    const EVP_MD *md;
    long hdatalen;
    void *hdata;

    if (s->s3->handshake_dgst == NULL) {
364 365 366 367 368
        hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
        if (hdatalen <= 0) {
            SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH);
            return 0;
        }
369

370
        s->s3->handshake_dgst = EVP_MD_CTX_new();
371 372 373 374 375 376 377 378 379
        if (s->s3->handshake_dgst == NULL) {
            SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
            return 0;
        }

        md = ssl_handshake_md(s);
        if (md == NULL) {
            SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR);
            return 0;
380
        }
381

382 383 384
        EVP_DigestInit_ex(s->s3->handshake_dgst, md, NULL);
        EVP_DigestUpdate(s->s3->handshake_dgst, hdata, hdatalen);

385
    }
386
    if (keep == 0) {
387 388 389 390 391 392
        BIO_free(s->s3->handshake_buffer);
        s->s3->handshake_buffer = NULL;
    }

    return 1;
}
393

394
int ssl3_final_finish_mac(SSL *s, const char *sender, int len, unsigned char *p)
395
{
396
    int ret;
397
    EVP_MD_CTX *ctx = NULL;
398

399 400
    if (!ssl3_digest_cached_records(s, 0))
        return 0;
401

402
    if (EVP_MD_CTX_type(s->s3->handshake_dgst) != NID_md5_sha1) {
D
Dr. Stephen Henson 已提交
403
        SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, SSL_R_NO_REQUIRED_DIGEST);
404 405
        return 0;
    }
406

407
    ctx = EVP_MD_CTX_new();
408 409 410 411 412
    if (ctx == NULL) {
        SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst);
413

414
    ret = EVP_MD_CTX_size(ctx);
415
    if (ret < 0) {
416
        EVP_MD_CTX_reset(ctx);
417
        return 0;
418
    }
419

420 421
    if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0)
            || EVP_MD_CTX_ctrl(ctx, EVP_CTRL_SSL3_MASTER_SECRET,
422 423
                               s->session->master_key_length,
                               s->session->master_key) <= 0
424
            || EVP_DigestFinal_ex(ctx, p, NULL) <= 0) {
D
Dr. Stephen Henson 已提交
425
        SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR);
426 427
        ret = 0;
    }
428

429
    EVP_MD_CTX_free(ctx);
430

431
    return ret;
432
}
433

U
Ulf Möller 已提交
434
int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
435 436 437
                                int len)
{
    static const unsigned char *salt[3] = {
438
#ifndef CHARSET_EBCDIC
439 440 441
        (const unsigned char *)"A",
        (const unsigned char *)"BB",
        (const unsigned char *)"CCC",
442
#else
443 444 445
        (const unsigned char *)"\x41",
        (const unsigned char *)"\x42\x42",
        (const unsigned char *)"\x43\x43\x43",
446
#endif
447 448
    };
    unsigned char buf[EVP_MAX_MD_SIZE];
449
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
450 451
    int i, ret = 0;
    unsigned int n;
D
Dr. Stephen Henson 已提交
452
#ifdef OPENSSL_SSL_TRACE_CRYPTO
453
    unsigned char *tmpout = out;
454
#endif
455

456 457 458 459
    if (ctx == NULL) {
        SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_MALLOC_FAILURE);
        return 0;
    }
460
    for (i = 0; i < 3; i++) {
461 462
        if (EVP_DigestInit_ex(ctx, s->ctx->sha1, NULL) <= 0
                || EVP_DigestUpdate(ctx, salt[i],
463
                                    strlen((const char *)salt[i])) <= 0
464 465
                || EVP_DigestUpdate(ctx, p, len) <= 0
                || EVP_DigestUpdate(ctx, &(s->s3->client_random[0]),
466
                                    SSL3_RANDOM_SIZE) <= 0
467
                || EVP_DigestUpdate(ctx, &(s->s3->server_random[0]),
468
                                    SSL3_RANDOM_SIZE) <= 0
469
                || EVP_DigestFinal_ex(ctx, buf, &n) <= 0
470

471 472 473 474
                || EVP_DigestInit_ex(ctx, s->ctx->md5, NULL) <= 0
                || EVP_DigestUpdate(ctx, p, len) <= 0
                || EVP_DigestUpdate(ctx, buf, n) <= 0
                || EVP_DigestFinal_ex(ctx, out, &n) <= 0) {
475 476 477 478
            SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
            ret = 0;
            break;
        }
479 480 481
        out += n;
        ret += n;
    }
482
    EVP_MD_CTX_free(ctx);
483

D
Dr. Stephen Henson 已提交
484
#ifdef OPENSSL_SSL_TRACE_CRYPTO
485
    if (ret > 0 && s->msg_callback) {
486 487 488 489 490 491 492 493 494 495 496 497
        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
                        p, len, s, s->msg_callback_arg);
        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
                        s->s3->client_random, SSL3_RANDOM_SIZE,
                        s, s->msg_callback_arg);
        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM,
                        s->s3->server_random, SSL3_RANDOM_SIZE,
                        s, s->msg_callback_arg);
        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER,
                        tmpout, SSL3_MASTER_SECRET_SIZE,
                        s, s->msg_callback_arg);
    }
498
#endif
R
Rich Salz 已提交
499
    OPENSSL_cleanse(buf, sizeof(buf));
500 501
    return (ret);
}
502

U
Ulf Möller 已提交
503
int ssl3_alert_code(int code)
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
{
    switch (code) {
    case SSL_AD_CLOSE_NOTIFY:
        return (SSL3_AD_CLOSE_NOTIFY);
    case SSL_AD_UNEXPECTED_MESSAGE:
        return (SSL3_AD_UNEXPECTED_MESSAGE);
    case SSL_AD_BAD_RECORD_MAC:
        return (SSL3_AD_BAD_RECORD_MAC);
    case SSL_AD_DECRYPTION_FAILED:
        return (SSL3_AD_BAD_RECORD_MAC);
    case SSL_AD_RECORD_OVERFLOW:
        return (SSL3_AD_BAD_RECORD_MAC);
    case SSL_AD_DECOMPRESSION_FAILURE:
        return (SSL3_AD_DECOMPRESSION_FAILURE);
    case SSL_AD_HANDSHAKE_FAILURE:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_NO_CERTIFICATE:
        return (SSL3_AD_NO_CERTIFICATE);
    case SSL_AD_BAD_CERTIFICATE:
        return (SSL3_AD_BAD_CERTIFICATE);
    case SSL_AD_UNSUPPORTED_CERTIFICATE:
        return (SSL3_AD_UNSUPPORTED_CERTIFICATE);
    case SSL_AD_CERTIFICATE_REVOKED:
        return (SSL3_AD_CERTIFICATE_REVOKED);
    case SSL_AD_CERTIFICATE_EXPIRED:
        return (SSL3_AD_CERTIFICATE_EXPIRED);
    case SSL_AD_CERTIFICATE_UNKNOWN:
        return (SSL3_AD_CERTIFICATE_UNKNOWN);
    case SSL_AD_ILLEGAL_PARAMETER:
        return (SSL3_AD_ILLEGAL_PARAMETER);
    case SSL_AD_UNKNOWN_CA:
        return (SSL3_AD_BAD_CERTIFICATE);
    case SSL_AD_ACCESS_DENIED:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_DECODE_ERROR:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_DECRYPT_ERROR:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_EXPORT_RESTRICTION:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_PROTOCOL_VERSION:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_INSUFFICIENT_SECURITY:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_INTERNAL_ERROR:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_USER_CANCELLED:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_NO_RENEGOTIATION:
        return (-1);            /* Don't send it :-) */
    case SSL_AD_UNSUPPORTED_EXTENSION:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_CERTIFICATE_UNOBTAINABLE:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_UNRECOGNIZED_NAME:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
        return (SSL3_AD_HANDSHAKE_FAILURE);
    case SSL_AD_UNKNOWN_PSK_IDENTITY:
        return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
    case SSL_AD_INAPPROPRIATE_FALLBACK:
        return (TLS1_AD_INAPPROPRIATE_FALLBACK);
568 569
    case SSL_AD_NO_APPLICATION_PROTOCOL:
        return (TLS1_AD_NO_APPLICATION_PROTOCOL);
570 571 572 573
    default:
        return (-1);
    }
}