Kannel: Open Source WAP and SMS gateway  svn-r5335
wtls_statesupport.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2018 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * 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. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * wtls_statesupport.c
59  *
60  * 2001 Nick Clarey, Yann Muller for 3G LAB
61  * Nikos Balkanas, InAccess Networks (2009)
62  */
63 
64 #include "gwlib/gwlib.h"
65 
66 #ifdef HAVE_WTLS_OPENSSL
67 #include <openssl/x509.h>
68 #include <openssl/des.h>
69 #ifndef NO_RC5
70 #include <openssl/rc5.h>
71 #else
72 #error "your OpenSSL installation lacks RC5 algorithm support"
73 #endif /* NO_RC5 */
74 
75 #include "wtls_statesupport.h"
76 #include "wtls_pdusupport.h"
77 
78 #define BLOCKLENGTH 64
79 #define INNERPAD 0x36
80 #define OUTERPAD 0x5C
81 
82 /*static keyxchg_table_t keyxchg_table[] = {
83  {"NULL",0},
84  {"Shared Secret", KEYSIZE_MAX},
85  {"DH-anon",KEYSIZE_MAX},
86  {"DH-anon-512",512},
87  {"DH-anon-768",768},
88  {"RSA-anon", KEYSIZE_MAX},
89  {"RSA-anon-512",512},
90  {"RSA-anon-768",768},
91  {"RSA",KEYSIZE_MAX},
92  {"RSA-512", 512},
93  {"RSA-768",768},
94  {"ECDH-anon",KEYSIZE_MAX},
95  {"ECDH-anon-113",113},
96  {"ECDH-anon-131",131},
97  {"ECDH-ECDSA",KEYSIZE_MAX}
98 }; */
99 
100 static bulk_table_t bulk_table[] = {
101  {"NULL Encryption", EXPORTABLE, STREAM, 0, 0, 0, 0, 0},
102  {"RC5-CBC-40", EXPORTABLE, BLOCK, 5, 16, 40, 8, 8},
103  {"RC5-CBC-56", EXPORTABLE, BLOCK, 7, 16, 56, 8, 8},
104  {"RC5-CBC", NOT_EXPORTABLE, BLOCK, 16, 16, 128, 8, 8},
105  {"DES-CBC-40", EXPORTABLE, BLOCK, 5, 8, 40, 8, 8},
106  {"DES-CBC", NOT_EXPORTABLE, BLOCK, 8, 8, 56, 8, 8},
107  {"3DES-CBC-EDE", NOT_EXPORTABLE, BLOCK, 24, 24, 168, 8, 8},
108  {"IDEA-CBC-40", EXPORTABLE, BLOCK, 5, 16, 40, 8, 8},
109  {"IDEA-CBC-56", EXPORTABLE, BLOCK, 7, 16, 56, 8, 8},
110  {"IDEA-CBC", NOT_EXPORTABLE, BLOCK, 16, 16, 128, 8, 8}
111 };
112 
113 static hash_table_t hash_table[] = {
114  {"SHA-0", 0, 0},
115  {"SHA1-40", 20, 5},
116  {"SHA1-80", 20, 10},
117  {"SHA1", 20, 20},
118  {"SHA-XOR-40", 0, 5},
119  {"MD5-40", 16, 5},
120  {"MD5-80", 16, 10},
121  {"MD5", 16, 16}
122 };
123 
124 X509 *x509_cert = NULL;
125 RSA *private_key = NULL;
126 int refresh = 2;
127 extern KeyExchangeSuite client_key_exchange_algo;
128 extern PublicKeyAlgorithm public_key_algo;
129 extern SignatureAlgorithm signature_algo;
130 extern unsigned char *MD5(const unsigned char *d, size_t n, unsigned char
131  *md);
132 extern unsigned char *stateName(int state);
133 
134 /*
135  * Function Prototypes.
136  */
137 
138 Octstr *wtls_hmac_hash(Octstr * key, Octstr * data, int algo);
139 Octstr *wtls_hash(Octstr * inputData, WTLSMachine * wtls_machine);
140 Octstr *wtls_rc5(Octstr * data, WTLSMachine * wtls_machine, int crypt);
141 Octstr *wtls_des(Octstr * data, WTLSMachine * wtls_machine, int crypt);
142 Octstr *wtls_P_hash(Octstr * secret, Octstr * seed, int byteLength,
143  WTLSMachine * wtls_machine);
144 Octstr *wtls_get_certificate(void);
145 int isSupportedKeyEx(int keyExId);
146 void add_all_handshake_data(WTLSMachine * wtls_machine, List * pdu_list);
147 
148 /* Add here the supported KeyExchangeSuites
149  used by wtls_choose_clientkeyid */
150 KeyExchangeSuite supportedKeyExSuite[] = { rsa_anon };
151 
153 {
154  int len, padLen = 0, macSize, recordType, block, refresh;
155  Octstr *openText, *MAContent, *tempData, *result;
156  char cipher[20], *p;
157 
158  if (payload->seqNum && wtls_machine->client_seq_num > payload->seqNum) {
159  error(0,
160  "Out of sequence packet received (p: %d < %d :w). Dropping datagram.",
161  payload->seqNum, wtls_machine->client_seq_num);
162  return (NULL);
163  } else
164  wtls_machine->client_seq_num = payload->seqNum;
165  refresh = 1 << wtls_machine->key_refresh;
166  if (wtls_machine->last_refresh < 0 || (wtls_machine->last_refresh +
167  refresh <=
168  wtls_machine->client_seq_num))
169  calculate_client_key_block(wtls_machine);
170  switch (wtls_machine->bulk_cipher_algorithm) {
171  case NULL_bulk:
172  openText = octstr_duplicate(payload->data);
173  break;
174 
175  case RC5_CBC:
176  case RC5_CBC_40:
177  case RC5_CBC_56:
178  openText = wtls_rc5(payload->data, wtls_machine, RC5_DECRYPT);
179  break;
180 
181  case DES_CBC:
182  case DES_CBC_40:
183  openText = wtls_des(payload->data, wtls_machine, DES_DECRYPT);
184  break;
185 
186  default:
187  cipherName(cipher, wtls_machine->bulk_cipher_algorithm);
188  error(0,
189  "wtls_decrypt: Unsupported bulk cipher algorithm (%s).",
190  cipher);
191  return (NULL);
192  break;
193  }
194  /* Verify MAC */
195  recordType = 1 << 7;
196  recordType |= payload->snMode << 6;
197  recordType |= payload->cipher << 5;
198  recordType |= payload->reserved << 4;
199  recordType |= payload->type;
200  len = octstr_len(openText);
201  p = octstr_get_cstr(openText);
202  block = bulk_table[wtls_machine->bulk_cipher_algorithm].block_size;
203 
204  padLen = *(p + len - 1);
205  if (padLen >= block || padLen != *(p + len - 2))
206  padLen = 0;
207  padLen++;
208  macSize = hash_table[wtls_machine->mac_algorithm].mac_size;
209 
210  tempData = octstr_create("");
211  pack_int16(tempData, 0, wtls_machine->client_seq_num);
212  octstr_append_char(tempData, recordType);
213  pack_int16(tempData, 3, len - macSize - padLen);
214  octstr_append_data(tempData, p, len - macSize - padLen);
215  MAContent = wtls_hmac_hash(wtls_machine->client_write_MAC_secret,
216  tempData, wtls_machine->mac_algorithm);
217  if (memcmp(octstr_get_cstr(MAContent), p + len - padLen - macSize,
218  macSize)) {
219  octstr_destroy(MAContent);
220  octstr_destroy(tempData);
221  octstr_destroy(openText);
222  error(0, "wtls_decrypt: Rejected packet due to bad MAC");
223  return (NULL);
224  }
225  octstr_destroy(MAContent);
226  octstr_destroy(tempData);
227  result = octstr_create_from_data((char *)p, len - padLen - macSize);
228  octstr_destroy(openText);
229  return (result);
230 }
231 
232 /* This function will convert our buffer into a completed GenericBlockCipher */
233 Octstr *wtls_encrypt(Octstr * buffer, WTLSMachine * wtls_machine,
234  int recordType)
235 {
236  Octstr *bufferCopy;
237  Octstr *encryptedContent;
238  Octstr *contentMac;
239  Octstr *tempData;
240  char *tempPadding = NULL;
241  int paddingLength, macSize, blockLength, bufferLength, refresh;
242  int i;
243 
244  refresh = 1 << wtls_machine->key_refresh;
245  if (!(wtls_machine->server_seq_num % refresh))
246  calculate_server_key_block(wtls_machine);
247  /* Copy our buffer */
248  bufferCopy = octstr_duplicate(buffer);
249 
250  /* Get the MAC of the content */
251  bufferLength = octstr_len(buffer);
252 
253  /* Copy the buffer in preparation for MAC calculation */
254  tempData = octstr_create("");
255  pack_int16(tempData, 0, wtls_machine->server_seq_num);
256  octstr_append_char(tempData, recordType);
257  pack_int16(tempData, octstr_len(tempData), bufferLength);
258  octstr_append(tempData, buffer);
259 
260  /* Calculate the MAC */
261  contentMac =
262  wtls_hmac_hash(wtls_machine->server_write_MAC_secret, tempData,
263  wtls_machine->mac_algorithm);
264 
265  /* Calculate the padding length */
266  macSize = hash_table[wtls_machine->mac_algorithm].mac_size;
267  blockLength =
268  bulk_table[wtls_machine->bulk_cipher_algorithm].block_size;
269 
270  paddingLength =
271  blockLength - ((bufferLength + macSize + 1) % blockLength);
272 
273  /* Append the MAC to the bufferCopy */
274  octstr_append(bufferCopy, contentMac);
275 
276  if (paddingLength > 0) {
277  /* Pad with the paddingLength itself paddingLength times. Confused yet? */
278  tempPadding = gw_malloc(paddingLength);
279  for (i = 0; i < paddingLength; i++) {
280  /* You're probably really spaced out around now...
281  see section 9.2.3.3 for more details... */
282  tempPadding[i] = paddingLength;
283  }
284  octstr_append_data(bufferCopy, tempPadding, paddingLength);
285  gw_free(tempPadding);
286  }
287  /* Add the length byte */
288  octstr_append_char(bufferCopy, paddingLength);
289 
290  /* Encrypt the content */
291  switch (wtls_machine->bulk_cipher_algorithm) {
292  case NULL_bulk:
293  encryptedContent = octstr_duplicate(bufferCopy);
294  break;
295 
296  case RC5_CBC:
297  case RC5_CBC_40:
298  case RC5_CBC_56:
299  encryptedContent =
300  wtls_rc5(bufferCopy, wtls_machine, RC5_ENCRYPT);
301  break;
302 
303  case DES_CBC:
304  case DES_CBC_40:
305  encryptedContent =
306  wtls_des(bufferCopy, wtls_machine, DES_ENCRYPT);
307  break;
308 
309  default:
310  error(0,
311  "wtls_encrypt: Unsupported bulk cipher algorithm (%d).",
312  wtls_machine->bulk_cipher_algorithm);
313  encryptedContent = NULL;
314  break;
315  }
316  octstr_destroy(bufferCopy);
317  octstr_destroy(contentMac);
318  octstr_destroy(tempData);
319  octstr_destroy(buffer);
320  return (encryptedContent);
321 }
322 
323 /*
324  * Naming utilities used in printing
325  */
326 
327 void keyName(char *name, int key)
328 {
329  switch (key) {
330  case null_k:
331  strcpy(name, "null_k");
332  break;
333 
334  case shared_secret:
335  strcpy(name, "shared_secret");
336  break;
337 
338  case dh_anon:
339  strcpy(name, "dh_anon");
340  break;
341 
342  case dh_anon_512:
343  strcpy(name, "dh_anon_512");
344  break;
345 
346  case dh_anon_768:
347  strcpy(name, "dh_anon_768");
348  break;
349 
350  case rsa_anon:
351  strcpy(name, "rsa_anon");
352  break;
353 
354  case rsa_anon_512:
355  strcpy(name, "rsa_anon_512");
356  break;
357 
358  case rsa_anon_768:
359  strcpy(name, "rsa_anon_768");
360  break;
361 
362  case rsa:
363  strcpy(name, "rsa");
364  break;
365 
366  case rsa_512:
367  strcpy(name, "rsa_512");
368  break;
369 
370  case rsa_768:
371  strcpy(name, "rsa_768");
372  break;
373 
374  case ecdh_anon:
375  strcpy(name, "ecdh_anon");
376  break;
377 
378  case ecdh_anon_113:
379  strcpy(name, "ecdh_anon_113");
380  break;
381 
382  case ecdh_anon_131:
383  strcpy(name, "ecdh_anon_131");
384  break;
385 
386  case ecdh_ecdsa:
387  strcpy(name, "ecdh_ecdsa");
388  break;
389  }
390 }
391 
392 void cipherName(char *name, int cipher)
393 {
394  switch (cipher) {
395  case NULL_bulk:
396  strcpy(name, "NULL_bulk");
397  break;
398 
399  case RC5_CBC_40:
400  strcpy(name, "RC5_CBC_40");
401  break;
402 
403  case RC5_CBC_56:
404  strcpy(name, "RC5_CBC_56");
405  break;
406 
407  case RC5_CBC:
408  strcpy(name, "RC5_CBC");
409  break;
410 
411  case DES_CBC_40:
412  strcpy(name, "DES_CBC_40");
413  break;
414 
415  case DES_CBC:
416  strcpy(name, "DES_CBC");
417  break;
418 
419  case TRIPLE_DES_CBC_EDE:
420  strcpy(name, "TRIPLE_DES_CBC_EDE");
421  break;
422 
423  case IDEA_CBC_40:
424  strcpy(name, "IDEA_CBC_40");
425  break;
426 
427  case IDEA_CBC_56:
428  strcpy(name, "IDEA_CBC_56");
429  break;
430 
431  case IDEA_CBC:
432  strcpy(name, "IDEA_CBC");
433  break;
434  }
435 }
436 
437 void macName(char *name, int mac)
438 {
439  switch (mac) {
440  case SHA_0:
441  strcpy(name, "SHA_0");
442  break;
443 
444  case SHA_40:
445  strcpy(name, "SHA_40");
446  break;
447 
448  case SHA_80:
449  strcpy(name, "SHA_80");
450  break;
451 
452  case SHA_NOLIMIT:
453  strcpy(name, "SHA_NOLIMIT");
454  break;
455 
456  case SHA_XOR_40:
457  strcpy(name, "SHA_XOR_40");
458  break;
459 
460  case MD5_40:
461  strcpy(name, "MD5_80");
462  break;
463 
464  case MD5_80:
465  strcpy(name, "MD5_80");
466  break;
467 
468  case MD5_NOLIMIT:
469  strcpy(name, "MD5_NOLIMIT");
470  break;
471  }
472 }
473 
474 void alertName(char *name, int alert)
475 {
476  switch (alert) {
478  strcpy(name, "connection_close_notify");
479  break;
480 
482  strcpy(name, "session_close_notify");
483  break;
484 
485  case no_connection:
486  strcpy(name, "no_connection");
487  break;
488 
489  case unexpected_message:
490  strcpy(name, "unexpected_message");
491  break;
492 
493  case time_required:
494  strcpy(name, "time_required");
495  break;
496 
497  case bad_record_mac:
498  strcpy(name, "bad_record_mac");
499  break;
500 
501  case decryption_failed:
502  strcpy(name, "decryption_failed");
503  break;
504 
505  case record_overflow:
506  strcpy(name, "record_overflow");
507  break;
508 
510  strcpy(name, "decompression_failure");
511  break;
512 
513  case handshake_failure:
514  strcpy(name, "handshake_failure");
515  break;
516 
517  case bad_certificate:
518  strcpy(name, "unsupported_certificate");
519  break;
520 
521  case certificate_revoked:
522  strcpy(name, "certificate_revoked");
523  break;
524 
525  case certificate_expired:
526  strcpy(name, "certificate_expired");
527  break;
528 
529  case certificate_unknown:
530  strcpy(name, "certificate_unknown");
531  break;
532 
533  case illegal_parameter:
534  strcpy(name, "illegal_parameter");
535  break;
536 
537  case unknown_ca:
538  strcpy(name, "unknown_ca");
539  break;
540 
541  case access_denied:
542  strcpy(name, "access_denied");
543  break;
544 
545  case decode_error:
546  strcpy(name, "decode_error");
547  break;
548 
549  case decrypt_error:
550  strcpy(name, "decrypt_error");
551  break;
552 
553  case unknown_key_id:
554  strcpy(name, "unknown_key_id");
555  break;
556 
557  case disabled_key_id:
558  strcpy(name, "disabled_key_id");
559  break;
560 
562  strcpy(name, "key_exchange_disabled");
563  break;
564 
565  case session_not_ready:
566  strcpy(name, "session_not_ready");
567  break;
568 
570  strcpy(name, "unknown_parameter_index");
571  break;
572 
574  strcpy(name, "duplicate_finished_received");
575  break;
576 
577  case export_restriction:
578  strcpy(name, "export_restriction");
579  break;
580 
581  case protocol_version:
582  strcpy(name, "protocol_version");
583  break;
584 
586  strcpy(name, "insufficient_security");
587  break;
588 
589  case internal_error:
590  strcpy(name, "internal_error");
591  break;
592 
593  case user_canceled:
594  strcpy(name, "user_canceled");
595  break;
596 
597  case no_renegotiation:
598  strcpy(name, "no_renegotiation");
599  break;
600  }
601 }
602 
603 void pduName(char *name, int pdu)
604 {
605  switch (pdu) {
606  case ChangeCipher_PDU:
607  strcpy(name, "Change Cipher");
608  break;
609 
610  case Alert_PDU:
611  strcpy(name, "Alert");
612  break;
613 
614  case Handshake_PDU:
615  strcpy(name, "Handshake");
616  break;
617 
618  case Application_PDU:
619  strcpy(name, "Application");
620  break;
621  }
622 }
623 
624 void hsName(char *name, int handshake)
625 {
626  switch (handshake) {
627  case hello_request:
628  strcpy(name, "Hello Request");
629  break;
630 
631  case client_hello:
632  strcpy(name, "Client Hello");
633  break;
634 
635  case server_hello:
636  strcpy(name, "Server Hello");
637  break;
638 
639  case certificate:
640  strcpy(name, "Certificate");
641  break;
642 
643  case server_key_exchange:
644  strcpy(name, "Server Key Exchange");
645  break;
646 
647  case certificate_request:
648  strcpy(name, "Certificate Request");
649  break;
650 
651  case server_hello_done:
652  strcpy(name, "Server Hello Done");
653  break;
654 
655  case certificate_verify:
656  strcpy(name, "Certificate Vaerify");
657  break;
658 
659  case client_key_exchange:
660  strcpy(name, "Client Key Exchange");
661  break;
662 
663  case finished:
664  strcpy(name, "Finished");
665  break;
666  }
667 }
668 
669 /* P_hash as described in WAP WTLS section 11.3.2 */
670 Octstr *wtls_P_hash(Octstr * secret, Octstr * seed, int byteLength,
671  WTLSMachine * wtls_machine)
672 {
673  Octstr *a;
674  Octstr *aPrev;
675  Octstr *aPlusSeed;
676  Octstr *hashTemp;
677  Octstr *hashedData;
678 
679  hashedData = octstr_create("");
680 
681  /* start with A(1) = HMAC_hash(secret, seed) */
682  aPrev = octstr_duplicate(seed);
683  do {
684  /* A(i) */
685  a = wtls_hmac_hash(secret, aPrev, SHA_80);
686  aPlusSeed = octstr_cat(a, seed);
687  /* HMAC */
688  hashTemp = wtls_hmac_hash(secret, aPlusSeed, SHA_80);
689  octstr_destroy(aPlusSeed);
690  octstr_append(hashedData, hashTemp);
691  octstr_destroy(hashTemp);
692  /* Update a(i-1) */
693  octstr_destroy(aPrev);
694  aPrev = a;
695  } while (octstr_len(hashedData) < byteLength);
696 
697  octstr_destroy(aPrev);
698  return (hashedData);
699 }
700 
701 /* Pseudo Random Function (PRF) as described in WAP WTLS section 11.3.2 */
702 Octstr *wtls_calculate_prf(Octstr * secret, Octstr * label, Octstr * seed,
703  int byteLength, WTLSMachine * wtls_machine)
704 {
705  Octstr *returnOctstr;
706  Octstr *labelPlusSeed;
707 
708  /* Create label + seed */
709  labelPlusSeed = octstr_cat(label, seed);
710 
711  /* PRF(secret, label, seed) = P_hash(secret, label + seed) */
712  returnOctstr = wtls_P_hash(secret, labelPlusSeed, byteLength,
713  wtls_machine);
714 
715  /* Return the first nbytes of the hashed data */
716  octstr_truncate(returnOctstr, byteLength);
717 
718  octstr_destroy(labelPlusSeed);
719  return (returnOctstr);
720 }
721 
722 /* MAC calculation */
723 Octstr *wtls_hmac_hash(Octstr * key, Octstr * data, int algo)
724 {
725  static unsigned char final_mac[1024];
726  unsigned char *mac, *buffer, *keyString;
727  int bufferlen, keylen;
728  uint mac_len = 0;
729  Octstr *returnOctstr = NULL;
730 
731  buffer = (unsigned char *)octstr_get_cstr(data);
732  bufferlen = octstr_len(data);
733  keyString = (unsigned char *)octstr_get_cstr(key);
734  keylen = octstr_len(key);
735 
736  mac = final_mac;
737 
738  switch (algo) {
739  case SHA_0:
740  /* Do nothing */
741  break;
742 
743  case SHA_40:
744  case SHA_80:
745  case SHA_NOLIMIT:
746  HMAC(EVP_sha1(), keyString, keylen, buffer, bufferlen, mac,
747  &mac_len);
748  break;
749 
750  case SHA_XOR_40:
751  error(0, "wtls_hmac_hash: SHA_XOR_40 Mac not supported");
752  // dunno yet
753  *mac = '\0';
754  break;
755 
756  case MD5_40:
757  case MD5_80:
758  case MD5_NOLIMIT:
759  HMAC(EVP_md5(), keyString, keylen, buffer, bufferlen, mac,
760  &mac_len);
761  break;
762  }
763  returnOctstr = octstr_create_from_data((char *)mac, mac_len);
764  return (returnOctstr);
765 }
766 
767 /* Not to be confused with octstr_hash, this applies the currently set hashing
768  algorithm from wtls_machine to the supplied input data, returning a hashed
769  Octstr. If it fails, it will return a NULL pointer */
770 Octstr *wtls_hash(Octstr * inputData, WTLSMachine * wtls_machine)
771 {
772  int inputDataLength;
773  int outputDataLength;
774  unsigned char *outputDataTemp;
775  unsigned char *inputDataTemp;
776  unsigned char *tempPointer = NULL;
777  Octstr *outputData;
778 
779  inputDataLength = octstr_len(inputData);
780  outputDataLength = hash_table[wtls_machine->mac_algorithm].key_size;
781  inputDataTemp = gw_malloc(inputDataLength);
782  outputDataTemp = gw_malloc(outputDataLength);
783 
784  /* Copy the contents of inputData into inputDataTemp, ready for hashing */
785  tempPointer = (unsigned char *)octstr_get_cstr(inputData);
786  memcpy((void *)inputDataTemp, (void *)tempPointer, inputDataLength);
787 
788  /* Hash away! */
789  // Here's where we need to hash on the selected algorithm, not just the SHA-1 algorithm
790  //debug("wtls", 0, "mac algo %d", wtls_machine->mac_algorithm);
791  switch (wtls_machine->mac_algorithm) {
792  case SHA_0:
793  /* Do nothing */
794  break;
795 
796  case SHA_40:
797  case SHA_80:
798  case SHA_NOLIMIT:
799  tempPointer =
800  SHA1(inputDataTemp, inputDataLength, outputDataTemp);
801  break;
802 
803  case SHA_XOR_40:
804  // dunno yet
805  break;
806 
807  case MD5_40:
808  case MD5_80:
809  case MD5_NOLIMIT:
810  tempPointer = MD5(inputDataTemp, inputDataLength,
811  outputDataTemp);
812  break;
813  }
814  if (!tempPointer) {
815  if (wtls_machine->mac_algorithm != SHA_0)
816  error(0, "wtls_hash: Failed to hash input");
817  gw_free(outputDataTemp);
818  gw_free(inputDataTemp);
819  return (NULL);
820  }
821 
822  /* Get our output data setup */
823  outputData = octstr_create_from_data((char *)outputDataTemp,
824  outputDataLength);
825 
826  /* some algorithms don't use the full length of H */
827  octstr_truncate(outputData,
828  hash_table[wtls_machine->mac_algorithm].mac_size);
829 
830  /* Delete our allocated memory */
831  gw_free(outputDataTemp);
832  gw_free(inputDataTemp);
833 
834  /* Return the outputData */
835  return (outputData);
836 }
837 
838 Octstr *wtls_des(Octstr * data, WTLSMachine * wtls_machine, int crypt)
839 {
840  Octstr *result;
841  unsigned char *output, iv[20], c[2];
842  des_key_schedule des_ks;
843  des_cblock des_key, des_iv;
844  int i, len = octstr_len(data);
845 
846  if (!data)
847  return (NULL);
848  if (crypt == DES_ENCRYPT) {
849  memcpy(iv, octstr_get_cstr(wtls_machine->server_write_IV),
850  octstr_len(wtls_machine->server_write_IV));
851  c[0] = (wtls_machine->server_seq_num & 0xFF00) >> 8;
852  c[1] = wtls_machine->server_seq_num & 0xFF;
853  for (i = 0;
854  i <
855  bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size;
856  i++)
857  iv[i] = iv[i] ^ c[i % 2];
858  memcpy(des_iv, iv, sizeof(des_iv));
859  memcpy(des_key,
860  octstr_get_cstr(wtls_machine->server_write_enc_key),
861  sizeof(des_key));
862  } else {
863  memcpy(iv, octstr_get_cstr(wtls_machine->client_write_IV),
864  octstr_len(wtls_machine->client_write_IV));
865  c[0] = (wtls_machine->client_seq_num & 0xFF00) >> 8;
866  c[1] = wtls_machine->client_seq_num & 0xFF;
867  for (i = 0;
868  i <
869  bulk_table[wtls_machine->bulk_cipher_algorithm].iv_size;
870  i++)
871  iv[i] = iv[i] ^ c[i % 2];
872  memcpy(des_iv, iv, sizeof(des_iv));
873  memcpy(des_key,
874  octstr_get_cstr(wtls_machine->client_write_enc_key),
875  sizeof(des_key));
876  }
877  des_set_odd_parity(&des_key);
878  if (des_set_key_checked(&des_key, des_ks)) {
879  error(0, "wtls_des ~> Unable to set key schedule");
880  return (NULL);
881  }
882  output = (unsigned char *)gw_malloc((len + 1) * sizeof(unsigned char));
883  des_ncbc_encrypt((unsigned char *)octstr_get_cstr(data), output, len,
884  des_ks, &des_iv, crypt);
885  result = octstr_create_from_data((char *)output, len);
886  gw_free(output);
887 
888  return (result);
889 }
890 
891 Octstr *wtls_rc5(Octstr * data, WTLSMachine * wtls_machine, int crypt)
892 {
893  Octstr *result;
894  EVP_CIPHER_CTX ectx;
895  unsigned char ebuf[20], *output, *input, iv[20], c[2];
896  int i = 0, len = octstr_len(data);
897 
898  if (!data)
899  return (NULL);
900  EVP_CipherInit(&ectx, ALG, NULL, NULL, crypt);
901  switch (wtls_machine->bulk_cipher_algorithm) {
902  case RC5_CBC_40:
903  case RC5_CBC_56:
904  i = 12;
905  break;
906 
907  default:
908  i = 16;
909  break;
910  }
911  EVP_CIPHER_CTX_ctrl(&ectx, EVP_CTRL_SET_RC5_ROUNDS, i, NULL);
912  if (crypt == RC5_ENCRYPT) {
913  memcpy(iv, octstr_get_cstr(wtls_machine->server_write_IV),
914  octstr_len(wtls_machine->server_write_IV));
915  c[0] = (wtls_machine->server_seq_num & 0xFF00) >> 8;
916  c[1] = wtls_machine->server_seq_num & 0xFF;
917  for (i = 0; i < bulk_table[wtls_machine->bulk_cipher_algorithm].
918  iv_size; i++)
919  iv[i] = iv[i] ^ c[i % 2];
920  EVP_CipherInit(&ectx, NULL, (unsigned char *)octstr_get_cstr(
921  wtls_machine->server_write_enc_key), iv, RC5_ENCRYPT);
922  } else {
923  memcpy(iv, octstr_get_cstr(wtls_machine->client_write_IV),
924  octstr_len(wtls_machine->client_write_IV));
925  c[0] = (wtls_machine->client_seq_num & 0xFF00) >> 8;
926  c[1] = wtls_machine->client_seq_num & 0xFF;
927  for (i = 0; i < bulk_table[wtls_machine->bulk_cipher_algorithm].
928  iv_size; i++)
929  iv[i] = iv[i] ^ c[i % 2];
930  EVP_CipherInit(&ectx, NULL, (unsigned char *)octstr_get_cstr(
931  wtls_machine->client_write_enc_key), iv, RC5_DECRYPT);
932  }
933 
934  output = gw_malloc(len + 1);
935  input = (unsigned char *)octstr_get_cstr(data);
936  i = 0;
937 
938  for (i = 0; i <= len - 8; i += 8) {
939  EVP_Cipher(&ectx, ebuf, input + i, 8);
940  memmove(output + i, ebuf, 8);
941  }
942 
943  // Leftovers...
944  if (i < len) {
945  EVP_Cipher(&ectx, ebuf, input + i, len - i);
946  memmove(output + i, ebuf, len - i);
947  }
948 
949  result = octstr_create_from_data((char *)output, len);
950  gw_free(output);
951  return (result);
952 }
953 
954 static Octstr *wtls_decrypt_rsa(Octstr * encryptedData)
955 {
956  int numBytesWritten = 0, numBytesToRead = 0;
957  Octstr *decryptedData = NULL;
958  unsigned char *tempDecryptionBuffer = NULL, *tempEncryptionPointer =
959  NULL;
960 
961  /* Allocate some memory for our decryption buffer */
962  tempDecryptionBuffer = gw_malloc(RSA_size(private_key));
963 
964  /* Calculate the number of bytes to read from encryptedData
965  * when decrypting
966  * */
967  numBytesToRead = octstr_len(encryptedData);
968 
969  /* Don't write to this pointer. Ever ever ever. */
970  tempEncryptionPointer = (unsigned char *)octstr_get_cstr(encryptedData);
971 
972  /* Decrypt the data in encryptedData */
973  debug("wtls", 0, "RSA_private_decrypt: Private_key: 0x%p", private_key);
974  numBytesWritten = RSA_private_decrypt(numBytesToRead,
975  tempEncryptionPointer,
976  tempDecryptionBuffer, private_key,
977  RSA_PKCS1_PADDING);
978 
979  if (numBytesWritten == -1) {
980  tempEncryptionPointer += 2;
981  numBytesToRead -= 2;
982  numBytesWritten = RSA_private_decrypt(numBytesToRead,
983  tempEncryptionPointer,
984  tempDecryptionBuffer,
985  private_key,
986  RSA_PKCS1_PADDING);
987  }
988 
989  if (numBytesWritten > 0) {
990  /* Move the tempDecryptionBuffer to an Octstr */
991  decryptedData =
992  octstr_create_from_data((char *)tempDecryptionBuffer,
993  numBytesWritten);
994  debug("wtls", 0, "Client's secret decrypted succesfully");
995  }
996 
997  /* Deallocate the tempDecryptionBuffer */
998  gw_free(tempDecryptionBuffer);
999  /* Return the decrypted data */
1000  return decryptedData;
1001 }
1002 
1003 Octstr *wtls_decrypt_key(int type, Octstr * encryptedData)
1004 {
1005  switch (type) {
1006  case rsa_anon:
1007  case rsa:
1008  return (wtls_decrypt_rsa(encryptedData));
1009  break;
1010  default:
1011  break;
1012  }
1013  return (NULL);
1014 }
1015 
1016 void wtls_decrypt_pdu_list(WTLSMachine * wtls_machine, List * pdu_list)
1017 {
1018  int i, listlen;
1019  Octstr *decryptedData = NULL;
1021 
1022  listlen = gwlist_len(pdu_list);
1023  for (i = 0; i < listlen; i++) {
1024  payload = (wtls_Payload *) gwlist_get(pdu_list, i);
1025  wtls_machine->client_seq_num++;
1026 
1027  if (payload->cipher) {
1028  debug("wtls", 0, "Decrypting PDU %d", i);
1029  if ((decryptedData =
1030  wtls_decrypt(payload, wtls_machine))) {
1031  /* replace the data */
1033  /* get rid of MAC leftovers and wtls headers */
1034  payload->data = decryptedData;
1035  } else {
1036  gwlist_delete(pdu_list, i, 1);
1038  payload = NULL;
1039  i--;
1040  listlen--;
1041  }
1042  } else
1043  debug("wtls", 0, "PDU %d is not encrypted.", i);
1044  if (payload && octstr_get_char(payload->data, 0) == '\1')
1045  wtls_machine->client_seq_num = -1; // Change Cipher
1046  debug("wtls", 0, "Received Incoming Payload:");
1048  }
1049 }
1050 
1052 {
1053  RSA *rsaStructure = NULL;
1054  EVP_PKEY *publicKey = NULL;
1055  BIGNUM *modulus = 0, *exponent = NULL;
1056  unsigned char *tempModulusStorage = 0, *tempExponentStorage = NULL;
1057  int numbytes = 0;
1058  RSAPublicKey *returnStructure = NULL;
1059  Octstr *Modulus = NULL, *Exponent = NULL;
1060 
1061  /* First, we need to extract the RSA structure from the X509 Cert */
1062  /* Get the EVP_PKEY structure from the X509 cert */
1063  publicKey = X509_PUBKEY_get(x509_cert->cert_info->key);
1064 
1065  /* Take said EVP_PKEY structure and get the RSA component */
1066  if (EVP_PKEY_type(publicKey->type) != EVP_PKEY_RSA) {
1067  return NULL;
1068  } else {
1069  rsaStructure = publicKey->pkey.rsa;
1070  }
1071 
1072  /* Then we need to grab the exponent component from the cert */
1073  exponent = rsaStructure->e;
1074 
1075  /* We need to allocate sufficient memory to hold the exponent */
1076  numbytes = BN_num_bytes(exponent);
1077  tempExponentStorage = gw_malloc(numbytes);
1078 
1079  /* Then we get the exponent */
1080  numbytes = BN_bn2bin(exponent, tempExponentStorage);
1081 
1082  /* And finally we convert the exponent to an Octstr */
1083  Exponent = octstr_create_from_data((char *)tempExponentStorage,
1084  numbytes);
1085 
1086  /* Then we need to grab the modulus component from the cert */
1087  modulus = rsaStructure->n;
1088 
1089  /* We need to allocate sufficient memory to hold the modulus */
1090  numbytes = BN_num_bytes(modulus);
1091  tempModulusStorage = gw_malloc(numbytes);
1092 
1093  /* Then we get the modulus */
1094  numbytes = BN_bn2bin(modulus, tempModulusStorage);
1095 
1096  /* And finally we convert the modulus to an Octstr */
1097  Modulus = octstr_create_from_data((char *)tempModulusStorage, numbytes);
1098 
1099  /* Put the components into our return structure */
1100  returnStructure = gw_malloc(sizeof(RSAPublicKey));
1101  returnStructure->rsa_exponent = Exponent;
1102  returnStructure->rsa_modulus = Modulus;
1103 
1104  /* And deallocate the memory allocated for holding the modulus */
1105  gw_free(tempModulusStorage);
1106  gw_free(tempExponentStorage);
1107 
1108  return (returnStructure);
1109 }
1110 
1111 Octstr *wtls_get_certificate(void)
1112 {
1113  unsigned char **pp;
1114  unsigned char *ppStart;
1115  int amountWritten = 1260;
1116  Octstr *returnOctstr;
1117 
1118  debug("wtls_get_certificate", 0, "x509_cert : 0x%p", x509_cert);
1119  /* Convert the x509 certificate to DER-encoding */
1120  amountWritten = i2d_X509(x509_cert, NULL);
1121  debug("wtls_get_certificate", 0, "amountWritten : %d", amountWritten);
1122 
1123  /* Allocate some memory for *pp */
1124  pp = (unsigned char **)gw_malloc(sizeof(unsigned char **));
1125 
1126  /* Allocate the memory and call the same function again?!!?
1127  What an original idea :-/ */
1128  ppStart =
1129  (unsigned char *)gw_malloc(sizeof(unsigned char) * amountWritten);
1130  debug("wtls_get_certificate", 0, "x509_cert_DER_pre : 0x%p", *pp);
1131  *pp = ppStart;
1132  amountWritten = i2d_X509(x509_cert, pp);
1133 
1134  /* And we do this, because otherwise *pp is pointing to the end of the buffer. Yay */
1135  *pp = ppStart;
1136  debug("wtls_get_certificate", 0, "x509_cert_DER_post : 0x%p", *pp);
1137 
1138  /* Convert the DER-encoded char string to an octstr */
1139  returnOctstr = octstr_create_from_data((char *)*pp, amountWritten);
1140 
1141  /* Destroy the memory allocated temporarily above */
1142  gw_free(*pp);
1143 
1144  /* Destroy the memory allocated for pp as well */
1145  gw_free(pp);
1146 
1147  /* Return the octstr */
1148  return returnOctstr;
1149 }
1150 
1151 /* Chooses a CipherSuite from the list provided by the client.
1152  Returns NULL if none is acceptable. */
1153 CipherSuite *wtls_choose_ciphersuite(List * ciphersuites)
1154 {
1155  CipherSuite *currentCS;
1156  int i = 0, listLen;
1157 
1158  listLen = gwlist_len(ciphersuites);
1159 
1160  /* the first CS in the list */
1161  for (; i < listLen; i++) {
1162  /* the next CS in the list */
1163  currentCS = gwlist_get(ciphersuites, i);
1164  /* Check if we support this BulkCipher */
1165  if (currentCS->bulk_cipher_algo == DES_CBC ||
1166  (currentCS->bulk_cipher_algo <= RC5_CBC &&
1167  currentCS->bulk_cipher_algo >= RC5_CBC_40))
1168 /* if(currentCS->bulk_cipher_algo >= NULL_bulk &&
1169  currentCS->bulk_cipher_algo <= IDEA_CBC)
1170 */ {
1171  /* Check if we support this MAC algsorithm */
1172  if (currentCS->mac_algo >= SHA_0 &&
1173  currentCS->mac_algo <= MD5_NOLIMIT) {
1174  char cipher[20], mac[15];
1175 
1176  /* We can use this CipherSuite then */
1177  cipherName(cipher, currentCS->bulk_cipher_algo);
1178  macName(mac, currentCS->mac_algo);
1179  debug("wtls", 0,
1180  "wtls_choose_ciphersuite ~> Accepted cipher: %s, mac: %s (#%d/%d)",
1181  cipher, mac, i + 1, listLen);
1182  break;
1183  }
1184  }
1185  }
1186  if (i < listLen)
1187  return (currentCS);
1188  else
1189  return (NULL);
1190 }
1191 
1192 int isSupportedKeyEx(int keyExId)
1193 {
1194  int maxSupported;
1195  int i = 0, retCode = 0;
1196 
1197  maxSupported = sizeof(supportedKeyExSuite) / sizeof(KeyExchangeSuite);
1198 
1199  for (; i < maxSupported; i++) {
1200  if (keyExId == supportedKeyExSuite[i]) {
1201  retCode = 1;
1202  break;
1203  }
1204  }
1205  return retCode;
1206 }
1207 
1208 int wtls_choose_clientkeyid(List * clientKeyIds, int *algo)
1209 {
1210  int returnKey = 0;
1211  KeyExchangeId *currentKeyId = NULL;
1212  int i = 0, listLen;
1213 
1214  listLen = gwlist_len(clientKeyIds);
1215 
1216  for (; i < listLen; i++) {
1217  currentKeyId = gwlist_get(clientKeyIds, i);
1218 
1219  /* check if the current key suite is supported */
1220  if (isSupportedKeyEx(currentKeyId->key_exchange_suite)) {
1221  char key[20];
1222 
1223  *algo = currentKeyId->key_exchange_suite;
1224  returnKey = i + 1;
1225  keyName(key, *algo);
1226  debug("wtls", 0,
1227  "wtls_choose_clientkeyid ~> Accepted key algorithm: %s (#%d/%d)",
1228  key, returnKey, listLen);
1229  dump_key_exchange_id("wtls", 0, currentKeyId);
1230  break;
1231  }
1232  }
1233  return returnKey;
1234 }
1235 
1236 int wtls_choose_snmode(int snmode)
1237 {
1238  return 2;
1239 }
1240 
1241 Random *wtls_get_random(void)
1242 {
1243  Random *randomData;
1244  unsigned char bytes[13], *p;
1245  struct timeval tp;
1246 
1247  randomData = gw_malloc(sizeof(Random));
1248  gettimeofday(&tp, NULL);
1249  randomData->gmt_unix_time = tp.tv_sec;
1250  p = bytes;
1251  while (p - bytes < 12) {
1252  while (!(*p = rand_r((uint *) & tp.tv_usec))) ;
1253  p++;
1254  }
1255  bytes[12] = '\0';
1256 
1257  randomData->random_bytes = octstr_create((char *)bytes);
1258  return (randomData);
1259 }
1260 
1261 int clienthellos_are_identical(List * pdu_list, List * last_received_packet)
1262 {
1263  return 0;
1264 }
1265 
1266 int certifcateverifys_are_identical(List * pdu_list,
1267  List * last_received_packet)
1268 {
1269  return 0;
1270 }
1271 
1272 int certificates_are_identical(List * pdu_list, List * last_received_packet)
1273 {
1274  return 0;
1275 }
1276 
1277 int clientkeyexchanges_are_identical(List * pdu_list,
1278  List * last_received_packet)
1279 {
1280  return 0;
1281 }
1282 
1283 int changecipherspecs_are_identical(List * pdu_list,
1284  List * last_received_packet)
1285 {
1286  return 0;
1287 }
1288 
1289 int finishes_are_indentical(List * pdu_list, List * last_received_packet)
1290 {
1291  return 0;
1292 }
1293 
1294 int packet_contains_changecipherspec(List * pdu_list)
1295 {
1296  return 0;
1297 }
1298 
1299 int packet_contains_finished(List * pdu_list)
1300 {
1301  return 0;
1302 }
1303 
1304 int packet_contains_optional_stuff(List * pdu_list)
1305 {
1306  return 0;
1307 }
1308 
1309 int packet_is_application_data(List * pdu_list)
1310 {
1311  int i, len = gwlist_len(pdu_list);
1312  wtls_Payload *tempPayload;
1313 
1314  for (i = 0; i < len; i++) {
1315  tempPayload = gwlist_get(pdu_list, i);
1316  if (tempPayload->type != Application_PDU)
1317  return (0);
1318  }
1319  return 1;
1320 }
1321 
1322 int packet_contains_userdata(List * pdu_list)
1323 {
1324  return 1;
1325 }
1326 
1327 int packet_contains_clienthello(List * pdu_list)
1328 {
1329  int i, len = gwlist_len(pdu_list);
1330  wtls_Payload *tempPayload;
1331 
1332  for (i = 0; i < len; i++) {
1333  tempPayload = gwlist_get(pdu_list, i);
1334  if (tempPayload->type == Handshake_PDU) {
1335  if (octstr_get_char(tempPayload->data, 0) ==
1336  client_hello)
1337  return (1);
1338  }
1339  }
1340  return (0);
1341 }
1342 
1343 int is_critical_alert(List * pdu_list, WTLSMachine * wtls_machine)
1344 {
1345  int i, listlen;
1347 
1348  listlen = gwlist_len(pdu_list);
1349 
1350  for (i = 0; i < listlen; i++) {
1351  payload = gwlist_get(pdu_list, i);
1352 
1353  if (payload->type == Alert_PDU &&
1355  char alert[40];
1356 
1358  error(0, "Received critical alert (%s) in %s. Aborting",
1359  alert, stateName(wtls_machine->state));
1360  return (1);
1361  }
1362  }
1363  return 0;
1364 }
1365 
1366 int is_warning_alert(List * pdu_list, WTLSMachine * wtls_machine)
1367 {
1368  int i, listlen;
1370 
1371  listlen = gwlist_len(pdu_list);
1372 
1373  for (i = 0; i < listlen; i++) {
1374  payload = gwlist_get(pdu_list, i);
1375 
1376  if (payload->type == Alert_PDU &&
1378  char alert[40];
1379 
1381  warning(0, "Received warning (%s) in %s.", alert,
1382  stateName(wtls_machine->state));
1383  return (1);
1384  }
1385  }
1386  return 0;
1387 }
1388 
1389 /* go through the list of wtls_Payloads and add the data of any
1390  handshake message to wtls_machine->handshake_data */
1391 void add_all_handshake_data(WTLSMachine * wtls_machine, List * pdu_list)
1392 {
1393  long i, listlen;
1395 
1396  gw_assert(pdu_list != NULL);
1397 
1398  listlen = gwlist_len(pdu_list);
1399  debug("wtls", 0, "adding handshake data from %ld PDU(s)", listlen);
1400  for (i = 0; i < listlen; i++) {
1401  payload = (wtls_Payload *) gwlist_get(pdu_list, i);
1402  if (payload->type == Handshake_PDU) {
1403  octstr_insert(wtls_machine->handshake_data,
1404  payload->data,
1405  octstr_len(wtls_machine->handshake_data));
1406  debug("wtls", 0, "Data from PDU %ld:", i);
1407  octstr_dump(payload->data, 2);
1408  }
1409  }
1410 }
1411 
1412 void calculate_server_key_block(WTLSMachine * wtls_machine)
1413 {
1414  Octstr *concatenatedRandoms = NULL;
1415  Octstr *labelMaster = NULL;
1416  Octstr *key_block;
1417  int seqNum, refresh;
1418 
1419  refresh = 1 << wtls_machine->key_refresh;
1420  /* Concatenate our random data */
1421  concatenatedRandoms = octstr_create("");
1422  seqNum = wtls_machine->server_seq_num;
1423  seqNum -= wtls_machine->server_seq_num % refresh;
1424  pack_int16(concatenatedRandoms, 0, seqNum);
1425  octstr_append(concatenatedRandoms, wtls_machine->server_random);
1426  octstr_append(concatenatedRandoms, wtls_machine->client_random);
1427 
1428  /* Calculate the key_block */
1429  labelMaster = octstr_create("server expansion");
1430  key_block = wtls_calculate_prf(wtls_machine->master_secret, labelMaster,
1431  concatenatedRandoms,
1432  hash_table[wtls_machine->mac_algorithm].
1433  key_size +
1434  bulk_table[wtls_machine->
1435  bulk_cipher_algorithm].
1436  key_material +
1437  bulk_table[wtls_machine->
1438  bulk_cipher_algorithm].
1439  iv_size, wtls_machine);
1440 
1441  octstr_destroy(labelMaster);
1442  octstr_destroy(concatenatedRandoms);
1443  labelMaster = NULL;
1444 
1445  /* Break the key_block in its 3 parts */
1446  wtls_machine->server_write_MAC_secret =
1447  octstr_copy(key_block, 0,
1448  hash_table[wtls_machine->mac_algorithm].key_size);
1449  octstr_delete(key_block, 0,
1450  hash_table[wtls_machine->mac_algorithm].key_size);
1451  wtls_machine->server_write_enc_key =
1452  octstr_copy(key_block, 0,
1453  bulk_table[wtls_machine->bulk_cipher_algorithm].
1454  key_material);
1455  octstr_delete(key_block, 0,
1456  bulk_table[wtls_machine->bulk_cipher_algorithm].
1457  key_material);
1458  wtls_machine->server_write_IV =
1459  octstr_copy(key_block, 0,
1460  bulk_table[wtls_machine->bulk_cipher_algorithm].
1461  iv_size);
1462  octstr_destroy(key_block);
1463 
1464  /* Additional calculations for exportable encryption algos */
1465  if (bulk_table[wtls_machine->bulk_cipher_algorithm].is_exportable ==
1466  EXPORTABLE) {
1467  Octstr *final_server_write_enc_key = NULL;
1468  Octstr *final_server_write_IV = NULL;
1469  Octstr *emptySecret = NULL;
1470 
1471  concatenatedRandoms =
1472  octstr_cat(wtls_machine->client_random,
1473  wtls_machine->server_random);
1474  labelMaster = octstr_create("server write key");
1475  final_server_write_enc_key =
1476  wtls_calculate_prf(wtls_machine->server_write_enc_key,
1477  labelMaster, concatenatedRandoms,
1478  bulk_table[wtls_machine->
1479  bulk_cipher_algorithm].
1480  expanded_key_material, wtls_machine);
1481  octstr_destroy(labelMaster);
1482  octstr_destroy(wtls_machine->server_write_enc_key);
1483  wtls_machine->server_write_enc_key = final_server_write_enc_key;
1484  final_server_write_enc_key = NULL;
1485 
1486  concatenatedRandoms = octstr_create("");
1487  pack_int16(concatenatedRandoms, 0, seqNum);
1488  octstr_append(concatenatedRandoms, wtls_machine->client_random);
1489  octstr_append(concatenatedRandoms, wtls_machine->server_random);
1490 
1491  labelMaster = octstr_create("server write IV");
1492  emptySecret = octstr_create("");
1493  final_server_write_IV =
1494  wtls_calculate_prf(emptySecret, labelMaster,
1495  concatenatedRandoms,
1496  bulk_table[wtls_machine->
1497  bulk_cipher_algorithm].
1498  iv_size, wtls_machine);
1499  octstr_destroy(wtls_machine->server_write_IV);
1500  wtls_machine->server_write_IV = final_server_write_IV;
1501  octstr_destroy(emptySecret);
1502  octstr_destroy(labelMaster);
1503  octstr_destroy(concatenatedRandoms);
1504  }
1505 }
1506 
1507 void calculate_client_key_block(WTLSMachine * wtls_machine)
1508 {
1509  Octstr *concatenatedRandoms = NULL;
1510  Octstr *key_block;
1511  Octstr *labelMaster = NULL;
1512  int seqNum, refresh;
1513 
1514  refresh = 1 << wtls_machine->key_refresh;
1515  /* Concatenate our random data */
1516  concatenatedRandoms = octstr_create("");
1517  seqNum = wtls_machine->client_seq_num;
1518  seqNum -= wtls_machine->client_seq_num % refresh;
1519  wtls_machine->last_refresh = seqNum;
1520  pack_int16(concatenatedRandoms, 0, seqNum);
1521  octstr_append(concatenatedRandoms, wtls_machine->server_random);
1522  octstr_append(concatenatedRandoms, wtls_machine->client_random);
1523 
1524  /* Calculate the key_block */
1525  labelMaster = octstr_create("client expansion");
1526  key_block = wtls_calculate_prf(wtls_machine->master_secret, labelMaster,
1527  concatenatedRandoms,
1528  hash_table[wtls_machine->mac_algorithm].
1529  key_size +
1530  bulk_table
1531  [wtls_machine->bulk_cipher_algorithm].
1532  key_material +
1533  bulk_table[wtls_machine->
1534  bulk_cipher_algorithm].
1535  iv_size, wtls_machine);
1536 
1537  octstr_destroy(labelMaster);
1538  octstr_destroy(concatenatedRandoms);
1539  labelMaster = NULL;
1540 
1541  /* Break the key_block in its 3 parts */
1542  wtls_machine->client_write_MAC_secret = octstr_copy(key_block, 0,
1543  hash_table
1544  [wtls_machine->
1545  mac_algorithm].
1546  key_size);
1547  octstr_delete(key_block, 0,
1548  hash_table[wtls_machine->mac_algorithm].key_size);
1549  wtls_machine->client_write_enc_key =
1550  octstr_copy(key_block, 0,
1551  bulk_table[wtls_machine->bulk_cipher_algorithm].
1552  key_material);
1553  octstr_delete(key_block, 0,
1554  bulk_table[wtls_machine->bulk_cipher_algorithm].
1555  key_material);
1556  wtls_machine->client_write_IV =
1557  octstr_copy(key_block, 0,
1558  bulk_table[wtls_machine->bulk_cipher_algorithm].
1559  iv_size);
1560  octstr_destroy(key_block);
1561 
1562  /* Additional calculations for exportable encryption algos */
1563  if (bulk_table[wtls_machine->bulk_cipher_algorithm].is_exportable ==
1564  EXPORTABLE) {
1565  Octstr *final_client_write_enc_key = NULL;
1566  Octstr *final_client_write_IV = NULL;
1567  Octstr *emptySecret = NULL;
1568 
1569  concatenatedRandoms = octstr_cat(wtls_machine->client_random,
1570  wtls_machine->server_random);
1571  labelMaster = octstr_create("client write key");
1572  final_client_write_enc_key =
1573  wtls_calculate_prf(wtls_machine->client_write_enc_key,
1574  labelMaster, concatenatedRandoms,
1575  bulk_table
1576  [wtls_machine->bulk_cipher_algorithm].
1577  expanded_key_material, wtls_machine);
1578 
1579  octstr_destroy(wtls_machine->client_write_enc_key);
1580  octstr_destroy(labelMaster);
1581  wtls_machine->client_write_enc_key = final_client_write_enc_key;
1582  final_client_write_enc_key = NULL;
1583  octstr_destroy(concatenatedRandoms);
1584 
1585  concatenatedRandoms = octstr_create("");
1586  pack_int16(concatenatedRandoms, 0, seqNum);
1587  octstr_append(concatenatedRandoms, wtls_machine->client_random);
1588  octstr_append(concatenatedRandoms, wtls_machine->server_random);
1589 
1590  labelMaster = octstr_create("client write IV");
1591  emptySecret = octstr_create("");
1592  final_client_write_IV =
1593  wtls_calculate_prf(emptySecret, labelMaster,
1594  concatenatedRandoms,
1595  bulk_table
1596  [wtls_machine->bulk_cipher_algorithm].
1597  iv_size, wtls_machine);
1598  octstr_destroy(wtls_machine->client_write_IV);
1599  wtls_machine->client_write_IV = final_client_write_IV;
1600  final_client_write_IV = NULL;
1601 
1602  octstr_destroy(emptySecret);
1603  octstr_destroy(labelMaster);
1604  octstr_destroy(concatenatedRandoms);
1605  }
1606 }
1607 
1608 #endif /* HAVE_WTLS_OPENSSL */
void calculate_client_key_block(WTLSMachine *wtls_machine)
void error(int err, const char *fmt,...)
Definition: log.c:648
OPEN NULL_STATE NULL_STATE OPENING packet_is_application_data(event->u.T_Unitdata_Ind.pdu_list)
void calculate_server_key_block(WTLSMachine *wtls_machine)
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1497
CipherSuite * wtls_choose_ciphersuite(List *ciphersuites)
#define STREAM
enum pubkey_algo PublicKeyAlgorithm
void wtls_payload_destroy(wtls_Payload *payload)
gw_assert(wtls_machine->packet_to_send !=NULL)
void hsName(char *name, int handshake)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
int wtls_choose_clientkeyid(List *clientKeyIDs, int *algo)
void dump_key_exchange_id(char *dbg, int level, KeyExchangeId *keyexid)
long gwlist_len(List *list)
Definition: list.c:166
void wtls_payload_dump(wtls_Payload *msg, int level)
#define NOT_EXPORTABLE
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
Octstr * rsa_exponent
Definition: wtls_pdu.h:171
int certificates_are_identical(List *pdu_list, List *last_received_packet)
int type
Definition: smsc_cimd2.c:215
void alertName(char *name, int alert)
Octstr * wtls_decrypt_key(int type, Octstr *encryptedData)
Octstr * wtls_hash(Octstr *inputData, WTLSMachine *wtls_machine)
int changecipherspecs_are_identical(List *pdu_list, List *last_received_packet)
enum keyex_suite KeyExchangeSuite
void pduName(char *name, int pdu)
#define ALG
EXCHANGE NULL_STATE EXCHANGE is_critical_alert(event->u.T_Unitdata_Ind.pdu_list, wtls_machine)
int pack_int16(Octstr *data, long charpos, int i)
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
Octstr * data
Definition: wtls_pdu.h:469
int is_warning_alert(List *pdu_list, WTLSMachine *wtls_machine)
int key_exchange_suite
Definition: wtls_pdu.h:246
static Octstr * payload
Definition: mtbatch.c:104
int packet_contains_userdata(List *pdu_list)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
int wtls_choose_snmode(int snmode)
#define EXPORTABLE
int packet_contains_optional_stuff(List *pdu_list)
void gwlist_delete(List *list, long pos, long count)
Definition: list.c:232
void cipherName(char *name, int cipher)
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
Random * wtls_get_random(void)
Octstr * wtls_decrypt(wtls_Payload *payload, WTLSMachine *wtls_machine)
int packet_contains_finished(List *pdu_list)
#define octstr_duplicate(ostr)
Definition: octstr.h:187
#define octstr_dump(ostr, level,...)
Definition: octstr.h:564
char * name
Definition: smsc_cimd2.c:212
void warning(int err, const char *fmt,...)
Definition: log.c:660
RSAPublicKey * wtls_get_rsapublickey(void)
int certifcateverifys_are_identical(List *pdu_list, List *last_received_packet)
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
enum sig_algo SignatureAlgorithm
EXCHANGE NULL_STATE clienthellos_are_identical(event->u.T_Unitdata_Ind.pdu_list, wtls_machine->last_received_packet)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void keyName(char *name, int key)
OPEN NULL_STATE NULL_STATE OPENING OPEN NULL_STATE NULL_STATE OPEN packet_contains_clienthello(event->u.T_Unitdata_Ind.pdu_list)
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void wtls_decrypt_pdu_list(WTLSMachine *wtls_machine, List *pdu_list)
int finishes_are_indentical(List *pdu_list, List *last_received_packet)
int mac_algo
Definition: wtls_pdu.h:286
Octstr * octstr_cat(Octstr *ostr1, Octstr *ostr2)
Definition: octstr.c:383
unsigned char * data
Definition: octstr.c:120
Octstr * wtls_calculate_prf(Octstr *secret, Octstr *label, Octstr *seed, int byteLength, WTLSMachine *wtls_machine)
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1327
Octstr * rsa_modulus
Definition: wtls_pdu.h:172
Definition: wtls_pdu.h:114
Octstr * wtls_encrypt(Octstr *buffer, WTLSMachine *wtls_machine, int recordType)
EXCHANGE NULL_STATE EXCHANGE NULL_STATE OPENING COMMIT packet_contains_changecipherspec(event->u.T_Unitdata_Ind.pdu_list) &&packet_contains_finished(event -> u.T_Unitdata_Ind.pdu_list) &&packet_contains_userdata(event->u.T_Unitdata_Ind.pdu_list),
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
#define octstr_create_from_data(data, len)
Definition: octstr.h:134
int bulk_cipher_algo
Definition: wtls_pdu.h:285
Definition: list.c:102
int clientkeyexchanges_are_identical(List *pdu_list, List *last_received_packet)
#define BLOCK
void macName(char *name, int mac)
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.