hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kwri...@apache.org
Subject svn commit: r1787322 - in /httpcomponents/httpclient/branches/pull-66/httpclient/src: main/java/org/apache/http/impl/auth/NTLMEngineImpl.java test/java/org/apache/http/impl/auth/TestNTLMEngineImpl.java
Date Fri, 17 Mar 2017 10:43:16 GMT
Author: kwright
Date: Fri Mar 17 10:43:16 2017
New Revision: 1787322

URL: http://svn.apache.org/viewvc?rev=1787322&view=rev
Log:
Pass in random number generator and current time to CipherGen, so we can build repeatable
Type3 responses

Modified:
    httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java
    httpcomponents/httpclient/branches/pull-66/httpclient/src/test/java/org/apache/http/impl/auth/TestNTLMEngineImpl.java

Modified: httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java?rev=1787322&r1=1787321&r2=1787322&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java
(original)
+++ httpcomponents/httpclient/branches/pull-66/httpclient/src/main/java/org/apache/http/impl/auth/NTLMEngineImpl.java
Fri Mar 17 10:43:16 2017
@@ -32,6 +32,7 @@ import java.security.Key;
 import java.security.MessageDigest;
 import java.util.Arrays;
 import java.util.Locale;
+import java.util.Random;
 
 import javax.crypto.Cipher;
 import javax.crypto.spec.SecretKeySpec;
@@ -300,31 +301,28 @@ final class NTLMEngineImpl implements NT
     }
 
     /** Calculate a challenge block */
-    private static byte[] makeRandomChallenge() throws NTLMEngineException {
-        if (RND_GEN == null) {
-            throw new NTLMEngineException("Random generator not available");
-        }
+    private static byte[] makeRandomChallenge(final Random random) throws NTLMEngineException
{
         final byte[] rval = new byte[8];
-        synchronized (RND_GEN) {
-            RND_GEN.nextBytes(rval);
+        synchronized (random) {
+            random.nextBytes(rval);
         }
         return rval;
     }
 
     /** Calculate a 16-byte secondary key */
-    private static byte[] makeSecondaryKey() throws NTLMEngineException {
-        if (RND_GEN == null) {
-            throw new NTLMEngineException("Random generator not available");
-        }
+    private static byte[] makeSecondaryKey(final Random random) throws NTLMEngineException
{
         final byte[] rval = new byte[16];
-        synchronized (RND_GEN) {
-            RND_GEN.nextBytes(rval);
+        synchronized (random) {
+            random.nextBytes(rval);
         }
         return rval;
     }
 
     protected static class CipherGen {
 
+        protected final Random random;
+        protected final long currentTime;
+
         protected final String domain;
         protected final String user;
         protected final String password;
@@ -356,10 +354,14 @@ final class NTLMEngineImpl implements NT
         protected byte[] ntlm2SessionResponseUserSessionKey = null;
         protected byte[] lanManagerSessionKey = null;
 
-        public CipherGen(final String domain, final String user, final String password,
+        public CipherGen(final Random random, final long currentTime,
+            final String domain, final String user, final String password,
             final byte[] challenge, final String target, final byte[] targetInformation,
             final byte[] clientChallenge, final byte[] clientChallenge2,
             final byte[] secondaryKey, final byte[] timestamp) {
+            this.random = random;
+            this.currentTime = currentTime;
+
             this.domain = domain;
             this.target = target;
             this.user = user;
@@ -372,16 +374,21 @@ final class NTLMEngineImpl implements NT
             this.timestamp = timestamp;
         }
 
-        public CipherGen(final String domain, final String user, final String password,
-            final byte[] challenge, final String target, final byte[] targetInformation)
{
-            this(domain, user, password, challenge, target, targetInformation, null, null,
null, null);
+        public CipherGen(final Random random, final long currentTime,
+            final String domain,
+            final String user,
+            final String password,
+            final byte[] challenge,
+            final String target,
+            final byte[] targetInformation) {
+            this(random, currentTime, domain, user, password, challenge, target, targetInformation,
null, null, null, null);
         }
 
         /** Calculate and return client challenge */
         public byte[] getClientChallenge()
             throws NTLMEngineException {
             if (clientChallenge == null) {
-                clientChallenge = makeRandomChallenge();
+                clientChallenge = makeRandomChallenge(random);
             }
             return clientChallenge;
         }
@@ -390,7 +397,7 @@ final class NTLMEngineImpl implements NT
         public byte[] getClientChallenge2()
             throws NTLMEngineException {
             if (clientChallenge2 == null) {
-                clientChallenge2 = makeRandomChallenge();
+                clientChallenge2 = makeRandomChallenge(random);
             }
             return clientChallenge2;
         }
@@ -399,7 +406,7 @@ final class NTLMEngineImpl implements NT
         public byte[] getSecondaryKey()
             throws NTLMEngineException {
             if (secondaryKey == null) {
-                secondaryKey = makeSecondaryKey();
+                secondaryKey = makeSecondaryKey(random);
             }
             return secondaryKey;
         }
@@ -461,7 +468,7 @@ final class NTLMEngineImpl implements NT
         /** Calculate a timestamp */
         public byte[] getTimestamp() {
             if (timestamp == null) {
-                long time = System.currentTimeMillis();
+                long time = this.currentTime;
                 time += 11644473600000l; // milliseconds from January 1, 1601 -> epoch.
                 time *= 10000; // tenths of a microsecond.
                 // convert to little-endian byte array.
@@ -1230,11 +1237,14 @@ final class NTLMEngineImpl implements NT
          *
          * @return The response as above.
          */
-        String getResponse() {
+        public String getResponse() {
             return new String(Base64.encodeBase64(getBytes()), StandardCharsets.US_ASCII);
         }
 
         public byte[] getBytes() {
+            if (messageContents == null) {
+                buildMessage();
+            }
             final byte[] resp;
             if ( messageContents.length > currentOutputPosition ) {
                 final byte[] tmp = new byte[currentOutputPosition];
@@ -1242,8 +1252,11 @@ final class NTLMEngineImpl implements NT
                 messageContents = tmp;
             }
             return messageContents;
-         }
+        }
 
+        protected void buildMessage() {
+            throw new RuntimeException("Message builder not implemented for "+getClass().getName());
+        }
     }
 
     /** Type 1 message assembly class */
@@ -1310,7 +1323,7 @@ final class NTLMEngineImpl implements NT
          * it
          */
         @Override
-        String getResponse() {
+        protected void buildMessage() {
             int domainBytesLength = 0;
             if ( domainBytes != null ) {
                 domainBytesLength = domainBytes.length;
@@ -1360,8 +1373,6 @@ final class NTLMEngineImpl implements NT
             if (domainBytes != null) {
                 addBytes(domainBytes);
             }
-
-            return super.getResponse();
         }
 
     }
@@ -1478,6 +1489,21 @@ final class NTLMEngineImpl implements NT
             this(domain, host, user, password, nonce, type2Flags, target, targetInformation,
null, null, null);
         }
 
+        /** More primitive constructor: don't include cert or previous messages.
+        */
+        Type3Message(final Random random, final long currentTime,
+            final String domain,
+            final String host,
+            final String user,
+            final String password,
+            final byte[] nonce,
+            final int type2Flags,
+            final String target,
+            final byte[] targetInformation)
+            throws NTLMEngineException {
+            this(random, currentTime, domain, host, user, password, nonce, type2Flags, target,
targetInformation, null, null, null);
+        }
+
         /** Constructor. Pass the arguments we will need */
         Type3Message(final String domain,
             final String host,
@@ -1491,6 +1517,28 @@ final class NTLMEngineImpl implements NT
             final byte[] type1Message,
             final byte[] type2Message)
             throws NTLMEngineException {
+            this(RND_GEN, System.currentTimeMillis(), domain, host, user, password, nonce,
type2Flags, target, targetInformation, peerServerCertificate, type1Message, type2Message);
+        }
+
+        /** Constructor. Pass the arguments we will need */
+        Type3Message(final Random random, final long currentTime,
+            final String domain,
+            final String host,
+            final String user,
+            final String password,
+            final byte[] nonce,
+            final int type2Flags,
+            final String target,
+            final byte[] targetInformation,
+            final X509Certificate peerServerCertificate,
+            final byte[] type1Message,
+            final byte[] type2Message)
+            throws NTLMEngineException {
+
+            if (random == null) {
+                throw new NTLMEngineException("Random generator not available");
+            }
+
             // Save the flags
             this.type2Flags = type2Flags;
             this.type1Message = type1Message;
@@ -1511,7 +1559,8 @@ final class NTLMEngineImpl implements NT
             }
 
              // Create a cipher generator class.  Use domain BEFORE it gets modified!
-            final CipherGen gen = new CipherGen(unqualifiedDomain,
+            final CipherGen gen = new CipherGen(random, currentTime,
+                unqualifiedDomain,
                 user,
                 password,
                 nonce,
@@ -1599,7 +1648,7 @@ final class NTLMEngineImpl implements NT
 
         /** Assemble the response */
         @Override
-        String getResponse() {
+        protected void buildMessage() {
             final int ntRespLen = ntResp.length;
             final int lmRespLen = lmResp.length;
 
@@ -1733,7 +1782,6 @@ final class NTLMEngineImpl implements NT
                 final byte[] mic = hmacMD5.getOutput();
                 System.arraycopy( mic, 0, messageContents, micPosition, mic.length );
             }
-            return super.getResponse();
         }
 
         /**

Modified: httpcomponents/httpclient/branches/pull-66/httpclient/src/test/java/org/apache/http/impl/auth/TestNTLMEngineImpl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/branches/pull-66/httpclient/src/test/java/org/apache/http/impl/auth/TestNTLMEngineImpl.java?rev=1787322&r1=1787321&r2=1787322&view=diff
==============================================================================
--- httpcomponents/httpclient/branches/pull-66/httpclient/src/test/java/org/apache/http/impl/auth/TestNTLMEngineImpl.java
(original)
+++ httpcomponents/httpclient/branches/pull-66/httpclient/src/test/java/org/apache/http/impl/auth/TestNTLMEngineImpl.java
Fri Mar 17 10:43:16 2017
@@ -29,6 +29,7 @@ package org.apache.http.impl.auth;
 import org.apache.http.Consts;
 import org.junit.Assert;
 import org.junit.Test;
+import java.util.Random;
 
 public class TestNTLMEngineImpl {
 
@@ -92,6 +93,8 @@ public class TestNTLMEngineImpl {
     @Test
     public void testLMResponse() throws Exception {
         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
+            new Random(1234),
+            1234L,
             null,
             null,
             "SecREt01",
@@ -110,6 +113,8 @@ public class TestNTLMEngineImpl {
     @Test
     public void testNTLMResponse() throws Exception {
         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
+            new Random(1234),
+            1234L,
             null,
             null,
             "SecREt01",
@@ -128,6 +133,8 @@ public class TestNTLMEngineImpl {
     @Test
     public void testLMv2Response() throws Exception {
         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
+            new Random(1234),
+            1234L,
             "DOMAIN",
             "user",
             "SecREt01",
@@ -146,6 +153,8 @@ public class TestNTLMEngineImpl {
     @Test
     public void testNTLMv2Response() throws Exception {
         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
+            new Random(1234),
+            1234L,
             "DOMAIN",
             "user",
             "SecREt01",
@@ -166,6 +175,8 @@ public class TestNTLMEngineImpl {
     @Test
     public void testLM2SessionResponse() throws Exception {
         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
+            new Random(1234),
+            1234L,
             "DOMAIN",
             "user",
             "SecREt01",
@@ -184,6 +195,8 @@ public class TestNTLMEngineImpl {
     @Test
     public void testNTLM2SessionResponse() throws Exception {
         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
+            new Random(1234),
+            1234L,
             "DOMAIN",
             "user",
             "SecREt01",
@@ -202,6 +215,8 @@ public class TestNTLMEngineImpl {
     @Test
     public void testNTLMUserSessionKey() throws Exception {
         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
+            new Random(1234),
+            1234L,
             "DOMAIN",
             "user",
             "SecREt01",
@@ -219,35 +234,32 @@ public class TestNTLMEngineImpl {
 
     @Test
     public void testType1Message() throws Exception {
-        final byte[] bytes = new NTLMEngineImpl().getType1Message("myhost", "mydomain").getBytes();
-        final byte[] bytes2 = toBytes("546C524D54564E545541414241414141415949496F6741414141416F414141414141414141436741414141464153674B4141414144773D3D");
+        final byte[] bytes = new NTLMEngineImpl.Type1Message("myhost", "mydomain").getBytes();
+        final byte[] bytes2 = toBytes("4E544C4D5353500001000000018208A2000000002800000000000000280000000501280A0000000F6D00790064006F006D00610069006E004D00590048004F0053005400");
         checkArraysMatch(bytes2, bytes);
     }
 
     @Test
     public void testType3Message() throws Exception {
-        final byte[] bytes = new NTLMEngineImpl().getType3Message("me", "mypassword", "myhost",
"mydomain",
+        final byte[] bytes = new NTLMEngineImpl.Type3Message(
+            new Random(1234),
+            1234L,
+            "me", "mypassword", "myhost", "mydomain",
             toBytes("0001020304050607"),
             0xffffffff,
             null,null).getBytes();
-        // Verify the parts that have no random or timestamp component
-        checkArraysMatch(toBytes("546C524D54564E545541414441414141474141594145674141414159414267415941414141424141454142344141414142414145414967414141414D414177416A4141414142414145414359414141412F2F2F2F2F7755424B416F4141414150"),
-            0, bytes);
-        checkArraysMatch(toBytes("414141414141414141414141414141414141414141"),
-            107, bytes);
-        checkArraysMatch(toBytes("5451425A414551415477424E414545415351424F414730415A51427441486B416141427641484D416441"),
-            160, bytes);
-        final byte[] bytes2 = new NTLMEngineImpl().getType3Message("me", "mypassword", "myhost",
"mydomain",
+        checkArraysMatch(toBytes("4E544C4D53535000030000001800180048000000180018006000000004000400780000000C000C007C0000001400140088000000100010009C000000FFFFFFFF0501280A0000000FA86886A5D297814200000000000000000000000000000000EEC7568E00798491244959B9C942F4F367C5CBABEEF546F74D0045006D00790068006F00730074006D007900700061007300730077006F007200640094DDAB1EBB82C9A1AB914CAE6F199644"),
+            bytes);
+        final byte[] bytes2 = new NTLMEngineImpl.Type3Message(
+            new Random(1234),
+            1234L,
+            "me", "mypassword", "myhost", "mydomain",
             toBytes("0001020304050607"),
             0xffffffff,
             "mytarget",
             toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000")).getBytes();
-        checkArraysMatch(toBytes("546C524D54564E545541414441414141474141594145674141414353414A49415941414141424141454144794141414142414145414149424141414D41417741426745414142414145414153415141412F2F2F2F2F7755424B416F4141414150"),
-            0, bytes2);
-        checkArraysMatch(toBytes("45424141414141414141"),
-            150, bytes2);
-        checkArraysMatch(toBytes("4141414141434141774152414250414530415151424A414534414151414D41464D41525142534146594152514253414151414641426B414738416251426841476B416267417541474D416277427441414D414967427A414755416367423241475541636741754147514162774274414745416151427541433441597742764147304141414141414141414141424E41466B4152414250414530415151424A414534416251426C414730416551426F414738416377423041"),
-            182, bytes2);
+        checkArraysMatch(toBytes("4E544C4D53535000030000001800180048000000920092006000000004000400F20000000C000C00F600000014001400020100001000100016010000FFFFFFFF0501280A0000000F3695F1EA7B164788A437892FA7504320DA2D8CF378EBC83CE856A8FB985BF7783545828A91A13AE8010100000000000020CBFAD5DEB19D01A86886A5D29781420000000002000C0044004F004D00410049004E0001000C005300450052005600450052000400140064006F006D00610069006E002E0063006F006D00030022007300650072007600650072002E0064006F006D00610069006E002E0063006F006D0000000000000000004D0045006D00790068006F00730074006D007900700061007300730077006F0072006400BB1AAD36F11631CC7CBC8800CEEE1C99"),
+            bytes2);
     }
 
     @Test
@@ -266,14 +278,4 @@ public class TestNTLMEngineImpl {
         }
     }
 
-    /* Byte array check helper */
-    static void checkArraysMatch(final byte[] a1,
-        final int a2StartIndex, final byte[] a2)
-        throws Exception {
-        Assert.assertTrue(a2.length - a2StartIndex >= a1.length);
-        for (int i = 0; i < a1.length; i++) {
-            Assert.assertEquals(a1[i],a2[i + a2StartIndex]);
-        }
-    }
-
 }



Mime
View raw message