Remove some apparently-unnecessary includes of emem.h.
[metze/wireshark/wip.git] / epan / crypt / airpdcap.c
1 /* airpdcap.c
2  *
3  * Copyright (c) 2006 CACE Technologies, Davis (California)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the project nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * Alternatively, this software may be distributed under the terms of the
19  * GNU General Public License ("GPL") version 2 as published by the Free
20  * Software Foundation.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 /****************************************************************************/
36 /*      File includes                                                           */
37
38 #include "config.h"
39
40 #include <glib.h>
41
42 #include <wsutil/crc32.h>
43 #include <wsutil/rc4.h>
44 #include <wsutil/sha1.h>
45 #include <wsutil/md5.h>
46 #include <wsutil/pint.h>
47
48 #include <epan/tvbuff.h>
49 #include <epan/to_str.h>
50 #include <epan/strutil.h>
51 #include <epan/crypt/airpdcap_rijndael.h>
52
53 #include "airpdcap_system.h"
54 #include "airpdcap_int.h"
55
56 #include "airpdcap_debug.h"
57
58 #include "wep-wpadefs.h"
59
60
61 /****************************************************************************/
62
63 /****************************************************************************/
64 /*      Constant definitions                                                    */
65
66 #define AIRPDCAP_SHA_DIGEST_LEN 20
67
68 /*      EAPOL definitions                                                       */
69 /**
70  * Length of the EAPOL-Key key confirmation key (KCK) used to calculate
71  * MIC over EAPOL frame and validate an EAPOL packet (128 bits)
72  */
73 #define AIRPDCAP_WPA_KCK_LEN    16
74 /**
75  *Offset of the Key MIC in the EAPOL packet body
76  */
77 #define AIRPDCAP_WPA_MICKEY_OFFSET      77
78 /**
79  * Maximum length of the EAPOL packet (it depends on the maximum MAC
80  * frame size)
81  */
82 #define AIRPDCAP_WPA_MAX_EAPOL_LEN      4095
83 /**
84  * EAPOL Key Descriptor Version 1, used for all EAPOL-Key frames to and
85  * from a STA when neither the group nor pairwise ciphers are CCMP for
86  * Key Descriptor 1.
87  * @note
88  * Defined in 802.11i-2004, page 78
89  */
90 #define AIRPDCAP_WPA_KEY_VER_NOT_CCMP   1
91 /**
92  * EAPOL Key Descriptor Version 2, used for all EAPOL-Key frames to and
93  * from a STA when either the pairwise or the group cipher is AES-CCMP
94  * for Key Descriptor 2.
95  * /note
96  * Defined in 802.11i-2004, page 78
97  */
98 #define AIRPDCAP_WPA_KEY_VER_AES_CCMP   2
99
100 /** Define EAPOL Key Descriptor type values:  use 254 for WPA and 2 for WPA2 **/
101 #define AIRPDCAP_RSN_WPA_KEY_DESCRIPTOR 254
102 #define AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR 2
103
104 /****************************************************************************/
105
106
107
108 /****************************************************************************/
109 /*      Macro definitions                                                       */
110
111 extern const UINT32 crc32_table[256];
112 #define CRC(crc, ch)     (crc = (crc >> 8) ^ crc32_table[(crc ^ (ch)) & 0xff])
113
114 #define AIRPDCAP_GET_TK(ptk)    (ptk + 32)
115
116 /****************************************************************************/
117
118 /****************************************************************************/
119 /*      Type definitions                                                        */
120
121 /*      Internal function prototype declarations                                */
122
123 #ifdef  __cplusplus
124 extern "C" {
125 #endif
126
127 /**
128  * It is a step of the PBKDF2 (specifically the PKCS #5 v2.0) defined in
129  * the RFC 2898 to derive a key (used as PMK in WPA)
130  * @param ppbytes [IN] pointer to a password (sequence of between 8 and
131  * 63 ASCII encoded characters)
132  * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
133  * encoded characters
134  * @param iterations [IN] times to hash the password (4096 for WPA)
135  * @param count [IN] ???
136  * @param output [OUT] pointer to a preallocated buffer of
137  * AIRPDCAP_SHA_DIGEST_LEN characters that will contain a part of the key
138  */
139 static INT AirPDcapRsnaPwd2PskStep(
140     const guint8 *ppbytes,
141     const guint passLength,
142     const CHAR *ssid,
143     const size_t ssidLength,
144     const INT iterations,
145     const INT count,
146     UCHAR *output)
147     ;
148
149 /**
150  * It calculates the passphrase-to-PSK mapping reccomanded for use with
151  * RSNAs. This implementation uses the PBKDF2 method defined in the RFC
152  * 2898.
153  * @param passphrase [IN] pointer to a password (sequence of between 8 and
154  * 63 ASCII encoded characters)
155  * @param ssid [IN] pointer to the SSID string encoded in max 32 ASCII
156  * encoded characters
157  * @param output [OUT] calculated PSK (to use as PMK in WPA)
158  * @note
159  * Described in 802.11i-2004, page 165
160  */
161 static INT AirPDcapRsnaPwd2Psk(
162     const CHAR *passphrase,
163     const CHAR *ssid,
164     const size_t ssidLength,
165     UCHAR *output)
166     ;
167
168 static INT AirPDcapRsnaMng(
169     UCHAR *decrypt_data,
170     guint mac_header_len,
171     guint *decrypt_len,
172     PAIRPDCAP_KEY_ITEM key,
173     AIRPDCAP_SEC_ASSOCIATION *sa,
174     INT offset)
175     ;
176
177 static INT AirPDcapWepMng(
178     PAIRPDCAP_CONTEXT ctx,
179     UCHAR *decrypt_data,
180     guint mac_header_len,
181     guint *decrypt_len,
182     PAIRPDCAP_KEY_ITEM key,
183     AIRPDCAP_SEC_ASSOCIATION *sa,
184     INT offset)
185     ;
186
187 static INT AirPDcapRsna4WHandshake(
188     PAIRPDCAP_CONTEXT ctx,
189     const UCHAR *data,
190     AIRPDCAP_SEC_ASSOCIATION *sa,
191     PAIRPDCAP_KEY_ITEM key,
192     INT offset)
193     ;
194 /**
195  * It checks whether the specified key is corrected or not.
196  * @note
197  * For a standard WEP key the length will be changed to the standard
198  * length, and the type changed in a generic WEP key.
199  * @param key [IN] pointer to the key to validate
200  * @return
201  * - TRUE: the key contains valid fields and values
202  * - FALSE: the key has some invalid field or value
203  */
204 static INT AirPDcapValidateKey(
205     PAIRPDCAP_KEY_ITEM key)
206     ;
207
208 static INT AirPDcapRsnaMicCheck(
209     UCHAR *eapol,
210     USHORT eapol_len,
211     UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
212     USHORT key_ver)
213     ;
214
215 /**
216  * @param ctx [IN] pointer to the current context
217  * @param id [IN] id of the association (composed by BSSID and MAC of
218  * the station)
219  * @return
220  * - index of the Security Association structure if found
221  * - -1, if the specified addresses pair BSSID-STA MAC has not been found
222  */
223 static INT AirPDcapGetSa(
224     PAIRPDCAP_CONTEXT ctx,
225     AIRPDCAP_SEC_ASSOCIATION_ID *id)
226     ;
227
228 static INT AirPDcapStoreSa(
229     PAIRPDCAP_CONTEXT ctx,
230     AIRPDCAP_SEC_ASSOCIATION_ID *id)
231     ;
232
233 static const UCHAR * AirPDcapGetStaAddress(
234     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
235     ;
236
237 static const UCHAR * AirPDcapGetBssidAddress(
238     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
239     ;
240
241 static void AirPDcapRsnaPrfX(
242     AIRPDCAP_SEC_ASSOCIATION *sa,
243     const UCHAR pmk[32],
244     const UCHAR snonce[32],
245     const INT x,        /*      for TKIP 512, for CCMP 384      */
246     UCHAR *ptk)
247     ;
248
249 #ifdef  __cplusplus
250 }
251 #endif
252
253 /****************************************************************************/
254
255 /****************************************************************************/
256 /* Exported function definitions                                                */
257
258 #ifdef  __cplusplus
259 extern "C" {
260 #endif
261
262 const guint8 broadcast_mac[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
263
264
265 /* NOTE : this assumes the WPA RSN IE format.  If it were to be a generic RSN IE, then
266    we would need to change the structure since it could be variable length depending on the number
267    of unicast OUI and auth OUI. */
268 typedef struct {
269     guint8 bElementID;
270     guint8 bLength;
271     guint8  OUI[4];
272     guint16 iVersion;
273     guint8  multicastOUI[4];
274     guint16 iUnicastCount;      /* this should always be 1 for WPA client */
275     guint8  unicastOUI[4];
276     guint16 iAuthCount;         /* this should always be 1 for WPA client */
277     guint8  authOUI[4];
278     guint16 iWPAcap;
279 } RSN_IE;
280
281 #define EAPKEY_MIC_LEN  16  /* length of the MIC key for EAPoL_Key packet's MIC using MD5 */
282 #define NONCE_LEN 32
283
284 #define TKIP_GROUP_KEY_LEN 32
285 #define CCMP_GROUP_KEY_LEN 16
286 /* Minimum size of the key bytes payload for a TKIP group key in an M3 message*/
287 #define TKIP_GROUP_KEYBYTES_LEN ( sizeof(RSN_IE) + 8 + TKIP_GROUP_KEY_LEN + 6 ) /* 72 */
288 /* arbitrary upper limit */
289 #define TKIP_GROUP_KEYBYTES_LEN_MAX ( TKIP_GROUP_KEYBYTES_LEN + 28 )
290 /* Minimum size of the key bytes payload for a TKIP group key in a group key message */
291 #define TKIP_GROUP_KEYBYTES_LEN_GKEY (8 + 8 + TKIP_GROUP_KEY_LEN ) /* 48 */
292 /*  size of CCMP key bytes payload */
293 #define CCMP_GROUP_KEYBYTES_LEN ( sizeof(RSN_IE) + 8 + CCMP_GROUP_KEY_LEN + 6 ) /* 56 */
294 typedef struct {
295     guint8  type;
296     guint8  key_information[2];  /* Make this an array to avoid alignment issues */
297     guint8  key_length[2];  /* Make this an array to avoid alignment issues */
298     guint8  replay_counter[8];
299     guint8  key_nonce[NONCE_LEN];
300     guint8  key_iv[16];
301     guint8  key_sequence_counter[8];  /* also called the RSC */
302     guint8  key_id[8];
303     guint8  key_mic[EAPKEY_MIC_LEN];
304     guint8  key_data_len[2];  /* Make this an array rather than a U16 to avoid alignment shifting */
305     guint8  ie[TKIP_GROUP_KEYBYTES_LEN_MAX]; /* Make this an array to avoid alignment issues */
306 } EAPOL_RSN_KEY,  * P_EAPOL_RSN_KEY;
307 #define RSN_KEY_WITHOUT_KEYBYTES_LEN sizeof(EAPOL_RSN_KEY)-TKIP_GROUP_KEYBYTES_LEN_MAX
308 /* Minimum possible group key msg size (group key msg using CCMP as cipher)*/
309 #define GROUP_KEY_PAYLOAD_LEN_MIN RSN_KEY_WITHOUT_KEYBYTES_LEN+CCMP_GROUP_KEY_LEN
310
311 /* A note about some limitations with the WPA decryption:
312
313 Unless someone takes the time to restructure the current method used for maintaining decryption keys, there
314 will be some anomalies observed when using the decryption feature.
315
316 Currently, there is only one pairwise (unicast) key and one group (broadcast) key saved for each security association
317 (SA).  As a result, if a wireless sniffer session captures the traffic of a station (STA) associating with an AP
318 more than once, or captures a STA roaming, then you will not be able to arbitrarilly click on different encrypted
319 packets in the trace and observe their internal decrypted structure.  This is because when you click on a packet,
320 Wireshark immediately performs the decryption routine with whatever the last key used was.  It does not maintain a
321 cache of all the keys that were used by this STA/AP pairing.
322
323 However, if you are just looking at the summary lines of a capture, it will appear that everything was decrypted properly.
324 This is because when first performing a capture or initially reading a capture file, Wireshark will first
325 process the packets in order. As it encounters new EAPOL packets, it will update its internal key list with the
326 newfound key. Then it will use that key for decrypting subsequent packets. Each time a new key is found, the old key
327 is overwritten. So, if you then click on a packet that was previously decrypted properly, it might suddenly no longer
328 be decrypted because a later EAPOL key had caused the internal decryption key to be updated.
329
330 For broadcast packets, there is a clunky work-around. If the AP is using group-key rotation, you simply have to find the appropriate
331 EAPOL group key packet (usually size is 211 bytes and will have a protocol type of EAPOL and Info field of Key). If you click on it
332 and then click on the broadcast packet you are trying to decrypt, the packet will be decrypted properly. By first
333 clicking on the EAPOL packet for the group-key, you will force Wireshark to parse that packet and load the group-key it
334 contains.  That group key will then be used for decrypting all subsequent broadcast packets you click on.
335
336 Ideally, it would be best to maintain an expanding list of SA keys. Perhaps we could associate packet number ranges
337 that they apply to.  Then, whenever we need to decrypt a packet, we can determine which key to use based on whether
338 it is broadcast or unicast and within what packet number range it falls.
339
340 Either that, or store two versions of encrypted packets - the orginal packet and its successfully
341 decrypted version.  Then Wireshark wouldn't have to decrypt packets on the fly if they were already successfully decrypted.
342
343 */
344
345
346 static void
347 AirPDcapDecryptWPABroadcastKey(const EAPOL_RSN_KEY *pEAPKey, guint8  *decryption_key, PAIRPDCAP_SEC_ASSOCIATION sa, gboolean group_hshake)
348 {
349     guint8  new_key[32];
350     guint8 key_version;
351     guint8  *szEncryptedKey;
352     guint16 key_bytes_len = 0; /* Length of the total key data field */
353     guint16 key_len = 0;       /* Actual group key length */
354     static AIRPDCAP_KEY_ITEM dummy_key; /* needed in case AirPDcapRsnaMng() wants the key structure */
355
356     /* We skip verifying the MIC of the key. If we were implementing a WPA supplicant we'd want to verify, but for a sniffer it's not needed. */
357
358     /* Preparation for decrypting the group key -  determine group key data length */
359     /* depending on whether the pairwise key is TKIP or AES encryption key */
360     key_version = AIRPDCAP_EAP_KEY_DESCR_VER(pEAPKey->key_information[1]);
361     if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){
362         /* TKIP */
363         key_bytes_len = pntoh16(pEAPKey->key_length);
364     }else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
365         /* AES */
366         key_bytes_len = pntoh16(pEAPKey->key_data_len);
367     }
368
369     if (key_bytes_len > TKIP_GROUP_KEYBYTES_LEN_MAX || key_bytes_len == 0) { /* Don't read past the end of pEAPKey->ie */
370         return;
371     }
372
373     /* Encrypted key is in the information element field of the EAPOL key packet */
374     szEncryptedKey = (guint8 *)g_memdup(pEAPKey->ie, key_bytes_len);
375
376     DEBUG_DUMP("Encrypted Broadcast key:", szEncryptedKey, key_bytes_len);
377     DEBUG_DUMP("KeyIV:", pEAPKey->key_iv, 16);
378     DEBUG_DUMP("decryption_key:", decryption_key, 16);
379
380     /* Build the full decryption key based on the IV and part of the pairwise key */
381     memcpy(new_key, pEAPKey->key_iv, 16);
382     memcpy(new_key+16, decryption_key, 16);
383     DEBUG_DUMP("FullDecrKey:", new_key, 32);
384
385     /* As we have no concept of the prior association request at this point, we need to deduce the     */
386     /* group key cipher from the length of the key bytes. In WPA this is straightforward as the        */
387     /* keybytes just contain the GTK, and the GTK is only in the group handshake, NOT the M3.          */
388     /* In WPA2 its a little more tricky as the M3 keybytes contain an RSN_IE, but the group handshake  */
389     /* does not. Also there are other (variable length) items in the keybytes which we need to account */
390     /* for to determine the true key length, and thus the group cipher.                                */
391
392     if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){
393         guint8 dummy[256];
394         /* TKIP key */
395         /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */
396         /* group key is decrypted using RC4.  Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */
397
398         rc4_state_struct rc4_state;
399
400         /* The WPA group key just contains the GTK bytes so deducing the type is straightforward   */
401         /* Note - WPA M3 doesn't contain a group key so we'll only be here for the group handshake */
402         sa->wpa.key_ver = (key_bytes_len >=TKIP_GROUP_KEY_LEN)?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
403
404         crypt_rc4_init(&rc4_state, new_key, sizeof(new_key));
405
406         /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */
407         crypt_rc4(&rc4_state, dummy, 256);
408         crypt_rc4(&rc4_state, szEncryptedKey, key_bytes_len);
409
410     } else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){
411         /* AES CCMP key */
412
413         guint8 key_found;
414         guint16 key_index;
415         guint8 *decrypted_data;
416
417         /* If this EAPOL frame is part of a separate group key handshake then this contains no    */
418         /* RSN IE, so we can deduct that from the calculation.                                    */
419         if (group_hshake)
420             sa->wpa.key_ver = (key_bytes_len >= (TKIP_GROUP_KEYBYTES_LEN_GKEY))?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
421         else
422             sa->wpa.key_ver = (key_bytes_len >= (TKIP_GROUP_KEYBYTES_LEN))?AIRPDCAP_WPA_KEY_VER_NOT_CCMP:AIRPDCAP_WPA_KEY_VER_AES_CCMP;
423
424         /* This storage is needed for the AES_unwrap function */
425         decrypted_data = (guint8 *) g_malloc(key_bytes_len);
426
427         AES_unwrap(decryption_key, 16, szEncryptedKey,  key_bytes_len, decrypted_data);
428
429         /* With WPA2 what we get after Broadcast Key decryption is an actual RSN structure.
430            The key itself is stored as a GTK KDE
431            WPA2 IE (1 byte) id = 0xdd, length (1 byte), GTK OUI (4 bytes), key index (1 byte) and 1 reserved byte. Thus we have to
432            pass pointer to the actual key with 8 bytes offset */
433
434         key_found = FALSE;
435         key_index = 0;
436         while(key_index < key_bytes_len && !key_found){
437             guint8 rsn_id;
438
439             /* Get RSN ID */
440             rsn_id = decrypted_data[key_index];
441
442             if (rsn_id != 0xdd){
443                 key_index += decrypted_data[key_index+1]+2;
444             }else{
445                 key_found = TRUE;
446             }
447         }
448
449         if (key_found){
450             /* Skip over the GTK header info, and don't copy past the end of the encrypted data */
451             memcpy(szEncryptedKey, decrypted_data+key_index+8, key_bytes_len-key_index-8);
452         }
453
454         g_free(decrypted_data);
455     }
456
457     key_len = (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)?TKIP_GROUP_KEY_LEN:CCMP_GROUP_KEY_LEN;
458
459     /* Decrypted key is now in szEncryptedKey with len of key_len */
460     DEBUG_DUMP("Broadcast key:", szEncryptedKey, key_len);
461
462     /* Load the proper key material info into the SA */
463     sa->key = &dummy_key;  /* we just need key to be not null because it is checked in AirPDcapRsnaMng().  The WPA key materials are actually in the .wpa structure */
464     sa->validKey = TRUE;
465
466     /* Since this is a GTK and its size is only 32 bytes (vs. the 64 byte size of a PTK), we fake it and put it in at a 32-byte offset so the  */
467     /* AirPDcapRsnaMng() function will extract the right piece of the GTK for decryption. (The first 16 bytes of the GTK are used for decryption.) */
468     memset(sa->wpa.ptk, 0, sizeof(sa->wpa.ptk));
469     memcpy(sa->wpa.ptk+32, szEncryptedKey, key_len);
470     g_free(szEncryptedKey);
471 }
472
473
474 /* Return a pointer the the requested SA. If it doesn't exist create it. */
475 static PAIRPDCAP_SEC_ASSOCIATION
476 AirPDcapGetSaPtr(
477     PAIRPDCAP_CONTEXT ctx,
478     AIRPDCAP_SEC_ASSOCIATION_ID *id)
479 {
480     int sa_index;
481
482     /* search for a cached Security Association for supplied BSSID and STA MAC  */
483     if ((sa_index=AirPDcapGetSa(ctx, id))==-1) {
484         /* create a new Security Association if it doesn't currently exist      */
485         if ((sa_index=AirPDcapStoreSa(ctx, id))==-1) {
486             return NULL;
487         }
488     }
489     /* get the Security Association structure   */
490     return &ctx->sa[sa_index];
491 }
492
493 static INT AirPDcapScanForGroupKey(
494     PAIRPDCAP_CONTEXT ctx,
495     const guint8 *data,
496     const guint mac_header_len,
497     const guint tot_len
498 )
499 {
500     const UCHAR *addr;
501     AIRPDCAP_SEC_ASSOCIATION_ID id;
502     guint bodyLength;
503     PAIRPDCAP_SEC_ASSOCIATION sta_sa;
504     PAIRPDCAP_SEC_ASSOCIATION sa;
505     int offset = 0;
506     const guint8 dot1x_header[] = {
507         0xAA,             /* DSAP=SNAP */
508         0xAA,             /* SSAP=SNAP */
509         0x03,             /* Control field=Unnumbered frame */
510         0x00, 0x00, 0x00, /* Org. code=encaps. Ethernet */
511         0x88, 0x8E        /* Type: 802.1X authentication */
512     };
513
514     const EAPOL_RSN_KEY *pEAPKey;
515 #ifdef _DEBUG
516     CHAR msgbuf[255];
517 #endif
518     AIRPDCAP_DEBUG_TRACE_START("AirPDcapScanForGroupKey");
519
520     if (mac_header_len + GROUP_KEY_PAYLOAD_LEN_MIN > tot_len) {
521         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Message too short", AIRPDCAP_DEBUG_LEVEL_3);
522         return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
523     }
524
525     /* cache offset in the packet data */
526     offset = mac_header_len;
527
528     /* check if the packet has an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24) */
529     if (memcmp(data+offset, dot1x_header, 8) == 0) {
530
531         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
532
533         /* skip LLC header */
534         offset+=8;
535
536
537         /* check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25) */
538         if (data[offset+1]!=3) {
539             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_3);
540             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
541         }
542
543         /* get and check the body length (IEEE 802.1X-2004, pg. 25) */
544         bodyLength=pntoh16(data+offset+2);
545         if ((tot_len-offset-4) > bodyLength) {
546             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "EAPOL body too short", AIRPDCAP_DEBUG_LEVEL_3);
547             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
548         }
549
550         /* skip EAPOL MPDU and go to the first byte of the body */
551         offset+=4;
552
553         pEAPKey = (const EAPOL_RSN_KEY *) (data+offset);
554
555         /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
556         if (/*pEAPKey->type!=0x1 &&*/ /* RC4 Key Descriptor Type (deprecated) */
557             pEAPKey->type != AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR &&             /* IEEE 802.11 Key Descriptor Type  (WPA2) */
558             pEAPKey->type != AIRPDCAP_RSN_WPA_KEY_DESCRIPTOR)           /* 254 = RSN_KEY_DESCRIPTOR - WPA,              */
559         {
560             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_3);
561             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
562         }
563
564         /* start with descriptor body */
565         offset+=1;
566
567         /* Verify the bitfields: Key = 0(groupwise) Mic = 1 Ack = 1 Secure = 1 */
568         if (AIRPDCAP_EAP_KEY(data[offset+1])!=0 ||
569             AIRPDCAP_EAP_ACK(data[offset+1])!=1 ||
570             AIRPDCAP_EAP_MIC(data[offset]) != 1 ||
571             AIRPDCAP_EAP_SEC(data[offset]) != 1){
572
573             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Key bitfields not correct", AIRPDCAP_DEBUG_LEVEL_3);
574             return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
575         }
576
577         /* get BSSID */
578         if ( (addr=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
579             memcpy(id.bssid, addr, AIRPDCAP_MAC_LEN);
580 #ifdef _DEBUG
581             sprintf(msgbuf, "BSSID: %2X.%2X.%2X.%2X.%2X.%2X\t", id.bssid[0],id.bssid[1],id.bssid[2],id.bssid[3],id.bssid[4],id.bssid[5]);
582 #endif
583             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
584         } else {
585             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
586             return AIRPDCAP_RET_REQ_DATA;
587         }
588
589         /* force STA address to be the broadcast MAC so we create an SA for the groupkey */
590         memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
591
592         /* get the Security Association structure for the broadcast MAC and AP */
593         sa = AirPDcapGetSaPtr(ctx, &id);
594         if (sa == NULL){
595             return AIRPDCAP_RET_UNSUCCESS;
596         }
597
598         /* Get the SA for the STA, since we need its pairwise key to decrpyt the group key */
599
600         /* get STA address */
601         if ( (addr=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
602             memcpy(id.sta, addr, AIRPDCAP_MAC_LEN);
603 #ifdef _DEBUG
604             sprintf(msgbuf, "ST_MAC: %2X.%2X.%2X.%2X.%2X.%2X\t", id.sta[0],id.sta[1],id.sta[2],id.sta[3],id.sta[4],id.sta[5]);
605 #endif
606             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
607         } else {
608             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
609             return AIRPDCAP_RET_REQ_DATA;
610         }
611
612         sta_sa = AirPDcapGetSaPtr(ctx, &id);
613         if (sta_sa == NULL){
614             return AIRPDCAP_RET_UNSUCCESS;
615         }
616
617         /* Extract the group key and install it in the SA */
618         AirPDcapDecryptWPABroadcastKey(pEAPKey, sta_sa->wpa.ptk+16, sa, TRUE);
619
620     }else{
621         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapScanForGroupKey", "Skipping: not an EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
622     }
623
624     AIRPDCAP_DEBUG_TRACE_END("AirPDcapScanForGroupKey");
625     return 0;
626 }
627
628
629 INT AirPDcapPacketProcess(
630     PAIRPDCAP_CONTEXT ctx,
631     const guint8 *data,
632     const guint mac_header_len,
633     const guint tot_len,
634     UCHAR *decrypt_data,
635     guint *decrypt_len,
636     PAIRPDCAP_KEY_ITEM key,
637     gboolean mngHandshake,
638     gboolean mngDecrypt)
639 {
640     const UCHAR *addr;
641     AIRPDCAP_SEC_ASSOCIATION_ID id;
642     PAIRPDCAP_SEC_ASSOCIATION sa;
643     int offset = 0;
644     guint bodyLength;
645     const guint8 dot1x_header[] = {
646         0xAA,             /* DSAP=SNAP */
647         0xAA,             /* SSAP=SNAP */
648         0x03,             /* Control field=Unnumbered frame */
649         0x00, 0x00, 0x00, /* Org. code=encaps. Ethernet */
650         0x88, 0x8E        /* Type: 802.1X authentication */
651     };
652
653     const guint8 bt_dot1x_header[] = {
654         0xAA,             /* DSAP=SNAP */
655         0xAA,             /* SSAP=SNAP */
656         0x03,             /* Control field=Unnumbered frame */
657         0x00, 0x19, 0x58, /* Org. code=Bluetooth SIG */
658         0x00, 0x03        /* Type: Bluetooth Security */
659     };
660
661 #ifdef _DEBUG
662     CHAR msgbuf[255];
663 #endif
664
665     AIRPDCAP_DEBUG_TRACE_START("AirPDcapPacketProcess");
666
667     if (ctx==NULL) {
668         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
669         AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
670         return AIRPDCAP_RET_UNSUCCESS;
671     }
672     if (data==NULL || tot_len==0) {
673         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "NULL data or length=0", AIRPDCAP_DEBUG_LEVEL_5);
674         AIRPDCAP_DEBUG_TRACE_END("AirPDcapPacketProcess");
675         return AIRPDCAP_RET_UNSUCCESS;
676     }
677
678     /* check if the packet is of data type */
679     if (AIRPDCAP_TYPE(data[0])!=AIRPDCAP_TYPE_DATA) {
680         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "not data packet", AIRPDCAP_DEBUG_LEVEL_5);
681         return AIRPDCAP_RET_NO_DATA;
682     }
683
684     /* check correct packet size, to avoid wrong elaboration of encryption algorithms */
685     if (tot_len < (UINT)(mac_header_len+AIRPDCAP_CRYPTED_DATA_MINLEN)) {
686         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "minimum length violated", AIRPDCAP_DEBUG_LEVEL_5);
687         return AIRPDCAP_RET_WRONG_DATA_SIZE;
688     }
689
690     /* get BSSID */
691     if ( (addr=AirPDcapGetBssidAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
692         memcpy(id.bssid, addr, AIRPDCAP_MAC_LEN);
693 #ifdef _DEBUG
694         sprintf(msgbuf, "BSSID: %2X.%2X.%2X.%2X.%2X.%2X\t", id.bssid[0],id.bssid[1],id.bssid[2],id.bssid[3],id.bssid[4],id.bssid[5]);
695 #endif
696         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
697     } else {
698         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "BSSID not found", AIRPDCAP_DEBUG_LEVEL_5);
699         return AIRPDCAP_RET_REQ_DATA;
700     }
701
702     /* get STA address */
703     if ( (addr=AirPDcapGetStaAddress((const AIRPDCAP_MAC_FRAME_ADDR4 *)(data))) != NULL) {
704         memcpy(id.sta, addr, AIRPDCAP_MAC_LEN);
705 #ifdef _DEBUG
706         sprintf(msgbuf, "ST_MAC: %2X.%2X.%2X.%2X.%2X.%2X\t", id.sta[0],id.sta[1],id.sta[2],id.sta[3],id.sta[4],id.sta[5]);
707 #endif
708         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
709     } else {
710         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "SA not found", AIRPDCAP_DEBUG_LEVEL_5);
711         return AIRPDCAP_RET_REQ_DATA;
712     }
713
714     /* get the Security Association structure for the STA and AP */
715     sa = AirPDcapGetSaPtr(ctx, &id);
716     if (sa == NULL){
717         return AIRPDCAP_RET_UNSUCCESS;
718     }
719
720     /* cache offset in the packet data (to scan encryption data) */
721     offset = mac_header_len;
722
723     /* check if data is encrypted (use the WEP bit in the Frame Control field) */
724     if (AIRPDCAP_WEP(data[1])==0)
725     {
726         if (mngHandshake) {
727             /* data is sent in cleartext, check if is an authentication message or end the process */
728             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Unencrypted data", AIRPDCAP_DEBUG_LEVEL_3);
729
730             /* check if the packet as an LLC header and the packet is 802.1X authentication (IEEE 802.1X-2004, pg. 24) */
731             if (memcmp(data+offset, dot1x_header, 8) == 0 || memcmp(data+offset, bt_dot1x_header, 8) == 0) {
732                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Authentication: EAPOL packet", AIRPDCAP_DEBUG_LEVEL_3);
733
734                 /* skip LLC header */
735                 offset+=8;
736
737                 /* check the version of the EAPOL protocol used (IEEE 802.1X-2004, pg. 24) */
738                 /* TODO EAPOL protocol version to check? */
739 #if 0
740                 if (data[offset]!=2) {
741                     AIRPDCAP_DEBUG_PRINT_LINE("EAPOL protocol version not recognized", AIRPDCAP_DEBUG_LEVEL_5);
742                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
743                 }
744 #endif
745
746                 /* check if the packet is a EAPOL-Key (0x03) (IEEE 802.1X-2004, pg. 25) */
747                 if (data[offset+1]!=3) {
748                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not EAPOL-Key", AIRPDCAP_DEBUG_LEVEL_5);
749                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
750                 }
751
752                 /* get and check the body length (IEEE 802.1X-2004, pg. 25) */
753                 bodyLength=pntoh16(data+offset+2);
754                 if ((tot_len-offset-4) < bodyLength) {
755                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "EAPOL body too short", AIRPDCAP_DEBUG_LEVEL_5);
756                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
757                 }
758
759                 /* skip EAPOL MPDU and go to the first byte of the body */
760                 offset+=4;
761
762                 /* check if the key descriptor type is valid (IEEE 802.1X-2004, pg. 27) */
763                 if (/*data[offset]!=0x1 &&*/    /* RC4 Key Descriptor Type (deprecated) */
764                     data[offset]!=0x2 &&        /* IEEE 802.11 Key Descriptor Type      */
765                     data[offset]!=0xFE)         /* TODO what's this value???            */
766                 {
767                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Not valid key descriptor type", AIRPDCAP_DEBUG_LEVEL_5);
768                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
769                 }
770
771                 /* start with descriptor body */
772                 offset+=1;
773
774                 /* manage the 4-way handshake to define the key */
775                 return AirPDcapRsna4WHandshake(ctx, data, sa, key, offset);
776             } else {
777                 /* cleartext message, not authentication */
778                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "No authentication data", AIRPDCAP_DEBUG_LEVEL_5);
779                 return AIRPDCAP_RET_NO_DATA_ENCRYPTED;
780             }
781         }
782     } else {
783         if (mngDecrypt) {
784
785             if (decrypt_data==NULL)
786                 return AIRPDCAP_RET_UNSUCCESS;
787
788             /* create new header and data to modify */
789             *decrypt_len = tot_len;
790             memcpy(decrypt_data, data, *decrypt_len);
791
792             /* encrypted data */
793             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "Encrypted data", AIRPDCAP_DEBUG_LEVEL_3);
794
795             /* check the Extension IV to distinguish between WEP encryption and WPA encryption */
796             /* refer to IEEE 802.11i-2004, 8.2.1.2, pag.35 for WEP,    */
797             /*          IEEE 802.11i-2004, 8.3.2.2, pag. 45 for TKIP,  */
798             /*          IEEE 802.11i-2004, 8.3.3.2, pag. 57 for CCMP   */
799             if (AIRPDCAP_EXTIV(data[offset+3])==0) {
800                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "WEP encryption", AIRPDCAP_DEBUG_LEVEL_3);
801                 return AirPDcapWepMng(ctx, decrypt_data, mac_header_len, decrypt_len, key, sa, offset);
802             } else {
803                 INT status;
804                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "TKIP or CCMP encryption", AIRPDCAP_DEBUG_LEVEL_3);
805
806                 /* If index >= 1, then use the group key.  This will not work if the AP is using
807                    more than one group key simultaneously.  I've not seen this in practice, however.
808                    Usually an AP will rotate between the two key index values of 1 and 2 whenever
809                    it needs to change the group key to be used. */
810                 if (AIRPDCAP_KEY_INDEX(data[offset+3])>=1){
811
812                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", "The key index = 1. This is encrypted with a group key.", AIRPDCAP_DEBUG_LEVEL_3);
813
814                     /* force STA address to broadcast MAC so we load the SA for the groupkey */
815                     memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
816
817 #ifdef _DEBUG
818                     sprintf(msgbuf, "ST_MAC: %2X.%2X.%2X.%2X.%2X.%2X\t", id.sta[0],id.sta[1],id.sta[2],id.sta[3],id.sta[4],id.sta[5]);
819                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapPacketProcess", msgbuf, AIRPDCAP_DEBUG_LEVEL_3);
820 #endif
821
822                     /* search for a cached Security Association for current BSSID and broadcast MAC */
823                     sa = AirPDcapGetSaPtr(ctx, &id);
824                     if (sa == NULL){
825                         return AIRPDCAP_RET_UNSUCCESS;
826                     }
827                 }
828
829                 /* Decrypt the packet using the appropriate SA */
830                 status = AirPDcapRsnaMng(decrypt_data, mac_header_len, decrypt_len, key, sa, offset);
831
832                 /* If we successfully decrypted a packet, scan it to see if it contains a group key handshake.
833                    The group key handshake could be sent at any time the AP wants to change the key (such as when
834                    it is using key rotation) so we must scan every packet. */
835                 if (status == AIRPDCAP_RET_SUCCESS)
836                     AirPDcapScanForGroupKey(ctx, decrypt_data, mac_header_len, *decrypt_len);
837                 return status;
838             }
839         }
840     }
841
842     return AIRPDCAP_RET_UNSUCCESS;
843 }
844
845 INT AirPDcapSetKeys(
846     PAIRPDCAP_CONTEXT ctx,
847     AIRPDCAP_KEY_ITEM keys[],
848     const size_t keys_nr)
849 {
850     INT i;
851     INT success;
852     AIRPDCAP_DEBUG_TRACE_START("AirPDcapSetKeys");
853
854     if (ctx==NULL || keys==NULL) {
855         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "NULL context or NULL keys array", AIRPDCAP_DEBUG_LEVEL_3);
856         AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
857         return 0;
858     }
859
860     if (keys_nr>AIRPDCAP_MAX_KEYS_NR) {
861         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Keys number greater than maximum", AIRPDCAP_DEBUG_LEVEL_3);
862         AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
863         return 0;
864     }
865
866     /* clean key and SA collections before setting new ones */
867     AirPDcapInitContext(ctx);
868
869     /* check and insert keys */
870     for (i=0, success=0; i<(INT)keys_nr; i++) {
871         if (AirPDcapValidateKey(keys+i)==TRUE) {
872             if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD) {
873                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PWD key", AIRPDCAP_DEBUG_LEVEL_4);
874                 AirPDcapRsnaPwd2Psk(keys[i].UserPwd.Passphrase, keys[i].UserPwd.Ssid, keys[i].UserPwd.SsidLen, keys[i].KeyData.Wpa.Psk);
875             }
876 #ifdef _DEBUG
877             else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK) {
878                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WPA-PMK key", AIRPDCAP_DEBUG_LEVEL_4);
879             } else if (keys[i].KeyType==AIRPDCAP_KEY_TYPE_WEP) {
880                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a WEP key", AIRPDCAP_DEBUG_LEVEL_4);
881             } else {
882                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapSetKeys", "Set a key", AIRPDCAP_DEBUG_LEVEL_4);
883             }
884 #endif
885             memcpy(&ctx->keys[success], &keys[i], sizeof(keys[i]));
886             success++;
887         }
888     }
889
890     ctx->keys_nr=success;
891
892     AIRPDCAP_DEBUG_TRACE_END("AirPDcapSetKeys");
893     return success;
894 }
895
896 static void
897 AirPDcapCleanKeys(
898     PAIRPDCAP_CONTEXT ctx)
899 {
900     AIRPDCAP_DEBUG_TRACE_START("AirPDcapCleanKeys");
901
902     if (ctx==NULL) {
903         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
904         AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
905         return;
906     }
907
908     memset(ctx->keys, 0, sizeof(AIRPDCAP_KEY_ITEM) * AIRPDCAP_MAX_KEYS_NR);
909
910     ctx->keys_nr=0;
911
912     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapCleanKeys", "Keys collection cleaned!", AIRPDCAP_DEBUG_LEVEL_5);
913     AIRPDCAP_DEBUG_TRACE_END("AirPDcapCleanKeys");
914 }
915
916 static void
917 AirPDcapRecurseCleanSA(
918     PAIRPDCAP_SEC_ASSOCIATION sa)
919 {
920     if (sa->next != NULL) {
921         AirPDcapRecurseCleanSA(sa->next);
922         g_free(sa->next);
923         sa->next = NULL;
924     }
925 }
926
927 static void
928 AirPDcapCleanSecAssoc(
929     PAIRPDCAP_CONTEXT ctx)
930 {
931     PAIRPDCAP_SEC_ASSOCIATION psa;
932     int i;
933
934     for (psa = ctx->sa, i = 0; i < AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR; i++, psa++) {
935         /* To iterate is human, to recurse, divine */
936         AirPDcapRecurseCleanSA(psa);
937     }
938 }
939
940 INT AirPDcapGetKeys(
941     const PAIRPDCAP_CONTEXT ctx,
942     AIRPDCAP_KEY_ITEM keys[],
943     const size_t keys_nr)
944 {
945     UINT i;
946     UINT j;
947     AIRPDCAP_DEBUG_TRACE_START("AirPDcapGetKeys");
948
949     if (ctx==NULL) {
950         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
951         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
952         return 0;
953     } else if (keys==NULL) {
954         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "NULL keys array", AIRPDCAP_DEBUG_LEVEL_5);
955         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
956         return (INT)ctx->keys_nr;
957     } else {
958         for (i=0, j=0; i<ctx->keys_nr && i<keys_nr && i<AIRPDCAP_MAX_KEYS_NR; i++) {
959             memcpy(&keys[j], &ctx->keys[i], sizeof(keys[j]));
960             j++;
961             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapGetKeys", "Got a key", AIRPDCAP_DEBUG_LEVEL_5);
962         }
963
964         AIRPDCAP_DEBUG_TRACE_END("AirPDcapGetKeys");
965         return j;
966     }
967 }
968
969 /*
970  * XXX - This won't be reliable if a packet containing SSID "B" shows
971  * up in the middle of a 4-way handshake for SSID "A".
972  * We should probably use a small array or hash table to keep multiple
973  * SSIDs.
974  */
975 INT AirPDcapSetLastSSID(
976     PAIRPDCAP_CONTEXT ctx,
977     CHAR *pkt_ssid,
978     size_t pkt_ssid_len)
979 {
980     if (!ctx || !pkt_ssid || pkt_ssid_len < 1 || pkt_ssid_len > WPA_SSID_MAX_SIZE)
981         return AIRPDCAP_RET_UNSUCCESS;
982
983     memcpy(ctx->pkt_ssid, pkt_ssid, pkt_ssid_len);
984     ctx->pkt_ssid_len = pkt_ssid_len;
985
986     return AIRPDCAP_RET_SUCCESS;
987 }
988
989 INT AirPDcapInitContext(
990     PAIRPDCAP_CONTEXT ctx)
991 {
992     AIRPDCAP_DEBUG_TRACE_START("AirPDcapInitContext");
993
994     if (ctx==NULL) {
995         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
996         AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
997         return AIRPDCAP_RET_UNSUCCESS;
998     }
999
1000     AirPDcapCleanKeys(ctx);
1001
1002     ctx->first_free_index=0;
1003     ctx->index=-1;
1004     ctx->sa_index=-1;
1005     ctx->pkt_ssid_len = 0;
1006
1007     memset(ctx->sa, 0, AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR * sizeof(AIRPDCAP_SEC_ASSOCIATION));
1008
1009     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapInitContext", "Context initialized!", AIRPDCAP_DEBUG_LEVEL_5);
1010     AIRPDCAP_DEBUG_TRACE_END("AirPDcapInitContext");
1011     return AIRPDCAP_RET_SUCCESS;
1012 }
1013
1014 INT AirPDcapDestroyContext(
1015     PAIRPDCAP_CONTEXT ctx)
1016 {
1017     AIRPDCAP_DEBUG_TRACE_START("AirPDcapDestroyContext");
1018
1019     if (ctx==NULL) {
1020         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "NULL context", AIRPDCAP_DEBUG_LEVEL_5);
1021         AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
1022         return AIRPDCAP_RET_UNSUCCESS;
1023     }
1024
1025     AirPDcapCleanKeys(ctx);
1026     AirPDcapCleanSecAssoc(ctx);
1027
1028     ctx->first_free_index=0;
1029     ctx->index=-1;
1030     ctx->sa_index=-1;
1031
1032     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapDestroyContext", "Context destroyed!", AIRPDCAP_DEBUG_LEVEL_5);
1033     AIRPDCAP_DEBUG_TRACE_END("AirPDcapDestroyContext");
1034     return AIRPDCAP_RET_SUCCESS;
1035 }
1036
1037 #ifdef __cplusplus
1038 }
1039 #endif
1040
1041 /****************************************************************************/
1042
1043 /****************************************************************************/
1044 /* Internal function definitions                                         */
1045
1046 #ifdef __cplusplus
1047 extern "C" {
1048 #endif
1049
1050 static INT
1051 AirPDcapRsnaMng(
1052     UCHAR *decrypt_data,
1053     guint mac_header_len,
1054     guint *decrypt_len,
1055     PAIRPDCAP_KEY_ITEM key,
1056     AIRPDCAP_SEC_ASSOCIATION *sa,
1057     INT offset)
1058 {
1059     INT ret_value=1;
1060     UCHAR *try_data;
1061     guint try_data_len = *decrypt_len;
1062
1063     if (sa->key==NULL) {
1064         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "No key associated", AIRPDCAP_DEBUG_LEVEL_3);
1065         return AIRPDCAP_RET_REQ_DATA;
1066     }
1067     if (sa->validKey==FALSE) {
1068         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Key not yet valid", AIRPDCAP_DEBUG_LEVEL_3);
1069         return AIRPDCAP_RET_UNSUCCESS;
1070     }
1071
1072     /* allocate a temp buffer for the decryption loop */
1073     try_data=(UCHAR *)g_malloc(try_data_len);
1074
1075     /* start of loop added by GCS */
1076     for(/* sa */; sa != NULL ;sa=sa->next) {
1077
1078         if (*decrypt_len > try_data_len) {
1079             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Invalid decryption length", AIRPDCAP_DEBUG_LEVEL_3);
1080             g_free(try_data);
1081             return AIRPDCAP_RET_UNSUCCESS;
1082         }
1083
1084        /* copy the encrypted data into a temp buffer */
1085        memcpy(try_data, decrypt_data, *decrypt_len);
1086
1087        if (sa->wpa.key_ver==1) {
1088            /* CCMP -> HMAC-MD5 is the EAPOL-Key MIC, RC4 is the EAPOL-Key encryption algorithm */
1089            AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP", AIRPDCAP_DEBUG_LEVEL_3);
1090            DEBUG_DUMP("ptk", sa->wpa.ptk, 64);
1091            DEBUG_DUMP("ptk portion used", AIRPDCAP_GET_TK(sa->wpa.ptk), 16);
1092
1093            ret_value=AirPDcapTkipDecrypt(try_data+offset, *decrypt_len-offset, try_data+AIRPDCAP_TA_OFFSET, AIRPDCAP_GET_TK(sa->wpa.ptk));
1094            if (ret_value){
1095                AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP failed!", AIRPDCAP_DEBUG_LEVEL_3);
1096                continue;
1097            }
1098
1099            AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "TKIP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1100            /* remove MIC (8bytes) and ICV (4bytes) from the end of packet */
1101            *decrypt_len-=12;
1102            break;
1103        } else {
1104            /* AES-CCMP -> HMAC-SHA1-128 is the EAPOL-Key MIC, AES wep_key wrap is the EAPOL-Key encryption algorithm */
1105            AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP", AIRPDCAP_DEBUG_LEVEL_3);
1106
1107            ret_value=AirPDcapCcmpDecrypt(try_data, mac_header_len, (INT)*decrypt_len, AIRPDCAP_GET_TK(sa->wpa.ptk));
1108            if (ret_value)
1109               continue;
1110
1111            AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "CCMP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1112            /* remove MIC (8bytes) from the end of packet */
1113            *decrypt_len-=8;
1114            break;
1115        }
1116     }
1117     /* end of loop */
1118
1119     /* none of the keys worked */
1120     if(sa == NULL) {
1121         g_free(try_data);
1122         return ret_value;
1123     }
1124
1125     if (*decrypt_len > try_data_len || *decrypt_len < 8) {
1126         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsnaMng", "Invalid decryption length", AIRPDCAP_DEBUG_LEVEL_3);
1127         g_free(try_data);
1128         return AIRPDCAP_RET_UNSUCCESS;
1129     }
1130
1131     /* copy the decrypted data into the decrypt buffer GCS*/
1132     memcpy(decrypt_data, try_data, *decrypt_len);
1133     g_free(try_data);
1134
1135     /* remove protection bit */
1136     decrypt_data[1]&=0xBF;
1137
1138     /* remove TKIP/CCMP header */
1139     offset = mac_header_len;
1140     *decrypt_len-=8;
1141     memmove(decrypt_data+offset, decrypt_data+offset+8, *decrypt_len-offset);
1142
1143     if (key!=NULL) {
1144         memcpy(key, sa->key, sizeof(AIRPDCAP_KEY_ITEM));
1145
1146         if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)
1147             key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
1148         else if (sa->wpa.key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
1149             key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
1150     }
1151
1152     return AIRPDCAP_RET_SUCCESS;
1153 }
1154
1155 static INT
1156 AirPDcapWepMng(
1157     PAIRPDCAP_CONTEXT ctx,
1158     UCHAR *decrypt_data,
1159     guint mac_header_len,
1160     guint *decrypt_len,
1161     PAIRPDCAP_KEY_ITEM key,
1162     AIRPDCAP_SEC_ASSOCIATION *sa,
1163     INT offset)
1164 {
1165     UCHAR wep_key[AIRPDCAP_WEP_KEY_MAXLEN+AIRPDCAP_WEP_IVLEN];
1166     size_t keylen;
1167     INT ret_value=1;
1168     INT key_index;
1169     AIRPDCAP_KEY_ITEM *tmp_key;
1170     UINT8 useCache=FALSE;
1171     UCHAR *try_data;
1172     guint try_data_len = *decrypt_len;
1173
1174     try_data = (UCHAR *)g_malloc(try_data_len);
1175
1176     if (sa->key!=NULL)
1177         useCache=TRUE;
1178
1179     for (key_index=0; key_index<(INT)ctx->keys_nr; key_index++) {
1180         /* use the cached one, or try all keys */
1181         if (!useCache) {
1182             tmp_key=&ctx->keys[key_index];
1183         } else {
1184             if (sa->key!=NULL && sa->key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
1185                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try cached WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1186                 tmp_key=sa->key;
1187             } else {
1188                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Cached key is not valid, try another WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1189                 tmp_key=&ctx->keys[key_index];
1190             }
1191         }
1192
1193         /* obviously, try only WEP keys... */
1194         if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP)
1195         {
1196             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Try WEP key...", AIRPDCAP_DEBUG_LEVEL_3);
1197
1198             memset(wep_key, 0, sizeof(wep_key));
1199             memcpy(try_data, decrypt_data, *decrypt_len);
1200
1201             /* Costruct the WEP seed: copy the IV in first 3 bytes and then the WEP key (refer to 802-11i-2004, 8.2.1.4.3, pag. 36) */
1202             memcpy(wep_key, try_data+mac_header_len, AIRPDCAP_WEP_IVLEN);
1203             keylen=tmp_key->KeyData.Wep.WepKeyLen;
1204             memcpy(wep_key+AIRPDCAP_WEP_IVLEN, tmp_key->KeyData.Wep.WepKey, keylen);
1205
1206             ret_value=AirPDcapWepDecrypt(wep_key,
1207                 keylen+AIRPDCAP_WEP_IVLEN,
1208                 try_data + (mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN),
1209                 *decrypt_len-(mac_header_len+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN+AIRPDCAP_CRC_LEN));
1210
1211             if (ret_value == AIRPDCAP_RET_SUCCESS)
1212                 memcpy(decrypt_data, try_data, *decrypt_len);
1213         }
1214
1215         if (!ret_value && tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WEP) {
1216             /* the tried key is the correct one, cached in the Security Association */
1217
1218             sa->key=tmp_key;
1219
1220             if (key!=NULL) {
1221                 memcpy(key, &sa->key, sizeof(AIRPDCAP_KEY_ITEM));
1222                 key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1223             }
1224
1225             break;
1226         } else {
1227             /* the cached key was not valid, try other keys */
1228
1229             if (useCache==TRUE) {
1230                 useCache=FALSE;
1231                 key_index--;
1232             }
1233         }
1234     }
1235
1236     g_free(try_data);
1237     if (ret_value)
1238         return ret_value;
1239
1240     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "WEP DECRYPTED!!!", AIRPDCAP_DEBUG_LEVEL_3);
1241
1242     /* remove ICV (4bytes) from the end of packet */
1243     *decrypt_len-=4;
1244
1245     if (*decrypt_len < 4) {
1246         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapWepMng", "Decryption length too short", AIRPDCAP_DEBUG_LEVEL_3);
1247         return AIRPDCAP_RET_UNSUCCESS;
1248     }
1249
1250     /* remove protection bit */
1251     decrypt_data[1]&=0xBF;
1252
1253     /* remove IC header */
1254     offset = mac_header_len;
1255     *decrypt_len-=4;
1256     memcpy(decrypt_data+offset, decrypt_data+offset+AIRPDCAP_WEP_IVLEN+AIRPDCAP_WEP_KIDLEN, *decrypt_len-offset);
1257
1258     return AIRPDCAP_RET_SUCCESS;
1259 }
1260
1261 /* Refer to IEEE 802.11i-2004, 8.5.3, pag. 85 */
1262 static INT
1263 AirPDcapRsna4WHandshake(
1264     PAIRPDCAP_CONTEXT ctx,
1265     const UCHAR *data,
1266     AIRPDCAP_SEC_ASSOCIATION *sa,
1267     PAIRPDCAP_KEY_ITEM key,
1268     INT offset)
1269 {
1270     AIRPDCAP_KEY_ITEM *tmp_key, *tmp_pkt_key, pkt_key;
1271     AIRPDCAP_SEC_ASSOCIATION *tmp_sa;
1272     INT key_index;
1273     INT ret_value=1;
1274     UCHAR useCache=FALSE;
1275     UCHAR eapol[AIRPDCAP_EAPOL_MAX_LEN];
1276     USHORT eapol_len;
1277
1278     if (sa->key!=NULL)
1279         useCache=TRUE;
1280
1281     /* a 4-way handshake packet use a Pairwise key type (IEEE 802.11i-2004, pg. 79) */
1282     if (AIRPDCAP_EAP_KEY(data[offset+1])!=1) {
1283         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Group/STAKey message (not used)", AIRPDCAP_DEBUG_LEVEL_5);
1284         return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
1285     }
1286
1287     /* TODO timeouts? */
1288
1289     /* This saves the sa since we are reauthenticating which will overwrite our current sa GCS*/
1290     if(sa->handshake == 4) {
1291         tmp_sa= g_new(AIRPDCAP_SEC_ASSOCIATION, 1);
1292         memcpy(tmp_sa, sa, sizeof(AIRPDCAP_SEC_ASSOCIATION));
1293         sa->next=tmp_sa;
1294     }
1295
1296     /* TODO consider key-index */
1297
1298     /* TODO considera Deauthentications */
1299
1300     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake...", AIRPDCAP_DEBUG_LEVEL_5);
1301
1302     /* manage 4-way handshake packets; this step completes the 802.1X authentication process (IEEE 802.11i-2004, pag. 85) */
1303
1304     /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0) */
1305     if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
1306         AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
1307         AIRPDCAP_EAP_MIC(data[offset])==0)
1308     {
1309         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 1", AIRPDCAP_DEBUG_LEVEL_3);
1310
1311         /* On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been        */
1312         /* used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current  */
1313         /* local value, the Supplicant discards the message.                                                               */
1314         /* -> not checked, the Authenticator will be send another Message 1 (hopefully!)                                   */
1315
1316         /* save ANonce (from authenticator) to derive the PTK with the SNonce (from the 2 message) */
1317         memcpy(sa->wpa.nonce, data+offset+12, 32);
1318
1319         /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-) */
1320         sa->wpa.key_ver=AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1]);
1321
1322         sa->handshake=1;
1323
1324         return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1325     }
1326
1327     /* message 2|4: Supplicant->Authenticator (Sec=0|1, Mic=1, Ack=0, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=SNonce|0, MIC=MIC(KCK,EAPOL)) */
1328     if (AIRPDCAP_EAP_INST(data[offset+1])==0 &&
1329         AIRPDCAP_EAP_ACK(data[offset+1])==0 &&
1330         AIRPDCAP_EAP_MIC(data[offset])==1)
1331     {
1332         if (AIRPDCAP_EAP_SEC(data[offset])==0) {
1333
1334             /* PATCH: some implementations set secure bit to 0 also in the 4th message */
1335             /*          to recognize which message is this check if wep_key data length is 0     */
1336             /*          in the 4th message                                                       */
1337             if (data[offset+92]!=0 || data[offset+93]!=0) {
1338                 /* message 2 */
1339                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 2", AIRPDCAP_DEBUG_LEVEL_3);
1340
1341                 /* On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the */
1342                 /* outstanding Message 1. If not, it silently discards the message.                                   */
1343                 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame,  */
1344                 /* the Authenticator silently discards Message 2.                                                     */
1345                 /* -> not checked; the Supplicant will send another message 2 (hopefully!)                            */
1346
1347                 /* now you can derive the PTK */
1348                 for (key_index=0; key_index<(INT)ctx->keys_nr || useCache; key_index++) {
1349                     /* use the cached one, or try all keys */
1350                     if (!useCache) {
1351                         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1352                         tmp_key=&ctx->keys[key_index];
1353                     } else {
1354                         /* there is a cached key in the security association, if it's a WPA key try it... */
1355                         if (sa->key!=NULL &&
1356                             (sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1357                              sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1358                              sa->key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)) {
1359                                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Try cached WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1360                                 tmp_key=sa->key;
1361                         } else {
1362                             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "Cached key is of a wrong type, try WPA key...", AIRPDCAP_DEBUG_LEVEL_3);
1363                             tmp_key=&ctx->keys[key_index];
1364                         }
1365                     }
1366
1367                     /* obviously, try only WPA keys... */
1368                     if (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1369                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1370                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK)
1371                     {
1372                         if (tmp_key->KeyType == AIRPDCAP_KEY_TYPE_WPA_PWD && tmp_key->UserPwd.SsidLen == 0 && ctx->pkt_ssid_len > 0 && ctx->pkt_ssid_len <= AIRPDCAP_WPA_SSID_MAX_LEN) {
1373                             /* We have a "wildcard" SSID.  Use the one from the packet. */
1374                             memcpy(&pkt_key, tmp_key, sizeof(pkt_key));
1375                             memcpy(&pkt_key.UserPwd.Ssid, ctx->pkt_ssid, ctx->pkt_ssid_len);
1376                              pkt_key.UserPwd.SsidLen = ctx->pkt_ssid_len;
1377                             AirPDcapRsnaPwd2Psk(pkt_key.UserPwd.Passphrase, pkt_key.UserPwd.Ssid,
1378                                 pkt_key.UserPwd.SsidLen, pkt_key.KeyData.Wpa.Psk);
1379                             tmp_pkt_key = &pkt_key;
1380                         } else {
1381                             tmp_pkt_key = tmp_key;
1382                         }
1383
1384                         /* derive the PTK from the BSSID, STA MAC, PMK, SNonce, ANonce */
1385                         AirPDcapRsnaPrfX(sa,                            /* authenticator nonce, bssid, station mac */
1386                                          tmp_pkt_key->KeyData.Wpa.Pmk,      /* PMK */
1387                                          data+offset+12,                /* supplicant nonce */
1388                                          512,
1389                                          sa->wpa.ptk);
1390
1391                         /* verify the MIC (compare the MIC in the packet included in this message with a MIC calculated with the PTK) */
1392                         eapol_len=pntoh16(data+offset-3)+4;
1393                         memcpy(eapol, &data[offset-5], (eapol_len<AIRPDCAP_EAPOL_MAX_LEN?eapol_len:AIRPDCAP_EAPOL_MAX_LEN));
1394                         ret_value=AirPDcapRsnaMicCheck(eapol,           /*      eapol frame (header also) */
1395                                                        eapol_len,       /*      eapol frame length        */
1396                                                        sa->wpa.ptk,     /*      Key Confirmation Key      */
1397                                                        AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])); /*  EAPOL-Key description version */
1398
1399                         /* If the MIC is valid, the Authenticator checks that the RSN information element bit-wise matches       */
1400                         /* that from the (Re)Association Request message.                                                        */
1401                         /*              i) TODO If these are not exactly the same, the Authenticator uses MLME-DEAUTHENTICATE.request */
1402                         /* primitive to terminate the association.                                                               */
1403                         /*              ii) If they do match bit-wise, the Authenticator constructs Message 3.                   */
1404                     }
1405
1406                     if (!ret_value &&
1407                         (tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PWD ||
1408                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PSK ||
1409                         tmp_key->KeyType==AIRPDCAP_KEY_TYPE_WPA_PMK))
1410                     {
1411                         /* the temporary key is the correct one, cached in the Security Association */
1412
1413                         sa->key=tmp_key;
1414
1415                         if (key!=NULL) {
1416                             memcpy(key, &tmp_key, sizeof(AIRPDCAP_KEY_ITEM));
1417                             if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_NOT_CCMP)
1418                                 key->KeyType=AIRPDCAP_KEY_TYPE_TKIP;
1419                             else if (AIRPDCAP_EAP_KEY_DESCR_VER(data[offset+1])==AIRPDCAP_WPA_KEY_VER_AES_CCMP)
1420                                 key->KeyType=AIRPDCAP_KEY_TYPE_CCMP;
1421                         }
1422
1423                         break;
1424                     } else {
1425                         /* the cached key was not valid, try other keys */
1426
1427                         if (useCache==TRUE) {
1428                             useCache=FALSE;
1429                             key_index--;
1430                         }
1431                     }
1432                 }
1433
1434                 if (ret_value) {
1435                     AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "handshake step failed", AIRPDCAP_DEBUG_LEVEL_3);
1436                     return AIRPDCAP_RET_NO_VALID_HANDSHAKE;
1437                 }
1438
1439                 sa->handshake=2;
1440
1441                 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1442             } else {
1443                 /* message 4 */
1444
1445                 /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
1446
1447                 /* TODO check MIC and Replay Counter                                                                     */
1448                 /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one  */
1449                 /* that it used on this 4-Way Handshake; if it is not, it silently discards the message.                 */
1450                 /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
1451                 /* Authenticator silently discards Message 4.                                                            */
1452
1453                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4 (patched)", AIRPDCAP_DEBUG_LEVEL_3);
1454
1455                 sa->handshake=4;
1456
1457                 sa->validKey=TRUE;
1458
1459                 return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1460             }
1461             /* END OF PATCH      */
1462             /*                   */
1463         } else {
1464             /* message 4 */
1465
1466             /* TODO "Note that when the 4-Way Handshake is first used Message 4 is sent in the clear." */
1467
1468             /* TODO check MIC and Replay Counter                                                                     */
1469             /* On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one  */
1470             /* that it used on this 4-Way Handshake; if it is not, it silently discards the message.                 */
1471             /* If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the */
1472             /* Authenticator silently discards Message 4.                                                            */
1473
1474             AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 4", AIRPDCAP_DEBUG_LEVEL_3);
1475
1476             sa->handshake=4;
1477
1478             sa->validKey=TRUE;
1479
1480             return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1481         }
1482     }
1483
1484     /* message 3: Authenticator->Supplicant (Sec=1, Mic=1, Ack=1, Inst=0/1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) */
1485     if (AIRPDCAP_EAP_ACK(data[offset+1])==1 &&
1486         AIRPDCAP_EAP_MIC(data[offset])==1)
1487     {
1488         const EAPOL_RSN_KEY *pEAPKey;
1489         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapRsna4WHandshake", "4-way handshake message 3", AIRPDCAP_DEBUG_LEVEL_3);
1490
1491         /* On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field     */
1492         /* value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1. */
1493         /* -> not checked, the Authenticator will send another message 3 (hopefully!)                                  */
1494
1495         /* TODO check page 88 (RNS) */
1496
1497         /* If using WPA2 PSK, message 3 will contain an RSN for the group key (GTK KDE).
1498            In order to properly support decrypting WPA2-PSK packets, we need to parse this to get the group key. */
1499         pEAPKey = (const EAPOL_RSN_KEY *)(&(data[offset-1]));
1500         if (pEAPKey->type == AIRPDCAP_RSN_WPA2_KEY_DESCRIPTOR){
1501             PAIRPDCAP_SEC_ASSOCIATION broadcast_sa;
1502             AIRPDCAP_SEC_ASSOCIATION_ID id;
1503
1504             /* Get broadcacst SA for the current BSSID */
1505             memcpy(id.sta, broadcast_mac, AIRPDCAP_MAC_LEN);
1506             memcpy(id.bssid, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1507             broadcast_sa = AirPDcapGetSaPtr(ctx, &id);
1508
1509             if (broadcast_sa == NULL){
1510                 return AIRPDCAP_RET_UNSUCCESS;
1511             }
1512             AirPDcapDecryptWPABroadcastKey(pEAPKey, sa->wpa.ptk+16, broadcast_sa, FALSE);
1513         }
1514
1515         return AIRPDCAP_RET_SUCCESS_HANDSHAKE;
1516     }
1517
1518     return AIRPDCAP_RET_UNSUCCESS;
1519 }
1520
1521 static INT
1522 AirPDcapRsnaMicCheck(
1523     UCHAR *eapol,
1524     USHORT eapol_len,
1525     UCHAR KCK[AIRPDCAP_WPA_KCK_LEN],
1526     USHORT key_ver)
1527 {
1528     UCHAR mic[AIRPDCAP_WPA_MICKEY_LEN];
1529     UCHAR c_mic[20];  /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */
1530
1531     /* copy the MIC from the EAPOL packet */
1532     memcpy(mic, eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, AIRPDCAP_WPA_MICKEY_LEN);
1533
1534     /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */
1535     memset(eapol+AIRPDCAP_WPA_MICKEY_OFFSET+4, 0, AIRPDCAP_WPA_MICKEY_LEN);
1536
1537     if (key_ver==AIRPDCAP_WPA_KEY_VER_NOT_CCMP) {
1538         /* use HMAC-MD5 for the EAPOL-Key MIC */
1539         md5_hmac(eapol, eapol_len, KCK, AIRPDCAP_WPA_KCK_LEN, c_mic);
1540     } else if (key_ver==AIRPDCAP_WPA_KEY_VER_AES_CCMP) {
1541         /* use HMAC-SHA1-128 for the EAPOL-Key MIC */
1542         sha1_hmac(KCK, AIRPDCAP_WPA_KCK_LEN, eapol, eapol_len, c_mic);
1543     } else
1544         /* key descriptor version not recognized */
1545         return AIRPDCAP_RET_UNSUCCESS;
1546
1547     /* compare calculated MIC with the Key MIC and return result (0 means success) */
1548     return memcmp(mic, c_mic, AIRPDCAP_WPA_MICKEY_LEN);
1549 }
1550
1551 static INT
1552 AirPDcapValidateKey(
1553     PAIRPDCAP_KEY_ITEM key)
1554 {
1555     size_t len;
1556     UCHAR ret=TRUE;
1557     AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
1558
1559     if (key==NULL) {
1560         AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "NULL key", AIRPDCAP_DEBUG_LEVEL_5);
1561         AIRPDCAP_DEBUG_TRACE_START("AirPDcapValidateKey");
1562         return FALSE;
1563     }
1564
1565     switch (key->KeyType) {
1566         case AIRPDCAP_KEY_TYPE_WEP:
1567             /* check key size limits */
1568             len=key->KeyData.Wep.WepKeyLen;
1569             if (len<AIRPDCAP_WEP_KEY_MINLEN || len>AIRPDCAP_WEP_KEY_MAXLEN) {
1570                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WEP key: key length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1571                 ret=FALSE;
1572             }
1573             break;
1574
1575         case AIRPDCAP_KEY_TYPE_WEP_40:
1576             /* set the standard length and use a generic WEP key type */
1577             key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_40_KEY_LEN;
1578             key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1579             break;
1580
1581         case AIRPDCAP_KEY_TYPE_WEP_104:
1582             /* set the standard length and use a generic WEP key type */
1583             key->KeyData.Wep.WepKeyLen=AIRPDCAP_WEP_104_KEY_LEN;
1584             key->KeyType=AIRPDCAP_KEY_TYPE_WEP;
1585             break;
1586
1587         case AIRPDCAP_KEY_TYPE_WPA_PWD:
1588             /* check passphrase and SSID size limits */
1589             len=strlen(key->UserPwd.Passphrase);
1590             if (len<AIRPDCAP_WPA_PASSPHRASE_MIN_LEN || len>AIRPDCAP_WPA_PASSPHRASE_MAX_LEN) {
1591                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: passphrase length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1592                 ret=FALSE;
1593             }
1594
1595             len=key->UserPwd.SsidLen;
1596             if (len>AIRPDCAP_WPA_SSID_MAX_LEN) {
1597                 AIRPDCAP_DEBUG_PRINT_LINE("AirPDcapValidateKey", "WPA-PWD key: ssid length not accepted", AIRPDCAP_DEBUG_LEVEL_5);
1598                 ret=FALSE;
1599             }
1600
1601             break;
1602
1603         case AIRPDCAP_KEY_TYPE_WPA_PSK:
1604             break;
1605
1606         case AIRPDCAP_KEY_TYPE_WPA_PMK:
1607             break;
1608
1609         default:
1610             ret=FALSE;
1611     }
1612
1613     AIRPDCAP_DEBUG_TRACE_END("AirPDcapValidateKey");
1614     return ret;
1615 }
1616
1617 static INT
1618 AirPDcapGetSa(
1619     PAIRPDCAP_CONTEXT ctx,
1620     AIRPDCAP_SEC_ASSOCIATION_ID *id)
1621 {
1622     INT sa_index;
1623
1624     if (ctx->sa_index!=-1) {
1625         /* at least one association was stored                               */
1626         /* search for the association from sa_index to 0 (most recent added) */
1627         for (sa_index=ctx->sa_index; sa_index>=0; sa_index--) {
1628             if (ctx->sa[sa_index].used) {
1629                 if (memcmp(id, &(ctx->sa[sa_index].saId), sizeof(AIRPDCAP_SEC_ASSOCIATION_ID))==0) {
1630                     ctx->index=sa_index;
1631                     return sa_index;
1632                 }
1633             }
1634         }
1635     }
1636
1637     return -1;
1638 }
1639
1640 static INT
1641 AirPDcapStoreSa(
1642     PAIRPDCAP_CONTEXT ctx,
1643     AIRPDCAP_SEC_ASSOCIATION_ID *id)
1644 {
1645     INT last_free;
1646
1647     if (ctx->sa[ctx->first_free_index].used) {
1648         /* last addition was in the middle of the array (and the first_free_index was just incremented by 1)   */
1649         /* search for a free space from the first_free_index to AIRPDCAP_STA_INFOS_NR (to avoid free blocks in */
1650         /*              the middle)                                                                            */
1651         for (last_free=ctx->first_free_index; last_free<AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR; last_free++)
1652             if (!ctx->sa[last_free].used)
1653                 break;
1654
1655         if (last_free>=AIRPDCAP_MAX_SEC_ASSOCIATIONS_NR) {
1656             /* there is no empty space available. FAILURE */
1657             return -1;
1658         }
1659
1660         /* store first free space index */
1661         ctx->first_free_index=last_free;
1662     }
1663
1664     /* use this info */
1665     ctx->index=ctx->first_free_index;
1666
1667     /* reset the info structure */
1668     memset(ctx->sa+ctx->index, 0, sizeof(AIRPDCAP_SEC_ASSOCIATION));
1669
1670     ctx->sa[ctx->index].used=1;
1671
1672     /* set the info structure */
1673     memcpy(&(ctx->sa[ctx->index].saId), id, sizeof(AIRPDCAP_SEC_ASSOCIATION_ID));
1674
1675     /* increment by 1 the first_free_index (heuristic) */
1676     ctx->first_free_index++;
1677
1678     /* set the sa_index if the added index is greater the the sa_index */
1679     if (ctx->index > ctx->sa_index)
1680         ctx->sa_index=ctx->index;
1681
1682     return ctx->index;
1683 }
1684
1685 /*
1686  * AirPDcapGetBssidAddress() and AirPDcapGetBssidAddress() are used for
1687  * key caching.  In each case, it's more important to return a value than
1688  * to return a _correct_ value, so we fudge addresses in some cases, e.g.
1689  * the BSSID in bridged connections.
1690  * FromDS    ToDS    Sta    BSSID
1691  * 0         0       addr2  addr3
1692  * 0         1       addr2  addr1
1693  * 1         0       addr1  addr2
1694  * 1         1       addr2  addr1
1695  */
1696
1697 static const UCHAR *
1698 AirPDcapGetStaAddress(
1699     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
1700 {
1701     switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
1702         case 0:
1703         case 1:
1704             return frame->addr2;
1705         case 2:
1706             return frame->addr1;
1707         case 3:
1708             if (memcmp(frame->addr1, frame->addr2, AIRPDCAP_MAC_LEN) < 0)
1709                 return frame->addr1;
1710             else
1711                 return frame->addr2;
1712
1713         default:
1714             return NULL;
1715     }
1716 }
1717
1718 static const UCHAR *
1719 AirPDcapGetBssidAddress(
1720     const AIRPDCAP_MAC_FRAME_ADDR4 *frame)
1721 {
1722     switch(AIRPDCAP_DS_BITS(frame->fc[1])) { /* Bit 1 = FromDS, bit 0 = ToDS */
1723         case 0:
1724             return frame->addr3;
1725         case 1:
1726             return frame->addr1;
1727         case 2:
1728             return frame->addr2;
1729         case 3:
1730             if (memcmp(frame->addr1, frame->addr2, AIRPDCAP_MAC_LEN) > 0)
1731                 return frame->addr1;
1732             else
1733                 return frame->addr2;
1734
1735         default:
1736             return NULL;
1737     }
1738 }
1739
1740 /* Function used to derive the PTK. Refer to IEEE 802.11I-2004, pag. 74 */
1741 static void
1742 AirPDcapRsnaPrfX(
1743     AIRPDCAP_SEC_ASSOCIATION *sa,
1744     const UCHAR pmk[32],
1745     const UCHAR snonce[32],
1746     const INT x,        /*      for TKIP 512, for CCMP 384 */
1747     UCHAR *ptk)
1748 {
1749     UINT8 i;
1750     UCHAR R[100];
1751     INT offset=sizeof("Pairwise key expansion");
1752
1753     memset(R, 0, 100);
1754
1755     memcpy(R, "Pairwise key expansion", offset);
1756
1757     /* Min(AA, SPA) || Max(AA, SPA) */
1758     if (memcmp(sa->saId.sta, sa->saId.bssid, AIRPDCAP_MAC_LEN) < 0)
1759     {
1760         memcpy(R + offset, sa->saId.sta, AIRPDCAP_MAC_LEN);
1761         memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1762     }
1763     else
1764     {
1765         memcpy(R + offset, sa->saId.bssid, AIRPDCAP_MAC_LEN);
1766         memcpy(R + offset+AIRPDCAP_MAC_LEN, sa->saId.sta, AIRPDCAP_MAC_LEN);
1767     }
1768
1769     offset+=AIRPDCAP_MAC_LEN*2;
1770
1771     /* Min(ANonce,SNonce) || Max(ANonce,SNonce) */
1772     if( memcmp(snonce, sa->wpa.nonce, 32) < 0 )
1773     {
1774         memcpy(R + offset, snonce, 32);
1775         memcpy(R + offset + 32, sa->wpa.nonce, 32);
1776     }
1777     else
1778     {
1779         memcpy(R + offset, sa->wpa.nonce, 32);
1780         memcpy(R + offset + 32, snonce, 32);
1781     }
1782
1783     offset+=32*2;
1784
1785     for(i = 0; i < (x+159)/160; i++)
1786     {
1787         R[offset] = i;
1788         sha1_hmac(pmk, 32, R, 100, ptk + i * 20);
1789     }
1790 }
1791
1792 static INT
1793 AirPDcapRsnaPwd2PskStep(
1794     const guint8 *ppBytes,
1795     const guint ppLength,
1796     const CHAR *ssid,
1797     const size_t ssidLength,
1798     const INT iterations,
1799     const INT count,
1800     UCHAR *output)
1801 {
1802     UCHAR digest[64], digest1[64];
1803     INT i, j;
1804
1805     if (ssidLength+4 > 36)
1806         return AIRPDCAP_RET_UNSUCCESS;
1807
1808     memset(digest, 0, 64);
1809     memset(digest1, 0, 64);
1810
1811     /* U1 = PRF(P, S || INT(i)) */
1812     memcpy(digest, ssid, ssidLength);
1813     digest[ssidLength] = (UCHAR)((count>>24) & 0xff);
1814     digest[ssidLength+1] = (UCHAR)((count>>16) & 0xff);
1815     digest[ssidLength+2] = (UCHAR)((count>>8) & 0xff);
1816     digest[ssidLength+3] = (UCHAR)(count & 0xff);
1817     sha1_hmac(ppBytes, ppLength, digest, (guint32) ssidLength+4, digest1);
1818
1819     /* output = U1 */
1820     memcpy(output, digest1, AIRPDCAP_SHA_DIGEST_LEN);
1821     for (i = 1; i < iterations; i++) {
1822         /* Un = PRF(P, Un-1) */
1823         sha1_hmac(ppBytes, ppLength, digest1, AIRPDCAP_SHA_DIGEST_LEN, digest);
1824
1825         memcpy(digest1, digest, AIRPDCAP_SHA_DIGEST_LEN);
1826         /* output = output xor Un */
1827         for (j = 0; j < AIRPDCAP_SHA_DIGEST_LEN; j++) {
1828             output[j] ^= digest[j];
1829         }
1830     }
1831
1832     return AIRPDCAP_RET_SUCCESS;
1833 }
1834
1835 static INT
1836 AirPDcapRsnaPwd2Psk(
1837     const CHAR *passphrase,
1838     const CHAR *ssid,
1839     const size_t ssidLength,
1840     UCHAR *output)
1841 {
1842     UCHAR m_output[AIRPDCAP_WPA_PSK_LEN];
1843     GByteArray *pp_ba = g_byte_array_new();
1844
1845     memset(m_output, 0, AIRPDCAP_WPA_PSK_LEN);
1846
1847     if (!uri_str_to_bytes(passphrase, pp_ba)) {
1848         g_byte_array_free(pp_ba, TRUE);
1849         return 0;
1850     }
1851
1852     AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 1, m_output);
1853     AirPDcapRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 2, &m_output[AIRPDCAP_SHA_DIGEST_LEN]);
1854
1855     memcpy(output, m_output, AIRPDCAP_WPA_PSK_LEN);
1856     g_byte_array_free(pp_ba, TRUE);
1857
1858     return 0;
1859 }
1860
1861 /*
1862  * Returns the decryption_key_t struct given a string describing the key.
1863  * Returns NULL if the input_string cannot be parsed.
1864  */
1865 decryption_key_t*
1866 parse_key_string(gchar* input_string, guint8 key_type)
1867 {
1868     gchar *key, *tmp_str;
1869     gchar *ssid;
1870
1871     GString    *key_string = NULL;
1872     GByteArray *ssid_ba = NULL, *key_ba;
1873     gboolean    res;
1874
1875     gchar **tokens;
1876     guint n = 0;
1877     decryption_key_t *dk;
1878
1879     if(input_string == NULL)
1880         return NULL;
1881
1882     /*
1883      * Parse the input_string. WEP and WPA will be just a string
1884      * of hexadecimal characters (if key is wrong, null will be
1885      * returned...).
1886      * WPA-PWD should be in the form
1887      * <key data>[:<ssid>]
1888      */
1889
1890     switch(key_type)
1891     {
1892     case AIRPDCAP_KEY_TYPE_WEP:
1893     case AIRPDCAP_KEY_TYPE_WEP_40:
1894     case AIRPDCAP_KEY_TYPE_WEP_104:
1895
1896        key_ba = g_byte_array_new();
1897        res = hex_str_to_bytes(input_string, key_ba, FALSE);
1898
1899        if (res && key_ba->len > 0) {
1900            /* Key is correct! It was probably an 'old style' WEP key */
1901            /* Create the decryption_key_t structure, fill it and return it*/
1902            dk = (decryption_key_t *)g_malloc(sizeof(decryption_key_t));
1903
1904            dk->type = AIRPDCAP_KEY_TYPE_WEP;
1905            /* XXX - The current key handling code in the GUI requires
1906             * no separators and lower case */
1907            tmp_str = bytes_to_str(NULL, key_ba->data, key_ba->len);
1908            dk->key  = g_string_new(tmp_str);
1909            g_string_ascii_down(dk->key);
1910            dk->bits = key_ba->len * 8;
1911            dk->ssid = NULL;
1912
1913            wmem_free(NULL, tmp_str);
1914            g_byte_array_free(key_ba, TRUE);
1915            return dk;
1916        }
1917
1918        /* Key doesn't work */
1919        g_byte_array_free(key_ba, TRUE);
1920        return NULL;
1921
1922     case AIRPDCAP_KEY_TYPE_WPA_PWD:
1923
1924         tokens = g_strsplit(input_string,":",0);
1925
1926         /* Tokens is a null termiated array of strings ... */
1927         while(tokens[n] != NULL)
1928             n++;
1929
1930         if(n < 1)
1931         {
1932             /* Free the array of strings */
1933             g_strfreev(tokens);
1934             return NULL;
1935         }
1936
1937         /*
1938          * The first token is the key
1939          */
1940         key = g_strdup(tokens[0]);
1941
1942         ssid = NULL;
1943         /* Maybe there is a second token (an ssid, if everything else is ok) */
1944         if(n >= 2)
1945         {
1946            ssid = g_strdup(tokens[1]);
1947         }
1948
1949         /* Create a new string */
1950         key_string = g_string_new(key);
1951         ssid_ba = NULL;
1952
1953         /* Two (or more) tokens mean that the user entered a WPA-PWD key ... */
1954         if( ((key_string->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WPA_KEY_MIN_CHAR_SIZE))
1955         {
1956             g_string_free(key_string, TRUE);
1957
1958             g_free(key);
1959             g_free(ssid);
1960
1961             /* Free the array of strings */
1962             g_strfreev(tokens);
1963             return NULL;
1964         }
1965
1966         if(ssid != NULL) /* more than two tokens found, means that the user specified the ssid */
1967         {
1968             ssid_ba = g_byte_array_new();
1969             if (! uri_str_to_bytes(ssid, ssid_ba)) {
1970                 g_string_free(key_string, TRUE);
1971                 g_byte_array_free(ssid_ba, TRUE);
1972                 g_free(key);
1973                 g_free(ssid);
1974                 /* Free the array of strings */
1975                 g_strfreev(tokens);
1976                 return NULL;
1977             }
1978
1979             if(ssid_ba->len > WPA_SSID_MAX_CHAR_SIZE)
1980             {
1981                 g_string_free(key_string, TRUE);
1982                 g_byte_array_free(ssid_ba, TRUE);
1983
1984                 g_free(key);
1985                 g_free(ssid);
1986
1987                 /* Free the array of strings */
1988                 g_strfreev(tokens);
1989                 return NULL;
1990             }
1991         }
1992
1993         /* Key was correct!!! Create the new decryption_key_t ... */
1994         dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
1995
1996         dk->type = AIRPDCAP_KEY_TYPE_WPA_PWD;
1997         dk->key  = g_string_new(key);
1998         dk->bits = 256; /* This is the length of the array pf bytes that will be generated using key+ssid ...*/
1999         dk->ssid = byte_array_dup(ssid_ba); /* NULL if ssid_ba is NULL */
2000
2001         g_string_free(key_string, TRUE);
2002         if (ssid_ba != NULL)
2003             g_byte_array_free(ssid_ba, TRUE);
2004
2005         g_free(key);
2006         if(ssid != NULL)
2007             g_free(ssid);
2008
2009         /* Free the array of strings */
2010         g_strfreev(tokens);
2011         return dk;
2012
2013     case AIRPDCAP_KEY_TYPE_WPA_PSK:
2014
2015         key_ba = g_byte_array_new();
2016         res = hex_str_to_bytes(input_string, key_ba, FALSE);
2017
2018         /* Two tokens means that the user should have entered a WPA-BIN key ... */
2019         if(!res || ((key_ba->len) != WPA_PSK_KEY_SIZE))
2020         {
2021             g_byte_array_free(key_ba, TRUE);
2022
2023             /* No ssid has been created ... */
2024             return NULL;
2025         }
2026
2027         /* Key was correct!!! Create the new decryption_key_t ... */
2028         dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
2029
2030         dk->type = AIRPDCAP_KEY_TYPE_WPA_PSK;
2031         dk->key  = g_string_new(input_string);
2032         dk->bits = (guint) dk->key->len * 4;
2033         dk->ssid = NULL;
2034
2035         g_byte_array_free(key_ba, TRUE);
2036         return dk;
2037     }
2038
2039     /* Type not supported */
2040     return NULL;
2041 }
2042
2043 /*
2044  * Returns a newly allocated string representing the given decryption_key_t
2045  * struct, or NULL if something is wrong...
2046  */
2047 gchar*
2048 get_key_string(decryption_key_t* dk)
2049 {
2050     gchar* output_string = NULL;
2051
2052     if(dk == NULL || dk->key == NULL)
2053         return NULL;
2054
2055     switch(dk->type) {
2056         case AIRPDCAP_KEY_TYPE_WEP:
2057             output_string = g_strdup(dk->key->str);
2058             break;
2059         case AIRPDCAP_KEY_TYPE_WPA_PWD:
2060             if(dk->ssid == NULL)
2061                 output_string = g_strdup(dk->key->str);
2062             else
2063                 output_string = g_strdup_printf("%s:%s",
2064                     dk->key->str, format_uri(dk->ssid, ":"));
2065             break;
2066         case AIRPDCAP_KEY_TYPE_WPA_PMK:
2067             output_string = g_strdup(dk->key->str);
2068             break;
2069         default:
2070             return NULL;
2071     }
2072
2073     return output_string;
2074 }
2075
2076 #ifdef __cplusplus
2077 }
2078 #endif
2079
2080 /****************************************************************************/
2081
2082 /*
2083  * Editor modelines
2084  *
2085  * Local Variables:
2086  * c-basic-offset: 4
2087  * tab-width: 8
2088  * indent-tabs-mode: nil
2089  * End:
2090  *
2091  * ex: set shiftwidth=4 tabstop=8 expandtab:
2092  * :indentSize=4:tabSize=8:noTabs=true:
2093  */