From ab309f4568da0b6b64952e082a0f7d4cb1b028f8 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Fri, 5 Nov 2010 22:26:39 +0300 Subject: auth: implemented mppe key derivation from ms-chap credentials --- accel-pptpd/auth/auth_mschap_v1.c | 34 +++++++++++ accel-pptpd/auth/auth_mschap_v2.c | 115 ++++++++++++++++++++++++++++++++++---- 2 files changed, 137 insertions(+), 12 deletions(-) diff --git a/accel-pptpd/auth/auth_mschap_v1.c b/accel-pptpd/auth/auth_mschap_v1.c index 8208ef2..c2fc432 100644 --- a/accel-pptpd/auth/auth_mschap_v1.c +++ b/accel-pptpd/auth/auth_mschap_v1.c @@ -10,9 +10,11 @@ #include #include +#include #include "log.h" #include "ppp.h" +#include "events.h" #include "ppp_auth.h" #include "ppp_lcp.h" #include "pwdb.h" @@ -97,6 +99,7 @@ static void chap_recv(struct ppp_handler_t *h); static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response_t *res, const char *name); static void chap_timeout_timer(struct triton_timer_t *t); static void chap_restart_timer(struct triton_timer_t *t); +static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash); static void print_buf(const uint8_t *buf,int size) { @@ -396,6 +399,8 @@ static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response des_encrypt(ad->val, z_hash + 7, nt_hash + 8); des_encrypt(ad->val, z_hash + 14, nt_hash + 16); + set_mppe_keys(ad, z_hash); + _free(passwd); _free(u_passwd); @@ -407,6 +412,35 @@ static int chap_check(uint8_t *ptr) return *ptr == MSCHAP_V1; } +static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash) +{ + MD4_CTX md4_ctx; + SHA_CTX sha_ctx; + uint8_t digest[20]; + + struct ev_mppe_keys_t ev_mppe = { + .ppp = ad->ppp, + .type = 1 << 2, + .policy = 1, + .recv_key = digest, + .send_key = digest, + }; + + //NtPasswordHashHash + MD4_Init(&md4_ctx); + MD4_Update(&md4_ctx, z_hash, 16); + MD4_Final(digest, &md4_ctx); + + //Get_Start_Key + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, ad->val, VALUE_SIZE); + SHA1_Final(digest, &sha_ctx); + + triton_event_fire(EV_MPPE_KEYS, &ev_mppe); +} + static int chap_restart(struct ppp_t *ppp, struct auth_data_t *auth) { struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth); diff --git a/accel-pptpd/auth/auth_mschap_v2.c b/accel-pptpd/auth/auth_mschap_v2.c index 08cdde9..374c152 100644 --- a/accel-pptpd/auth/auth_mschap_v2.c +++ b/accel-pptpd/auth/auth_mschap_v2.c @@ -14,6 +14,7 @@ #include "log.h" #include "ppp.h" +#include "events.h" #include "ppp_auth.h" #include "ppp_lcp.h" #include "pwdb.h" @@ -41,18 +42,6 @@ static int conf_max_failure = 3; static int urandom_fd; -static uint8_t magic1[39] = - {0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, - 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, - 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74}; -static uint8_t magic2[41] = - {0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, - 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, - 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, - 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, - 0x6E}; - struct chap_hdr_t { uint16_t proto; @@ -111,6 +100,7 @@ static void chap_recv(struct ppp_handler_t *h); static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response_t *msg, const char *name); static void chap_timeout_timer(struct triton_timer_t *t); static void chap_restart_timer(struct triton_timer_t *t); +static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash, uint8_t *nt_hash); static void print_buf(const uint8_t *buf, int size) { @@ -248,6 +238,19 @@ static int generate_response(struct chap_auth_data_t *ad, struct chap_response_t uint8_t response[SHA_DIGEST_LENGTH]; int i; + uint8_t magic1[39] = + {0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74}; + uint8_t magic2[41] = + {0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, + 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E}; + + passwd = pwdb_get_passwd(ad->ppp,name); if (!passwd) return -1; @@ -485,12 +488,100 @@ static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response des_encrypt(c_hash,z_hash+7,nt_hash+8); des_encrypt(c_hash,z_hash+14,nt_hash+16); + set_mppe_keys(ad, z_hash, msg->nt_hash); + _free(passwd); _free(u_passwd); return memcmp(nt_hash,msg->nt_hash,24); } +static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash, uint8_t *nt_hash) +{ + MD4_CTX md4_ctx; + SHA_CTX sha_ctx; + uint8_t digest[20]; + uint8_t send_key[20]; + uint8_t recv_key[20]; + + uint8_t pad1[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}; + + uint8_t pad2[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}; + + uint8_t 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}; + + uint8_t 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}; + + uint8_t 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}; + + struct ev_mppe_keys_t ev_mppe = { + .ppp = ad->ppp, + .type = 1 << 2, + .policy = 1, + .recv_key = recv_key, + .send_key = send_key, + }; + + //NtPasswordHashHash + MD4_Init(&md4_ctx); + MD4_Update(&md4_ctx, z_hash, 16); + MD4_Final(digest, &md4_ctx); + + //GetMasterKey + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, nt_hash, 24); + SHA1_Update(&sha_ctx, magic1, sizeof(magic1)); + SHA1_Final(digest, &sha_ctx); + + //send key + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, pad1, sizeof(pad1)); + SHA1_Update(&sha_ctx, magic3, sizeof(magic2)); + SHA1_Update(&sha_ctx, pad2, sizeof(pad2)); + SHA1_Final(send_key, &sha_ctx); + + //recv key + SHA1_Init(&sha_ctx); + SHA1_Update(&sha_ctx, digest, 16); + SHA1_Update(&sha_ctx, pad1, sizeof(pad1)); + SHA1_Update(&sha_ctx, magic2, sizeof(magic3)); + SHA1_Update(&sha_ctx, pad2, sizeof(pad2)); + SHA1_Final(recv_key, &sha_ctx); + + triton_event_fire(EV_MPPE_KEYS, &ev_mppe); +} + static int chap_check(uint8_t *ptr) { return *ptr == MSCHAP_V2; -- cgit v1.2.3