xref: /freebsd/crypto/openssl/ssl/s3_enc.c (revision a79b71281cd63ad7a6cc43a6d5673a2510b51630)
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 			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 					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 			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=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 		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 		memcpy(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 		/* This should be using (bs-1) and bs instead of 7 and 8 */
370 		if ((bs != 1) && send)
371 			{
372 			i=bs-((int)l%bs);
373 
374 			/* we need to add 'i-1' padding bytes */
375 			l+=i;
376 			rec->length+=i;
377 			rec->input[l-1]=(i-1);
378 			}
379 
380 		EVP_Cipher(ds,rec->data,rec->input,l);
381 
382 		if ((bs != 1) && !send)
383 			{
384 			i=rec->data[l-1]+1;
385 			if (i > bs)
386 				{
387 				SSLerr(SSL_F_SSL3_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
388 				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPT_ERROR);
389 				return(0);
390 				}
391 			rec->length-=i;
392 			}
393 		}
394 	return(1);
395 	}
396 
397 void ssl3_init_finished_mac(SSL *s)
398 	{
399 	EVP_DigestInit(&(s->s3->finish_dgst1),s->ctx->md5);
400 	EVP_DigestInit(&(s->s3->finish_dgst2),s->ctx->sha1);
401 	}
402 
403 void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
404 	{
405 	EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len);
406 	EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,len);
407 	}
408 
409 int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p)
410 	{
411 	return(ssl3_handshake_mac(s,ctx,NULL,0,p));
412 	}
413 
414 int ssl3_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2,
415 	     const char *sender, int len, unsigned char *p)
416 	{
417 	int ret;
418 
419 	ret=ssl3_handshake_mac(s,ctx1,sender,len,p);
420 	p+=ret;
421 	ret+=ssl3_handshake_mac(s,ctx2,sender,len,p);
422 	return(ret);
423 	}
424 
425 static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
426 	     const char *sender, int len, unsigned char *p)
427 	{
428 	unsigned int ret;
429 	int npad,n;
430 	unsigned int i;
431 	unsigned char md_buf[EVP_MAX_MD_SIZE];
432 	EVP_MD_CTX ctx;
433 
434 	EVP_MD_CTX_copy(&ctx,in_ctx);
435 
436 	n=EVP_MD_CTX_size(&ctx);
437 	npad=(48/n)*n;
438 
439 	if (sender != NULL)
440 		EVP_DigestUpdate(&ctx,sender,len);
441 	EVP_DigestUpdate(&ctx,s->session->master_key,
442 		s->session->master_key_length);
443 	EVP_DigestUpdate(&ctx,ssl3_pad_1,npad);
444 	EVP_DigestFinal(&ctx,md_buf,&i);
445 
446 	EVP_DigestInit(&ctx,EVP_MD_CTX_md(&ctx));
447 	EVP_DigestUpdate(&ctx,s->session->master_key,
448 		s->session->master_key_length);
449 	EVP_DigestUpdate(&ctx,ssl3_pad_2,npad);
450 	EVP_DigestUpdate(&ctx,md_buf,i);
451 	EVP_DigestFinal(&ctx,p,&ret);
452 
453 	memset(&ctx,0,sizeof(EVP_MD_CTX));
454 
455 	return((int)ret);
456 	}
457 
458 int ssl3_mac(SSL *ssl, unsigned char *md, int send)
459 	{
460 	SSL3_RECORD *rec;
461 	unsigned char *mac_sec,*seq;
462 	EVP_MD_CTX md_ctx;
463 	const EVP_MD *hash;
464 	unsigned char *p,rec_char;
465 	unsigned int md_size;
466 	int npad,i;
467 
468 	if (send)
469 		{
470 		rec= &(ssl->s3->wrec);
471 		mac_sec= &(ssl->s3->write_mac_secret[0]);
472 		seq= &(ssl->s3->write_sequence[0]);
473 		hash=ssl->write_hash;
474 		}
475 	else
476 		{
477 		rec= &(ssl->s3->rrec);
478 		mac_sec= &(ssl->s3->read_mac_secret[0]);
479 		seq= &(ssl->s3->read_sequence[0]);
480 		hash=ssl->read_hash;
481 		}
482 
483 	md_size=EVP_MD_size(hash);
484 	npad=(48/md_size)*md_size;
485 
486 	/* Chop the digest off the end :-) */
487 
488 	EVP_DigestInit(  &md_ctx,hash);
489 	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
490 	EVP_DigestUpdate(&md_ctx,ssl3_pad_1,npad);
491 	EVP_DigestUpdate(&md_ctx,seq,8);
492 	rec_char=rec->type;
493 	EVP_DigestUpdate(&md_ctx,&rec_char,1);
494 	p=md;
495 	s2n(rec->length,p);
496 	EVP_DigestUpdate(&md_ctx,md,2);
497 	EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
498 	EVP_DigestFinal( &md_ctx,md,NULL);
499 
500 	EVP_DigestInit(  &md_ctx,hash);
501 	EVP_DigestUpdate(&md_ctx,mac_sec,md_size);
502 	EVP_DigestUpdate(&md_ctx,ssl3_pad_2,npad);
503 	EVP_DigestUpdate(&md_ctx,md,md_size);
504 	EVP_DigestFinal( &md_ctx,md,&md_size);
505 
506 	for (i=7; i>=0; i--)
507 		if (++seq[i]) break;
508 
509 	return(md_size);
510 	}
511 
512 int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
513 	     int len)
514 	{
515 	static const unsigned char *salt[3]={
516 #ifndef CHARSET_EBCDIC
517 		(const unsigned char *)"A",
518 		(const unsigned char *)"BB",
519 		(const unsigned char *)"CCC",
520 #else
521 		(const unsigned char *)"\x41",
522 		(const unsigned char *)"\x42\x42",
523 		(const unsigned char *)"\x43\x43\x43",
524 #endif
525 		};
526 	unsigned char buf[EVP_MAX_MD_SIZE];
527 	EVP_MD_CTX ctx;
528 	int i,ret=0;
529 	unsigned int n;
530 
531 	for (i=0; i<3; i++)
532 		{
533 		EVP_DigestInit(&ctx,s->ctx->sha1);
534 		EVP_DigestUpdate(&ctx,salt[i],strlen((const char *)salt[i]));
535 		EVP_DigestUpdate(&ctx,p,len);
536 		EVP_DigestUpdate(&ctx,&(s->s3->client_random[0]),
537 			SSL3_RANDOM_SIZE);
538 		EVP_DigestUpdate(&ctx,&(s->s3->server_random[0]),
539 			SSL3_RANDOM_SIZE);
540 		EVP_DigestFinal(&ctx,buf,&n);
541 
542 		EVP_DigestInit(&ctx,s->ctx->md5);
543 		EVP_DigestUpdate(&ctx,p,len);
544 		EVP_DigestUpdate(&ctx,buf,n);
545 		EVP_DigestFinal(&ctx,out,&n);
546 		out+=n;
547 		ret+=n;
548 		}
549 	return(ret);
550 	}
551 
552 int ssl3_alert_code(int code)
553 	{
554 	switch (code)
555 		{
556 	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
557 	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
558 	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
559 	case SSL_AD_DECRYPTION_FAILED:	return(SSL3_AD_BAD_RECORD_MAC);
560 	case SSL_AD_RECORD_OVERFLOW:	return(SSL3_AD_BAD_RECORD_MAC);
561 	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
562 	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
563 	case SSL_AD_NO_CERTIFICATE:	return(SSL3_AD_NO_CERTIFICATE);
564 	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
565 	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
566 	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
567 	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
568 	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
569 	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
570 	case SSL_AD_UNKNOWN_CA:		return(SSL3_AD_BAD_CERTIFICATE);
571 	case SSL_AD_ACCESS_DENIED:	return(SSL3_AD_HANDSHAKE_FAILURE);
572 	case SSL_AD_DECODE_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
573 	case SSL_AD_DECRYPT_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
574 	case SSL_AD_EXPORT_RESTRICTION:	return(SSL3_AD_HANDSHAKE_FAILURE);
575 	case SSL_AD_PROTOCOL_VERSION:	return(SSL3_AD_HANDSHAKE_FAILURE);
576 	case SSL_AD_INSUFFICIENT_SECURITY:return(SSL3_AD_HANDSHAKE_FAILURE);
577 	case SSL_AD_INTERNAL_ERROR:	return(SSL3_AD_HANDSHAKE_FAILURE);
578 	case SSL_AD_USER_CANCELLED:	return(SSL3_AD_HANDSHAKE_FAILURE);
579 	case SSL_AD_NO_RENEGOTIATION:	return(-1); /* Don't send it :-) */
580 	default:			return(-1);
581 		}
582 	}
583 
584