View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.auth;
28  
29  import org.apache.http.Consts;
30  import org.junit.Assert;
31  import org.junit.Test;
32  
33  public class TestNTLMEngineImpl {
34  
35      @Test
36      public void testMD4() throws Exception {
37          checkMD4("", "31d6cfe0d16ae931b73c59d7e0c089c0");
38          checkMD4("a", "bde52cb31de33e46245e05fbdbd6fb24");
39          checkMD4("abc", "a448017aaf21d8525fc10ae87aa6729d");
40          checkMD4("message digest", "d9130a8164549fe818874806e1c7014b");
41          checkMD4("abcdefghijklmnopqrstuvwxyz", "d79e1c308aa5bbcdeea8ed63df412da9");
42          checkMD4("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
43                  "043f8582f241db351ce627e153e7f0e4");
44          checkMD4(
45                  "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
46                  "e33b4ddc9c38f2199c3e7b164fcc0536");
47      }
48  
49      /* Test suite helper */
50      static byte toNibble(final char c) {
51          if (c >= 'a' && c <= 'f') {
52              return (byte) (c - 'a' + 0x0a);
53          }
54          return (byte) (c - '0');
55      }
56  
57      /* Test suite helper */
58      static byte[] toBytes(final String hex) {
59          final byte[] rval = new byte[hex.length() / 2];
60          int i = 0;
61          while (i < rval.length) {
62              rval[i] = (byte) ((toNibble(hex.charAt(i * 2)) << 4) | (toNibble(hex
63                      .charAt(i * 2 + 1))));
64              i++;
65          }
66          return rval;
67      }
68  
69      /* Test suite MD4 helper */
70      static void checkMD4(final String input, final String hexOutput) throws Exception {
71          NTLMEngineImpl.MD4 md4;
72          md4 = new NTLMEngineImpl.MD4();
73          md4.update(input.getBytes(Consts.ASCII));
74          final byte[] answer = md4.getOutput();
75          final byte[] correctAnswer = toBytes(hexOutput);
76          if (answer.length != correctAnswer.length) {
77              throw new Exception("Answer length disagrees for MD4('" + input + "')");
78          }
79          int i = 0;
80          while (i < answer.length) {
81              if (answer[i] != correctAnswer[i]) {
82                  throw new Exception("Answer value for MD4('" + input + "') disagrees at position "
83                          + Integer.toString(i));
84              }
85              i++;
86          }
87      }
88  
89      @Test
90      public void testLMResponse() throws Exception {
91          final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
92              null,
93              null,
94              "SecREt01",
95              toBytes("0123456789abcdef"),
96              null,
97              null,
98              null,
99              null,
100             null,
101             null);
102 
103         checkArraysMatch(toBytes("c337cd5cbd44fc9782a667af6d427c6de67c20c2d3e77c56"),
104             gen.getLMResponse());
105     }
106 
107     @Test
108     public void testNTLMResponse() throws Exception {
109         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
110             null,
111             null,
112             "SecREt01",
113             toBytes("0123456789abcdef"),
114             null,
115             null,
116             null,
117             null,
118             null,
119             null);
120 
121         checkArraysMatch(toBytes("25a98c1c31e81847466b29b2df4680f39958fb8c213a9cc6"),
122             gen.getNTLMResponse());
123     }
124 
125     @Test
126     public void testLMv2Response() throws Exception {
127         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
128             "DOMAIN",
129             "user",
130             "SecREt01",
131             toBytes("0123456789abcdef"),
132             "DOMAIN",
133             null,
134             toBytes("ffffff0011223344"),
135             toBytes("ffffff0011223344"),
136             null,
137             null);
138 
139         checkArraysMatch(toBytes("d6e6152ea25d03b7c6ba6629c2d6aaf0ffffff0011223344"),
140             gen.getLMv2Response());
141     }
142 
143     @Test
144     public void testNTLMv2Response() throws Exception {
145         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
146             "DOMAIN",
147             "user",
148             "SecREt01",
149             toBytes("0123456789abcdef"),
150             "DOMAIN",
151             toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"),
152             toBytes("ffffff0011223344"),
153             toBytes("ffffff0011223344"),
154             null,
155             toBytes("0090d336b734c301"));
156 
157         checkArraysMatch(toBytes("01010000000000000090d336b734c301ffffff00112233440000000002000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d000000000000000000"),
158             gen.getNTLMv2Blob());
159         checkArraysMatch(toBytes("cbabbca713eb795d04c97abc01ee498301010000000000000090d336b734c301ffffff00112233440000000002000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d000000000000000000"),
160             gen.getNTLMv2Response());
161     }
162 
163     @Test
164     public void testLM2SessionResponse() throws Exception {
165         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
166             "DOMAIN",
167             "user",
168             "SecREt01",
169             toBytes("0123456789abcdef"),
170             "DOMAIN",
171             toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"),
172             toBytes("ffffff0011223344"),
173             toBytes("ffffff0011223344"),
174             null,
175             toBytes("0090d336b734c301"));
176 
177         checkArraysMatch(toBytes("ffffff001122334400000000000000000000000000000000"),
178             gen.getLM2SessionResponse());
179     }
180 
181     @Test
182     public void testNTLM2SessionResponse() throws Exception {
183         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
184             "DOMAIN",
185             "user",
186             "SecREt01",
187             toBytes("0123456789abcdef"),
188             "DOMAIN",
189             toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"),
190             toBytes("ffffff0011223344"),
191             toBytes("ffffff0011223344"),
192             null,
193             toBytes("0090d336b734c301"));
194 
195         checkArraysMatch(toBytes("10d550832d12b2ccb79d5ad1f4eed3df82aca4c3681dd455"),
196             gen.getNTLM2SessionResponse());
197     }
198 
199     @Test
200     public void testNTLMUserSessionKey() throws Exception {
201         final NTLMEngineImpl.CipherGen gen = new NTLMEngineImpl.CipherGen(
202             "DOMAIN",
203             "user",
204             "SecREt01",
205             toBytes("0123456789abcdef"),
206             "DOMAIN",
207             toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"),
208             toBytes("ffffff0011223344"),
209             toBytes("ffffff0011223344"),
210             null,
211             toBytes("0090d336b734c301"));
212 
213         checkArraysMatch(toBytes("3f373ea8e4af954f14faa506f8eebdc4"),
214             gen.getNTLMUserSessionKey());
215     }
216 
217     @Test
218     public void testType1Message() throws Exception {
219         new NTLMEngineImpl().getType1Message("myhost", "mydomain");
220     }
221 
222     @Test
223     public void testType3Message() throws Exception {
224         new NTLMEngineImpl().getType3Message("me", "mypassword", "myhost", "mydomain",
225             toBytes("0001020304050607"),
226             0xffffffff,
227             null,null);
228         new NTLMEngineImpl().getType3Message("me", "mypassword", "myhost", "mydomain",
229             toBytes("0001020304050607"),
230             0xffffffff,
231             "mytarget",
232             toBytes("02000c0044004f004d00410049004e0001000c005300450052005600450052000400140064006f006d00610069006e002e0063006f006d00030022007300650072007600650072002e0064006f006d00610069006e002e0063006f006d0000000000"));
233     }
234 
235     @Test
236     public void testRC4() throws Exception {
237         checkArraysMatch(toBytes("e37f97f2544f4d7e"),
238             NTLMEngineImpl.RC4(toBytes("0a003602317a759a"),
239                 toBytes("2785f595293f3e2813439d73a223810d")));
240     }
241 
242     /* Byte array check helper */
243     static void checkArraysMatch(final byte[] a1, final byte[] a2)
244         throws Exception {
245         Assert.assertEquals(a1.length,a2.length);
246         for (int i = 0; i < a1.length; i++) {
247             Assert.assertEquals(a1[i],a2[i]);
248         }
249     }
250 }