private string GetSecurityLayerOutgoingBlob(string challenge, NTAuthentication clientContext)
        {
            int num;

            if (challenge == null)
            {
                return(null);
            }
            byte[] buffer = Convert.FromBase64String(challenge);
            try
            {
                num = clientContext.VerifySignature(buffer, 0, buffer.Length);
            }
            catch (Win32Exception)
            {
                return(null);
            }
            if (((num < 4) || (buffer[0] != 1)) || (((buffer[1] != 0) || (buffer[2] != 0)) || (buffer[3] != 0)))
            {
                return(null);
            }
            byte[] output = null;
            try
            {
                num = clientContext.MakeSignature(buffer, 0, 4, ref output);
            }
            catch (Win32Exception)
            {
                return(null);
            }
            return(Convert.ToBase64String(output, 0, num));
        }
Esempio n. 2
0
        public void NtlmSignatureTest()
        {
            FakeNtlmServer   fakeNtlmServer = new FakeNtlmServer(s_testCredentialRight);
            NTAuthentication ntAuth         = new NTAuthentication(
                isServer: false, "NTLM", s_testCredentialRight, "HTTP/foo",
                ContextFlagsPal.Connection | ContextFlagsPal.InitIntegrity | ContextFlagsPal.Confidentiality, null);

            DoNtlmExchange(fakeNtlmServer, ntAuth);

            Assert.True(fakeNtlmServer.IsAuthenticated);

            // Test MakeSignature on client side and decoding it on server side
            byte[]? output = null;
            int len = ntAuth.MakeSignature(s_Hello, 0, s_Hello.Length, ref output);

            Assert.NotNull(output);
            Assert.Equal(16 + s_Hello.Length, len);
            // Unseal the content and check it
            byte[] temp = new byte[s_Hello.Length];
            fakeNtlmServer.Unseal(output.AsSpan(16), temp);
            Assert.Equal(s_Hello, temp);
            // Check the signature
            fakeNtlmServer.VerifyMIC(temp, output.AsSpan(0, 16), sequenceNumber: 0);

            // Test creating signature on server side and decoding it with VerifySignature on client side
            byte[] serverSignedMessage = new byte[16 + s_Hello.Length];
            fakeNtlmServer.Seal(s_Hello, serverSignedMessage.AsSpan(16, s_Hello.Length));
            fakeNtlmServer.GetMIC(s_Hello, serverSignedMessage.AsSpan(0, 16), sequenceNumber: 0);
            len = ntAuth.VerifySignature(serverSignedMessage, 0, serverSignedMessage.Length);
            Assert.Equal(s_Hello.Length, len);
            // NOTE: VerifySignature doesn't return the content on Windows
            // Assert.Equal(s_Hello, serverSignedMessage.AsSpan(0, len).ToArray());
        }
Esempio n. 3
0
        // Function for SASL security layer negotiation after
        // authorization completes.
        //
        // Returns null for failure, Base64 encoded string on
        // success.
        private string GetSecurityLayerOutgoingBlob(string challenge, NTAuthentication clientContext)
        {
            // must have a security layer challenge

            if (challenge == null)
            {
                return(null);
            }

            // "unwrap" challenge

            byte[] input = Convert.FromBase64String(challenge);

            int len;

            try
            {
                len = clientContext.VerifySignature(input, 0, input.Length);
            }
            catch (Win32Exception)
            {
                // any decrypt failure is an auth failure
                return(null);
            }

            // Per RFC 2222 Section 7.2.2:
            //   the client should then expect the server to issue a
            //   token in a subsequent challenge.  The client passes
            //   this token to GSS_Unwrap and interprets the first
            //   octet of cleartext as a bit-mask specifying the
            //   security layers supported by the server and the
            //   second through fourth octets as the maximum size
            //   output_message to send to the server.
            // Section 7.2.3
            //   The security layer and their corresponding bit-masks
            //   are as follows:
            //     1 No security layer
            //     2 Integrity protection
            //       Sender calls GSS_Wrap with conf_flag set to FALSE
            //     4 Privacy protection
            //       Sender calls GSS_Wrap with conf_flag set to TRUE
            //
            // Exchange 2007 and our client only support
            // "No security layer". Therefore verify first byte is value 1
            // and the 2nd-4th bytes are value zero since token size is not
            // applicable when there is no security layer.

            if (len < 4 ||          // expect 4 bytes
                input[0] != 1 ||    // first value 1
                input[1] != 0 ||    // rest value 0
                input[2] != 0 ||
                input[3] != 0)
            {
                return(null);
            }

            // Continuing with RFC 2222 section 7.2.2:
            //   The client then constructs data, with the first octet
            //   containing the bit-mask specifying the selected security
            //   layer, the second through fourth octets containing in
            //   network byte order the maximum size output_message the client
            //   is able to receive, and the remaining octets containing the
            //   authorization identity.
            //
            // So now this contructs the "wrapped" response.  The response is
            // payload is identical to the received server payload and the
            // "authorization identity" is not supplied as it is unnecessary.

            // let MakeSignature figure out length of output
            byte[] output = null;
            try
            {
                len = clientContext.MakeSignature(input, 0, 4, ref output);
            }
            catch (Win32Exception)
            {
                // any encrypt failure is an auth failure
                return(null);
            }

            // return Base64 encoded string of signed payload
            return(Convert.ToBase64String(output, 0, len));
        }
        // Function for SASL security layer negotiation after
        // authorization completes.   
        //
        // Returns null for failure, Base64 encoded string on
        // success.
        private string GetSecurityLayerOutgoingBlob(string challenge, NTAuthentication clientContext)
        {
            // must have a security layer challenge

            if (challenge == null)
                return null;

            // "unwrap" challenge

            byte[] input = Convert.FromBase64String(challenge);

            int len;

            try
            {
                len = clientContext.VerifySignature(input, 0, input.Length);
            }
            catch (Win32Exception)
            {
                // any decrypt failure is an auth failure
                return null;
            }

            // Per RFC 2222 Section 7.2.2:
            //   the client should then expect the server to issue a 
            //   token in a subsequent challenge.  The client passes
            //   this token to GSS_Unwrap and interprets the first 
            //   octet of cleartext as a bit-mask specifying the 
            //   security layers supported by the server and the 
            //   second through fourth octets as the maximum size 
            //   output_message to send to the server.   
            // Section 7.2.3
            //   The security layer and their corresponding bit-masks
            //   are as follows:
            //     1 No security layer
            //     2 Integrity protection
            //       Sender calls GSS_Wrap with conf_flag set to FALSE
            //     4 Privacy protection
            //       Sender calls GSS_Wrap with conf_flag set to TRUE
            //
            // Exchange 2007 and our client only support 
            // "No security layer". Therefore verify first byte is value 1
            // and the 2nd-4th bytes are value zero since token size is not
            // applicable when there is no security layer.

            if (len < 4 ||          // expect 4 bytes
                input[0] != 1 ||    // first value 1
                input[1] != 0 ||    // rest value 0
                input[2] != 0 ||
                input[3] != 0)
            {
                return null;
            }

            // Continuing with RFC 2222 section 7.2.2:
            //   The client then constructs data, with the first octet 
            //   containing the bit-mask specifying the selected security
            //   layer, the second through fourth octets containing in 
            //   network byte order the maximum size output_message the client
            //   is able to receive, and the remaining octets containing the
            //   authorization identity.  
            // 
            // So now this contructs the "wrapped" response.  The response is
            // payload is identical to the received server payload and the 
            // "authorization identity" is not supplied as it is unnecessary.

            // let MakeSignature figure out length of output
            byte[] output = null;
            try
            {
                len = clientContext.MakeSignature(input, 0, 4, ref output);
            }
            catch (Win32Exception)
            {
                // any encrypt failure is an auth failure
                return null;
            }

            // return Base64 encoded string of signed payload
            return Convert.ToBase64String(output, 0, len);
        }
        // Function for SASL security layer negotiation after
        // authorization completes.
        //
        // Returns null for failure, Base64 encoded string on
        // success.
        private string GetSecurityLayerOutgoingBlob(
            string challenge,
            NTAuthentication clientContext)
        {
            // must have a security layer challenge

            if (challenge == null)
            {
                return(null);
            }

            // "unwrap" challenge

            byte[] input = Convert.FromBase64String(challenge);

            int len;

            try {
                len = clientContext.VerifySignature(input, 0, input.Length);
            }
            catch (Win32Exception) {
                // any decrypt failure is an auth failure
                return(null);
            }

            // Per RFC 2222 Section 7.2.2:
            //   the client should then expect the server to issue a
            //   token in a subsequent challenge.  The client passes
            //   this token to GSS_Unwrap and interprets the first
            //   octet of cleartext as a bit-mask specifying the
            //   security layers supported by the server and the
            //   second through fourth octets as the maximum size
            //   output_message to send to the server.
            // Section 7.2.3
            //   The security layer and their corresponding bit-masks
            //   are as follows:
            //     1 No security layer
            //     2 Integrity protection
            //       Sender calls GSS_Wrap with conf_flag set to FALSE
            //     4 Privacy protection
            //       Sender calls GSS_Wrap with conf_flag set to TRUE
            //
            // Our SmtpClient only supports "No security layer". So, make
            // sure that the server also supports this. We don't care if the
            // server also supports other features (Integrity or Privacy).
            // Therefore verify first bit in first byte is value 1.
            // We ignore the 2nd-4th bytes since token size is not
            // applicable when we select no security layer.
            if (len < 4 || (input[0] & 0x1) != 1)
            {
                return(null);
            }

            // Continuing with RFC 2222 section 7.2.2:
            //   The client then constructs data, with the first octet
            //   containing the bit-mask specifying the selected security
            //   layer, the second through fourth octets containing in
            //   network byte order the maximum size output_message the client
            //   is able to receive, and the remaining octets containing the
            //   authorization identity.
            //
            // Our response back to server is very simple. We select "No security layer".
            input[0] = 1;

            // let MakeSignature figure out length of output
            byte[] output = null;
            try {
                len = clientContext.MakeSignature(input, 0, 4, ref output);
            }
            catch (Win32Exception) {
                // any decrypt failure is an auth failure
                return(null);
            }

            // return Base64 encoded string of signed payload
            return(Convert.ToBase64String(output, 0, len));
        }