1 /* ssl/s3_enc.c */ 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 #include <stdio.h> 60 #include <openssl/md5.h> 61 #include <openssl/sha.h> 62 #include <openssl/evp.h> 63 #include "ssl_locl.h" 64 65 static unsigned char ssl3_pad_1[48]={ 66 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, 67 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, 68 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, 69 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, 70 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, 71 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36 }; 72 73 static unsigned char ssl3_pad_2[48]={ 74 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 75 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 76 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 77 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 78 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c, 79 0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c,0x5c }; 80 81 static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, 82 const char *sender, int len, unsigned char *p); 83 84 static void ssl3_generate_key_block(SSL *s, unsigned char *km, int num) 85 { 86 MD5_CTX m5; 87 SHA_CTX s1; 88 unsigned char buf[8],smd[SHA_DIGEST_LENGTH]; 89 unsigned char c='A'; 90 int i,j,k; 91 92 #ifdef CHARSET_EBCDIC 93 c = os_toascii[c]; /*'A' in ASCII */ 94 #endif 95 k=0; 96 for (i=0; i<num; i+=MD5_DIGEST_LENGTH) 97 { 98 k++; 99 for (j=0; j<k; j++) 100 buf[j]=c; 101 c++; 102 SHA1_Init( &s1); 103 SHA1_Update(&s1,buf,k); 104 SHA1_Update(&s1,s->session->master_key, 105 s->session->master_key_length); 106 SHA1_Update(&s1,s->s3->server_random,SSL3_RANDOM_SIZE); 107 SHA1_Update(&s1,s->s3->client_random,SSL3_RANDOM_SIZE); 108 SHA1_Final( smd,&s1); 109 110 MD5_Init( &m5); 111 MD5_Update(&m5,s->session->master_key, 112 s->session->master_key_length); 113 MD5_Update(&m5,smd,SHA_DIGEST_LENGTH); 114 if ((i+MD5_DIGEST_LENGTH) > num) 115 { 116 MD5_Final(smd,&m5); 117 memcpy(km,smd,(num-i)); 118 } 119 else 120 MD5_Final(km,&m5); 121 122 km+=MD5_DIGEST_LENGTH; 123 } 124 memset(smd,0,SHA_DIGEST_LENGTH); 125 } 126 127 int ssl3_change_cipher_state(SSL *s, int which) 128 { 129 unsigned char *p,*key_block,*mac_secret; 130 unsigned char exp_key[EVP_MAX_KEY_LENGTH]; 131 unsigned char exp_iv[EVP_MAX_KEY_LENGTH]; 132 unsigned char *ms,*key,*iv,*er1,*er2; 133 EVP_CIPHER_CTX *dd; 134 const EVP_CIPHER *c; 135 COMP_METHOD *comp; 136 const EVP_MD *m; 137 MD5_CTX md; 138 int exp,n,i,j,k,cl; 139 140 exp=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); 141 c=s->s3->tmp.new_sym_enc; 142 m=s->s3->tmp.new_hash; 143 if (s->s3->tmp.new_compression == NULL) 144 comp=NULL; 145 else 146 comp=s->s3->tmp.new_compression->method; 147 key_block=s->s3->tmp.key_block; 148 149 if (which & SSL3_CC_READ) 150 { 151 if ((s->enc_read_ctx == NULL) && 152 ((s->enc_read_ctx=(EVP_CIPHER_CTX *) 153 OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) 154 goto err; 155 dd= s->enc_read_ctx; 156 s->read_hash=m; 157 /* COMPRESS */ 158 if (s->expand != NULL) 159 { 160 COMP_CTX_free(s->expand); 161 s->expand=NULL; 162 } 163 if (comp != NULL) 164 { 165 s->expand=COMP_CTX_new(comp); 166 if (s->expand == NULL) 167 { 168 SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); 169 goto err2; 170 } 171 if (s->s3->rrec.comp == NULL) 172 s->s3->rrec.comp=(unsigned char *) 173 OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); 174 if (s->s3->rrec.comp == NULL) 175 goto err; 176 } 177 memset(&(s->s3->read_sequence[0]),0,8); 178 mac_secret= &(s->s3->read_mac_secret[0]); 179 } 180 else 181 { 182 if ((s->enc_write_ctx == NULL) && 183 ((s->enc_write_ctx=(EVP_CIPHER_CTX *) 184 OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) 185 goto err; 186 dd= s->enc_write_ctx; 187 s->write_hash=m; 188 /* COMPRESS */ 189 if (s->compress != NULL) 190 { 191 COMP_CTX_free(s->compress); 192 s->compress=NULL; 193 } 194 if (comp != NULL) 195 { 196 s->compress=COMP_CTX_new(comp); 197 if (s->compress == NULL) 198 { 199 SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); 200 goto err2; 201 } 202 } 203 memset(&(s->s3->write_sequence[0]),0,8); 204 mac_secret= &(s->s3->write_mac_secret[0]); 205 } 206 207 EVP_CIPHER_CTX_init(dd); 208 209 p=s->s3->tmp.key_block; 210 i=EVP_MD_size(m); 211 cl=EVP_CIPHER_key_length(c); 212 j=exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? 213 cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; 214 /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ 215 k=EVP_CIPHER_iv_length(c); 216 if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || 217 (which == SSL3_CHANGE_CIPHER_SERVER_READ)) 218 { 219 ms= &(p[ 0]); n=i+i; 220 key= &(p[ n]); n+=j+j; 221 iv= &(p[ n]); n+=k+k; 222 er1= &(s->s3->client_random[0]); 223 er2= &(s->s3->server_random[0]); 224 } 225 else 226 { 227 n=i; 228 ms= &(p[ n]); n+=i+j; 229 key= &(p[ n]); n+=j+k; 230 iv= &(p[ n]); n+=k; 231 er1= &(s->s3->server_random[0]); 232 er2= &(s->s3->client_random[0]); 233 } 234 235 if (n > s->s3->tmp.key_block_length) 236 { 237 SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,SSL_R_INTERNAL_ERROR); 238 goto err2; 239 } 240 241 memcpy(mac_secret,ms,i); 242 if (exp) 243 { 244 /* In here I set both the read and write key/iv to the 245 * same value since only the correct one will be used :-). 246 */ 247 MD5_Init(&md); 248 MD5_Update(&md,key,j); 249 MD5_Update(&md,er1,SSL3_RANDOM_SIZE); 250 MD5_Update(&md,er2,SSL3_RANDOM_SIZE); 251 MD5_Final(&(exp_key[0]),&md); 252 key= &(exp_key[0]); 253 254 if (k > 0) 255 { 256 MD5_Init(&md); 257 MD5_Update(&md,er1,SSL3_RANDOM_SIZE); 258 MD5_Update(&md,er2,SSL3_RANDOM_SIZE); 259 MD5_Final(&(exp_iv[0]),&md); 260 iv= &(exp_iv[0]); 261 } 262 } 263 264 s->session->key_arg_length=0; 265 266 EVP_CipherInit(dd,c,key,iv,(which & SSL3_CC_WRITE)); 267 268 memset(&(exp_key[0]),0,sizeof(exp_key)); 269 memset(&(exp_iv[0]),0,sizeof(exp_iv)); 270 return(1); 271 err: 272 SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); 273 err2: 274 return(0); 275 } 276 277 int ssl3_setup_key_block(SSL *s) 278 { 279 unsigned char *p; 280 const EVP_CIPHER *c; 281 const EVP_MD *hash; 282 int num; 283 SSL_COMP *comp; 284 285 if (s->s3->tmp.key_block_length != 0) 286 return(1); 287 288 if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) 289 { 290 SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); 291 return(0); 292 } 293 294 s->s3->tmp.new_sym_enc=c; 295 s->s3->tmp.new_hash=hash; 296 s->s3->tmp.new_compression=comp; 297 298 num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); 299 num*=2; 300 301 ssl3_cleanup_key_block(s); 302 303 if ((p=OPENSSL_malloc(num)) == NULL) 304 goto err; 305 306 s->s3->tmp.key_block_length=num; 307 s->s3->tmp.key_block=p; 308 309 ssl3_generate_key_block(s,p,num); 310 311 return(1); 312 err: 313 SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); 314 return(0); 315 } 316 317 void ssl3_cleanup_key_block(SSL *s) 318 { 319 if (s->s3->tmp.key_block != NULL) 320 { 321 memset(s->s3->tmp.key_block,0, 322 s->s3->tmp.key_block_length); 323 OPENSSL_free(s->s3->tmp.key_block); 324 s->s3->tmp.key_block=NULL; 325 } 326 s->s3->tmp.key_block_length=0; 327 } 328 329 int ssl3_enc(SSL *s, int send) 330 { 331 SSL3_RECORD *rec; 332 EVP_CIPHER_CTX *ds; 333 unsigned long l; 334 int bs,i; 335 const EVP_CIPHER *enc; 336 337 if (send) 338 { 339 ds=s->enc_write_ctx; 340 rec= &(s->s3->wrec); 341 if (s->enc_write_ctx == NULL) 342 enc=NULL; 343 else 344 enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx); 345 } 346 else 347 { 348 ds=s->enc_read_ctx; 349 rec= &(s->s3->rrec); 350 if (s->enc_read_ctx == NULL) 351 enc=NULL; 352 else 353 enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx); 354 } 355 356 if ((s->session == NULL) || (ds == NULL) || 357 (enc == NULL)) 358 { 359 memmove(rec->data,rec->input,rec->length); 360 rec->input=rec->data; 361 } 362 else 363 { 364 l=rec->length; 365 bs=EVP_CIPHER_block_size(ds->cipher); 366 367 /* COMPRESS */ 368 369 if ((bs != 1) && send) 370 { 371 i=bs-((int)l%bs); 372 373 /* we need to add 'i-1' padding bytes */ 374 l+=i; 375 rec->length+=i; 376 rec->input[l-1]=(i-1); 377 } 378 379 if (!send) 380 { 381 if (l == 0 || l%bs != 0) 382 { 383 SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); 384 ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED); 385 return 0; 386 } 387 } 388 389 EVP_Cipher(ds,rec->data,rec->input,l); 390 391 if ((bs != 1) && !send) 392 { 393 i=rec->data[l-1]+1; 394 /* SSL 3.0 bounds the number of padding bytes by the block size; 395 * padding bytes (except that last) are arbitrary */ 396 if (i > bs) 397 { 398 /* Incorrect padding. SSLerr() and ssl3_alert are done 399 * by caller: we don't want to reveal whether this is 400 * a decryption error or a MAC verification failure 401 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */ 402 return -1; 403 } 404 rec->length-=i; 405 } 406 } 407 return(1); 408 } 409 410 void ssl3_init_finished_mac(SSL *s) 411 { 412 EVP_DigestInit(&(s->s3->finish_dgst1),s->ctx->md5); 413 EVP_DigestInit(&(s->s3->finish_dgst2),s->ctx->sha1); 414 } 415 416 void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) 417 { 418 EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len); 419 EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len); 420 } 421 422 int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p) 423 { 424 return(ssl3_handshake_mac(s,ctx,NULL,0,p)); 425 } 426 427 int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2, 428 const char *sender, int len, unsigned char *p) 429 { 430 int ret; 431 432 ret=ssl3_handshake_mac(s,ctx1,sender,len,p); 433 p+=ret; 434 ret+=ssl3_handshake_mac(s,ctx2,sender,len,p); 435 return(ret); 436 } 437 438 static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx, 439 const char *sender, int len, unsigned char *p) 440 { 441 unsigned int ret; 442 int npad,n; 443 unsigned int i; 444 unsigned char md_buf[EVP_MAX_MD_SIZE]; 445 EVP_MD_CTX ctx; 446 447 EVP_MD_CTX_copy(&ctx,in_ctx); 448 449 n=EVP_MD_CTX_size(&ctx); 450 npad=(48/n)*n; 451 452 if (sender != NULL) 453 EVP_DigestUpdate(&ctx,sender,len); 454 EVP_DigestUpdate(&ctx,s->session->master_key, 455 s->session->master_key_length); 456 EVP_DigestUpdate(&ctx,ssl3_pad_1,npad); 457 EVP_DigestFinal(&ctx,md_buf,&i); 458 459 EVP_DigestInit(&ctx,EVP_MD_CTX_md(&ctx)); 460 EVP_DigestUpdate(&ctx,s->session->master_key, 461 s->session->master_key_length); 462 EVP_DigestUpdate(&ctx,ssl3_pad_2,npad); 463 EVP_DigestUpdate(&ctx,md_buf,i); 464 EVP_DigestFinal(&ctx,p,&ret); 465 466 memset(&ctx,0,sizeof(EVP_MD_CTX)); 467 468 return((int)ret); 469 } 470 471 int ssl3_mac(SSL *ssl, unsigned char *md, int send) 472 { 473 SSL3_RECORD *rec; 474 unsigned char *mac_sec,*seq; 475 EVP_MD_CTX md_ctx; 476 const EVP_MD *hash; 477 unsigned char *p,rec_char; 478 unsigned int md_size; 479 int npad,i; 480 481 if (send) 482 { 483 rec= &(ssl->s3->wrec); 484 mac_sec= &(ssl->s3->write_mac_secret[0]); 485 seq= &(ssl->s3->write_sequence[0]); 486 hash=ssl->write_hash; 487 } 488 else 489 { 490 rec= &(ssl->s3->rrec); 491 mac_sec= &(ssl->s3->read_mac_secret[0]); 492 seq= &(ssl->s3->read_sequence[0]); 493 hash=ssl->read_hash; 494 } 495 496 md_size=EVP_MD_size(hash); 497 npad=(48/md_size)*md_size; 498 499 /* Chop the digest off the end :-) */ 500 501 EVP_DigestInit( &md_ctx,hash); 502 EVP_DigestUpdate(&md_ctx,mac_sec,md_size); 503 EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad); 504 EVP_DigestUpdate(&md_ctx,seq,8); 505 rec_char=rec->type; 506 EVP_DigestUpdate(&md_ctx,&rec_char,1); 507 p=md; 508 s2n(rec->length,p); 509 EVP_DigestUpdate(&md_ctx,md,2); 510 EVP_DigestUpdate(&md_ctx,rec->input,rec->length); 511 EVP_DigestFinal( &md_ctx,md,NULL); 512 513 EVP_DigestInit( &md_ctx,hash); 514 EVP_DigestUpdate(&md_ctx,mac_sec,md_size); 515 EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad); 516 EVP_DigestUpdate(&md_ctx,md,md_size); 517 EVP_DigestFinal( &md_ctx,md,&md_size); 518 519 for (i=7; i>=0; i--) 520 { 521 ++seq[i]; 522 if (seq[i] != 0) break; 523 } 524 525 return(md_size); 526 } 527 528 int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, 529 int len) 530 { 531 static const unsigned char *salt[3]={ 532 #ifndef CHARSET_EBCDIC 533 (const unsigned char *)"A", 534 (const unsigned char *)"BB", 535 (const unsigned char *)"CCC", 536 #else 537 (const unsigned char *)"\x41", 538 (const unsigned char *)"\x42\x42", 539 (const unsigned char *)"\x43\x43\x43", 540 #endif 541 }; 542 unsigned char buf[EVP_MAX_MD_SIZE]; 543 EVP_MD_CTX ctx; 544 int i,ret=0; 545 unsigned int n; 546 547 for (i=0; i<3; i++) 548 { 549 EVP_DigestInit(&ctx,s->ctx->sha1); 550 EVP_DigestUpdate(&ctx,salt[i],strlen((const char *)salt[i])); 551 EVP_DigestUpdate(&ctx,p,len); 552 EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]), 553 SSL3_RANDOM_SIZE); 554 EVP_DigestUpdate(&ctx,&(s->s3->server_random[0]), 555 SSL3_RANDOM_SIZE); 556 EVP_DigestFinal(&ctx,buf,&n); 557 558 EVP_DigestInit(&ctx,s->ctx->md5); 559 EVP_DigestUpdate(&ctx,p,len); 560 EVP_DigestUpdate(&ctx,buf,n); 561 EVP_DigestFinal(&ctx,out,&n); 562 out+=n; 563 ret+=n; 564 } 565 return(ret); 566 } 567 568 int ssl3_alert_code(int code) 569 { 570 switch (code) 571 { 572 case SSL_AD_CLOSE_NOTIFY: return(SSL3_AD_CLOSE_NOTIFY); 573 case SSL_AD_UNEXPECTED_MESSAGE: return(SSL3_AD_UNEXPECTED_MESSAGE); 574 case SSL_AD_BAD_RECORD_MAC: return(SSL3_AD_BAD_RECORD_MAC); 575 case SSL_AD_DECRYPTION_FAILED: return(SSL3_AD_BAD_RECORD_MAC); 576 case SSL_AD_RECORD_OVERFLOW: return(SSL3_AD_BAD_RECORD_MAC); 577 case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE); 578 case SSL_AD_HANDSHAKE_FAILURE: return(SSL3_AD_HANDSHAKE_FAILURE); 579 case SSL_AD_NO_CERTIFICATE: return(SSL3_AD_NO_CERTIFICATE); 580 case SSL_AD_BAD_CERTIFICATE: return(SSL3_AD_BAD_CERTIFICATE); 581 case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE); 582 case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED); 583 case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED); 584 case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN); 585 case SSL_AD_ILLEGAL_PARAMETER: return(SSL3_AD_ILLEGAL_PARAMETER); 586 case SSL_AD_UNKNOWN_CA: return(SSL3_AD_BAD_CERTIFICATE); 587 case SSL_AD_ACCESS_DENIED: return(SSL3_AD_HANDSHAKE_FAILURE); 588 case SSL_AD_DECODE_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); 589 case SSL_AD_DECRYPT_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); 590 case SSL_AD_EXPORT_RESTRICTION: return(SSL3_AD_HANDSHAKE_FAILURE); 591 case SSL_AD_PROTOCOL_VERSION: return(SSL3_AD_HANDSHAKE_FAILURE); 592 case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE); 593 case SSL_AD_INTERNAL_ERROR: return(SSL3_AD_HANDSHAKE_FAILURE); 594 case SSL_AD_USER_CANCELLED: return(SSL3_AD_HANDSHAKE_FAILURE); 595 case SSL_AD_NO_RENEGOTIATION: return(-1); /* Don't send it :-) */ 596 default: return(-1); 597 } 598 } 599 600