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); }
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); }
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); }
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); }
// --- 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); }
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); }
private static void Add(CipherSuiteInfo info) { SupportedSuites[info.CipherSuite] = info; }