Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / ssl / s3_both.c
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.]
56  */
57 /* ====================================================================
58  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
59  *
60  * Redistribution and use in source and binary forms, with or without
61  * modification, are permitted provided that the following conditions
62  * are met:
63  *
64  * 1. Redistributions of source code must retain the above copyright
65  *    notice, this list of conditions and the following disclaimer.
66  *
67  * 2. Redistributions in binary form must reproduce the above copyright
68  *    notice, this list of conditions and the following disclaimer in
69  *    the documentation and/or other materials provided with the
70  *    distribution.
71  *
72  * 3. All advertising materials mentioning features or use of this
73  *    software must display the following acknowledgment:
74  *    "This product includes software developed by the OpenSSL Project
75  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76  *
77  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78  *    endorse or promote products derived from this software without
79  *    prior written permission. For written permission, please contact
80  *    openssl-core@openssl.org.
81  *
82  * 5. Products derived from this software may not be called "OpenSSL"
83  *    nor may "OpenSSL" appear in their names without prior written
84  *    permission of the OpenSSL Project.
85  *
86  * 6. Redistributions of any form whatsoever must retain the following
87  *    acknowledgment:
88  *    "This product includes software developed by the OpenSSL Project
89  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90  *
91  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
95  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102  * OF THE POSSIBILITY OF SUCH DAMAGE.
103  * ====================================================================
104  *
105  * This product includes cryptographic software written by Eric Young
106  * (eay@cryptsoft.com).  This product includes software written by Tim
107  * Hudson (tjh@cryptsoft.com). */
108 /* ====================================================================
109  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
110  * ECC cipher suite support in OpenSSL originally developed by
111  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
112
113 #include <assert.h>
114 #include <limits.h>
115 #include <stdio.h>
116 #include <string.h>
117
118 #include <openssl/buf.h>
119 #include <openssl/evp.h>
120 #include <openssl/mem.h>
121 #include <openssl/md5.h>
122 #include <openssl/obj.h>
123 #include <openssl/rand.h>
124 #include <openssl/sha.h>
125 #include <openssl/x509.h>
126
127 #include "ssl_locl.h"
128
129 /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
130 int ssl3_do_write(SSL *s, int type, enum should_add_to_finished_hash should_add_to_finished_hash)
131         {
132         int ret;
133
134         ret=ssl3_write_bytes(s,type,&s->init_buf->data[s->init_off],
135                              s->init_num);
136         if (ret < 0) return(-1);
137         if (type == SSL3_RT_HANDSHAKE && should_add_to_finished_hash == add_to_finished_hash)
138                 {
139                 /* should not be done for 'Hello Request's, but in that case
140                  * we'll ignore the result anyway */
141                 ssl3_finish_mac(s,(unsigned char *)&s->init_buf->data[s->init_off],ret);
142                 }
143         
144         if (ret == s->init_num)
145                 {
146                 if (s->msg_callback)
147                         s->msg_callback(1, s->version, type, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
148                 return(1);
149                 }
150         s->init_off+=ret;
151         s->init_num-=ret;
152         return(0);
153         }
154
155 int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
156         {
157         unsigned char *p;
158         int i;
159         unsigned long l;
160
161         if (s->state == a)
162                 {
163                 p = ssl_handshake_start(s);
164
165                 i=s->method->ssl3_enc->final_finish_mac(s,
166                         sender,slen,s->s3->tmp.finish_md);
167                 if (i == 0)
168                         return 0;
169                 s->s3->tmp.finish_md_len = i;
170                 memcpy(p, s->s3->tmp.finish_md, i);
171                 l=i;
172
173                 /* Log the master secret, if logging is enabled. */
174                 if (!ssl_ctx_log_master_secret(s->ctx,
175                                 s->s3->client_random, SSL3_RANDOM_SIZE,
176                                 s->session->master_key, s->session->master_key_length))
177                         {
178                         return 0;
179                         }
180
181                 /* Copy the finished so we can use it for
182                    renegotiation checks */
183                 if(s->type == SSL_ST_CONNECT)
184                         {
185                          assert(i <= EVP_MAX_MD_SIZE);
186                          memcpy(s->s3->previous_client_finished, 
187                              s->s3->tmp.finish_md, i);
188                          s->s3->previous_client_finished_len=i;
189                         }
190                 else
191                         {
192                         assert(i <= EVP_MAX_MD_SIZE);
193                         memcpy(s->s3->previous_server_finished, 
194                             s->s3->tmp.finish_md, i);
195                         s->s3->previous_server_finished_len=i;
196                         }
197
198                 ssl_set_handshake_header(s, SSL3_MT_FINISHED, l);
199                 s->state=b;
200                 }
201
202         /* SSL3_ST_SEND_xxxxxx_HELLO_B */
203         return ssl_do_write(s);
204         }
205
206 /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
207 static void ssl3_take_mac(SSL *s)
208         {
209         const char *sender;
210         int slen;
211         /* If no new cipher setup return immediately: other functions will
212          * set the appropriate error.
213          */
214         if (s->s3->tmp.new_cipher == NULL)
215                 return;
216         if (s->state & SSL_ST_CONNECT)
217                 {
218                 sender=s->method->ssl3_enc->server_finished_label;
219                 slen=s->method->ssl3_enc->server_finished_label_len;
220                 }
221         else
222                 {
223                 sender=s->method->ssl3_enc->client_finished_label;
224                 slen=s->method->ssl3_enc->client_finished_label_len;
225                 }
226
227         s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
228                 sender,slen,s->s3->tmp.peer_finish_md);
229         }
230
231 int ssl3_get_finished(SSL *s, int a, int b)
232         {
233         int al,i,ok;
234         long n;
235         unsigned char *p;
236
237         n=s->method->ssl_get_message(s,
238                 a,
239                 b,
240                 SSL3_MT_FINISHED,
241                 64, /* should actually be 36+4 :-) */
242                 SSL_GET_MESSAGE_DONT_HASH_MESSAGE,
243                 &ok);
244
245         if (!ok) return((int)n);
246
247         /* Snapshot the finished hash before incorporating the new message. */
248         ssl3_take_mac(s);
249         ssl3_hash_current_message(s);
250
251         /* If this occurs, we have missed a message.
252          * TODO(davidben): Is this check now redundant with
253          * SSL3_FLAGS_EXPECT_CCS? */
254         if (!s->s3->change_cipher_spec)
255                 {
256                 al=SSL_AD_UNEXPECTED_MESSAGE;
257                 OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
258                 goto f_err;
259                 }
260         s->s3->change_cipher_spec=0;
261
262         p = s->init_msg;
263         i = s->s3->tmp.peer_finish_md_len;
264
265         if (i != n)
266                 {
267                 al=SSL_AD_DECODE_ERROR;
268                 OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_BAD_DIGEST_LENGTH);
269                 goto f_err;
270                 }
271
272         if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
273                 {
274                 al=SSL_AD_DECRYPT_ERROR;
275                 OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_DIGEST_CHECK_FAILED);
276                 goto f_err;
277                 }
278
279         /* Copy the finished so we can use it for
280            renegotiation checks */
281         if(s->type == SSL_ST_ACCEPT)
282                 {
283                 assert(i <= EVP_MAX_MD_SIZE);
284                 memcpy(s->s3->previous_client_finished, 
285                     s->s3->tmp.peer_finish_md, i);
286                 s->s3->previous_client_finished_len=i;
287                 }
288         else
289                 {
290                 assert(i <= EVP_MAX_MD_SIZE);
291                 memcpy(s->s3->previous_server_finished, 
292                     s->s3->tmp.peer_finish_md, i);
293                 s->s3->previous_server_finished_len=i;
294                 }
295
296         return(1);
297 f_err:
298         ssl3_send_alert(s,SSL3_AL_FATAL,al);
299         return(0);
300         }
301
302 /* for these 2 messages, we need to
303  * ssl->enc_read_ctx                    re-init
304  * ssl->s3->read_sequence               zero
305  * ssl->s3->read_mac_secret             re-init
306  * ssl->session->read_sym_enc           assign
307  * ssl->session->read_compression       assign
308  * ssl->session->read_hash              assign
309  */
310 int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
311         { 
312         unsigned char *p;
313
314         if (s->state == a)
315                 {
316                 p=(unsigned char *)s->init_buf->data;
317                 *p=SSL3_MT_CCS;
318                 s->init_num=1;
319                 s->init_off=0;
320
321                 s->state=b;
322                 }
323
324         /* SSL3_ST_CW_CHANGE_B */
325         return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC, dont_add_to_finished_hash));
326         }
327
328 unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk)
329         {
330         unsigned char *p;
331         unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s);
332
333         if (!ssl_add_cert_chain(s, cpk, &l))
334                 return 0;
335
336         l -= 3 + SSL_HM_HEADER_LENGTH(s);
337         p = ssl_handshake_start(s);
338         l2n3(l,p);
339         l += 3;
340         ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l);
341         return l + SSL_HM_HEADER_LENGTH(s);
342         }
343
344 /* Obtain handshake message of message type 'mt' (any if mt == -1),
345  * maximum acceptable body length 'max'.
346  * The first four bytes (msg_type and length) are read in state 'st1',
347  * the body is read in state 'stn'.
348  */
349 long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int hash_message, int *ok)
350         {
351         unsigned char *p;
352         unsigned long l;
353         long n;
354         int i,al;
355
356         if (s->s3->tmp.reuse_message)
357                 {
358                 /* A SSL_GET_MESSAGE_DONT_HASH_MESSAGE call cannot be combined
359                  * with reuse_message; the SSL_GET_MESSAGE_DONT_HASH_MESSAGE
360                  * would have to have been applied to the previous call. */
361                 assert(hash_message != SSL_GET_MESSAGE_DONT_HASH_MESSAGE);
362                 s->s3->tmp.reuse_message=0;
363                 if ((mt >= 0) && (s->s3->tmp.message_type != mt))
364                         {
365                         al=SSL_AD_UNEXPECTED_MESSAGE;
366                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_UNEXPECTED_MESSAGE);
367                         goto f_err;
368                         }
369                 *ok=1;
370                 s->init_msg = (uint8_t*)s->init_buf->data + 4;
371                 s->init_num = (int)s->s3->tmp.message_size;
372                 return s->init_num;
373                 }
374
375         p=(unsigned char *)s->init_buf->data;
376
377         if (s->state == st1) /* s->init_num < 4 */
378                 {
379                 int skip_message;
380
381                 do
382                         {
383                         while (s->init_num < 4)
384                                 {
385                                 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
386                                         &p[s->init_num],4 - s->init_num, 0);
387                                 if (i <= 0)
388                                         {
389                                         s->rwstate=SSL_READING;
390                                         *ok = 0;
391                                         return i;
392                                         }
393                                 s->init_num+=i;
394                                 }
395                         
396                         skip_message = 0;
397                         if (!s->server)
398                                 if (p[0] == SSL3_MT_HELLO_REQUEST)
399                                         /* The server may always send 'Hello Request' messages --
400                                          * we are doing a handshake anyway now, so ignore them
401                                          * if their format is correct. Does not count for
402                                          * 'Finished' MAC. */
403                                         if (p[1] == 0 && p[2] == 0 &&p[3] == 0)
404                                                 {
405                                                 s->init_num = 0;
406                                                 skip_message = 1;
407
408                                                 if (s->msg_callback)
409                                                         s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, 4, s, s->msg_callback_arg);
410                                                 }
411                         }
412                 while (skip_message);
413
414                 /* s->init_num == 4 */
415
416                 if ((mt >= 0) && (*p != mt))
417                         {
418                         al=SSL_AD_UNEXPECTED_MESSAGE;
419                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_UNEXPECTED_MESSAGE);
420                         goto f_err;
421                         }
422                 s->s3->tmp.message_type= *(p++);
423
424                 n2l3(p,l);
425                 if (l > (unsigned long)max)
426                         {
427                         al=SSL_AD_ILLEGAL_PARAMETER;
428                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_EXCESSIVE_MESSAGE_SIZE);
429                         goto f_err;
430                         }
431                 if (l > (INT_MAX-4)) /* BUF_MEM_grow takes an 'int' parameter */
432                         {
433                         al=SSL_AD_ILLEGAL_PARAMETER;
434                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_EXCESSIVE_MESSAGE_SIZE);
435                         goto f_err;
436                         }
437                 if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l+4))
438                         {
439                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, ERR_R_BUF_LIB);
440                         goto err;
441                         }
442                 s->s3->tmp.message_size=l;
443                 s->state=stn;
444
445                 s->init_msg = (uint8_t*)s->init_buf->data + 4;
446                 s->init_num = 0;
447                 }
448
449         /* next state (stn) */
450         p = s->init_msg;
451         n = s->s3->tmp.message_size - s->init_num;
452         while (n > 0)
453                 {
454                 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0);
455                 if (i <= 0)
456                         {
457                         s->rwstate=SSL_READING;
458                         *ok = 0;
459                         return i;
460                         }
461                 s->init_num += i;
462                 n -= i;
463                 }
464
465         /* Feed this message into MAC computation. */
466         if (hash_message != SSL_GET_MESSAGE_DONT_HASH_MESSAGE)
467                 ssl3_hash_current_message(s);
468         if (s->msg_callback)
469                 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
470         *ok=1;
471         return s->init_num;
472 f_err:
473         ssl3_send_alert(s,SSL3_AL_FATAL,al);
474 err:
475         *ok=0;
476         return(-1);
477         }
478
479 void ssl3_hash_current_message(SSL *s)
480         {
481         /* The handshake header (different size between DTLS and TLS) is included in the hash. */
482         size_t header_len = s->init_msg - (uint8_t *)s->init_buf->data;
483         ssl3_finish_mac(s, (uint8_t *)s->init_buf->data, s->init_num + header_len);
484         }
485
486 /* ssl3_cert_verify_hash is documented as needing EVP_MAX_MD_SIZE because that
487  * is sufficient pre-TLS1.2 as well. */
488 OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE > MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
489         combined_tls_hash_fits_in_max);
490
491 int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len, const EVP_MD **out_md, EVP_PKEY *pkey)
492         {
493         /* For TLS v1.2 send signature algorithm and signature using
494          * agreed digest and cached handshake records. Otherwise, use
495          * SHA1 or MD5 + SHA1 depending on key type.  */
496         if (SSL_USE_SIGALGS(s))
497                 {
498                 const uint8_t *hdata;
499                 size_t hdatalen;
500                 EVP_MD_CTX mctx;
501                 unsigned len;
502
503                 if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen))
504                         {
505                         OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_INTERNAL_ERROR);
506                         return 0;
507                         }
508                 EVP_MD_CTX_init(&mctx);
509                 if (!EVP_DigestInit_ex(&mctx, *out_md, NULL)
510                         || !EVP_DigestUpdate(&mctx, hdata, hdatalen)
511                         || !EVP_DigestFinal(&mctx, out, &len))
512                         {
513                         OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_EVP_LIB);
514                         EVP_MD_CTX_cleanup(&mctx);
515                         return 0;
516                         }
517                 *out_len = len;
518                 }
519         else if (pkey->type == EVP_PKEY_RSA)
520                 {
521                 if (s->method->ssl3_enc->cert_verify_mac(s, NID_md5, out) == 0 ||
522                         s->method->ssl3_enc->cert_verify_mac(s,
523                                 NID_sha1, out + MD5_DIGEST_LENGTH) == 0)
524                         return 0;
525                 *out_len = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH;
526                 /* Using a NULL signature MD makes EVP_PKEY_sign perform
527                  * a raw RSA signature, rather than wrapping in a
528                  * DigestInfo. */
529                 *out_md = NULL;
530                 }
531         else if (pkey->type == EVP_PKEY_EC)
532                 {
533                 if (s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, out) == 0)
534                         return 0;
535                 *out_len = SHA_DIGEST_LENGTH;
536                 *out_md = EVP_sha1();
537                 }
538         else
539                 {
540                 OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_INTERNAL_ERROR);
541                 return 0;
542                 }
543         return 1;
544         }
545
546 int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
547         {
548         EVP_PKEY *pk;
549         int ret= -1,i;
550
551         if (pkey == NULL)
552                 pk=X509_get_pubkey(x);
553         else
554                 pk=pkey;
555         if (pk == NULL) goto err;
556
557         i=pk->type;
558         if (i == EVP_PKEY_RSA)
559                 {
560                 ret=SSL_PKEY_RSA_ENC;
561                 }
562         else if (i == EVP_PKEY_EC)
563                 {
564                 ret = SSL_PKEY_ECC;
565                 }       
566                 
567 err:
568         if(!pkey) EVP_PKEY_free(pk);
569         return(ret);
570         }
571
572 int ssl_verify_alarm_type(long type)
573         {
574         int al;
575
576         switch(type)
577                 {
578         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
579         case X509_V_ERR_UNABLE_TO_GET_CRL:
580         case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
581                 al=SSL_AD_UNKNOWN_CA;
582                 break;
583         case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
584         case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
585         case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
586         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
587         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
588         case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
589         case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
590         case X509_V_ERR_CERT_NOT_YET_VALID:
591         case X509_V_ERR_CRL_NOT_YET_VALID:
592         case X509_V_ERR_CERT_UNTRUSTED:
593         case X509_V_ERR_CERT_REJECTED:
594                 al=SSL_AD_BAD_CERTIFICATE;
595                 break;
596         case X509_V_ERR_CERT_SIGNATURE_FAILURE:
597         case X509_V_ERR_CRL_SIGNATURE_FAILURE:
598                 al=SSL_AD_DECRYPT_ERROR;
599                 break;
600         case X509_V_ERR_CERT_HAS_EXPIRED:
601         case X509_V_ERR_CRL_HAS_EXPIRED:
602                 al=SSL_AD_CERTIFICATE_EXPIRED;
603                 break;
604         case X509_V_ERR_CERT_REVOKED:
605                 al=SSL_AD_CERTIFICATE_REVOKED;
606                 break;
607         case X509_V_ERR_OUT_OF_MEM:
608                 al=SSL_AD_INTERNAL_ERROR;
609                 break;
610         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
611         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
612         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
613         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
614         case X509_V_ERR_CERT_CHAIN_TOO_LONG:
615         case X509_V_ERR_PATH_LENGTH_EXCEEDED:
616         case X509_V_ERR_INVALID_CA:
617                 al=SSL_AD_UNKNOWN_CA;
618                 break;
619         case X509_V_ERR_APPLICATION_VERIFICATION:
620                 al=SSL_AD_HANDSHAKE_FAILURE;
621                 break;
622         case X509_V_ERR_INVALID_PURPOSE:
623                 al=SSL_AD_UNSUPPORTED_CERTIFICATE;
624                 break;
625         default:
626                 al=SSL_AD_CERTIFICATE_UNKNOWN;
627                 break;
628                 }
629         return(al);
630         }
631
632 int ssl3_setup_read_buffer(SSL *s)
633         {
634         unsigned char *p;
635         size_t len,align=0,headerlen;
636         
637         if (SSL_IS_DTLS(s))
638                 headerlen = DTLS1_RT_HEADER_LENGTH;
639         else
640                 headerlen = SSL3_RT_HEADER_LENGTH;
641
642 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
643         align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
644 #endif
645
646         if (s->s3->rbuf.buf == NULL)
647                 {
648                 len = SSL3_RT_MAX_PLAIN_LENGTH
649                         + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
650                         + headerlen + align;
651                 if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
652                         {
653                         s->s3->init_extra = 1;
654                         len += SSL3_RT_MAX_EXTRA;
655                         }
656                 if ((p=OPENSSL_malloc(len)) == NULL)
657                         goto err;
658                 s->s3->rbuf.buf = p;
659                 s->s3->rbuf.len = len;
660                 }
661
662         s->packet= &(s->s3->rbuf.buf[0]);
663         return 1;
664
665 err:
666         OPENSSL_PUT_ERROR(SSL, ssl3_setup_read_buffer, ERR_R_MALLOC_FAILURE);
667         return 0;
668         }
669
670 int ssl3_setup_write_buffer(SSL *s)
671         {
672         unsigned char *p;
673         size_t len,align=0,headerlen;
674
675         if (SSL_IS_DTLS(s))
676                 headerlen = DTLS1_RT_HEADER_LENGTH + 1;
677         else
678                 headerlen = SSL3_RT_HEADER_LENGTH;
679
680 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
681         align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
682 #endif
683
684         if (s->s3->wbuf.buf == NULL)
685                 {
686                 len = s->max_send_fragment
687                         + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
688                         + headerlen + align;
689                 /* Account for 1/n-1 record splitting. */
690                 if (s->mode & SSL_MODE_CBC_RECORD_SPLITTING)
691                         len += headerlen + align + 1
692                                 + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
693
694                 if ((p=OPENSSL_malloc(len)) == NULL)
695                         goto err;
696                 s->s3->wbuf.buf = p;
697                 s->s3->wbuf.len = len;
698                 }
699
700         return 1;
701
702 err:
703         OPENSSL_PUT_ERROR(SSL, ssl3_setup_write_buffer, ERR_R_MALLOC_FAILURE);
704         return 0;
705         }
706
707
708 int ssl3_setup_buffers(SSL *s)
709         {
710         if (!ssl3_setup_read_buffer(s))
711                 return 0;
712         if (!ssl3_setup_write_buffer(s))
713                 return 0;
714         return 1;
715         }
716
717 int ssl3_release_write_buffer(SSL *s)
718         {
719         if (s->s3->wbuf.buf != NULL)
720                 {
721                 OPENSSL_free(s->s3->wbuf.buf);
722                 s->s3->wbuf.buf = NULL;
723                 }
724         return 1;
725         }
726
727 int ssl3_release_read_buffer(SSL *s)
728         {
729         if (s->s3->rbuf.buf != NULL)
730                 {
731                 OPENSSL_free(s->s3->rbuf.buf);
732                 s->s3->rbuf.buf = NULL;
733                 }
734         return 1;
735         }
736