xref: /dflybsd-src/contrib/wpa_supplicant/src/eap_peer/eap_md5.c (revision 6d49e1aea1f916afb9e202b8d2ad09cfab6e48c3)
1*6d49e1aeSJan Lentfer /*
2*6d49e1aeSJan Lentfer  * EAP peer method: EAP-MD5 (RFC 3748 and RFC 1994)
3*6d49e1aeSJan Lentfer  * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
4*6d49e1aeSJan Lentfer  *
5*6d49e1aeSJan Lentfer  * This program is free software; you can redistribute it and/or modify
6*6d49e1aeSJan Lentfer  * it under the terms of the GNU General Public License version 2 as
7*6d49e1aeSJan Lentfer  * published by the Free Software Foundation.
8*6d49e1aeSJan Lentfer  *
9*6d49e1aeSJan Lentfer  * Alternatively, this software may be distributed under the terms of BSD
10*6d49e1aeSJan Lentfer  * license.
11*6d49e1aeSJan Lentfer  *
12*6d49e1aeSJan Lentfer  * See README and COPYING for more details.
13*6d49e1aeSJan Lentfer  */
14*6d49e1aeSJan Lentfer 
15*6d49e1aeSJan Lentfer #include "includes.h"
16*6d49e1aeSJan Lentfer 
17*6d49e1aeSJan Lentfer #include "common.h"
18*6d49e1aeSJan Lentfer #include "eap_i.h"
19*6d49e1aeSJan Lentfer #include "eap_common/chap.h"
20*6d49e1aeSJan Lentfer 
21*6d49e1aeSJan Lentfer 
22*6d49e1aeSJan Lentfer static void * eap_md5_init(struct eap_sm *sm)
23*6d49e1aeSJan Lentfer {
24*6d49e1aeSJan Lentfer 	/* No need for private data. However, must return non-NULL to indicate
25*6d49e1aeSJan Lentfer 	 * success. */
26*6d49e1aeSJan Lentfer 	return (void *) 1;
27*6d49e1aeSJan Lentfer }
28*6d49e1aeSJan Lentfer 
29*6d49e1aeSJan Lentfer 
30*6d49e1aeSJan Lentfer static void eap_md5_deinit(struct eap_sm *sm, void *priv)
31*6d49e1aeSJan Lentfer {
32*6d49e1aeSJan Lentfer }
33*6d49e1aeSJan Lentfer 
34*6d49e1aeSJan Lentfer 
35*6d49e1aeSJan Lentfer static struct wpabuf * eap_md5_process(struct eap_sm *sm, void *priv,
36*6d49e1aeSJan Lentfer 				       struct eap_method_ret *ret,
37*6d49e1aeSJan Lentfer 				       const struct wpabuf *reqData)
38*6d49e1aeSJan Lentfer {
39*6d49e1aeSJan Lentfer 	struct wpabuf *resp;
40*6d49e1aeSJan Lentfer 	const u8 *pos, *challenge, *password;
41*6d49e1aeSJan Lentfer 	u8 *rpos, id;
42*6d49e1aeSJan Lentfer 	size_t len, challenge_len, password_len;
43*6d49e1aeSJan Lentfer 
44*6d49e1aeSJan Lentfer 	password = eap_get_config_password(sm, &password_len);
45*6d49e1aeSJan Lentfer 	if (password == NULL) {
46*6d49e1aeSJan Lentfer 		wpa_printf(MSG_INFO, "EAP-MD5: Password not configured");
47*6d49e1aeSJan Lentfer 		eap_sm_request_password(sm);
48*6d49e1aeSJan Lentfer 		ret->ignore = TRUE;
49*6d49e1aeSJan Lentfer 		return NULL;
50*6d49e1aeSJan Lentfer 	}
51*6d49e1aeSJan Lentfer 
52*6d49e1aeSJan Lentfer 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqData, &len);
53*6d49e1aeSJan Lentfer 	if (pos == NULL || len == 0) {
54*6d49e1aeSJan Lentfer 		wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame (pos=%p len=%lu)",
55*6d49e1aeSJan Lentfer 			   pos, (unsigned long) len);
56*6d49e1aeSJan Lentfer 		ret->ignore = TRUE;
57*6d49e1aeSJan Lentfer 		return NULL;
58*6d49e1aeSJan Lentfer 	}
59*6d49e1aeSJan Lentfer 
60*6d49e1aeSJan Lentfer 	/*
61*6d49e1aeSJan Lentfer 	 * CHAP Challenge:
62*6d49e1aeSJan Lentfer 	 * Value-Size (1 octet) | Value(Challenge) | Name(optional)
63*6d49e1aeSJan Lentfer 	 */
64*6d49e1aeSJan Lentfer 	challenge_len = *pos++;
65*6d49e1aeSJan Lentfer 	if (challenge_len == 0 || challenge_len > len - 1) {
66*6d49e1aeSJan Lentfer 		wpa_printf(MSG_INFO, "EAP-MD5: Invalid challenge "
67*6d49e1aeSJan Lentfer 			   "(challenge_len=%lu len=%lu)",
68*6d49e1aeSJan Lentfer 			   (unsigned long) challenge_len, (unsigned long) len);
69*6d49e1aeSJan Lentfer 		ret->ignore = TRUE;
70*6d49e1aeSJan Lentfer 		return NULL;
71*6d49e1aeSJan Lentfer 	}
72*6d49e1aeSJan Lentfer 	ret->ignore = FALSE;
73*6d49e1aeSJan Lentfer 	challenge = pos;
74*6d49e1aeSJan Lentfer 	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge",
75*6d49e1aeSJan Lentfer 		    challenge, challenge_len);
76*6d49e1aeSJan Lentfer 
77*6d49e1aeSJan Lentfer 	wpa_printf(MSG_DEBUG, "EAP-MD5: Generating Challenge Response");
78*6d49e1aeSJan Lentfer 	ret->methodState = METHOD_DONE;
79*6d49e1aeSJan Lentfer 	ret->decision = DECISION_UNCOND_SUCC;
80*6d49e1aeSJan Lentfer 	ret->allowNotifications = TRUE;
81*6d49e1aeSJan Lentfer 
82*6d49e1aeSJan Lentfer 	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHAP_MD5_LEN,
83*6d49e1aeSJan Lentfer 			     EAP_CODE_RESPONSE, eap_get_id(reqData));
84*6d49e1aeSJan Lentfer 	if (resp == NULL)
85*6d49e1aeSJan Lentfer 		return NULL;
86*6d49e1aeSJan Lentfer 
87*6d49e1aeSJan Lentfer 	/*
88*6d49e1aeSJan Lentfer 	 * CHAP Response:
89*6d49e1aeSJan Lentfer 	 * Value-Size (1 octet) | Value(Response) | Name(optional)
90*6d49e1aeSJan Lentfer 	 */
91*6d49e1aeSJan Lentfer 	wpabuf_put_u8(resp, CHAP_MD5_LEN);
92*6d49e1aeSJan Lentfer 
93*6d49e1aeSJan Lentfer 	id = eap_get_id(resp);
94*6d49e1aeSJan Lentfer 	rpos = wpabuf_put(resp, CHAP_MD5_LEN);
95*6d49e1aeSJan Lentfer 	chap_md5(id, password, password_len, challenge, challenge_len, rpos);
96*6d49e1aeSJan Lentfer 	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", rpos, CHAP_MD5_LEN);
97*6d49e1aeSJan Lentfer 
98*6d49e1aeSJan Lentfer 	return resp;
99*6d49e1aeSJan Lentfer }
100*6d49e1aeSJan Lentfer 
101*6d49e1aeSJan Lentfer 
102*6d49e1aeSJan Lentfer int eap_peer_md5_register(void)
103*6d49e1aeSJan Lentfer {
104*6d49e1aeSJan Lentfer 	struct eap_method *eap;
105*6d49e1aeSJan Lentfer 	int ret;
106*6d49e1aeSJan Lentfer 
107*6d49e1aeSJan Lentfer 	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
108*6d49e1aeSJan Lentfer 				    EAP_VENDOR_IETF, EAP_TYPE_MD5, "MD5");
109*6d49e1aeSJan Lentfer 	if (eap == NULL)
110*6d49e1aeSJan Lentfer 		return -1;
111*6d49e1aeSJan Lentfer 
112*6d49e1aeSJan Lentfer 	eap->init = eap_md5_init;
113*6d49e1aeSJan Lentfer 	eap->deinit = eap_md5_deinit;
114*6d49e1aeSJan Lentfer 	eap->process = eap_md5_process;
115*6d49e1aeSJan Lentfer 
116*6d49e1aeSJan Lentfer 	ret = eap_peer_method_register(eap);
117*6d49e1aeSJan Lentfer 	if (ret)
118*6d49e1aeSJan Lentfer 		eap_peer_method_free(eap);
119*6d49e1aeSJan Lentfer 	return ret;
120*6d49e1aeSJan Lentfer }
121