]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/chap_ms.c
Fix out-of-bounds accesses to ZPasswordHash arrays (#395)
[ppp.git] / pppd / chap_ms.c
index 45a10f38cd76162dbc7aa4c6bf06f5dc908ee55b..d1e0cf80212c265cdfeae2c4c6659d15c8422108 100644 (file)
 #include <linux/ppp-comp.h>
 #endif
 
-#include "pppd.h"
-#include "chap-new.h"
+#include "pppd-private.h"
+#include "options.h"
+#include "chap.h"
 #include "chap_ms.h"
 #include "magic.h"
 #include "mppe.h"
-#include "ppp-crypto.h"
+#include "crypto.h"
+#include "crypto_ms.h"
 
 #ifdef UNIT_TEST
 #undef PPP_WITH_MPPE
 #endif
 
 static void    ascii2unicode (char[], int, u_char[]);
-static void    NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]);
-static int     ChallengeResponse (u_char *, u_char *, u_char[24]);
+static void    NTPasswordHash (u_char *, int, unsigned char *);
+static int     ChallengeResponse (u_char *, u_char *, u_char*);
 static void    ChapMS_NT (u_char *, char *, int, u_char[24]);
 static void    ChapMS2_NT (u_char *, u_char[16], char *, char *, int,
                                u_char[24]);
@@ -138,7 +140,7 @@ static char *mschap2_peer_challenge = NULL;
 /*
  * Command-line options.
  */
-static option_t chapms_option_list[] = {
+static struct option chapms_option_list[] = {
 #ifdef PPP_WITH_MSLANMAN
        { "ms-lanman", o_bool, &ms_lanman,
          "Use LanMan passwd when using MS-CHAP", 1 },
@@ -502,60 +504,31 @@ print_msg:
        free(msg);
 }
 
-// TODO: Move this definition somewhere
-#define NT_RESPONSE_LEN 24
-
 static int
 ChallengeResponse(u_char *challenge,
-                 u_char PasswordHash[MD4_SIGNATURE_SIZE],
-                 u_char response[NT_RESPONSE_LEN])
+                 u_char *PasswordHash,
+                 u_char *response)
 {
-    u_char ZPasswordHash[21];
+    u_char ZPasswordHash[24];
     PPP_CIPHER_CTX *ctx;
-    int outlen = NT_RESPONSE_LEN;
-    int offset = 0;
-    int retval = 0;
 
     BZERO(ZPasswordHash, sizeof(ZPasswordHash));
-    BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE);
+    BCOPY(PasswordHash, ZPasswordHash, MD4_DIGEST_LENGTH);
 
 #if 0
     dbglog("ChallengeResponse - ZPasswordHash %.*B",
           sizeof(ZPasswordHash), ZPasswordHash);
 #endif
 
-    ctx = PPP_CIPHER_CTX_new();
-    if (ctx != NULL) {
-
-        if (PPP_CipherInit(ctx, PPP_des_ecb(), ZPasswordHash + 0, NULL, 1)) {
-
-            if (PPP_CipherUpdate(ctx, response + offset, &outlen, challenge, 8)) {
-                offset += outlen;
-
-                PPP_CIPHER_CTX_set_cipher_data(ctx, ZPasswordHash + 7);
-                if (PPP_CipherUpdate(ctx, response + offset, &outlen, challenge, 8)) {
-                    offset += outlen;
-
-                    PPP_CIPHER_CTX_set_cipher_data(ctx, ZPasswordHash + 14);
-                    if (PPP_CipherUpdate(ctx, response + offset, &outlen, challenge, 8)) {
-                        offset += outlen;
-
-                        if (PPP_CipherFinal(ctx, response + offset, &outlen)) {
-
-                            retval = 1;
-                        }
-                    }
-                }
-            }
-        }
-
-        PPP_CIPHER_CTX_free(ctx);
-    }
+    if (DesEncrypt(challenge, ZPasswordHash + 0,  response + 0) &&
+        DesEncrypt(challenge, ZPasswordHash + 7,  response + 8) &&
+        DesEncrypt(challenge, ZPasswordHash + 14, response + 16))
+        return 1;
 
 #if 0
     dbglog("ChallengeResponse - response %.24B", response);
 #endif
-    return retval;
+    return 0;
 }
 
 void
@@ -564,9 +537,9 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge,
     
 {
     PPP_MD_CTX* ctx;
-    u_char     hash[SHA1_SIGNATURE_SIZE];
+    u_char     hash[SHA_DIGEST_LENGTH];
     int     hash_len;
-    char       *user;
+    const char *user;
 
     /* remove domain from "domain\username" */
     if ((user = strrchr(username, '\\')) != NULL)
@@ -585,7 +558,7 @@ ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge,
 
                     if (PPP_DigestUpdate(ctx, user, strlen(user))) {
                         
-                        hash_len = SHA1_SIGNATURE_SIZE;
+                        hash_len = SHA_DIGEST_LENGTH;
                         if (PPP_DigestFinal(ctx, hash, &hash_len)) {
 
                             BCOPY(hash, Challenge, 8);
@@ -617,7 +590,7 @@ ascii2unicode(char ascii[], int ascii_len, u_char unicode[])
 }
 
 static void
-NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE])
+NTPasswordHash(u_char *secret, int secret_len, unsigned char* hash)
 {
     PPP_MD_CTX* ctx = PPP_MD_CTX_new();
     if (ctx != NULL) {
@@ -626,7 +599,7 @@ NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE])
 
             if (PPP_DigestUpdate(ctx, secret, secret_len)) {
 
-                int hash_len = MD4_SIGNATURE_SIZE;
+                int hash_len = MD4_DIGEST_LENGTH;
                 PPP_DigestFinal(ctx, hash, &hash_len);
             }
         }
@@ -640,7 +613,7 @@ ChapMS_NT(u_char *rchallenge, char *secret, int secret_len,
          u_char NTResponse[24])
 {
     u_char     unicodePassword[MAX_NT_PASSWORD * 2];
-    u_char     PasswordHash[MD4_SIGNATURE_SIZE];
+    u_char     PasswordHash[MD4_DIGEST_LENGTH];
 
     /* Hash the Unicode version of the secret (== password). */
     ascii2unicode(secret, secret_len, unicodePassword);
@@ -654,7 +627,7 @@ ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username,
           char *secret, int secret_len, u_char NTResponse[24])
 {
     u_char     unicodePassword[MAX_NT_PASSWORD * 2];
-    u_char     PasswordHash[MD4_SIGNATURE_SIZE];
+    u_char     PasswordHash[MD4_DIGEST_LENGTH];
     u_char     Challenge[8];
 
     ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
@@ -675,7 +648,7 @@ ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
 {
     int                        i;
     u_char             UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
-    u_char             PasswordHash[MD4_SIGNATURE_SIZE];
+    u_char             PasswordHash[MD4_DIGEST_LENGTH];
 
     /* LANMan password is case insensitive */
     BZERO(UcasePassword, sizeof(UcasePassword));
@@ -691,10 +664,10 @@ ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
 
 
 void
-GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
-                             u_char NTResponse[24], u_char PeerChallenge[16],
-                             u_char *rchallenge, char *username,
-                             u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1])
+GenerateAuthenticatorResponse(unsigned char* PasswordHashHash,
+                             unsigned char *NTResponse, unsigned char *PeerChallenge,
+                             unsigned char *rchallenge, char *username,
+                             unsigned char *authResponse)
 {
     /*
      * "Magic" constants used in response generation, from RFC 2759.
@@ -713,7 +686,7 @@ GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
 
     int                i;
     PPP_MD_CTX *ctx;
-    u_char     Digest[SHA1_SIGNATURE_SIZE];
+    u_char     Digest[SHA_DIGEST_LENGTH];
     int     hash_len;
     u_char     Challenge[8];
 
@@ -722,7 +695,7 @@ GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
 
         if (PPP_DigestInit(ctx, PPP_sha1())) {
 
-            if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_SIGNATURE_SIZE)) {
+            if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_DIGEST_LENGTH)) {
 
                 if (PPP_DigestUpdate(ctx, NTResponse, 24)) {
 
@@ -775,8 +748,8 @@ GenerateAuthenticatorResponsePlain
                 u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1])
 {
     u_char     unicodePassword[MAX_NT_PASSWORD * 2];
-    u_char     PasswordHash[MD4_SIGNATURE_SIZE];
-    u_char     PasswordHashHash[MD4_SIGNATURE_SIZE];
+    u_char     PasswordHash[MD4_DIGEST_LENGTH];
+    u_char     PasswordHashHash[MD4_DIGEST_LENGTH];
 
     /* Hash (x2) the Unicode version of the secret (== password). */
     ascii2unicode(secret, secret_len, unicodePassword);
@@ -798,8 +771,8 @@ static void
 Set_Start_Key(u_char *rchallenge, char *secret, int secret_len)
 {
     u_char     unicodePassword[MAX_NT_PASSWORD * 2];
-    u_char     PasswordHash[MD4_SIGNATURE_SIZE];
-    u_char     PasswordHashHash[MD4_SIGNATURE_SIZE];
+    u_char     PasswordHash[MD4_DIGEST_LENGTH];
+    u_char     PasswordHashHash[MD4_DIGEST_LENGTH];
 
     /* Hash (x2) the Unicode version of the secret (== password). */
     ascii2unicode(secret, secret_len, unicodePassword);
@@ -816,8 +789,8 @@ static void
 SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer)
 {
     u_char     unicodePassword[MAX_NT_PASSWORD * 2];
-    u_char     PasswordHash[MD4_SIGNATURE_SIZE];
-    u_char     PasswordHashHash[MD4_SIGNATURE_SIZE];
+    u_char     PasswordHash[MD4_DIGEST_LENGTH];
+    u_char     PasswordHashHash[MD4_DIGEST_LENGTH];
     /* Hash (x2) the Unicode version of the secret (== password). */
     ascii2unicode(secret, secret_len, unicodePassword);
     NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
@@ -863,7 +836,7 @@ ChapMS(u_char *rchallenge, char *secret, int secret_len,
  * Authenticator Response.
  */
 void
-ChapMS2(u_char *rchallenge, u_char *PeerChallenge,
+ChapMS2(unsigned char *rchallenge, unsigned char *PeerChallenge,
        char *user, char *secret, int secret_len, unsigned char *response,
        u_char authResponse[], int authenticator)
 {
@@ -922,7 +895,7 @@ chapms_init(void)
 {
        chap_register_digest(&chapms_digest);
        chap_register_digest(&chapms2_digest);
-       add_options(chapms_option_list);
+       ppp_add_options(chapms_option_list);
 }
 #else