summaryrefslogtreecommitdiff
path: root/src/lib/libssl
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl')
-rw-r--r--src/lib/libssl/d1_both.c1193
-rw-r--r--src/lib/libssl/d1_clnt.c1156
-rw-r--r--src/lib/libssl/d1_enc.c281
-rw-r--r--src/lib/libssl/d1_lib.c210
-rw-r--r--src/lib/libssl/d1_meth.c77
-rw-r--r--src/lib/libssl/d1_pkt.c1778
-rw-r--r--src/lib/libssl/d1_srvr.c1147
-rw-r--r--src/lib/libssl/dtls1.h211
-rw-r--r--src/lib/libssl/test/CAss.cnf45
-rw-r--r--src/lib/libssl/test/cms-examples.pl409
-rw-r--r--src/lib/libssl/test/cms-test.pl453
-rw-r--r--src/lib/libssl/test/smcont.txt1
-rw-r--r--src/lib/libssl/test/smime-certs/smdsa1.pem34
-rw-r--r--src/lib/libssl/test/smime-certs/smdsa2.pem34
-rw-r--r--src/lib/libssl/test/smime-certs/smdsa3.pem34
-rw-r--r--src/lib/libssl/test/smime-certs/smdsap.pem9
-rw-r--r--src/lib/libssl/test/smime-certs/smroot.pem30
-rw-r--r--src/lib/libssl/test/smime-certs/smrsa1.pem31
-rw-r--r--src/lib/libssl/test/smime-certs/smrsa2.pem31
-rw-r--r--src/lib/libssl/test/smime-certs/smrsa3.pem31
20 files changed, 7194 insertions, 1 deletions
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c
new file mode 100644
index 0000000000..15a201a25c
--- /dev/null
+++ b/src/lib/libssl/d1_both.c
@@ -0,0 +1,1193 @@
1/* ssl/d1_both.c */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@openssl.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
60 * All rights reserved.
61 *
62 * This package is an SSL implementation written
63 * by Eric Young (eay@cryptsoft.com).
64 * The implementation was written so as to conform with Netscapes SSL.
65 *
66 * This library is free for commercial and non-commercial use as long as
67 * the following conditions are aheared to. The following conditions
68 * apply to all code found in this distribution, be it the RC4, RSA,
69 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
70 * included with this distribution is covered by the same copyright terms
71 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
72 *
73 * Copyright remains Eric Young's, and as such any Copyright notices in
74 * the code are not to be removed.
75 * If this package is used in a product, Eric Young should be given attribution
76 * as the author of the parts of the library used.
77 * This can be in the form of a textual message at program startup or
78 * in documentation (online or textual) provided with the package.
79 *
80 * Redistribution and use in source and binary forms, with or without
81 * modification, are permitted provided that the following conditions
82 * are met:
83 * 1. Redistributions of source code must retain the copyright
84 * notice, this list of conditions and the following disclaimer.
85 * 2. Redistributions in binary form must reproduce the above copyright
86 * notice, this list of conditions and the following disclaimer in the
87 * documentation and/or other materials provided with the distribution.
88 * 3. All advertising materials mentioning features or use of this software
89 * must display the following acknowledgement:
90 * "This product includes cryptographic software written by
91 * Eric Young (eay@cryptsoft.com)"
92 * The word 'cryptographic' can be left out if the rouines from the library
93 * being used are not cryptographic related :-).
94 * 4. If you include any Windows specific code (or a derivative thereof) from
95 * the apps directory (application code) you must include an acknowledgement:
96 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
97 *
98 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
99 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
101 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
102 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108 * SUCH DAMAGE.
109 *
110 * The licence and distribution terms for any publically available version or
111 * derivative of this code cannot be changed. i.e. this code cannot simply be
112 * copied and put under another distribution licence
113 * [including the GNU Public Licence.]
114 */
115
116#include <limits.h>
117#include <string.h>
118#include <stdio.h>
119#include "ssl_locl.h"
120#include <openssl/buffer.h>
121#include <openssl/rand.h>
122#include <openssl/objects.h>
123#include <openssl/evp.h>
124#include <openssl/x509.h>
125
126
127/* XDTLS: figure out the right values */
128static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
129
130static unsigned int dtls1_min_mtu(void);
131static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
132static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
133 unsigned long frag_len);
134static unsigned char *dtls1_write_message_header(SSL *s,
135 unsigned char *p);
136static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
137 unsigned long len, unsigned short seq_num, unsigned long frag_off,
138 unsigned long frag_len);
139static int dtls1_retransmit_buffered_messages(SSL *s);
140static long dtls1_get_message_fragment(SSL *s, int st1, int stn,
141 long max, int *ok);
142
143static hm_fragment *
144dtls1_hm_fragment_new(unsigned long frag_len)
145 {
146 hm_fragment *frag = NULL;
147 unsigned char *buf = NULL;
148
149 frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
150 if ( frag == NULL)
151 return NULL;
152
153 if (frag_len)
154 {
155 buf = (unsigned char *)OPENSSL_malloc(frag_len);
156 if ( buf == NULL)
157 {
158 OPENSSL_free(frag);
159 return NULL;
160 }
161 }
162
163 /* zero length fragment gets zero frag->fragment */
164 frag->fragment = buf;
165
166 return frag;
167 }
168
169static void
170dtls1_hm_fragment_free(hm_fragment *frag)
171 {
172 if (frag->fragment) OPENSSL_free(frag->fragment);
173 OPENSSL_free(frag);
174 }
175
176/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
177int dtls1_do_write(SSL *s, int type)
178 {
179 int ret;
180 int curr_mtu;
181 unsigned int len, frag_off;
182
183 /* AHA! Figure out the MTU, and stick to the right size */
184 if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
185 {
186 s->d1->mtu =
187 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
188
189 /* I've seen the kernel return bogus numbers when it doesn't know
190 * (initial write), so just make sure we have a reasonable number */
191 if ( s->d1->mtu < dtls1_min_mtu())
192 {
193 s->d1->mtu = 0;
194 s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
195 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
196 s->d1->mtu, NULL);
197 }
198 }
199#if 0
200 mtu = s->d1->mtu;
201
202 fprintf(stderr, "using MTU = %d\n", mtu);
203
204 mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
205
206 curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
207
208 if ( curr_mtu > 0)
209 mtu = curr_mtu;
210 else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
211 return ret;
212
213 if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
214 {
215 ret = BIO_flush(SSL_get_wbio(s));
216 if ( ret <= 0)
217 return ret;
218 mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
219 }
220
221 OPENSSL_assert(mtu > 0); /* should have something reasonable now */
222
223#endif
224
225 if ( s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
226 OPENSSL_assert(s->init_num ==
227 (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
228
229 frag_off = 0;
230 while( s->init_num)
231 {
232 curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) -
233 DTLS1_RT_HEADER_LENGTH;
234
235 if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
236 {
237 /* grr.. we could get an error if MTU picked was wrong */
238 ret = BIO_flush(SSL_get_wbio(s));
239 if ( ret <= 0)
240 return ret;
241 curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH;
242 }
243
244 if ( s->init_num > curr_mtu)
245 len = curr_mtu;
246 else
247 len = s->init_num;
248
249
250 /* XDTLS: this function is too long. split out the CCS part */
251 if ( type == SSL3_RT_HANDSHAKE)
252 {
253 if ( s->init_off != 0)
254 {
255 OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
256 s->init_off -= DTLS1_HM_HEADER_LENGTH;
257 s->init_num += DTLS1_HM_HEADER_LENGTH;
258
259 /* write atleast DTLS1_HM_HEADER_LENGTH bytes */
260 if ( len <= DTLS1_HM_HEADER_LENGTH)
261 len += DTLS1_HM_HEADER_LENGTH;
262 }
263
264 dtls1_fix_message_header(s, frag_off,
265 len - DTLS1_HM_HEADER_LENGTH);
266
267 dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]);
268
269 OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
270 }
271
272 ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off],
273 len);
274 if (ret < 0)
275 {
276 /* might need to update MTU here, but we don't know
277 * which previous packet caused the failure -- so can't
278 * really retransmit anything. continue as if everything
279 * is fine and wait for an alert to handle the
280 * retransmit
281 */
282 if ( BIO_ctrl(SSL_get_wbio(s),
283 BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL))
284 s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
285 BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
286 else
287 return(-1);
288 }
289 else
290 {
291
292 /* bad if this assert fails, only part of the handshake
293 * message got sent. but why would this happen? */
294 OPENSSL_assert(len == (unsigned int)ret);
295
296 if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting)
297 {
298 /* should not be done for 'Hello Request's, but in that case
299 * we'll ignore the result anyway */
300 unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off];
301 const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
302 int xlen;
303
304 if (frag_off == 0 && s->client_version != DTLS1_BAD_VER)
305 {
306 /* reconstruct message header is if it
307 * is being sent in single fragment */
308 *p++ = msg_hdr->type;
309 l2n3(msg_hdr->msg_len,p);
310 s2n (msg_hdr->seq,p);
311 l2n3(0,p);
312 l2n3(msg_hdr->msg_len,p);
313 p -= DTLS1_HM_HEADER_LENGTH;
314 xlen = ret;
315 }
316 else
317 {
318 p += DTLS1_HM_HEADER_LENGTH;
319 xlen = ret - DTLS1_HM_HEADER_LENGTH;
320 }
321
322 ssl3_finish_mac(s, p, xlen);
323 }
324
325 if (ret == s->init_num)
326 {
327 if (s->msg_callback)
328 s->msg_callback(1, s->version, type, s->init_buf->data,
329 (size_t)(s->init_off + s->init_num), s,
330 s->msg_callback_arg);
331
332 s->init_off = 0; /* done writing this message */
333 s->init_num = 0;
334
335 return(1);
336 }
337 s->init_off+=ret;
338 s->init_num-=ret;
339 frag_off += (ret -= DTLS1_HM_HEADER_LENGTH);
340 }
341 }
342 return(0);
343 }
344
345
346/* Obtain handshake message of message type 'mt' (any if mt == -1),
347 * maximum acceptable body length 'max'.
348 * Read an entire handshake message. Handshake messages arrive in
349 * fragments.
350 */
351long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
352 {
353 int i, al;
354 struct hm_header_st *msg_hdr;
355
356 /* s3->tmp is used to store messages that are unexpected, caused
357 * by the absence of an optional handshake message */
358 if (s->s3->tmp.reuse_message)
359 {
360 s->s3->tmp.reuse_message=0;
361 if ((mt >= 0) && (s->s3->tmp.message_type != mt))
362 {
363 al=SSL_AD_UNEXPECTED_MESSAGE;
364 SSLerr(SSL_F_DTLS1_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
365 goto f_err;
366 }
367 *ok=1;
368 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
369 s->init_num = (int)s->s3->tmp.message_size;
370 return s->init_num;
371 }
372
373 msg_hdr = &s->d1->r_msg_hdr;
374 do
375 {
376 if ( msg_hdr->frag_off == 0)
377 {
378 /* s->d1->r_message_header.msg_len = 0; */
379 memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
380 }
381
382 i = dtls1_get_message_fragment(s, st1, stn, max, ok);
383 if ( i == DTLS1_HM_BAD_FRAGMENT ||
384 i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */
385 continue;
386 else if ( i <= 0 && !*ok)
387 return i;
388
389 /* Note that s->init_sum is used as a counter summing
390 * up fragments' lengths: as soon as they sum up to
391 * handshake packet length, we assume we have got all
392 * the fragments. Overlapping fragments would cause
393 * premature termination, so we don't expect overlaps.
394 * Well, handling overlaps would require something more
395 * drastic. Indeed, as it is now there is no way to
396 * tell if out-of-order fragment from the middle was
397 * the last. '>=' is the best/least we can do to control
398 * the potential damage caused by malformed overlaps. */
399 if ((unsigned int)s->init_num >= msg_hdr->msg_len)
400 {
401 unsigned char *p = (unsigned char *)s->init_buf->data;
402 unsigned long msg_len = msg_hdr->msg_len;
403
404 /* reconstruct message header as if it was
405 * sent in single fragment */
406 *(p++) = msg_hdr->type;
407 l2n3(msg_len,p);
408 s2n (msg_hdr->seq,p);
409 l2n3(0,p);
410 l2n3(msg_len,p);
411 if (s->client_version != DTLS1_BAD_VER)
412 p -= DTLS1_HM_HEADER_LENGTH,
413 msg_len += DTLS1_HM_HEADER_LENGTH;
414
415 ssl3_finish_mac(s, p, msg_len);
416 if (s->msg_callback)
417 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
418 p, msg_len,
419 s, s->msg_callback_arg);
420
421 memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
422
423 s->d1->handshake_read_seq++;
424 /* we just read a handshake message from the other side:
425 * this means that we don't need to retransmit of the
426 * buffered messages.
427 * XDTLS: may be able clear out this
428 * buffer a little sooner (i.e if an out-of-order
429 * handshake message/record is received at the record
430 * layer.
431 * XDTLS: exception is that the server needs to
432 * know that change cipher spec and finished messages
433 * have been received by the client before clearing this
434 * buffer. this can simply be done by waiting for the
435 * first data segment, but is there a better way? */
436 dtls1_clear_record_buffer(s);
437
438 s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
439 return s->init_num;
440 }
441 else
442 msg_hdr->frag_off = i;
443 } while(1) ;
444
445f_err:
446 ssl3_send_alert(s,SSL3_AL_FATAL,al);
447 *ok = 0;
448 return -1;
449 }
450
451
452static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max)
453 {
454 size_t frag_off,frag_len,msg_len;
455
456 msg_len = msg_hdr->msg_len;
457 frag_off = msg_hdr->frag_off;
458 frag_len = msg_hdr->frag_len;
459
460 /* sanity checking */
461 if ( (frag_off+frag_len) > msg_len)
462 {
463 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
464 return SSL_AD_ILLEGAL_PARAMETER;
465 }
466
467 if ( (frag_off+frag_len) > (unsigned long)max)
468 {
469 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
470 return SSL_AD_ILLEGAL_PARAMETER;
471 }
472
473 if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
474 {
475 /* msg_len is limited to 2^24, but is effectively checked
476 * against max above */
477 if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH))
478 {
479 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB);
480 return SSL_AD_INTERNAL_ERROR;
481 }
482
483 s->s3->tmp.message_size = msg_len;
484 s->d1->r_msg_hdr.msg_len = msg_len;
485 s->s3->tmp.message_type = msg_hdr->type;
486 s->d1->r_msg_hdr.type = msg_hdr->type;
487 s->d1->r_msg_hdr.seq = msg_hdr->seq;
488 }
489 else if (msg_len != s->d1->r_msg_hdr.msg_len)
490 {
491 /* They must be playing with us! BTW, failure to enforce
492 * upper limit would open possibility for buffer overrun. */
493 SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
494 return SSL_AD_ILLEGAL_PARAMETER;
495 }
496
497 return 0; /* no error */
498 }
499
500
501static int
502dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
503 {
504 /* (0) check whether the desired fragment is available
505 * if so:
506 * (1) copy over the fragment to s->init_buf->data[]
507 * (2) update s->init_num
508 */
509 pitem *item;
510 hm_fragment *frag;
511 int al;
512
513 *ok = 0;
514 item = pqueue_peek(s->d1->buffered_messages);
515 if ( item == NULL)
516 return 0;
517
518 frag = (hm_fragment *)item->data;
519
520 if ( s->d1->handshake_read_seq == frag->msg_header.seq)
521 {
522 pqueue_pop(s->d1->buffered_messages);
523
524 al=dtls1_preprocess_fragment(s,&frag->msg_header,max);
525
526 if (al==0) /* no alert */
527 {
528 unsigned char *p = (unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
529 memcpy(&p[frag->msg_header.frag_off],
530 frag->fragment,frag->msg_header.frag_len);
531 }
532
533 dtls1_hm_fragment_free(frag);
534 pitem_free(item);
535
536 if (al==0)
537 {
538 *ok = 1;
539 return frag->msg_header.frag_len;
540 }
541
542 ssl3_send_alert(s,SSL3_AL_FATAL,al);
543 s->init_num = 0;
544 *ok = 0;
545 return -1;
546 }
547 else
548 return 0;
549 }
550
551
552static int
553dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
554{
555 int i=-1;
556 hm_fragment *frag = NULL;
557 pitem *item = NULL;
558 PQ_64BIT seq64;
559 unsigned long frag_len = msg_hdr->frag_len;
560
561 if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
562 goto err;
563
564 if (msg_hdr->seq <= s->d1->handshake_read_seq)
565 {
566 unsigned char devnull [256];
567
568 while (frag_len)
569 {
570 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
571 devnull,
572 frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
573 if (i<=0) goto err;
574 frag_len -= i;
575 }
576 }
577
578 frag = dtls1_hm_fragment_new(frag_len);
579 if ( frag == NULL)
580 goto err;
581
582 memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
583
584 if (frag_len)
585 {
586 /* read the body of the fragment (header has already been read */
587 i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
588 frag->fragment,frag_len,0);
589 if (i<=0 || (unsigned long)i!=frag_len)
590 goto err;
591 }
592
593 pq_64bit_init(&seq64);
594 pq_64bit_assign_word(&seq64, msg_hdr->seq);
595
596 item = pitem_new(seq64, frag);
597 pq_64bit_free(&seq64);
598 if ( item == NULL)
599 goto err;
600
601 pqueue_insert(s->d1->buffered_messages, item);
602 return DTLS1_HM_FRAGMENT_RETRY;
603
604err:
605 if ( frag != NULL) dtls1_hm_fragment_free(frag);
606 if ( item != NULL) OPENSSL_free(item);
607 *ok = 0;
608 return i;
609 }
610
611
612static long
613dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
614 {
615 unsigned char wire[DTLS1_HM_HEADER_LENGTH];
616 unsigned long l, frag_off, frag_len;
617 int i,al;
618 struct hm_header_st msg_hdr;
619
620 /* see if we have the required fragment already */
621 if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
622 {
623 if (*ok) s->init_num += frag_len;
624 return frag_len;
625 }
626
627 /* read handshake message header */
628 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire,
629 DTLS1_HM_HEADER_LENGTH, 0);
630 if (i <= 0) /* nbio, or an error */
631 {
632 s->rwstate=SSL_READING;
633 *ok = 0;
634 return i;
635 }
636 OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH);
637
638 /* parse the message fragment header */
639 dtls1_get_message_header(wire, &msg_hdr);
640
641 /*
642 * if this is a future (or stale) message it gets buffered
643 * (or dropped)--no further processing at this time
644 */
645 if ( msg_hdr.seq != s->d1->handshake_read_seq)
646 return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
647
648 l = msg_hdr.msg_len;
649 frag_off = msg_hdr.frag_off;
650 frag_len = msg_hdr.frag_len;
651
652 if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
653 wire[0] == SSL3_MT_HELLO_REQUEST)
654 {
655 /* The server may always send 'Hello Request' messages --
656 * we are doing a handshake anyway now, so ignore them
657 * if their format is correct. Does not count for
658 * 'Finished' MAC. */
659 if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0)
660 {
661 if (s->msg_callback)
662 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
663 wire, DTLS1_HM_HEADER_LENGTH, s,
664 s->msg_callback_arg);
665
666 s->init_num = 0;
667 return dtls1_get_message_fragment(s, st1, stn,
668 max, ok);
669 }
670 else /* Incorrectly formated Hello request */
671 {
672 al=SSL_AD_UNEXPECTED_MESSAGE;
673 SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
674 goto f_err;
675 }
676 }
677
678 if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max)))
679 goto f_err;
680
681 /* XDTLS: ressurect this when restart is in place */
682 s->state=stn;
683
684 if ( frag_len > 0)
685 {
686 unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
687
688 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
689 &p[frag_off],frag_len,0);
690 /* XDTLS: fix this--message fragments cannot span multiple packets */
691 if (i <= 0)
692 {
693 s->rwstate=SSL_READING;
694 *ok = 0;
695 return i;
696 }
697 }
698 else
699 i = 0;
700
701 /* XDTLS: an incorrectly formatted fragment should cause the
702 * handshake to fail */
703 OPENSSL_assert(i == (int)frag_len);
704
705 *ok = 1;
706
707 /* Note that s->init_num is *not* used as current offset in
708 * s->init_buf->data, but as a counter summing up fragments'
709 * lengths: as soon as they sum up to handshake packet
710 * length, we assume we have got all the fragments. */
711 s->init_num += frag_len;
712 return frag_len;
713
714f_err:
715 ssl3_send_alert(s,SSL3_AL_FATAL,al);
716 s->init_num = 0;
717
718 *ok=0;
719 return(-1);
720 }
721
722int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
723 {
724 unsigned char *p,*d;
725 int i;
726 unsigned long l;
727
728 if (s->state == a)
729 {
730 d=(unsigned char *)s->init_buf->data;
731 p= &(d[DTLS1_HM_HEADER_LENGTH]);
732
733 i=s->method->ssl3_enc->final_finish_mac(s,
734 &(s->s3->finish_dgst1),
735 &(s->s3->finish_dgst2),
736 sender,slen,s->s3->tmp.finish_md);
737 s->s3->tmp.finish_md_len = i;
738 memcpy(p, s->s3->tmp.finish_md, i);
739 p+=i;
740 l=i;
741
742#ifdef OPENSSL_SYS_WIN16
743 /* MSVC 1.5 does not clear the top bytes of the word unless
744 * I do this.
745 */
746 l&=0xffff;
747#endif
748
749 d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l);
750 s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH;
751 s->init_off=0;
752
753 /* buffer the message to handle re-xmits */
754 dtls1_buffer_message(s, 0);
755
756 s->state=b;
757 }
758
759 /* SSL3_ST_SEND_xxxxxx_HELLO_B */
760 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
761 }
762
763/* for these 2 messages, we need to
764 * ssl->enc_read_ctx re-init
765 * ssl->s3->read_sequence zero
766 * ssl->s3->read_mac_secret re-init
767 * ssl->session->read_sym_enc assign
768 * ssl->session->read_compression assign
769 * ssl->session->read_hash assign
770 */
771int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
772 {
773 unsigned char *p;
774
775 if (s->state == a)
776 {
777 p=(unsigned char *)s->init_buf->data;
778 *p++=SSL3_MT_CCS;
779 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
780 s->init_num=DTLS1_CCS_HEADER_LENGTH;
781
782 if (s->client_version == DTLS1_BAD_VER)
783 {
784 s->d1->next_handshake_write_seq++;
785 s2n(s->d1->handshake_write_seq,p);
786 s->init_num+=2;
787 }
788
789 s->init_off=0;
790
791 dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
792 s->d1->handshake_write_seq, 0, 0);
793
794 /* buffer the message to handle re-xmits */
795 dtls1_buffer_message(s, 1);
796
797 s->state=b;
798 }
799
800 /* SSL3_ST_CW_CHANGE_B */
801 return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
802 }
803
804unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
805 {
806 unsigned char *p;
807 int n,i;
808 unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
809 BUF_MEM *buf;
810 X509_STORE_CTX xs_ctx;
811 X509_OBJECT obj;
812
813 /* TLSv1 sends a chain with nothing in it, instead of an alert */
814 buf=s->init_buf;
815 if (!BUF_MEM_grow_clean(buf,10))
816 {
817 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
818 return(0);
819 }
820 if (x != NULL)
821 {
822 if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
823 {
824 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
825 return(0);
826 }
827
828 for (;;)
829 {
830 n=i2d_X509(x,NULL);
831 if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
832 {
833 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
834 return(0);
835 }
836 p=(unsigned char *)&(buf->data[l]);
837 l2n3(n,p);
838 i2d_X509(x,&p);
839 l+=n+3;
840 if (X509_NAME_cmp(X509_get_subject_name(x),
841 X509_get_issuer_name(x)) == 0) break;
842
843 i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
844 X509_get_issuer_name(x),&obj);
845 if (i <= 0) break;
846 x=obj.data.x509;
847 /* Count is one too high since the X509_STORE_get uped the
848 * ref count */
849 X509_free(x);
850 }
851
852 X509_STORE_CTX_cleanup(&xs_ctx);
853 }
854
855 /* Thawte special :-) */
856 if (s->ctx->extra_certs != NULL)
857 for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
858 {
859 x=sk_X509_value(s->ctx->extra_certs,i);
860 n=i2d_X509(x,NULL);
861 if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
862 {
863 SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
864 return(0);
865 }
866 p=(unsigned char *)&(buf->data[l]);
867 l2n3(n,p);
868 i2d_X509(x,&p);
869 l+=n+3;
870 }
871
872 l-= (3 + DTLS1_HM_HEADER_LENGTH);
873
874 p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
875 l2n3(l,p);
876 l+=3;
877 p=(unsigned char *)&(buf->data[0]);
878 p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);
879
880 l+=DTLS1_HM_HEADER_LENGTH;
881 return(l);
882 }
883
884int dtls1_read_failed(SSL *s, int code)
885 {
886 DTLS1_STATE *state;
887 BIO *bio;
888 int send_alert = 0;
889
890 if ( code > 0)
891 {
892 fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
893 return 1;
894 }
895
896 bio = SSL_get_rbio(s);
897 if ( ! BIO_dgram_recv_timedout(bio))
898 {
899 /* not a timeout, none of our business,
900 let higher layers handle this. in fact it's probably an error */
901 return code;
902 }
903
904 if ( ! SSL_in_init(s)) /* done, no need to send a retransmit */
905 {
906 BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
907 return code;
908 }
909
910 state = s->d1;
911 state->timeout.num_alerts++;
912 if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
913 {
914 /* fail the connection, enough alerts have been sent */
915 SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED);
916 return 0;
917 }
918
919 state->timeout.read_timeouts++;
920 if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
921 {
922 send_alert = 1;
923 state->timeout.read_timeouts = 1;
924 }
925
926
927#if 0 /* for now, each alert contains only one record number */
928 item = pqueue_peek(state->rcvd_records);
929 if ( item )
930 {
931 /* send an alert immediately for all the missing records */
932 }
933 else
934#endif
935
936#if 0 /* no more alert sending, just retransmit the last set of messages */
937 if ( send_alert)
938 ssl3_send_alert(s,SSL3_AL_WARNING,
939 DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
940#endif
941
942 return dtls1_retransmit_buffered_messages(s) ;
943 }
944
945
946static int
947dtls1_retransmit_buffered_messages(SSL *s)
948 {
949 pqueue sent = s->d1->sent_messages;
950 piterator iter;
951 pitem *item;
952 hm_fragment *frag;
953 int found = 0;
954
955 iter = pqueue_iterator(sent);
956
957 for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter))
958 {
959 frag = (hm_fragment *)item->data;
960 if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 &&
961 found)
962 {
963 fprintf(stderr, "dtls1_retransmit_message() failed\n");
964 return -1;
965 }
966 }
967
968 return 1;
969 }
970
971int
972dtls1_buffer_message(SSL *s, int is_ccs)
973 {
974 pitem *item;
975 hm_fragment *frag;
976 PQ_64BIT seq64;
977 unsigned int epoch = s->d1->w_epoch;
978
979 /* this function is called immediately after a message has
980 * been serialized */
981 OPENSSL_assert(s->init_off == 0);
982
983 frag = dtls1_hm_fragment_new(s->init_num);
984
985 memcpy(frag->fragment, s->init_buf->data, s->init_num);
986
987 if ( is_ccs)
988 {
989 OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
990 DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num);
991 epoch++;
992 }
993 else
994 {
995 OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
996 DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
997 }
998
999 frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
1000 frag->msg_header.seq = s->d1->w_msg_hdr.seq;
1001 frag->msg_header.type = s->d1->w_msg_hdr.type;
1002 frag->msg_header.frag_off = 0;
1003 frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
1004 frag->msg_header.is_ccs = is_ccs;
1005
1006 pq_64bit_init(&seq64);
1007 pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq);
1008
1009 item = pitem_new(seq64, frag);
1010 pq_64bit_free(&seq64);
1011 if ( item == NULL)
1012 {
1013 dtls1_hm_fragment_free(frag);
1014 return 0;
1015 }
1016
1017#if 0
1018 fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type);
1019 fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len);
1020 fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num);
1021#endif
1022
1023 pqueue_insert(s->d1->sent_messages, item);
1024 return 1;
1025 }
1026
1027int
1028dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
1029 int *found)
1030 {
1031 int ret;
1032 /* XDTLS: for now assuming that read/writes are blocking */
1033 pitem *item;
1034 hm_fragment *frag ;
1035 unsigned long header_length;
1036 PQ_64BIT seq64;
1037
1038 /*
1039 OPENSSL_assert(s->init_num == 0);
1040 OPENSSL_assert(s->init_off == 0);
1041 */
1042
1043 /* XDTLS: the requested message ought to be found, otherwise error */
1044 pq_64bit_init(&seq64);
1045 pq_64bit_assign_word(&seq64, seq);
1046
1047 item = pqueue_find(s->d1->sent_messages, seq64);
1048 pq_64bit_free(&seq64);
1049 if ( item == NULL)
1050 {
1051 fprintf(stderr, "retransmit: message %d non-existant\n", seq);
1052 *found = 0;
1053 return 0;
1054 }
1055
1056 *found = 1;
1057 frag = (hm_fragment *)item->data;
1058
1059 if ( frag->msg_header.is_ccs)
1060 header_length = DTLS1_CCS_HEADER_LENGTH;
1061 else
1062 header_length = DTLS1_HM_HEADER_LENGTH;
1063
1064 memcpy(s->init_buf->data, frag->fragment,
1065 frag->msg_header.msg_len + header_length);
1066 s->init_num = frag->msg_header.msg_len + header_length;
1067
1068 dtls1_set_message_header_int(s, frag->msg_header.type,
1069 frag->msg_header.msg_len, frag->msg_header.seq, 0,
1070 frag->msg_header.frag_len);
1071
1072 s->d1->retransmitting = 1;
1073 ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
1074 SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
1075 s->d1->retransmitting = 0;
1076
1077 (void)BIO_flush(SSL_get_wbio(s));
1078 return ret;
1079 }
1080
1081/* call this function when the buffered messages are no longer needed */
1082void
1083dtls1_clear_record_buffer(SSL *s)
1084 {
1085 pitem *item;
1086
1087 for(item = pqueue_pop(s->d1->sent_messages);
1088 item != NULL; item = pqueue_pop(s->d1->sent_messages))
1089 {
1090 dtls1_hm_fragment_free((hm_fragment *)item->data);
1091 pitem_free(item);
1092 }
1093 }
1094
1095
1096unsigned char *
1097dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt,
1098 unsigned long len, unsigned long frag_off, unsigned long frag_len)
1099 {
1100 if ( frag_off == 0)
1101 {
1102 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
1103 s->d1->next_handshake_write_seq++;
1104 }
1105
1106 dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
1107 frag_off, frag_len);
1108
1109 return p += DTLS1_HM_HEADER_LENGTH;
1110 }
1111
1112
1113/* don't actually do the writing, wait till the MTU has been retrieved */
1114static void
1115dtls1_set_message_header_int(SSL *s, unsigned char mt,
1116 unsigned long len, unsigned short seq_num, unsigned long frag_off,
1117 unsigned long frag_len)
1118 {
1119 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
1120
1121 msg_hdr->type = mt;
1122 msg_hdr->msg_len = len;
1123 msg_hdr->seq = seq_num;
1124 msg_hdr->frag_off = frag_off;
1125 msg_hdr->frag_len = frag_len;
1126 }
1127
1128static void
1129dtls1_fix_message_header(SSL *s, unsigned long frag_off,
1130 unsigned long frag_len)
1131 {
1132 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
1133
1134 msg_hdr->frag_off = frag_off;
1135 msg_hdr->frag_len = frag_len;
1136 }
1137
1138static unsigned char *
1139dtls1_write_message_header(SSL *s, unsigned char *p)
1140 {
1141 struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
1142
1143 *p++ = msg_hdr->type;
1144 l2n3(msg_hdr->msg_len, p);
1145
1146 s2n(msg_hdr->seq, p);
1147 l2n3(msg_hdr->frag_off, p);
1148 l2n3(msg_hdr->frag_len, p);
1149
1150 return p;
1151 }
1152
1153static unsigned int
1154dtls1_min_mtu(void)
1155 {
1156 return (g_probable_mtu[(sizeof(g_probable_mtu) /
1157 sizeof(g_probable_mtu[0])) - 1]);
1158 }
1159
1160static unsigned int
1161dtls1_guess_mtu(unsigned int curr_mtu)
1162 {
1163 size_t i;
1164
1165 if ( curr_mtu == 0 )
1166 return g_probable_mtu[0] ;
1167
1168 for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
1169 if ( curr_mtu > g_probable_mtu[i])
1170 return g_probable_mtu[i];
1171
1172 return curr_mtu;
1173 }
1174
1175void
1176dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
1177 {
1178 memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
1179 msg_hdr->type = *(data++);
1180 n2l3(data, msg_hdr->msg_len);
1181
1182 n2s(data, msg_hdr->seq);
1183 n2l3(data, msg_hdr->frag_off);
1184 n2l3(data, msg_hdr->frag_len);
1185 }
1186
1187void
1188dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
1189 {
1190 memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));
1191
1192 ccs_hdr->type = *(data++);
1193 }
diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c
new file mode 100644
index 0000000000..5e59dc845a
--- /dev/null
+++ b/src/lib/libssl/d1_clnt.c
@@ -0,0 +1,1156 @@
1/* ssl/d1_clnt.c */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
60 * All rights reserved.
61 *
62 * This package is an SSL implementation written
63 * by Eric Young (eay@cryptsoft.com).
64 * The implementation was written so as to conform with Netscapes SSL.
65 *
66 * This library is free for commercial and non-commercial use as long as
67 * the following conditions are aheared to. The following conditions
68 * apply to all code found in this distribution, be it the RC4, RSA,
69 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
70 * included with this distribution is covered by the same copyright terms
71 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
72 *
73 * Copyright remains Eric Young's, and as such any Copyright notices in
74 * the code are not to be removed.
75 * If this package is used in a product, Eric Young should be given attribution
76 * as the author of the parts of the library used.
77 * This can be in the form of a textual message at program startup or
78 * in documentation (online or textual) provided with the package.
79 *
80 * Redistribution and use in source and binary forms, with or without
81 * modification, are permitted provided that the following conditions
82 * are met:
83 * 1. Redistributions of source code must retain the copyright
84 * notice, this list of conditions and the following disclaimer.
85 * 2. Redistributions in binary form must reproduce the above copyright
86 * notice, this list of conditions and the following disclaimer in the
87 * documentation and/or other materials provided with the distribution.
88 * 3. All advertising materials mentioning features or use of this software
89 * must display the following acknowledgement:
90 * "This product includes cryptographic software written by
91 * Eric Young (eay@cryptsoft.com)"
92 * The word 'cryptographic' can be left out if the rouines from the library
93 * being used are not cryptographic related :-).
94 * 4. If you include any Windows specific code (or a derivative thereof) from
95 * the apps directory (application code) you must include an acknowledgement:
96 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
97 *
98 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
99 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
101 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
102 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108 * SUCH DAMAGE.
109 *
110 * The licence and distribution terms for any publically available version or
111 * derivative of this code cannot be changed. i.e. this code cannot simply be
112 * copied and put under another distribution licence
113 * [including the GNU Public Licence.]
114 */
115
116#include <stdio.h>
117#include "ssl_locl.h"
118#include "kssl_lcl.h"
119#include <openssl/buffer.h>
120#include <openssl/rand.h>
121#include <openssl/objects.h>
122#include <openssl/evp.h>
123#include <openssl/md5.h>
124#ifndef OPENSSL_NO_DH
125#include <openssl/dh.h>
126#endif
127
128static SSL_METHOD *dtls1_get_client_method(int ver);
129static int dtls1_get_hello_verify(SSL *s);
130
131static SSL_METHOD *dtls1_get_client_method(int ver)
132 {
133 if (ver == DTLS1_VERSION)
134 return(DTLSv1_client_method());
135 else
136 return(NULL);
137 }
138
139IMPLEMENT_dtls1_meth_func(DTLSv1_client_method,
140 ssl_undefined_function,
141 dtls1_connect,
142 dtls1_get_client_method)
143
144int dtls1_connect(SSL *s)
145 {
146 BUF_MEM *buf=NULL;
147 unsigned long Time=(unsigned long)time(NULL),l;
148 long num1;
149 void (*cb)(const SSL *ssl,int type,int val)=NULL;
150 int ret= -1;
151 int new_state,state,skip=0;;
152
153 RAND_add(&Time,sizeof(Time),0);
154 ERR_clear_error();
155 clear_sys_error();
156
157 if (s->info_callback != NULL)
158 cb=s->info_callback;
159 else if (s->ctx->info_callback != NULL)
160 cb=s->ctx->info_callback;
161
162 s->in_handshake++;
163 if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
164
165 for (;;)
166 {
167 state=s->state;
168
169 switch(s->state)
170 {
171 case SSL_ST_RENEGOTIATE:
172 s->new_session=1;
173 s->state=SSL_ST_CONNECT;
174 s->ctx->stats.sess_connect_renegotiate++;
175 /* break */
176 case SSL_ST_BEFORE:
177 case SSL_ST_CONNECT:
178 case SSL_ST_BEFORE|SSL_ST_CONNECT:
179 case SSL_ST_OK|SSL_ST_CONNECT:
180
181 s->server=0;
182 if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
183
184 if ((s->version & 0xff00 ) != (DTLS1_VERSION & 0xff00))
185 {
186 SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
187 ret = -1;
188 goto end;
189 }
190
191 /* s->version=SSL3_VERSION; */
192 s->type=SSL_ST_CONNECT;
193
194 if (s->init_buf == NULL)
195 {
196 if ((buf=BUF_MEM_new()) == NULL)
197 {
198 ret= -1;
199 goto end;
200 }
201 if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
202 {
203 ret= -1;
204 goto end;
205 }
206 s->init_buf=buf;
207 buf=NULL;
208 }
209
210 if (!ssl3_setup_buffers(s)) { ret= -1; goto end; }
211
212 /* setup buffing BIO */
213 if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
214
215 /* don't push the buffering BIO quite yet */
216
217 s->state=SSL3_ST_CW_CLNT_HELLO_A;
218 s->ctx->stats.sess_connect++;
219 s->init_num=0;
220 /* mark client_random uninitialized */
221 memset(s->s3->client_random,0,sizeof(s->s3->client_random));
222 break;
223
224 case SSL3_ST_CW_CLNT_HELLO_A:
225 case SSL3_ST_CW_CLNT_HELLO_B:
226
227 s->shutdown=0;
228
229 /* every DTLS ClientHello resets Finished MAC */
230 ssl3_init_finished_mac(s);
231
232 ret=dtls1_client_hello(s);
233 if (ret <= 0) goto end;
234
235 if ( s->d1->send_cookie)
236 {
237 s->state=SSL3_ST_CW_FLUSH;
238 s->s3->tmp.next_state=SSL3_ST_CR_SRVR_HELLO_A;
239 }
240 else
241 s->state=SSL3_ST_CR_SRVR_HELLO_A;
242
243 s->init_num=0;
244
245 /* turn on buffering for the next lot of output */
246 if (s->bbio != s->wbio)
247 s->wbio=BIO_push(s->bbio,s->wbio);
248
249 break;
250
251 case SSL3_ST_CR_SRVR_HELLO_A:
252 case SSL3_ST_CR_SRVR_HELLO_B:
253 ret=ssl3_get_server_hello(s);
254 if (ret <= 0) goto end;
255 else
256 {
257 if (s->hit)
258 s->state=SSL3_ST_CR_FINISHED_A;
259 else
260 s->state=DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
261 }
262 s->init_num=0;
263 break;
264
265 case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
266 case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
267
268 ret = dtls1_get_hello_verify(s);
269 if ( ret <= 0)
270 goto end;
271 if ( s->d1->send_cookie) /* start again, with a cookie */
272 s->state=SSL3_ST_CW_CLNT_HELLO_A;
273 else
274 s->state = SSL3_ST_CR_CERT_A;
275 s->init_num = 0;
276 break;
277
278 case SSL3_ST_CR_CERT_A:
279 case SSL3_ST_CR_CERT_B:
280 /* Check if it is anon DH */
281 if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
282 {
283 ret=ssl3_get_server_certificate(s);
284 if (ret <= 0) goto end;
285 }
286 else
287 skip=1;
288 s->state=SSL3_ST_CR_KEY_EXCH_A;
289 s->init_num=0;
290 break;
291
292 case SSL3_ST_CR_KEY_EXCH_A:
293 case SSL3_ST_CR_KEY_EXCH_B:
294 ret=ssl3_get_key_exchange(s);
295 if (ret <= 0) goto end;
296 s->state=SSL3_ST_CR_CERT_REQ_A;
297 s->init_num=0;
298
299 /* at this point we check that we have the
300 * required stuff from the server */
301 if (!ssl3_check_cert_and_algorithm(s))
302 {
303 ret= -1;
304 goto end;
305 }
306 break;
307
308 case SSL3_ST_CR_CERT_REQ_A:
309 case SSL3_ST_CR_CERT_REQ_B:
310 ret=ssl3_get_certificate_request(s);
311 if (ret <= 0) goto end;
312 s->state=SSL3_ST_CR_SRVR_DONE_A;
313 s->init_num=0;
314 break;
315
316 case SSL3_ST_CR_SRVR_DONE_A:
317 case SSL3_ST_CR_SRVR_DONE_B:
318 ret=ssl3_get_server_done(s);
319 if (ret <= 0) goto end;
320 if (s->s3->tmp.cert_req)
321 s->state=SSL3_ST_CW_CERT_A;
322 else
323 s->state=SSL3_ST_CW_KEY_EXCH_A;
324 s->init_num=0;
325
326 break;
327
328 case SSL3_ST_CW_CERT_A:
329 case SSL3_ST_CW_CERT_B:
330 case SSL3_ST_CW_CERT_C:
331 case SSL3_ST_CW_CERT_D:
332 ret=dtls1_send_client_certificate(s);
333 if (ret <= 0) goto end;
334 s->state=SSL3_ST_CW_KEY_EXCH_A;
335 s->init_num=0;
336 break;
337
338 case SSL3_ST_CW_KEY_EXCH_A:
339 case SSL3_ST_CW_KEY_EXCH_B:
340 ret=dtls1_send_client_key_exchange(s);
341 if (ret <= 0) goto end;
342 l=s->s3->tmp.new_cipher->algorithms;
343 /* EAY EAY EAY need to check for DH fix cert
344 * sent back */
345 /* For TLS, cert_req is set to 2, so a cert chain
346 * of nothing is sent, but no verify packet is sent */
347 if (s->s3->tmp.cert_req == 1)
348 {
349 s->state=SSL3_ST_CW_CERT_VRFY_A;
350 }
351 else
352 {
353 s->state=SSL3_ST_CW_CHANGE_A;
354 s->s3->change_cipher_spec=0;
355 }
356
357 s->init_num=0;
358 break;
359
360 case SSL3_ST_CW_CERT_VRFY_A:
361 case SSL3_ST_CW_CERT_VRFY_B:
362 ret=dtls1_send_client_verify(s);
363 if (ret <= 0) goto end;
364 s->state=SSL3_ST_CW_CHANGE_A;
365 s->init_num=0;
366 s->s3->change_cipher_spec=0;
367 break;
368
369 case SSL3_ST_CW_CHANGE_A:
370 case SSL3_ST_CW_CHANGE_B:
371 ret=dtls1_send_change_cipher_spec(s,
372 SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
373 if (ret <= 0) goto end;
374 s->state=SSL3_ST_CW_FINISHED_A;
375 s->init_num=0;
376
377 s->session->cipher=s->s3->tmp.new_cipher;
378#ifdef OPENSSL_NO_COMP
379 s->session->compress_meth=0;
380#else
381 if (s->s3->tmp.new_compression == NULL)
382 s->session->compress_meth=0;
383 else
384 s->session->compress_meth=
385 s->s3->tmp.new_compression->id;
386#endif
387 if (!s->method->ssl3_enc->setup_key_block(s))
388 {
389 ret= -1;
390 goto end;
391 }
392
393 if (!s->method->ssl3_enc->change_cipher_state(s,
394 SSL3_CHANGE_CIPHER_CLIENT_WRITE))
395 {
396 ret= -1;
397 goto end;
398 }
399
400 dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
401 break;
402
403 case SSL3_ST_CW_FINISHED_A:
404 case SSL3_ST_CW_FINISHED_B:
405 ret=dtls1_send_finished(s,
406 SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
407 s->method->ssl3_enc->client_finished_label,
408 s->method->ssl3_enc->client_finished_label_len);
409 if (ret <= 0) goto end;
410 s->state=SSL3_ST_CW_FLUSH;
411
412 /* clear flags */
413 s->s3->flags&= ~SSL3_FLAGS_POP_BUFFER;
414 if (s->hit)
415 {
416 s->s3->tmp.next_state=SSL_ST_OK;
417 if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
418 {
419 s->state=SSL_ST_OK;
420 s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
421 s->s3->delay_buf_pop_ret=0;
422 }
423 }
424 else
425 {
426 s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
427 }
428 s->init_num=0;
429 /* mark client_random uninitialized */
430 memset (s->s3->client_random,0,sizeof(s->s3->client_random));
431
432 break;
433
434 case SSL3_ST_CR_FINISHED_A:
435 case SSL3_ST_CR_FINISHED_B:
436
437 ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
438 SSL3_ST_CR_FINISHED_B);
439 if (ret <= 0) goto end;
440
441 if (s->hit)
442 s->state=SSL3_ST_CW_CHANGE_A;
443 else
444 s->state=SSL_ST_OK;
445 s->init_num=0;
446 break;
447
448 case SSL3_ST_CW_FLUSH:
449 /* number of bytes to be flushed */
450 num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
451 if (num1 > 0)
452 {
453 s->rwstate=SSL_WRITING;
454 num1=BIO_flush(s->wbio);
455 if (num1 <= 0) { ret= -1; goto end; }
456 s->rwstate=SSL_NOTHING;
457 }
458
459 s->state=s->s3->tmp.next_state;
460 break;
461
462 case SSL_ST_OK:
463 /* clean a few things up */
464 ssl3_cleanup_key_block(s);
465
466#if 0
467 if (s->init_buf != NULL)
468 {
469 BUF_MEM_free(s->init_buf);
470 s->init_buf=NULL;
471 }
472#endif
473
474 /* If we are not 'joining' the last two packets,
475 * remove the buffering now */
476 if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
477 ssl_free_wbio_buffer(s);
478 /* else do it later in ssl3_write */
479
480 s->init_num=0;
481 s->new_session=0;
482
483 ssl_update_cache(s,SSL_SESS_CACHE_CLIENT);
484 if (s->hit) s->ctx->stats.sess_hit++;
485
486 ret=1;
487 /* s->server=0; */
488 s->handshake_func=dtls1_connect;
489 s->ctx->stats.sess_connect_good++;
490
491 if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
492
493 /* done with handshaking */
494 s->d1->handshake_read_seq = 0;
495 goto end;
496 /* break; */
497
498 default:
499 SSLerr(SSL_F_DTLS1_CONNECT,SSL_R_UNKNOWN_STATE);
500 ret= -1;
501 goto end;
502 /* break; */
503 }
504
505 /* did we do anything */
506 if (!s->s3->tmp.reuse_message && !skip)
507 {
508 if (s->debug)
509 {
510 if ((ret=BIO_flush(s->wbio)) <= 0)
511 goto end;
512 }
513
514 if ((cb != NULL) && (s->state != state))
515 {
516 new_state=s->state;
517 s->state=state;
518 cb(s,SSL_CB_CONNECT_LOOP,1);
519 s->state=new_state;
520 }
521 }
522 skip=0;
523 }
524end:
525 s->in_handshake--;
526 if (buf != NULL)
527 BUF_MEM_free(buf);
528 if (cb != NULL)
529 cb(s,SSL_CB_CONNECT_EXIT,ret);
530 return(ret);
531 }
532
533int dtls1_client_hello(SSL *s)
534 {
535 unsigned char *buf;
536 unsigned char *p,*d;
537 unsigned int i,j;
538 unsigned long Time,l;
539 SSL_COMP *comp;
540
541 buf=(unsigned char *)s->init_buf->data;
542 if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
543 {
544 if ((s->session == NULL) ||
545 (s->session->ssl_version != s->version) ||
546 (s->session->not_resumable))
547 {
548 if (!ssl_get_new_session(s,0))
549 goto err;
550 }
551 /* else use the pre-loaded session */
552
553 p=s->s3->client_random;
554 /* if client_random is initialized, reuse it, we are
555 * required to use same upon reply to HelloVerify */
556 for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ;
557 if (i==sizeof(s->s3->client_random))
558 {
559 Time=(unsigned long)time(NULL); /* Time */
560 l2n(Time,p);
561 RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
562 }
563
564 /* Do the message type and length last */
565 d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
566
567 *(p++)=s->version>>8;
568 *(p++)=s->version&0xff;
569 s->client_version=s->version;
570
571 /* Random stuff */
572 memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
573 p+=SSL3_RANDOM_SIZE;
574
575 /* Session ID */
576 if (s->new_session)
577 i=0;
578 else
579 i=s->session->session_id_length;
580 *(p++)=i;
581 if (i != 0)
582 {
583 if (i > sizeof s->session->session_id)
584 {
585 SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
586 goto err;
587 }
588 memcpy(p,s->session->session_id,i);
589 p+=i;
590 }
591
592 /* cookie stuff */
593 if ( s->d1->cookie_len > sizeof(s->d1->cookie))
594 {
595 SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
596 goto err;
597 }
598 *(p++) = s->d1->cookie_len;
599 memcpy(p, s->d1->cookie, s->d1->cookie_len);
600 p += s->d1->cookie_len;
601
602 /* Ciphers supported */
603 i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0);
604 if (i == 0)
605 {
606 SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
607 goto err;
608 }
609 s2n(i,p);
610 p+=i;
611
612 /* COMPRESSION */
613 if (s->ctx->comp_methods == NULL)
614 j=0;
615 else
616 j=sk_SSL_COMP_num(s->ctx->comp_methods);
617 *(p++)=1+j;
618 for (i=0; i<j; i++)
619 {
620 comp=sk_SSL_COMP_value(s->ctx->comp_methods,i);
621 *(p++)=comp->id;
622 }
623 *(p++)=0; /* Add the NULL method */
624
625 l=(p-d);
626 d=buf;
627
628 d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l);
629
630 s->state=SSL3_ST_CW_CLNT_HELLO_B;
631 /* number of bytes to write */
632 s->init_num=p-buf;
633 s->init_off=0;
634
635 /* buffer the message to handle re-xmits */
636 dtls1_buffer_message(s, 0);
637 }
638
639 /* SSL3_ST_CW_CLNT_HELLO_B */
640 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
641err:
642 return(-1);
643 }
644
645static int dtls1_get_hello_verify(SSL *s)
646 {
647 int n, al, ok = 0;
648 unsigned char *data;
649 unsigned int cookie_len;
650
651 n=s->method->ssl_get_message(s,
652 DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
653 DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
654 -1,
655 s->max_cert_list,
656 &ok);
657
658 if (!ok) return((int)n);
659
660 if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST)
661 {
662 s->d1->send_cookie = 0;
663 s->s3->tmp.reuse_message=1;
664 return(1);
665 }
666
667 data = (unsigned char *)s->init_msg;
668
669 if ((data[0] != (s->version>>8)) || (data[1] != (s->version&0xff)))
670 {
671 SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY,SSL_R_WRONG_SSL_VERSION);
672 s->version=(s->version&0xff00)|data[1];
673 al = SSL_AD_PROTOCOL_VERSION;
674 goto f_err;
675 }
676 data+=2;
677
678 cookie_len = *(data++);
679 if ( cookie_len > sizeof(s->d1->cookie))
680 {
681 al=SSL_AD_ILLEGAL_PARAMETER;
682 goto f_err;
683 }
684
685 memcpy(s->d1->cookie, data, cookie_len);
686 s->d1->cookie_len = cookie_len;
687
688 s->d1->send_cookie = 1;
689 return 1;
690
691f_err:
692 ssl3_send_alert(s, SSL3_AL_FATAL, al);
693 return -1;
694 }
695
696int dtls1_send_client_key_exchange(SSL *s)
697 {
698 unsigned char *p,*d;
699 int n;
700 unsigned long l;
701#ifndef OPENSSL_NO_RSA
702 unsigned char *q;
703 EVP_PKEY *pkey=NULL;
704#endif
705#ifndef OPENSSL_NO_KRB5
706 KSSL_ERR kssl_err;
707#endif /* OPENSSL_NO_KRB5 */
708
709 if (s->state == SSL3_ST_CW_KEY_EXCH_A)
710 {
711 d=(unsigned char *)s->init_buf->data;
712 p= &(d[DTLS1_HM_HEADER_LENGTH]);
713
714 l=s->s3->tmp.new_cipher->algorithms;
715
716 /* Fool emacs indentation */
717 if (0) {}
718#ifndef OPENSSL_NO_RSA
719 else if (l & SSL_kRSA)
720 {
721 RSA *rsa;
722 unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
723
724 if (s->session->sess_cert->peer_rsa_tmp != NULL)
725 rsa=s->session->sess_cert->peer_rsa_tmp;
726 else
727 {
728 pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
729 if ((pkey == NULL) ||
730 (pkey->type != EVP_PKEY_RSA) ||
731 (pkey->pkey.rsa == NULL))
732 {
733 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
734 goto err;
735 }
736 rsa=pkey->pkey.rsa;
737 EVP_PKEY_free(pkey);
738 }
739
740 tmp_buf[0]=s->client_version>>8;
741 tmp_buf[1]=s->client_version&0xff;
742 if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0)
743 goto err;
744
745 s->session->master_key_length=sizeof tmp_buf;
746
747 q=p;
748 /* Fix buf for TLS and [incidentally] DTLS */
749 if (s->version > SSL3_VERSION)
750 p+=2;
751 n=RSA_public_encrypt(sizeof tmp_buf,
752 tmp_buf,p,rsa,RSA_PKCS1_PADDING);
753#ifdef PKCS1_CHECK
754 if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++;
755 if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;
756#endif
757 if (n <= 0)
758 {
759 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT);
760 goto err;
761 }
762
763 /* Fix buf for TLS and [incidentally] DTLS */
764 if (s->version > SSL3_VERSION)
765 {
766 s2n(n,q);
767 n+=2;
768 }
769
770 s->session->master_key_length=
771 s->method->ssl3_enc->generate_master_secret(s,
772 s->session->master_key,
773 tmp_buf,sizeof tmp_buf);
774 OPENSSL_cleanse(tmp_buf,sizeof tmp_buf);
775 }
776#endif
777#ifndef OPENSSL_NO_KRB5
778 else if (l & SSL_kKRB5)
779 {
780 krb5_error_code krb5rc;
781 KSSL_CTX *kssl_ctx = s->kssl_ctx;
782 /* krb5_data krb5_ap_req; */
783 krb5_data *enc_ticket;
784 krb5_data authenticator, *authp = NULL;
785 EVP_CIPHER_CTX ciph_ctx;
786 EVP_CIPHER *enc = NULL;
787 unsigned char iv[EVP_MAX_IV_LENGTH];
788 unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
789 unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH
790 + EVP_MAX_IV_LENGTH];
791 int padl, outl = sizeof(epms);
792
793 EVP_CIPHER_CTX_init(&ciph_ctx);
794
795#ifdef KSSL_DEBUG
796 printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
797 l, SSL_kKRB5);
798#endif /* KSSL_DEBUG */
799
800 authp = NULL;
801#ifdef KRB5SENDAUTH
802 if (KRB5SENDAUTH) authp = &authenticator;
803#endif /* KRB5SENDAUTH */
804
805 krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp,
806 &kssl_err);
807 enc = kssl_map_enc(kssl_ctx->enctype);
808 if (enc == NULL)
809 goto err;
810#ifdef KSSL_DEBUG
811 {
812 printf("kssl_cget_tkt rtn %d\n", krb5rc);
813 if (krb5rc && kssl_err.text)
814 printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
815 }
816#endif /* KSSL_DEBUG */
817
818 if (krb5rc)
819 {
820 ssl3_send_alert(s,SSL3_AL_FATAL,
821 SSL_AD_HANDSHAKE_FAILURE);
822 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
823 kssl_err.reason);
824 goto err;
825 }
826
827 /* 20010406 VRS - Earlier versions used KRB5 AP_REQ
828 ** in place of RFC 2712 KerberosWrapper, as in:
829 **
830 ** Send ticket (copy to *p, set n = length)
831 ** n = krb5_ap_req.length;
832 ** memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
833 ** if (krb5_ap_req.data)
834 ** kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
835 **
836 ** Now using real RFC 2712 KerberosWrapper
837 ** (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
838 ** Note: 2712 "opaque" types are here replaced
839 ** with a 2-byte length followed by the value.
840 ** Example:
841 ** KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
842 ** Where "xx xx" = length bytes. Shown here with
843 ** optional authenticator omitted.
844 */
845
846 /* KerberosWrapper.Ticket */
847 s2n(enc_ticket->length,p);
848 memcpy(p, enc_ticket->data, enc_ticket->length);
849 p+= enc_ticket->length;
850 n = enc_ticket->length + 2;
851
852 /* KerberosWrapper.Authenticator */
853 if (authp && authp->length)
854 {
855 s2n(authp->length,p);
856 memcpy(p, authp->data, authp->length);
857 p+= authp->length;
858 n+= authp->length + 2;
859
860 free(authp->data);
861 authp->data = NULL;
862 authp->length = 0;
863 }
864 else
865 {
866 s2n(0,p);/* null authenticator length */
867 n+=2;
868 }
869
870 if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0)
871 goto err;
872
873 /* 20010420 VRS. Tried it this way; failed.
874 ** EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
875 ** EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
876 ** kssl_ctx->length);
877 ** EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
878 */
879
880 memset(iv, 0, sizeof iv); /* per RFC 1510 */
881 EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,
882 kssl_ctx->key,iv);
883 EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf,
884 sizeof tmp_buf);
885 EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
886 outl += padl;
887 if (outl > sizeof epms)
888 {
889 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
890 goto err;
891 }
892 EVP_CIPHER_CTX_cleanup(&ciph_ctx);
893
894 /* KerberosWrapper.EncryptedPreMasterSecret */
895 s2n(outl,p);
896 memcpy(p, epms, outl);
897 p+=outl;
898 n+=outl + 2;
899
900 s->session->master_key_length=
901 s->method->ssl3_enc->generate_master_secret(s,
902 s->session->master_key,
903 tmp_buf, sizeof tmp_buf);
904
905 OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
906 OPENSSL_cleanse(epms, outl);
907 }
908#endif
909#ifndef OPENSSL_NO_DH
910 else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
911 {
912 DH *dh_srvr,*dh_clnt;
913
914 if (s->session->sess_cert->peer_dh_tmp != NULL)
915 dh_srvr=s->session->sess_cert->peer_dh_tmp;
916 else
917 {
918 /* we get them from the cert */
919 ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
920 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
921 goto err;
922 }
923
924 /* generate a new random key */
925 if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL)
926 {
927 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
928 goto err;
929 }
930 if (!DH_generate_key(dh_clnt))
931 {
932 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
933 goto err;
934 }
935
936 /* use the 'p' output buffer for the DH key, but
937 * make sure to clear it out afterwards */
938
939 n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt);
940
941 if (n <= 0)
942 {
943 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB);
944 goto err;
945 }
946
947 /* generate master key from the result */
948 s->session->master_key_length=
949 s->method->ssl3_enc->generate_master_secret(s,
950 s->session->master_key,p,n);
951 /* clean up */
952 memset(p,0,n);
953
954 /* send off the data */
955 n=BN_num_bytes(dh_clnt->pub_key);
956 s2n(n,p);
957 BN_bn2bin(dh_clnt->pub_key,p);
958 n+=2;
959
960 DH_free(dh_clnt);
961
962 /* perhaps clean things up a bit EAY EAY EAY EAY*/
963 }
964#endif
965 else
966 {
967 ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
968 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
969 goto err;
970 }
971
972 d = dtls1_set_message_header(s, d,
973 SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n);
974 /*
975 *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
976 l2n3(n,d);
977 l2n(s->d1->handshake_write_seq,d);
978 s->d1->handshake_write_seq++;
979 */
980
981 s->state=SSL3_ST_CW_KEY_EXCH_B;
982 /* number of bytes to write */
983 s->init_num=n+DTLS1_HM_HEADER_LENGTH;
984 s->init_off=0;
985
986 /* buffer the message to handle re-xmits */
987 dtls1_buffer_message(s, 0);
988 }
989
990 /* SSL3_ST_CW_KEY_EXCH_B */
991 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
992err:
993 return(-1);
994 }
995
996int dtls1_send_client_verify(SSL *s)
997 {
998 unsigned char *p,*d;
999 unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
1000 EVP_PKEY *pkey;
1001#ifndef OPENSSL_NO_RSA
1002 unsigned u=0;
1003#endif
1004 unsigned long n;
1005#ifndef OPENSSL_NO_DSA
1006 int j;
1007#endif
1008
1009 if (s->state == SSL3_ST_CW_CERT_VRFY_A)
1010 {
1011 d=(unsigned char *)s->init_buf->data;
1012 p= &(d[DTLS1_HM_HEADER_LENGTH]);
1013 pkey=s->cert->key->privatekey;
1014
1015 s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2),
1016 &(data[MD5_DIGEST_LENGTH]));
1017
1018#ifndef OPENSSL_NO_RSA
1019 if (pkey->type == EVP_PKEY_RSA)
1020 {
1021 s->method->ssl3_enc->cert_verify_mac(s,
1022 &(s->s3->finish_dgst1),&(data[0]));
1023 if (RSA_sign(NID_md5_sha1, data,
1024 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
1025 &(p[2]), &u, pkey->pkey.rsa) <= 0 )
1026 {
1027 SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB);
1028 goto err;
1029 }
1030 s2n(u,p);
1031 n=u+2;
1032 }
1033 else
1034#endif
1035#ifndef OPENSSL_NO_DSA
1036 if (pkey->type == EVP_PKEY_DSA)
1037 {
1038 if (!DSA_sign(pkey->save_type,
1039 &(data[MD5_DIGEST_LENGTH]),
1040 SHA_DIGEST_LENGTH,&(p[2]),
1041 (unsigned int *)&j,pkey->pkey.dsa))
1042 {
1043 SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB);
1044 goto err;
1045 }
1046 s2n(j,p);
1047 n=j+2;
1048 }
1049 else
1050#endif
1051 {
1052 SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY,ERR_R_INTERNAL_ERROR);
1053 goto err;
1054 }
1055
1056 d = dtls1_set_message_header(s, d,
1057 SSL3_MT_CERTIFICATE_VERIFY, n, 0, n) ;
1058
1059 s->init_num=(int)n+DTLS1_HM_HEADER_LENGTH;
1060 s->init_off=0;
1061
1062 /* buffer the message to handle re-xmits */
1063 dtls1_buffer_message(s, 0);
1064
1065 s->state = SSL3_ST_CW_CERT_VRFY_B;
1066 }
1067
1068 /* s->state = SSL3_ST_CW_CERT_VRFY_B */
1069 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1070err:
1071 return(-1);
1072 }
1073
1074int dtls1_send_client_certificate(SSL *s)
1075 {
1076 X509 *x509=NULL;
1077 EVP_PKEY *pkey=NULL;
1078 int i;
1079 unsigned long l;
1080
1081 if (s->state == SSL3_ST_CW_CERT_A)
1082 {
1083 if ((s->cert == NULL) ||
1084 (s->cert->key->x509 == NULL) ||
1085 (s->cert->key->privatekey == NULL))
1086 s->state=SSL3_ST_CW_CERT_B;
1087 else
1088 s->state=SSL3_ST_CW_CERT_C;
1089 }
1090
1091 /* We need to get a client cert */
1092 if (s->state == SSL3_ST_CW_CERT_B)
1093 {
1094 /* If we get an error, we need to
1095 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
1096 * We then get retied later */
1097 i=0;
1098 if (s->ctx->client_cert_cb != NULL)
1099 i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
1100 if (i < 0)
1101 {
1102 s->rwstate=SSL_X509_LOOKUP;
1103 return(-1);
1104 }
1105 s->rwstate=SSL_NOTHING;
1106 if ((i == 1) && (pkey != NULL) && (x509 != NULL))
1107 {
1108 s->state=SSL3_ST_CW_CERT_B;
1109 if ( !SSL_use_certificate(s,x509) ||
1110 !SSL_use_PrivateKey(s,pkey))
1111 i=0;
1112 }
1113 else if (i == 1)
1114 {
1115 i=0;
1116 SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
1117 }
1118
1119 if (x509 != NULL) X509_free(x509);
1120 if (pkey != NULL) EVP_PKEY_free(pkey);
1121 if (i == 0)
1122 {
1123 if (s->version == SSL3_VERSION)
1124 {
1125 s->s3->tmp.cert_req=0;
1126 ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE);
1127 return(1);
1128 }
1129 else
1130 {
1131 s->s3->tmp.cert_req=2;
1132 }
1133 }
1134
1135 /* Ok, we have a cert */
1136 s->state=SSL3_ST_CW_CERT_C;
1137 }
1138
1139 if (s->state == SSL3_ST_CW_CERT_C)
1140 {
1141 s->state=SSL3_ST_CW_CERT_D;
1142 l=dtls1_output_cert_chain(s,
1143 (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509);
1144 s->init_num=(int)l;
1145 s->init_off=0;
1146
1147 /* set header called by dtls1_output_cert_chain() */
1148
1149 /* buffer the message to handle re-xmits */
1150 dtls1_buffer_message(s, 0);
1151 }
1152 /* SSL3_ST_CW_CERT_D */
1153 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1154 }
1155
1156
diff --git a/src/lib/libssl/d1_enc.c b/src/lib/libssl/d1_enc.c
new file mode 100644
index 0000000000..cbff7495c5
--- /dev/null
+++ b/src/lib/libssl/d1_enc.c
@@ -0,0 +1,281 @@
1/* ssl/d1_enc.c */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@openssl.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
60 * All rights reserved.
61 *
62 * This package is an SSL implementation written
63 * by Eric Young (eay@cryptsoft.com).
64 * The implementation was written so as to conform with Netscapes SSL.
65 *
66 * This library is free for commercial and non-commercial use as long as
67 * the following conditions are aheared to. The following conditions
68 * apply to all code found in this distribution, be it the RC4, RSA,
69 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
70 * included with this distribution is covered by the same copyright terms
71 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
72 *
73 * Copyright remains Eric Young's, and as such any Copyright notices in
74 * the code are not to be removed.
75 * If this package is used in a product, Eric Young should be given attribution
76 * as the author of the parts of the library used.
77 * This can be in the form of a textual message at program startup or
78 * in documentation (online or textual) provided with the package.
79 *
80 * Redistribution and use in source and binary forms, with or without
81 * modification, are permitted provided that the following conditions
82 * are met:
83 * 1. Redistributions of source code must retain the copyright
84 * notice, this list of conditions and the following disclaimer.
85 * 2. Redistributions in binary form must reproduce the above copyright
86 * notice, this list of conditions and the following disclaimer in the
87 * documentation and/or other materials provided with the distribution.
88 * 3. All advertising materials mentioning features or use of this software
89 * must display the following acknowledgement:
90 * "This product includes cryptographic software written by
91 * Eric Young (eay@cryptsoft.com)"
92 * The word 'cryptographic' can be left out if the rouines from the library
93 * being used are not cryptographic related :-).
94 * 4. If you include any Windows specific code (or a derivative thereof) from
95 * the apps directory (application code) you must include an acknowledgement:
96 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
97 *
98 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
99 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
101 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
102 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108 * SUCH DAMAGE.
109 *
110 * The licence and distribution terms for any publically available version or
111 * derivative of this code cannot be changed. i.e. this code cannot simply be
112 * copied and put under another distribution licence
113 * [including the GNU Public Licence.]
114 */
115
116#include <stdio.h>
117#include "ssl_locl.h"
118#include <openssl/comp.h>
119#include <openssl/evp.h>
120#include <openssl/hmac.h>
121#include <openssl/md5.h>
122#include <openssl/rand.h>
123
124
125int dtls1_enc(SSL *s, int send)
126 {
127 SSL3_RECORD *rec;
128 EVP_CIPHER_CTX *ds;
129 unsigned long l;
130 int bs,i,ii,j,k,n=0;
131 const EVP_CIPHER *enc;
132
133 if (send)
134 {
135 if (s->write_hash != NULL)
136 n=EVP_MD_size(s->write_hash);
137 ds=s->enc_write_ctx;
138 rec= &(s->s3->wrec);
139 if (s->enc_write_ctx == NULL)
140 enc=NULL;
141 else
142 {
143 enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
144 if ( rec->data != rec->input)
145 /* we can't write into the input stream */
146 fprintf(stderr, "%s:%d: rec->data != rec->input\n",
147 __FILE__, __LINE__);
148 else if ( EVP_CIPHER_block_size(ds->cipher) > 1)
149 {
150 if (!RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)))
151 return -1;
152 }
153 }
154 }
155 else
156 {
157 if (s->read_hash != NULL)
158 n=EVP_MD_size(s->read_hash);
159 ds=s->enc_read_ctx;
160 rec= &(s->s3->rrec);
161 if (s->enc_read_ctx == NULL)
162 enc=NULL;
163 else
164 enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
165 }
166
167#ifdef KSSL_DEBUG
168 printf("dtls1_enc(%d)\n", send);
169#endif /* KSSL_DEBUG */
170
171 if ((s->session == NULL) || (ds == NULL) ||
172 (enc == NULL))
173 {
174 memmove(rec->data,rec->input,rec->length);
175 rec->input=rec->data;
176 }
177 else
178 {
179 l=rec->length;
180 bs=EVP_CIPHER_block_size(ds->cipher);
181
182 if ((bs != 1) && send)
183 {
184 i=bs-((int)l%bs);
185
186 /* Add weird padding of upto 256 bytes */
187
188 /* we need to add 'i' padding bytes of value j */
189 j=i-1;
190 if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
191 {
192 if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
193 j++;
194 }
195 for (k=(int)l; k<(int)(l+i); k++)
196 rec->input[k]=j;
197 l+=i;
198 rec->length+=i;
199 }
200
201#ifdef KSSL_DEBUG
202 {
203 unsigned long ui;
204 printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
205 ds,rec->data,rec->input,l);
206 printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
207 ds->buf_len, ds->cipher->key_len,
208 DES_KEY_SZ, DES_SCHEDULE_SZ,
209 ds->cipher->iv_len);
210 printf("\t\tIV: ");
211 for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
212 printf("\n");
213 printf("\trec->input=");
214 for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
215 printf("\n");
216 }
217#endif /* KSSL_DEBUG */
218
219 if (!send)
220 {
221 if (l == 0 || l%bs != 0)
222 {
223 SSLerr(SSL_F_DTLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
224 ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
225 return 0;
226 }
227 }
228
229 EVP_Cipher(ds,rec->data,rec->input,l);
230
231#ifdef KSSL_DEBUG
232 {
233 unsigned long i;
234 printf("\trec->data=");
235 for (i=0; i<l; i++)
236 printf(" %02x", rec->data[i]); printf("\n");
237 }
238#endif /* KSSL_DEBUG */
239
240 if ((bs != 1) && !send)
241 {
242 ii=i=rec->data[l-1]; /* padding_length */
243 i++;
244 if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
245 {
246 /* First packet is even in size, so check */
247 if ((memcmp(s->s3->read_sequence,
248 "\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
249 s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
250 if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
251 i--;
252 }
253 /* TLS 1.0 does not bound the number of padding bytes by the block size.
254 * All of them must have value 'padding_length'. */
255 if (i > (int)rec->length)
256 {
257 /* Incorrect padding. SSLerr() and ssl3_alert are done
258 * by caller: we don't want to reveal whether this is
259 * a decryption error or a MAC verification failure
260 * (see http://www.openssl.org/~bodo/tls-cbc.txt)
261 */
262 return -1;
263 }
264 for (j=(int)(l-i); j<(int)l; j++)
265 {
266 if (rec->data[j] != ii)
267 {
268 /* Incorrect padding */
269 return -1;
270 }
271 }
272 rec->length-=i;
273
274 rec->data += bs; /* skip the implicit IV */
275 rec->input += bs;
276 rec->length -= bs;
277 }
278 }
279 return(1);
280 }
281
diff --git a/src/lib/libssl/d1_lib.c b/src/lib/libssl/d1_lib.c
new file mode 100644
index 0000000000..fc088b4148
--- /dev/null
+++ b/src/lib/libssl/d1_lib.c
@@ -0,0 +1,210 @@
1/* ssl/d1_lib.c */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
60#include <stdio.h>
61#include <openssl/objects.h>
62#include "ssl_locl.h"
63
64const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
65
66SSL3_ENC_METHOD DTLSv1_enc_data={
67 dtls1_enc,
68 tls1_mac,
69 tls1_setup_key_block,
70 tls1_generate_master_secret,
71 tls1_change_cipher_state,
72 tls1_final_finish_mac,
73 TLS1_FINISH_MAC_LENGTH,
74 tls1_cert_verify_mac,
75 TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE,
76 TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
77 tls1_alert_code,
78 };
79
80long dtls1_default_timeout(void)
81 {
82 /* 2 hours, the 24 hours mentioned in the DTLSv1 spec
83 * is way too long for http, the cache would over fill */
84 return(60*60*2);
85 }
86
87IMPLEMENT_dtls1_meth_func(dtlsv1_base_method,
88 ssl_undefined_function,
89 ssl_undefined_function,
90 ssl_bad_method)
91
92int dtls1_new(SSL *s)
93 {
94 DTLS1_STATE *d1;
95
96 if (!ssl3_new(s)) return(0);
97 if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0);
98 memset(d1,0, sizeof *d1);
99
100 /* d1->handshake_epoch=0; */
101#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)
102 d1->bitmap.length=64;
103#else
104 d1->bitmap.length=sizeof(d1->bitmap.map) * 8;
105#endif
106 pq_64bit_init(&(d1->bitmap.map));
107 pq_64bit_init(&(d1->bitmap.max_seq_num));
108
109 pq_64bit_init(&(d1->next_bitmap.map));
110 pq_64bit_init(&(d1->next_bitmap.max_seq_num));
111
112 d1->unprocessed_rcds.q=pqueue_new();
113 d1->processed_rcds.q=pqueue_new();
114 d1->buffered_messages = pqueue_new();
115 d1->sent_messages=pqueue_new();
116
117 if ( s->server)
118 {
119 d1->cookie_len = sizeof(s->d1->cookie);
120 }
121
122 if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q
123 || ! d1->buffered_messages || ! d1->sent_messages)
124 {
125 if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q);
126 if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q);
127 if ( d1->buffered_messages) pqueue_free(d1->buffered_messages);
128 if ( d1->sent_messages) pqueue_free(d1->sent_messages);
129 OPENSSL_free(d1);
130 return (0);
131 }
132
133 s->d1=d1;
134 s->method->ssl_clear(s);
135 return(1);
136 }
137
138void dtls1_free(SSL *s)
139 {
140 pitem *item = NULL;
141 hm_fragment *frag = NULL;
142
143 ssl3_free(s);
144
145 while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL)
146 {
147 OPENSSL_free(item->data);
148 pitem_free(item);
149 }
150 pqueue_free(s->d1->unprocessed_rcds.q);
151
152 while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL)
153 {
154 OPENSSL_free(item->data);
155 pitem_free(item);
156 }
157 pqueue_free(s->d1->processed_rcds.q);
158
159 while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL)
160 {
161 frag = (hm_fragment *)item->data;
162 OPENSSL_free(frag->fragment);
163 OPENSSL_free(frag);
164 pitem_free(item);
165 }
166 pqueue_free(s->d1->buffered_messages);
167
168 while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL)
169 {
170 frag = (hm_fragment *)item->data;
171 OPENSSL_free(frag->fragment);
172 OPENSSL_free(frag);
173 pitem_free(item);
174 }
175 pqueue_free(s->d1->sent_messages);
176
177 pq_64bit_free(&(s->d1->bitmap.map));
178 pq_64bit_free(&(s->d1->bitmap.max_seq_num));
179
180 pq_64bit_free(&(s->d1->next_bitmap.map));
181 pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
182
183 OPENSSL_free(s->d1);
184 }
185
186void dtls1_clear(SSL *s)
187 {
188 ssl3_clear(s);
189 s->version=DTLS1_VERSION;
190 }
191
192/*
193 * As it's impossible to use stream ciphers in "datagram" mode, this
194 * simple filter is designed to disengage them in DTLS. Unfortunately
195 * there is no universal way to identify stream SSL_CIPHER, so we have
196 * to explicitly list their SSL_* codes. Currently RC4 is the only one
197 * available, but if new ones emerge, they will have to be added...
198 */
199SSL_CIPHER *dtls1_get_cipher(unsigned int u)
200 {
201 SSL_CIPHER *ciph = ssl3_get_cipher(u);
202
203 if (ciph != NULL)
204 {
205 if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4)
206 return NULL;
207 }
208
209 return ciph;
210 }
diff --git a/src/lib/libssl/d1_meth.c b/src/lib/libssl/d1_meth.c
new file mode 100644
index 0000000000..8a6cf31947
--- /dev/null
+++ b/src/lib/libssl/d1_meth.c
@@ -0,0 +1,77 @@
1/* ssl/d1_meth.h */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
60#include <stdio.h>
61#include <openssl/objects.h>
62#include "ssl_locl.h"
63
64static SSL_METHOD *dtls1_get_method(int ver);
65static SSL_METHOD *dtls1_get_method(int ver)
66 {
67 if (ver == DTLS1_VERSION)
68 return(DTLSv1_method());
69 else
70 return(NULL);
71 }
72
73IMPLEMENT_dtls1_meth_func(DTLSv1_method,
74 dtls1_accept,
75 dtls1_connect,
76 dtls1_get_method)
77
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c
new file mode 100644
index 0000000000..377696deac
--- /dev/null
+++ b/src/lib/libssl/d1_pkt.c
@@ -0,0 +1,1778 @@
1/* ssl/d1_pkt.c */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@openssl.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
60 * All rights reserved.
61 *
62 * This package is an SSL implementation written
63 * by Eric Young (eay@cryptsoft.com).
64 * The implementation was written so as to conform with Netscapes SSL.
65 *
66 * This library is free for commercial and non-commercial use as long as
67 * the following conditions are aheared to. The following conditions
68 * apply to all code found in this distribution, be it the RC4, RSA,
69 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
70 * included with this distribution is covered by the same copyright terms
71 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
72 *
73 * Copyright remains Eric Young's, and as such any Copyright notices in
74 * the code are not to be removed.
75 * If this package is used in a product, Eric Young should be given attribution
76 * as the author of the parts of the library used.
77 * This can be in the form of a textual message at program startup or
78 * in documentation (online or textual) provided with the package.
79 *
80 * Redistribution and use in source and binary forms, with or without
81 * modification, are permitted provided that the following conditions
82 * are met:
83 * 1. Redistributions of source code must retain the copyright
84 * notice, this list of conditions and the following disclaimer.
85 * 2. Redistributions in binary form must reproduce the above copyright
86 * notice, this list of conditions and the following disclaimer in the
87 * documentation and/or other materials provided with the distribution.
88 * 3. All advertising materials mentioning features or use of this software
89 * must display the following acknowledgement:
90 * "This product includes cryptographic software written by
91 * Eric Young (eay@cryptsoft.com)"
92 * The word 'cryptographic' can be left out if the rouines from the library
93 * being used are not cryptographic related :-).
94 * 4. If you include any Windows specific code (or a derivative thereof) from
95 * the apps directory (application code) you must include an acknowledgement:
96 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
97 *
98 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
99 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
101 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
102 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108 * SUCH DAMAGE.
109 *
110 * The licence and distribution terms for any publically available version or
111 * derivative of this code cannot be changed. i.e. this code cannot simply be
112 * copied and put under another distribution licence
113 * [including the GNU Public Licence.]
114 */
115
116#include <stdio.h>
117#include <errno.h>
118#define USE_SOCKETS
119#include "ssl_locl.h"
120#include <openssl/evp.h>
121#include <openssl/buffer.h>
122#include <openssl/pqueue.h>
123#include <openssl/rand.h>
124
125static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
126 int len, int peek);
127static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
128 PQ_64BIT *seq_num);
129static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
130static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
131 unsigned int *is_next_epoch);
132#if 0
133static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
134 unsigned short *priority, unsigned long *offset);
135#endif
136static int dtls1_buffer_record(SSL *s, record_pqueue *q,
137 PQ_64BIT priority);
138static int dtls1_process_record(SSL *s);
139#if PQ_64BIT_IS_INTEGER
140static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num);
141#endif
142static void dtls1_clear_timeouts(SSL *s);
143
144/* copy buffered record into SSL structure */
145static int
146dtls1_copy_record(SSL *s, pitem *item)
147 {
148 DTLS1_RECORD_DATA *rdata;
149
150 rdata = (DTLS1_RECORD_DATA *)item->data;
151
152 if (s->s3->rbuf.buf != NULL)
153 OPENSSL_free(s->s3->rbuf.buf);
154
155 s->packet = rdata->packet;
156 s->packet_length = rdata->packet_length;
157 memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
158 memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
159
160 return(1);
161 }
162
163
164static int
165dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority)
166{
167 DTLS1_RECORD_DATA *rdata;
168 pitem *item;
169
170 rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
171 item = pitem_new(priority, rdata);
172 if (rdata == NULL || item == NULL)
173 {
174 if (rdata != NULL) OPENSSL_free(rdata);
175 if (item != NULL) pitem_free(item);
176
177 SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
178 return(0);
179 }
180
181 rdata->packet = s->packet;
182 rdata->packet_length = s->packet_length;
183 memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER));
184 memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD));
185
186 item->data = rdata;
187
188 /* insert should not fail, since duplicates are dropped */
189 if (pqueue_insert(queue->q, item) == NULL)
190 {
191 OPENSSL_free(rdata);
192 pitem_free(item);
193 return(0);
194 }
195
196 s->packet = NULL;
197 s->packet_length = 0;
198 memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
199 memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD));
200
201 if (!ssl3_setup_buffers(s))
202 {
203 SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
204 OPENSSL_free(rdata);
205 pitem_free(item);
206 return(0);
207 }
208
209 return(1);
210 }
211
212
213static int
214dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
215 {
216 pitem *item;
217
218 item = pqueue_pop(queue->q);
219 if (item)
220 {
221 dtls1_copy_record(s, item);
222
223 OPENSSL_free(item->data);
224 pitem_free(item);
225
226 return(1);
227 }
228
229 return(0);
230 }
231
232
233/* retrieve a buffered record that belongs to the new epoch, i.e., not processed
234 * yet */
235#define dtls1_get_unprocessed_record(s) \
236 dtls1_retrieve_buffered_record((s), \
237 &((s)->d1->unprocessed_rcds))
238
239/* retrieve a buffered record that belongs to the current epoch, ie, processed */
240#define dtls1_get_processed_record(s) \
241 dtls1_retrieve_buffered_record((s), \
242 &((s)->d1->processed_rcds))
243
244static int
245dtls1_process_buffered_records(SSL *s)
246 {
247 pitem *item;
248
249 item = pqueue_peek(s->d1->unprocessed_rcds.q);
250 if (item)
251 {
252 DTLS1_RECORD_DATA *rdata;
253 rdata = (DTLS1_RECORD_DATA *)item->data;
254
255 /* Check if epoch is current. */
256 if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
257 return(1); /* Nothing to do. */
258
259 /* Process all the records. */
260 while (pqueue_peek(s->d1->unprocessed_rcds.q))
261 {
262 dtls1_get_unprocessed_record(s);
263 if ( ! dtls1_process_record(s))
264 return(0);
265 dtls1_buffer_record(s, &(s->d1->processed_rcds),
266 s->s3->rrec.seq_num);
267 }
268 }
269
270 /* sync epoch numbers once all the unprocessed records
271 * have been processed */
272 s->d1->processed_rcds.epoch = s->d1->r_epoch;
273 s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;
274
275 return(1);
276 }
277
278
279#if 0
280
281static int
282dtls1_get_buffered_record(SSL *s)
283 {
284 pitem *item;
285 PQ_64BIT priority =
286 (((PQ_64BIT)s->d1->handshake_read_seq) << 32) |
287 ((PQ_64BIT)s->d1->r_msg_hdr.frag_off);
288
289 if ( ! SSL_in_init(s)) /* if we're not (re)negotiating,
290 nothing buffered */
291 return 0;
292
293
294 item = pqueue_peek(s->d1->rcvd_records);
295 if (item && item->priority == priority)
296 {
297 /* Check if we've received the record of interest. It must be
298 * a handshake record, since data records as passed up without
299 * buffering */
300 DTLS1_RECORD_DATA *rdata;
301 item = pqueue_pop(s->d1->rcvd_records);
302 rdata = (DTLS1_RECORD_DATA *)item->data;
303
304 if (s->s3->rbuf.buf != NULL)
305 OPENSSL_free(s->s3->rbuf.buf);
306
307 s->packet = rdata->packet;
308 s->packet_length = rdata->packet_length;
309 memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER));
310 memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD));
311
312 OPENSSL_free(item->data);
313 pitem_free(item);
314
315 /* s->d1->next_expected_seq_num++; */
316 return(1);
317 }
318
319 return 0;
320 }
321
322#endif
323
324static int
325dtls1_process_record(SSL *s)
326{
327 int i,al;
328 int clear=0;
329 int enc_err;
330 SSL_SESSION *sess;
331 SSL3_RECORD *rr;
332 unsigned int mac_size;
333 unsigned char md[EVP_MAX_MD_SIZE];
334
335
336 rr= &(s->s3->rrec);
337 sess = s->session;
338
339 /* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
340 * and we have that many bytes in s->packet
341 */
342 rr->input= &(s->packet[DTLS1_RT_HEADER_LENGTH]);
343
344 /* ok, we can now read from 's->packet' data into 'rr'
345 * rr->input points at rr->length bytes, which
346 * need to be copied into rr->data by either
347 * the decryption or by the decompression
348 * When the data is 'copied' into the rr->data buffer,
349 * rr->input will be pointed at the new buffer */
350
351 /* We now have - encrypted [ MAC [ compressed [ plain ] ] ]
352 * rr->length bytes of encrypted compressed stuff. */
353
354 /* check is not needed I believe */
355 if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
356 {
357 al=SSL_AD_RECORD_OVERFLOW;
358 SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
359 goto f_err;
360 }
361
362 /* decrypt in place in 'rr->input' */
363 rr->data=rr->input;
364
365 enc_err = s->method->ssl3_enc->enc(s,0);
366 if (enc_err <= 0)
367 {
368 if (enc_err == 0)
369 /* SSLerr() and ssl3_send_alert() have been called */
370 goto err;
371
372 /* otherwise enc_err == -1 */
373 goto decryption_failed_or_bad_record_mac;
374 }
375
376#ifdef TLS_DEBUG
377printf("dec %d\n",rr->length);
378{ unsigned int z; for (z=0; z<rr->length; z++) printf("%02X%c",rr->data[z],((z+1)%16)?' ':'\n'); }
379printf("\n");
380#endif
381
382 /* r->length is now the compressed data plus mac */
383if ( (sess == NULL) ||
384 (s->enc_read_ctx == NULL) ||
385 (s->read_hash == NULL))
386 clear=1;
387
388 if (!clear)
389 {
390 mac_size=EVP_MD_size(s->read_hash);
391
392 if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
393 {
394#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
395 al=SSL_AD_RECORD_OVERFLOW;
396 SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
397 goto f_err;
398#else
399 goto decryption_failed_or_bad_record_mac;
400#endif
401 }
402 /* check the MAC for rr->input (it's in mac_size bytes at the tail) */
403 if (rr->length < mac_size)
404 {
405#if 0 /* OK only for stream ciphers */
406 al=SSL_AD_DECODE_ERROR;
407 SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
408 goto f_err;
409#else
410 goto decryption_failed_or_bad_record_mac;
411#endif
412 }
413 rr->length-=mac_size;
414 i=s->method->ssl3_enc->mac(s,md,0);
415 if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
416 {
417 goto decryption_failed_or_bad_record_mac;
418 }
419 }
420
421 /* r->length is now just compressed */
422 if (s->expand != NULL)
423 {
424 if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH)
425 {
426 al=SSL_AD_RECORD_OVERFLOW;
427 SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
428 goto f_err;
429 }
430 if (!ssl3_do_uncompress(s))
431 {
432 al=SSL_AD_DECOMPRESSION_FAILURE;
433 SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_BAD_DECOMPRESSION);
434 goto f_err;
435 }
436 }
437
438 if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH)
439 {
440 al=SSL_AD_RECORD_OVERFLOW;
441 SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DATA_LENGTH_TOO_LONG);
442 goto f_err;
443 }
444
445 rr->off=0;
446 /* So at this point the following is true
447 * ssl->s3->rrec.type is the type of record
448 * ssl->s3->rrec.length == number of bytes in record
449 * ssl->s3->rrec.off == offset to first valid byte
450 * ssl->s3->rrec.data == where to take bytes from, increment
451 * after use :-).
452 */
453
454 /* we have pulled in a full packet so zero things */
455 s->packet_length=0;
456 dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
457 return(1);
458
459decryption_failed_or_bad_record_mac:
460 /* Separate 'decryption_failed' alert was introduced with TLS 1.0,
461 * SSL 3.0 only has 'bad_record_mac'. But unless a decryption
462 * failure is directly visible from the ciphertext anyway,
463 * we should not reveal which kind of error occured -- this
464 * might become visible to an attacker (e.g. via logfile) */
465 al=SSL_AD_BAD_RECORD_MAC;
466 SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
467f_err:
468 ssl3_send_alert(s,SSL3_AL_FATAL,al);
469err:
470 return(0);
471}
472
473
474/* Call this to get a new input record.
475 * It will return <= 0 if more data is needed, normally due to an error
476 * or non-blocking IO.
477 * When it finishes, one packet has been decoded and can be found in
478 * ssl->s3->rrec.type - is the type of record
479 * ssl->s3->rrec.data, - data
480 * ssl->s3->rrec.length, - number of bytes
481 */
482/* used only by dtls1_read_bytes */
483int dtls1_get_record(SSL *s)
484 {
485 int ssl_major,ssl_minor,al;
486 int i,n;
487 SSL3_RECORD *rr;
488 SSL_SESSION *sess;
489 unsigned char *p;
490 unsigned short version;
491 DTLS1_BITMAP *bitmap;
492 unsigned int is_next_epoch;
493
494 rr= &(s->s3->rrec);
495 sess=s->session;
496
497 /* The epoch may have changed. If so, process all the
498 * pending records. This is a non-blocking operation. */
499 if ( ! dtls1_process_buffered_records(s))
500 return 0;
501
502 /* if we're renegotiating, then there may be buffered records */
503 if (dtls1_get_processed_record(s))
504 return 1;
505
506 /* get something from the wire */
507again:
508 /* check if we have the header */
509 if ( (s->rstate != SSL_ST_READ_BODY) ||
510 (s->packet_length < DTLS1_RT_HEADER_LENGTH))
511 {
512 n=ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0);
513 /* read timeout is handled by dtls1_read_bytes */
514 if (n <= 0) return(n); /* error or non-blocking */
515
516 OPENSSL_assert(s->packet_length == DTLS1_RT_HEADER_LENGTH);
517
518 s->rstate=SSL_ST_READ_BODY;
519
520 p=s->packet;
521
522 /* Pull apart the header into the DTLS1_RECORD */
523 rr->type= *(p++);
524 ssl_major= *(p++);
525 ssl_minor= *(p++);
526 version=(ssl_major<<8)|ssl_minor;
527
528 /* sequence number is 64 bits, with top 2 bytes = epoch */
529 n2s(p,rr->epoch);
530
531 memcpy(&(s->s3->read_sequence[2]), p, 6);
532 p+=6;
533
534 n2s(p,rr->length);
535
536 /* Lets check version */
537 if (!s->first_packet)
538 {
539 if (version != s->version && version != DTLS1_BAD_VER)
540 {
541 SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
542 /* Send back error using their
543 * version number :-) */
544 s->version=version;
545 al=SSL_AD_PROTOCOL_VERSION;
546 goto f_err;
547 }
548 }
549
550 if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
551 (version & 0xff00) != (DTLS1_BAD_VER & 0xff00))
552 {
553 SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
554 goto err;
555 }
556
557 if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH)
558 {
559 al=SSL_AD_RECORD_OVERFLOW;
560 SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
561 goto f_err;
562 }
563
564 s->client_version = version;
565 /* now s->rstate == SSL_ST_READ_BODY */
566 }
567
568 /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
569
570 if (rr->length > s->packet_length-DTLS1_RT_HEADER_LENGTH)
571 {
572 /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
573 i=rr->length;
574 n=ssl3_read_n(s,i,i,1);
575 if (n <= 0) return(n); /* error or non-blocking io */
576
577 /* this packet contained a partial record, dump it */
578 if ( n != i)
579 {
580 s->packet_length = 0;
581 goto again;
582 }
583
584 /* now n == rr->length,
585 * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
586 }
587 s->rstate=SSL_ST_READ_HEADER; /* set state for later operations */
588
589 /* match epochs. NULL means the packet is dropped on the floor */
590 bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
591 if ( bitmap == NULL)
592 {
593 s->packet_length = 0; /* dump this record */
594 goto again; /* get another record */
595 }
596
597 /* check whether this is a repeat, or aged record */
598 if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
599 {
600 s->packet_length=0; /* dump this record */
601 goto again; /* get another record */
602 }
603
604 /* just read a 0 length packet */
605 if (rr->length == 0) goto again;
606
607 /* If this record is from the next epoch (either HM or ALERT), buffer it
608 * since it cannot be processed at this time.
609 * Records from the next epoch are marked as received even though they are
610 * not processed, so as to prevent any potential resource DoS attack */
611 if (is_next_epoch)
612 {
613 dtls1_record_bitmap_update(s, bitmap);
614 dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num);
615 s->packet_length = 0;
616 goto again;
617 }
618
619 if ( ! dtls1_process_record(s))
620 return(0);
621
622 dtls1_clear_timeouts(s); /* done waiting */
623 return(1);
624
625f_err:
626 ssl3_send_alert(s,SSL3_AL_FATAL,al);
627err:
628 return(0);
629 }
630
631/* Return up to 'len' payload bytes received in 'type' records.
632 * 'type' is one of the following:
633 *
634 * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
635 * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
636 * - 0 (during a shutdown, no data has to be returned)
637 *
638 * If we don't have stored data to work from, read a SSL/TLS record first
639 * (possibly multiple records if we still don't have anything to return).
640 *
641 * This function must handle any surprises the peer may have for us, such as
642 * Alert records (e.g. close_notify), ChangeCipherSpec records (not really
643 * a surprise, but handled as if it were), or renegotiation requests.
644 * Also if record payloads contain fragments too small to process, we store
645 * them until there is enough for the respective protocol (the record protocol
646 * may use arbitrary fragmentation and even interleaving):
647 * Change cipher spec protocol
648 * just 1 byte needed, no need for keeping anything stored
649 * Alert protocol
650 * 2 bytes needed (AlertLevel, AlertDescription)
651 * Handshake protocol
652 * 4 bytes needed (HandshakeType, uint24 length) -- we just have
653 * to detect unexpected Client Hello and Hello Request messages
654 * here, anything else is handled by higher layers
655 * Application data protocol
656 * none of our business
657 */
658int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
659 {
660 int al,i,j,ret;
661 unsigned int n;
662 SSL3_RECORD *rr;
663 void (*cb)(const SSL *ssl,int type2,int val)=NULL;
664
665 if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
666 if (!ssl3_setup_buffers(s))
667 return(-1);
668
669 /* XXX: check what the second '&& type' is about */
670 if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
671 (type != SSL3_RT_HANDSHAKE) && type) ||
672 (peek && (type != SSL3_RT_APPLICATION_DATA)))
673 {
674 SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
675 return -1;
676 }
677
678 /* check whether there's a handshake message (client hello?) waiting */
679 if ( (ret = have_handshake_fragment(s, type, buf, len, peek)))
680 return ret;
681
682 /* Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. */
683
684 if (!s->in_handshake && SSL_in_init(s))
685 {
686 /* type == SSL3_RT_APPLICATION_DATA */
687 i=s->handshake_func(s);
688 if (i < 0) return(i);
689 if (i == 0)
690 {
691 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
692 return(-1);
693 }
694 }
695
696start:
697 s->rwstate=SSL_NOTHING;
698
699 /* s->s3->rrec.type - is the type of record
700 * s->s3->rrec.data, - data
701 * s->s3->rrec.off, - offset into 'data' for next read
702 * s->s3->rrec.length, - number of bytes. */
703 rr = &(s->s3->rrec);
704
705 /* get new packet if necessary */
706 if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
707 {
708 ret=dtls1_get_record(s);
709 if (ret <= 0)
710 {
711 ret = dtls1_read_failed(s, ret);
712 /* anything other than a timeout is an error */
713 if (ret <= 0)
714 return(ret);
715 else
716 goto start;
717 }
718 }
719
720 /* we now have a packet which can be read and processed */
721
722 if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
723 * reset by ssl3_get_finished */
724 && (rr->type != SSL3_RT_HANDSHAKE))
725 {
726 al=SSL_AD_UNEXPECTED_MESSAGE;
727 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
728 goto err;
729 }
730
731 /* If the other end has shut down, throw anything we read away
732 * (even in 'peek' mode) */
733 if (s->shutdown & SSL_RECEIVED_SHUTDOWN)
734 {
735 rr->length=0;
736 s->rwstate=SSL_NOTHING;
737 return(0);
738 }
739
740
741 if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
742 {
743 /* make sure that we are not getting application data when we
744 * are doing a handshake for the first time */
745 if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
746 (s->enc_read_ctx == NULL))
747 {
748 al=SSL_AD_UNEXPECTED_MESSAGE;
749 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_APP_DATA_IN_HANDSHAKE);
750 goto f_err;
751 }
752
753 if (len <= 0) return(len);
754
755 if ((unsigned int)len > rr->length)
756 n = rr->length;
757 else
758 n = (unsigned int)len;
759
760 memcpy(buf,&(rr->data[rr->off]),n);
761 if (!peek)
762 {
763 rr->length-=n;
764 rr->off+=n;
765 if (rr->length == 0)
766 {
767 s->rstate=SSL_ST_READ_HEADER;
768 rr->off=0;
769 }
770 }
771 return(n);
772 }
773
774
775 /* If we get here, then type != rr->type; if we have a handshake
776 * message, then it was unexpected (Hello Request or Client Hello). */
777
778 /* In case of record types for which we have 'fragment' storage,
779 * fill that so that we can process the data at a fixed place.
780 */
781 {
782 unsigned int k, dest_maxlen = 0;
783 unsigned char *dest = NULL;
784 unsigned int *dest_len = NULL;
785
786 if (rr->type == SSL3_RT_HANDSHAKE)
787 {
788 dest_maxlen = sizeof s->d1->handshake_fragment;
789 dest = s->d1->handshake_fragment;
790 dest_len = &s->d1->handshake_fragment_len;
791 }
792 else if (rr->type == SSL3_RT_ALERT)
793 {
794 dest_maxlen = sizeof(s->d1->alert_fragment);
795 dest = s->d1->alert_fragment;
796 dest_len = &s->d1->alert_fragment_len;
797 }
798 /* else it's a CCS message, or it's wrong */
799 else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC)
800 {
801 /* Not certain if this is the right error handling */
802 al=SSL_AD_UNEXPECTED_MESSAGE;
803 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
804 goto f_err;
805 }
806
807
808 if (dest_maxlen > 0)
809 {
810 /* XDTLS: In a pathalogical case, the Client Hello
811 * may be fragmented--don't always expect dest_maxlen bytes */
812 if ( rr->length < dest_maxlen)
813 {
814 s->rstate=SSL_ST_READ_HEADER;
815 rr->length = 0;
816 goto start;
817 }
818
819 /* now move 'n' bytes: */
820 for ( k = 0; k < dest_maxlen; k++)
821 {
822 dest[k] = rr->data[rr->off++];
823 rr->length--;
824 }
825 *dest_len = dest_maxlen;
826 }
827 }
828
829 /* s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE;
830 * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT.
831 * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) */
832
833 /* If we are a client, check for an incoming 'Hello Request': */
834 if ((!s->server) &&
835 (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
836 (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
837 (s->session != NULL) && (s->session->cipher != NULL))
838 {
839 s->d1->handshake_fragment_len = 0;
840
841 if ((s->d1->handshake_fragment[1] != 0) ||
842 (s->d1->handshake_fragment[2] != 0) ||
843 (s->d1->handshake_fragment[3] != 0))
844 {
845 al=SSL_AD_DECODE_ERROR;
846 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_HELLO_REQUEST);
847 goto err;
848 }
849
850 /* no need to check sequence number on HELLO REQUEST messages */
851
852 if (s->msg_callback)
853 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
854 s->d1->handshake_fragment, 4, s, s->msg_callback_arg);
855
856 if (SSL_is_init_finished(s) &&
857 !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
858 !s->s3->renegotiate)
859 {
860 ssl3_renegotiate(s);
861 if (ssl3_renegotiate_check(s))
862 {
863 i=s->handshake_func(s);
864 if (i < 0) return(i);
865 if (i == 0)
866 {
867 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
868 return(-1);
869 }
870
871 if (!(s->mode & SSL_MODE_AUTO_RETRY))
872 {
873 if (s->s3->rbuf.left == 0) /* no read-ahead left? */
874 {
875 BIO *bio;
876 /* In the case where we try to read application data,
877 * but we trigger an SSL handshake, we return -1 with
878 * the retry option set. Otherwise renegotiation may
879 * cause nasty problems in the blocking world */
880 s->rwstate=SSL_READING;
881 bio=SSL_get_rbio(s);
882 BIO_clear_retry_flags(bio);
883 BIO_set_retry_read(bio);
884 return(-1);
885 }
886 }
887 }
888 }
889 /* we either finished a handshake or ignored the request,
890 * now try again to obtain the (application) data we were asked for */
891 goto start;
892 }
893
894 if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH)
895 {
896 int alert_level = s->d1->alert_fragment[0];
897 int alert_descr = s->d1->alert_fragment[1];
898
899 s->d1->alert_fragment_len = 0;
900
901 if (s->msg_callback)
902 s->msg_callback(0, s->version, SSL3_RT_ALERT,
903 s->d1->alert_fragment, 2, s, s->msg_callback_arg);
904
905 if (s->info_callback != NULL)
906 cb=s->info_callback;
907 else if (s->ctx->info_callback != NULL)
908 cb=s->ctx->info_callback;
909
910 if (cb != NULL)
911 {
912 j = (alert_level << 8) | alert_descr;
913 cb(s, SSL_CB_READ_ALERT, j);
914 }
915
916 if (alert_level == 1) /* warning */
917 {
918 s->s3->warn_alert = alert_descr;
919 if (alert_descr == SSL_AD_CLOSE_NOTIFY)
920 {
921 s->shutdown |= SSL_RECEIVED_SHUTDOWN;
922 return(0);
923 }
924#if 0
925 /* XXX: this is a possible improvement in the future */
926 /* now check if it's a missing record */
927 if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
928 {
929 unsigned short seq;
930 unsigned int frag_off;
931 unsigned char *p = &(s->d1->alert_fragment[2]);
932
933 n2s(p, seq);
934 n2l3(p, frag_off);
935
936 dtls1_retransmit_message(s, seq, frag_off, &found);
937 if ( ! found && SSL_in_init(s))
938 {
939 /* fprintf( stderr,"in init = %d\n", SSL_in_init(s)); */
940 /* requested a message not yet sent,
941 send an alert ourselves */
942 ssl3_send_alert(s,SSL3_AL_WARNING,
943 DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
944 }
945 }
946#endif
947 }
948 else if (alert_level == 2) /* fatal */
949 {
950 char tmp[16];
951
952 s->rwstate=SSL_NOTHING;
953 s->s3->fatal_alert = alert_descr;
954 SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
955 BIO_snprintf(tmp,sizeof tmp,"%d",alert_descr);
956 ERR_add_error_data(2,"SSL alert number ",tmp);
957 s->shutdown|=SSL_RECEIVED_SHUTDOWN;
958 SSL_CTX_remove_session(s->ctx,s->session);
959 return(0);
960 }
961 else
962 {
963 al=SSL_AD_ILLEGAL_PARAMETER;
964 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNKNOWN_ALERT_TYPE);
965 goto f_err;
966 }
967
968 goto start;
969 }
970
971 if (s->shutdown & SSL_SENT_SHUTDOWN) /* but we have not received a shutdown */
972 {
973 s->rwstate=SSL_NOTHING;
974 rr->length=0;
975 return(0);
976 }
977
978 if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
979 {
980 struct ccs_header_st ccs_hdr;
981
982 dtls1_get_ccs_header(rr->data, &ccs_hdr);
983
984 /* 'Change Cipher Spec' is just a single byte, so we know
985 * exactly what the record payload has to look like */
986 /* XDTLS: check that epoch is consistent */
987 if ( (s->client_version == DTLS1_BAD_VER && rr->length != 3) ||
988 (s->client_version != DTLS1_BAD_VER && rr->length != DTLS1_CCS_HEADER_LENGTH) ||
989 (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
990 {
991 i=SSL_AD_ILLEGAL_PARAMETER;
992 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
993 goto err;
994 }
995
996 rr->length=0;
997
998 if (s->msg_callback)
999 s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
1000 rr->data, 1, s, s->msg_callback_arg);
1001
1002 s->s3->change_cipher_spec=1;
1003 if (!ssl3_do_change_cipher_spec(s))
1004 goto err;
1005
1006 /* do this whenever CCS is processed */
1007 dtls1_reset_seq_numbers(s, SSL3_CC_READ);
1008
1009 if (s->client_version == DTLS1_BAD_VER)
1010 s->d1->handshake_read_seq++;
1011
1012 goto start;
1013 }
1014
1015 /* Unexpected handshake message (Client Hello, or protocol violation) */
1016 if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
1017 !s->in_handshake)
1018 {
1019 struct hm_header_st msg_hdr;
1020
1021 /* this may just be a stale retransmit */
1022 dtls1_get_message_header(rr->data, &msg_hdr);
1023 if( rr->epoch != s->d1->r_epoch)
1024 {
1025 rr->length = 0;
1026 goto start;
1027 }
1028
1029 if (((s->state&SSL_ST_MASK) == SSL_ST_OK) &&
1030 !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS))
1031 {
1032#if 0 /* worked only because C operator preferences are not as expected (and
1033 * because this is not really needed for clients except for detecting
1034 * protocol violations): */
1035 s->state=SSL_ST_BEFORE|(s->server)
1036 ?SSL_ST_ACCEPT
1037 :SSL_ST_CONNECT;
1038#else
1039 s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT;
1040#endif
1041 s->new_session=1;
1042 }
1043 i=s->handshake_func(s);
1044 if (i < 0) return(i);
1045 if (i == 0)
1046 {
1047 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
1048 return(-1);
1049 }
1050
1051 if (!(s->mode & SSL_MODE_AUTO_RETRY))
1052 {
1053 if (s->s3->rbuf.left == 0) /* no read-ahead left? */
1054 {
1055 BIO *bio;
1056 /* In the case where we try to read application data,
1057 * but we trigger an SSL handshake, we return -1 with
1058 * the retry option set. Otherwise renegotiation may
1059 * cause nasty problems in the blocking world */
1060 s->rwstate=SSL_READING;
1061 bio=SSL_get_rbio(s);
1062 BIO_clear_retry_flags(bio);
1063 BIO_set_retry_read(bio);
1064 return(-1);
1065 }
1066 }
1067 goto start;
1068 }
1069
1070 switch (rr->type)
1071 {
1072 default:
1073#ifndef OPENSSL_NO_TLS
1074 /* TLS just ignores unknown message types */
1075 if (s->version == TLS1_VERSION)
1076 {
1077 rr->length = 0;
1078 goto start;
1079 }
1080#endif
1081 al=SSL_AD_UNEXPECTED_MESSAGE;
1082 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
1083 goto f_err;
1084 case SSL3_RT_CHANGE_CIPHER_SPEC:
1085 case SSL3_RT_ALERT:
1086 case SSL3_RT_HANDSHAKE:
1087 /* we already handled all of these, with the possible exception
1088 * of SSL3_RT_HANDSHAKE when s->in_handshake is set, but that
1089 * should not happen when type != rr->type */
1090 al=SSL_AD_UNEXPECTED_MESSAGE;
1091 SSLerr(SSL_F_DTLS1_READ_BYTES,ERR_R_INTERNAL_ERROR);
1092 goto f_err;
1093 case SSL3_RT_APPLICATION_DATA:
1094 /* At this point, we were expecting handshake data,
1095 * but have application data. If the library was
1096 * running inside ssl3_read() (i.e. in_read_app_data
1097 * is set) and it makes sense to read application data
1098 * at this point (session renegotiation not yet started),
1099 * we will indulge it.
1100 */
1101 if (s->s3->in_read_app_data &&
1102 (s->s3->total_renegotiations != 0) &&
1103 ((
1104 (s->state & SSL_ST_CONNECT) &&
1105 (s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&
1106 (s->state <= SSL3_ST_CR_SRVR_HELLO_A)
1107 ) || (
1108 (s->state & SSL_ST_ACCEPT) &&
1109 (s->state <= SSL3_ST_SW_HELLO_REQ_A) &&
1110 (s->state >= SSL3_ST_SR_CLNT_HELLO_A)
1111 )
1112 ))
1113 {
1114 s->s3->in_read_app_data=2;
1115 return(-1);
1116 }
1117 else
1118 {
1119 al=SSL_AD_UNEXPECTED_MESSAGE;
1120 SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_UNEXPECTED_RECORD);
1121 goto f_err;
1122 }
1123 }
1124 /* not reached */
1125
1126f_err:
1127 ssl3_send_alert(s,SSL3_AL_FATAL,al);
1128err:
1129 return(-1);
1130 }
1131
1132int
1133dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
1134 {
1135 unsigned int n,tot;
1136 int i;
1137
1138 if (SSL_in_init(s) && !s->in_handshake)
1139 {
1140 i=s->handshake_func(s);
1141 if (i < 0) return(i);
1142 if (i == 0)
1143 {
1144 SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,SSL_R_SSL_HANDSHAKE_FAILURE);
1145 return -1;
1146 }
1147 }
1148
1149 tot = s->s3->wnum;
1150 n = len - tot;
1151
1152 while( n)
1153 {
1154 /* dtls1_write_bytes sends one record at a time, sized according to
1155 * the currently known MTU */
1156 i = dtls1_write_bytes(s, type, buf_, len);
1157 if (i <= 0) return i;
1158
1159 if ((i == (int)n) ||
1160 (type == SSL3_RT_APPLICATION_DATA &&
1161 (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))
1162 {
1163 /* next chunk of data should get another prepended empty fragment
1164 * in ciphersuites with known-IV weakness: */
1165 s->s3->empty_fragment_done = 0;
1166 return tot+i;
1167 }
1168
1169 tot += i;
1170 n-=i;
1171 }
1172
1173 return tot;
1174 }
1175
1176
1177 /* this only happens when a client hello is received and a handshake
1178 * is started. */
1179static int
1180have_handshake_fragment(SSL *s, int type, unsigned char *buf,
1181 int len, int peek)
1182 {
1183
1184 if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0))
1185 /* (partially) satisfy request from storage */
1186 {
1187 unsigned char *src = s->d1->handshake_fragment;
1188 unsigned char *dst = buf;
1189 unsigned int k,n;
1190
1191 /* peek == 0 */
1192 n = 0;
1193 while ((len > 0) && (s->d1->handshake_fragment_len > 0))
1194 {
1195 *dst++ = *src++;
1196 len--; s->d1->handshake_fragment_len--;
1197 n++;
1198 }
1199 /* move any remaining fragment bytes: */
1200 for (k = 0; k < s->d1->handshake_fragment_len; k++)
1201 s->d1->handshake_fragment[k] = *src++;
1202 return n;
1203 }
1204
1205 return 0;
1206 }
1207
1208
1209
1210
1211/* Call this to write data in records of type 'type'
1212 * It will return <= 0 if not all data has been sent or non-blocking IO.
1213 */
1214int dtls1_write_bytes(SSL *s, int type, const void *buf_, int len)
1215 {
1216 const unsigned char *buf=buf_;
1217 unsigned int tot,n,nw;
1218 int i;
1219 unsigned int mtu;
1220
1221 s->rwstate=SSL_NOTHING;
1222 tot=s->s3->wnum;
1223
1224 n=(len-tot);
1225
1226 /* handshake layer figures out MTU for itself, but data records
1227 * are also sent through this interface, so need to figure out MTU */
1228#if 0
1229 mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_MTU, 0, NULL);
1230 mtu += DTLS1_HM_HEADER_LENGTH; /* HM already inserted */
1231#endif
1232 mtu = s->d1->mtu;
1233
1234 if (mtu > SSL3_RT_MAX_PLAIN_LENGTH)
1235 mtu = SSL3_RT_MAX_PLAIN_LENGTH;
1236
1237 if (n > mtu)
1238 nw=mtu;
1239 else
1240 nw=n;
1241
1242 i=do_dtls1_write(s, type, &(buf[tot]), nw, 0);
1243 if (i <= 0)
1244 {
1245 s->s3->wnum=tot;
1246 return i;
1247 }
1248
1249 if ( (int)s->s3->wnum + i == len)
1250 s->s3->wnum = 0;
1251 else
1252 s->s3->wnum += i;
1253
1254 return tot + i;
1255 }
1256
1257int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
1258 {
1259 unsigned char *p,*pseq;
1260 int i,mac_size,clear=0;
1261 int prefix_len = 0;
1262 SSL3_RECORD *wr;
1263 SSL3_BUFFER *wb;
1264 SSL_SESSION *sess;
1265 int bs;
1266
1267 /* first check if there is a SSL3_BUFFER still being written
1268 * out. This will happen with non blocking IO */
1269 if (s->s3->wbuf.left != 0)
1270 {
1271 OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */
1272 return(ssl3_write_pending(s,type,buf,len));
1273 }
1274
1275 /* If we have an alert to send, lets send it */
1276 if (s->s3->alert_dispatch)
1277 {
1278 i=s->method->ssl_dispatch_alert(s);
1279 if (i <= 0)
1280 return(i);
1281 /* if it went, fall through and send more stuff */
1282 }
1283
1284 if (len == 0 && !create_empty_fragment)
1285 return 0;
1286
1287 wr= &(s->s3->wrec);
1288 wb= &(s->s3->wbuf);
1289 sess=s->session;
1290
1291 if ( (sess == NULL) ||
1292 (s->enc_write_ctx == NULL) ||
1293 (s->write_hash == NULL))
1294 clear=1;
1295
1296 if (clear)
1297 mac_size=0;
1298 else
1299 mac_size=EVP_MD_size(s->write_hash);
1300
1301 /* DTLS implements explicit IV, so no need for empty fragments */
1302#if 0
1303 /* 'create_empty_fragment' is true only when this function calls itself */
1304 if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
1305 && SSL_version(s) != DTLS1_VERSION)
1306 {
1307 /* countermeasure against known-IV weakness in CBC ciphersuites
1308 * (see http://www.openssl.org/~bodo/tls-cbc.txt)
1309 */
1310
1311 if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
1312 {
1313 /* recursive function call with 'create_empty_fragment' set;
1314 * this prepares and buffers the data for an empty fragment
1315 * (these 'prefix_len' bytes are sent out later
1316 * together with the actual payload) */
1317 prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
1318 if (prefix_len <= 0)
1319 goto err;
1320
1321 if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
1322 {
1323 /* insufficient space */
1324 SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
1325 goto err;
1326 }
1327 }
1328
1329 s->s3->empty_fragment_done = 1;
1330 }
1331#endif
1332
1333 p = wb->buf + prefix_len;
1334
1335 /* write the header */
1336
1337 *(p++)=type&0xff;
1338 wr->type=type;
1339
1340 if (s->client_version == DTLS1_BAD_VER)
1341 *(p++) = DTLS1_BAD_VER>>8,
1342 *(p++) = DTLS1_BAD_VER&0xff;
1343 else
1344 *(p++)=(s->version>>8),
1345 *(p++)=s->version&0xff;
1346
1347 /* field where we are to write out packet epoch, seq num and len */
1348 pseq=p;
1349 p+=10;
1350
1351 /* lets setup the record stuff. */
1352
1353 /* Make space for the explicit IV in case of CBC.
1354 * (this is a bit of a boundary violation, but what the heck).
1355 */
1356 if ( s->enc_write_ctx &&
1357 (EVP_CIPHER_mode( s->enc_write_ctx->cipher ) & EVP_CIPH_CBC_MODE))
1358 bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
1359 else
1360 bs = 0;
1361
1362 wr->data=p + bs; /* make room for IV in case of CBC */
1363 wr->length=(int)len;
1364 wr->input=(unsigned char *)buf;
1365
1366 /* we now 'read' from wr->input, wr->length bytes into
1367 * wr->data */
1368
1369 /* first we compress */
1370 if (s->compress != NULL)
1371 {
1372 if (!ssl3_do_compress(s))
1373 {
1374 SSLerr(SSL_F_DO_DTLS1_WRITE,SSL_R_COMPRESSION_FAILURE);
1375 goto err;
1376 }
1377 }
1378 else
1379 {
1380 memcpy(wr->data,wr->input,wr->length);
1381 wr->input=wr->data;
1382 }
1383
1384 /* we should still have the output to wr->data and the input
1385 * from wr->input. Length should be wr->length.
1386 * wr->data still points in the wb->buf */
1387
1388 if (mac_size != 0)
1389 {
1390 s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1);
1391 wr->length+=mac_size;
1392 }
1393
1394 /* this is true regardless of mac size */
1395 wr->input=p;
1396 wr->data=p;
1397
1398
1399 /* ssl3_enc can only have an error on read */
1400 if (bs) /* bs != 0 in case of CBC */
1401 {
1402 RAND_pseudo_bytes(p,bs);
1403 /* master IV and last CBC residue stand for
1404 * the rest of randomness */
1405 wr->length += bs;
1406 }
1407
1408 s->method->ssl3_enc->enc(s,1);
1409
1410 /* record length after mac and block padding */
1411/* if (type == SSL3_RT_APPLICATION_DATA ||
1412 (type == SSL3_RT_ALERT && ! SSL_in_init(s))) */
1413
1414 /* there's only one epoch between handshake and app data */
1415
1416 s2n(s->d1->w_epoch, pseq);
1417
1418 /* XDTLS: ?? */
1419/* else
1420 s2n(s->d1->handshake_epoch, pseq); */
1421
1422 memcpy(pseq, &(s->s3->write_sequence[2]), 6);
1423 pseq+=6;
1424 s2n(wr->length,pseq);
1425
1426 /* we should now have
1427 * wr->data pointing to the encrypted data, which is
1428 * wr->length long */
1429 wr->type=type; /* not needed but helps for debugging */
1430 wr->length+=DTLS1_RT_HEADER_LENGTH;
1431
1432#if 0 /* this is now done at the message layer */
1433 /* buffer the record, making it easy to handle retransmits */
1434 if ( type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC)
1435 dtls1_buffer_record(s, wr->data, wr->length,
1436 *((PQ_64BIT *)&(s->s3->write_sequence[0])));
1437#endif
1438
1439 ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
1440
1441 if (create_empty_fragment)
1442 {
1443 /* we are in a recursive call;
1444 * just return the length, don't write out anything here
1445 */
1446 return wr->length;
1447 }
1448
1449 /* now let's set up wb */
1450 wb->left = prefix_len + wr->length;
1451 wb->offset = 0;
1452
1453 /* memorize arguments so that ssl3_write_pending can detect bad write retries later */
1454 s->s3->wpend_tot=len;
1455 s->s3->wpend_buf=buf;
1456 s->s3->wpend_type=type;
1457 s->s3->wpend_ret=len;
1458
1459 /* we now just need to write the buffer */
1460 return ssl3_write_pending(s,type,buf,len);
1461err:
1462 return -1;
1463 }
1464
1465
1466
1467static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
1468 PQ_64BIT *seq_num)
1469 {
1470#if PQ_64BIT_IS_INTEGER
1471 PQ_64BIT mask = 0x0000000000000001L;
1472#endif
1473 PQ_64BIT rcd_num, tmp;
1474
1475 pq_64bit_init(&rcd_num);
1476 pq_64bit_init(&tmp);
1477
1478 /* this is the sequence number for the record just read */
1479 pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8);
1480
1481
1482 if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
1483 pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num)))
1484 {
1485 pq_64bit_assign(seq_num, &rcd_num);
1486 pq_64bit_free(&rcd_num);
1487 pq_64bit_free(&tmp);
1488 return 1; /* this record is new */
1489 }
1490
1491 pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
1492
1493 if ( pq_64bit_get_word(&tmp) > bitmap->length)
1494 {
1495 pq_64bit_free(&rcd_num);
1496 pq_64bit_free(&tmp);
1497 return 0; /* stale, outside the window */
1498 }
1499
1500#if PQ_64BIT_IS_BIGNUM
1501 {
1502 int offset;
1503 pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
1504 pq_64bit_sub_word(&tmp, 1);
1505 offset = pq_64bit_get_word(&tmp);
1506 if ( pq_64bit_is_bit_set(&(bitmap->map), offset))
1507 {
1508 pq_64bit_free(&rcd_num);
1509 pq_64bit_free(&tmp);
1510 return 0;
1511 }
1512 }
1513#else
1514 mask <<= (bitmap->max_seq_num - rcd_num - 1);
1515 if (bitmap->map & mask)
1516 return 0; /* record previously received */
1517#endif
1518
1519 pq_64bit_assign(seq_num, &rcd_num);
1520 pq_64bit_free(&rcd_num);
1521 pq_64bit_free(&tmp);
1522 return 1;
1523 }
1524
1525
1526static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
1527 {
1528 unsigned int shift;
1529 PQ_64BIT rcd_num;
1530 PQ_64BIT tmp;
1531 PQ_64BIT_CTX *ctx;
1532
1533 pq_64bit_init(&rcd_num);
1534 pq_64bit_init(&tmp);
1535
1536 pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8);
1537
1538 /* unfortunate code complexity due to 64-bit manipulation support
1539 * on 32-bit machines */
1540 if ( pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
1541 pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num)))
1542 {
1543 pq_64bit_sub(&tmp, &rcd_num, &(bitmap->max_seq_num));
1544 pq_64bit_add_word(&tmp, 1);
1545
1546 shift = (unsigned int)pq_64bit_get_word(&tmp);
1547
1548 pq_64bit_lshift(&(tmp), &(bitmap->map), shift);
1549 pq_64bit_assign(&(bitmap->map), &tmp);
1550
1551 pq_64bit_set_bit(&(bitmap->map), 0);
1552 pq_64bit_add_word(&rcd_num, 1);
1553 pq_64bit_assign(&(bitmap->max_seq_num), &rcd_num);
1554
1555 pq_64bit_assign_word(&tmp, 1);
1556 pq_64bit_lshift(&tmp, &tmp, bitmap->length);
1557 ctx = pq_64bit_ctx_new(&ctx);
1558 pq_64bit_mod(&(bitmap->map), &(bitmap->map), &tmp, ctx);
1559 pq_64bit_ctx_free(ctx);
1560 }
1561 else
1562 {
1563 pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
1564 pq_64bit_sub_word(&tmp, 1);
1565 shift = (unsigned int)pq_64bit_get_word(&tmp);
1566
1567 pq_64bit_set_bit(&(bitmap->map), shift);
1568 }
1569
1570 pq_64bit_free(&rcd_num);
1571 pq_64bit_free(&tmp);
1572 }
1573
1574
1575int dtls1_dispatch_alert(SSL *s)
1576 {
1577 int i,j;
1578 void (*cb)(const SSL *ssl,int type,int val)=NULL;
1579 unsigned char buf[2 + 2 + 3]; /* alert level + alert desc + message seq +frag_off */
1580 unsigned char *ptr = &buf[0];
1581
1582 s->s3->alert_dispatch=0;
1583
1584 memset(buf, 0x00, sizeof(buf));
1585 *ptr++ = s->s3->send_alert[0];
1586 *ptr++ = s->s3->send_alert[1];
1587
1588 if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
1589 {
1590 s2n(s->d1->handshake_read_seq, ptr);
1591#if 0
1592 if ( s->d1->r_msg_hdr.frag_off == 0) /* waiting for a new msg */
1593
1594 else
1595 s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */
1596#endif
1597
1598#if 0
1599 fprintf(stderr, "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n",s->d1->handshake_read_seq,s->d1->r_msg_hdr.seq);
1600#endif
1601 l2n3(s->d1->r_msg_hdr.frag_off, ptr);
1602 }
1603
1604 i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
1605 if (i <= 0)
1606 {
1607 s->s3->alert_dispatch=1;
1608 /* fprintf( stderr, "not done with alert\n" ); */
1609 }
1610 else
1611 {
1612 if ( s->s3->send_alert[0] == SSL3_AL_FATAL ||
1613 s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
1614 (void)BIO_flush(s->wbio);
1615
1616 if (s->msg_callback)
1617 s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert,
1618 2, s, s->msg_callback_arg);
1619
1620 if (s->info_callback != NULL)
1621 cb=s->info_callback;
1622 else if (s->ctx->info_callback != NULL)
1623 cb=s->ctx->info_callback;
1624
1625 if (cb != NULL)
1626 {
1627 j=(s->s3->send_alert[0]<<8)|s->s3->send_alert[1];
1628 cb(s,SSL_CB_WRITE_ALERT,j);
1629 }
1630 }
1631 return(i);
1632 }
1633
1634
1635static DTLS1_BITMAP *
1636dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, unsigned int *is_next_epoch)
1637 {
1638
1639 *is_next_epoch = 0;
1640
1641 /* In current epoch, accept HM, CCS, DATA, & ALERT */
1642 if (rr->epoch == s->d1->r_epoch)
1643 return &s->d1->bitmap;
1644
1645 /* Only HM and ALERT messages can be from the next epoch */
1646 else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
1647 (rr->type == SSL3_RT_HANDSHAKE ||
1648 rr->type == SSL3_RT_ALERT))
1649 {
1650 *is_next_epoch = 1;
1651 return &s->d1->next_bitmap;
1652 }
1653
1654 return NULL;
1655 }
1656
1657#if 0
1658static int
1659dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, unsigned short *priority,
1660 unsigned long *offset)
1661 {
1662
1663 /* alerts are passed up immediately */
1664 if ( rr->type == SSL3_RT_APPLICATION_DATA ||
1665 rr->type == SSL3_RT_ALERT)
1666 return 0;
1667
1668 /* Only need to buffer if a handshake is underway.
1669 * (this implies that Hello Request and Client Hello are passed up
1670 * immediately) */
1671 if ( SSL_in_init(s))
1672 {
1673 unsigned char *data = rr->data;
1674 /* need to extract the HM/CCS sequence number here */
1675 if ( rr->type == SSL3_RT_HANDSHAKE ||
1676 rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
1677 {
1678 unsigned short seq_num;
1679 struct hm_header_st msg_hdr;
1680 struct ccs_header_st ccs_hdr;
1681
1682 if ( rr->type == SSL3_RT_HANDSHAKE)
1683 {
1684 dtls1_get_message_header(data, &msg_hdr);
1685 seq_num = msg_hdr.seq;
1686 *offset = msg_hdr.frag_off;
1687 }
1688 else
1689 {
1690 dtls1_get_ccs_header(data, &ccs_hdr);
1691 seq_num = ccs_hdr.seq;
1692 *offset = 0;
1693 }
1694
1695 /* this is either a record we're waiting for, or a
1696 * retransmit of something we happened to previously
1697 * receive (higher layers will drop the repeat silently */
1698 if ( seq_num < s->d1->handshake_read_seq)
1699 return 0;
1700 if (rr->type == SSL3_RT_HANDSHAKE &&
1701 seq_num == s->d1->handshake_read_seq &&
1702 msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off)
1703 return 0;
1704 else if ( seq_num == s->d1->handshake_read_seq &&
1705 (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC ||
1706 msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off))
1707 return 0;
1708 else
1709 {
1710 *priority = seq_num;
1711 return 1;
1712 }
1713 }
1714 else /* unknown record type */
1715 return 0;
1716 }
1717
1718 return 0;
1719 }
1720#endif
1721
1722void
1723dtls1_reset_seq_numbers(SSL *s, int rw)
1724 {
1725 unsigned char *seq;
1726 unsigned int seq_bytes = sizeof(s->s3->read_sequence);
1727
1728 if ( rw & SSL3_CC_READ)
1729 {
1730 seq = s->s3->read_sequence;
1731 s->d1->r_epoch++;
1732
1733 pq_64bit_assign(&(s->d1->bitmap.map), &(s->d1->next_bitmap.map));
1734 s->d1->bitmap.length = s->d1->next_bitmap.length;
1735 pq_64bit_assign(&(s->d1->bitmap.max_seq_num),
1736 &(s->d1->next_bitmap.max_seq_num));
1737
1738 pq_64bit_free(&(s->d1->next_bitmap.map));
1739 pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
1740 memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
1741 pq_64bit_init(&(s->d1->next_bitmap.map));
1742 pq_64bit_init(&(s->d1->next_bitmap.max_seq_num));
1743 }
1744 else
1745 {
1746 seq = s->s3->write_sequence;
1747 s->d1->w_epoch++;
1748 }
1749
1750 memset(seq, 0x00, seq_bytes);
1751 }
1752
1753#if PQ_64BIT_IS_INTEGER
1754static PQ_64BIT
1755bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num)
1756 {
1757 PQ_64BIT _num;
1758
1759 _num = (((PQ_64BIT)bytes[0]) << 56) |
1760 (((PQ_64BIT)bytes[1]) << 48) |
1761 (((PQ_64BIT)bytes[2]) << 40) |
1762 (((PQ_64BIT)bytes[3]) << 32) |
1763 (((PQ_64BIT)bytes[4]) << 24) |
1764 (((PQ_64BIT)bytes[5]) << 16) |
1765 (((PQ_64BIT)bytes[6]) << 8) |
1766 (((PQ_64BIT)bytes[7]) );
1767
1768 *num = _num ;
1769 return _num;
1770 }
1771#endif
1772
1773
1774static void
1775dtls1_clear_timeouts(SSL *s)
1776 {
1777 memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st));
1778 }
diff --git a/src/lib/libssl/d1_srvr.c b/src/lib/libssl/d1_srvr.c
new file mode 100644
index 0000000000..927b01f3c4
--- /dev/null
+++ b/src/lib/libssl/d1_srvr.c
@@ -0,0 +1,1147 @@
1/* ssl/d1_srvr.c */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
60 * All rights reserved.
61 *
62 * This package is an SSL implementation written
63 * by Eric Young (eay@cryptsoft.com).
64 * The implementation was written so as to conform with Netscapes SSL.
65 *
66 * This library is free for commercial and non-commercial use as long as
67 * the following conditions are aheared to. The following conditions
68 * apply to all code found in this distribution, be it the RC4, RSA,
69 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
70 * included with this distribution is covered by the same copyright terms
71 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
72 *
73 * Copyright remains Eric Young's, and as such any Copyright notices in
74 * the code are not to be removed.
75 * If this package is used in a product, Eric Young should be given attribution
76 * as the author of the parts of the library used.
77 * This can be in the form of a textual message at program startup or
78 * in documentation (online or textual) provided with the package.
79 *
80 * Redistribution and use in source and binary forms, with or without
81 * modification, are permitted provided that the following conditions
82 * are met:
83 * 1. Redistributions of source code must retain the copyright
84 * notice, this list of conditions and the following disclaimer.
85 * 2. Redistributions in binary form must reproduce the above copyright
86 * notice, this list of conditions and the following disclaimer in the
87 * documentation and/or other materials provided with the distribution.
88 * 3. All advertising materials mentioning features or use of this software
89 * must display the following acknowledgement:
90 * "This product includes cryptographic software written by
91 * Eric Young (eay@cryptsoft.com)"
92 * The word 'cryptographic' can be left out if the rouines from the library
93 * being used are not cryptographic related :-).
94 * 4. If you include any Windows specific code (or a derivative thereof) from
95 * the apps directory (application code) you must include an acknowledgement:
96 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
97 *
98 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
99 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
101 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
102 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108 * SUCH DAMAGE.
109 *
110 * The licence and distribution terms for any publically available version or
111 * derivative of this code cannot be changed. i.e. this code cannot simply be
112 * copied and put under another distribution licence
113 * [including the GNU Public Licence.]
114 */
115
116#include <stdio.h>
117#include "ssl_locl.h"
118#include <openssl/buffer.h>
119#include <openssl/rand.h>
120#include <openssl/objects.h>
121#include <openssl/evp.h>
122#include <openssl/x509.h>
123#include <openssl/md5.h>
124#ifndef OPENSSL_NO_DH
125#include <openssl/dh.h>
126#endif
127
128static SSL_METHOD *dtls1_get_server_method(int ver);
129static int dtls1_send_hello_verify_request(SSL *s);
130
131static SSL_METHOD *dtls1_get_server_method(int ver)
132 {
133 if (ver == DTLS1_VERSION)
134 return(DTLSv1_server_method());
135 else
136 return(NULL);
137 }
138
139IMPLEMENT_dtls1_meth_func(DTLSv1_server_method,
140 dtls1_accept,
141 ssl_undefined_function,
142 dtls1_get_server_method)
143
144int dtls1_accept(SSL *s)
145 {
146 BUF_MEM *buf;
147 unsigned long l,Time=(unsigned long)time(NULL);
148 void (*cb)(const SSL *ssl,int type,int val)=NULL;
149 long num1;
150 int ret= -1;
151 int new_state,state,skip=0;
152
153 RAND_add(&Time,sizeof(Time),0);
154 ERR_clear_error();
155 clear_sys_error();
156
157 if (s->info_callback != NULL)
158 cb=s->info_callback;
159 else if (s->ctx->info_callback != NULL)
160 cb=s->ctx->info_callback;
161
162 /* init things to blank */
163 s->in_handshake++;
164 if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
165
166 if (s->cert == NULL)
167 {
168 SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_NO_CERTIFICATE_SET);
169 return(-1);
170 }
171
172 for (;;)
173 {
174 state=s->state;
175
176 switch (s->state)
177 {
178 case SSL_ST_RENEGOTIATE:
179 s->new_session=1;
180 /* s->state=SSL_ST_ACCEPT; */
181
182 case SSL_ST_BEFORE:
183 case SSL_ST_ACCEPT:
184 case SSL_ST_BEFORE|SSL_ST_ACCEPT:
185 case SSL_ST_OK|SSL_ST_ACCEPT:
186
187 s->server=1;
188 if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
189
190 if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00))
191 {
192 SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR);
193 return -1;
194 }
195 s->type=SSL_ST_ACCEPT;
196
197 if (s->init_buf == NULL)
198 {
199 if ((buf=BUF_MEM_new()) == NULL)
200 {
201 ret= -1;
202 goto end;
203 }
204 if (!BUF_MEM_grow(buf,SSL3_RT_MAX_PLAIN_LENGTH))
205 {
206 ret= -1;
207 goto end;
208 }
209 s->init_buf=buf;
210 }
211
212 if (!ssl3_setup_buffers(s))
213 {
214 ret= -1;
215 goto end;
216 }
217
218 s->init_num=0;
219
220 if (s->state != SSL_ST_RENEGOTIATE)
221 {
222 /* Ok, we now need to push on a buffering BIO so that
223 * the output is sent in a way that TCP likes :-)
224 */
225 if (!ssl_init_wbio_buffer(s,1)) { ret= -1; goto end; }
226
227 ssl3_init_finished_mac(s);
228 s->state=SSL3_ST_SR_CLNT_HELLO_A;
229 s->ctx->stats.sess_accept++;
230 }
231 else
232 {
233 /* s->state == SSL_ST_RENEGOTIATE,
234 * we will just send a HelloRequest */
235 s->ctx->stats.sess_accept_renegotiate++;
236 s->state=SSL3_ST_SW_HELLO_REQ_A;
237 }
238
239 if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))
240 s->d1->send_cookie = 1;
241 else
242 s->d1->send_cookie = 0;
243
244 break;
245
246 case SSL3_ST_SW_HELLO_REQ_A:
247 case SSL3_ST_SW_HELLO_REQ_B:
248
249 s->shutdown=0;
250 ret=dtls1_send_hello_request(s);
251 if (ret <= 0) goto end;
252 s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
253 s->state=SSL3_ST_SW_FLUSH;
254 s->init_num=0;
255
256 ssl3_init_finished_mac(s);
257 break;
258
259 case SSL3_ST_SW_HELLO_REQ_C:
260 s->state=SSL_ST_OK;
261 break;
262
263 case SSL3_ST_SR_CLNT_HELLO_A:
264 case SSL3_ST_SR_CLNT_HELLO_B:
265 case SSL3_ST_SR_CLNT_HELLO_C:
266
267 s->shutdown=0;
268 ret=ssl3_get_client_hello(s);
269 if (ret <= 0) goto end;
270 s->new_session = 2;
271
272 if ( s->d1->send_cookie)
273 s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A;
274 else
275 s->state = SSL3_ST_SW_SRVR_HELLO_A;
276
277 s->init_num=0;
278 break;
279
280 case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
281 case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
282
283 ret = dtls1_send_hello_verify_request(s);
284 if ( ret <= 0) goto end;
285 s->d1->send_cookie = 0;
286 s->state=SSL3_ST_SW_FLUSH;
287 s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
288
289 /* HelloVerifyRequests resets Finished MAC */
290 if (s->client_version != DTLS1_BAD_VER)
291 ssl3_init_finished_mac(s);
292 break;
293
294 case SSL3_ST_SW_SRVR_HELLO_A:
295 case SSL3_ST_SW_SRVR_HELLO_B:
296 ret=dtls1_send_server_hello(s);
297 if (ret <= 0) goto end;
298
299 if (s->hit)
300 s->state=SSL3_ST_SW_CHANGE_A;
301 else
302 s->state=SSL3_ST_SW_CERT_A;
303 s->init_num=0;
304 break;
305
306 case SSL3_ST_SW_CERT_A:
307 case SSL3_ST_SW_CERT_B:
308 /* Check if it is anon DH */
309 if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
310 {
311 ret=dtls1_send_server_certificate(s);
312 if (ret <= 0) goto end;
313 }
314 else
315 skip=1;
316 s->state=SSL3_ST_SW_KEY_EXCH_A;
317 s->init_num=0;
318 break;
319
320 case SSL3_ST_SW_KEY_EXCH_A:
321 case SSL3_ST_SW_KEY_EXCH_B:
322 l=s->s3->tmp.new_cipher->algorithms;
323
324 /* clear this, it may get reset by
325 * send_server_key_exchange */
326 if ((s->options & SSL_OP_EPHEMERAL_RSA)
327#ifndef OPENSSL_NO_KRB5
328 && !(l & SSL_KRB5)
329#endif /* OPENSSL_NO_KRB5 */
330 )
331 /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
332 * even when forbidden by protocol specs
333 * (handshake may fail as clients are not required to
334 * be able to handle this) */
335 s->s3->tmp.use_rsa_tmp=1;
336 else
337 s->s3->tmp.use_rsa_tmp=0;
338
339 /* only send if a DH key exchange, fortezza or
340 * RSA but we have a sign only certificate */
341 if (s->s3->tmp.use_rsa_tmp
342 || (l & (SSL_DH|SSL_kFZA))
343 || ((l & SSL_kRSA)
344 && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
345 || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
346 && EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
347 )
348 )
349 )
350 )
351 {
352 ret=dtls1_send_server_key_exchange(s);
353 if (ret <= 0) goto end;
354 }
355 else
356 skip=1;
357
358 s->state=SSL3_ST_SW_CERT_REQ_A;
359 s->init_num=0;
360 break;
361
362 case SSL3_ST_SW_CERT_REQ_A:
363 case SSL3_ST_SW_CERT_REQ_B:
364 if (/* don't request cert unless asked for it: */
365 !(s->verify_mode & SSL_VERIFY_PEER) ||
366 /* if SSL_VERIFY_CLIENT_ONCE is set,
367 * don't request cert during re-negotiation: */
368 ((s->session->peer != NULL) &&
369 (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
370 /* never request cert in anonymous ciphersuites
371 * (see section "Certificate request" in SSL 3 drafts
372 * and in RFC 2246): */
373 ((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&
374 /* ... except when the application insists on verification
375 * (against the specs, but s3_clnt.c accepts this for SSL 3) */
376 !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
377 /* never request cert in Kerberos ciphersuites */
378 (s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))
379 {
380 /* no cert request */
381 skip=1;
382 s->s3->tmp.cert_request=0;
383 s->state=SSL3_ST_SW_SRVR_DONE_A;
384 }
385 else
386 {
387 s->s3->tmp.cert_request=1;
388 ret=dtls1_send_certificate_request(s);
389 if (ret <= 0) goto end;
390#ifndef NETSCAPE_HANG_BUG
391 s->state=SSL3_ST_SW_SRVR_DONE_A;
392#else
393 s->state=SSL3_ST_SW_FLUSH;
394 s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
395#endif
396 s->init_num=0;
397 }
398 break;
399
400 case SSL3_ST_SW_SRVR_DONE_A:
401 case SSL3_ST_SW_SRVR_DONE_B:
402 ret=dtls1_send_server_done(s);
403 if (ret <= 0) goto end;
404 s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
405 s->state=SSL3_ST_SW_FLUSH;
406 s->init_num=0;
407 break;
408
409 case SSL3_ST_SW_FLUSH:
410 /* number of bytes to be flushed */
411 num1=BIO_ctrl(s->wbio,BIO_CTRL_INFO,0,NULL);
412 if (num1 > 0)
413 {
414 s->rwstate=SSL_WRITING;
415 num1=BIO_flush(s->wbio);
416 if (num1 <= 0) { ret= -1; goto end; }
417 s->rwstate=SSL_NOTHING;
418 }
419
420 s->state=s->s3->tmp.next_state;
421 break;
422
423 case SSL3_ST_SR_CERT_A:
424 case SSL3_ST_SR_CERT_B:
425 /* Check for second client hello (MS SGC) */
426 ret = ssl3_check_client_hello(s);
427 if (ret <= 0)
428 goto end;
429 if (ret == 2)
430 s->state = SSL3_ST_SR_CLNT_HELLO_C;
431 else {
432 /* could be sent for a DH cert, even if we
433 * have not asked for it :-) */
434 ret=ssl3_get_client_certificate(s);
435 if (ret <= 0) goto end;
436 s->init_num=0;
437 s->state=SSL3_ST_SR_KEY_EXCH_A;
438 }
439 break;
440
441 case SSL3_ST_SR_KEY_EXCH_A:
442 case SSL3_ST_SR_KEY_EXCH_B:
443 ret=ssl3_get_client_key_exchange(s);
444 if (ret <= 0) goto end;
445 s->state=SSL3_ST_SR_CERT_VRFY_A;
446 s->init_num=0;
447
448 /* We need to get hashes here so if there is
449 * a client cert, it can be verified */
450 s->method->ssl3_enc->cert_verify_mac(s,
451 &(s->s3->finish_dgst1),
452 &(s->s3->tmp.cert_verify_md[0]));
453 s->method->ssl3_enc->cert_verify_mac(s,
454 &(s->s3->finish_dgst2),
455 &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
456
457 break;
458
459 case SSL3_ST_SR_CERT_VRFY_A:
460 case SSL3_ST_SR_CERT_VRFY_B:
461
462 /* we should decide if we expected this one */
463 ret=ssl3_get_cert_verify(s);
464 if (ret <= 0) goto end;
465
466 s->state=SSL3_ST_SR_FINISHED_A;
467 s->init_num=0;
468 break;
469
470 case SSL3_ST_SR_FINISHED_A:
471 case SSL3_ST_SR_FINISHED_B:
472 ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
473 SSL3_ST_SR_FINISHED_B);
474 if (ret <= 0) goto end;
475 if (s->hit)
476 s->state=SSL_ST_OK;
477 else
478 s->state=SSL3_ST_SW_CHANGE_A;
479 s->init_num=0;
480 break;
481
482 case SSL3_ST_SW_CHANGE_A:
483 case SSL3_ST_SW_CHANGE_B:
484
485 s->session->cipher=s->s3->tmp.new_cipher;
486 if (!s->method->ssl3_enc->setup_key_block(s))
487 { ret= -1; goto end; }
488
489 ret=dtls1_send_change_cipher_spec(s,
490 SSL3_ST_SW_CHANGE_A,SSL3_ST_SW_CHANGE_B);
491
492 if (ret <= 0) goto end;
493 s->state=SSL3_ST_SW_FINISHED_A;
494 s->init_num=0;
495
496 if (!s->method->ssl3_enc->change_cipher_state(s,
497 SSL3_CHANGE_CIPHER_SERVER_WRITE))
498 {
499 ret= -1;
500 goto end;
501 }
502
503 dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
504 break;
505
506 case SSL3_ST_SW_FINISHED_A:
507 case SSL3_ST_SW_FINISHED_B:
508 ret=dtls1_send_finished(s,
509 SSL3_ST_SW_FINISHED_A,SSL3_ST_SW_FINISHED_B,
510 s->method->ssl3_enc->server_finished_label,
511 s->method->ssl3_enc->server_finished_label_len);
512 if (ret <= 0) goto end;
513 s->state=SSL3_ST_SW_FLUSH;
514 if (s->hit)
515 s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
516 else
517 s->s3->tmp.next_state=SSL_ST_OK;
518 s->init_num=0;
519 break;
520
521 case SSL_ST_OK:
522 /* clean a few things up */
523 ssl3_cleanup_key_block(s);
524
525#if 0
526 BUF_MEM_free(s->init_buf);
527 s->init_buf=NULL;
528#endif
529
530 /* remove buffering on output */
531 ssl_free_wbio_buffer(s);
532
533 s->init_num=0;
534
535 if (s->new_session == 2) /* skipped if we just sent a HelloRequest */
536 {
537 /* actually not necessarily a 'new' session unless
538 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
539
540 s->new_session=0;
541
542 ssl_update_cache(s,SSL_SESS_CACHE_SERVER);
543
544 s->ctx->stats.sess_accept_good++;
545 /* s->server=1; */
546 s->handshake_func=dtls1_accept;
547
548 if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_DONE,1);
549 }
550
551 ret = 1;
552
553 /* done handshaking, next message is client hello */
554 s->d1->handshake_read_seq = 0;
555 /* next message is server hello */
556 s->d1->handshake_write_seq = 0;
557 goto end;
558 /* break; */
559
560 default:
561 SSLerr(SSL_F_DTLS1_ACCEPT,SSL_R_UNKNOWN_STATE);
562 ret= -1;
563 goto end;
564 /* break; */
565 }
566
567 if (!s->s3->tmp.reuse_message && !skip)
568 {
569 if (s->debug)
570 {
571 if ((ret=BIO_flush(s->wbio)) <= 0)
572 goto end;
573 }
574
575
576 if ((cb != NULL) && (s->state != state))
577 {
578 new_state=s->state;
579 s->state=state;
580 cb(s,SSL_CB_ACCEPT_LOOP,1);
581 s->state=new_state;
582 }
583 }
584 skip=0;
585 }
586end:
587 /* BIO_flush(s->wbio); */
588
589 s->in_handshake--;
590 if (cb != NULL)
591 cb(s,SSL_CB_ACCEPT_EXIT,ret);
592 return(ret);
593 }
594
595int dtls1_send_hello_request(SSL *s)
596 {
597 unsigned char *p;
598
599 if (s->state == SSL3_ST_SW_HELLO_REQ_A)
600 {
601 p=(unsigned char *)s->init_buf->data;
602 p = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0);
603
604 s->state=SSL3_ST_SW_HELLO_REQ_B;
605 /* number of bytes to write */
606 s->init_num=DTLS1_HM_HEADER_LENGTH;
607 s->init_off=0;
608
609 /* no need to buffer this message, since there are no retransmit
610 * requests for it */
611 }
612
613 /* SSL3_ST_SW_HELLO_REQ_B */
614 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
615 }
616
617int dtls1_send_hello_verify_request(SSL *s)
618 {
619 unsigned int msg_len;
620 unsigned char *msg, *buf, *p;
621
622 if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A)
623 {
624 buf = (unsigned char *)s->init_buf->data;
625
626 msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
627 if (s->client_version == DTLS1_BAD_VER)
628 *(p++) = DTLS1_BAD_VER>>8,
629 *(p++) = DTLS1_BAD_VER&0xff;
630 else
631 *(p++) = s->version >> 8,
632 *(p++) = s->version & 0xFF;
633
634 if (s->ctx->app_gen_cookie_cb != NULL &&
635 s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
636 &(s->d1->cookie_len)) == 0)
637 {
638 SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR);
639 return 0;
640 }
641 /* else the cookie is assumed to have
642 * been initialized by the application */
643
644 *(p++) = (unsigned char) s->d1->cookie_len;
645 memcpy(p, s->d1->cookie, s->d1->cookie_len);
646 p += s->d1->cookie_len;
647 msg_len = p - msg;
648
649 dtls1_set_message_header(s, buf,
650 DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, msg_len);
651
652 s->state=DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
653 /* number of bytes to write */
654 s->init_num=p-buf;
655 s->init_off=0;
656
657 /* buffer the message to handle re-xmits */
658 dtls1_buffer_message(s, 0);
659 }
660
661 /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
662 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
663 }
664
665int dtls1_send_server_hello(SSL *s)
666 {
667 unsigned char *buf;
668 unsigned char *p,*d;
669 int i;
670 unsigned int sl;
671 unsigned long l,Time;
672
673 if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
674 {
675 buf=(unsigned char *)s->init_buf->data;
676 p=s->s3->server_random;
677 Time=(unsigned long)time(NULL); /* Time */
678 l2n(Time,p);
679 RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time));
680 /* Do the message type and length last */
681 d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
682
683 if (s->client_version == DTLS1_BAD_VER)
684 *(p++)=DTLS1_BAD_VER>>8,
685 *(p++)=DTLS1_BAD_VER&0xff;
686 else
687 *(p++)=s->version>>8,
688 *(p++)=s->version&0xff;
689
690 /* Random stuff */
691 memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
692 p+=SSL3_RANDOM_SIZE;
693
694 /* now in theory we have 3 options to sending back the
695 * session id. If it is a re-use, we send back the
696 * old session-id, if it is a new session, we send
697 * back the new session-id or we send back a 0 length
698 * session-id if we want it to be single use.
699 * Currently I will not implement the '0' length session-id
700 * 12-Jan-98 - I'll now support the '0' length stuff.
701 */
702 if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER))
703 s->session->session_id_length=0;
704
705 sl=s->session->session_id_length;
706 if (sl > sizeof s->session->session_id)
707 {
708 SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
709 return -1;
710 }
711 *(p++)=sl;
712 memcpy(p,s->session->session_id,sl);
713 p+=sl;
714
715 /* put the cipher */
716 i=ssl3_put_cipher_by_char(s->s3->tmp.new_cipher,p);
717 p+=i;
718
719 /* put the compression method */
720#ifdef OPENSSL_NO_COMP
721 *(p++)=0;
722#else
723 if (s->s3->tmp.new_compression == NULL)
724 *(p++)=0;
725 else
726 *(p++)=s->s3->tmp.new_compression->id;
727#endif
728
729 /* do the header */
730 l=(p-d);
731 d=buf;
732
733 d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l);
734
735 s->state=SSL3_ST_CW_CLNT_HELLO_B;
736 /* number of bytes to write */
737 s->init_num=p-buf;
738 s->init_off=0;
739
740 /* buffer the message to handle re-xmits */
741 dtls1_buffer_message(s, 0);
742 }
743
744 /* SSL3_ST_CW_CLNT_HELLO_B */
745 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
746 }
747
748int dtls1_send_server_done(SSL *s)
749 {
750 unsigned char *p;
751
752 if (s->state == SSL3_ST_SW_SRVR_DONE_A)
753 {
754 p=(unsigned char *)s->init_buf->data;
755
756 /* do the header */
757 p = dtls1_set_message_header(s, p, SSL3_MT_SERVER_DONE, 0, 0, 0);
758
759 s->state=SSL3_ST_SW_SRVR_DONE_B;
760 /* number of bytes to write */
761 s->init_num=DTLS1_HM_HEADER_LENGTH;
762 s->init_off=0;
763
764 /* buffer the message to handle re-xmits */
765 dtls1_buffer_message(s, 0);
766 }
767
768 /* SSL3_ST_CW_CLNT_HELLO_B */
769 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
770 }
771
772int dtls1_send_server_key_exchange(SSL *s)
773 {
774#ifndef OPENSSL_NO_RSA
775 unsigned char *q;
776 int j,num;
777 RSA *rsa;
778 unsigned char md_buf[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
779 unsigned int u;
780#endif
781#ifndef OPENSSL_NO_DH
782 DH *dh=NULL,*dhp;
783#endif
784 EVP_PKEY *pkey;
785 unsigned char *p,*d;
786 int al,i;
787 unsigned long type;
788 int n;
789 CERT *cert;
790 BIGNUM *r[4];
791 int nr[4],kn;
792 BUF_MEM *buf;
793 EVP_MD_CTX md_ctx;
794
795 EVP_MD_CTX_init(&md_ctx);
796 if (s->state == SSL3_ST_SW_KEY_EXCH_A)
797 {
798 type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
799 cert=s->cert;
800
801 buf=s->init_buf;
802
803 r[0]=r[1]=r[2]=r[3]=NULL;
804 n=0;
805#ifndef OPENSSL_NO_RSA
806 if (type & SSL_kRSA)
807 {
808 rsa=cert->rsa_tmp;
809 if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL))
810 {
811 rsa=s->cert->rsa_tmp_cb(s,
812 SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
813 SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
814 if(rsa == NULL)
815 {
816 al=SSL_AD_HANDSHAKE_FAILURE;
817 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
818 goto f_err;
819 }
820 RSA_up_ref(rsa);
821 cert->rsa_tmp=rsa;
822 }
823 if (rsa == NULL)
824 {
825 al=SSL_AD_HANDSHAKE_FAILURE;
826 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_RSA_KEY);
827 goto f_err;
828 }
829 r[0]=rsa->n;
830 r[1]=rsa->e;
831 s->s3->tmp.use_rsa_tmp=1;
832 }
833 else
834#endif
835#ifndef OPENSSL_NO_DH
836 if (type & SSL_kEDH)
837 {
838 dhp=cert->dh_tmp;
839 if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
840 dhp=s->cert->dh_tmp_cb(s,
841 SSL_C_IS_EXPORT(s->s3->tmp.new_cipher),
842 SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher));
843 if (dhp == NULL)
844 {
845 al=SSL_AD_HANDSHAKE_FAILURE;
846 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_TMP_DH_KEY);
847 goto f_err;
848 }
849
850 if (s->s3->tmp.dh != NULL)
851 {
852 DH_free(dh);
853 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
854 goto err;
855 }
856
857 if ((dh=DHparams_dup(dhp)) == NULL)
858 {
859 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
860 goto err;
861 }
862
863 s->s3->tmp.dh=dh;
864 if ((dhp->pub_key == NULL ||
865 dhp->priv_key == NULL ||
866 (s->options & SSL_OP_SINGLE_DH_USE)))
867 {
868 if(!DH_generate_key(dh))
869 {
870 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
871 ERR_R_DH_LIB);
872 goto err;
873 }
874 }
875 else
876 {
877 dh->pub_key=BN_dup(dhp->pub_key);
878 dh->priv_key=BN_dup(dhp->priv_key);
879 if ((dh->pub_key == NULL) ||
880 (dh->priv_key == NULL))
881 {
882 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_DH_LIB);
883 goto err;
884 }
885 }
886 r[0]=dh->p;
887 r[1]=dh->g;
888 r[2]=dh->pub_key;
889 }
890 else
891#endif
892 {
893 al=SSL_AD_HANDSHAKE_FAILURE;
894 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
895 goto f_err;
896 }
897 for (i=0; r[i] != NULL; i++)
898 {
899 nr[i]=BN_num_bytes(r[i]);
900 n+=2+nr[i];
901 }
902
903 if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
904 {
905 if ((pkey=ssl_get_sign_pkey(s,s->s3->tmp.new_cipher))
906 == NULL)
907 {
908 al=SSL_AD_DECODE_ERROR;
909 goto f_err;
910 }
911 kn=EVP_PKEY_size(pkey);
912 }
913 else
914 {
915 pkey=NULL;
916 kn=0;
917 }
918
919 if (!BUF_MEM_grow_clean(buf,n+DTLS1_HM_HEADER_LENGTH+kn))
920 {
921 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
922 goto err;
923 }
924 d=(unsigned char *)s->init_buf->data;
925 p= &(d[DTLS1_HM_HEADER_LENGTH]);
926
927 for (i=0; r[i] != NULL; i++)
928 {
929 s2n(nr[i],p);
930 BN_bn2bin(r[i],p);
931 p+=nr[i];
932 }
933
934 /* not anonymous */
935 if (pkey != NULL)
936 {
937 /* n is the length of the params, they start at
938 * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space
939 * at the end. */
940#ifndef OPENSSL_NO_RSA
941 if (pkey->type == EVP_PKEY_RSA)
942 {
943 q=md_buf;
944 j=0;
945 for (num=2; num > 0; num--)
946 {
947 EVP_DigestInit_ex(&md_ctx,(num == 2)
948 ?s->ctx->md5:s->ctx->sha1, NULL);
949 EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
950 EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
951 EVP_DigestUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
952 EVP_DigestFinal_ex(&md_ctx,q,
953 (unsigned int *)&i);
954 q+=i;
955 j+=i;
956 }
957 if (RSA_sign(NID_md5_sha1, md_buf, j,
958 &(p[2]), &u, pkey->pkey.rsa) <= 0)
959 {
960 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_RSA);
961 goto err;
962 }
963 s2n(u,p);
964 n+=u+2;
965 }
966 else
967#endif
968#if !defined(OPENSSL_NO_DSA)
969 if (pkey->type == EVP_PKEY_DSA)
970 {
971 /* lets do DSS */
972 EVP_SignInit_ex(&md_ctx,EVP_dss1(), NULL);
973 EVP_SignUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
974 EVP_SignUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
975 EVP_SignUpdate(&md_ctx,&(d[DTLS1_HM_HEADER_LENGTH]),n);
976 if (!EVP_SignFinal(&md_ctx,&(p[2]),
977 (unsigned int *)&i,pkey))
978 {
979 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_DSA);
980 goto err;
981 }
982 s2n(i,p);
983 n+=i+2;
984 }
985 else
986#endif
987 {
988 /* Is this error check actually needed? */
989 al=SSL_AD_HANDSHAKE_FAILURE;
990 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_PKEY_TYPE);
991 goto f_err;
992 }
993 }
994
995 d = dtls1_set_message_header(s, d,
996 SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n);
997
998 /* we should now have things packed up, so lets send
999 * it off */
1000 s->init_num=n+DTLS1_HM_HEADER_LENGTH;
1001 s->init_off=0;
1002
1003 /* buffer the message to handle re-xmits */
1004 dtls1_buffer_message(s, 0);
1005 }
1006
1007 s->state = SSL3_ST_SW_KEY_EXCH_B;
1008 EVP_MD_CTX_cleanup(&md_ctx);
1009 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1010f_err:
1011 ssl3_send_alert(s,SSL3_AL_FATAL,al);
1012err:
1013 EVP_MD_CTX_cleanup(&md_ctx);
1014 return(-1);
1015 }
1016
1017int dtls1_send_certificate_request(SSL *s)
1018 {
1019 unsigned char *p,*d;
1020 int i,j,nl,off,n;
1021 STACK_OF(X509_NAME) *sk=NULL;
1022 X509_NAME *name;
1023 BUF_MEM *buf;
1024 unsigned int msg_len;
1025
1026 if (s->state == SSL3_ST_SW_CERT_REQ_A)
1027 {
1028 buf=s->init_buf;
1029
1030 d=p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
1031
1032 /* get the list of acceptable cert types */
1033 p++;
1034 n=ssl3_get_req_cert_type(s,p);
1035 d[0]=n;
1036 p+=n;
1037 n++;
1038
1039 off=n;
1040 p+=2;
1041 n+=2;
1042
1043 sk=SSL_get_client_CA_list(s);
1044 nl=0;
1045 if (sk != NULL)
1046 {
1047 for (i=0; i<sk_X509_NAME_num(sk); i++)
1048 {
1049 name=sk_X509_NAME_value(sk,i);
1050 j=i2d_X509_NAME(name,NULL);
1051 if (!BUF_MEM_grow_clean(buf,DTLS1_HM_HEADER_LENGTH+n+j+2))
1052 {
1053 SSLerr(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
1054 goto err;
1055 }
1056 p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+n]);
1057 if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
1058 {
1059 s2n(j,p);
1060 i2d_X509_NAME(name,&p);
1061 n+=2+j;
1062 nl+=2+j;
1063 }
1064 else
1065 {
1066 d=p;
1067 i2d_X509_NAME(name,&p);
1068 j-=2; s2n(j,d); j+=2;
1069 n+=j;
1070 nl+=j;
1071 }
1072 }
1073 }
1074 /* else no CA names */
1075 p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH+off]);
1076 s2n(nl,p);
1077
1078 d=(unsigned char *)buf->data;
1079 *(d++)=SSL3_MT_CERTIFICATE_REQUEST;
1080 l2n3(n,d);
1081 s2n(s->d1->handshake_write_seq,d);
1082 s->d1->handshake_write_seq++;
1083
1084 /* we should now have things packed up, so lets send
1085 * it off */
1086
1087 s->init_num=n+DTLS1_HM_HEADER_LENGTH;
1088 s->init_off=0;
1089#ifdef NETSCAPE_HANG_BUG
1090/* XXX: what to do about this? */
1091 p=(unsigned char *)s->init_buf->data + s->init_num;
1092
1093 /* do the header */
1094 *(p++)=SSL3_MT_SERVER_DONE;
1095 *(p++)=0;
1096 *(p++)=0;
1097 *(p++)=0;
1098 s->init_num += 4;
1099#endif
1100
1101 /* XDTLS: set message header ? */
1102 msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
1103 dtls1_set_message_header(s, (void *)s->init_buf->data,
1104 SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0, msg_len);
1105
1106 /* buffer the message to handle re-xmits */
1107 dtls1_buffer_message(s, 0);
1108
1109 s->state = SSL3_ST_SW_CERT_REQ_B;
1110 }
1111
1112 /* SSL3_ST_SW_CERT_REQ_B */
1113 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1114err:
1115 return(-1);
1116 }
1117
1118int dtls1_send_server_certificate(SSL *s)
1119 {
1120 unsigned long l;
1121 X509 *x;
1122
1123 if (s->state == SSL3_ST_SW_CERT_A)
1124 {
1125 x=ssl_get_server_send_cert(s);
1126 if (x == NULL &&
1127 /* VRS: allow null cert if auth == KRB5 */
1128 (s->s3->tmp.new_cipher->algorithms
1129 & (SSL_MKEY_MASK|SSL_AUTH_MASK))
1130 != (SSL_aKRB5|SSL_kKRB5))
1131 {
1132 SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
1133 return(0);
1134 }
1135
1136 l=dtls1_output_cert_chain(s,x);
1137 s->state=SSL3_ST_SW_CERT_B;
1138 s->init_num=(int)l;
1139 s->init_off=0;
1140
1141 /* buffer the message to handle re-xmits */
1142 dtls1_buffer_message(s, 0);
1143 }
1144
1145 /* SSL3_ST_SW_CERT_B */
1146 return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
1147 }
diff --git a/src/lib/libssl/dtls1.h b/src/lib/libssl/dtls1.h
new file mode 100644
index 0000000000..a663cf85f2
--- /dev/null
+++ b/src/lib/libssl/dtls1.h
@@ -0,0 +1,211 @@
1/* ssl/dtls1.h */
2/*
3 * DTLS implementation written by Nagendra Modadugu
4 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
5 */
6/* ====================================================================
7 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 * software must display the following acknowledgment:
23 * "This product includes software developed by the OpenSSL Project
24 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 * endorse or promote products derived from this software without
28 * prior written permission. For written permission, please contact
29 * openssl-core@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 * nor may "OpenSSL" appear in their names without prior written
33 * permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 * acknowledgment:
37 * "This product includes software developed by the OpenSSL Project
38 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This product includes cryptographic software written by Eric Young
55 * (eay@cryptsoft.com). This product includes software written by Tim
56 * Hudson (tjh@cryptsoft.com).
57 *
58 */
59
60#ifndef HEADER_DTLS1_H
61#define HEADER_DTLS1_H
62
63#include <openssl/buffer.h>
64#include <openssl/pqueue.h>
65
66#ifdef __cplusplus
67extern "C" {
68#endif
69
70#define DTLS1_VERSION 0xFEFF
71#define DTLS1_BAD_VER 0x0100
72
73#define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110
74
75/* lengths of messages */
76#define DTLS1_COOKIE_LENGTH 32
77
78#define DTLS1_RT_HEADER_LENGTH 13
79
80#define DTLS1_HM_HEADER_LENGTH 12
81
82#define DTLS1_HM_BAD_FRAGMENT -2
83#define DTLS1_HM_FRAGMENT_RETRY -3
84
85#define DTLS1_CCS_HEADER_LENGTH 1
86
87#define DTLS1_AL_HEADER_LENGTH 7
88
89
90typedef struct dtls1_bitmap_st
91 {
92 PQ_64BIT map;
93 unsigned long length; /* sizeof the bitmap in bits */
94 PQ_64BIT max_seq_num; /* max record number seen so far */
95 } DTLS1_BITMAP;
96
97struct hm_header_st
98 {
99 unsigned char type;
100 unsigned long msg_len;
101 unsigned short seq;
102 unsigned long frag_off;
103 unsigned long frag_len;
104 unsigned int is_ccs;
105 };
106
107struct ccs_header_st
108 {
109 unsigned char type;
110 unsigned short seq;
111 };
112
113struct dtls1_timeout_st
114 {
115 /* Number of read timeouts so far */
116 unsigned int read_timeouts;
117
118 /* Number of write timeouts so far */
119 unsigned int write_timeouts;
120
121 /* Number of alerts received so far */
122 unsigned int num_alerts;
123 };
124
125typedef struct record_pqueue_st
126 {
127 unsigned short epoch;
128 pqueue q;
129 } record_pqueue;
130
131typedef struct hm_fragment_st
132 {
133 struct hm_header_st msg_header;
134 unsigned char *fragment;
135 } hm_fragment;
136
137typedef struct dtls1_state_st
138 {
139 unsigned int send_cookie;
140 unsigned char cookie[DTLS1_COOKIE_LENGTH];
141 unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
142 unsigned int cookie_len;
143
144 /*
145 * The current data and handshake epoch. This is initially
146 * undefined, and starts at zero once the initial handshake is
147 * completed
148 */
149 unsigned short r_epoch;
150 unsigned short w_epoch;
151
152 /* records being received in the current epoch */
153 DTLS1_BITMAP bitmap;
154
155 /* renegotiation starts a new set of sequence numbers */
156 DTLS1_BITMAP next_bitmap;
157
158 /* handshake message numbers */
159 unsigned short handshake_write_seq;
160 unsigned short next_handshake_write_seq;
161
162 unsigned short handshake_read_seq;
163
164 /* Received handshake records (processed and unprocessed) */
165 record_pqueue unprocessed_rcds;
166 record_pqueue processed_rcds;
167
168 /* Buffered handshake messages */
169 pqueue buffered_messages;
170
171 /* Buffered (sent) handshake records */
172 pqueue sent_messages;
173
174 unsigned int mtu; /* max wire packet size */
175
176 struct hm_header_st w_msg_hdr;
177 struct hm_header_st r_msg_hdr;
178
179 struct dtls1_timeout_st timeout;
180
181 /* storage for Alert/Handshake protocol data received but not
182 * yet processed by ssl3_read_bytes: */
183 unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
184 unsigned int alert_fragment_len;
185 unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
186 unsigned int handshake_fragment_len;
187
188 unsigned int retransmitting;
189
190 } DTLS1_STATE;
191
192typedef struct dtls1_record_data_st
193 {
194 unsigned char *packet;
195 unsigned int packet_length;
196 SSL3_BUFFER rbuf;
197 SSL3_RECORD rrec;
198 } DTLS1_RECORD_DATA;
199
200
201/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
202#define DTLS1_TMO_READ_COUNT 2
203#define DTLS1_TMO_WRITE_COUNT 2
204
205#define DTLS1_TMO_ALERT_COUNT 12
206
207#ifdef __cplusplus
208}
209#endif
210#endif
211
diff --git a/src/lib/libssl/test/CAss.cnf b/src/lib/libssl/test/CAss.cnf
index 21da59a73a..20f8f05e3d 100644
--- a/src/lib/libssl/test/CAss.cnf
+++ b/src/lib/libssl/test/CAss.cnf
@@ -24,10 +24,53 @@ organizationName_value = Dodgy Brothers
24commonName = Common Name (eg, YOUR name) 24commonName = Common Name (eg, YOUR name)
25commonName_value = Dodgy CA 25commonName_value = Dodgy CA
26 26
27####################################################################
28[ ca ]
29default_ca = CA_default # The default ca section
30
31####################################################################
32[ CA_default ]
33
34dir = ./demoCA # Where everything is kept
35certs = $dir/certs # Where the issued certs are kept
36crl_dir = $dir/crl # Where the issued crl are kept
37database = $dir/index.txt # database index file.
38#unique_subject = no # Set to 'no' to allow creation of
39 # several ctificates with same subject.
40new_certs_dir = $dir/newcerts # default place for new certs.
41
42certificate = $dir/cacert.pem # The CA certificate
43serial = $dir/serial # The current serial number
44crl = $dir/crl.pem # The current CRL
45private_key = $dir/private/cakey.pem# The private key
46RANDFILE = $dir/private/.rand # private random number file
47
48x509_extensions = v3_ca # The extentions to add to the cert
49
50name_opt = ca_default # Subject Name options
51cert_opt = ca_default # Certificate field options
52
53default_days = 365 # how long to certify for
54default_crl_days= 30 # how long before next CRL
55default_md = md5 # which md to use.
56preserve = no # keep passed DN ordering
57
58policy = policy_anything
59
60[ policy_anything ]
61countryName = optional
62stateOrProvinceName = optional
63localityName = optional
64organizationName = optional
65organizationalUnitName = optional
66commonName = supplied
67emailAddress = optional
68
69
70
27[ v3_ca ] 71[ v3_ca ]
28subjectKeyIdentifier=hash 72subjectKeyIdentifier=hash
29authorityKeyIdentifier=keyid:always,issuer:always 73authorityKeyIdentifier=keyid:always,issuer:always
30basicConstraints = CA:true,pathlen:1 74basicConstraints = CA:true,pathlen:1
31keyUsage = cRLSign, keyCertSign 75keyUsage = cRLSign, keyCertSign
32issuerAltName=issuer:copy 76issuerAltName=issuer:copy
33
diff --git a/src/lib/libssl/test/cms-examples.pl b/src/lib/libssl/test/cms-examples.pl
new file mode 100644
index 0000000000..2e95b48ba4
--- /dev/null
+++ b/src/lib/libssl/test/cms-examples.pl
@@ -0,0 +1,409 @@
1# test/cms-examples.pl
2# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3# project.
4#
5# ====================================================================
6# Copyright (c) 2008 The OpenSSL Project. All rights reserved.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11#
12# 1. Redistributions of source code must retain the above copyright
13# notice, this list of conditions and the following disclaimer.
14#
15# 2. Redistributions in binary form must reproduce the above copyright
16# notice, this list of conditions and the following disclaimer in
17# the documentation and/or other materials provided with the
18# distribution.
19#
20# 3. All advertising materials mentioning features or use of this
21# software must display the following acknowledgment:
22# "This product includes software developed by the OpenSSL Project
23# for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24#
25# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26# endorse or promote products derived from this software without
27# prior written permission. For written permission, please contact
28# licensing@OpenSSL.org.
29#
30# 5. Products derived from this software may not be called "OpenSSL"
31# nor may "OpenSSL" appear in their names without prior written
32# permission of the OpenSSL Project.
33#
34# 6. Redistributions of any form whatsoever must retain the following
35# acknowledgment:
36# "This product includes software developed by the OpenSSL Project
37# for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38#
39# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50# OF THE POSSIBILITY OF SUCH DAMAGE.
51# ====================================================================
52
53# Perl script to run tests against S/MIME examples in RFC4134
54# Assumes RFC is in current directory and called "rfc4134.txt"
55
56use MIME::Base64;
57
58my $badttest = 0;
59my $verbose = 1;
60
61my $cmscmd;
62my $exdir = "./";
63my $exfile = "./rfc4134.txt";
64
65if (-f "../apps/openssl")
66 {
67 $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
68 }
69elsif (-f "..\\out32dll\\openssl.exe")
70 {
71 $cmscmd = "..\\out32dll\\openssl.exe cms";
72 }
73elsif (-f "..\\out32\\openssl.exe")
74 {
75 $cmscmd = "..\\out32\\openssl.exe cms";
76 }
77
78my @test_list = (
79 [ "3.1.bin" => "dataout" ],
80 [ "3.2.bin" => "encode, dataout" ],
81 [ "4.1.bin" => "encode, verifyder, cont, dss" ],
82 [ "4.2.bin" => "encode, verifyder, cont, rsa" ],
83 [ "4.3.bin" => "encode, verifyder, cont_extern, dss" ],
84 [ "4.4.bin" => "encode, verifyder, cont, dss" ],
85 [ "4.5.bin" => "verifyder, cont, rsa" ],
86 [ "4.6.bin" => "encode, verifyder, cont, dss" ],
87 [ "4.7.bin" => "encode, verifyder, cont, dss" ],
88 [ "4.8.eml" => "verifymime, dss" ],
89 [ "4.9.eml" => "verifymime, dss" ],
90 [ "4.10.bin" => "encode, verifyder, cont, dss" ],
91 [ "4.11.bin" => "encode, certsout" ],
92 [ "5.1.bin" => "encode, envelopeder, cont" ],
93 [ "5.2.bin" => "encode, envelopeder, cont" ],
94 [ "5.3.eml" => "envelopemime, cont" ],
95 [ "6.0.bin" => "encode, digest, cont" ],
96 [ "7.1.bin" => "encode, encrypted, cont" ],
97 [ "7.2.bin" => "encode, encrypted, cont" ]
98);
99
100# Extract examples from RFC4134 text.
101# Base64 decode all examples, certificates and
102# private keys are converted to PEM format.
103
104my ( $filename, $data );
105
106my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
107
108$data = "";
109
110open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
111
112while (<IN>) {
113 next unless (/^\|/);
114 s/^\|//;
115 next if (/^\*/);
116 if (/^>(.*)$/) {
117 $filename = $1;
118 next;
119 }
120 if (/^</) {
121 $filename = "$exdir/$filename";
122 if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) {
123 $data = decode_base64($data);
124 open OUT, ">$filename";
125 binmode OUT;
126 print OUT $data;
127 close OUT;
128 push @cleanup, $filename;
129 }
130 elsif ( $filename =~ /\.cer$/ ) {
131 write_pem( $filename, "CERTIFICATE", $data );
132 }
133 elsif ( $filename =~ /\.pri$/ ) {
134 write_pem( $filename, "PRIVATE KEY", $data );
135 }
136 $data = "";
137 $filename = "";
138 }
139 else {
140 $data .= $_;
141 }
142
143}
144
145my $secretkey =
146 "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
147
148foreach (@test_list) {
149 my ( $file, $tlist ) = @$_;
150 print "Example file $file:\n";
151 if ( $tlist =~ /encode/ ) {
152 run_reencode_test( $exdir, $file );
153 }
154 if ( $tlist =~ /certsout/ ) {
155 run_certsout_test( $exdir, $file );
156 }
157 if ( $tlist =~ /dataout/ ) {
158 run_dataout_test( $exdir, $file );
159 }
160 if ( $tlist =~ /verify/ ) {
161 run_verify_test( $exdir, $tlist, $file );
162 }
163 if ( $tlist =~ /digest/ ) {
164 run_digest_test( $exdir, $tlist, $file );
165 }
166 if ( $tlist =~ /encrypted/ ) {
167 run_encrypted_test( $exdir, $tlist, $file, $secretkey );
168 }
169 if ( $tlist =~ /envelope/ ) {
170 run_envelope_test( $exdir, $tlist, $file );
171 }
172
173}
174
175foreach (@cleanup) {
176 unlink $_;
177}
178
179if ($badtest) {
180 print "\n$badtest TESTS FAILED!!\n";
181}
182else {
183 print "\n***All tests successful***\n";
184}
185
186sub write_pem {
187 my ( $filename, $str, $data ) = @_;
188
189 $filename =~ s/\.[^.]*$/.pem/;
190
191 push @cleanup, $filename;
192
193 open OUT, ">$filename";
194
195 print OUT "-----BEGIN $str-----\n";
196 print OUT $data;
197 print OUT "-----END $str-----\n";
198
199 close OUT;
200}
201
202sub run_reencode_test {
203 my ( $cmsdir, $tfile ) = @_;
204 unlink "tmp.der";
205
206 system( "$cmscmd -cmsout -inform DER -outform DER"
207 . " -in $cmsdir/$tfile -out tmp.der" );
208
209 if ($?) {
210 print "\tReencode command FAILED!!\n";
211 $badtest++;
212 }
213 elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) {
214 print "\tReencode FAILED!!\n";
215 $badtest++;
216 }
217 else {
218 print "\tReencode passed\n" if $verbose;
219 }
220}
221
222sub run_certsout_test {
223 my ( $cmsdir, $tfile ) = @_;
224 unlink "tmp.der";
225 unlink "tmp.pem";
226
227 system( "$cmscmd -cmsout -inform DER -certsout tmp.pem"
228 . " -in $cmsdir/$tfile -out tmp.der" );
229
230 if ($?) {
231 print "\tCertificate output command FAILED!!\n";
232 $badtest++;
233 }
234 else {
235 print "\tCertificate output passed\n" if $verbose;
236 }
237}
238
239sub run_dataout_test {
240 my ( $cmsdir, $tfile ) = @_;
241 unlink "tmp.txt";
242
243 system(
244 "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" );
245
246 if ($?) {
247 print "\tDataout command FAILED!!\n";
248 $badtest++;
249 }
250 elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) {
251 print "\tDataout compare FAILED!!\n";
252 $badtest++;
253 }
254 else {
255 print "\tDataout passed\n" if $verbose;
256 }
257}
258
259sub run_verify_test {
260 my ( $cmsdir, $tlist, $tfile ) = @_;
261 unlink "tmp.txt";
262
263 $form = "DER" if $tlist =~ /verifyder/;
264 $form = "SMIME" if $tlist =~ /verifymime/;
265 $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/;
266 $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/;
267
268 $cmd =
269 "$cmscmd -verify -inform $form"
270 . " -CAfile $cafile"
271 . " -in $cmsdir/$tfile -out tmp.txt";
272
273 $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/;
274
275 system("$cmd 2>cms.err 1>cms.out");
276
277 if ($?) {
278 print "\tVerify command FAILED!!\n";
279 $badtest++;
280 }
281 elsif ( $tlist =~ /cont/
282 && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
283 {
284 print "\tVerify content compare FAILED!!\n";
285 $badtest++;
286 }
287 else {
288 print "\tVerify passed\n" if $verbose;
289 }
290}
291
292sub run_envelope_test {
293 my ( $cmsdir, $tlist, $tfile ) = @_;
294 unlink "tmp.txt";
295
296 $form = "DER" if $tlist =~ /envelopeder/;
297 $form = "SMIME" if $tlist =~ /envelopemime/;
298
299 $cmd =
300 "$cmscmd -decrypt -inform $form"
301 . " -recip $cmsdir/BobRSASignByCarl.pem"
302 . " -inkey $cmsdir/BobPrivRSAEncrypt.pem"
303 . " -in $cmsdir/$tfile -out tmp.txt";
304
305 system("$cmd 2>cms.err 1>cms.out");
306
307 if ($?) {
308 print "\tDecrypt command FAILED!!\n";
309 $badtest++;
310 }
311 elsif ( $tlist =~ /cont/
312 && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
313 {
314 print "\tDecrypt content compare FAILED!!\n";
315 $badtest++;
316 }
317 else {
318 print "\tDecrypt passed\n" if $verbose;
319 }
320}
321
322sub run_digest_test {
323 my ( $cmsdir, $tlist, $tfile ) = @_;
324 unlink "tmp.txt";
325
326 my $cmd =
327 "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt";
328
329 system("$cmd 2>cms.err 1>cms.out");
330
331 if ($?) {
332 print "\tDigest verify command FAILED!!\n";
333 $badtest++;
334 }
335 elsif ( $tlist =~ /cont/
336 && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
337 {
338 print "\tDigest verify content compare FAILED!!\n";
339 $badtest++;
340 }
341 else {
342 print "\tDigest verify passed\n" if $verbose;
343 }
344}
345
346sub run_encrypted_test {
347 my ( $cmsdir, $tlist, $tfile, $key ) = @_;
348 unlink "tmp.txt";
349
350 system( "$cmscmd -EncryptedData_decrypt -inform DER"
351 . " -secretkey $key"
352 . " -in $cmsdir/$tfile -out tmp.txt" );
353
354 if ($?) {
355 print "\tEncrypted Data command FAILED!!\n";
356 $badtest++;
357 }
358 elsif ( $tlist =~ /cont/
359 && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
360 {
361 print "\tEncrypted Data content compare FAILED!!\n";
362 $badtest++;
363 }
364 else {
365 print "\tEncryptedData verify passed\n" if $verbose;
366 }
367}
368
369sub cmp_files {
370 my ( $f1, $f2 ) = @_;
371 my ( $fp1, $fp2 );
372
373 my ( $rd1, $rd2 );
374
375 if ( !open( $fp1, "<$f1" ) ) {
376 print STDERR "Can't Open file $f1\n";
377 return 0;
378 }
379
380 if ( !open( $fp2, "<$f2" ) ) {
381 print STDERR "Can't Open file $f2\n";
382 return 0;
383 }
384
385 binmode $fp1;
386 binmode $fp2;
387
388 my $ret = 0;
389
390 for ( ; ; ) {
391 $n1 = sysread $fp1, $rd1, 4096;
392 $n2 = sysread $fp2, $rd2, 4096;
393 last if ( $n1 != $n2 );
394 last if ( $rd1 ne $rd2 );
395
396 if ( $n1 == 0 ) {
397 $ret = 1;
398 last;
399 }
400
401 }
402
403 close $fp1;
404 close $fp2;
405
406 return $ret;
407
408}
409
diff --git a/src/lib/libssl/test/cms-test.pl b/src/lib/libssl/test/cms-test.pl
new file mode 100644
index 0000000000..a84e089ddc
--- /dev/null
+++ b/src/lib/libssl/test/cms-test.pl
@@ -0,0 +1,453 @@
1# test/cms-test.pl
2# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3# project.
4#
5# ====================================================================
6# Copyright (c) 2008 The OpenSSL Project. All rights reserved.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11#
12# 1. Redistributions of source code must retain the above copyright
13# notice, this list of conditions and the following disclaimer.
14#
15# 2. Redistributions in binary form must reproduce the above copyright
16# notice, this list of conditions and the following disclaimer in
17# the documentation and/or other materials provided with the
18# distribution.
19#
20# 3. All advertising materials mentioning features or use of this
21# software must display the following acknowledgment:
22# "This product includes software developed by the OpenSSL Project
23# for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24#
25# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26# endorse or promote products derived from this software without
27# prior written permission. For written permission, please contact
28# licensing@OpenSSL.org.
29#
30# 5. Products derived from this software may not be called "OpenSSL"
31# nor may "OpenSSL" appear in their names without prior written
32# permission of the OpenSSL Project.
33#
34# 6. Redistributions of any form whatsoever must retain the following
35# acknowledgment:
36# "This product includes software developed by the OpenSSL Project
37# for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38#
39# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50# OF THE POSSIBILITY OF SUCH DAMAGE.
51# ====================================================================
52
53# CMS, PKCS7 consistency test script. Run extensive tests on
54# OpenSSL PKCS#7 and CMS implementations.
55
56my $ossl_path;
57
58if ( -f "../apps/openssl" ) {
59 $ossl_path = "../util/shlib_wrap.sh ../apps/openssl";
60}
61elsif ( -f "..\\out32dll\\openssl.exe" ) {
62 $ossl_path = "..\\out32dll\\openssl.exe";
63}
64elsif ( -f "..\\out32\\openssl.exe" ) {
65 $ossl_path = "..\\out32\\openssl.exe";
66}
67else {
68 die "Can't find OpenSSL executable";
69}
70
71my $pk7cmd = "$ossl_path smime ";
72my $cmscmd = "$ossl_path cms ";
73my $smdir = "smime-certs";
74my $halt_err = 1;
75
76my $badcmd = 0;
77my $ossl8 = `$ossl_path version -v` =~ /0\.9\.8/;
78
79my @smime_pkcs7_tests = (
80
81 [
82 "signed content DER format, RSA key",
83 "-sign -in smcont.txt -outform DER -nodetach"
84 . " -certfile $smdir/smroot.pem"
85 . " -signer $smdir/smrsa1.pem -out test.cms",
86 "-verify -in test.cms -inform DER "
87 . " -CAfile $smdir/smroot.pem -out smtst.txt"
88 ],
89
90 [
91 "signed detached content DER format, RSA key",
92 "-sign -in smcont.txt -outform DER"
93 . " -signer $smdir/smrsa1.pem -out test.cms",
94 "-verify -in test.cms -inform DER "
95 . " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt"
96 ],
97
98 [
99 "signed content test streaming BER format, RSA",
100 "-sign -in smcont.txt -outform DER -nodetach"
101 . " -stream -signer $smdir/smrsa1.pem -out test.cms",
102 "-verify -in test.cms -inform DER "
103 . " -CAfile $smdir/smroot.pem -out smtst.txt"
104 ],
105
106 [
107 "signed content DER format, DSA key",
108 "-sign -in smcont.txt -outform DER -nodetach"
109 . " -signer $smdir/smdsa1.pem -out test.cms",
110 "-verify -in test.cms -inform DER "
111 . " -CAfile $smdir/smroot.pem -out smtst.txt"
112 ],
113
114 [
115 "signed detached content DER format, DSA key",
116 "-sign -in smcont.txt -outform DER"
117 . " -signer $smdir/smdsa1.pem -out test.cms",
118 "-verify -in test.cms -inform DER "
119 . " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt"
120 ],
121
122 [
123 "signed detached content DER format, add RSA signer",
124 "-resign -inform DER -in test.cms -outform DER"
125 . " -signer $smdir/smrsa1.pem -out test2.cms",
126 "-verify -in test2.cms -inform DER "
127 . " -CAfile $smdir/smroot.pem -out smtst.txt -content smcont.txt"
128 ],
129
130 [
131 "signed content test streaming BER format, DSA key",
132 "-sign -in smcont.txt -outform DER -nodetach"
133 . " -stream -signer $smdir/smdsa1.pem -out test.cms",
134 "-verify -in test.cms -inform DER "
135 . " -CAfile $smdir/smroot.pem -out smtst.txt"
136 ],
137
138 [
139 "signed content test streaming BER format, 2 DSA and 2 RSA keys",
140 "-sign -in smcont.txt -outform DER -nodetach"
141 . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
142 . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
143 . " -stream -out test.cms",
144 "-verify -in test.cms -inform DER "
145 . " -CAfile $smdir/smroot.pem -out smtst.txt"
146 ],
147
148 [
149"signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
150 "-sign -in smcont.txt -outform DER -noattr -nodetach"
151 . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
152 . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
153 . " -stream -out test.cms",
154 "-verify -in test.cms -inform DER "
155 . " -CAfile $smdir/smroot.pem -out smtst.txt"
156 ],
157
158 [
159 "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
160 "-sign -in smcont.txt -nodetach"
161 . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
162 . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
163 . " -stream -out test.cms",
164 "-verify -in test.cms " . " -CAfile $smdir/smroot.pem -out smtst.txt"
165 ],
166
167 [
168"signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
169 "-sign -in smcont.txt"
170 . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
171 . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
172 . " -stream -out test.cms",
173 "-verify -in test.cms " . " -CAfile $smdir/smroot.pem -out smtst.txt"
174 ],
175
176 [
177 "enveloped content test streaming S/MIME format, 3 recipients",
178 "-encrypt -in smcont.txt"
179 . " -stream -out test.cms"
180 . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
181 "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
182 ],
183
184 [
185"enveloped content test streaming S/MIME format, 3 recipients, 3rd used",
186 "-encrypt -in smcont.txt"
187 . " -stream -out test.cms"
188 . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
189 "-decrypt -recip $smdir/smrsa3.pem -in test.cms -out smtst.txt"
190 ],
191
192 [
193"enveloped content test streaming S/MIME format, 3 recipients, key only used",
194 "-encrypt -in smcont.txt"
195 . " -stream -out test.cms"
196 . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
197 "-decrypt -inkey $smdir/smrsa3.pem -in test.cms -out smtst.txt"
198 ],
199
200 [
201"enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
202 "-encrypt -in smcont.txt"
203 . " -aes256 -stream -out test.cms"
204 . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
205 "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
206 ],
207
208);
209
210my @smime_cms_tests = (
211
212 [
213 "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
214 "-sign -in smcont.txt -outform DER -nodetach -keyid"
215 . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
216 . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
217 . " -stream -out test.cms",
218 "-verify -in test.cms -inform DER "
219 . " -CAfile $smdir/smroot.pem -out smtst.txt"
220 ],
221
222 [
223 "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
224 "-sign -in smcont.txt -outform PEM -nodetach"
225 . " -signer $smdir/smrsa1.pem -signer $smdir/smrsa2.pem"
226 . " -signer $smdir/smdsa1.pem -signer $smdir/smdsa2.pem"
227 . " -stream -out test.cms",
228 "-verify -in test.cms -inform PEM "
229 . " -CAfile $smdir/smroot.pem -out smtst.txt"
230 ],
231
232 [
233 "signed content MIME format, RSA key, signed receipt request",
234 "-sign -in smcont.txt -signer $smdir/smrsa1.pem -nodetach"
235 . " -receipt_request_to test@openssl.org -receipt_request_all"
236 . " -out test.cms",
237 "-verify -in test.cms "
238 . " -CAfile $smdir/smroot.pem -out smtst.txt"
239 ],
240
241 [
242 "signed receipt MIME format, RSA key",
243 "-sign_receipt -in test.cms"
244 . " -signer $smdir/smrsa2.pem"
245 . " -out test2.cms",
246 "-verify_receipt test2.cms -in test.cms"
247 . " -CAfile $smdir/smroot.pem"
248 ],
249
250 [
251 "enveloped content test streaming S/MIME format, 3 recipients, keyid",
252 "-encrypt -in smcont.txt"
253 . " -stream -out test.cms -keyid"
254 . " $smdir/smrsa1.pem $smdir/smrsa2.pem $smdir/smrsa3.pem ",
255 "-decrypt -recip $smdir/smrsa1.pem -in test.cms -out smtst.txt"
256 ],
257
258 [
259 "enveloped content test streaming PEM format, KEK",
260 "-encrypt -in smcont.txt -outform PEM -aes128"
261 . " -stream -out test.cms "
262 . " -secretkey 000102030405060708090A0B0C0D0E0F "
263 . " -secretkeyid C0FEE0",
264 "-decrypt -in test.cms -out smtst.txt -inform PEM"
265 . " -secretkey 000102030405060708090A0B0C0D0E0F "
266 . " -secretkeyid C0FEE0"
267 ],
268
269 [
270 "enveloped content test streaming PEM format, KEK, key only",
271 "-encrypt -in smcont.txt -outform PEM -aes128"
272 . " -stream -out test.cms "
273 . " -secretkey 000102030405060708090A0B0C0D0E0F "
274 . " -secretkeyid C0FEE0",
275 "-decrypt -in test.cms -out smtst.txt -inform PEM"
276 . " -secretkey 000102030405060708090A0B0C0D0E0F "
277 ],
278
279 [
280 "data content test streaming PEM format",
281 "-data_create -in smcont.txt -outform PEM -nodetach"
282 . " -stream -out test.cms",
283 "-data_out -in test.cms -inform PEM -out smtst.txt"
284 ],
285
286 [
287 "encrypted content test streaming PEM format, 128 bit RC2 key",
288 "-EncryptedData_encrypt -in smcont.txt -outform PEM"
289 . " -rc2 -secretkey 000102030405060708090A0B0C0D0E0F"
290 . " -stream -out test.cms",
291 "-EncryptedData_decrypt -in test.cms -inform PEM "
292 . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
293 ],
294
295 [
296 "encrypted content test streaming PEM format, 40 bit RC2 key",
297 "-EncryptedData_encrypt -in smcont.txt -outform PEM"
298 . " -rc2 -secretkey 0001020304"
299 . " -stream -out test.cms",
300 "-EncryptedData_decrypt -in test.cms -inform PEM "
301 . " -secretkey 0001020304 -out smtst.txt"
302 ],
303
304 [
305 "encrypted content test streaming PEM format, triple DES key",
306 "-EncryptedData_encrypt -in smcont.txt -outform PEM"
307 . " -des3 -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
308 . " -stream -out test.cms",
309 "-EncryptedData_decrypt -in test.cms -inform PEM "
310 . " -secretkey 000102030405060708090A0B0C0D0E0F1011121314151617"
311 . " -out smtst.txt"
312 ],
313
314 [
315 "encrypted content test streaming PEM format, 128 bit AES key",
316 "-EncryptedData_encrypt -in smcont.txt -outform PEM"
317 . " -aes128 -secretkey 000102030405060708090A0B0C0D0E0F"
318 . " -stream -out test.cms",
319 "-EncryptedData_decrypt -in test.cms -inform PEM "
320 . " -secretkey 000102030405060708090A0B0C0D0E0F -out smtst.txt"
321 ],
322
323);
324
325my @smime_cms_comp_tests = (
326
327 [
328 "compressed content test streaming PEM format",
329 "-compress -in smcont.txt -outform PEM -nodetach"
330 . " -stream -out test.cms",
331 "-uncompress -in test.cms -inform PEM -out smtst.txt"
332 ]
333
334);
335
336print "PKCS#7 <=> PKCS#7 consistency tests\n";
337
338run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $pk7cmd );
339
340print "CMS => PKCS#7 compatibility tests\n";
341
342run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $pk7cmd );
343
344print "CMS <= PKCS#7 compatibility tests\n";
345
346run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $pk7cmd, $cmscmd );
347
348print "CMS <=> CMS consistency tests\n";
349
350run_smime_tests( \$badcmd, \@smime_pkcs7_tests, $cmscmd, $cmscmd );
351run_smime_tests( \$badcmd, \@smime_cms_tests, $cmscmd, $cmscmd );
352
353if ( `$ossl_path version -f` =~ /ZLIB/ ) {
354 run_smime_tests( \$badcmd, \@smime_cms_comp_tests, $cmscmd, $cmscmd );
355}
356else {
357 print "Zlib not supported: compression tests skipped\n";
358}
359
360print "Running modified tests for OpenSSL 0.9.8 cms backport\n" if($ossl8);
361
362if ($badcmd) {
363 print "$badcmd TESTS FAILED!!\n";
364}
365else {
366 print "ALL TESTS SUCCESSFUL.\n";
367}
368
369unlink "test.cms";
370unlink "test2.cms";
371unlink "smtst.txt";
372unlink "cms.out";
373unlink "cms.err";
374
375sub run_smime_tests {
376 my ( $rv, $aref, $scmd, $vcmd ) = @_;
377
378 foreach $smtst (@$aref) {
379 my ( $tnam, $rscmd, $rvcmd ) = @$smtst;
380 if ($ossl8)
381 {
382 # Skip smime resign: 0.9.8 smime doesn't support -resign
383 next if ($scmd =~ /smime/ && $rscmd =~ /-resign/);
384 # Disable streaming: option not supported in 0.9.8
385 $tnam =~ s/streaming//;
386 $rscmd =~ s/-stream//;
387 $rvcmd =~ s/-stream//;
388 }
389 system("$scmd$rscmd 2>cms.err 1>cms.out");
390 if ($?) {
391 print "$tnam: generation error\n";
392 $$rv++;
393 exit 1 if $halt_err;
394 next;
395 }
396 system("$vcmd$rvcmd 2>cms.err 1>cms.out");
397 if ($?) {
398 print "$tnam: verify error\n";
399 $$rv++;
400 exit 1 if $halt_err;
401 next;
402 }
403 if (!cmp_files("smtst.txt", "smcont.txt")) {
404 print "$tnam: content verify error\n";
405 $$rv++;
406 exit 1 if $halt_err;
407 next;
408 }
409 print "$tnam: OK\n";
410 }
411}
412
413sub cmp_files {
414 my ( $f1, $f2 ) = @_;
415 my ( $fp1, $fp2 );
416
417 my ( $rd1, $rd2 );
418
419 if ( !open( $fp1, "<$f1" ) ) {
420 print STDERR "Can't Open file $f1\n";
421 return 0;
422 }
423
424 if ( !open( $fp2, "<$f2" ) ) {
425 print STDERR "Can't Open file $f2\n";
426 return 0;
427 }
428
429 binmode $fp1;
430 binmode $fp2;
431
432 my $ret = 0;
433
434 for ( ; ; ) {
435 $n1 = sysread $fp1, $rd1, 4096;
436 $n2 = sysread $fp2, $rd2, 4096;
437 last if ( $n1 != $n2 );
438 last if ( $rd1 ne $rd2 );
439
440 if ( $n1 == 0 ) {
441 $ret = 1;
442 last;
443 }
444
445 }
446
447 close $fp1;
448 close $fp2;
449
450 return $ret;
451
452}
453
diff --git a/src/lib/libssl/test/smcont.txt b/src/lib/libssl/test/smcont.txt
new file mode 100644
index 0000000000..e837c0b75b
--- /dev/null
+++ b/src/lib/libssl/test/smcont.txt
@@ -0,0 +1 @@
Some test content for OpenSSL CMS \ No newline at end of file
diff --git a/src/lib/libssl/test/smime-certs/smdsa1.pem b/src/lib/libssl/test/smime-certs/smdsa1.pem
new file mode 100644
index 0000000000..d5677dbfbe
--- /dev/null
+++ b/src/lib/libssl/test/smime-certs/smdsa1.pem
@@ -0,0 +1,34 @@
1-----BEGIN DSA PRIVATE KEY-----
2MIIBuwIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
3OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
4GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
5jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
6wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
7+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
8SJCBQw5zAoGATQlPPF+OeU8nu3rsdXGDiZdJzOkuCce3KQfTABA9C+Dk4CVcvBdd
9YRLGpnykumkNTO1sTO+4/Gphsuje1ujK9td4UEhdYqylCe5QjEMrszDlJtelDQF9
10C0yhdjKGTP0kxofLhsGckcuQvcKEKffT2pDDKJIy4vWQO0UyJl1vjLcCFG2uiGGx
119fMUZq1v0ePD4Wo0Xkxo
12-----END DSA PRIVATE KEY-----
13-----BEGIN CERTIFICATE-----
14MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsWMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
15BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
16TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
17CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
18ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
19CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
20mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
21jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
22CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
23kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
24xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBN
25CU88X455Tye7eux1cYOJl0nM6S4Jx7cpB9MAED0L4OTgJVy8F11hEsamfKS6aQ1M
267WxM77j8amGy6N7W6Mr213hQSF1irKUJ7lCMQyuzMOUm16UNAX0LTKF2MoZM/STG
27h8uGwZyRy5C9woQp99PakMMokjLi9ZA7RTImXW+Mt6OBgzCBgDAdBgNVHQ4EFgQU
284Qfbhpi5yqXaXuCLXj427mR25MkwHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
29aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
30c21pbWVkc2ExQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBAFrdUzKK1pWO
31kd02S423KUBc4GWWyiGlVoEO7WxVhHLJ8sm67X7OtJOwe0UGt+Nc5qLtyJYSirw8
32phjiTdNpQCTJ8+Kc56tWkJ6H7NAI4vTJtPL5BM/EmeYrVSU9JI9xhqpyKw9IBD+n
33hRJ79W9FaiJRvaAOX+TkyTukJrxAWRyv
34-----END CERTIFICATE-----
diff --git a/src/lib/libssl/test/smime-certs/smdsa2.pem b/src/lib/libssl/test/smime-certs/smdsa2.pem
new file mode 100644
index 0000000000..ef86c115d7
--- /dev/null
+++ b/src/lib/libssl/test/smime-certs/smdsa2.pem
@@ -0,0 +1,34 @@
1-----BEGIN DSA PRIVATE KEY-----
2MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
3OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
4GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
5jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
6wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
7+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
8SJCBQw5zAoGBAIPmO8BtJ+Yac58trrPwq9b/6VW3jQTWzTLWSH84/QQdqQa+Pz3v
9It/+hHM0daNF5uls8ICsPL1aLXmRx0pHvIyb0aAzYae4T4Jv/COPDMTdKbA1uitJ
10VbkGZrm+LIrs7I9lOkb4T0vI6kL/XdOCXY1469zsqCgJ/O2ibn6mq0nWAhR716o2
11Nf8SimTZYB0/CKje6M5ufA==
12-----END DSA PRIVATE KEY-----
13-----BEGIN CERTIFICATE-----
14MIIDpTCCAw6gAwIBAgIJAMtotfHYdEsXMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
15BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
16TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
17CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
18ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggG4MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
19CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
20mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
21jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
22CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
23kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
24xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhQACgYEA
25g+Y7wG0n5hpzny2us/Cr1v/pVbeNBNbNMtZIfzj9BB2pBr4/Pe8i3/6EczR1o0Xm
266WzwgKw8vVoteZHHSke8jJvRoDNhp7hPgm/8I48MxN0psDW6K0lVuQZmub4siuzs
27j2U6RvhPS8jqQv9d04JdjXjr3OyoKAn87aJufqarSdajgYMwgYAwHQYDVR0OBBYE
28FHsAGNfVltSYUq4hC+YVYwsYtA+dMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcXdsab
29rWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMCAGA1UdEQQZMBeB
30FXNtaW1lZHNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQCx9BtCbaYF
31FXjLClkuKXbESaDZA1biPgY25i00FsUzARuhCpqD2v+0tu5c33ZzIhL6xlvBRU5l
326Atw/xpZhae+hdBEtxPJoGekLLrHOau7Md3XwDjV4lFgcEJkWZoaSOOIK+4D5jF0
33jZWtHjnwEzuLYlo7ScHSsbcQfjH0M1TP5A==
34-----END CERTIFICATE-----
diff --git a/src/lib/libssl/test/smime-certs/smdsa3.pem b/src/lib/libssl/test/smime-certs/smdsa3.pem
new file mode 100644
index 0000000000..eeb848dabc
--- /dev/null
+++ b/src/lib/libssl/test/smime-certs/smdsa3.pem
@@ -0,0 +1,34 @@
1-----BEGIN DSA PRIVATE KEY-----
2MIIBvAIBAAKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3
3OjSGLh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqt
4GcoAgsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2J
5jt+dqk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qt
6wjqvWp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK
7+FMOGnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4Z
8SJCBQw5zAoGAYzOpPmh8Je1IDauEXhgaLz14wqYUHHcrj2VWVJ6fRm8GhdQFJSI7
9GUk08pgKZSKic2lNqxuzW7/vFxKQ/nvzfytY16b+2i+BR4Q6yvMzCebE1hHVg0Ju
10TwfUMwoFEOhYP6ZwHSUiQl9IBMH9TNJCMwYMxfY+VOrURFsjGTRUgpwCFQCIGt5g
11Y+XZd0Sv69CatDIRYWvaIA==
12-----END DSA PRIVATE KEY-----
13-----BEGIN CERTIFICATE-----
14MIIDpDCCAw2gAwIBAgIJAMtotfHYdEsYMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
15BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
16TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
17CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
18ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEAxSX7
19CDziGsDDuW4sPgKGFITVcUXgTi0KLFN0L+AfJK2nNATa9zo0hi4dcGcR6oZQBNEJ
20mrE2iqI7pNtJzVnhZ3M0s+rw5dCFSRIUvFWKK+ZLfYC6rRnKAILH+IEQyLrSckA2
21jZ9yFWPPbl1FSKHsb0Hi0AwQoEDwuTvKyXagcLcCFQCtiY7fnapNO3kFBOfZKGFB
22CsjaKwKBgQCOCBKbrH/BteJAh5kbZx1zNrRuRFiQ5lukLcI6r1qdRilMeVhctbVV
23kfZ5eay9A4vpDXRDaPkpCo+4d7g7pRjiOk9JkGG1dodSCvhTDhpzqr2fHjUxNp+D
24xk6OabmetywZvkGK0LKzYlGOL2pCxUNqxCv0i8HbAxSuGUiQgUMOcwOBhAACgYBj
25M6k+aHwl7UgNq4ReGBovPXjCphQcdyuPZVZUnp9GbwaF1AUlIjsZSTTymAplIqJz
26aU2rG7Nbv+8XEpD+e/N/K1jXpv7aL4FHhDrK8zMJ5sTWEdWDQm5PB9QzCgUQ6Fg/
27pnAdJSJCX0gEwf1M0kIzBgzF9j5U6tREWyMZNFSCnKOBgzCBgDAdBgNVHQ4EFgQU
28VhpVXqQ/EzUMdxLvP7o9EhJ8h70wHwYDVR0jBBgwFoAUE89Lp7uJLrM4Vxd2xput
29aFvl7RcwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwIAYDVR0RBBkwF4EV
30c21pbWVkc2EzQG9wZW5zc2wub3JnMA0GCSqGSIb3DQEBBQUAA4GBACM9e75EQa8m
31k/AZkH/tROqf3yeqijULl9x8FjFatqoY+29OM6oMGM425IqSkKd2ipz7OxO0SShu
32rE0O3edS7DvYBwvhWPviRaYBMyZ4iFJVup+fOzoYK/j/bASxS3BHQBwb2r4rhe25
33OlTyyFEk7DJyW18YFOG97S1P52oQ5f5x
34-----END CERTIFICATE-----
diff --git a/src/lib/libssl/test/smime-certs/smdsap.pem b/src/lib/libssl/test/smime-certs/smdsap.pem
new file mode 100644
index 0000000000..249706c8c7
--- /dev/null
+++ b/src/lib/libssl/test/smime-certs/smdsap.pem
@@ -0,0 +1,9 @@
1-----BEGIN DSA PARAMETERS-----
2MIIBHwKBgQDFJfsIPOIawMO5biw+AoYUhNVxReBOLQosU3Qv4B8krac0BNr3OjSG
3Lh1wZxHqhlAE0QmasTaKojuk20nNWeFnczSz6vDl0IVJEhS8VYor5kt9gLqtGcoA
4gsf4gRDIutJyQDaNn3IVY89uXUVIoexvQeLQDBCgQPC5O8rJdqBwtwIVAK2Jjt+d
5qk07eQUE59koYUEKyNorAoGBAI4IEpusf8G14kCHmRtnHXM2tG5EWJDmW6Qtwjqv
6Wp1GKUx5WFy1tVWR9nl5rL0Di+kNdENo+SkKj7h3uDulGOI6T0mQYbV2h1IK+FMO
7GnOqvZ8eNTE2n4PGTo5puZ63LBm+QYrQsrNiUY4vakLFQ2rEK/SLwdsDFK4ZSJCB
8Qw5z
9-----END DSA PARAMETERS-----
diff --git a/src/lib/libssl/test/smime-certs/smroot.pem b/src/lib/libssl/test/smime-certs/smroot.pem
new file mode 100644
index 0000000000..a59eb2684c
--- /dev/null
+++ b/src/lib/libssl/test/smime-certs/smroot.pem
@@ -0,0 +1,30 @@
1-----BEGIN RSA PRIVATE KEY-----
2MIICXAIBAAKBgQDBV1Z/Q5gPF7lojc8pKUdyz5+Jf2B3vs4he6egekugWnoJduki
39Lnae/JchB/soIX0co3nLc11NuFFlnAWJNMDJr08l5AHAJLYNHevF5l/f9oDQwvZ
4speKh1xpIAJNqCTzVeQ/ZLx6/GccIXV/xDuKIiovqJTPgR5WPkYKaw++lQIDAQAB
5AoGALXnUj5SflJU4+B2652ydMKUjWl0KnL/VjkyejgGV/j6py8Ybaixz9q8Gv7oY
6JDlRqMC1HfZJCFQDQrHy5VJ+CywA/H9WrqKo/Ch9U4tJAZtkig1Cmay/BAYixVu0
7xBeim10aKF6hxHH4Chg9We+OCuzWBWJhqveNjuDedL/i7JUCQQDlejovcwBUCbhJ
8U12qKOwlaboolWbl7yF3XdckTJZg7+1UqQHZH5jYZlLZyZxiaC92SNV0SyTLJZnS
9Jh5CO+VDAkEA16/pPcuVtMMz/R6SSPpRSIAa1stLs0mFSs3NpR4pdm0n42mu05pO
101tJEt3a1g7zkreQBf53+Dwb+lA841EkjRwJBAIFmt0DifKDnCkBu/jZh9SfzwsH3
113Zpzik+hXxxdA7+ODCrdUul449vDd5zQD5t+XKU61QNLDGhxv5e9XvrCg7kCQH/a
123ldsVF0oDaxxL+QkxoREtCQ5tLEd1u7F2q6Tl56FDE0pe6Ih6bQ8RtG+g9EI60IN
13U7oTrOO5kLWx5E0q4ccCQAZVgoenn9MhRU1agKOCuM6LT2DxReTu4XztJzynej+8
140J93n3ebanB1MlRpn1XJwhQ7gAC8ImaQKLJK5jdJzFc=
15-----END RSA PRIVATE KEY-----
16-----BEGIN CERTIFICATE-----
17MIICaTCCAdKgAwIBAgIJAP6VN47boiXRMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
18BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
19TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDdaFw0xNjA1MTExMzUzMDdaMEQx
20CzAJBgNVBAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRU
21ZXN0IFMvTUlNRSBSU0EgUm9vdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
22wVdWf0OYDxe5aI3PKSlHcs+fiX9gd77OIXunoHpLoFp6CXbpIvS52nvyXIQf7KCF
239HKN5y3NdTbhRZZwFiTTAya9PJeQBwCS2DR3rxeZf3/aA0ML2bKXiodcaSACTagk
2481XkP2S8evxnHCF1f8Q7iiIqL6iUz4EeVj5GCmsPvpUCAwEAAaNjMGEwHQYDVR0O
25BBYEFBPPS6e7iS6zOFcXdsabrWhb5e0XMB8GA1UdIwQYMBaAFBPPS6e7iS6zOFcX
26dsabrWhb5e0XMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqG
27SIb3DQEBBQUAA4GBAIECprq5viDvnDbkyOaiSr9ubMUmWqvycfAJMdPZRKcOZczS
28l+L9R9lF3JSqbt3knOe9u6bGDBOTY2285PdCCuHRVMk2Af1f6El1fqAlRUwNqipp
29r68sWFuRqrcRNtk6QQvXfkOhrqQBuDa7te/OVQLa2lGN9Dr2mQsD8ijctatG
30-----END CERTIFICATE-----
diff --git a/src/lib/libssl/test/smime-certs/smrsa1.pem b/src/lib/libssl/test/smime-certs/smrsa1.pem
new file mode 100644
index 0000000000..2cf3148e33
--- /dev/null
+++ b/src/lib/libssl/test/smime-certs/smrsa1.pem
@@ -0,0 +1,31 @@
1-----BEGIN RSA PRIVATE KEY-----
2MIICXgIBAAKBgQC6A978j4pmPgUtUQqF+bjh6vdhwGOGZSD7xXgFTMjm88twfv+E
3ixkq2KXSDjD0ZXoQbdOaSbvGRQrIJpG2NGiKAFdYNrP025kCCdh5wF/aEI7KLEm7
4JlHwXpQsuj4wkMgmkFjL3Ty4Z55aNH+2pPQIa0k+ENJXm2gDuhqgBmduAwIDAQAB
5AoGBAJMuYu51aO2THyeHGwt81uOytcCbqGP7eoib62ZOJhxPRGYjpmuqX+R9/V5i
6KiwGavm63JYUx0WO9YP+uIZxm1BUATzkgkS74u5LP6ajhkZh6/Bck1oIYYkbVOXl
7JVrdENuH6U7nupznsyYgONByo+ykFPVUGmutgiaC7NMVo/MxAkEA6KLejWXdCIEn
8xr7hGph9NlvY9xuRIMexRV/WrddcFfCdjI1PciIupgrIkR65M9yr7atm1iU6/aRf
9KOr8rLZsSQJBAMyyXN71NsDNx4BP6rtJ/LJMP0BylznWkA7zWfGCbAYn9VhZVlSY
10Eu9Gyr7quD1ix7G3kInKVYOEEOpockBLz+sCQQCedyMmKjcQLfpMVYW8uhbAynvW
11h36qV5yXZxszO7nMcCTBsxhk5IfmLv5EbCs3+p9avCDGyoGOeUMg+kC33WORAkAg
12oUIarH4o5+SoeJTTfCzTA0KF9H5U0vYt2+73h7HOnWoHxl3zqDZEfEVvf50U8/0f
13QELDJETTbScBJtsnkq43AkEA38etvoZ2i4FJvvo7R/9gWBHVEcrGzcsCBYrNnIR1
14SZLRwHEGaiOK1wxMsWzqp7PJwL9z/M8A8DyOFBx3GPOniA==
15-----END RSA PRIVATE KEY-----
16-----BEGIN CERTIFICATE-----
17MIICizCCAfSgAwIBAgIJAMtotfHYdEsTMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
18BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
19TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
20CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
21ZXN0IFMvTUlNRSBFRSBSU0EgIzEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
22ALoD3vyPimY+BS1RCoX5uOHq92HAY4ZlIPvFeAVMyObzy3B+/4SLGSrYpdIOMPRl
23ehBt05pJu8ZFCsgmkbY0aIoAV1g2s/TbmQIJ2HnAX9oQjsosSbsmUfBelCy6PjCQ
24yCaQWMvdPLhnnlo0f7ak9AhrST4Q0lebaAO6GqAGZ24DAgMBAAGjgYMwgYAwHQYD
25VR0OBBYEFE2vMvKz5jrC7Lbdg68XwZ95iL/QMB8GA1UdIwQYMBaAFBPPS6e7iS6z
26OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
27EQQZMBeBFXNtaW1lcnNhMUBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQAi
28O3GOkUl646oLnOimc36i9wxZ1tejsqs8vMjJ0Pym6Uq9FE2JoGzJ6OhB1GOsEVmj
299cQ5UNQcRYL3cqOFtl6f4Dpu/lhzfbaqgmLjv29G1mS0uuTZrixhlyCXjwcbOkNC
30I/+wvHHENYIK5+T/79M9LaZ2Qk4F9MNE1VMljdz9Qw==
31-----END CERTIFICATE-----
diff --git a/src/lib/libssl/test/smime-certs/smrsa2.pem b/src/lib/libssl/test/smime-certs/smrsa2.pem
new file mode 100644
index 0000000000..d41f69c82f
--- /dev/null
+++ b/src/lib/libssl/test/smime-certs/smrsa2.pem
@@ -0,0 +1,31 @@
1-----BEGIN RSA PRIVATE KEY-----
2MIICWwIBAAKBgQCwBfryW4Vu5U9wNIDKspJO/N9YF4CcTlrCUyzVlKgb+8urHlSe
359i5verR9IOCCXkemjOzZ/3nALTGqYZlnEvHp0Rjk+KdKXnKBIB+SRPpeu3LcXMT
4WPgsThPa0UQxedNKG0g6aG+kLhsDlFBCoxd09jJtSpb9jmroJOq0ZYEHLwIDAQAB
5AoGAKa/w4677Je1W5+r3SYoLDnvi5TkDs4D3C6ipKJgBTEdQz+DqB4w/DpZE4551
6+rkFn1LDxcxuHGRVa+tAMhZW97fwq9YUbjVZEyOz79qrX+BMyl/NbHkf1lIKDo3q
7dWalzQvop7nbzeLC+VmmviwZfLQUbA61AQl3jm4dswT4XykCQQDloDadEv/28NTx
8bvvywvyGuvJkCkEIycm4JrIInvwsd76h/chZ3oymrqzc7hkEtK6kThqlS5y+WXl6
9QzPruTKTAkEAxD2ro/VUoN+scIVaLmn0RBmZ67+9Pdn6pNSfjlK3s0T0EM6/iUWS
10M06l6L9wFS3/ceu1tIifsh9BeqOGTa+udQJARIFnybTBaIqw/NZ/lA1YCVn8tpvY
11iyaoZ6gjtS65TQrsdKeh/i3HCHNUXxUpoZ3F/H7QtD+6o49ODou+EbVOwQJAVmex
12A2gp8wuJKaINqxIL81AybZLnCCzKJ3lXJ5tUNyLNM/lUbGStktm2Q1zHRQwTxV07
13jFn7trn8YrtNjzcjYQJAUKIJRt38A8Jw3HoPT+D0WS2IgxjVL0eYGsZX1lyeammG
146rfnQ3u5uP7mEK2EH2o8mDUpAE0gclWBU9UkKxJsGA==
15-----END RSA PRIVATE KEY-----
16-----BEGIN CERTIFICATE-----
17MIICizCCAfSgAwIBAgIJAMtotfHYdEsUMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
18BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
19TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDhaFw0xNjA1MTAxMzUzMDhaMEUx
20CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
21ZXN0IFMvTUlNRSBFRSBSU0EgIzIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
22ALAF+vJbhW7lT3A0gMqykk7831gXgJxOWsJTLNWUqBv7y6seVJ7n2Lm96tH0g4IJ
23eR6aM7Nn/ecAtMaphmWcS8enRGOT4p0pecoEgH5JE+l67ctxcxNY+CxOE9rRRDF5
2400obSDpob6QuGwOUUEKjF3T2Mm1Klv2Oaugk6rRlgQcvAgMBAAGjgYMwgYAwHQYD
25VR0OBBYEFIL/u+mEvaw7RuKLRuElfVkxSQjYMB8GA1UdIwQYMBaAFBPPS6e7iS6z
26OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
27EQQZMBeBFXNtaW1lcnNhMkBvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQC2
28rXR5bm/9RtOMQPleNpd3y6uUX3oy+0CafK5Yl3PMnItjjnKJ0l1/DbLbDj2twehe
29ewaB8CROcBCA3AMLSmGvPKgUCFMGtWam3328M4fBHzon5ka7qDXzM+imkAly/Yx2
30YNdR/aNOug+5sXygHmTSKqiCpQjOIClzXoPVVeEVHw==
31-----END CERTIFICATE-----
diff --git a/src/lib/libssl/test/smime-certs/smrsa3.pem b/src/lib/libssl/test/smime-certs/smrsa3.pem
new file mode 100644
index 0000000000..c8cbe55151
--- /dev/null
+++ b/src/lib/libssl/test/smime-certs/smrsa3.pem
@@ -0,0 +1,31 @@
1-----BEGIN RSA PRIVATE KEY-----
2MIICXAIBAAKBgQC6syTZtZNe1hRScFc4PUVyVLsr7+C1HDIZnOHmwFoLayX6RHwy
3ep/TkdwiPHnemVLuwvpSjLMLZkXy/J764kSHJrNeVl3UvmCVCOm40hAtK1+F39pM
4h8phkbPPD7i+hwq4/Vs79o46nzwbVKmzgoZBJhZ+codujUSYM3LjJ4aq+wIDAQAB
5AoGAE1Zixrnr3bLGwBMqtYSDIOhtyos59whImCaLr17U9MHQWS+mvYO98if1aQZi
6iQ/QazJ+wvYXxWJ+dEB+JvYwqrGeuAU6He/rAb4OShG4FPVU2D19gzRnaButWMeT
7/1lgXV08hegGBL7RQNaN7b0viFYMcKnSghleMP0/q+Y/oaECQQDkXEwDYJW13X9p
8ijS20ykWdY5lLknjkHRhhOYux0rlhOqsyMZjoUmwI2m0qj9yrIysKhrk4MZaM/uC
9hy0xp3hdAkEA0Uv/UY0Kwsgc+W6YxeypECtg1qCE6FBib8n4iFy/6VcWqhvE5xrs
10OdhKv9/p6aLjLneGd1sU+F8eS9LGyKIbNwJBAJPgbNzXA7uUZriqZb5qeTXxBDfj
11RLfXSHYKAKEULxz3+JvRHB9SR4yHMiFrCdExiZrHXUkPgYLSHLGG5a4824UCQD6T
129XvhquUARkGCAuWy0/3Eqoihp/t6BWSdQ9Upviu7YUhtUxsyXo0REZB7F4pGrJx5
13GlhXgFaewgUzuUHFzlMCQCzJMMWslWpoLntnR6sMhBMhBFHSw+Y5CbxBmFrdtSkd
14VdtNO1VuDCTxjjW7W3Khj7LX4KZ1ye/5jfAgnnnXisc=
15-----END RSA PRIVATE KEY-----
16-----BEGIN CERTIFICATE-----
17MIICizCCAfSgAwIBAgIJAMtotfHYdEsVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
18BAYTAlVLMRYwFAYDVQQKEw1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDExRUZXN0IFMv
19TUlNRSBSU0EgUm9vdDAeFw0wODAyMjIxMzUzMDlaFw0xNjA1MTAxMzUzMDlaMEUx
20CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
21ZXN0IFMvTUlNRSBFRSBSU0EgIzMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
22ALqzJNm1k17WFFJwVzg9RXJUuyvv4LUcMhmc4ebAWgtrJfpEfDJ6n9OR3CI8ed6Z
23Uu7C+lKMswtmRfL8nvriRIcms15WXdS+YJUI6bjSEC0rX4Xf2kyHymGRs88PuL6H
24Crj9Wzv2jjqfPBtUqbOChkEmFn5yh26NRJgzcuMnhqr7AgMBAAGjgYMwgYAwHQYD
25VR0OBBYEFDsSFjNtYZzd0tTHafNS7tneQQj6MB8GA1UdIwQYMBaAFBPPS6e7iS6z
26OFcXdsabrWhb5e0XMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCAGA1Ud
27EQQZMBeBFXNtaW1lcnNhM0BvcGVuc3NsLm9yZzANBgkqhkiG9w0BAQUFAAOBgQBE
28tUDB+1Dqigu4p1xtdq7JRK6S+gfA7RWmhz0j2scb2zhpS12h37JLHsidGeKAzZYq
29jUjOrH/j3xcV5AnuJoqImJaN23nzzxtR4qGGX2mrq6EtObzdEGgCUaizsGM+0slJ
30PYxcy8KeY/63B1BpYhj2RjGkL6HrvuAaxVORa3acoA==
31-----END CERTIFICATE-----