Slight code cleanup for handling finished labels.
[openssl.git] / ssl / s3_both.c
1 /* ssl/s3_both.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #include <stdio.h>
60 #include <openssl/buffer.h>
61 #include <openssl/rand.h>
62 #include <openssl/objects.h>
63 #include <openssl/evp.h>
64 #include <openssl/x509.h>
65 #include "ssl_locl.h"
66
67 int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
68         {
69         unsigned char *p,*d;
70         int i;
71         unsigned long l;
72
73         if (s->state == a)
74                 {
75                 d=(unsigned char *)s->init_buf->data;
76                 p= &(d[4]);
77
78                 i=s->method->ssl3_enc->final_finish_mac(s,
79                         &(s->s3->finish_dgst1),
80                         &(s->s3->finish_dgst2),
81                         sender,slen,p);
82                 p+=i;
83                 l=i;
84
85 #ifdef WIN16
86                 /* MSVC 1.5 does not clear the top bytes of the word unless
87                  * I do this.
88                  */
89                 l&=0xffff;
90 #endif
91
92                 *(d++)=SSL3_MT_FINISHED;
93                 l2n3(l,d);
94                 s->init_num=(int)l+4;
95                 s->init_off=0;
96
97                 s->state=b;
98                 }
99
100         /* SSL3_ST_SEND_xxxxxx_HELLO_B */
101         return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
102         }
103
104 int ssl3_get_finished(SSL *s, int a, int b)
105         {
106         int al,i,ok;
107         long n;
108         unsigned char *p;
109
110         /* the mac has already been generated when we received the
111          * change cipher spec message and is in s->s3->tmp.finish_md
112          */ 
113
114         n=ssl3_get_message(s,
115                 a,
116                 b,
117                 SSL3_MT_FINISHED,
118                 64, /* should actually be 36+4 :-) */
119                 &ok);
120
121         if (!ok) return((int)n);
122
123         /* If this occurs if we has missed a message */
124         if (!s->s3->change_cipher_spec)
125                 {
126                 al=SSL_AD_UNEXPECTED_MESSAGE;
127                 SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_GOT_A_FIN_BEFORE_A_CCS);
128                 goto f_err;
129                 }
130         s->s3->change_cipher_spec=0;
131
132         p=(unsigned char *)s->init_buf->data;
133
134         i=s->method->ssl3_enc->finish_mac_length;
135
136         if (i != n)
137                 {
138                 al=SSL_AD_DECODE_ERROR;
139                 SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_BAD_DIGEST_LENGTH);
140                 goto f_err;
141                 }
142
143         if (memcmp(  p,    (char *)&(s->s3->tmp.finish_md[0]),i) != 0)
144                 {
145                 al=SSL_AD_DECRYPT_ERROR;
146                 SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
147                 goto f_err;
148                 }
149
150         return(1);
151 f_err:
152         ssl3_send_alert(s,SSL3_AL_FATAL,al);
153         return(0);
154         }
155
156 /* for these 2 messages, we need to
157  * ssl->enc_read_ctx                    re-init
158  * ssl->s3->read_sequence               zero
159  * ssl->s3->read_mac_secret             re-init
160  * ssl->session->read_sym_enc           assign
161  * ssl->session->read_compression       assign
162  * ssl->session->read_hash              assign
163  */
164 int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
165         { 
166         unsigned char *p;
167
168         if (s->state == a)
169                 {
170                 p=(unsigned char *)s->init_buf->data;
171                 *p=SSL3_MT_CCS;
172                 s->init_num=1;
173                 s->init_off=0;
174
175                 s->state=b;
176                 }
177
178         /* SSL3_ST_CW_CHANGE_B */
179         return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
180         }
181
182 unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
183         {
184         unsigned char *p;
185         int n,i;
186         unsigned long l=7;
187         BUF_MEM *buf;
188         X509_STORE_CTX xs_ctx;
189         X509_OBJECT obj;
190
191         /* TLSv1 sends a chain with nothing in it, instead of an alert */
192         buf=s->init_buf;
193         if (!BUF_MEM_grow(buf,(int)(10)))
194                 {
195                 SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
196                 return(0);
197                 }
198         if (x != NULL)
199                 {
200                 X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL);
201
202                 for (;;)
203                         {
204                         n=i2d_X509(x,NULL);
205                         if (!BUF_MEM_grow(buf,(int)(n+l+3)))
206                                 {
207                                 SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
208                                 return(0);
209                                 }
210                         p=(unsigned char *)&(buf->data[l]);
211                         l2n3(n,p);
212                         i2d_X509(x,&p);
213                         l+=n+3;
214                         if (X509_NAME_cmp(X509_get_subject_name(x),
215                                 X509_get_issuer_name(x)) == 0) break;
216
217                         i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
218                                 X509_get_issuer_name(x),&obj);
219                         if (i <= 0) break;
220                         x=obj.data.x509;
221                         /* Count is one too high since the X509_STORE_get uped the
222                          * ref count */
223                         X509_free(x);
224                         }
225
226                 X509_STORE_CTX_cleanup(&xs_ctx);
227                 }
228
229         /* Thawte special :-) */
230         if (s->ctx->extra_certs != NULL)
231         for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
232                 {
233                 x=sk_X509_value(s->ctx->extra_certs,i);
234                 n=i2d_X509(x,NULL);
235                 if (!BUF_MEM_grow(buf,(int)(n+l+3)))
236                         {
237                         SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
238                         return(0);
239                         }
240                 p=(unsigned char *)&(buf->data[l]);
241                 l2n3(n,p);
242                 i2d_X509(x,&p);
243                 l+=n+3;
244                 }
245
246         l-=7;
247         p=(unsigned char *)&(buf->data[4]);
248         l2n3(l,p);
249         l+=3;
250         p=(unsigned char *)&(buf->data[0]);
251         *(p++)=SSL3_MT_CERTIFICATE;
252         l2n3(l,p);
253         l+=4;
254         return(l);
255         }
256
257 long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
258         {
259         unsigned char *p;
260         unsigned long l;
261         long n;
262         int i,al;
263
264         if (s->s3->tmp.reuse_message)
265                 {
266                 s->s3->tmp.reuse_message=0;
267                 if ((mt >= 0) && (s->s3->tmp.message_type != mt))
268                         {
269                         al=SSL_AD_UNEXPECTED_MESSAGE;
270                         SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
271                         goto f_err;
272                         }
273                 *ok=1;
274                 return((int)s->s3->tmp.message_size);
275                 }
276
277         p=(unsigned char *)s->init_buf->data;
278
279         if (s->state == st1)
280                 {
281                 i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],
282                                   4-s->init_num);
283                 if (i < (4-s->init_num))
284                         {
285                         *ok=0;
286                         return(ssl3_part_read(s,i));
287                         }
288
289                 if ((mt >= 0) && (*p != mt))
290                         {
291                         al=SSL_AD_UNEXPECTED_MESSAGE;
292                         SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
293                         goto f_err;
294                         }
295                 if((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
296                                         (st1 == SSL3_ST_SR_CERT_A) &&
297                                         (stn == SSL3_ST_SR_CERT_B))
298                         {
299                         /* At this point we have got an MS SGC second client
300                          * hello. We need to restart the mac and mac the data
301                          * currently received.
302                          */
303                         ssl3_init_finished_mac(s);
304                         ssl3_finish_mac(s, p + s->init_num, i);
305                         }
306                         
307                 s->s3->tmp.message_type= *(p++);
308
309                 n2l3(p,l);
310                 if (l > (unsigned long)max)
311                         {
312                         al=SSL_AD_ILLEGAL_PARAMETER;
313                         SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE);
314                         goto f_err;
315                         }
316                 if (l && !BUF_MEM_grow(s->init_buf,(int)l))
317                         {
318                         SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB);
319                         goto err;
320                         }
321                 s->s3->tmp.message_size=l;
322                 s->state=stn;
323
324                 s->init_num=0;
325                 }
326
327         /* next state (stn) */
328         p=(unsigned char *)s->init_buf->data;
329         n=s->s3->tmp.message_size;
330         if (n > 0)
331                 {
332                 i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n);
333                 if (i != (int)n)
334                         {
335                         *ok=0;
336                         return(ssl3_part_read(s,i));
337                         }
338                 }
339         *ok=1;
340         return(n);
341 f_err:
342         ssl3_send_alert(s,SSL3_AL_FATAL,al);
343 err:
344         *ok=0;
345         return(-1);
346         }
347
348 int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
349         {
350         EVP_PKEY *pk;
351         int ret= -1,i,j;
352
353         if (pkey == NULL)
354                 pk=X509_get_pubkey(x);
355         else
356                 pk=pkey;
357         if (pk == NULL) goto err;
358
359         i=pk->type;
360         if (i == EVP_PKEY_RSA)
361                 {
362                 ret=SSL_PKEY_RSA_ENC;
363                 if (x != NULL)
364                         {
365                         j=X509_get_ext_count(x);
366                         /* check to see if this is a signing only certificate */
367                         /* EAY EAY EAY EAY */
368                         }
369                 }
370         else if (i == EVP_PKEY_DSA)
371                 {
372                 ret=SSL_PKEY_DSA_SIGN;
373                 }
374         else if (i == EVP_PKEY_DH)
375                 {
376                 /* if we just have a key, we needs to be guess */
377
378                 if (x == NULL)
379                         ret=SSL_PKEY_DH_DSA;
380                 else
381                         {
382                         j=X509_get_signature_type(x);
383                         if (j == EVP_PKEY_RSA)
384                                 ret=SSL_PKEY_DH_RSA;
385                         else if (j== EVP_PKEY_DSA)
386                                 ret=SSL_PKEY_DH_DSA;
387                         else ret= -1;
388                         }
389                 }
390         else
391                 ret= -1;
392
393 err:
394         if(!pkey) EVP_PKEY_free(pk);
395         return(ret);
396         }
397
398 int ssl_verify_alarm_type(long type)
399         {
400         int al;
401
402         switch(type)
403                 {
404         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
405         case X509_V_ERR_UNABLE_TO_GET_CRL:
406                 al=SSL_AD_UNKNOWN_CA;
407                 break;
408         case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
409         case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
410         case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
411         case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
412         case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
413         case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
414         case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
415         case X509_V_ERR_CERT_NOT_YET_VALID:
416         case X509_V_ERR_CRL_NOT_YET_VALID:
417                 al=SSL_AD_BAD_CERTIFICATE;
418                 break;
419         case X509_V_ERR_CERT_SIGNATURE_FAILURE:
420         case X509_V_ERR_CRL_SIGNATURE_FAILURE:
421                 al=SSL_AD_DECRYPT_ERROR;
422                 break;
423         case X509_V_ERR_CERT_HAS_EXPIRED:
424         case X509_V_ERR_CRL_HAS_EXPIRED:
425                 al=SSL_AD_CERTIFICATE_EXPIRED;
426                 break;
427         case X509_V_ERR_CERT_REVOKED:
428                 al=SSL_AD_CERTIFICATE_REVOKED;
429                 break;
430         case X509_V_ERR_OUT_OF_MEM:
431                 al=SSL_AD_INTERNAL_ERROR;
432                 break;
433         case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
434         case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
435         case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
436         case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
437         case X509_V_ERR_CERT_CHAIN_TOO_LONG:
438                 al=SSL_AD_UNKNOWN_CA;
439                 break;
440         case X509_V_ERR_APPLICATION_VERIFICATION:
441                 al=SSL_AD_HANDSHAKE_FAILURE;
442                 break;
443         default:
444                 al=SSL_AD_CERTIFICATE_UNKNOWN;
445                 break;
446                 }
447         return(al);
448         }
449
450 int ssl3_setup_buffers(SSL *s)
451         {
452         unsigned char *p;
453         unsigned int extra;
454
455         if (s->s3->rbuf.buf == NULL)
456                 {
457                 if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
458                         extra=SSL3_RT_MAX_EXTRA;
459                 else
460                         extra=0;
461                 if ((p=(unsigned char *)Malloc(SSL3_RT_MAX_PACKET_SIZE+extra))
462                         == NULL)
463                         goto err;
464                 s->s3->rbuf.buf=p;
465                 }
466
467         if (s->s3->wbuf.buf == NULL)
468                 {
469                 if ((p=(unsigned char *)Malloc(SSL3_RT_MAX_PACKET_SIZE))
470                         == NULL)
471                         goto err;
472                 s->s3->wbuf.buf=p;
473                 }
474         s->packet= &(s->s3->rbuf.buf[0]);
475         return(1);
476 err:
477         SSLerr(SSL_F_SSL3_SETUP_BUFFERS,ERR_R_MALLOC_FAILURE);
478         return(0);
479         }