22 RCSID(
"$Id: 399689abf3b775f3d16f9fb82fa35d931cbd6497 $")
29 #include <freeradius-devel/rad_assert.h>
35 #include <openssl/des.h>
36 #include <openssl/md4.h>
37 #include <openssl/md5.h>
38 #include <openssl/sha.h>
82 size_t i, passcode_len;
85 uint8_t mppe_keys[32];
88 char mppe_keys_string[2 + (2 *
sizeof(mppe_keys)) + 1];
91 (void) memset(mppe_keys, 0,
sizeof(mppe_keys));
100 passcode_len = strlen(passcode);
101 for (i = 0; i < passcode_len; ++i) {
103 password_unicode[i * 2] = *passcode++;
104 password_unicode[i * 2 + 1] = 0;
108 (void) MD4(password_unicode, 2 * passcode_len, password_md);
113 mppe_keys_string[0] =
'0';
114 mppe_keys_string[1] =
'x';
116 for (i = 0; i < 32; ++i) {
117 (void) sprintf(&mppe_keys_string[i*2+2],
"%02X", mppe_keys[i]);
145 uint8_t md1[SHA_DIGEST_LENGTH];
146 uint8_t md2[SHA_DIGEST_LENGTH];
147 uint8_t auth_md[SHA_DIGEST_LENGTH];
149 char auth_md_string[2 + (2 *
sizeof(auth_md)) + 1];
157 char auth_octet_string[2 + 2 + (2 *
sizeof(auth_md_string))];
159 char const *username = request->
username->vp_strvalue;
160 int username_len = request->
username->vp_length;
164 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
165 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
166 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
167 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
171 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
172 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
173 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
174 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
184 passcode_len = strlen(passcode);
185 for (i = 0; i < passcode_len; ++i) {
187 password_unicode[i * 2] = *passcode++;
188 password_unicode[i * 2 + 1] = 0;
191 (void) MD4(password_unicode, 2 * passcode_len, password_md);
198 SHA1_Update(&ctx, rvp->vp_strvalue + 26, 24);
199 SHA1_Update(&ctx, magic1,
sizeof(magic1));
200 SHA1_Final(md1, &ctx);
204 SHA1_Update(&ctx, rvp->vp_strvalue + 2, 16);
205 SHA1_Update(&ctx, cvp->vp_strvalue, 16);
206 SHA1_Update(&ctx, username, username_len);
207 SHA1_Final(md2, &ctx);
211 SHA1_Update(&ctx, md1, SHA_DIGEST_LENGTH);
212 SHA1_Update(&ctx, md2, 8);
213 SHA1_Update(&ctx, magic2,
sizeof(magic2));
214 SHA1_Final(auth_md, &ctx);
217 auth_md_string[0] =
'S';
218 auth_md_string[1] =
'=';
219 for (i = 0; i <
sizeof(auth_md); ++i) {
220 (void) sprintf(&auth_md_string[i * 2 + 2],
"%02X", auth_md[i]);
224 auth_octet_string[0] =
'0';
225 auth_octet_string[1] =
'x';
226 (void) sprintf(&auth_octet_string[2],
"%02X", rvp->vp_strvalue[0]);
227 for (i = 0; i <
sizeof(auth_md_string) - 1; ++i) {
228 (void) sprintf(&auth_octet_string[i * 2 +4],
"%02X", auth_md_string[i]);
269 uint8_t Magic1[27] = {
270 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
271 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
272 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
275 uint8_t Magic2[84] = {
276 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
277 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
278 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
279 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
280 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
281 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
282 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
283 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
284 0x6b, 0x65, 0x79, 0x2e
287 uint8_t Magic3[84] = {
288 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
289 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
290 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
291 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
292 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
293 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
294 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
295 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
296 0x6b, 0x65, 0x79, 0x2e
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
306 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
307 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
308 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
309 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
311 uint8_t MasterKey[16];
312 uint8_t MasterSendKey[16];
313 uint8_t MasterReceiveKey[16];
316 uint8_t sha_md[SHA_DIGEST_LENGTH];
319 char mppe_key_string[2 + (2 *
sizeof(MasterKey)) + 1];
324 SHA1_Update(&ctx, rvp->vp_strvalue + 26, 24);
325 SHA1_Update(&ctx, Magic1,
sizeof(Magic1));
326 SHA1_Final(sha_md, &ctx);
327 (void) memcpy(MasterKey, sha_md, 16);
331 SHA1_Update(&ctx, MasterKey, 16);
332 SHA1_Update(&ctx, SHSpad1, 40);
333 SHA1_Update(&ctx, Magic3,
sizeof(Magic3));
334 SHA1_Update(&ctx, SHSpad2, 40);
335 SHA1_Final(sha_md, &ctx);
336 (void) memcpy(MasterSendKey, sha_md, 16);
340 SHA1_Update(&ctx, MasterKey, 16);
341 SHA1_Update(&ctx, SHSpad1, 40);
342 SHA1_Update(&ctx, Magic2,
sizeof(Magic3));
343 SHA1_Update(&ctx, SHSpad2, 40);
344 SHA1_Final(sha_md, &ctx);
345 (void) memcpy(MasterReceiveKey, sha_md, 16);
350 mppe_key_string[0] =
'0';
351 mppe_key_string[1] =
'x';
352 for (i = 0; i <
sizeof(MasterSendKey); ++i) {
353 (void) sprintf(&mppe_key_string[i*2+2],
"%02X", MasterSendKey[i]);
361 mppe_key_string[0] =
'0';
362 mppe_key_string[1] =
'x';
363 for (i = 0; i <
sizeof(MasterReceiveKey); ++i) {
364 (void) sprintf(&mppe_key_string[i*2+2],
"%02X", MasterReceiveKey[i]);
const fr_dict_attr_t * pwattr[8]
uint32_t mschapv2_mppe_types
Key type/length for mschapv2/mppe.
uint32_t mschap_mppe_policy
Whether or not do to mppe for mschap .
VALUE_PAIR * username
Cached username VALUE_PAIR from request RADIUS_PACKET.
VALUE_PAIR * vps
Result of decoding the packet into VALUE_PAIRs.
static char const * otp_mppe_policy[3]
void void MD4_DIGEST_LENGTH
Stores an attribute, a value and various bits of other data.
VALUE_PAIR * fr_pair_find_by_da(VALUE_PAIR *head, fr_dict_attr_t const *da, int8_t tag)
Find the pair with the matching DAs.
uint32_t mschapv2_mppe_policy
Whether or not do to mppe for mschapv2.
static const uint8_t magic2[84]
#define pair_make_reply(_a, _b, _c)
#define OTP_MAX_PASSCODE_LEN
RADIUS_PACKET * packet
Incoming request.
static char const * otp_mppe_types[3]
static const uint8_t SHSpad1[40]
static const uint8_t SHSpad2[40]
static const uint8_t magic1[27]
void otp_mppe(REQUEST *request, otp_pwe_t pwe, rlm_otp_t const *opt, char const *passcode)
uint32_t mschap_mppe_types
key type/length for mschap/mppe.
#define USES_APPLE_DEPRECATED_API