github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/upstreamproxy/go-ntlm/ntlm/ntlmv1_test.go (about)

     1  //Copyright 2013 Thomson Reuters Global Resources. BSD License please see License file for more information
     2  
     3  package ntlm
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/base64"
     8  	"encoding/hex"
     9  	"testing"
    10  )
    11  
    12  func TestLMOWFv1(t *testing.T) {
    13  	// Sample from MS-NLMP
    14  	result, err := lmowfv1("Password")
    15  	expected, _ := hex.DecodeString("e52cac67419a9a224a3b108f3fa6cb6d")
    16  	if err != nil || !bytes.Equal(result, expected) {
    17  		t.Errorf("LMNOWFv1 is not correct, got %s expected %s", hex.EncodeToString(result), "e52cac67419a9a224a3b108f3fa6cb6d")
    18  	}
    19  }
    20  
    21  func TestNTOWFv1(t *testing.T) {
    22  	// Sample from MS-NLMP
    23  	result := ntowfv1("Password")
    24  	expected, _ := hex.DecodeString("a4f49c406510bdcab6824ee7c30fd852")
    25  	if !bytes.Equal(result, expected) {
    26  		t.Error("NTOWFv1 is not correct")
    27  	}
    28  }
    29  
    30  func checkV1Value(t *testing.T, name string, value []byte, expected string, err error) {
    31  	if err != nil {
    32  		t.Errorf("NTLMv1 %s received error: %s", name, err)
    33  	} else {
    34  		expectedBytes, _ := hex.DecodeString(expected)
    35  		if !bytes.Equal(expectedBytes, value) {
    36  			t.Errorf("NTLMv1 %s is not correct got %s expected %s", name, hex.EncodeToString(value), expected)
    37  		}
    38  	}
    39  }
    40  
    41  // There was an issue where all NTLMv1 authentications with extended session security
    42  // would authenticate. This was due to a bug in the MS-NLMP docs. This tests for that issue
    43  func TestNtlmV1ExtendedSessionSecurity(t *testing.T) {
    44  	// NTLMv1 with extended session security
    45  	challengeMessage := "TlRMTVNTUAACAAAAAAAAADgAAABVgphiRy3oSZvn1I4AAAAAAAAAAKIAogA4AAAABQEoCgAAAA8CAA4AUgBFAFUAVABFAFIAUwABABwAVQBLAEIAUAAtAEMAQgBUAFIATQBGAEUAMAA2AAQAFgBSAGUAdQB0AGUAcgBzAC4AbgBlAHQAAwA0AHUAawBiAHAALQBjAGIAdAByAG0AZgBlADAANgAuAFIAZQB1AHQAZQByAHMALgBuAGUAdAAFABYAUgBlAHUAdABlAHIAcwAuAG4AZQB0AAAAAAA="
    46  	authenticateMessage := "TlRMTVNTUAADAAAAGAAYAJgAAAAYABgAsAAAAAAAAABIAAAAOgA6AEgAAAAWABYAggAAABAAEADIAAAAVYKYYgUCzg4AAAAPMQAwADAAMAAwADEALgB3AGMAcABAAHQAaABvAG0AcwBvAG4AcgBlAHUAdABlAHIAcwAuAGMAbwBtAE4AWQBDAFMATQBTAEcAOQA5ADAAOQBRWAK3h/TIywAAAAAAAAAAAAAAAAAAAAA3tp89kZU1hs1XZp7KTyGm3XsFAT9stEDW9YXDaeYVBmBcBb//2FOu"
    47  
    48  	challengeData, _ := base64.StdEncoding.DecodeString(challengeMessage)
    49  	c, _ := ParseChallengeMessage(challengeData)
    50  
    51  	authenticateData, _ := base64.StdEncoding.DecodeString(authenticateMessage)
    52  	msg, err := ParseAuthenticateMessage(authenticateData, 1)
    53  	if err != nil {
    54  		t.Errorf("Could not process authenticate message: %s", err)
    55  	}
    56  
    57  	context, err := CreateServerSession(Version1, ConnectionlessMode)
    58  	if err != nil {
    59  		t.Errorf("Could not create NTLMv1 session")
    60  	}
    61  	context.SetUserInfo("100001.wcp.thomsonreuters.com", "notmypass", "")
    62  	context.SetServerChallenge(c.ServerChallenge)
    63  	err = context.ProcessAuthenticateMessage(msg)
    64  	if err == nil {
    65  		t.Errorf("This message should have failed to authenticate, but it passed")
    66  	}
    67  }
    68  
    69  func TestNtlmV1(t *testing.T) {
    70  	flags := uint32(0)
    71  	flags = NTLMSSP_NEGOTIATE_KEY_EXCH.Set(flags)
    72  	flags = NTLMSSP_NEGOTIATE_56.Set(flags)
    73  	flags = NTLMSSP_NEGOTIATE_128.Set(flags)
    74  	flags = NTLMSSP_NEGOTIATE_VERSION.Set(flags)
    75  	flags = NTLMSSP_TARGET_TYPE_SERVER.Set(flags)
    76  	flags = NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags)
    77  	flags = NTLMSSP_NEGOTIATE_NTLM.Set(flags)
    78  	flags = NTLMSSP_NEGOTIATE_SEAL.Set(flags)
    79  	flags = NTLMSSP_NEGOTIATE_SIGN.Set(flags)
    80  	flags = NTLM_NEGOTIATE_OEM.Set(flags)
    81  	flags = NTLMSSP_NEGOTIATE_UNICODE.Set(flags)
    82  
    83  	n := new(V1ClientSession)
    84  	n.SetUserInfo("User", "Password", "Domain")
    85  	n.NegotiateFlags = flags
    86  	n.responseKeyNT, _ = hex.DecodeString("a4f49c406510bdcab6824ee7c30fd852")
    87  	n.responseKeyLM, _ = hex.DecodeString("e52cac67419a9a224a3b108f3fa6cb6d")
    88  	n.clientChallenge, _ = hex.DecodeString("aaaaaaaaaaaaaaaa")
    89  	n.serverChallenge, _ = hex.DecodeString("0123456789abcdef")
    90  
    91  	var err error
    92  	// 4.2.2.1.3 Session Base Key and Key Exchange Key
    93  	err = n.computeSessionBaseKey()
    94  	checkV1Value(t, "sessionBaseKey", n.sessionBaseKey, "d87262b0cde4b1cb7499becccdf10784", err)
    95  	err = n.computeKeyExchangeKey()
    96  	checkV1Value(t, "keyExchangeKey", n.keyExchangeKey, "d87262b0cde4b1cb7499becccdf10784", err)
    97  
    98  	// 4.2.2.2.1 NTLMv1 Response
    99  	// NTChallengeResponse with With NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY not set
   100  	err = n.computeExpectedResponses()
   101  	checkV1Value(t, "NTChallengeResponse", n.ntChallengeResponse, "67c43011f30298a2ad35ece64f16331c44bdbed927841f94", err)
   102  	// 4.2.2.2.2 LMv1 Response
   103  	// The LmChallengeResponse is specified in section 3.3.1. With the NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY flag
   104  	// not set and with the NoLMResponseNTLMv1 flag not set
   105  	checkV1Value(t, "LMChallengeResponse", n.lmChallengeResponse, "98def7b87f88aa5dafe2df779688a172def11c7d5ccdef13", err)
   106  
   107  	// If the NTLMSSP_NEGOTIATE_LM_KEY flag is set then the KeyExchangeKey is:
   108  	n.NegotiateFlags = NTLMSSP_NEGOTIATE_LM_KEY.Set(n.NegotiateFlags)
   109  	err = n.computeKeyExchangeKey()
   110  	checkV1Value(t, "keyExchangeKey with NTLMSSP_NEGOTIATE_LM_KEY", n.keyExchangeKey, "b09e379f7fbecb1eaf0afdcb0383c8a0", err)
   111  	n.NegotiateFlags = NTLMSSP_NEGOTIATE_LM_KEY.Unset(n.NegotiateFlags)
   112  
   113  	// 4.2.2.2.3 Encrypted Session Key
   114  	//n.randomSessionKey, _ = hex.DecodeString("55555555555555555555555555555555")
   115  
   116  	// RC4 decryption of the EncryptedRandomSessionKey with the KeyExchange key
   117  	//err = n.computeKeyExchangeKey()
   118  	//n.encryptedRandomSessionKey, err = hex.DecodeString("518822b1b3f350c8958682ecbb3e3cb7")
   119  	//err = n.computeExportedSessionKey()
   120  	//checkV1Value(t, "ExportedSessionKey", n.exportedSessionKey, "55555555555555555555555555555555", err)
   121  
   122  	// NTLMSSP_REQUEST_NON_NT_SESSION_KEY is set:
   123  	n.NegotiateFlags = NTLMSSP_REQUEST_NON_NT_SESSION_KEY.Set(n.NegotiateFlags)
   124  	err = n.computeKeyExchangeKey()
   125  	//	n.encryptedRandomSessionKey, err = hex.DecodeString("7452ca55c225a1ca04b48fae32cf56fc")
   126  	//	err = n.computeExportedSessionKey()
   127  	//	checkV1Value(t, "ExportedSessionKey - NTLMSSP_REQUEST_NON_NT_SESSION_KEY", n.exportedSessionKey, "55555555555555555555555555555555", err)
   128  	n.NegotiateFlags = NTLMSSP_REQUEST_NON_NT_SESSION_KEY.Unset(n.NegotiateFlags)
   129  
   130  	// NTLMSSP_NEGOTIATE_LM_KEY is set:
   131  	n.NegotiateFlags = NTLMSSP_NEGOTIATE_LM_KEY.Set(n.NegotiateFlags)
   132  	err = n.computeKeyExchangeKey()
   133  	//	n.encryptedRandomSessionKey, err = hex.DecodeString("4cd7bb57d697ef9b549f02b8f9b37864")
   134  	//	err = n.computeExportedSessionKey()
   135  	//	checkV1Value(t, "ExportedSessionKey - NTLMSSP_NEGOTIATE_LM_KEY", n.exportedSessionKey, "55555555555555555555555555555555", err)
   136  	n.NegotiateFlags = NTLMSSP_NEGOTIATE_LM_KEY.Unset(n.NegotiateFlags)
   137  
   138  	// 4.2.2.3 Messages
   139  	challengeMessageBytes, _ := hex.DecodeString("4e544c4d53535000020000000c000c003800000033820a820123456789abcdef00000000000000000000000000000000060070170000000f530065007200760065007200")
   140  	challengeMessage, err := ParseChallengeMessage(challengeMessageBytes)
   141  	if err == nil {
   142  		challengeMessage.String()
   143  	} else {
   144  		t.Errorf("Could not parse challenge message: %s", err)
   145  	}
   146  
   147  	client := new(V1ClientSession)
   148  	client.SetUserInfo("User", "Password", "Domain")
   149  	err = client.ProcessChallengeMessage(challengeMessage)
   150  	if err != nil {
   151  		t.Errorf("Could not process challenge message: %s", err)
   152  	}
   153  
   154  	server := new(V1ServerSession)
   155  	server.SetUserInfo("User", "Password", "Domain")
   156  	authenticateMessageBytes, err := hex.DecodeString("4e544c4d5353500003000000180018006c00000018001800840000000c000c00480000000800080054000000100010005c000000100010009c000000358280e20501280a0000000f44006f006d00610069006e00550073006500720043004f004d005000550054004500520098def7b87f88aa5dafe2df779688a172def11c7d5ccdef1367c43011f30298a2ad35ece64f16331c44bdbed927841f94518822b1b3f350c8958682ecbb3e3cb7")
   157  	authenticateMessage, err := ParseAuthenticateMessage(authenticateMessageBytes, 1)
   158  	if err == nil {
   159  		authenticateMessage.String()
   160  	} else {
   161  		t.Errorf("Could not parse authenticate message: %s", err)
   162  	}
   163  
   164  	server = new(V1ServerSession)
   165  	server.SetUserInfo("User", "Password", "Domain")
   166  	server.serverChallenge = challengeMessage.ServerChallenge
   167  
   168  	err = server.ProcessAuthenticateMessage(authenticateMessage)
   169  	if err != nil {
   170  		t.Errorf("Could not process authenticate message: %s", err)
   171  	}
   172  }
   173  
   174  func TestNTLMv1WithClientChallenge(t *testing.T) {
   175  	flags := uint32(0)
   176  	flags = NTLMSSP_NEGOTIATE_56.Set(flags)
   177  	flags = NTLMSSP_NEGOTIATE_VERSION.Set(flags)
   178  	flags = NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY.Set(flags)
   179  	flags = NTLMSSP_TARGET_TYPE_SERVER.Set(flags)
   180  	flags = NTLMSSP_NEGOTIATE_ALWAYS_SIGN.Set(flags)
   181  	flags = NTLMSSP_NEGOTIATE_NTLM.Set(flags)
   182  	flags = NTLMSSP_NEGOTIATE_SEAL.Set(flags)
   183  	flags = NTLMSSP_NEGOTIATE_SIGN.Set(flags)
   184  	flags = NTLM_NEGOTIATE_OEM.Set(flags)
   185  	flags = NTLMSSP_NEGOTIATE_UNICODE.Set(flags)
   186  
   187  	n := new(V1Session)
   188  	n.NegotiateFlags = flags
   189  	n.responseKeyNT, _ = hex.DecodeString("a4f49c406510bdcab6824ee7c30fd852")
   190  	n.responseKeyLM, _ = hex.DecodeString("e52cac67419a9a224a3b108f3fa6cb6d")
   191  	n.clientChallenge, _ = hex.DecodeString("aaaaaaaaaaaaaaaa")
   192  	n.serverChallenge, _ = hex.DecodeString("0123456789abcdef")
   193  
   194  	var err error
   195  	// 4.2.2.1.3 Session Base Key and Key Exchange Key
   196  	err = n.computeExpectedResponses()
   197  	err = n.computeSessionBaseKey()
   198  	checkV1Value(t, "sessionBaseKey", n.sessionBaseKey, "d87262b0cde4b1cb7499becccdf10784", err)
   199  	checkV1Value(t, "LMv1Response", n.lmChallengeResponse, "aaaaaaaaaaaaaaaa00000000000000000000000000000000", err)
   200  	checkV1Value(t, "NTLMv1Response", n.ntChallengeResponse, "7537f803ae367128ca458204bde7caf81e97ed2683267232", err)
   201  	err = n.computeKeyExchangeKey()
   202  	checkV1Value(t, "keyExchangeKey", n.keyExchangeKey, "eb93429a8bd952f8b89c55b87f475edc", err)
   203  
   204  	challengeMessageBytes, _ := hex.DecodeString("4e544c4d53535000020000000c000c003800000033820a820123456789abcdef00000000000000000000000000000000060070170000000f530065007200760065007200")
   205  	challengeMessage, err := ParseChallengeMessage(challengeMessageBytes)
   206  	if err == nil {
   207  		challengeMessage.String()
   208  	} else {
   209  		t.Errorf("Could not parse challenge message: %s", err)
   210  	}
   211  
   212  	client := new(V1ClientSession)
   213  	client.SetUserInfo("User", "Password", "Domain")
   214  	err = client.ProcessChallengeMessage(challengeMessage)
   215  	if err != nil {
   216  		t.Errorf("Could not process challenge message: %s", err)
   217  	}
   218  
   219  	server := new(V1ServerSession)
   220  	server.SetUserInfo("User", "Password", "Domain")
   221  	server.serverChallenge = challengeMessage.ServerChallenge
   222  
   223  	authenticateMessageBytes, _ := hex.DecodeString("4e544c4d5353500003000000180018006c00000018001800840000000c000c00480000000800080054000000100010005c000000000000009c000000358208820501280a0000000f44006f006d00610069006e00550073006500720043004f004d0050005500540045005200aaaaaaaaaaaaaaaa000000000000000000000000000000007537f803ae367128ca458204bde7caf81e97ed2683267232")
   224  	authenticateMessage, err := ParseAuthenticateMessage(authenticateMessageBytes, 1)
   225  	if err == nil {
   226  		authenticateMessage.String()
   227  	} else {
   228  		t.Errorf("Could not parse authenticate message: %s", err)
   229  	}
   230  
   231  	err = server.ProcessAuthenticateMessage(authenticateMessage)
   232  	if err != nil {
   233  		t.Errorf("Could not process authenticate message: %s", err)
   234  	}
   235  
   236  	checkV1Value(t, "SealKey", server.ClientSealingKey, "04dd7f014d8504d265a25cc86a3a7c06", nil)
   237  	checkV1Value(t, "SignKey", server.ClientSigningKey, "60e799be5c72fc92922ae8ebe961fb8d", nil)
   238  }