1d710eef2e9499fa48fdb7898e9a9d1c27477939
[openssl.git] / ssl / s3_both.c
1 /* ssl/s3_both.c */
2 /* Copyright (C) 1995-1997 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 "buffer.h"
61 #include "rand.h"
62 #include "objects.h"
63 #include "evp.h"
64 #include "x509.h"
65 #include "ssl_locl.h"
66
67 #define BREAK   break
68
69 /* SSL3err(SSL_F_SSL3_GET_FINISHED,SSL_R_EXCESSIVE_MESSAGE_SIZE);
70  */
71
72 unsigned char ssl3_server_finished_const[4]=
73         {SSL3_MD_SERVER_FINISHED_CONST};
74 unsigned char ssl3_client_finished_const[4]=
75         {SSL3_MD_CLIENT_FINISHED_CONST};
76
77 int ssl3_send_finished(s,a,b,sender)
78 SSL *s;
79 int a;
80 int b;
81 unsigned char *sender;
82         {
83         unsigned char *p,*d;
84         int i;
85         unsigned long l;
86
87         if (s->state == a)
88                 {
89                 d=(unsigned char *)s->init_buf->data;
90                 p= &(d[4]);
91
92                 i=ssl3_final_finish_mac(s,&(s->s3->finish_dgst1),sender,p);
93                 p+=i;
94                 l=i;
95                 i=ssl3_final_finish_mac(s,&(s->s3->finish_dgst2),sender,p);
96                 l+=i;
97
98                 *(d++)=SSL3_MT_FINISHED;
99                 l2n3(l,d);
100                 s->init_num=(int)l+4;
101                 s->init_off=0;
102
103                 s->state=b;
104                 }
105
106         /* SSL3_ST_SEND_xxxxxx_HELLO_B */
107         return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
108         }
109
110 int ssl3_get_finished(s,a,b,sender)
111 SSL *s;
112 int a;
113 int b;
114 unsigned char *sender;
115         {
116         int al,i,j,ok;
117         long n;
118         unsigned char *p;
119
120         /* the mac has already been generated when we received the
121          * change cipher spec message and is in s->s3->tmp.in_dgst[12]
122          */ 
123
124         n=ssl3_get_message(s,
125                 a,
126                 b,
127                 SSL3_MT_FINISHED,
128                 64, /* should actually be 36+4 :-) */
129                 &ok);
130
131         if (!ok) return((int)n);
132
133         /* If this occurs if we has missed a message */
134         if (!s->s3->change_cipher_spec)
135                 {
136                 al=SSL3_AD_UNEXPECTED_MESSAGE;
137                 SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_GOT_A_FIN_BEFORE_A_CCS);
138                 goto f_err;
139                 }
140         s->s3->change_cipher_spec=0;
141
142         p=(unsigned char *)s->init_buf->data;
143
144         i=EVP_MD_CTX_size(&(s->s3->finish_dgst1));
145         j=EVP_MD_CTX_size(&(s->s3->finish_dgst2));
146
147         if ((i+j) != n)
148                 {
149                 al=SSL3_AD_ILLEGAL_PARAMETER;
150                 SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_BAD_DIGEST_LENGTH);
151                 goto f_err;
152                 }
153
154         if (    (memcmp(  p,    &(s->s3->tmp.finish_md1[0]),i) != 0) ||
155                 (memcmp(&(p[i]),&(s->s3->tmp.finish_md2[0]),j) != 0))
156                 {
157                 al=SSL3_AD_ILLEGAL_PARAMETER;
158                 SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
159                 goto f_err;
160                 }
161
162         return(1);
163 f_err:
164         ssl3_send_alert(s,SSL3_AL_FATAL,al);
165         return(0);
166         }
167
168 /* for these 2 messages, we need to
169  * ssl->enc_read_ctx                    re-init
170  * ssl->s3->read_sequence               zero
171  * ssl->s3->read_mac_secret             re-init
172  * ssl->session->read_sym_enc           assign
173  * ssl->session->read_compression       assign
174  * ssl->session->read_hash              assign
175  */
176 int ssl3_send_change_cipher_spec(s,a,b)
177 SSL *s;
178 int a,b;
179         { 
180         unsigned char *p;
181
182         if (s->state == a)
183                 {
184                 p=(unsigned char *)s->init_buf->data;
185                 *p=SSL3_MT_CCS;
186                 s->init_num=1;
187                 s->init_off=0;
188
189                 s->state=b;
190                 }
191
192         /* SSL3_ST_CW_CHANGE_B */
193         return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
194         }
195
196 unsigned long ssl3_output_cert_chain(s,x)
197 SSL *s;
198 X509 *x;
199         {
200         unsigned char *p;
201         int n,i;
202         unsigned long l=7;
203         BUF_MEM *buf;
204         X509_STORE_CTX xs_ctx;
205         X509_OBJECT obj;
206
207         X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL);
208
209         buf=s->init_buf;
210         for (;;)
211                 {
212                 n=i2d_X509(x,NULL);
213                 if (!BUF_MEM_grow(buf,(int)(n+l+3)))
214                         {
215                         SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
216                         return(0);
217                         }
218                 p=(unsigned char *)&(buf->data[l]);
219                 l2n3(n,p);
220                 i2d_X509(x,&p);
221                 l+=n+3;
222                 if (X509_NAME_cmp(X509_get_subject_name(x),
223                         X509_get_issuer_name(x)) == 0) break;
224
225                 i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
226                         X509_get_issuer_name(x),&obj);
227                 if (i <= 0) break;
228                 x=obj.data.x509;
229                 /* Count is one too high since the X509_STORE_get uped the
230                  * ref count */
231                 X509_free(x);
232                 }
233
234         X509_STORE_CTX_cleanup(&xs_ctx);
235
236         l-=7;
237         p=(unsigned char *)&(buf->data[4]);
238         l2n3(l,p);
239         l+=3;
240         p=(unsigned char *)&(buf->data[0]);
241         *(p++)=SSL3_MT_CERTIFICATE;
242         l2n3(l,p);
243         l+=4;
244         return(l);
245         }
246
247 long ssl3_get_message(s,st1,stn,mt,max,ok)
248 SSL *s;
249 int st1,stn,mt;
250 long max;
251 int *ok;
252         {
253         unsigned char *p;
254         unsigned long l;
255         long n;
256         int i,al;
257
258         if (s->s3->tmp.reuse_message)
259                 {
260                 s->s3->tmp.reuse_message=0;
261                 if ((mt >= 0) && (s->s3->tmp.message_type != mt))
262                         {
263                         al=SSL3_AD_UNEXPECTED_MESSAGE;
264                         SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
265                         goto f_err;
266                         }
267                 *ok=1;
268                 return((int)s->s3->tmp.message_size);
269                 }
270
271         p=(unsigned char *)s->init_buf->data;
272
273         if (s->state == st1)
274                 {
275                 i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,
276                         (char *)&(p[s->init_num]),
277                         4-s->init_num);
278                 if (i < (4-s->init_num))
279                         {
280                         *ok=0;
281                         return(ssl3_part_read(s,i));
282                         }
283
284                 if ((mt >= 0) && (*p != mt))
285                         {
286                         al=SSL3_AD_UNEXPECTED_MESSAGE;
287                         SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
288                         goto f_err;
289                         }
290                 s->s3->tmp.message_type= *(p++);
291
292                 n2l3(p,l);
293                 if (l > (unsigned long)max)
294                         {
295                         al=SSL3_AD_ILLEGAL_PARAMETER;
296                         SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
297                         goto f_err;
298                         }
299                 if (l && !BUF_MEM_grow(s->init_buf,(int)l))
300                         {
301                         SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);
302                         goto err;
303                         }
304                 s->s3->tmp.message_size=l;
305                 s->state=stn;
306
307                 s->init_num=0;
308                 }
309
310         /* next state (stn) */
311         p=(unsigned char *)s->init_buf->data;
312         n=s->s3->tmp.message_size;
313         if (n > 0)
314                 {
315                 i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,
316                         (char *)&(p[s->init_num]),(int)n);
317                 if (i != (int)n)
318                         {
319                         *ok=0;
320                         return(ssl3_part_read(s,i));
321                         }
322                 }
323         *ok=1;
324         return(n);
325 f_err:
326         ssl3_send_alert(s,SSL3_AL_FATAL,al);
327 err:
328         *ok=0;
329         return(-1);
330         }
331
332 int ssl_cert_type(x,pkey)
333 X509 *x;
334 EVP_PKEY *pkey;
335         {
336         EVP_PKEY *pk;
337         int ret= -1,i,j;
338
339         if (pkey == NULL)
340                 pk=X509_get_pubkey(x);
341         else
342                 pk=pkey;
343         if (pk == NULL) goto err;
344
345         i=pk->type;
346         if (i == EVP_PKEY_RSA)
347                 {
348                 ret=SSL_PKEY_RSA_ENC;
349                 if (x != NULL)
350                         {
351                         j=X509_get_ext_count(x);
352                         /* check to see if this is a signing only certificate */
353                         /* EAY EAY EAY EAY */
354                         }
355                 }
356         else if (i == EVP_PKEY_DSA)
357                 {
358                 ret=SSL_PKEY_DSA_SIGN;
359                 }
360         else if (i == EVP_PKEY_DH)
361                 {
362                 /* if we just have a key, we needs to be guess */
363
364                 if (x == NULL)
365                         ret=SSL_PKEY_DH_DSA;
366                 else
367                         {
368                         j=X509_get_signature_type(x);
369                         if (j == EVP_PKEY_RSA)
370                                 ret=SSL_PKEY_DH_RSA;
371                         else if (j== EVP_PKEY_DSA)
372                                 ret=SSL_PKEY_DH_DSA;
373                         else ret= -1;
374                         }
375                 }
376         else
377                 ret= -1;
378
379 err:
380         return(ret);
381         }
382
383 int ssl_verify_alarm_type(type)
384 int type;
385         {
386         int al;
387
388         switch(type)
389                 {
390         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
391
392         case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
393         case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
394         case X509_V_ERR_CERT_SIGNATURE_FAILURE:
395         case X509_V_ERR_CERT_NOT_YET_VALID:
396         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
397         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
398         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
399         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
400         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
401         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
402                 al=SSL3_AD_BAD_CERTIFICATE;
403                 break;
404         case X509_V_ERR_CERT_HAS_EXPIRED:
405                 al=SSL3_AD_CERTIFICATE_EXPIRED;
406                 break;
407         default:
408                 al=SSL3_AD_CERTIFICATE_UNKNOWN;
409                 break;
410                 }
411         return(al);
412         }
413
414 int ssl3_setup_buffers(s)
415 SSL *s;
416         {
417         unsigned char *p;
418         unsigned int extra;
419
420         if (s->s3->rbuf.buf == NULL)
421                 {
422                 if (s->ctx->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
423                         extra=SSL3_RT_MAX_EXTRA;
424                 else
425                         extra=0;
426                 if ((p=(unsigned char *)Malloc(SSL3_RT_MAX_PACKET_SIZE+extra))
427                         == NULL)
428                         goto err;
429                 s->s3->rbuf.buf=p;
430                 }
431
432         if (s->s3->wbuf.buf == NULL)
433                 {
434                 if ((p=(unsigned char *)Malloc(SSL3_RT_MAX_PACKET_SIZE))
435                         == NULL)
436                         goto err;
437                 s->s3->wbuf.buf=p;
438                 }
439         s->packet= &(s->s3->rbuf.buf[0]);
440         return(1);
441 err:
442         SSLerr(SSL_F_SSL3_SETUP_BUFFERS,ERR_R_MALLOC_FAILURE);
443         return(0);
444         }