예제 #1
0
		protected override void Read (TlsBuffer incoming)
		{
			ClientRandom = new SecureBuffer (incoming.ReadBytes (32));

			var length = (short)incoming.ReadByte ();
			SessionID = new SecureBuffer (incoming.ReadBytes (length));

			length = incoming.ReadInt16 ();
			if ((length % 2) != 0)
				throw new TlsException (AlertDescription.DecodeError);

			bool seenSCSV = false;
			ClientCiphers = new CipherSuiteCode [length >> 1];
			for (int i = 0; i < ClientCiphers.Length; i++) {
				ClientCiphers [i] = (CipherSuiteCode)incoming.ReadInt16 ();
				if (ClientCiphers [i] == CipherSuiteCode.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
					seenSCSV = true;
			}

			// Compression methods
			length = incoming.ReadByte ();
			incoming.Position += length;

			Extensions = new TlsExtensionCollection (incoming);

			if (seenSCSV)
				Extensions.AddRenegotiationExtension ();
		}
예제 #2
0
        /// <summary>
        /// Reads password from console displaying substitute characters instead of real ones
        /// into a sealed SecureBuffer
        /// </summary>
        public static SecureBuffer ReadPasswordToSecureBuffer(char substitute)
        {
            var result = new SecureBuffer();

            while (true)
            {
                char c = Console.ReadKey(true).KeyChar;
                if (Char.IsControl(c))
                {
                    result.Seal();
                    return(result);
                }

                var buf = Encoding.UTF8.GetBytes(new char[] { c });

                for (var i = 0; i < buf.Length; i++)
                {
                    result.Push(buf[i]);
                }

                Array.Clear(buf, 0, buf.Length);

                if (substitute != (char)0)
                {
                    Console.Write(substitute);
                }
            }
        }
예제 #3
0
        private void tbPassword_TextChanged(object sender, EventArgs e)
        {
            var pm    = App.SecurityManager.PasswordManager;
            var bytes = Encoding.UTF8.GetBytes(tbPassword.Text);

            using (var password = new SecureBuffer(bytes.Length))
            {
                foreach (var b in bytes)
                {
                    password.Push(b);
                }
                Array.Clear(bytes, 0, bytes.Length);
                password.Seal();

                var hash = pm.ComputeHash(PasswordFamily.Text, password);

                Text = "Score: {0}   Easy%: {1}  Normal%: {2} Hard%: {3}".Args(
                    pm.CalculateStrenghtScore(PasswordFamily.Text, password),
                    pm.CalculateStrenghtPercent(PasswordFamily.Text, password, DefaultPasswordManager.TOP_SCORE_MINIMUM),
                    pm.CalculateStrenghtPercent(PasswordFamily.Text, password, DefaultPasswordManager.TOP_SCORE_NORMAL),
                    pm.CalculateStrenghtPercent(PasswordFamily.Text, password, DefaultPasswordManager.TOP_SCORE_MAXIMUM));

                tbJSON.Text = hash.ToString();
            }
        }
예제 #4
0
        void Init(SecureBuffer key)
        {
            algorithm.Initialize();

            int keyLength = key.Size;

            if (key.Size > blockSize)
            {
                algorithm.TransformFinalBlock(key.Buffer, 0, keyLength);
                Buffer.BlockCopy(algorithm.Hash, 0, inputPad.Buffer, 0, digestSize);

                keyLength = digestSize;
            }
            else
            {
                Array.Copy(key.Buffer, 0, inputPad.Buffer, 0, keyLength);
            }

            Array.Clear(inputPad.Buffer, keyLength, blockSize - keyLength);
            Array.Copy(inputPad.Buffer, 0, outputPad.Buffer, 0, blockSize);

            xor(inputPad.Buffer, IPAD);
            xor(outputPad.Buffer, OPAD);

            // Initialise the digest
            algorithm.TransformBlock(inputPad.Buffer, 0, inputPad.Size, null, 0);

            final = false;
        }
예제 #5
0
        /// <summary>
        /// Signs the message using the context's session key.
        /// </summary>
        /// <remarks>
        /// The structure of the returned buffer is as follows:
        ///  - 4 bytes, unsigned big-endian integer indicating the length of the plaintext message
        ///  - 2 bytes, unsigned big-endian integer indicating the length of the signture
        ///  - The plaintext message
        ///  - The message's signature.
        /// </remarks>
        /// <param name="message"></param>
        /// <returns></returns>
        public byte[] MakeSignature(byte[] message)
        {
            SecurityStatus status = SecurityStatus.InternalError;

            SecPkgContext_Sizes sizes;
            SecureBuffer        dataBuffer;
            SecureBuffer        signatureBuffer;
            SecureBufferAdapter adapter;

            CheckLifecycle();

            sizes = QueryBufferSizes();

            dataBuffer      = new SecureBuffer(new byte[message.Length], BufferType.Data);
            signatureBuffer = new SecureBuffer(new byte[sizes.MaxSignature], BufferType.Token);

            Array.Copy(message, dataBuffer.Buffer, message.Length);

            using (adapter = new SecureBufferAdapter(new[] { dataBuffer, signatureBuffer }))
            {
                status = ContextNativeMethods.SafeMakeSignature(
                    this.ContextHandle,
                    0,
                    adapter,
                    0
                    );
            }

            if (status != SecurityStatus.OK)
            {
                SSPIException exc = new SSPIException("Failed to create message signature.", status);
                throw new SecurityException(ErrorHandling.ErrorCodes.Security.SSPI_ERROR, new string[] { exc.Message });
            }

            byte[] outMessage;
            int    position = 0;

            // Enough room for
            //  - original message length (4 bytes)
            //  - signature length        (2 bytes)
            //  - original message
            //  - signature

            outMessage = new byte[4 + 2 + dataBuffer.Length + signatureBuffer.Length];

            ByteWriter.WriteInt32_BE(dataBuffer.Length, outMessage, position);
            position += 4;

            ByteWriter.WriteInt16_BE((Int16)signatureBuffer.Length, outMessage, position);
            position += 2;

            Array.Copy(dataBuffer.Buffer, 0, outMessage, position, dataBuffer.Length);
            position += dataBuffer.Length;

            Array.Copy(signatureBuffer.Buffer, 0, outMessage, position, signatureBuffer.Length);
            position += signatureBuffer.Length;

            return(outMessage);
        }
예제 #6
0
 public SecureBuffer ComputeInitialIV(SecureBuffer cs, int size)
 {
     if (this is PseudoRandomFunctionTls12)
     {
         throw new InvalidOperationException();
     }
     return(PRF(new SecureBuffer(CipherSuite.EmptyArray), "IV block", cs, size));
 }
예제 #7
0
        public byte[] TestPRF(HandshakeHashType algorithm, byte[] secret, string seed, byte[] data, int length)
        {
            var prf = new PseudoRandomFunctionTls12(algorithm);

            var result = prf.PRF(SecureBuffer.CreateCopy(secret), seed, SecureBuffer.CreateCopy(data), length);

            return(result.StealBuffer());
        }
예제 #8
0
 protected override void Read(TlsBuffer incoming)
 {
     Hash = new SecureBuffer(incoming.ReadBytes(12));
     if (incoming.Remaining != 0)
     {
         throw new TlsException(AlertDescription.DecodeError);
     }
 }
예제 #9
0
 public static bool VerifySignature(SignatureAndHashAlgorithm type, SecureBuffer data, AsymmetricAlgorithm key, SecureBuffer signature)
 {
     using (var d = new DisposeContext()) {
         var algorithm = d.Add((HashAlgorithm)GetAlgorithm(type.Hash));
         algorithm.TransformFinalBlock(data.Buffer, 0, data.Size);
         return(VerifySignature(type, algorithm, d.Add(algorithm.Hash), key, signature));
     }
 }
예제 #10
0
        public override void HandleClient(TlsContext ctx, KeyExchange clientExchange)
        {
            var serverDh = (DiffieHellmanKeyExchange)clientExchange;

            using (var X = new SecureBuffer(dh.DecryptKeyExchange(serverDh.Y))) {
                ComputeMasterSecret(ctx, X);
            }
        }
예제 #11
0
 public override void GenerateClient(TlsContext ctx)
 {
     using (var dh = new DiffieHellmanManaged(P, G, 0)) {
         using (var X = new SecureBuffer(dh.DecryptKeyExchange(Y))) {
             Y = dh.CreateKeyExchange();
             ComputeMasterSecret(ctx, X);
         }
     }
 }
예제 #12
0
 public TlsServerHello(TlsProtocolCode protocol, SecureBuffer random, SecureBuffer session, CipherSuiteCode cipher, TlsExtensionCollection extensions)
     : base(HandshakeType.ServerHello)
 {
     ServerProtocol = protocol;
     ServerRandom   = random;
     SessionID      = session;
     SelectedCipher = cipher;
     Extensions     = extensions;
 }
예제 #13
0
		public TlsServerHello (TlsProtocolCode protocol, SecureBuffer random, SecureBuffer session, CipherSuiteCode cipher, TlsExtensionCollection extensions)
			: base (HandshakeType.ServerHello)
		{
			ServerProtocol = protocol;
			ServerRandom = random;
			SessionID = session;
			SelectedCipher = cipher;
			Extensions = extensions;
		}
		public override void GenerateClient (TlsContext context)
		{
			GenerateKeyPair (context, domainParameters, out clientQ, out clientD);
			clientKey = ExternalizeKey (clientQ);

			var agreement = CalculateAgreement (serverQ, clientD);
			using (var preMaster = new SecureBuffer (agreement.ToByteArrayUnsigned ()))
				ComputeMasterSecret (context, preMaster);
		}
예제 #15
0
        public override void ReadServer(TlsBuffer incoming)
        {
            P = incoming.ReadBytes(incoming.ReadInt16());
            G = incoming.ReadBytes(incoming.ReadInt16());
            Y = incoming.ReadBytes(incoming.ReadInt16());

            SignatureAlgorithm = new SignatureAndHashAlgorithm(incoming);
            Signature          = incoming.ReadSecureBuffer(incoming.ReadInt16());
        }
예제 #16
0
		public TlsClientHello (TlsProtocolCode protocol, SecureBuffer random, SecureBuffer session, CipherSuiteCode[] ciphers, TlsExtensionCollection extensions)
			: base (HandshakeType.ClientHello)
		{
			ClientProtocol = protocol;
			ClientRandom = random;
			SessionID = session;
			ClientCiphers = ciphers;
			Extensions = extensions;
		}
예제 #17
0
 public TlsClientHello(TlsProtocolCode protocol, SecureBuffer random, SecureBuffer session, CipherSuiteCode[] ciphers, TlsExtensionCollection extensions)
     : base(HandshakeType.ClientHello)
 {
     ClientProtocol = protocol;
     ClientRandom   = random;
     SessionID      = session;
     ClientCiphers  = ciphers;
     Extensions     = extensions;
 }
		public override void GenerateClient (TlsContext ctx)
		{
			using (var dh = new DiffieHellmanManaged (P, G, 0)) {
				using (var X = new SecureBuffer (dh.DecryptKeyExchange (Y))) {
					Y = dh.CreateKeyExchange ();
					ComputeMasterSecret (ctx, X);
				}
			}
		}
예제 #19
0
        public override void GenerateClient(TlsContext context)
        {
            GenerateKeyPair(context, domainParameters, out clientQ, out clientD);
            clientKey = ExternalizeKey(clientQ);

            var agreement = CalculateAgreement(serverQ, clientD);

            using (var preMaster = new SecureBuffer(agreement.ToByteArrayUnsigned()))
                ComputeMasterSecret(context, preMaster);
        }
예제 #20
0
		static byte[] CreateHash (HashAlgorithmType type, SecureBuffer data)
		{
			if (!HashAlgorithmProvider.IsAlgorithmSupported (type))
				throw new TlsException (AlertDescription.IlegalParameter);
			using (var d = new DisposeContext ()) {
				var algorithm = d.Add (HashAlgorithmProvider.CreateAlgorithm (type));
				algorithm.TransformBlock (data.Buffer, 0, data.Size);
				return algorithm.GetRunningHash ();
			}
		}
예제 #21
0
        public override void HandleClient(TlsContext context, KeyExchange clientExchange)
        {
            var clientKey = ((EllipticCurveKeyExchange)clientExchange).clientKey;

            clientQ = domainParameters.Curve.DecodePoint(clientKey);

            var agreement = CalculateAgreement(clientQ, serverD);

            using (var preMaster = new SecureBuffer(agreement.ToByteArrayUnsigned()))
                ComputeMasterSecret(context, preMaster);
        }
예제 #22
0
		void ComputeMasterSecret (DisposeContext d, TlsContext ctx, SecureBuffer preMasterSecret)
		{
			// Compute ClientRandom + ServerRandom
			int clen = ctx.HandshakeParameters.ClientRandom.Size;
			int slen = ctx.HandshakeParameters.ServerRandom.Size;
			int rlen = clen + slen;
			var cs = d.CreateBuffer (rlen);
			Buffer.BlockCopy (ctx.HandshakeParameters.ClientRandom.Buffer, 0, cs.Buffer, 0, clen);
			Buffer.BlockCopy (ctx.HandshakeParameters.ServerRandom.Buffer, 0, cs.Buffer, clen, slen);

			// Server Random + Client Random
			var sc = d.CreateBuffer (rlen);
			Buffer.BlockCopy (ctx.HandshakeParameters.ServerRandom.Buffer, 0, sc.Buffer, 0, slen);
			Buffer.BlockCopy (ctx.HandshakeParameters.ClientRandom.Buffer, 0, sc.Buffer, slen, clen);

			// Create master secret
			var crypto = ctx.Session.PendingCrypto;
			crypto.MasterSecret = crypto.Cipher.PRF.ComputeMasterSecret (preMasterSecret, cs);

			#if DEBUG_FULL
			if (ctx.EnableDebugging) {
				DebugHelper.WriteLine ("CS", cs);
				DebugHelper.WriteLine ("SC", sc);
				DebugHelper.WriteLine ("PRE-MASTER", preMasterSecret);
				DebugHelper.WriteLine ("MASTER SECRET", crypto.MasterSecret.Buffer);
			}
			#endif

			var keyBlock = crypto.Cipher.PRF.ComputeKeyExpansion (d, crypto.MasterSecret, sc, crypto.Cipher.KeyBlockSize);

			#if DEBUG_FULL
			if (ctx.EnableDebugging) {
				DebugHelper.WriteLine ("KEY BLOCK SIZE: {0}", crypto.Cipher.KeyBlockSize);
				DebugHelper.WriteLine ("KEY BLOCK", keyBlock.Buffer);
			}
			#endif

			crypto.ClientWriteMac = keyBlock.ReadSecureBuffer (crypto.Cipher.HashSize);
			crypto.ServerWriteMac = keyBlock.ReadSecureBuffer (crypto.Cipher.HashSize);
			crypto.ClientWriteKey = keyBlock.ReadSecureBuffer (crypto.Cipher.KeyMaterialSize);
			crypto.ServerWriteKey = keyBlock.ReadSecureBuffer (crypto.Cipher.KeyMaterialSize);

			if (crypto.Cipher.HasFixedIV) {
				crypto.ClientWriteIV = keyBlock.ReadSecureBuffer (crypto.Cipher.FixedIvSize);
				crypto.ServerWriteIV = keyBlock.ReadSecureBuffer (crypto.Cipher.FixedIvSize);

				#if DEBUG_FULL
				if (ctx.EnableDebugging) {
					DebugHelper.WriteLine ("CLIENT IV", crypto.ClientWriteIV.Buffer);
					DebugHelper.WriteLine ("SERVER IV", crypto.ServerWriteIV.Buffer);
				}
				#endif
			}
		}
예제 #23
0
        HMac(HashAlgorithm algorithm, int blockSize, SecureBuffer key)
        {
            this.algorithm  = Add(algorithm);
            this.digestSize = algorithm.HashSize / 8;
            this.blockSize  = blockSize;

            this.inputPad  = CreateBuffer(blockSize);
            this.outputPad = CreateBuffer(blockSize);

            Init(key);
        }
예제 #24
0
        /// <summary>
        /// Encrypts the byte array using the context's session key.
        /// </summary>
        /// <remarks>
        /// The structure of the returned data is as follows:
        ///  - 2 bytes, an unsigned big-endian integer indicating the length of the trailer buffer size
        ///  - 4 bytes, an unsigned big-endian integer indicating the length of the message buffer size.
        ///  - 2 bytes, an unsigned big-endian integer indicating the length of the encryption padding buffer size.
        ///  - The trailer buffer
        ///  - The message buffer
        ///  - The padding buffer.
        /// </remarks>
        /// <param name="input">The raw message to encrypt.</param>
        /// <returns>The packed and encrypted message.</returns>
        public byte[] Encrypt(byte[] input)
        {
            // The message is encrypted in place in the buffer we provide to Win32 EncryptMessage
            SecPkgContext_Sizes sizes;

            SecureBuffer        trailerBuffer;
            SecureBuffer        dataBuffer;
            SecureBuffer        paddingBuffer;
            SecureBufferAdapter adapter;

            SecurityStatus status = SecurityStatus.InvalidHandle;

            byte[] result;

            CheckLifecycle();

            sizes = QueryBufferSizes();

            trailerBuffer = new SecureBuffer(new byte[sizes.SecurityTrailer], BufferType.Token);
            dataBuffer    = new SecureBuffer(new byte[input.Length], BufferType.Data);
            paddingBuffer = new SecureBuffer(new byte[sizes.BlockSize], BufferType.Padding);

            Array.Copy(input, dataBuffer.Buffer, input.Length);

            using (adapter = new SecureBufferAdapter(new[] { trailerBuffer, dataBuffer, paddingBuffer }))
            {
                status = ContextNativeMethods.SafeEncryptMessage(
                    this.ContextHandle,
                    WrapNoEncrypt,
                    adapter,
                    0
                    );
            }

            if (status != SecurityStatus.OK)
            {
                throw new SspiException("Failed to encrypt message", status);
            }

            int position = 0;

            // Return 1 buffer with the 3 buffers joined
            result = new byte[trailerBuffer.Length + dataBuffer.Length + paddingBuffer.Length];

            Array.Copy(trailerBuffer.Buffer, 0, result, position, trailerBuffer.Length);
            position += trailerBuffer.Length;

            Array.Copy(dataBuffer.Buffer, 0, result, position, dataBuffer.Length);
            position += dataBuffer.Length;

            Array.Copy(paddingBuffer.Buffer, 0, result, position, paddingBuffer.Length);

            return(result);
        }
예제 #25
0
        void CreateServer(TlsContext ctx)
        {
            dh = new DiffieHellmanManaged();
            Y  = dh.CreateKeyExchange();
            var dhparams = dh.ExportParameters(true);

            P = dhparams.P;
            G = dhparams.G;

            using (var buffer = CreateParameterBuffer(ctx.HandshakeParameters))
                Signature = SignatureHelper.CreateSignature(SignatureAlgorithm, buffer, ctx.Configuration.PrivateKey);
        }
예제 #26
0
 static byte[] CreateHash(HashAlgorithmType type, SecureBuffer data)
 {
     if (!HashAlgorithmProvider.IsAlgorithmSupported(type))
     {
         throw new TlsException(AlertDescription.IlegalParameter);
     }
     using (var d = new DisposeContext()) {
         var algorithm = d.Add(HashAlgorithmProvider.CreateAlgorithm(type));
         algorithm.TransformBlock(data.Buffer, 0, data.Size);
         return(algorithm.GetRunningHash());
     }
 }
예제 #27
0
        public byte[] TestHMac(HandshakeHashType algorithm, byte[] key, byte[] data)
        {
            var hmac = HMac.Create(algorithm, SecureBuffer.CreateCopy(key));

            hmac.Reset();
            hmac.TransformBlock(data, 0, data.Length);

            var output = new byte [hmac.MacSize];

            hmac.TransformFinalBlock(output, 0, output.Length);

            return(output);
        }
예제 #28
0
        public void GenerateHardenedRandomBytes_ShouldYieldHighEntropy()
        {
            // Arrange.
            var valueRange                     = 256;
            var confidence                     = 0.223d;
            var curveTolerance                 = 5m;
            var length                         = (valueRange * valueRange);
            var target                         = (RandomByteArrayProfile)null;
            var meanTarget                     = valueRange;
            var meanLowerBoundary              = Convert.ToDecimal(meanTarget - (meanTarget * confidence));
            var meanUpperBoundary              = Convert.ToDecimal(meanTarget + (meanTarget * confidence));
            var medianTarget                   = valueRange;
            var medianLowerBoundary            = Convert.ToDecimal(medianTarget - (medianTarget * confidence));
            var medianUpperBoundary            = Convert.ToDecimal(medianTarget + (medianTarget * confidence));
            var standardDeviationTarget        = Math.Sqrt(valueRange);
            var standardDevisionLowerBoundary  = Convert.ToDecimal(standardDeviationTarget - (standardDeviationTarget * confidence));
            var standardDeviationUpperBoundary = Convert.ToDecimal(standardDeviationTarget + (standardDeviationTarget * confidence));
            var valueCountLowerBoundary        = Convert.ToInt64(meanTarget - (Convert.ToDecimal(standardDeviationTarget) * curveTolerance));
            var valueCountUpperBoundary        = Convert.ToInt64(meanTarget + (Convert.ToDecimal(standardDeviationTarget) * curveTolerance));

            // Act.
            using (var array = SecureBuffer.GenerateHardenedRandomBytes(Convert.ToInt32(length)))
            {
                array.Access(buffer =>
                {
                    target = new RandomByteArrayProfile(buffer);
                });
            }

            // Assert.
            target.ArrayLength.Should().Be(Convert.ToInt64(length));
            target.AverageLengthBetweenStatistics.Mean.Should().BeLessOrEqualTo(meanUpperBoundary);
            target.AverageLengthBetweenStatistics.Mean.Should().BeGreaterOrEqualTo(meanLowerBoundary);
            target.CountStatistics.Mean.Should().BeLessOrEqualTo(meanUpperBoundary);
            target.CountStatistics.Mean.Should().BeGreaterOrEqualTo(meanLowerBoundary);
            target.AverageLengthBetweenStatistics.Median.Should().BeLessOrEqualTo(medianUpperBoundary);
            target.AverageLengthBetweenStatistics.Median.Should().BeGreaterOrEqualTo(medianLowerBoundary);
            target.CountStatistics.Median.Should().BeLessOrEqualTo(medianUpperBoundary);
            target.CountStatistics.Median.Should().BeGreaterOrEqualTo(medianLowerBoundary);
            target.AverageLengthBetweenStatistics.StandardDeviation.Should().BeLessOrEqualTo(standardDeviationUpperBoundary);
            target.AverageLengthBetweenStatistics.StandardDeviation.Should().BeGreaterOrEqualTo(standardDevisionLowerBoundary);
            target.CountStatistics.StandardDeviation.Should().BeLessOrEqualTo(standardDeviationUpperBoundary);
            target.CountStatistics.StandardDeviation.Should().BeGreaterOrEqualTo(standardDevisionLowerBoundary);

            foreach (var record in target.Records)
            {
                // Assert.
                record.Count.Should().BeLessOrEqualTo(valueCountUpperBoundary);
                record.Count.Should().BeGreaterOrEqualTo(valueCountLowerBoundary);
            }
        }
예제 #29
0
        public static HMac Create(HandshakeHashType type, SecureBuffer key)
        {
            switch (type)
            {
            case HandshakeHashType.SHA256:
                return(new HMac(SHA256.Create(), 64, key));

            case HandshakeHashType.SHA384:
                return(new HMac(SHA384.Create(), 128, key));

            default:
                throw new NotSupportedException();
            }
        }
예제 #30
0
        public void InitializeGCM(CipherSuiteCode code, byte[] key, byte[] implNonce, byte[] explNonce)
        {
            Cipher = CipherSuiteFactory.CreateCipherSuite(Protocol, code);
                        #if DEBUG_FULL
            Cipher.EnableDebugging = EnableDebugging;
                        #endif
            Crypto = Add(new MyGaloisCounterCipher(IsServer, Protocol, Cipher, explNonce));

            Crypto.ServerWriteKey = SecureBuffer.CreateCopy(key);
            Crypto.ClientWriteKey = SecureBuffer.CreateCopy(key);
            Crypto.ServerWriteIV  = SecureBuffer.CreateCopy(implNonce);
            Crypto.ClientWriteIV  = SecureBuffer.CreateCopy(implNonce);

            Crypto.InitializeCipher();
        }
예제 #31
0
		public static HMac Create (HashAlgorithmType type, SecureBuffer key)
		{
			switch (type) {
			case HashAlgorithmType.Md5:
				return new HMac (MD5.Create (), 64, key);
			case HashAlgorithmType.Sha1:
				return new HMac (SHA1.Create (), 64, key);
			case HashAlgorithmType.Sha256:
				return new HMac (SHA256.Create (), 64, key);
			case HashAlgorithmType.Sha384:
				return new HMac (SHA384.Create (), 128, key);
			default:
				throw new NotSupportedException ();
			}
		}
예제 #32
0
        public void InitializeCBC(CipherSuiteCode code, byte[] key, byte[] mac, byte[] iv)
        {
            Cipher = CipherSuiteFactory.CreateCipherSuite(Protocol, code);
                        #if DEBUG_FULL
            Cipher.EnableDebugging = EnableDebugging;
                        #endif
            Crypto = Add(new MyCbcBlockCipher(this, iv));

            Crypto.ServerWriteKey = SecureBuffer.CreateCopy(key);
            Crypto.ClientWriteKey = SecureBuffer.CreateCopy(key);
            Crypto.ServerWriteMac = SecureBuffer.CreateCopy(mac);
            Crypto.ClientWriteMac = SecureBuffer.CreateCopy(mac);

            Crypto.InitializeCipher();
        }
예제 #33
0
		public override void HandleClient (TlsContext ctx, KeyExchange clientExchange)
		{
			// Read client premaster secret
			var encryptedPreMaster = ((RSAKeyExchange)clientExchange).encryptedPreMasterSecret;

			if (!ctx.Configuration.HasCredentials)
				throw new TlsException (AlertDescription.BadCertificate, "Server certificate Private Key unavailable.");

			// Decrypt premaster secret
			var deformatter = new RSAPKCS1KeyExchangeDeformatter (ctx.Configuration.PrivateKey);

			using (var preMasterSecret = new SecureBuffer (deformatter.DecryptKeyExchange (encryptedPreMaster))) {
				// Create master secret
				ComputeMasterSecret (ctx, preMasterSecret);
			}
		}
예제 #34
0
        protected override SecureBuffer PRF(DisposeContext d, SecureBuffer secret, string label, SecureBuffer data, int length)
        {
            /* Secret Length calc exmplain from the RFC2246. Section 5
             *
             * S1 and S2 are the two halves of the secret and each is the same
             * length. S1 is taken from the first half of the secret, S2 from the
             * second half. Their length is created by rounding up the length of the
             * overall secret divided by two; thus, if the original secret is an odd
             * number of bytes long, the last byte of S1 will be the same as the
             * first byte of S2.
             */

            // split secret in 2
            int secretLen = secret.Size >> 1;

            // rounding up
            if ((secret.Size & 0x1) == 0x1)
            {
                secretLen++;
            }

            // Secret 1
            var secret1 = d.CreateBuffer(secretLen);

            Buffer.BlockCopy(secret.Buffer, 0, secret1.Buffer, 0, secretLen);

            // Secret2
            var secret2 = d.CreateBuffer(secretLen);

            Buffer.BlockCopy(secret.Buffer, (secret.Size - secretLen), secret2.Buffer, 0, secretLen);

            // Secret 1 processing
            var p_md5 = d.Add(Expand(d, HMac.Create(HashAlgorithmType.Md5, secret1), label, data, length));

            // Secret 2 processing
            var p_sha = d.Add(Expand(d, HMac.Create(HashAlgorithmType.Sha1, secret2), label, data, length));

            // Perfor XOR of both results
            var masterSecret = new SecureBuffer(length);

            for (int i = 0; i < length; i++)
            {
                masterSecret.Buffer[i] = (byte)(p_md5.Buffer[i] ^ p_sha.Buffer[i]);
            }

            return(masterSecret);
        }
        /// <summary>
        /// Converts the value of the current <see cref="CascadingSymmetricKey" /> to its equivalent binary representation.
        /// </summary>
        /// <returns>
        /// A binary representation of the current <see cref="CascadingSymmetricKey" />.
        /// </returns>
        public SecureBuffer ToBuffer()
        {
            var result = new SecureBuffer(SerializedLength);

            try
            {
                using (var controlToken = StateControl.Enter())
                {
                    result.Access(pinnedResultBuffer =>
                    {
                        var keyLength = SecureSymmetricKey.SerializedLength;

                        for (var i = 0; i < MaximumDepth; i++)
                        {
                            if (i < Depth)
                            {
                                using (var keyBuffer = Keys[i].ToBuffer())
                                {
                                    keyBuffer.Access(pinnedKeyBuffer =>
                                    {
                                        // Copy the key buffers out to the result buffer.
                                        Array.Copy(pinnedKeyBuffer, 0, pinnedResultBuffer, (keyLength * i), keyLength);
                                    });
                                }

                                continue;
                            }

                            // Fill the unused segments with random bytes.
                            var randomBytes = new Byte[keyLength];
                            HardenedRandomNumberGenerator.Instance.GetBytes(randomBytes);
                            Array.Copy(randomBytes, 0, pinnedResultBuffer, (keyLength * i), keyLength);
                        }

                        // Append the depth as a 16-bit integer.
                        Buffer.BlockCopy(BitConverter.GetBytes(Convert.ToUInt16(Depth)), 0, pinnedResultBuffer, (SerializedLength - sizeof(UInt16)), sizeof(UInt16));
                    });

                    return(result);
                }
            }
            catch
            {
                result.Dispose();
                throw new SecurityException("Key serialization failed.");
            }
        }
예제 #36
0
        public void Constructor_ShouldRaiseArgumentOutOfRangeException_ForZeroPlaintextLengthArgument()
        {
            // Arrange.
            var length = 0;

            // Act.
            var action = new Action(() =>
            {
                using (var target = new SecureBuffer(length))
                {
                    return;
                }
            });

            // Assert.
            action.Should().Throw <ArgumentOutOfRangeException>();
        }
예제 #37
0
        public override void HandleClient(TlsContext ctx, KeyExchange serverExchange)
        {
            // Read client premaster secret
            var encryptedPreMaster = ((RSAKeyExchange)serverExchange).encryptedPreMasterSecret;

            if (!ctx.Configuration.HasCredentials)
            {
                throw new TlsException(AlertDescription.BadCertificate, "Server certificate Private Key unavailable.");
            }

            // Decrypt premaster secret
            var deformatter = new RSAPKCS1KeyExchangeDeformatter(ctx.Configuration.PrivateKey);

            using (var preMasterSecret = new SecureBuffer(deformatter.DecryptKeyExchange(encryptedPreMaster))) {
                // Create master secret
                ComputeMasterSecret(ctx, preMasterSecret);
            }
        }
예제 #38
0
        /// <summary>
        /// Decrypts the specified ciphertext.
        /// </summary>
        /// <param name="ciphertext">
        /// The ciphertext to decrypt.
        /// </param>
        /// <param name="key">
        /// The key derivation bits used to transform the ciphertext.
        /// </param>
        /// <param name="algorithm">
        /// The algorithm specification used to transform the ciphertext.
        /// </param>
        /// <returns>
        /// The resulting plaintext object.
        /// </returns>
        /// <exception cref="SecurityException">
        /// An exception was raised during decryption or deserialization.
        /// </exception>
        public T Decrypt(Byte[] ciphertext, SecureBuffer key, SymmetricAlgorithmSpecification algorithm)
        {
            try
            {
                var plaintext = default(T);

                key.Access(keyBuffer =>
                {
                    plaintext = Decrypt(ciphertext, keyBuffer, algorithm);
                });

                return(plaintext);
            }
            catch
            {
                throw new SecurityException("The decryption operation failed.");
            }
        }
예제 #39
0
        /// <summary>
        /// Encrypts the specified plaintext object.
        /// </summary>
        /// <param name="plaintextObject">
        /// The plaintext object to encrypt.
        /// </param>
        /// <param name="key">
        /// The key derivation bits used to transform the object.
        /// </param>
        /// <param name="algorithm">
        /// The algorithm specification used to transform the object.
        /// </param>
        /// <param name="initializationVector">
        /// An initialization vector with length greater than or equal to the block size for the specified cipher (extra bytes are
        /// ignored), or <see langword="null" /> to generate a random initialization vector.
        /// </param>
        /// <returns>
        /// The resulting ciphertext.
        /// </returns>
        /// <exception cref="SecurityException">
        /// An exception was raised during encryption or serialization.
        /// </exception>
        public Byte[] Encrypt(T plaintextObject, SecureBuffer key, SymmetricAlgorithmSpecification algorithm, Byte[] initializationVector)
        {
            try
            {
                var ciphertext = (Byte[])null;

                key.Access(keyBuffer =>
                {
                    ciphertext = Encrypt(plaintextObject, keyBuffer, algorithm, initializationVector);
                });

                return(ciphertext);
            }
            catch
            {
                throw new SecurityException("The encryption operation failed.");
            }
        }
예제 #40
0
		protected override void Read (TlsBuffer incoming)
		{
			// Server random
			ServerRandom = new SecureBuffer (incoming.ReadBytes (32));

			// Session ID
			var sessionIdLength = (int)incoming.ReadByte ();
			if (sessionIdLength > 0) {
				SessionID = new SecureBuffer (incoming.ReadBytes (sessionIdLength));
			}

			// Cipher suite
			SelectedCipher = (CipherSuiteCode)incoming.ReadInt16 ();

			var compressionMethod = incoming.ReadByte ();
			if (compressionMethod != 0)
				throw new TlsException (AlertDescription.IlegalParameter, "Invalid compression method received from server");

			Extensions = new TlsExtensionCollection (incoming);
		}
		protected override SecureBuffer PRF (DisposeContext d, SecureBuffer secret, string label, SecureBuffer data, int length)
		{
			/* Secret Length calc exmplain from the RFC2246. Section 5
			 * 
			 * S1 and S2 are the two halves of the secret and each is the same
			 * length. S1 is taken from the first half of the secret, S2 from the
			 * second half. Their length is created by rounding up the length of the
			 * overall secret divided by two; thus, if the original secret is an odd
			 * number of bytes long, the last byte of S1 will be the same as the
			 * first byte of S2.
			 */

			// split secret in 2
			int secretLen = secret.Size >> 1;
			// rounding up
			if ((secret.Size & 0x1) == 0x1)
				secretLen++;

			// Secret 1
			var secret1 = d.CreateBuffer (secretLen);
			Buffer.BlockCopy (secret.Buffer, 0, secret1.Buffer, 0, secretLen);

			// Secret2
			var secret2 = d.CreateBuffer (secretLen);
			Buffer.BlockCopy (secret.Buffer, (secret.Size - secretLen), secret2.Buffer, 0, secretLen);

			// Secret 1 processing
			var p_md5 = d.Add (Expand (d, HMac.Create (HashAlgorithmType.Md5, secret1), label, data, length));

			// Secret 2 processing
			var p_sha = d.Add (Expand (d, HMac.Create (HashAlgorithmType.Sha1, secret2), label, data, length));

			// Perfor XOR of both results
			var masterSecret = new SecureBuffer (length);
			for (int i = 0; i < length; i++)
				masterSecret.Buffer[i] = (byte)(p_md5.Buffer[i] ^ p_sha.Buffer[i]);

			return masterSecret;
		}
예제 #42
0
		public override TlsExtension ProcessServer (TlsContext context)
		{
			if (!context.IsServer)
				throw new InvalidOperationException ();

			if (context.Session.SecureRenegotiation) {
				if (!TlsBuffer.Compare (context.Session.ClientVerifyData, Data))
					throw new TlsException (AlertDescription.HandshakeFailure);
			} else {
				if (Data != null && Data.Size != 0)
					throw new TlsException (AlertDescription.HandshakeFailure);
				context.HandshakeParameters.RequestedSecureNegotiation = true;
				context.HandshakeParameters.SecureNegotiationSupported = true;
				context.Session.SecureRenegotiation = true;
				return new RenegotiationExtension (new SecureBuffer (0));
			}

			var clientData = context.Session.ClientVerifyData;
			var serverData =  context.Session.ServerVerifyData;
			#if DEBUG_FULL
			if (context.EnableDebugging) {
				DebugHelper.WriteLine ("WRITING CLIENT DATA", clientData);
				DebugHelper.WriteLine ("WRITING SERVER DATA", serverData);
			}
			#endif
			var data = new SecureBuffer (clientData.Size + serverData.Size);
			Buffer.BlockCopy (clientData.Buffer, 0, data.Buffer, 0, clientData.Size);
			Buffer.BlockCopy (serverData.Buffer, 0, data.Buffer, clientData.Size, serverData.Size);

			return new RenegotiationExtension (data);
		}
예제 #43
0
		public TlsFinished (SecureBuffer hash)
			: base (HandshakeType.Finished)
		{
			Hash = hash;
		}
예제 #44
0
		public static bool VerifySignature (SignatureAndHashAlgorithm type, byte[] hash, AsymmetricAlgorithm key, SecureBuffer signature)
		{
			if (type.Signature != SignatureAlgorithmType.Rsa)
				throw new TlsException (AlertDescription.IlegalParameter);
			return VerifySignature (type.Hash, hash, key, signature);
 		}
예제 #45
0
		void Init (SecureBuffer key)
		{
			algorithm.Initialize ();

			int keyLength = key.Size;

			if (key.Size > blockSize) {
				algorithm.TransformFinalBlock (key.Buffer, 0, keyLength);
				Buffer.BlockCopy (algorithm.Hash, 0, inputPad.Buffer, 0, digestSize);

				keyLength = digestSize;
			} else {
				Array.Copy (key.Buffer, 0, inputPad.Buffer, 0, keyLength);
			}

			Array.Clear (inputPad.Buffer, keyLength, blockSize - keyLength);
			Array.Copy (inputPad.Buffer, 0, outputPad.Buffer, 0, blockSize);

			xor (inputPad.Buffer, IPAD);
			xor (outputPad.Buffer, OPAD);

			// Initialise the digest
			algorithm.TransformBlock (inputPad.Buffer, 0, inputPad.Size, null, 0);

			final = false;
		}
		protected override SecureBuffer PRF (DisposeContext d, SecureBuffer secret, string label, SecureBuffer data, int length)
		{
			return Expand (d, HMac.Create (HandshakeHashType, secret), label, data, length);
		}
		public override void HandleClient (TlsContext ctx, KeyExchange clientExchange)
		{
			var serverDh = (DiffieHellmanKeyExchange)clientExchange;
			using (var X = new SecureBuffer (dh.DecryptKeyExchange (serverDh.Y))) {
				ComputeMasterSecret (ctx, X);
			}
		}
예제 #48
0
		public void Create (SecureBuffer data, AsymmetricAlgorithm key)
		{
			var hash = CreateHash (HashAlgorithm, data);
			Create (hash, key);
		}
예제 #49
0
		public bool Verify (SecureBuffer data, AsymmetricAlgorithm key)
		{
			var hash = CreateHash (HashAlgorithm, data);
			return Verify (hash, key);
		}
예제 #50
0
		internal RenegotiationExtension (TlsBuffer incoming)
		{
			Data = new SecureBuffer (incoming.ReadBytes (incoming.ReadByte ()));
		}
예제 #51
0
		protected virtual void CreateExplicitNonce (SecureBuffer explicitNonce)
		{
			random.GetBytes (explicitNonce.Buffer);
		}
		public override void HandleClient (TlsContext context, KeyExchange clientExchange)
		{
			var clientKey = ((EllipticCurveKeyExchange)clientExchange).clientKey;

			clientQ = domainParameters.Curve.DecodePoint (clientKey);

			var agreement = CalculateAgreement (clientQ, serverD);
			using (var preMaster = new SecureBuffer (agreement.ToByteArrayUnsigned ()))
				ComputeMasterSecret (context, preMaster);
		}
예제 #53
0
		RenegotiationExtension (SecureBuffer data)
		{
			Data = data;
		}
예제 #54
0
		public SignatureTls12 (TlsBuffer incoming)
		{
			SignatureAlgorithm = new SignatureAndHashAlgorithm (incoming);
			Signature = Add (incoming.ReadSecureBuffer (incoming.ReadInt16 ()));
		}
예제 #55
0
		public override void Create (byte[] hash, AsymmetricAlgorithm key)
		{
			Signature = SignatureHelper.CreateSignature (HashAlgorithmType.Md5Sha1, hash, key);
		}
예제 #56
0
		public override void Create (byte[] hash, AsymmetricAlgorithm key)
		{
			Signature = SignatureHelper.CreateSignature (SignatureAlgorithm, hash, key);
		}
예제 #57
0
		public static HMac Create (HandshakeHashType type, SecureBuffer key)
		{
			switch (type) {
			case HandshakeHashType.SHA256:
				return new HMac (SHA256.Create (), 64, key);
			case HandshakeHashType.SHA384:
				return new HMac (SHA384.Create (), 128, key);
			default:
				throw new NotSupportedException ();
			}
		}
예제 #58
0
		public static bool VerifySignature (HashAlgorithmType type, byte[] hash, AsymmetricAlgorithm key, SecureBuffer signature)
		{
			return MSC.PKCS1.Verify_v15 ((RSA)key, type, hash, signature.Buffer);
		}
예제 #59
0
		protected override void Read (TlsBuffer incoming)
		{
			Hash = new SecureBuffer (incoming.ReadBytes (12));
			if (incoming.Remaining != 0)
				throw new TlsException (AlertDescription.DecodeError);
		}
예제 #60
0
		HMac (HashAlgorithm algorithm, int blockSize, SecureBuffer key)
		{
			this.algorithm = Add (algorithm);
			this.digestSize = algorithm.HashSize / 8;
			this.blockSize = blockSize;

			this.inputPad = CreateBuffer (blockSize);
			this.outputPad = CreateBuffer (blockSize);

			Init (key);
		}