Upstream version 9.38.198.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/obj.h>
122 #include <openssl/rand.h>
123 #include <openssl/x509.h>
124
125 #include "ssl_locl.h"
126
127 /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
128 int ssl3_do_write(SSL *s, int type)
129         {
130         int ret;
131
132         ret=ssl3_write_bytes(s,type,&s->init_buf->data[s->init_off],
133                              s->init_num);
134         if (ret < 0) return(-1);
135         if (type == SSL3_RT_HANDSHAKE)
136                 /* should not be done for 'Hello Request's, but in that case
137                  * we'll ignore the result anyway */
138                 ssl3_finish_mac(s,(unsigned char *)&s->init_buf->data[s->init_off],ret);
139         
140         if (ret == s->init_num)
141                 {
142                 if (s->msg_callback)
143                         s->msg_callback(1, s->version, type, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
144                 return(1);
145                 }
146         s->init_off+=ret;
147         s->init_num-=ret;
148         return(0);
149         }
150
151 int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
152         {
153         unsigned char *p;
154         int i;
155         unsigned long l;
156
157         if (s->state == a)
158                 {
159                 p = ssl_handshake_start(s);
160
161                 i=s->method->ssl3_enc->final_finish_mac(s,
162                         sender,slen,s->s3->tmp.finish_md);
163                 if (i == 0)
164                         return 0;
165                 s->s3->tmp.finish_md_len = i;
166                 memcpy(p, s->s3->tmp.finish_md, i);
167                 l=i;
168
169                 /* Copy the finished so we can use it for
170                    renegotiation checks */
171                 if(s->type == SSL_ST_CONNECT)
172                         {
173                          assert(i <= EVP_MAX_MD_SIZE);
174                          memcpy(s->s3->previous_client_finished, 
175                              s->s3->tmp.finish_md, i);
176                          s->s3->previous_client_finished_len=i;
177                         }
178                 else
179                         {
180                         assert(i <= EVP_MAX_MD_SIZE);
181                         memcpy(s->s3->previous_server_finished, 
182                             s->s3->tmp.finish_md, i);
183                         s->s3->previous_server_finished_len=i;
184                         }
185
186 #ifdef OPENSSL_SYS_WIN16
187                 /* MSVC 1.5 does not clear the top bytes of the word unless
188                  * I do this.
189                  */
190                 l&=0xffff;
191 #endif
192                 ssl_set_handshake_header(s, SSL3_MT_FINISHED, l);
193                 s->state=b;
194                 }
195
196         /* SSL3_ST_SEND_xxxxxx_HELLO_B */
197         return ssl_do_write(s);
198         }
199
200 #ifndef OPENSSL_NO_NEXTPROTONEG
201 /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
202 static void ssl3_take_mac(SSL *s)
203         {
204         const char *sender;
205         int slen;
206         /* If no new cipher setup return immediately: other functions will
207          * set the appropriate error.
208          */
209         if (s->s3->tmp.new_cipher == NULL)
210                 return;
211         if (s->state & SSL_ST_CONNECT)
212                 {
213                 sender=s->method->ssl3_enc->server_finished_label;
214                 slen=s->method->ssl3_enc->server_finished_label_len;
215                 }
216         else
217                 {
218                 sender=s->method->ssl3_enc->client_finished_label;
219                 slen=s->method->ssl3_enc->client_finished_label_len;
220                 }
221
222         s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
223                 sender,slen,s->s3->tmp.peer_finish_md);
224         }
225 #endif
226
227 int ssl3_get_finished(SSL *s, int a, int b)
228         {
229         int al,i,ok;
230         long n;
231         unsigned char *p;
232
233 #ifdef OPENSSL_NO_NEXTPROTONEG
234         /* the mac has already been generated when we received the
235          * change cipher spec message and is in s->s3->tmp.peer_finish_md
236          */ 
237 #endif
238
239         n=s->method->ssl_get_message(s,
240                 a,
241                 b,
242                 SSL3_MT_FINISHED,
243                 64, /* should actually be 36+4 :-) */
244                 &ok);
245
246         if (!ok) return((int)n);
247
248         /* If this occurs, we have missed a message.
249          * TODO(davidben): Is this check now redundant with
250          * SSL3_FLAGS_EXPECT_CCS? */
251         if (!s->s3->change_cipher_spec)
252                 {
253                 al=SSL_AD_UNEXPECTED_MESSAGE;
254                 OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
255                 goto f_err;
256                 }
257         s->s3->change_cipher_spec=0;
258
259         p = s->init_msg;
260         i = s->s3->tmp.peer_finish_md_len;
261
262         if (i != n)
263                 {
264                 al=SSL_AD_DECODE_ERROR;
265                 OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_BAD_DIGEST_LENGTH);
266                 goto f_err;
267                 }
268
269         if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
270                 {
271                 al=SSL_AD_DECRYPT_ERROR;
272                 OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_DIGEST_CHECK_FAILED);
273                 goto f_err;
274                 }
275
276         /* Copy the finished so we can use it for
277            renegotiation checks */
278         if(s->type == SSL_ST_ACCEPT)
279                 {
280                 assert(i <= EVP_MAX_MD_SIZE);
281                 memcpy(s->s3->previous_client_finished, 
282                     s->s3->tmp.peer_finish_md, i);
283                 s->s3->previous_client_finished_len=i;
284                 }
285         else
286                 {
287                 assert(i <= EVP_MAX_MD_SIZE);
288                 memcpy(s->s3->previous_server_finished, 
289                     s->s3->tmp.peer_finish_md, i);
290                 s->s3->previous_server_finished_len=i;
291                 }
292
293         return(1);
294 f_err:
295         ssl3_send_alert(s,SSL3_AL_FATAL,al);
296         return(0);
297         }
298
299 /* for these 2 messages, we need to
300  * ssl->enc_read_ctx                    re-init
301  * ssl->s3->read_sequence               zero
302  * ssl->s3->read_mac_secret             re-init
303  * ssl->session->read_sym_enc           assign
304  * ssl->session->read_compression       assign
305  * ssl->session->read_hash              assign
306  */
307 int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
308         { 
309         unsigned char *p;
310
311         if (s->state == a)
312                 {
313                 p=(unsigned char *)s->init_buf->data;
314                 *p=SSL3_MT_CCS;
315                 s->init_num=1;
316                 s->init_off=0;
317
318                 s->state=b;
319                 }
320
321         /* SSL3_ST_CW_CHANGE_B */
322         return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
323         }
324
325 unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk)
326         {
327         unsigned char *p;
328         unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s);
329
330         if (!ssl_add_cert_chain(s, cpk, &l))
331                 return 0;
332
333         l -= 3 + SSL_HM_HEADER_LENGTH(s);
334         p = ssl_handshake_start(s);
335         l2n3(l,p);
336         l += 3;
337         ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l);
338         return l + SSL_HM_HEADER_LENGTH(s);
339         }
340
341 /* Obtain handshake message of message type 'mt' (any if mt == -1),
342  * maximum acceptable body length 'max'.
343  * The first four bytes (msg_type and length) are read in state 'st1',
344  * the body is read in state 'stn'.
345  */
346 long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
347         {
348         unsigned char *p;
349         unsigned long l;
350         long n;
351         int i,al;
352
353         if (s->s3->tmp.reuse_message)
354                 {
355                 s->s3->tmp.reuse_message=0;
356                 if ((mt >= 0) && (s->s3->tmp.message_type != mt))
357                         {
358                         al=SSL_AD_UNEXPECTED_MESSAGE;
359                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_UNEXPECTED_MESSAGE);
360                         goto f_err;
361                         }
362                 *ok=1;
363                 s->init_msg = (uint8_t*)s->init_buf->data + 4;
364                 s->init_num = (int)s->s3->tmp.message_size;
365                 return s->init_num;
366                 }
367
368         p=(unsigned char *)s->init_buf->data;
369
370         if (s->state == st1) /* s->init_num < 4 */
371                 {
372                 int skip_message;
373
374                 do
375                         {
376                         while (s->init_num < 4)
377                                 {
378                                 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
379                                         &p[s->init_num],4 - s->init_num, 0);
380                                 if (i <= 0)
381                                         {
382                                         s->rwstate=SSL_READING;
383                                         *ok = 0;
384                                         return i;
385                                         }
386                                 s->init_num+=i;
387                                 }
388                         
389                         skip_message = 0;
390                         if (!s->server)
391                                 if (p[0] == SSL3_MT_HELLO_REQUEST)
392                                         /* The server may always send 'Hello Request' messages --
393                                          * we are doing a handshake anyway now, so ignore them
394                                          * if their format is correct. Does not count for
395                                          * 'Finished' MAC. */
396                                         if (p[1] == 0 && p[2] == 0 &&p[3] == 0)
397                                                 {
398                                                 s->init_num = 0;
399                                                 skip_message = 1;
400
401                                                 if (s->msg_callback)
402                                                         s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, 4, s, s->msg_callback_arg);
403                                                 }
404                         }
405                 while (skip_message);
406
407                 /* s->init_num == 4 */
408
409                 if ((mt >= 0) && (*p != mt))
410                         {
411                         al=SSL_AD_UNEXPECTED_MESSAGE;
412                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_UNEXPECTED_MESSAGE);
413                         goto f_err;
414                         }
415                 if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
416                                         (st1 == SSL3_ST_SR_CERT_A) &&
417                                         (stn == SSL3_ST_SR_CERT_B))
418                         {
419                         /* At this point we have got an MS SGC second client
420                          * hello (maybe we should always allow the client to
421                          * start a new handshake?). We need to restart the mac.
422                          * Don't increment {num,total}_renegotiations because
423                          * we have not completed the handshake. */
424                         ssl3_init_finished_mac(s);
425                         }
426
427                 s->s3->tmp.message_type= *(p++);
428
429                 n2l3(p,l);
430                 if (l > (unsigned long)max)
431                         {
432                         al=SSL_AD_ILLEGAL_PARAMETER;
433                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_EXCESSIVE_MESSAGE_SIZE);
434                         goto f_err;
435                         }
436                 if (l > (INT_MAX-4)) /* BUF_MEM_grow takes an 'int' parameter */
437                         {
438                         al=SSL_AD_ILLEGAL_PARAMETER;
439                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_EXCESSIVE_MESSAGE_SIZE);
440                         goto f_err;
441                         }
442                 if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l+4))
443                         {
444                         OPENSSL_PUT_ERROR(SSL, ssl3_get_message, ERR_R_BUF_LIB);
445                         goto err;
446                         }
447                 s->s3->tmp.message_size=l;
448                 s->state=stn;
449
450                 s->init_msg = (uint8_t*)s->init_buf->data + 4;
451                 s->init_num = 0;
452                 }
453
454         /* next state (stn) */
455         p = s->init_msg;
456         n = s->s3->tmp.message_size - s->init_num;
457         while (n > 0)
458                 {
459                 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0);
460                 if (i <= 0)
461                         {
462                         s->rwstate=SSL_READING;
463                         *ok = 0;
464                         return i;
465                         }
466                 s->init_num += i;
467                 n -= i;
468                 }
469
470 #ifndef OPENSSL_NO_NEXTPROTONEG
471         /* If receiving Finished, record MAC of prior handshake messages for
472          * Finished verification. */
473         if (*s->init_buf->data == SSL3_MT_FINISHED)
474                 ssl3_take_mac(s);
475 #endif
476
477         /* Feed this message into MAC computation. */
478         if (*((unsigned char*) s->init_buf->data) != SSL3_MT_ENCRYPTED_EXTENSIONS)
479                 ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
480         if (s->msg_callback)
481                 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
482         *ok=1;
483         return s->init_num;
484 f_err:
485         ssl3_send_alert(s,SSL3_AL_FATAL,al);
486 err:
487         *ok=0;
488         return(-1);
489         }
490
491 int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
492         {
493         EVP_PKEY *pk;
494         int ret= -1,i;
495
496         if (pkey == NULL)
497                 pk=X509_get_pubkey(x);
498         else
499                 pk=pkey;
500         if (pk == NULL) goto err;
501
502         i=pk->type;
503         if (i == EVP_PKEY_RSA)
504                 {
505                 ret=SSL_PKEY_RSA_ENC;
506                 }
507         else if (i == EVP_PKEY_DSA)
508                 {
509                 ret=SSL_PKEY_DSA_SIGN;
510                 }
511 #ifndef OPENSSL_NO_EC
512         else if (i == EVP_PKEY_EC)
513                 {
514                 ret = SSL_PKEY_ECC;
515                 }       
516 #endif
517         else if (x && (i == EVP_PKEY_DH || i == EVP_PKEY_DHX))
518                 {
519                 /* For DH two cases: DH certificate signed with RSA and
520                  * DH certificate signed with DSA.
521                  */
522                 i = X509_certificate_type(x, pk);
523                 if (i & EVP_PKS_RSA)
524                         ret = SSL_PKEY_DH_RSA;
525                 else if (i & EVP_PKS_DSA)
526                         ret = SSL_PKEY_DH_DSA;
527                 }
528                 
529 err:
530         if(!pkey) EVP_PKEY_free(pk);
531         return(ret);
532         }
533
534 int ssl_verify_alarm_type(long type)
535         {
536         int al;
537
538         switch(type)
539                 {
540         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
541         case X509_V_ERR_UNABLE_TO_GET_CRL:
542         case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
543                 al=SSL_AD_UNKNOWN_CA;
544                 break;
545         case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
546         case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
547         case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
548         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
549         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
550         case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
551         case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
552         case X509_V_ERR_CERT_NOT_YET_VALID:
553         case X509_V_ERR_CRL_NOT_YET_VALID:
554         case X509_V_ERR_CERT_UNTRUSTED:
555         case X509_V_ERR_CERT_REJECTED:
556                 al=SSL_AD_BAD_CERTIFICATE;
557                 break;
558         case X509_V_ERR_CERT_SIGNATURE_FAILURE:
559         case X509_V_ERR_CRL_SIGNATURE_FAILURE:
560                 al=SSL_AD_DECRYPT_ERROR;
561                 break;
562         case X509_V_ERR_CERT_HAS_EXPIRED:
563         case X509_V_ERR_CRL_HAS_EXPIRED:
564                 al=SSL_AD_CERTIFICATE_EXPIRED;
565                 break;
566         case X509_V_ERR_CERT_REVOKED:
567                 al=SSL_AD_CERTIFICATE_REVOKED;
568                 break;
569         case X509_V_ERR_OUT_OF_MEM:
570                 al=SSL_AD_INTERNAL_ERROR;
571                 break;
572         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
573         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
574         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
575         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
576         case X509_V_ERR_CERT_CHAIN_TOO_LONG:
577         case X509_V_ERR_PATH_LENGTH_EXCEEDED:
578         case X509_V_ERR_INVALID_CA:
579                 al=SSL_AD_UNKNOWN_CA;
580                 break;
581         case X509_V_ERR_APPLICATION_VERIFICATION:
582                 al=SSL_AD_HANDSHAKE_FAILURE;
583                 break;
584         case X509_V_ERR_INVALID_PURPOSE:
585                 al=SSL_AD_UNSUPPORTED_CERTIFICATE;
586                 break;
587         default:
588                 al=SSL_AD_CERTIFICATE_UNKNOWN;
589                 break;
590                 }
591         return(al);
592         }
593
594 int ssl3_setup_read_buffer(SSL *s)
595         {
596         unsigned char *p;
597         size_t len,align=0,headerlen;
598         
599         if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
600                 headerlen = DTLS1_RT_HEADER_LENGTH;
601         else
602                 headerlen = SSL3_RT_HEADER_LENGTH;
603
604 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
605         align = (-SSL3_RT_HEADER_LENGTH)&(SSL3_ALIGN_PAYLOAD-1);
606 #endif
607
608         if (s->s3->rbuf.buf == NULL)
609                 {
610                 len = SSL3_RT_MAX_PLAIN_LENGTH
611                         + SSL3_RT_MAX_ENCRYPTED_OVERHEAD
612                         + headerlen + align;
613                 if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
614                         {
615                         s->s3->init_extra = 1;
616                         len += SSL3_RT_MAX_EXTRA;
617                         }
618                 if ((p=OPENSSL_malloc(len)) == NULL)
619                         goto err;
620                 s->s3->rbuf.buf = p;
621                 s->s3->rbuf.len = len;
622                 }
623
624         s->packet= &(s->s3->rbuf.buf[0]);
625         return 1;
626
627 err:
628         OPENSSL_PUT_ERROR(SSL, ssl3_setup_read_buffer, ERR_R_MALLOC_FAILURE);
629         return 0;
630         }
631
632 int ssl3_setup_write_buffer(SSL *s)
633         {
634         unsigned char *p;
635         size_t len,align=0,headerlen;
636
637         if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
638                 headerlen = DTLS1_RT_HEADER_LENGTH + 1;
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->wbuf.buf == NULL)
647                 {
648                 len = s->max_send_fragment
649                         + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
650                         + headerlen + align;
651                 if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
652                         len += headerlen + align
653                                 + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
654
655                 if ((p=OPENSSL_malloc(len)) == NULL)
656                         goto err;
657                 s->s3->wbuf.buf = p;
658                 s->s3->wbuf.len = len;
659                 }
660
661         return 1;
662
663 err:
664         OPENSSL_PUT_ERROR(SSL, ssl3_setup_write_buffer, ERR_R_MALLOC_FAILURE);
665         return 0;
666         }
667
668
669 int ssl3_setup_buffers(SSL *s)
670         {
671         if (!ssl3_setup_read_buffer(s))
672                 return 0;
673         if (!ssl3_setup_write_buffer(s))
674                 return 0;
675         return 1;
676         }
677
678 int ssl3_release_write_buffer(SSL *s)
679         {
680         if (s->s3->wbuf.buf != NULL)
681                 {
682                 OPENSSL_free(s->s3->wbuf.buf);
683                 s->s3->wbuf.buf = NULL;
684                 }
685         return 1;
686         }
687
688 int ssl3_release_read_buffer(SSL *s)
689         {
690         if (s->s3->rbuf.buf != NULL)
691                 {
692                 OPENSSL_free(s->s3->rbuf.buf);
693                 s->s3->rbuf.buf = NULL;
694                 }
695         return 1;
696         }
697