10Sstevel@tonic-gate /* ssl/s3_both.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
580Sstevel@tonic-gate /* ====================================================================
590Sstevel@tonic-gate * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
600Sstevel@tonic-gate *
610Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
620Sstevel@tonic-gate * modification, are permitted provided that the following conditions
630Sstevel@tonic-gate * are met:
640Sstevel@tonic-gate *
650Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
660Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
670Sstevel@tonic-gate *
680Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
690Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
700Sstevel@tonic-gate * the documentation and/or other materials provided with the
710Sstevel@tonic-gate * distribution.
720Sstevel@tonic-gate *
730Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
740Sstevel@tonic-gate * software must display the following acknowledgment:
750Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
760Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
770Sstevel@tonic-gate *
780Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
790Sstevel@tonic-gate * endorse or promote products derived from this software without
800Sstevel@tonic-gate * prior written permission. For written permission, please contact
810Sstevel@tonic-gate * openssl-core@openssl.org.
820Sstevel@tonic-gate *
830Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
840Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
850Sstevel@tonic-gate * permission of the OpenSSL Project.
860Sstevel@tonic-gate *
870Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
880Sstevel@tonic-gate * acknowledgment:
890Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
900Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
910Sstevel@tonic-gate *
920Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
930Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
940Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
950Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
960Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
970Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
980Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
990Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1000Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1010Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1020Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1030Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
1040Sstevel@tonic-gate * ====================================================================
1050Sstevel@tonic-gate *
1060Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
1070Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
1080Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
1090Sstevel@tonic-gate *
1100Sstevel@tonic-gate */
111*2139Sjp161948 /* ====================================================================
112*2139Sjp161948 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113*2139Sjp161948 * ECC cipher suite support in OpenSSL originally developed by
114*2139Sjp161948 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115*2139Sjp161948 */
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate #include <limits.h>
1180Sstevel@tonic-gate #include <string.h>
1190Sstevel@tonic-gate #include <stdio.h>
1200Sstevel@tonic-gate #include "ssl_locl.h"
1210Sstevel@tonic-gate #include <openssl/buffer.h>
1220Sstevel@tonic-gate #include <openssl/rand.h>
1230Sstevel@tonic-gate #include <openssl/objects.h>
1240Sstevel@tonic-gate #include <openssl/evp.h>
1250Sstevel@tonic-gate #include <openssl/x509.h>
1260Sstevel@tonic-gate
1270Sstevel@tonic-gate /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
ssl3_do_write(SSL * s,int type)1280Sstevel@tonic-gate int ssl3_do_write(SSL *s, int type)
1290Sstevel@tonic-gate {
1300Sstevel@tonic-gate int ret;
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate ret=ssl3_write_bytes(s,type,&s->init_buf->data[s->init_off],
1330Sstevel@tonic-gate s->init_num);
1340Sstevel@tonic-gate if (ret < 0) return(-1);
1350Sstevel@tonic-gate if (type == SSL3_RT_HANDSHAKE)
1360Sstevel@tonic-gate /* should not be done for 'Hello Request's, but in that case
1370Sstevel@tonic-gate * we'll ignore the result anyway */
1380Sstevel@tonic-gate ssl3_finish_mac(s,(unsigned char *)&s->init_buf->data[s->init_off],ret);
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate if (ret == s->init_num)
1410Sstevel@tonic-gate {
1420Sstevel@tonic-gate if (s->msg_callback)
1430Sstevel@tonic-gate s->msg_callback(1, s->version, type, s->init_buf->data, (size_t)(s->init_off + s->init_num), s, s->msg_callback_arg);
1440Sstevel@tonic-gate return(1);
1450Sstevel@tonic-gate }
1460Sstevel@tonic-gate s->init_off+=ret;
1470Sstevel@tonic-gate s->init_num-=ret;
1480Sstevel@tonic-gate return(0);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate
ssl3_send_finished(SSL * s,int a,int b,const char * sender,int slen)1510Sstevel@tonic-gate int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
1520Sstevel@tonic-gate {
1530Sstevel@tonic-gate unsigned char *p,*d;
1540Sstevel@tonic-gate int i;
1550Sstevel@tonic-gate unsigned long l;
1560Sstevel@tonic-gate
1570Sstevel@tonic-gate if (s->state == a)
1580Sstevel@tonic-gate {
1590Sstevel@tonic-gate d=(unsigned char *)s->init_buf->data;
1600Sstevel@tonic-gate p= &(d[4]);
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate i=s->method->ssl3_enc->final_finish_mac(s,
1630Sstevel@tonic-gate &(s->s3->finish_dgst1),
1640Sstevel@tonic-gate &(s->s3->finish_dgst2),
1650Sstevel@tonic-gate sender,slen,s->s3->tmp.finish_md);
1660Sstevel@tonic-gate s->s3->tmp.finish_md_len = i;
1670Sstevel@tonic-gate memcpy(p, s->s3->tmp.finish_md, i);
1680Sstevel@tonic-gate p+=i;
1690Sstevel@tonic-gate l=i;
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate #ifdef OPENSSL_SYS_WIN16
1720Sstevel@tonic-gate /* MSVC 1.5 does not clear the top bytes of the word unless
1730Sstevel@tonic-gate * I do this.
1740Sstevel@tonic-gate */
1750Sstevel@tonic-gate l&=0xffff;
1760Sstevel@tonic-gate #endif
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate *(d++)=SSL3_MT_FINISHED;
1790Sstevel@tonic-gate l2n3(l,d);
1800Sstevel@tonic-gate s->init_num=(int)l+4;
1810Sstevel@tonic-gate s->init_off=0;
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate s->state=b;
1840Sstevel@tonic-gate }
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate /* SSL3_ST_SEND_xxxxxx_HELLO_B */
1870Sstevel@tonic-gate return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate
ssl3_get_finished(SSL * s,int a,int b)1900Sstevel@tonic-gate int ssl3_get_finished(SSL *s, int a, int b)
1910Sstevel@tonic-gate {
1920Sstevel@tonic-gate int al,i,ok;
1930Sstevel@tonic-gate long n;
1940Sstevel@tonic-gate unsigned char *p;
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate /* the mac has already been generated when we received the
1970Sstevel@tonic-gate * change cipher spec message and is in s->s3->tmp.peer_finish_md
1980Sstevel@tonic-gate */
1990Sstevel@tonic-gate
200*2139Sjp161948 n=s->method->ssl_get_message(s,
2010Sstevel@tonic-gate a,
2020Sstevel@tonic-gate b,
2030Sstevel@tonic-gate SSL3_MT_FINISHED,
2040Sstevel@tonic-gate 64, /* should actually be 36+4 :-) */
2050Sstevel@tonic-gate &ok);
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate if (!ok) return((int)n);
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate /* If this occurs, we have missed a message */
2100Sstevel@tonic-gate if (!s->s3->change_cipher_spec)
2110Sstevel@tonic-gate {
2120Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE;
2130Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_GOT_A_FIN_BEFORE_A_CCS);
2140Sstevel@tonic-gate goto f_err;
2150Sstevel@tonic-gate }
2160Sstevel@tonic-gate s->s3->change_cipher_spec=0;
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate p = (unsigned char *)s->init_msg;
2190Sstevel@tonic-gate i = s->s3->tmp.peer_finish_md_len;
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate if (i != n)
2220Sstevel@tonic-gate {
2230Sstevel@tonic-gate al=SSL_AD_DECODE_ERROR;
2240Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_BAD_DIGEST_LENGTH);
2250Sstevel@tonic-gate goto f_err;
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
2290Sstevel@tonic-gate {
2300Sstevel@tonic-gate al=SSL_AD_DECRYPT_ERROR;
2310Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
2320Sstevel@tonic-gate goto f_err;
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate return(1);
2360Sstevel@tonic-gate f_err:
2370Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,al);
2380Sstevel@tonic-gate return(0);
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate /* for these 2 messages, we need to
2420Sstevel@tonic-gate * ssl->enc_read_ctx re-init
2430Sstevel@tonic-gate * ssl->s3->read_sequence zero
2440Sstevel@tonic-gate * ssl->s3->read_mac_secret re-init
2450Sstevel@tonic-gate * ssl->session->read_sym_enc assign
2460Sstevel@tonic-gate * ssl->session->read_compression assign
2470Sstevel@tonic-gate * ssl->session->read_hash assign
2480Sstevel@tonic-gate */
ssl3_send_change_cipher_spec(SSL * s,int a,int b)2490Sstevel@tonic-gate int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
2500Sstevel@tonic-gate {
2510Sstevel@tonic-gate unsigned char *p;
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate if (s->state == a)
2540Sstevel@tonic-gate {
2550Sstevel@tonic-gate p=(unsigned char *)s->init_buf->data;
2560Sstevel@tonic-gate *p=SSL3_MT_CCS;
2570Sstevel@tonic-gate s->init_num=1;
2580Sstevel@tonic-gate s->init_off=0;
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate s->state=b;
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate
2630Sstevel@tonic-gate /* SSL3_ST_CW_CHANGE_B */
2640Sstevel@tonic-gate return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
2650Sstevel@tonic-gate }
2660Sstevel@tonic-gate
ssl3_output_cert_chain(SSL * s,X509 * x)2670Sstevel@tonic-gate unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
2680Sstevel@tonic-gate {
2690Sstevel@tonic-gate unsigned char *p;
2700Sstevel@tonic-gate int n,i;
2710Sstevel@tonic-gate unsigned long l=7;
2720Sstevel@tonic-gate BUF_MEM *buf;
2730Sstevel@tonic-gate X509_STORE_CTX xs_ctx;
2740Sstevel@tonic-gate X509_OBJECT obj;
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate int no_chain;
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
2790Sstevel@tonic-gate no_chain = 1;
2800Sstevel@tonic-gate else
2810Sstevel@tonic-gate no_chain = 0;
2820Sstevel@tonic-gate
2830Sstevel@tonic-gate /* TLSv1 sends a chain with nothing in it, instead of an alert */
2840Sstevel@tonic-gate buf=s->init_buf;
2850Sstevel@tonic-gate if (!BUF_MEM_grow_clean(buf,10))
2860Sstevel@tonic-gate {
2870Sstevel@tonic-gate SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
2880Sstevel@tonic-gate return(0);
2890Sstevel@tonic-gate }
2900Sstevel@tonic-gate if (x != NULL)
2910Sstevel@tonic-gate {
2920Sstevel@tonic-gate if(!no_chain && !X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
2930Sstevel@tonic-gate {
2940Sstevel@tonic-gate SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
2950Sstevel@tonic-gate return(0);
2960Sstevel@tonic-gate }
2970Sstevel@tonic-gate
2980Sstevel@tonic-gate for (;;)
2990Sstevel@tonic-gate {
3000Sstevel@tonic-gate n=i2d_X509(x,NULL);
3010Sstevel@tonic-gate if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
3020Sstevel@tonic-gate {
3030Sstevel@tonic-gate SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
3040Sstevel@tonic-gate return(0);
3050Sstevel@tonic-gate }
3060Sstevel@tonic-gate p=(unsigned char *)&(buf->data[l]);
3070Sstevel@tonic-gate l2n3(n,p);
3080Sstevel@tonic-gate i2d_X509(x,&p);
3090Sstevel@tonic-gate l+=n+3;
3100Sstevel@tonic-gate
3110Sstevel@tonic-gate if (no_chain)
3120Sstevel@tonic-gate break;
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate if (X509_NAME_cmp(X509_get_subject_name(x),
3150Sstevel@tonic-gate X509_get_issuer_name(x)) == 0) break;
3160Sstevel@tonic-gate
3170Sstevel@tonic-gate i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
3180Sstevel@tonic-gate X509_get_issuer_name(x),&obj);
3190Sstevel@tonic-gate if (i <= 0) break;
3200Sstevel@tonic-gate x=obj.data.x509;
3210Sstevel@tonic-gate /* Count is one too high since the X509_STORE_get uped the
3220Sstevel@tonic-gate * ref count */
3230Sstevel@tonic-gate X509_free(x);
3240Sstevel@tonic-gate }
3250Sstevel@tonic-gate if (!no_chain)
3260Sstevel@tonic-gate X509_STORE_CTX_cleanup(&xs_ctx);
3270Sstevel@tonic-gate }
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate /* Thawte special :-) */
3300Sstevel@tonic-gate if (s->ctx->extra_certs != NULL)
3310Sstevel@tonic-gate for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
3320Sstevel@tonic-gate {
3330Sstevel@tonic-gate x=sk_X509_value(s->ctx->extra_certs,i);
3340Sstevel@tonic-gate n=i2d_X509(x,NULL);
3350Sstevel@tonic-gate if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
3360Sstevel@tonic-gate {
3370Sstevel@tonic-gate SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
3380Sstevel@tonic-gate return(0);
3390Sstevel@tonic-gate }
3400Sstevel@tonic-gate p=(unsigned char *)&(buf->data[l]);
3410Sstevel@tonic-gate l2n3(n,p);
3420Sstevel@tonic-gate i2d_X509(x,&p);
3430Sstevel@tonic-gate l+=n+3;
3440Sstevel@tonic-gate }
3450Sstevel@tonic-gate
3460Sstevel@tonic-gate l-=7;
3470Sstevel@tonic-gate p=(unsigned char *)&(buf->data[4]);
3480Sstevel@tonic-gate l2n3(l,p);
3490Sstevel@tonic-gate l+=3;
3500Sstevel@tonic-gate p=(unsigned char *)&(buf->data[0]);
3510Sstevel@tonic-gate *(p++)=SSL3_MT_CERTIFICATE;
3520Sstevel@tonic-gate l2n3(l,p);
3530Sstevel@tonic-gate l+=4;
3540Sstevel@tonic-gate return(l);
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate
3570Sstevel@tonic-gate /* Obtain handshake message of message type 'mt' (any if mt == -1),
3580Sstevel@tonic-gate * maximum acceptable body length 'max'.
3590Sstevel@tonic-gate * The first four bytes (msg_type and length) are read in state 'st1',
3600Sstevel@tonic-gate * the body is read in state 'stn'.
3610Sstevel@tonic-gate */
ssl3_get_message(SSL * s,int st1,int stn,int mt,long max,int * ok)3620Sstevel@tonic-gate long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
3630Sstevel@tonic-gate {
3640Sstevel@tonic-gate unsigned char *p;
3650Sstevel@tonic-gate unsigned long l;
3660Sstevel@tonic-gate long n;
3670Sstevel@tonic-gate int i,al;
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate if (s->s3->tmp.reuse_message)
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate s->s3->tmp.reuse_message=0;
3720Sstevel@tonic-gate if ((mt >= 0) && (s->s3->tmp.message_type != mt))
3730Sstevel@tonic-gate {
3740Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE;
3750Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
3760Sstevel@tonic-gate goto f_err;
3770Sstevel@tonic-gate }
3780Sstevel@tonic-gate *ok=1;
3790Sstevel@tonic-gate s->init_msg = s->init_buf->data + 4;
3800Sstevel@tonic-gate s->init_num = (int)s->s3->tmp.message_size;
3810Sstevel@tonic-gate return s->init_num;
3820Sstevel@tonic-gate }
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate p=(unsigned char *)s->init_buf->data;
3850Sstevel@tonic-gate
3860Sstevel@tonic-gate if (s->state == st1) /* s->init_num < 4 */
3870Sstevel@tonic-gate {
3880Sstevel@tonic-gate int skip_message;
3890Sstevel@tonic-gate
3900Sstevel@tonic-gate do
3910Sstevel@tonic-gate {
3920Sstevel@tonic-gate while (s->init_num < 4)
3930Sstevel@tonic-gate {
394*2139Sjp161948 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
395*2139Sjp161948 &p[s->init_num],4 - s->init_num, 0);
3960Sstevel@tonic-gate if (i <= 0)
3970Sstevel@tonic-gate {
3980Sstevel@tonic-gate s->rwstate=SSL_READING;
3990Sstevel@tonic-gate *ok = 0;
4000Sstevel@tonic-gate return i;
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate s->init_num+=i;
4030Sstevel@tonic-gate }
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate skip_message = 0;
4060Sstevel@tonic-gate if (!s->server)
4070Sstevel@tonic-gate if (p[0] == SSL3_MT_HELLO_REQUEST)
4080Sstevel@tonic-gate /* The server may always send 'Hello Request' messages --
4090Sstevel@tonic-gate * we are doing a handshake anyway now, so ignore them
4100Sstevel@tonic-gate * if their format is correct. Does not count for
4110Sstevel@tonic-gate * 'Finished' MAC. */
4120Sstevel@tonic-gate if (p[1] == 0 && p[2] == 0 &&p[3] == 0)
4130Sstevel@tonic-gate {
4140Sstevel@tonic-gate s->init_num = 0;
4150Sstevel@tonic-gate skip_message = 1;
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate if (s->msg_callback)
4180Sstevel@tonic-gate s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, 4, s, s->msg_callback_arg);
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate while (skip_message);
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate /* s->init_num == 4 */
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate if ((mt >= 0) && (*p != mt))
4260Sstevel@tonic-gate {
4270Sstevel@tonic-gate al=SSL_AD_UNEXPECTED_MESSAGE;
4280Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
4290Sstevel@tonic-gate goto f_err;
4300Sstevel@tonic-gate }
4310Sstevel@tonic-gate if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
4320Sstevel@tonic-gate (st1 == SSL3_ST_SR_CERT_A) &&
4330Sstevel@tonic-gate (stn == SSL3_ST_SR_CERT_B))
4340Sstevel@tonic-gate {
4350Sstevel@tonic-gate /* At this point we have got an MS SGC second client
4360Sstevel@tonic-gate * hello (maybe we should always allow the client to
4370Sstevel@tonic-gate * start a new handshake?). We need to restart the mac.
4380Sstevel@tonic-gate * Don't increment {num,total}_renegotiations because
4390Sstevel@tonic-gate * we have not completed the handshake. */
4400Sstevel@tonic-gate ssl3_init_finished_mac(s);
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate s->s3->tmp.message_type= *(p++);
4440Sstevel@tonic-gate
4450Sstevel@tonic-gate n2l3(p,l);
4460Sstevel@tonic-gate if (l > (unsigned long)max)
4470Sstevel@tonic-gate {
4480Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER;
4490Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
4500Sstevel@tonic-gate goto f_err;
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate if (l > (INT_MAX-4)) /* BUF_MEM_grow takes an 'int' parameter */
4530Sstevel@tonic-gate {
4540Sstevel@tonic-gate al=SSL_AD_ILLEGAL_PARAMETER;
4550Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
4560Sstevel@tonic-gate goto f_err;
4570Sstevel@tonic-gate }
4580Sstevel@tonic-gate if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l+4))
4590Sstevel@tonic-gate {
4600Sstevel@tonic-gate SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);
4610Sstevel@tonic-gate goto err;
4620Sstevel@tonic-gate }
4630Sstevel@tonic-gate s->s3->tmp.message_size=l;
4640Sstevel@tonic-gate s->state=stn;
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate s->init_msg = s->init_buf->data + 4;
4670Sstevel@tonic-gate s->init_num = 0;
4680Sstevel@tonic-gate }
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate /* next state (stn) */
4710Sstevel@tonic-gate p = s->init_msg;
4720Sstevel@tonic-gate n = s->s3->tmp.message_size - s->init_num;
4730Sstevel@tonic-gate while (n > 0)
4740Sstevel@tonic-gate {
475*2139Sjp161948 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0);
4760Sstevel@tonic-gate if (i <= 0)
4770Sstevel@tonic-gate {
4780Sstevel@tonic-gate s->rwstate=SSL_READING;
4790Sstevel@tonic-gate *ok = 0;
4800Sstevel@tonic-gate return i;
4810Sstevel@tonic-gate }
4820Sstevel@tonic-gate s->init_num += i;
4830Sstevel@tonic-gate n -= i;
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
4860Sstevel@tonic-gate if (s->msg_callback)
4870Sstevel@tonic-gate s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg);
4880Sstevel@tonic-gate *ok=1;
4890Sstevel@tonic-gate return s->init_num;
4900Sstevel@tonic-gate f_err:
4910Sstevel@tonic-gate ssl3_send_alert(s,SSL3_AL_FATAL,al);
4920Sstevel@tonic-gate err:
4930Sstevel@tonic-gate *ok=0;
4940Sstevel@tonic-gate return(-1);
4950Sstevel@tonic-gate }
4960Sstevel@tonic-gate
ssl_cert_type(X509 * x,EVP_PKEY * pkey)4970Sstevel@tonic-gate int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
4980Sstevel@tonic-gate {
4990Sstevel@tonic-gate EVP_PKEY *pk;
500*2139Sjp161948 int ret= -1,i;
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate if (pkey == NULL)
5030Sstevel@tonic-gate pk=X509_get_pubkey(x);
5040Sstevel@tonic-gate else
5050Sstevel@tonic-gate pk=pkey;
5060Sstevel@tonic-gate if (pk == NULL) goto err;
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate i=pk->type;
5090Sstevel@tonic-gate if (i == EVP_PKEY_RSA)
5100Sstevel@tonic-gate {
5110Sstevel@tonic-gate ret=SSL_PKEY_RSA_ENC;
5120Sstevel@tonic-gate }
5130Sstevel@tonic-gate else if (i == EVP_PKEY_DSA)
5140Sstevel@tonic-gate {
5150Sstevel@tonic-gate ret=SSL_PKEY_DSA_SIGN;
5160Sstevel@tonic-gate }
517*2139Sjp161948 #ifndef OPENSSL_NO_EC
518*2139Sjp161948 else if (i == EVP_PKEY_EC)
5190Sstevel@tonic-gate {
520*2139Sjp161948 ret = SSL_PKEY_ECC;
5210Sstevel@tonic-gate }
522*2139Sjp161948 #endif
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate err:
5250Sstevel@tonic-gate if(!pkey) EVP_PKEY_free(pk);
5260Sstevel@tonic-gate return(ret);
5270Sstevel@tonic-gate }
5280Sstevel@tonic-gate
ssl_verify_alarm_type(long type)5290Sstevel@tonic-gate int ssl_verify_alarm_type(long type)
5300Sstevel@tonic-gate {
5310Sstevel@tonic-gate int al;
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate switch(type)
5340Sstevel@tonic-gate {
5350Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
5360Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_GET_CRL:
5370Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
5380Sstevel@tonic-gate al=SSL_AD_UNKNOWN_CA;
5390Sstevel@tonic-gate break;
5400Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
5410Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
5420Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
5430Sstevel@tonic-gate case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
5440Sstevel@tonic-gate case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
5450Sstevel@tonic-gate case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
5460Sstevel@tonic-gate case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
5470Sstevel@tonic-gate case X509_V_ERR_CERT_NOT_YET_VALID:
5480Sstevel@tonic-gate case X509_V_ERR_CRL_NOT_YET_VALID:
5490Sstevel@tonic-gate case X509_V_ERR_CERT_UNTRUSTED:
5500Sstevel@tonic-gate case X509_V_ERR_CERT_REJECTED:
5510Sstevel@tonic-gate al=SSL_AD_BAD_CERTIFICATE;
5520Sstevel@tonic-gate break;
5530Sstevel@tonic-gate case X509_V_ERR_CERT_SIGNATURE_FAILURE:
5540Sstevel@tonic-gate case X509_V_ERR_CRL_SIGNATURE_FAILURE:
5550Sstevel@tonic-gate al=SSL_AD_DECRYPT_ERROR;
5560Sstevel@tonic-gate break;
5570Sstevel@tonic-gate case X509_V_ERR_CERT_HAS_EXPIRED:
5580Sstevel@tonic-gate case X509_V_ERR_CRL_HAS_EXPIRED:
5590Sstevel@tonic-gate al=SSL_AD_CERTIFICATE_EXPIRED;
5600Sstevel@tonic-gate break;
5610Sstevel@tonic-gate case X509_V_ERR_CERT_REVOKED:
5620Sstevel@tonic-gate al=SSL_AD_CERTIFICATE_REVOKED;
5630Sstevel@tonic-gate break;
5640Sstevel@tonic-gate case X509_V_ERR_OUT_OF_MEM:
5650Sstevel@tonic-gate al=SSL_AD_INTERNAL_ERROR;
5660Sstevel@tonic-gate break;
5670Sstevel@tonic-gate case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
5680Sstevel@tonic-gate case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
5690Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
5700Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
5710Sstevel@tonic-gate case X509_V_ERR_CERT_CHAIN_TOO_LONG:
5720Sstevel@tonic-gate case X509_V_ERR_PATH_LENGTH_EXCEEDED:
5730Sstevel@tonic-gate case X509_V_ERR_INVALID_CA:
5740Sstevel@tonic-gate al=SSL_AD_UNKNOWN_CA;
5750Sstevel@tonic-gate break;
5760Sstevel@tonic-gate case X509_V_ERR_APPLICATION_VERIFICATION:
5770Sstevel@tonic-gate al=SSL_AD_HANDSHAKE_FAILURE;
5780Sstevel@tonic-gate break;
5790Sstevel@tonic-gate case X509_V_ERR_INVALID_PURPOSE:
5800Sstevel@tonic-gate al=SSL_AD_UNSUPPORTED_CERTIFICATE;
5810Sstevel@tonic-gate break;
5820Sstevel@tonic-gate default:
5830Sstevel@tonic-gate al=SSL_AD_CERTIFICATE_UNKNOWN;
5840Sstevel@tonic-gate break;
5850Sstevel@tonic-gate }
5860Sstevel@tonic-gate return(al);
5870Sstevel@tonic-gate }
5880Sstevel@tonic-gate
ssl3_setup_buffers(SSL * s)5890Sstevel@tonic-gate int ssl3_setup_buffers(SSL *s)
5900Sstevel@tonic-gate {
5910Sstevel@tonic-gate unsigned char *p;
5920Sstevel@tonic-gate unsigned int extra;
5930Sstevel@tonic-gate size_t len;
5940Sstevel@tonic-gate
5950Sstevel@tonic-gate if (s->s3->rbuf.buf == NULL)
5960Sstevel@tonic-gate {
5970Sstevel@tonic-gate if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
5980Sstevel@tonic-gate extra=SSL3_RT_MAX_EXTRA;
5990Sstevel@tonic-gate else
6000Sstevel@tonic-gate extra=0;
6010Sstevel@tonic-gate len = SSL3_RT_MAX_PACKET_SIZE + extra;
6020Sstevel@tonic-gate if ((p=OPENSSL_malloc(len)) == NULL)
6030Sstevel@tonic-gate goto err;
6040Sstevel@tonic-gate s->s3->rbuf.buf = p;
6050Sstevel@tonic-gate s->s3->rbuf.len = len;
6060Sstevel@tonic-gate }
6070Sstevel@tonic-gate
6080Sstevel@tonic-gate if (s->s3->wbuf.buf == NULL)
6090Sstevel@tonic-gate {
6100Sstevel@tonic-gate len = SSL3_RT_MAX_PACKET_SIZE;
6110Sstevel@tonic-gate len += SSL3_RT_HEADER_LENGTH + 256; /* extra space for empty fragment */
6120Sstevel@tonic-gate if ((p=OPENSSL_malloc(len)) == NULL)
6130Sstevel@tonic-gate goto err;
6140Sstevel@tonic-gate s->s3->wbuf.buf = p;
6150Sstevel@tonic-gate s->s3->wbuf.len = len;
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate s->packet= &(s->s3->rbuf.buf[0]);
6180Sstevel@tonic-gate return(1);
6190Sstevel@tonic-gate err:
6200Sstevel@tonic-gate SSLerr(SSL_F_SSL3_SETUP_BUFFERS,ERR_R_MALLOC_FAILURE);
6210Sstevel@tonic-gate return(0);
6220Sstevel@tonic-gate }
623