Beispiel #1
0
 /// <summary>
 /// This will change the encryption keys used to create resume tickets, thus
 /// invalidating all existing tickets.
 /// </summary>
 public void InvalidateAllTickets()
 {
     lock (m_syncRoot)
     {
         var state = m_state.Clone();
         state.ServerKeyName       = Guid.NewGuid();
         state.ServerHMACKey       = SaltGenerator.Create(32);
         state.ServerEncryptionkey = SaltGenerator.Create(32);
         m_state = state;
     }
 }
        private unsafe void CreateResumeTicket(Guid userToken, out byte[] ticket, out byte[] sessionSecret)
        {
#if SQLCLR
            ticket        = null;
            sessionSecret = null;
#else
            State state = m_state;

            //Ticket Structure:
            //  byte      TicketVersion = 1
            //  Guid      ServerKeyName
            //  DateTime  AuthenticationTime
            //  byte[16]  IV
            //  byte[]    Encrypted Session Data 32+16
            //  byte[32]  HMAC (Sha2-256)

            const int encryptedLength = 32 + 16;
            const int ticketSize      = 1 + 16 + 8 + 16 + encryptedLength + 32;

            byte[] initializationVector = SaltGenerator.Create(16);
            sessionSecret = SaltGenerator.Create(32);
            byte[] userTokenBytes = userToken.ToRfcBytes();
            byte[] dataToEncrypt  = new byte[encryptedLength];
            sessionSecret.CopyTo(dataToEncrypt, 0);
            userTokenBytes.CopyTo(dataToEncrypt, sessionSecret.Length);
            ticket = new byte[ticketSize];

            using (Aes aes = Cipher.CreateAes())
            {
                aes.Key     = state.ServerEncryptionkey;
                aes.IV      = initializationVector;
                aes.Mode    = CipherMode.CBC;
                aes.Padding = PaddingMode.None;
                ICryptoTransform decrypt       = aes.CreateEncryptor();
                byte[]           encryptedData = decrypt.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);

                fixed(byte *lp = ticket)
                {
                    BinaryStreamPointerWrapper stream = new BinaryStreamPointerWrapper(lp, ticket.Length);

                    stream.Write((byte)1);
                    stream.Write(state.ServerKeyName);
                    stream.Write(DateTime.UtcNow.RoundDownToNearestMinute());
                    stream.Write(initializationVector);
                    stream.Write(encryptedData); //Encrypted data, 32 byte session key, n byte user token
                    stream.Write(HMAC <Sha256Digest> .Compute(state.ServerHMACKey, ticket, 0, ticket.Length - 32));
                }
            }
#endif
        }
Beispiel #3
0
        private bool TryResumeSession(Stream stream, byte[] certSignatures, out Guid userToken)
        {
#if SQLCLR
            userToken = Guid.Empty;
            return(false);
#else
            //Resume Session:
            // C => S
            // byte    ResumeSession
            // byte    TicketLength
            // byte[]  Ticket
            // byte    ClientChallengeLength
            // byte[]  ClientChallenge

            // S <= C
            // byte    HashMethod
            // byte    ServerChallengeLength
            // byte[]  ServerChallenge

            IDigest hash            = new Sha384Digest();
            byte[]  serverChallenge = SaltGenerator.Create(16);
            stream.WriteByte((byte)HashMethod.Sha384);
            stream.WriteByte((byte)serverChallenge.Length);
            stream.Write(serverChallenge);
            stream.Flush();

            // C => S
            // byte    ClientResponseLength
            // byte[]  ClientChallenge

            byte[] ticket          = stream.ReadBytes(stream.ReadNextByte());
            byte[] clientChallenge = stream.ReadBytes(stream.ReadNextByte());
            byte[] clientResponse  = stream.ReadBytes(stream.ReadByte());

            // S => C
            // bool   IsSuccessful
            // byte   ServerResponseLength
            // byte[] ServerResponse

            if (TryLoadTicket(ticket, out byte[] secret, out userToken))
Beispiel #4
0
        private bool TryResumeSession(ref Stream secureStream, Stream stream2, byte[] certSignatures)
        {
#if SQLCLR
            return(false);
#else
            if (m_resumeTicket != null && m_sessionSecret != null)
            {
                //Resume Session:
                // C => S
                // byte    ResumeSession
                // byte    TicketLength
                // byte[]  Ticket
                // byte    ClientChallengeLength
                // byte[]  ClientChallenge

                byte[] clientChallenge = SaltGenerator.Create(16);
                stream2.WriteByte((byte)AuthenticationMode.ResumeSession);
                stream2.WriteByte((byte)m_resumeTicket.Length);
                stream2.Write(m_resumeTicket);
                stream2.WriteByte((byte)clientChallenge.Length);
                stream2.Write(clientChallenge);
                stream2.Flush();

                // S <= C
                // byte    HashMethod
                // byte    ServerChallengeLength
                // byte[]  ServerChallenge

                HashMethod hashMethod      = (HashMethod)stream2.ReadNextByte();
                IDigest    hash            = Scram.CreateDigest(hashMethod);
                byte[]     serverChallenge = stream2.ReadBytes(stream2.ReadNextByte());

                // C => S
                // byte    ClientResponseLength
                // byte[]  ClientChallenge

                byte[] clientResponse = hash.ComputeHash(serverChallenge, clientChallenge, m_sessionSecret, certSignatures);
                byte[] serverResponse = hash.ComputeHash(clientChallenge, serverChallenge, m_sessionSecret, certSignatures);

                stream2.WriteByte((byte)clientResponse.Length);
                stream2.Write(clientResponse);
                stream2.Flush();

                // S => C
                // bool   IsSuccessful
                // byte   ServerResponseLength
                // byte[] ServerResponse

                if (stream2.ReadBoolean())
                {
                    byte[] serverResponseCheck = stream2.ReadBytes(stream2.ReadNextByte());

                    // C => S
                    // bool   IsSuccessful
                    if (serverResponse.SecureEquals(serverResponseCheck))
                    {
                        stream2.Write(true);
                        stream2.Flush();
                        secureStream = stream2;
                        return(true);
                    }

                    stream2.Write(false);
                    stream2.Flush();
                }

                m_resumeTicket  = null;
                m_sessionSecret = null;
            }
            return(false);
#endif
        }
Beispiel #5
0
        private bool TryResumeSession(Stream stream, byte[] certSignatures, out Guid userToken)
        {
#if SQLCLR
            userToken = Guid.Empty;
            return(false);
#else
            //Resume Session:
            // C => S
            // byte    ResumeSession
            // byte    TicketLength
            // byte[]  Ticket
            // byte    ClientChallengeLength
            // byte[]  ClientChallenge

            // S <= C
            // byte    HashMethod
            // byte    ServerChallengeLength
            // byte[]  ServerChallenge

            IDigest hash            = new Sha384Digest();
            byte[]  serverChallenge = SaltGenerator.Create(16);
            stream.WriteByte((byte)HashMethod.Sha384);
            stream.WriteByte((byte)serverChallenge.Length);
            stream.Write(serverChallenge);
            stream.Flush();

            // C => S
            // byte    ClientResponseLength
            // byte[]  ClientChallenge

            byte[] ticket          = stream.ReadBytes(stream.ReadNextByte());
            byte[] clientChallenge = stream.ReadBytes(stream.ReadNextByte());
            byte[] clientResponse  = stream.ReadBytes(stream.ReadByte());

            byte[] secret;

            // S => C
            // bool   IsSuccessful
            // byte   ServerResponseLength
            // byte[] ServerResponse

            if (TryLoadTicket(ticket, out secret, out userToken))
            {
                byte[] clientResponseCheck = hash.ComputeHash(serverChallenge, clientChallenge, secret, certSignatures);
                if (clientResponse.SecureEquals(clientResponseCheck))
                {
                    byte[] serverResponse = hash.ComputeHash(clientChallenge, serverChallenge, secret, certSignatures);
                    stream.Write(true);
                    stream.WriteByte((byte)serverResponse.Length);
                    stream.Write(serverResponse);
                    stream.Flush();

                    if (stream.ReadBoolean())
                    {
                        return(true);
                    }
                    return(false);
                }
            }
            stream.Write(false);
            userToken = default(Guid);
            return(false);
#endif
        }