예제 #1
0
        internal static bool TransformBuffer(CipherSuiteInfo cipher, ICryptoTransform transform, byte[] inputBuffer, int inputOffset, int inputCount, out byte[] outputBuffer)
        {
            outputBuffer = null;
            if (inputCount % transform.InputBlockSize != 0)
            {
                throw new Exception("Input data size doesn't match block size");
            }
            int blockCount = inputCount / transform.InputBlockSize;

            outputBuffer = new byte[blockCount * transform.OutputBlockSize];
            if (transform.CanTransformMultipleBlocks)
            {
                transform.TransformBlock(inputBuffer, inputOffset, blockCount * transform.InputBlockSize, outputBuffer, 0);
            }
            else
            {
                for (int i = 0; i < blockCount; i++)
                {
                    int input  = inputOffset + i * transform.InputBlockSize;
                    int output = i * transform.OutputBlockSize;
                    transform.TransformBlock(inputBuffer, input, transform.InputBlockSize, outputBuffer, output);
                }
            }
            // Remove IV from the beginning of the fragment if necessary?
            if (cipher.CipherType == ECipherType.Block && cipher.HasExplicitIV)
            {
                byte[] temp = new byte[outputBuffer.Length - cipher.RecordIVLength];
                Buffer.BlockCopy(outputBuffer, cipher.RecordIVLength, temp, 0, temp.Length);
                outputBuffer = temp;
            }
            return(true);
        }
예제 #2
0
 public static bool VerifyMAC(CipherSuiteInfo cipher, KeyedHashAlgorithm hasher, ulong seqNum, ERecordType recordType, byte[] buffer, out byte[] bufferWithoutMac)
 {
     bufferWithoutMac = null;
     if (cipher.CipherType == ECipherType.Stream || cipher.CipherType == ECipherType.Block)
     {
         if (buffer.Length < cipher.MACLength)
         {
             return(false);
         }
         bufferWithoutMac = new byte[buffer.Length - cipher.MACLength];
         Buffer.BlockCopy(buffer, 0, bufferWithoutMac, 0, bufferWithoutMac.Length);
         byte[] hash = CreateMAC(EProtocol.SSLv30, hasher, seqNum, recordType, bufferWithoutMac, 0);
         for (int i = 1; i <= cipher.MACLength; i++)
         {
             if (buffer[buffer.Length - i] != hash[hash.Length - i])
             {
                 byte[] originalMac = new byte[16];
                 Buffer.BlockCopy(buffer, buffer.Length - cipher.MACLength, originalMac, 0, cipher.MACLength);
                 throw new HttpsException($"MAC verification fail:\n{BufferFormat.AsHexString(originalMac, cipher.MACLength)}{BufferFormat.AsHexString(hash, cipher.MACLength)}");
             }
         }
         return(true);
     }
     return(false);
 }
예제 #3
0
 public CipherKeyBlock(CipherSuiteInfo cipherSuite, PseudoRandomFunctionSSL prf)
 {
     ClientWriteMACKey = prf.GetBytes(cipherSuite.MACKeyLength);
     ServerWriteMACKey = prf.GetBytes(cipherSuite.MACKeyLength);
     ClientWriteKey    = prf.GetBytes(cipherSuite.EncKeyLength);
     ServerWriteKey    = prf.GetBytes(cipherSuite.EncKeyLength);
     ClientWriteIV     = prf.GetBytes(cipherSuite.FixedIVLength);
     ServerWriteIV     = prf.GetBytes(cipherSuite.FixedIVLength);
 }
예제 #4
0
 public static bool Select(ECipherSuite[] selectFrom, out CipherSuiteInfo selected)
 {
     selected = null;
     foreach (ECipherSuite suite in SupportedSuites.Keys)
     {
         if (selectFrom.Contains(suite))
         {
             selected = SupportedSuites[suite];
             return(true);
         }
     }
     return(false);
 }
예제 #5
0
        // --- Handshake Packets -------------------------------------------------------------------------------------
        // -----------------------------------------------------------------------------------------------------------

        private void ReceiveClientHello(ICertificateProvider certProvider, INetState ns, HttpsReader reader)
        {
            HttpsCmsgHello packet = new HttpsCmsgHello(reader);

            if (packet.SessionID != null)
            {
                throw new HttpsException($"provided a sessionID (unsupported)", reader);
            }
            if (!SupportedCiphers.Select(packet.Ciphers, out CipherSuiteInfo cipherSelected))
            {
                throw new HttpsException("does not support any of our cipher suites", reader);
            }
            CipherSuite   = cipherSelected;
            _ClientRandom = packet.ClientRandom;
            _ServerRandom = new byte[32];
            Randoms.NextBytesUnixTimePrefix(_ServerRandom);
            HttpsWriter serverHello     = new HttpsSmsgHello(ns.Https, CipherSuite.CipherSuite, SessionIdentifier, _ServerRandom);
            HttpsWriter serverCerts     = new HttpsSmsgCertificate(ns.Https, certProvider.HttpsGetCerts());
            HttpsWriter serverHelloDone = new HttpsSmsgHelloDone(ns.Https);

            Send(ns, serverHello);
            Send(ns, serverCerts);
            Send(ns, serverHelloDone);
        }
예제 #6
0
 public static bool CreateMAC(CipherSuiteInfo cipher, KeyedHashAlgorithm hasher, ulong seqNum, ERecordType recordType, byte[] buffer, int offset, out byte[] mac)
 {
     mac = CreateMAC(EProtocol.SSLv30, hasher, seqNum, recordType, buffer, offset);
     return(true);
 }
예제 #7
0
 private static void Add(CipherSuiteInfo info)
 {
     SupportedSuites[info.CipherSuite] = info;
 }