]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/wpa_supplicant/eap_md5.c
This commit was generated by cvs2svn to compensate for changes in r162079,
[FreeBSD/FreeBSD.git] / contrib / wpa_supplicant / eap_md5.c
1 /*
2  * WPA Supplicant / EAP-MD5
3  * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17
18 #include "common.h"
19 #include "eap_i.h"
20 #include "wpa_supplicant.h"
21 #include "config_ssid.h"
22 #include "md5.h"
23 #include "crypto.h"
24
25
26 static void * eap_md5_init(struct eap_sm *sm)
27 {
28         return (void *) 1;
29 }
30
31
32 static void eap_md5_deinit(struct eap_sm *sm, void *priv)
33 {
34 }
35
36
37 static u8 * eap_md5_process(struct eap_sm *sm, void *priv,
38                             struct eap_method_ret *ret,
39                             const u8 *reqData, size_t reqDataLen,
40                             size_t *respDataLen)
41 {
42         struct wpa_ssid *config = eap_get_config(sm);
43         const struct eap_hdr *req;
44         struct eap_hdr *resp;
45         const u8 *pos, *challenge;
46         u8 *rpos;
47         int challenge_len;
48         size_t len;
49         const u8 *addr[3];
50         size_t elen[3];
51
52         if (config == NULL || config->password == NULL) {
53                 wpa_printf(MSG_INFO, "EAP-MD5: Password not configured");
54                 eap_sm_request_password(sm, config);
55                 ret->ignore = TRUE;
56                 return NULL;
57         }
58
59         pos = eap_hdr_validate(EAP_TYPE_MD5, reqData, reqDataLen, &len);
60         if (pos == NULL) {
61                 ret->ignore = TRUE;
62                 return NULL;
63         }
64         req = (const struct eap_hdr *) reqData;
65         challenge_len = *pos++;
66         if (challenge_len == 0 ||
67             challenge_len > len - 1) {
68                 wpa_printf(MSG_INFO, "EAP-MD5: Invalid challenge "
69                            "(challenge_len=%d len=%lu",
70                            challenge_len, (unsigned long) len);
71                 ret->ignore = TRUE;
72                 return NULL;
73         }
74         ret->ignore = FALSE;
75         challenge = pos;
76         wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge",
77                     challenge, challenge_len);
78
79         wpa_printf(MSG_DEBUG, "EAP-MD5: generating Challenge Response");
80         ret->methodState = METHOD_DONE;
81         ret->decision = DECISION_UNCOND_SUCC;
82         ret->allowNotifications = TRUE;
83
84         *respDataLen = sizeof(struct eap_hdr) + 1 + 1 + MD5_MAC_LEN;
85         resp = malloc(*respDataLen);
86         if (resp == NULL)
87                 return NULL;
88         resp->code = EAP_CODE_RESPONSE;
89         resp->identifier = req->identifier;
90         resp->length = host_to_be16(*respDataLen);
91         rpos = (u8 *) (resp + 1);
92         *rpos++ = EAP_TYPE_MD5;
93         *rpos++ = MD5_MAC_LEN; /* Value-Size */
94
95         addr[0] = &resp->identifier;
96         elen[0] = 1;
97         addr[1] = config->password;
98         elen[1] = config->password_len;
99         addr[2] = challenge;
100         elen[2] = challenge_len;
101         md5_vector(3, addr, elen, rpos);
102         wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", rpos, MD5_MAC_LEN);
103
104         return (u8 *) resp;
105 }
106
107
108 const struct eap_method eap_method_md5 =
109 {
110         .method = EAP_TYPE_MD5,
111         .name = "MD5",
112         .init = eap_md5_init,
113         .deinit = eap_md5_deinit,
114         .process = eap_md5_process,
115 };