📄 otp_mppe.c
字号:
for (i = 0; i < sizeof(auth_md); ++i) (void) sprintf(&auth_md_string[i * 2 + 2], "%02X", auth_md[i]); /* And then octet conversion. Ugh! */ auth_octet_string[0] = '0'; auth_octet_string[1] = 'x'; (void) sprintf(&auth_octet_string[2], "%02X", rvp->vp_strvalue[0]); for (i = 0; i < sizeof(auth_md_string) - 1; ++i) (void) sprintf(&auth_octet_string[i * 2 +4], "%02X", auth_md_string[i]); vp = pairmake("MS-CHAP2-Success", auth_octet_string, T_OP_EQ); rad_assert(vp != NULL); pairadd(avp, vp); } /* Generate mutual auth info. */ /* * Now, set some MPPE related attributes. */ vp = pairmake("MS-MPPE-Encryption-Policy", otp_mppe_policy[opt->mschapv2_mppe_policy], T_OP_EQ); rad_assert(vp != NULL); pairadd(avp, vp); vp = pairmake("MS-MPPE-Encryption-Types", otp_mppe_types[opt->mschapv2_mppe_types], T_OP_EQ); rad_assert(vp != NULL); pairadd(avp, vp); /* If no MPPE, we're done. */ if (!opt->mschapv2_mppe_policy) return; /* * Generate the MPPE initial session key, per RFC 3079. * (Although, RFC 2548 leaves us guessing at how to generate this.) * For MS-CHAPv2 we support all key lengths (40-, 56- and 128-bit), * although MPPE via RADIUS supports only 40- and 128-bit keys. * This is a bit more complicated than MS-CHAP. Start by generating * a "master session key" * MSB16(SHA(NTPasswordHashHash|NT_RESPONSE|MAGIC1)), where * NTPasswordHashHash is MD4(MD4(unicode(password))), NT_RESPONSE * is from the MS-CHAP2-Response attribute, and MAGIC1 is a * constant from RFC 3079. Then, we derive asymmetric send/receive * keys from the master session key. The "master send key" is * MSBx(SHA(MASTERKEY|SHSPAD1|MAGIC3|SHSPAD2)), * and the "master receive key" is * MSBx(SHA(MASTERKEY|SHSPAD1|MAGIC2|SHSPAD2)), where * MASTERKEY is the "master session key" generated above, and the * other values are constants from RFC 3079. MSBx is the x-most * significant bytes, where x is 5, 7, or 16 as appropriate for * the desired key length. We always generate 16 byte (128-bit) * keys, the NAS is required to truncate as needed. */ { /* These constants and key vars are named from RFC 3079. */ /* "This is the MPPE Master Key" */ unsigned char Magic1[27] = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; /* "On the client side, this is the send key; " "on the server side, it is the receive key." */ unsigned char Magic2[84] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x2e }; /* "On the client side, this is the receive key; " "on the server side, it is the send key." */ unsigned char Magic3[84] = { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x2e }; unsigned char SHSpad1[40] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char SHSpad2[40] = { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 }; unsigned char MasterKey[16]; unsigned char MasterSendKey[16]; unsigned char MasterReceiveKey[16]; SHA_CTX ctx; unsigned char sha_md[SHA_DIGEST_LENGTH];#if 0 /* salting/encoding now handled in lib/radius.c:tunnel_pwencode() */ unsigned char md5_md[MD5_DIGEST_LENGTH]; /* From RFC 2548: S R A */ unsigned char encode_buf[MAX_STRING_LEN + AUTH_VECTOR_LEN + 2]; int secretlen; /* A useless value required by RFC 2548. */ unsigned char salt[2]; unsigned char mppe_key[32]; /* 1 + 16 + padding */ /* 0x ( ASCII(salt) ) */ unsigned char mppe_key_string[2 + (2 * sizeof(salt)) + /* ( ASCII(mppe_key) ) \0 */ (2 * sizeof(mppe_key)) + 1];#else /* 0 */ /* 0x ( ASCII(mppe_key) ) \0 */ unsigned char mppe_key_string[2 + (2 * sizeof(MasterKey)) + 1];#endif /* else !0 */ /* Generate the master session key. */ SHA1_Init(&ctx); SHA1_Update(&ctx, password_md_md, MD4_DIGEST_LENGTH); SHA1_Update(&ctx, rvp->vp_strvalue + 26, 24); SHA1_Update(&ctx, Magic1, sizeof(Magic1)); SHA1_Final(sha_md, &ctx); (void) memcpy(MasterKey, sha_md, 16); /* Generate the master send key. */ SHA1_Init(&ctx); SHA1_Update(&ctx, MasterKey, 16); SHA1_Update(&ctx, SHSpad1, 40); SHA1_Update(&ctx, Magic3, sizeof(Magic3)); SHA1_Update(&ctx, SHSpad2, 40); SHA1_Final(sha_md, &ctx); (void) memcpy(MasterSendKey, sha_md, 16); /* Generate the master receive key. */ SHA1_Init(&ctx); SHA1_Update(&ctx, MasterKey, 16); SHA1_Update(&ctx, SHSpad1, 40); SHA1_Update(&ctx, Magic2, sizeof(Magic3)); SHA1_Update(&ctx, SHSpad2, 40); SHA1_Final(sha_md, &ctx); (void) memcpy(MasterReceiveKey, sha_md, 16); /* * Now, generate the MS-MPPE-Send-Key attribute. */#if 0 /* Setup the salt value. */ salt[0] = 0x80; salt[1] = 0x01; /* Encode the key. */ (void) memset(mppe_key, 0, sizeof(mppe_key)); mppe_key[0] = 16; /* length */ (void) memcpy(&mppe_key[1], MasterSendKey, 16); secretlen = strlen(request->secret); (void) memcpy(encode_buf, request->secret, secretlen); (void) memcpy(encode_buf + secretlen, request->packet->vector, AUTH_VECTOR_LEN); (void) memcpy(encode_buf + secretlen + 16, salt, 2); (void) MD5(encode_buf, secretlen + AUTH_VECTOR_LEN + 2, md5_md); for (i = 0; i < 16; ++i) mppe_key[i] ^= md5_md[i]; (void) memcpy(encode_buf + secretlen, mppe_key, 16); (void) MD5(encode_buf, secretlen + 16, md5_md); for (i = 0; i < 16; ++i) mppe_key[i + 16] ^= md5_md[i]; /* Whew. Now stringify it for pairmake(). */ mppe_key_string[0] = '0'; mppe_key_string[1] = 'x'; (void) sprintf(&mppe_key_string[2], "%02X", salt[0]); (void) sprintf(&mppe_key_string[4], "%02X", salt[1]); for (i = 0; i < sizeof(mppe_key); ++i) (void) sprintf(&mppe_key_string[i*2+6], "%02X", mppe_key[i]);#else /* 0 */ mppe_key_string[0] = '0'; mppe_key_string[1] = 'x'; for (i = 0; i < sizeof(MasterSendKey); ++i) (void) sprintf(&mppe_key_string[i*2+2], "%02X", MasterSendKey[i]);#endif /* else !0 */ vp = pairmake("MS-MPPE-Send-Key", mppe_key_string, T_OP_EQ); rad_assert(vp != NULL); pairadd(avp, vp); /* * Generate the MS-MPPE-Recv-Key attribute. */#if 0 /* Setup the salt value. */ salt[0] = 0x80; salt[1] = 0x02; /* Encode the key. */ (void) memset(mppe_key, 0, sizeof(mppe_key)); mppe_key[0] = 16; /* length */ (void) memcpy(&mppe_key[1], MasterReceiveKey, 16); secretlen = strlen(request->secret); (void) memcpy(encode_buf, request->secret, secretlen); (void) memcpy(encode_buf + secretlen, request->packet->vector, AUTH_VECTOR_LEN); (void) memcpy(encode_buf + secretlen + 16, salt, 2); (void) MD5(encode_buf, secretlen + AUTH_VECTOR_LEN + 2, md5_md); for (i = 0; i < 16; ++i) mppe_key[i] ^= md5_md[i]; (void) memcpy(encode_buf + secretlen, mppe_key, 16); (void) MD5(encode_buf, secretlen + 16, md5_md); for (i = 0; i < 16; ++i) mppe_key[i + 16] ^= md5_md[i]; /* Whew. Now stringify it for pairmake(). */ mppe_key_string[0] = '0'; mppe_key_string[1] = 'x'; (void) sprintf(&mppe_key_string[2], "%02X", salt[0]); (void) sprintf(&mppe_key_string[4], "%02X", salt[1]); for (i = 0; i < sizeof(mppe_key); ++i) (void) sprintf(&mppe_key_string[i*2+6], "%02X", mppe_key[i]);#else /* 0 */ mppe_key_string[0] = '0'; mppe_key_string[1] = 'x'; for (i = 0; i < sizeof(MasterReceiveKey); ++i) (void) sprintf(&mppe_key_string[i*2+2], "%02X", MasterReceiveKey[i]);#endif /* else !0 */ vp = pairmake("MS-MPPE-Recv-Key", mppe_key_string, T_OP_EQ); rad_assert(vp != NULL); pairadd(avp, vp); } /* (doing mppe) */ } /* PWE_MSCHAP2 */ break; /* PWE_MSCHAP2 */ } /* switch (pwe) */ return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -