summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2010-11-05 22:26:39 +0300
committerDmitry Kozlov <xeb@mail.ru>2010-11-05 22:34:46 +0300
commitab309f4568da0b6b64952e082a0f7d4cb1b028f8 (patch)
tree218a7d0f8062e084879ca795e341f40d00dfd281
parent5d2364b07fc2bde23dcb9d71c33d56a54e423c84 (diff)
downloadaccel-ppp-xebd-ab309f4568da0b6b64952e082a0f7d4cb1b028f8.tar.gz
accel-ppp-xebd-ab309f4568da0b6b64952e082a0f7d4cb1b028f8.zip
auth: implemented mppe key derivation from ms-chap credentials
-rw-r--r--accel-pptpd/auth/auth_mschap_v1.c34
-rw-r--r--accel-pptpd/auth/auth_mschap_v2.c115
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 <openssl/md4.h>
#include <openssl/des.h>
+#include <openssl/sha.h>
#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;