1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2014 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 
wtls_decrypt(wtls_Payload * payload,WTLSMachine * wtls_machine)152 Octstr *wtls_decrypt(wtls_Payload * payload, WTLSMachine * wtls_machine)
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 */
wtls_encrypt(Octstr * buffer,WTLSMachine * wtls_machine,int recordType)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 
keyName(char * name,int key)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 
cipherName(char * name,int cipher)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 
macName(char * name,int mac)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 
alertName(char * name,int alert)474 void alertName(char *name, int alert)
475 {
476    switch (alert) {
477    case connection_close_notify:
478       strcpy(name, "connection_close_notify");
479       break;
480 
481    case session_close_notify:
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 
509    case decompression_failure:
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 
561    case key_exchange_disabled:
562       strcpy(name, "key_exchange_disabled");
563       break;
564 
565    case session_not_ready:
566       strcpy(name, "session_not_ready");
567       break;
568 
569    case unknown_parameter_index:
570       strcpy(name, "unknown_parameter_index");
571       break;
572 
573    case duplicate_finished_received:
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 
585    case insufficient_security:
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 
pduName(char * name,int pdu)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 
hsName(char * name,int handshake)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 */
wtls_P_hash(Octstr * secret,Octstr * seed,int byteLength,WTLSMachine * wtls_machine)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 */
wtls_calculate_prf(Octstr * secret,Octstr * label,Octstr * seed,int byteLength,WTLSMachine * wtls_machine)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 */
wtls_hmac_hash(Octstr * key,Octstr * data,int algo)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 */
wtls_hash(Octstr * inputData,WTLSMachine * wtls_machine)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 
wtls_des(Octstr * data,WTLSMachine * wtls_machine,int crypt)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 
wtls_rc5(Octstr * data,WTLSMachine * wtls_machine,int crypt)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 
wtls_decrypt_rsa(Octstr * encryptedData)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 
wtls_decrypt_key(int type,Octstr * encryptedData)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 
wtls_decrypt_pdu_list(WTLSMachine * wtls_machine,List * pdu_list)1016 void wtls_decrypt_pdu_list(WTLSMachine * wtls_machine, List * pdu_list)
1017 {
1018 	int i, listlen;
1019    Octstr *decryptedData = NULL;
1020 	wtls_Payload *payload;
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 */
1032 			octstr_destroy(payload->data);
1033             /* get rid of MAC leftovers and wtls headers */
1034 			payload->data = decryptedData;
1035          } else {
1036             gwlist_delete(pdu_list, i, 1);
1037             wtls_payload_destroy(payload);
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:");
1047       wtls_payload_dump(payload, 1);
1048 	}
1049 }
1050 
wtls_get_rsapublickey(void)1051 RSAPublicKey *wtls_get_rsapublickey(void)
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 
wtls_get_certificate(void)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. */
wtls_choose_ciphersuite(List * ciphersuites)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 
isSupportedKeyEx(int keyExId)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 
wtls_choose_clientkeyid(List * clientKeyIds,int * algo)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 
wtls_choose_snmode(int snmode)1236 int wtls_choose_snmode(int snmode)
1237 {
1238         return 2;
1239 }
1240 
wtls_get_random(void)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 
clienthellos_are_identical(List * pdu_list,List * last_received_packet)1261 int clienthellos_are_identical(List * pdu_list, List * last_received_packet)
1262 {
1263         return 0;
1264 }
1265 
certifcateverifys_are_identical(List * pdu_list,List * last_received_packet)1266 int certifcateverifys_are_identical(List * pdu_list,
1267                 List * last_received_packet)
1268 {
1269         return 0;
1270 }
1271 
certificates_are_identical(List * pdu_list,List * last_received_packet)1272 int certificates_are_identical(List * pdu_list, List * last_received_packet)
1273 {
1274         return 0;
1275 }
1276 
clientkeyexchanges_are_identical(List * pdu_list,List * last_received_packet)1277 int clientkeyexchanges_are_identical(List * pdu_list,
1278                  List * last_received_packet)
1279 {
1280         return 0;
1281 }
1282 
changecipherspecs_are_identical(List * pdu_list,List * last_received_packet)1283 int changecipherspecs_are_identical(List * pdu_list,
1284                 List * last_received_packet)
1285 {
1286         return 0;
1287 }
1288 
finishes_are_indentical(List * pdu_list,List * last_received_packet)1289 int finishes_are_indentical(List * pdu_list, List * last_received_packet)
1290 {
1291         return 0;
1292 }
1293 
packet_contains_changecipherspec(List * pdu_list)1294 int packet_contains_changecipherspec(List * pdu_list)
1295 {
1296         return 0;
1297 }
1298 
packet_contains_finished(List * pdu_list)1299 int packet_contains_finished(List * pdu_list)
1300 {
1301         return 0;
1302 }
1303 
packet_contains_optional_stuff(List * pdu_list)1304 int packet_contains_optional_stuff(List * pdu_list)
1305 {
1306         return 0;
1307 }
1308 
packet_is_application_data(List * pdu_list)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 
packet_contains_userdata(List * pdu_list)1322 int packet_contains_userdata(List * pdu_list)
1323 {
1324    return 1;
1325 }
1326 
packet_contains_clienthello(List * pdu_list)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 
is_critical_alert(List * pdu_list,WTLSMachine * wtls_machine)1343 int is_critical_alert(List * pdu_list, WTLSMachine * wtls_machine)
1344 {
1345    int i, listlen;
1346    wtls_Payload *payload;
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 &&
1354           octstr_get_char(payload->data, 0) >= critical_alert) {
1355          char alert[40];
1356 
1357          alertName(alert, octstr_get_char(payload->data, 1));
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 
is_warning_alert(List * pdu_list,WTLSMachine * wtls_machine)1366 int is_warning_alert(List * pdu_list, WTLSMachine * wtls_machine)
1367 {
1368    int i, listlen;
1369    wtls_Payload *payload;
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 &&
1377           octstr_get_char(payload->data, 0) == warning_alert) {
1378          char alert[40];
1379 
1380          alertName(alert, octstr_get_char(payload->data, 1));
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 */
add_all_handshake_data(WTLSMachine * wtls_machine,List * pdu_list)1391 void add_all_handshake_data(WTLSMachine * wtls_machine, List * pdu_list)
1392 {
1393 	long i, listlen;
1394 	wtls_Payload *payload;
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 
calculate_server_key_block(WTLSMachine * wtls_machine)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 
calculate_client_key_block(WTLSMachine * wtls_machine)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 */
1609