コード例 #1
0
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            base.SetFromNetMQMessage(message);

            if (message.FrameCount != 3)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            // get the randon number
            NetMQFrame randomNumberFrame = message.Pop();
            RandomNumber = randomNumberFrame.ToByteArray();

            // get the length of the ciphers array
            NetMQFrame ciphersLengthFrame = message.Pop();
            int ciphersLength = BitConverter.ToInt32(ciphersLengthFrame.Buffer, 0);

            // get the ciphers
            NetMQFrame ciphersFrame = message.Pop();
            CipherSuites = new CipherSuite[ciphersLength];
            for (int i = 0; i < ciphersLength; i++)
            {
                CipherSuites[i] = (CipherSuite)ciphersFrame.Buffer[i * 2 + 1];
            }
        }
コード例 #2
0
        public CipherSuite DecideCipherSuite(CipherSuite[] clientCipherSuites)
        {
            var supportedCiphers = CipherSuiteExtensions.GetSupportedCipherSuites();
            var cipher = clientCipherSuites.FirstOrDefault(x => supportedCiphers.Contains(x));

            // WARNING: default is TLS_NULL_WITH_NULL_NULL....

            return cipher;
        }
コード例 #3
0
ファイル: ServerHello.cs プロジェクト: kazuki/opencrypto-tls
 public ServerHello(ProtocolVersion ver, byte[] random, byte[] sessionID, CipherSuite suite, CompressionMethod compression, Extension[] extensions)
     : base(HandshakeType.ServerHello)
 {
     _version = ver;
     _random = random;
     _sessionID = sessionID;
     _cipherSuite = suite;
     _compression = compression;
     _extensions = extensions;
 }
コード例 #4
0
        public ClientHelloMessage(TlsVersion version, byte[] randomBytes, byte[] sessionId, HelloExtension[] extensions, CipherSuite[] cipherSuites, CompressionMethod[] compressionMethods)
            : base(HandshakeType.ClientHello, version, randomBytes, sessionId, extensions)
        {
            SecurityAssert.NotNull(cipherSuites);
            SecurityAssert.SAssert(cipherSuites.Length >= 2 && cipherSuites.Length <= 0xFFFE);
            CipherSuites = cipherSuites;

            SecurityAssert.NotNull(compressionMethods);
            SecurityAssert.SAssert(compressionMethods.Length >= 1 && cipherSuites.Length <= 0xFF);
            CompressionMethods = compressionMethods;
        }
コード例 #5
0
ファイル: ServerHelloMessage.cs プロジェクト: hdxhan/netmq
        /// <summary>
        /// Remove the three frames from the given NetMQMessage, interpreting them thusly:
        /// 1. a byte with the <see cref="HandshakeType"/>,
        /// 2. RandomNumber (a byte-array),
        /// 3. a 2-byte array with the <see cref="CipherSuite"/> in the 2nd byte.
        /// </summary>
        /// <param name="message">a NetMQMessage - which must have 3 frames</param>
        /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.InvalidFramesCount"/>: FrameCount must be 2.</exception>
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            base.SetFromNetMQMessage(message);

            if (message.FrameCount != 2)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            // Get the random number
            NetMQFrame randomNumberFrame = message.Pop();
            RandomNumber = randomNumberFrame.ToByteArray();

            // Get the cipher suite
            NetMQFrame cipherSuiteFrame = message.Pop();
            CipherSuite = (CipherSuite)cipherSuiteFrame.Buffer[1];
        }
コード例 #6
0
 public virtual CipherSuite Select(CipherSuite[] suites)
 {
     CipherSuite[] supports = _supports;
     int minIdx = int.MaxValue;
     for (int q = 0; q < suites.Length; q ++) {
         for (int i = 0; i < supports.Length; i++) {
             if (suites[q] == supports[i]) {
                 if (minIdx > i)
                     minIdx = i;
                 break;
             }
         }
     }
     if (minIdx == int.MaxValue)
         return CipherSuite.NONE;
     return supports[minIdx];
 }
コード例 #7
0
ファイル: HandshakeLayer.cs プロジェクト: jasenkin/netmq
        public HandshakeLayer(SecureChannel secureChannel, ConnectionEnd connectionEnd)
        {
            m_secureChannel = secureChannel;
            SecurityParameters = new SecurityParameters();
              SecurityParameters.Entity = connectionEnd;
              SecurityParameters.CompressionAlgorithm = CompressionMethod.Null;
              SecurityParameters.PRFAlgorithm = PRFAlgorithm.SHA256;
              SecurityParameters.CipherType = CipherType.Block;

              AllowedCipherSuites = new CipherSuite[]
            {
              CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256,
              CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA,
              CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256,
              CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA,
            };

              VerifyCertificate = c => c.Verify();
        }
コード例 #8
0
        public void SSLv3Test()
        {
            byte[] finished1eb = new byte[] {
                0x16, 0x03, 0x00, 0x00, 0x40, 0x3c, 0xcd, 0xad,
                0xec, 0xd6, 0x18, 0x75, 0x2e, 0x6e, 0x37, 0xdf,
                0x19, 0x6d, 0x4f, 0xd4, 0x9c, 0x2c, 0x42, 0x1c,
                0xe7, 0x74, 0x45, 0xf9, 0x77, 0xb1, 0xde, 0x79,
                0x0f, 0xc4, 0x8b, 0xaf, 0x85, 0x7b, 0xa3, 0x73,
                0x92, 0x4c, 0xb7, 0xf4, 0xa3, 0x45, 0x78, 0x53,
                0x88, 0x18, 0xff, 0x2f, 0x3f, 0x7d, 0x27, 0xa1,
                0x4c, 0xa4, 0x1a, 0x5d, 0x81, 0x8d, 0xf3, 0xc8,
                0x3b, 0xb3, 0x71, 0x77, 0x59
            };
            byte[] finished2eb = new byte[] {
                0x16, 0x03, 0x00, 0x00, 0x40, 0xaa, 0xd4, 0x9e,
                0x02, 0x07, 0x52, 0x0f, 0xb0, 0x82, 0x79, 0x9a,
                0xbe, 0x53, 0xce, 0xfe, 0x66, 0xb3, 0xd5, 0xb1,
                0x58, 0x84, 0x5e, 0xe4, 0x7a, 0xb7, 0x86, 0x4c,
                0xbe, 0x33, 0x75, 0xc0, 0x57, 0xab, 0x78, 0xba,
                0x18, 0x02, 0xa8, 0xcb, 0x26, 0x2b, 0x0d, 0x3e,
                0x3a, 0xdb, 0xc5, 0x7a, 0xb8, 0x33, 0x6c, 0x35,
                0xe3, 0xa6, 0x09, 0xfe, 0x54, 0x45, 0xd0, 0x66,
                0xad, 0x95, 0xff, 0xb0, 0x3c
            };
            byte[] finished1db = new byte[] {
                0x16, 0x03, 0x00, 0x00, 0x28, 0x14, 0x00, 0x00,
                0x24, 0x98, 0x29, 0xF5, 0xAB, 0x95, 0xFD, 0x76,
                0x14, 0xDA, 0xA0, 0xA7, 0x97, 0x22, 0xCF, 0xB5,
                0x27, 0x8C, 0x96, 0xC6, 0xC7, 0x37, 0xDF, 0xD6,
                0x25, 0xB9, 0x19, 0x65, 0x2B, 0xA5, 0x06, 0x7D,
                0x10, 0x73, 0x7A, 0x59, 0xEA
            };
            byte[] finished2db = new byte[] {
                0x16, 0x03, 0x00, 0x00, 0x28, 0x14, 0x00, 0x00,
                0x24, 0x34, 0xCC, 0xA5, 0xD0, 0x08, 0x84, 0x26,
                0x19, 0xD9, 0xE5, 0x20, 0x68, 0x7B, 0xE5, 0x27,
                0xC8, 0x82, 0x71, 0x4E, 0xB1, 0x0E, 0xED, 0xE9,
                0x52, 0x01, 0xF3, 0xBE, 0x10, 0x46, 0x52, 0xDE,
                0x68, 0x2B, 0x42, 0xF8, 0x5F
            };
            byte[] crandom = new byte[] {
                0x4e, 0x60, 0xc6, 0xbd, 0x66, 0xbb, 0x66, 0x74,
                0xc8, 0xa2, 0x65, 0x5a, 0x1c, 0x3d, 0xf3, 0x7d,
                0xb0, 0xbc, 0x39, 0x60, 0x82, 0x6b, 0xec, 0xe9,
                0x62, 0xc6, 0xaa, 0x92, 0x5f, 0x7c, 0x3d, 0x3a
            };
            byte[] srandom = new byte[] {
                0x4e, 0x60, 0xc6, 0xb9, 0x1f, 0xff, 0xb5, 0x62,
                0xad, 0x3b, 0xe9, 0x16, 0xd9, 0x80, 0x04, 0xc5,
                0x91, 0x92, 0xa7, 0x1b, 0xe1, 0x39, 0x9e, 0x91,
                0x16, 0x76, 0xe1, 0x71, 0x2a, 0x9e, 0x23, 0x62
            };
            byte[] master = new byte[] {
                0x7C, 0xEE, 0xFE, 0xE3, 0x6A, 0x10, 0x82, 0xDC,
                0x69, 0xB0, 0xF2, 0x7C, 0xB6, 0xC1, 0xE9, 0x93,
                0xD8, 0x53, 0x40, 0x52, 0x7F, 0xAB, 0x2A, 0x45,
                0x3B, 0x4D, 0x69, 0xEF, 0x67, 0x60, 0xC2, 0x0E,
                0x97, 0x23, 0x40, 0x2B, 0x5A, 0x99, 0x90, 0x06,
                0xA7, 0x13, 0x10, 0x47, 0x5A, 0xC7, 0x6A, 0xAA
            };

            Record finished1 = GetRecord(finished1db);
            Record finished2 = GetRecord(finished2eb);

            CipherSuitePluginManager pluginManager = GetPluginManager();
            RecordHandler            recordHandler = new RecordHandler(ProtocolVersion.SSL3_0, true);

            CipherSuite cipherSuite = pluginManager.GetCipherSuite(ProtocolVersion.SSL3_0, 0x000a);

            Assert.IsNotNull(cipherSuite);

            // Set correct cipher suite
            ConnectionState connectionState = new ConnectionState(crandom, srandom, master);

            recordHandler.SetCipherSuite(cipherSuite, connectionState);

            // Test that initial state doesn't modify records
            recordHandler.ProcessOutputRecord(finished1);
            recordHandler.ProcessInputRecord(finished2);
            Assert.AreEqual(finished1db, finished1.GetBytes());
            Assert.AreEqual(finished2eb, finished2.GetBytes());

            recordHandler.ChangeLocalState();
            recordHandler.ProcessOutputRecord(finished1);
            recordHandler.ChangeRemoteState();
            recordHandler.ProcessInputRecord(finished2);

            // Ignore last block, it has some random padding
            int bsize = cipherSuite.BulkCipherAlgorithm.BlockSize;

            byte[] tmp1 = new byte[finished1eb.Length - bsize];
            byte[] tmp2 = new byte[finished1eb.Length - bsize];
            Buffer.BlockCopy(finished1eb, 0, tmp1, 0, tmp1.Length);
            Buffer.BlockCopy(finished1.GetBytes(), 0, tmp2, 0, tmp2.Length);

            Assert.AreEqual(tmp1, tmp2);
            Assert.AreEqual(finished2db, finished2.GetBytes());
        }
コード例 #9
0
        private void SetCipherSuite(CipherSuite cipher)
        {
            switch (cipher)
            {
            case CipherSuite.TLS_NULL_WITH_NULL_NULL:
            case CipherSuite.TLS_RSA_WITH_NULL_SHA:
            case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
                SecurityParameters.BulkCipherAlgorithm = BulkCipherAlgorithm.Null;
                SecurityParameters.FixedIVLength       = 0;
                SecurityParameters.EncKeyLength        = 0;
                SecurityParameters.BlockLength         = 0;
                SecurityParameters.RecordIVLength      = 0;
                break;

            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
                SecurityParameters.BulkCipherAlgorithm = BulkCipherAlgorithm.AES;
                SecurityParameters.FixedIVLength       = 0;
                SecurityParameters.EncKeyLength        = 16;
                SecurityParameters.BlockLength         = 16;
                SecurityParameters.RecordIVLength      = 16;
                break;

            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
                SecurityParameters.BulkCipherAlgorithm = BulkCipherAlgorithm.AES;
                SecurityParameters.FixedIVLength       = 0;
                SecurityParameters.EncKeyLength        = 32;
                SecurityParameters.BlockLength         = 16;
                SecurityParameters.RecordIVLength      = 16;
                break;

            default:
                throw new ArgumentOutOfRangeException("cipher");
            }

            switch (cipher)
            {
            case CipherSuite.TLS_NULL_WITH_NULL_NULL:
                SecurityParameters.MACAlgorithm = MACAlgorithm.Null;
                SecurityParameters.MACKeyLength = 0;
                SecurityParameters.MACLength    = 0;
                break;

            case CipherSuite.TLS_RSA_WITH_NULL_SHA:
            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
                SecurityParameters.MACAlgorithm = MACAlgorithm.HMACSha1;
                SecurityParameters.MACKeyLength = 20;
                SecurityParameters.MACLength    = 20;
                break;

            case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
                SecurityParameters.MACAlgorithm = MACAlgorithm.HMACSha256;
                SecurityParameters.MACKeyLength = 32;
                SecurityParameters.MACLength    = 32;
                break;

            default:
                throw new ArgumentOutOfRangeException("cipher");
            }
        }
コード例 #10
0
        public static bool IsAEADCipher(this ICipherSuitesProvider cipherSuiteProvider, CipherSuite cipherSuite)
        {
            var cipherAlgorithm = cipherSuiteProvider.ResolveCipherAlgorithm(cipherSuite);

            return(cipherAlgorithm is AEADCipherAdapter || cipherAlgorithm is IAEADBlockCipher);
        }
コード例 #11
0
 public override string ToString()
 {
     return(CipherSuite.ToString());
 }
コード例 #12
0
        public IActionResult IssueCertificate(CertRequest certRequest)
        {
            if (certRequest.CertPassphrase.Length < Constants.MinPassphraseLength)
            {
                _logger.LogWarning(
                    string.Format(
                        "User {} tried to issue new certificate with too short passphrase.",
                        certRequest.Uid
                        )
                    );
                return(BadRequest("Too short passphrase"));
            }

            CipherSuite cipherSuite = certRequest.RequestedCipherSuite;

            if (!cipherSuite.IsValidCipherSuite())
            {
                _logger.LogWarning("Invalid cipher suite:\n" + cipherSuite);
                return(BadRequest("Invalid cipher suite."));
            }

            User user = _userDBAuthenticator.AuthenticateAndGetUser(certRequest.Uid, certRequest.Password);

            if (user != null)
            {
                // Load the certificate
                X509Certificate2 coreCACert = new X509Certificate2(CAConfig.CoreCACertPath);

                HashAlgorithmName   hashAlg = new HashAlgorithmName(cipherSuite.HashAlg);
                AsymmetricAlgorithm privKey = null;
                string privKeyExport        = null;

                CertificateRequest req = null;

                if (cipherSuite.Alg.Equals(EncryptionAlgorithms.RSA))
                {
                    privKey       = RSA.Create(cipherSuite.KeySize);
                    privKeyExport = ((RSA)privKey).ToPem();

                    req = new CertificateRequest(
                        "CN=" + user.Id,
                        (RSA)privKey,
                        hashAlg,
                        RSASignaturePadding.Pss
                        );
                }
                else if (cipherSuite.Alg.Equals(EncryptionAlgorithms.ECDSA))
                {
                    privKey       = ECDsa.Create();
                    privKeyExport = ((ECDsa)privKey).ToPem();

                    req = new CertificateRequest(
                        "CN=" + user.Id,
                        (ECDsa)privKey,
                        hashAlg
                        );
                }
                else
                {
                    _logger.LogError(
                        string.Format(
                            "Unknown encryption algorithm '{0}'.",
                            cipherSuite.Alg
                            )
                        );
                    throw new CryptographicUnexpectedOperationException();
                }

                // Add email as SAN
                SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
                sanBuilder.AddEmailAddress(user.Email);
                req.CertificateExtensions.Add(sanBuilder.Build());

                // Arguments: Is no CA, no restricted nr of path levels, (nr of path levels), is not critical
                req.CertificateExtensions.Add(
                    new X509BasicConstraintsExtension(false, false, 0, false)
                    );

                req.CertificateExtensions.Add(
                    new X509SubjectKeyIdentifierExtension(req.PublicKey, false)
                    );

                req.CertificateExtensions.Add(
                    new X509KeyUsageExtension(
                        X509KeyUsageFlags.KeyEncipherment
                        | X509KeyUsageFlags.DigitalSignature
                        | X509KeyUsageFlags.NonRepudiation,
                        false
                        )
                    );

                OidCollection oidCollection = new OidCollection();
                // Set Client Authentication Oid
                oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.2"));
                // Set Secure Email / Email protection Oid
                oidCollection.Add(new Oid("1.3.6.1.5.5.7.3.4"));

                req.CertificateExtensions.Add(
                    new X509EnhancedKeyUsageExtension(
                        oidCollection,
                        false
                        )
                    );

                // Add CRL Distribution Point (CDP)
                req.CertificateExtensions.Add(
                    new System.Security.Cryptography.X509Certificates.X509Extension(
                        new Oid(X509Extensions.CrlDistributionPoints.Id),
                        new CrlDistPoint(
                            new[] {
                    new DistributionPoint(
                        new DistributionPointName(
                            new GeneralNames(
                                new GeneralName(
                                    GeneralName.UniformResourceIdentifier,
                                    CAConfig.CrlDistributionPoint
                                    )
                                )
                            ),
                        null,
                        null
                        )
                }
                            ).GetDerEncoded(),
                        false
                        )
                    );

                X509Certificate2 coreCaPublicCert = new X509Certificate2(coreCACert.Export(X509ContentType.Cert));
                if (coreCaPublicCert.HasPrivateKey)
                {
                    _logger.LogError("Core CA public certificate exported with private key!");
                    throw new CryptographicUnexpectedOperationException();
                }

                // Use transaction to prevent race conditions on the serial number
                X509Certificate2 userCert;

                using (
                    IDbContextTransaction scope = _caDBModifier.GetScope()
                    )
                {
                    SerialNumber serialNr = _caDBModifier.GetMaxSerialNr();

                    // It is necessary to use this constructor to be able to sign keys
                    // that use different algorithms than the one for the core CA's key
                    userCert = req.Create(
                        coreCACert.SubjectName,
                        X509SignatureGenerator.CreateForRSA(
                            (RSA)coreCACert.PrivateKey,
                            RSASignaturePadding.Pss
                            ),
                        DateTimeOffset.UtcNow,
                        DateTimeOffset.UtcNow.AddDays(CAConfig.UserCertValidityPeriod),
                        serialNr.SerialNrBytes
                        );

                    _caDBModifier.RevokeAllCertificatesOfUser(user);

                    // Add certificate to DB
                    _caDBModifier.AddCertificate(
                        new PublicCertificate {
                        SerialNr    = serialNr.SerialNr,
                        Uid         = user.Id,
                        Certificate = Convert.ToBase64String(
                            userCert.Export(X509ContentType.Cert)
                            ),
                        IsRevoked = false
                    }
                        );

                    scope.Commit();
                }

                var collection = new X509Certificate2Collection();

                X509Certificate2 userCertWithPrivKey;
                if (privKey is RSA rsa)
                {
                    userCertWithPrivKey = userCert.CopyWithPrivateKey(rsa);
                }
                else if (privKey is ECDsa dsa)
                {
                    userCertWithPrivKey = userCert.CopyWithPrivateKey(dsa);
                }
                else
                {
                    throw new CryptographicUnexpectedOperationException();
                }

                collection.Add(userCertWithPrivKey);
                collection.Add(coreCaPublicCert);

                BackupPrivateKey(privKeyExport, user.Id + '_' + userCert.Thumbprint + ".pem.enc");

                byte[] certBytes        = collection.Export(X509ContentType.Pkcs12, certRequest.CertPassphrase);
                string pkcs12ArchiveB64 = Convert.ToBase64String(certBytes);

                // Add encrypted private key to DB
                _caDBModifier.AddPrivateKey(
                    new PrivateKey {
                    Uid       = user.Id,
                    KeyPkcs12 = pkcs12ArchiveB64
                }
                    );

                _logger.LogInformation("Successfully issued new certificate for user " + user.Id);

                return(Ok(
                           new UserCertificate {
                    Pkcs12Archive = pkcs12ArchiveB64
                }
                           ));
            }
            else
            {
                _logger.LogWarning(
                    "Unauthorized attempt to issue certificate for user "
                    + certRequest.Uid
                    );
                return(Unauthorized());
            }
        }
コード例 #13
0
        internal static void RegisterSuite(CipherSuite suite, TlsCipherAlgorithm cipher, TlsHashAlgorithm digest, TlsSignatureAlgorithm signature, TlsKeyExchange exchange)
        {
            Suites.Add(suite);

            CipherMapping.Add(suite, cipher);
            DigestMapping.Add(suite, digest);
            SignatureMapping.Add(suite, signature);
            KeyExchangeMapping.Add(suite, exchange);
        }
コード例 #14
0
ファイル: Cipher.cs プロジェクト: Hitchhikrr/Voip
 public Cipher(CipherSuite suite, BulkEncryptionAlgorithm encrypalgo, MACAlgorithm macalgo,
     byte nBlockSize, byte nIVSize, int nKeyBits, byte nKeyMaterialSize)
 {
     CipherSuite = suite;
     BulkEncryptionAlgorithm = encrypalgo;
     MACAlgorithm = macalgo;
     BlockSizeBytes = nBlockSize;
     IVSize = nIVSize;
     KeySizeBits= nKeyBits;
     KeyMaterialLength = nKeyMaterialSize;
     KeyBlockSize = (this.KeyMaterialLength + this.HashSize + this.IVSize) << 1;
 }
コード例 #15
0
 public ServerHelloMessage(TlsVersion version, byte[] randomBytes, byte[] sessionId, HelloExtension[] extensions, CipherSuite cipherSuite, CompressionMethod compressionMethod)
     : base(HandshakeType.ServerHello, version, randomBytes, sessionId, extensions)
 {
     CipherSuite = cipherSuite;
     CompressionMethod = compressionMethod;
 }
コード例 #16
0
 internal static bool IsSupported(CipherSuite suite)
 {
     return _list.ContainsKey (suite);
 }
コード例 #17
0
 internal static CipherSuiteInfo GetSuiteInfo(CipherSuite suite)
 {
     return _list[suite];
 }
コード例 #18
0
        private void ProcessServerHello(IByteBuffer body)
        {
            ProtocolVersion recordLayerVersion = recordLayer.GetReadVersion();

            ReportServerVersion(recordLayerVersion);
            recordLayer.SetWriteVersion(recordLayerVersion);

            AsyncDtlsSecurityParameters securityParameters = (AsyncDtlsSecurityParameters)clientState.ClientContext.SecurityParameters;

            ProtocolVersion server_version = ProtocolVersion.Get(body.ReadByte() & 0xFF, body.ReadByte() & 0xFF);

            ReportServerVersion(server_version);

            byte[] serverRandom = new byte[32];
            body.ReadBytes(serverRandom);
            securityParameters.SetServerRandom(serverRandom);

            byte[] selectedSessionID = new byte[body.ReadByte() & 0x0FF];
            if (selectedSessionID.Length > 0)
            {
                body.ReadBytes(selectedSessionID);
            }

            clientState.SelectedSessionID = selectedSessionID;
            if (selectedSessionID.Length > 32)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            clientState.Client.NotifySessionID(selectedSessionID);
            clientState.ResumedSession = selectedSessionID.Length > 0 && clientState.TlsSession != null && ArrayUtils.Equals(clientState.SelectedSessionID, clientState.TlsSession.SessionID);

            int     selectedCipherSuite   = body.ReadUnsignedShort();
            Boolean inOfferedCipherSuites = false;

            for (int i = 0; i < clientState.OfferedCipherSuites.Length; i++)
            {
                if (selectedCipherSuite == clientState.OfferedCipherSuites[i])
                {
                    inOfferedCipherSuites = true;
                    break;
                }
            }

            if (!inOfferedCipherSuites || selectedCipherSuite == CipherSuite.TLS_NULL_WITH_NULL_NULL || CipherSuite.IsScsv(selectedCipherSuite) || !DtlsHelper.GetMinimumVersion(selectedCipherSuite).IsEqualOrEarlierVersionOf(clientState.ClientContext.ServerVersion.GetEquivalentTLSVersion()))
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            switch (DtlsHelper.GetEncryptionAlgorithm(selectedCipherSuite))
            {
            case EncryptionAlgorithm.RC4_40:
            case EncryptionAlgorithm.RC4_128:
                throw new TlsFatalAlert(AlertDescription.internal_error);
            }

            clientState.Client.NotifySelectedCipherSuite(selectedCipherSuite);

            byte    selectedCompressionMethod   = body.ReadByte();
            Boolean inOfferedCompressionMethods = false;

            for (int i = 0; i < clientState.OfferedCompressionMethods.Length; i++)
            {
                if (selectedCompressionMethod == clientState.OfferedCompressionMethods[i])
                {
                    inOfferedCompressionMethods = true;
                    break;
                }
            }

            if (!inOfferedCompressionMethods)
            {
                throw new TlsFatalAlert(AlertDescription.illegal_parameter);
            }

            clientState.Client.NotifySelectedCompressionMethod(selectedCompressionMethod);
            clientState.ServerExtensions = DtlsHelper.ReadSelectedExtensions(body);

            if (clientState.ServerExtensions != null)
            {
                foreach (Int32 extType in clientState.ServerExtensions.Keys)
                {
                    if (extType.Equals(DtlsHelper.EXT_RenegotiationInfo))
                    {
                        continue;
                    }

                    if (!clientState.ClientExtensions.Contains(extType))
                    {
                        throw new TlsFatalAlert(AlertDescription.unsupported_extension);
                    }
                }
            }

            byte[] renegExtData = null;
            if (clientState.ServerExtensions.Contains(DtlsHelper.EXT_RenegotiationInfo))
            {
                renegExtData = (byte[])clientState.ServerExtensions[DtlsHelper.EXT_RenegotiationInfo];
            }

            if (renegExtData != null)
            {
                clientState.SecureRenegotiation = true;

                if (!ArrayUtils.Equals(renegExtData, DtlsHelper.EMPTY_BYTES_WITH_LENGTH))
                {
                    throw new TlsFatalAlert(AlertDescription.handshake_failure);
                }
            }

            if (clientState.SecureRenegotiation)
            {
                clientState.Client.NotifySecureRenegotiation(clientState.SecureRenegotiation);
            }

            IDictionary sessionClientExtensions = clientState.ClientExtensions;
            IDictionary sessionServerExtensions = clientState.ServerExtensions;

            if (clientState.ResumedSession)
            {
                if (selectedCipherSuite != clientState.SessionParameters.CipherSuite || selectedCompressionMethod != clientState.SessionParameters.CompressionAlgorithm)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                sessionClientExtensions = null;
                sessionServerExtensions = (Dictionary <Int32, byte[]>)clientState.SessionParameters.ReadServerExtensions();
            }

            securityParameters.SetCipherSuite(selectedCipherSuite);
            securityParameters.SetCompressionAlgorithm(selectedCompressionMethod);

            if (sessionServerExtensions != null)
            {
                byte[] encryptThenMac = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_encrypt_then_mac))
                {
                    encryptThenMac = (byte[])sessionServerExtensions[DtlsHelper.EXT_encrypt_then_mac];
                }

                if (encryptThenMac != null && encryptThenMac.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                Boolean serverSentEncryptThenMAC = encryptThenMac != null;
                if (serverSentEncryptThenMAC && DtlsHelper.GetCipherType(securityParameters.CipherSuite) != CipherType.block)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                securityParameters.SetEncryptThenMAC(serverSentEncryptThenMAC);

                byte[] extendedMacSecret = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_extended_master_secret))
                {
                    extendedMacSecret = (byte[])sessionServerExtensions[DtlsHelper.EXT_extended_master_secret];
                }

                if (extendedMacSecret != null && extendedMacSecret.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                securityParameters.SetExtendedMasterSecret(extendedMacSecret != null);

                securityParameters.SetMaxFragmentLength(DtlsHelper.EvaluateMaxFragmentLengthExtension(clientState.ResumedSession, sessionClientExtensions, sessionServerExtensions, AlertDescription.illegal_parameter));

                byte[] truncatedHMAC = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_truncated_hmac))
                {
                    truncatedHMAC = (byte[])sessionServerExtensions[DtlsHelper.EXT_truncated_hmac];
                }

                if (truncatedHMAC != null && truncatedHMAC.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                securityParameters.SetTruncatedHMac(truncatedHMAC != null);

                byte[] statusRequest = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_status_request))
                {
                    statusRequest = (byte[])sessionServerExtensions[DtlsHelper.EXT_status_request];
                }

                if (statusRequest != null && statusRequest.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                clientState.AllowCertificateStatus = (!clientState.ResumedSession && statusRequest != null);

                byte[] sessionTicket = null;
                if (sessionServerExtensions.Contains(DtlsHelper.EXT_SessionTicket))
                {
                    sessionTicket = (byte[])sessionServerExtensions[DtlsHelper.EXT_SessionTicket];
                }

                if (sessionTicket != null && sessionTicket.Length > 0)
                {
                    throw new TlsFatalAlert(AlertDescription.illegal_parameter);
                }

                clientState.ExpectSessionTicket = (!clientState.ResumedSession && sessionTicket != null);
            }

            if (sessionClientExtensions != null)
            {
                clientState.Client.ProcessServerExtensions(sessionServerExtensions);
            }

            securityParameters.SetPrfAlgorithm(DtlsHelper.GetPRFAlgorithm(clientState.ClientContext.ServerVersion, securityParameters.CipherSuite));
            securityParameters.SetVerifyDataLength(12);
        }
コード例 #19
0
        public void TLSv12Test()
        {
            byte[] finished2eb = new byte[] {
                0x16, 0x03, 0x03, 0x00, 0x28, 0x77, 0xb7, 0x66,
                0x18, 0x6f, 0x70, 0x52, 0x14, 0xc9, 0xa4, 0xbc,
                0xbf, 0x26, 0x05, 0xf7, 0x99, 0x42, 0xb1, 0xc5,
                0xc3, 0xcf, 0x3c, 0xb6, 0x48, 0x34, 0xfc, 0xd6,
                0x35, 0x45, 0xf0, 0x12, 0xce, 0x1b, 0x0b, 0xff,
                0x94, 0x15, 0x8f, 0x56, 0xda
            };
            byte[] finished1db = new byte[] {
                0x16, 0x03, 0x03, 0x00, 0x10, 0x14, 0x00, 0x00,
                0x0C, 0x01, 0xE4, 0xC1, 0xFF, 0x6B, 0x7E, 0x2F,
                0x6F, 0x6B, 0xC5, 0x16, 0xE6
            };
            byte[] finished2db = new byte[] {
                0x16, 0x03, 0x03, 0x00, 0x10, 0x14, 0x00, 0x00,
                0x0C, 0x83, 0x51, 0x75, 0x4D, 0x01, 0x37, 0x51,
                0xEE, 0x72, 0x2F, 0xAE, 0x90
            };
            byte[] crandom = new byte[] {
                0x4e, 0x61, 0xfd, 0x0b, 0x16, 0x0e, 0x3c, 0x92,
                0xa0, 0x15, 0x90, 0x61, 0xfb, 0x2e, 0x51, 0xb4,
                0x8f, 0xb0, 0xf5, 0xf2, 0x67, 0x4e, 0x20, 0x7f,
                0xc3, 0x0d, 0x8e, 0x85, 0xdb, 0xfb, 0x58, 0xac
            };
            byte[] srandom = new byte[] {
                0x4e, 0x61, 0xfd, 0xe6, 0xf9, 0x06, 0x4d, 0x7c,
                0x4c, 0x5b, 0x0b, 0x72, 0x6a, 0xba, 0x86, 0x76,
                0xd9, 0x7d, 0xce, 0xcc, 0xd5, 0x24, 0x60, 0x6e,
                0xaf, 0x16, 0x0f, 0x85, 0x52, 0x8d, 0xba, 0x86
            };
            byte[] master = new byte[] {
                0xCA, 0xCB, 0xE5, 0x65, 0x39, 0x78, 0xFC, 0xCE,
                0x18, 0xD8, 0x1C, 0xD8, 0xAD, 0x4E, 0x5E, 0x91,
                0x18, 0x2B, 0x0E, 0xEF, 0x60, 0x13, 0xBB, 0xBF,
                0xD8, 0x62, 0x77, 0x7F, 0xA3, 0xEF, 0x76, 0xAB,
                0x7E, 0x3A, 0x26, 0xF2, 0xE1, 0xB8, 0x50, 0x46,
                0x65, 0x85, 0x04, 0x23, 0xCC, 0x52, 0x2C, 0x87
            };

            Record finished1 = GetRecord(finished1db);
            Record finished2 = GetRecord(finished2eb);

            CipherSuitePluginManager pluginManager = GetPluginManager();
            RecordHandler            recordHandler = new RecordHandler(ProtocolVersion.SSL3_0, true);

            // Check that GCM suite is not available in TLS 1.1
            CipherSuite nullSuite = pluginManager.GetCipherSuite(ProtocolVersion.TLS1_1, 0x00a2);

            Assert.IsNull(nullSuite);

            // Check that GCM suite is available in TLS 1.2
            CipherSuite cipherSuite = pluginManager.GetCipherSuite(ProtocolVersion.TLS1_2, 0x00a2);

            Assert.IsNotNull(cipherSuite);

            // Set correct cipher suite
            ConnectionState connectionState = new ConnectionState(crandom, srandom, master);

            recordHandler.SetCipherSuite(cipherSuite, connectionState);

            // Test that initial state doesn't modify records
            recordHandler.ProcessOutputRecord(finished1);
            recordHandler.ProcessInputRecord(finished2);
            Assert.AreEqual(finished1db, finished1.GetBytes());
            Assert.AreEqual(finished2eb, finished2.GetBytes());

            recordHandler.ChangeLocalState();
            recordHandler.ProcessOutputRecord(finished1);
            recordHandler.ChangeRemoteState();
            recordHandler.ProcessInputRecord(finished2);

            Assert.AreEqual(finished2db, finished2.GetBytes());
        }
コード例 #20
0
        public void SetCipherSuite(CipherSuite suite, AsymmetricAlgorithm signAlgo)
        {
            CipherSuiteInfo info = SupportedCipherSuites.GetSuiteInfo (suite);
            if (info == null)
                throw new NotSupportedException ();

            _bulk_cipher = info.BulkCipherAlgorithm;
            _cipherType = info.CipherType;
            _enc_key_length = info.EncKeyLength;
            _block_length = info.BlockLength;
            _fixed_iv_length = info.FixedIVLength;
            _record_iv_length = info.RecordIVLength;
            _mac = info.MACAlgorithm;
            _mac_length = info.MACLength;
            _mac_key_length = info.MACKeyLength;
            _keyExchange = info.KeyExchangeAlgorithm;

            // TODO: TLS1.2spec ?
            switch (_prfType) {
                case PRFAlgorithm.MD5_AND_SHA1: _prf = new MD5_AND_SHA1 (); break;
                case PRFAlgorithm.SSL3: _prf = new SSL3_PRF (this); break;
                default: throw new NotSupportedException ();
            }

            switch (_keyExchange) {
                case KeyExchangeAlgorithm.ECDHE_ECDSA:
                    _keyExchanger = new ECDHE_ECDSA ((openCrypto.EllipticCurve.Signature.ECDSA)signAlgo);
                    break;
                case KeyExchangeAlgorithm.DHE_DSS:
                    _keyExchanger = new DHE_DSS ((DSACryptoServiceProvider)signAlgo);
                    break;
                case KeyExchangeAlgorithm.RSA:
                    _keyExchanger = new KeyExchange.RSA ((RSACryptoServiceProvider)signAlgo);
                    break;
                default:
                    throw new NotImplementedException ();
            }
        }
コード例 #21
0
ファイル: Cipher.cs プロジェクト: Hitchhikrr/Voip
        public static Cipher FindCipher(CipherSuite suite)
        {
            if (CommonCiphers.ContainsKey(suite) == true)
                return CommonCiphers[suite];

            return null;
        }
コード例 #22
0
        private void ProcessHandshakeMessage(HandshakeType type, byte[] buf)
        {
            MemoryStream inStr = new MemoryStream(buf, false);

            /*
             * Check the type.
             */
            switch (type)
            {
            case HandshakeType.certificate:
            {
                switch (connection_state)
                {
                case CS_SERVER_HELLO_RECEIVED:
                {
                    // Parse the Certificate message and send to cipher suite

                    Certificate serverCertificate = Certificate.Parse(inStr);

                    AssertEmpty(inStr);

                    this.keyExchange.ProcessServerCertificate(serverCertificate);

                    this.authentication = tlsClient.GetAuthentication();
                    this.authentication.NotifyServerCertificate(serverCertificate);

                    break;
                }

                default:
                    this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message);
                    break;
                }

                connection_state = CS_SERVER_CERTIFICATE_RECEIVED;
                break;
            }

            case HandshakeType.finished:
                switch (connection_state)
                {
                case CS_SERVER_CHANGE_CIPHER_SPEC_RECEIVED:
                    /*
                     * Read the checksum from the finished message, it has always 12 bytes.
                     */
                    byte[] serverVerifyData = new byte[12];
                    TlsUtilities.ReadFully(serverVerifyData, inStr);

                    AssertEmpty(inStr);

                    /*
                     * Calculate our own checksum.
                     */
                    byte[] expectedServerVerifyData = TlsUtilities.PRF(
                        securityParameters.masterSecret, "server finished",
                        rs.GetCurrentHash(), 12);

                    /*
                     * Compare both checksums.
                     */
                    if (!Arrays.ConstantTimeAreEqual(expectedServerVerifyData, serverVerifyData))
                    {
                        /*
                         * Wrong checksum in the finished message.
                         */
                        this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure);
                    }

                    connection_state = CS_DONE;

                    /*
                     * We are now ready to receive application data.
                     */
                    this.appDataReady = true;
                    break;

                default:
                    this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message);
                    break;
                }
                break;

            case HandshakeType.server_hello:
                switch (connection_state)
                {
                case CS_CLIENT_HELLO_SEND:
                    /*
                     * Read the server hello message
                     */
                    TlsUtilities.CheckVersion(inStr, this);

                    /*
                     * Read the server random
                     */
                    securityParameters.serverRandom = new byte[32];
                    TlsUtilities.ReadFully(securityParameters.serverRandom, inStr);

                    byte[] sessionID = TlsUtilities.ReadOpaque8(inStr);
                    if (sessionID.Length > 32)
                    {
                        this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter);
                    }

                    this.tlsClient.NotifySessionID(sessionID);

                    /*
                     * Find out which CipherSuite the server has chosen and check that
                     * it was one of the offered ones.
                     */
                    CipherSuite selectedCipherSuite = (CipherSuite)TlsUtilities.ReadUint16(inStr);
                    if (!ArrayContains(offeredCipherSuites, selectedCipherSuite) ||
                        selectedCipherSuite == CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
                    {
                        this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter);
                    }

                    this.tlsClient.NotifySelectedCipherSuite(selectedCipherSuite);

                    /*
                     * Find out which CompressionMethod the server has chosen and check that
                     * it was one of the offered ones.
                     */
                    CompressionMethod selectedCompressionMethod = (CompressionMethod)TlsUtilities.ReadUint8(inStr);
                    if (!ArrayContains(offeredCompressionMethods, selectedCompressionMethod))
                    {
                        this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter);
                    }

                    this.tlsClient.NotifySelectedCompressionMethod(selectedCompressionMethod);

                    /*
                     * RFC3546 2.2 The extended server hello message format MAY be
                     * sent in place of the server hello message when the client has
                     * requested extended functionality via the extended client hello
                     * message specified in Section 2.1.
                     * ...
                     * Note that the extended server hello message is only sent in response
                     * to an extended client hello message.  This prevents the possibility
                     * that the extended server hello message could "break" existing TLS 1.0
                     * clients.
                     */

                    /*
                     * TODO RFC 3546 2.3
                     * If [...] the older session is resumed, then the server MUST ignore
                     * extensions appearing in the client hello, and send a server hello
                     * containing no extensions.
                     */

                    // ExtensionType -> byte[]
                    IDictionary serverExtensions = Platform.CreateHashtable();

                    if (inStr.Position < inStr.Length)
                    {
                        // Process extensions from extended server hello
                        byte[] extBytes = TlsUtilities.ReadOpaque16(inStr);

                        MemoryStream ext = new MemoryStream(extBytes, false);
                        while (ext.Position < ext.Length)
                        {
                            ExtensionType extType  = (ExtensionType)TlsUtilities.ReadUint16(ext);
                            byte[]        extValue = TlsUtilities.ReadOpaque16(ext);

                            // Note: RFC 5746 makes a special case for EXT_RenegotiationInfo
                            if (extType != ExtensionType.renegotiation_info &&
                                !clientExtensions.Contains(extType))
                            {
                                /*
                                 * RFC 3546 2.3
                                 * Note that for all extension types (including those defined in
                                 * future), the extension type MUST NOT appear in the extended server
                                 * hello unless the same extension type appeared in the corresponding
                                 * client hello.  Thus clients MUST abort the handshake if they receive
                                 * an extension type in the extended server hello that they did not
                                 * request in the associated (extended) client hello.
                                 */
                                this.FailWithError(AlertLevel.fatal, AlertDescription.unsupported_extension);
                            }

                            if (serverExtensions.Contains(extType))
                            {
                                /*
                                 * RFC 3546 2.3
                                 * Also note that when multiple extensions of different types are
                                 * present in the extended client hello or the extended server hello,
                                 * the extensions may appear in any order. There MUST NOT be more than
                                 * one extension of the same type.
                                 */
                                this.FailWithError(AlertLevel.fatal, AlertDescription.illegal_parameter);
                            }

                            serverExtensions.Add(extType, extValue);
                        }
                    }

                    AssertEmpty(inStr);

                    /*
                     * RFC 5746 3.4. When a ServerHello is received, the client MUST check if it
                     * includes the "renegotiation_info" extension:
                     */
                    {
                        bool secure_negotiation = serverExtensions.Contains(ExtensionType.renegotiation_info);

                        /*
                         * If the extension is present, set the secure_renegotiation flag
                         * to TRUE.  The client MUST then verify that the length of the
                         * "renegotiated_connection" field is zero, and if it is not, MUST
                         * abort the handshake (by sending a fatal handshake_failure
                         * alert).
                         */
                        if (secure_negotiation)
                        {
                            byte[] renegExtValue = (byte[])serverExtensions[ExtensionType.renegotiation_info];

                            if (!Arrays.ConstantTimeAreEqual(renegExtValue,
                                                             CreateRenegotiationInfo(emptybuf)))
                            {
                                this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure);
                            }
                        }

                        tlsClient.NotifySecureRenegotiation(secure_negotiation);
                    }

                    if (clientExtensions != null)
                    {
                        tlsClient.ProcessServerExtensions(serverExtensions);
                    }

                    this.keyExchange = tlsClient.GetKeyExchange();

                    connection_state = CS_SERVER_HELLO_RECEIVED;
                    break;

                default:
                    this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message);
                    break;
                }
                break;

            case HandshakeType.server_hello_done:
                switch (connection_state)
                {
                case CS_SERVER_CERTIFICATE_RECEIVED:
                case CS_SERVER_KEY_EXCHANGE_RECEIVED:
                case CS_CERTIFICATE_REQUEST_RECEIVED:

                    // NB: Original code used case label fall-through
                    if (connection_state == CS_SERVER_CERTIFICATE_RECEIVED)
                    {
                        // There was no server key exchange message; check it's OK
                        this.keyExchange.SkipServerKeyExchange();
                    }

                    AssertEmpty(inStr);

                    connection_state = CS_SERVER_HELLO_DONE_RECEIVED;

                    TlsCredentials clientCreds = null;
                    if (certificateRequest == null)
                    {
                        this.keyExchange.SkipClientCredentials();
                    }
                    else
                    {
                        clientCreds = this.authentication.GetClientCredentials(certificateRequest);

                        Certificate clientCert;
                        if (clientCreds == null)
                        {
                            this.keyExchange.SkipClientCredentials();
                            clientCert = Certificate.EmptyChain;
                        }
                        else
                        {
                            this.keyExchange.ProcessClientCredentials(clientCreds);
                            clientCert = clientCreds.Certificate;
                        }

                        SendClientCertificate(clientCert);
                    }

                    /*
                     * Send the client key exchange message, depending on the key
                     * exchange we are using in our CipherSuite.
                     */
                    SendClientKeyExchange();

                    connection_state = CS_CLIENT_KEY_EXCHANGE_SEND;

                    if (clientCreds != null && clientCreds is TlsSignerCredentials)
                    {
                        TlsSignerCredentials signerCreds = (TlsSignerCredentials)clientCreds;
                        byte[] md5andsha1 = rs.GetCurrentHash();
                        byte[] clientCertificateSignature = signerCreds.GenerateCertificateSignature(
                            md5andsha1);
                        SendCertificateVerify(clientCertificateSignature);

                        connection_state = CS_CERTIFICATE_VERIFY_SEND;
                    }

                    /*
                     * Now, we send change cipher state
                     */
                    byte[] cmessage = new byte[1];
                    cmessage[0] = 1;
                    rs.WriteMessage(ContentType.change_cipher_spec, cmessage, 0, cmessage.Length);

                    connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC_SEND;

                    /*
                     * Calculate the master_secret
                     */
                    byte[] pms = this.keyExchange.GeneratePremasterSecret();

                    securityParameters.masterSecret = TlsUtilities.PRF(pms, "master secret",
                                                                       TlsUtilities.Concat(securityParameters.clientRandom, securityParameters.serverRandom),
                                                                       48);

                    // TODO Is there a way to ensure the data is really overwritten?

                    /*
                     * RFC 2246 8.1. The pre_master_secret should be deleted from
                     * memory once the master_secret has been computed.
                     */
                    Array.Clear(pms, 0, pms.Length);

                    /*
                     * Initialize our cipher suite
                     */
                    rs.ClientCipherSpecDecided(tlsClient.GetCompression(), tlsClient.GetCipher());

                    /*
                     * Send our finished message.
                     */
                    byte[] clientVerifyData = TlsUtilities.PRF(securityParameters.masterSecret,
                                                               "client finished", rs.GetCurrentHash(), 12);

                    MemoryStream bos = new MemoryStream();
                    TlsUtilities.WriteUint8((byte)HandshakeType.finished, bos);
                    TlsUtilities.WriteOpaque24(clientVerifyData, bos);
                    byte[] message = bos.ToArray();

                    rs.WriteMessage(ContentType.handshake, message, 0, message.Length);

                    this.connection_state = CS_CLIENT_FINISHED_SEND;
                    break;

                default:
                    this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure);
                    break;
                }
                break;

            case HandshakeType.server_key_exchange:
            {
                switch (connection_state)
                {
                case CS_SERVER_HELLO_RECEIVED:
                case CS_SERVER_CERTIFICATE_RECEIVED:
                {
                    // NB: Original code used case label fall-through
                    if (connection_state == CS_SERVER_HELLO_RECEIVED)
                    {
                        // There was no server certificate message; check it's OK
                        this.keyExchange.SkipServerCertificate();
                        this.authentication = null;
                    }

                    this.keyExchange.ProcessServerKeyExchange(inStr);

                    AssertEmpty(inStr);
                    break;
                }

                default:
                    this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message);
                    break;
                }

                this.connection_state = CS_SERVER_KEY_EXCHANGE_RECEIVED;
                break;
            }

            case HandshakeType.certificate_request:
                switch (connection_state)
                {
                case CS_SERVER_CERTIFICATE_RECEIVED:
                case CS_SERVER_KEY_EXCHANGE_RECEIVED:
                {
                    // NB: Original code used case label fall-through
                    if (connection_state == CS_SERVER_CERTIFICATE_RECEIVED)
                    {
                        // There was no server key exchange message; check it's OK
                        this.keyExchange.SkipServerKeyExchange();
                    }

                    if (this.authentication == null)
                    {
                        /*
                         * RFC 2246 7.4.4. It is a fatal handshake_failure alert
                         * for an anonymous server to request client identification.
                         */
                        this.FailWithError(AlertLevel.fatal, AlertDescription.handshake_failure);
                    }

                    int numTypes = TlsUtilities.ReadUint8(inStr);
                    ClientCertificateType[] certificateTypes = new ClientCertificateType[numTypes];
                    for (int i = 0; i < numTypes; ++i)
                    {
                        certificateTypes[i] = (ClientCertificateType)TlsUtilities.ReadUint8(inStr);
                    }

                    byte[] authorities = TlsUtilities.ReadOpaque16(inStr);

                    AssertEmpty(inStr);

                    IList authorityDNs = Platform.CreateArrayList();

                    MemoryStream bis = new MemoryStream(authorities, false);
                    while (bis.Position < bis.Length)
                    {
                        byte[] dnBytes = TlsUtilities.ReadOpaque16(bis);
                        // TODO Switch to X500Name when available
                        authorityDNs.Add(X509Name.GetInstance(Asn1Object.FromByteArray(dnBytes)));
                    }

                    this.certificateRequest = new CertificateRequest(certificateTypes,
                                                                     authorityDNs);
                    this.keyExchange.ValidateCertificateRequest(this.certificateRequest);

                    break;
                }

                default:
                    this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message);
                    break;
                }

                this.connection_state = CS_CERTIFICATE_REQUEST_RECEIVED;
                break;

            case HandshakeType.hello_request:
                /*
                 * RFC 2246 7.4.1.1 Hello request
                 * This message will be ignored by the client if the client is currently
                 * negotiating a session. This message may be ignored by the client if it
                 * does not wish to renegotiate a session, or the client may, if it wishes,
                 * respond with a no_renegotiation alert.
                 */
                if (connection_state == CS_DONE)
                {
                    // Renegotiation not supported yet
                    SendAlert(AlertLevel.warning, AlertDescription.no_renegotiation);
                }
                break;

            case HandshakeType.client_key_exchange:
            case HandshakeType.certificate_verify:
            case HandshakeType.client_hello:
            default:
                // We do not support this!
                this.FailWithError(AlertLevel.fatal, AlertDescription.unexpected_message);
                break;
            }
        }
コード例 #23
0
 public static void Write(this EndianBinaryWriter writer, CipherSuite value)
 {
     writer.Write((ushort)value);
 }
コード例 #24
0
        public ClientHello(byte[] clientHelloBytes) : base(clientHelloBytes)
        {
            var index = 0;

            var _protocolVersion = Utils.ToUInt16(clientHelloBytes, index);

            index += 2;

            var bytes_random = new byte[32];

            Buffer.BlockCopy(clientHelloBytes, index, bytes_random, 0, bytes_random.Length);
            index += 32;

            var _sessionIDLength = clientHelloBytes[index];

            byte[] _sessionID = null;
            index++;

            // if sessionID exists
            if (_sessionIDLength > 0)
            {
                _sessionID = new byte[_sessionIDLength];
                Buffer.BlockCopy(clientHelloBytes, index, _sessionID, 0, _sessionIDLength);
                index += _sessionIDLength;
            }

            var _cipherSuiteLen = Utils.ToUInt16(clientHelloBytes, index);

            _cipherSuiteLen = (ushort)(_cipherSuiteLen / 2);
            index          += 2;
            CipherSuite[] _cipherSuites = new CipherSuite[_cipherSuiteLen];
            for (int csi = 0; csi < _cipherSuiteLen; csi++)
            {
                _cipherSuites[csi] = (CipherSuite)Utils.ToUInt16(clientHelloBytes, index);
                index += 2;
            }

            var _compressionMethodLen = clientHelloBytes[index];

            index++;
            CompressionMethod[] _compressionMethods = new CompressionMethod[_compressionMethodLen];
            for (int cmi = 0; cmi < _compressionMethodLen; cmi++)
            {
                _compressionMethods[cmi] = (CompressionMethod)clientHelloBytes[index];
                index++;
            }

            var _extensionsLength = Utils.ToUInt16(clientHelloBytes, index);

            index += 2;

            var bytes_extensions = new byte[_extensionsLength];

            Buffer.BlockCopy(clientHelloBytes, index, bytes_extensions, 0, _extensionsLength);
            var _extensions = TLS.Extensions.Extension.Extract(bytes_extensions);

            this.ProtocolVersion    = (ProtocolVersion)_protocolVersion;
            this.Random             = new ValueTypes.Random(bytes_random);
            this.Session            = new ValueTypes.Session(_sessionID);
            this.CipherSuites       = new ValueTypes.CipherSuites(_cipherSuites);
            this.CompressionMethods = new ValueTypes.CompressionMethods(_compressionMethods);
            this.Extensions         = _extensions;
            this.ExtensionsLength   = TLS.Extensions.Extension.GetLength(_extensions);
        }
コード例 #25
0
        private static bool IsSupported(CipherSuite suite)
        {
            // suite
            if (!Suites.Contains(suite)) { return false; }
            // cipher
            if (!CipherMapping.ContainsKey(suite)) { return false; }
            if (!IsSupported(CipherMapping[suite])) { return false; }
            // digest
            if (!DigestMapping.ContainsKey(suite)) { return false; }
            if (!IsSupported(DigestMapping[suite])) { return false; }
            // signature
            if (!SignatureMapping.ContainsKey(suite)) { return false; }
            if (!IsSupported(SignatureMapping[suite])) { return false; }
            // keyexchange
            if (!KeyExchangeMapping.ContainsKey(suite)) { return false; }
            if (!IsSupported(KeyExchangeMapping[suite])) { return false; }

            return true;
        }
コード例 #26
0
        /// <summary>
        /// Reads this object in from an array, returning how many bytes were read, or 0 if there is an error or not enough data
        /// </summary>
        /// <param name="bData"></param>
        /// <param name="nStartAt"></param>
        /// <returns></returns>
        public uint ReadFromArray(byte[] bData, int nStartAt)
        {
            CipherSuites.Clear();
            CompressionMethods.Clear();

            uint nReadSoFar = 0;

            if (bData.Length < (nStartAt + 35))
            {
                return(0);
            }

            Version = ByteHelper.ReadUshortBigEndian(bData, (int)(nStartAt + nReadSoFar)); nReadSoFar += 2;

            nReadSoFar += RandomStruct.ReadFromArray(bData, (int)(nStartAt + nReadSoFar));

            SessionIDLength = bData[nStartAt + nReadSoFar]; nReadSoFar += 1;
            if (SessionIDLength > 0)
            {
                if (bData.Length < (nStartAt + nReadSoFar + SessionIDLength))
                {
                    return(0);
                }
                this.SessionID = ByteHelper.ReadByteArray(bData, (int)(nStartAt + nReadSoFar), (int)SessionIDLength); nReadSoFar += SessionIDLength;
            }

            if (bData.Length < (nStartAt + nReadSoFar + 2))
            {
                return(0);
            }
            CipherSuitesLength = ByteHelper.ReadUshortBigEndian(bData, (int)(nStartAt + nReadSoFar)); nReadSoFar += 2;

            if (CipherSuitesLength > 0)
            {
                if (bData.Length < (nStartAt + nReadSoFar + CipherSuitesLength))
                {
                    return(0);
                }
                for (int i = 0; i < CipherSuitesLength / 2; i++)
                {
                    CipherSuite nNextCipherSuite = (CipherSuite)ByteHelper.ReadUshortBigEndian(bData, (int)(nStartAt + nReadSoFar)); nReadSoFar += 2;
                    CipherSuites.Add(nNextCipherSuite);
                }
            }

            if (bData.Length < (nStartAt + nReadSoFar + 2))
            {
                return(0);
            }
            CompressionMethodsLength = ByteHelper.ReadByte(bData, (int)(nStartAt + nReadSoFar)); nReadSoFar += 1;
            if (CompressionMethodsLength > 0)
            {
                if (bData.Length < (nStartAt + nReadSoFar + CompressionMethodsLength))
                {
                    return(0);
                }
                for (int i = 0; i < CipherSuitesLength / 2; i++)
                {
                    CompressionMethod bNextCompressionMethod = (CompressionMethod)ByteHelper.ReadByte(bData, (int)(nStartAt + nReadSoFar)); nReadSoFar += 1;
                    CompressionMethods.Add(bNextCompressionMethod);
                }
            }


            return(nReadSoFar);
        }
コード例 #27
0
 /// <summary>Add a new encryption zone.</summary>
 /// <remarks>
 /// Add a new encryption zone.
 /// <p/>
 /// Called while holding the FSDirectory lock.
 /// </remarks>
 /// <param name="inodeId">of the encryption zone</param>
 /// <param name="keyName">encryption zone key name</param>
 internal virtual void AddEncryptionZone(long inodeId, CipherSuite suite, CryptoProtocolVersion
                                         version, string keyName)
 {
     System.Diagnostics.Debug.Assert(dir.HasWriteLock());
     UnprotectedAddEncryptionZone(inodeId, suite, version, keyName);
 }
コード例 #28
0
        public static CipherSuite InitializeCipherSuite(byte[] master, byte[] clientrnd, byte[] serverrnd, CipherDefinition definition, ConnectionEnd entity)
        {
            CipherSuite        ret  = new CipherSuite();
            SymmetricAlgorithm bulk = (SymmetricAlgorithm)Activator.CreateInstance(definition.BulkCipherAlgorithm);

            if (definition.BulkIVSize > 0)
            {
                bulk.Mode = CipherMode.CBC;
            }
            bulk.Padding   = PaddingMode.None;
            bulk.BlockSize = definition.BulkIVSize * 8;
            // get the keys and IVs
            byte[] client_mac, server_mac, client_key, server_key, client_iv, server_iv;
            byte[] random = new byte[64];
            Array.Copy(serverrnd, 0, random, 0, 32);
            Array.Copy(clientrnd, 0, random, 32, 32);
            PseudoRandomDeriveBytes prf = new PseudoRandomDeriveBytes(master, "key expansion", random);

            client_mac = prf.GetBytes(definition.HashSize);
            server_mac = prf.GetBytes(definition.HashSize);
            client_key = prf.GetBytes(definition.BulkKeySize);
            server_key = prf.GetBytes(definition.BulkKeySize);
            client_iv  = prf.GetBytes(definition.BulkIVSize);
            server_iv  = prf.GetBytes(definition.BulkIVSize);
            prf.Dispose();
            if (definition.Exportable)               // make some extra modifications if the keys are exportable
            {
                Array.Copy(clientrnd, 0, random, 0, 32);
                Array.Copy(serverrnd, 0, random, 32, 32);
                prf        = new PseudoRandomDeriveBytes(client_key, "client write key", random);
                client_key = prf.GetBytes(definition.BulkExpandedSize);
                prf.Dispose();
                prf        = new PseudoRandomDeriveBytes(server_key, "server write key", random);
                server_key = prf.GetBytes(definition.BulkExpandedSize);
                prf.Dispose();
                prf       = new PseudoRandomDeriveBytes(new byte[0], "IV block", random);
                client_iv = prf.GetBytes(definition.BulkIVSize);
                server_iv = prf.GetBytes(definition.BulkIVSize);
                prf.Dispose();
            }
            // generate the cipher objects
            if (entity == ConnectionEnd.Client)
            {
                ret.Encryptor    = bulk.CreateEncryptor(client_key, client_iv);
                ret.Decryptor    = bulk.CreateDecryptor(server_key, server_iv);
                ret.LocalHasher  = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), client_mac);
                ret.RemoteHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), server_mac);
            }
            else
            {
                ret.Encryptor    = bulk.CreateEncryptor(server_key, server_iv);
                ret.Decryptor    = bulk.CreateDecryptor(client_key, client_iv);
                ret.LocalHasher  = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), server_mac);
                ret.RemoteHasher = new HMAC((HashAlgorithm)Activator.CreateInstance(definition.HashAlgorithm), client_mac);
            }
            // clear sensitive data
            Array.Clear(client_mac, 0, client_mac.Length);
            Array.Clear(server_mac, 0, server_mac.Length);
            Array.Clear(client_key, 0, client_key.Length);
            Array.Clear(server_key, 0, server_key.Length);
            Array.Clear(client_iv, 0, client_iv.Length);
            Array.Clear(server_iv, 0, server_iv.Length);
            Array.Clear(random, 0, random.Length);
            return(ret);
        }
コード例 #29
0
        void ProcessHandshake()
        {
            ClientHello clientHello = _recordLayer.Read() as ClientHello;

            if (clientHello == null)
            {
                throw new Exception();
            }
            Console.WriteLine("[TLSServer] Receive ClientHello Version: {0}", clientHello.Version);
            Console.WriteLine("[TLSServer] CipherSuites");
            for (int i = 0; i < clientHello.CipherSuites.Length; i++)
            {
                Console.WriteLine("  {0}", clientHello.CipherSuites[i]);
            }
            CipherSuite selected = _selector.Select(clientHello.CipherSuites);

            Console.WriteLine("[TLSServer] CipherSuite Selected. {0}", selected);
            if (selected == CipherSuite.NONE)
            {
                // Alertを送るべき?
                throw new Exception();
            }
            CipherSuiteInfo selectedInfo = SupportedCipherSuites.GetSuiteInfo(selected);

            _sparams.SetVersion(clientHello.Version);
            _sparams.SetCipherSuite(selected, _signAlgo);
            _sparams.ClientRandom        = clientHello.Random;
            _recordLayer.ProtocolVersion = clientHello.Version;

            byte[]      serverRandom     = new byte[RandomData.Size];
            Extension[] serverExtensions = null;
            if (selectedInfo.IsECC)
            {
                serverExtensions = new Extension[] { new Extension(ExtensionType.EcPointFormats, new byte[] { 1, 0 }) }
            }
            ;
            RandomData.CreateRandomData(serverRandom, 0);
            _sparams.ServerRandom = serverRandom;
            ServerHello serverHello = new ServerHello(clientHello.Version, serverRandom, Utility.EmptyByteArray, selected, CompressionMethod.Null, serverExtensions);

            _recordLayer.Write(serverHello);

            Certificate serverCert = new Certificate(_certs);

            _recordLayer.Write(serverCert);

            if (Utility.IsNeedServerKeyExchangeMessage(_states.SecurityParameters.KeyExchangeAlgorithm))
            {
                ServerKeyExchange serverExchange = new ServerKeyExchange(_sparams);
                _recordLayer.Write(serverExchange);
            }

            _recordLayer.Write(new ServerHelloDone());

            TLSMessage        msg            = _recordLayer.Read();
            ClientKeyExchange clientExchange = (ClientKeyExchange)msg;

            clientExchange.ComputeServerMasterSecret(_sparams);
            Console.WriteLine("MasterSecret");
            Utility.Dump(_sparams.MasterSecret);
            _sparams.ComputeKeyBlock();

            ChangeCipherSpec changeCipherSpec = (ChangeCipherSpec)_recordLayer.Read();

            _recordLayer.EnableReceiveCipher(_sparams.CreateServerDecryptor(), _sparams.CreateClientWriteHMAC());

            Finished finished = (Finished)_recordLayer.Read();

            Console.WriteLine("VerifyData");
            Utility.Dump(finished.VerifyData);
            Console.WriteLine("Computed VerifyData");
            byte[] verifyData = _sparams.ComputeFinishedVerifyData(false);
            Utility.Dump(verifyData);
            if (!Utility.Equals(finished.VerifyData, 0, verifyData, 0, verifyData.Length))
            {
                throw new Exception();
            }

            _recordLayer.Write(ChangeCipherSpec.Instance);
            _recordLayer.EnableSendCipher(_sparams.CreateServerEncryptor(), _sparams.CreateServerWriteHMAC());
            _recordLayer.ComputeHandshakeHash(true);
            verifyData = _sparams.ComputeFinishedVerifyData(true);
            Console.WriteLine("Finished VerifyData");
            Utility.Dump(verifyData);
            finished = new Finished(_recordLayer.ProtocolVersion, verifyData);
            _recordLayer.Write(finished);
        }
コード例 #30
0
        private static CipherSuite SelectCipherSuite(CipherSuitePluginManager pluginManager,
                                                     ProtocolVersion clientVersion, ProtocolVersion minVersion, ProtocolVersion maxVersion,
                                                     List <CipherSuiteId> clientSuites, List <CipherSuiteId> serverSuites,
                                                     ServerCertificateSelectionCallback certificateSelectionCallback,
                                                     List <X509CertificateCollection> availableCertificates)
        {
            if (clientVersion < minVersion)
            {
                throw new AlertException(AlertDescription.ProtocolVersion,
                                         "Offered client version " + clientVersion +
                                         " lower than minimum supported version " + minVersion);
            }

            // Initialize our return value as null
            CipherSuite selectedCipherSuite = null;

            // Run as long as we either select a cipher suite or run out of versions
            ProtocolVersion selectedVersion = clientVersion < maxVersion ? clientVersion : maxVersion;

            while (selectedCipherSuite == null)
            {
                foreach (CipherSuiteId id in clientSuites)
                {
                    if (!serverSuites.Contains(id))
                    {
                        continue;
                    }

                    // Try initializing the cipher suite based on ID
                    selectedCipherSuite = pluginManager.GetCipherSuite(selectedVersion, (ushort)id);
                    if (selectedCipherSuite == null)
                    {
                        continue;
                    }

                    // Try selecting a suitable certificate for this cipher suite
                    int certificateIndex = certificateSelectionCallback(selectedCipherSuite, availableCertificates.ToArray());
                    if (certificateIndex >= 0 && certificateIndex < availableCertificates.Count)
                    {
                        // We finally found the valid suite, break out from the loop
                        break;
                    }
                    // No certificate was found for the suite, ignore
                    selectedCipherSuite = null;
                }

                if (selectedCipherSuite != null)
                {
                    break;
                }
                if (selectedVersion == minVersion)
                {
                    break;
                }
                selectedVersion = selectedVersion.PreviousProtocolVersion;
            }

            if (selectedCipherSuite == null)
            {
                throw new AlertException(AlertDescription.HandshakeFailure,
                                         "None of the cipher suites offered by client is accepted");
            }
            return(selectedCipherSuite);
        }
コード例 #31
0
ファイル: ServerHello.cs プロジェクト: whSwitching/TLSHandler
        public ServerHello(ProtocolVersion protocolVersion, ValueTypes.Random random, ValueTypes.Session session, CipherSuite cipher, Extensions.Extension[] extensions = null) : base(null)
        {
            this.ProtocolVersion   = protocolVersion;
            this.Random            = random;
            this.Session           = session;
            this.CipherSuite       = cipher;
            this.CompressionMethod = CompressionMethod.NO_COMPRESSION;
            this.Extensions        = extensions;
            this.ExtensionsLength  = TLS.Extensions.Extension.GetLength(extensions);

            byte[] bytes_random  = this.Random.Data;
            byte[] bytes_session = this.Session.Data;

            // length of the Handshake Header payload (aka the ServerHello message)
            int length = 2;                     // 2 bytes ProtocolVersion

            length += bytes_random.Length;      //   bytes ServerRandom
            length += bytes_session.Length;     // 1 byte SessionIDLength + bytes SessionID
            length += 2;                        // 2 bytes CipherSuite
            length += 1;                        // 1 byte CompressionMethod
            length += 2;                        // 2 bytes ExtensionsLength
            length += this.ExtensionsLength;    // total bytes of extensions

            Data = new byte[length];
            int index = 0;

            // ProtocolVersion
            Data[index]     = (byte)(((ushort)ProtocolVersion & 0xff00) >> 8);
            Data[index + 1] = (byte)((ushort)ProtocolVersion & 0x00ff);
            index          += 2;
            // ServerRandom
            Buffer.BlockCopy(bytes_random, 0, Data, index, bytes_random.Length);
            index += bytes_random.Length;
            // SessionIDLength + SessionID
            Buffer.BlockCopy(bytes_session, 0, Data, index, bytes_session.Length);
            index += bytes_session.Length;
            // CipherSuite
            Data[index]     = (byte)(((ushort)this.CipherSuite & 0xff00) >> 8);
            Data[index + 1] = (byte)((ushort)this.CipherSuite & 0x00ff);
            index          += 2;
            // CompressionMethod
            Data[index] = (byte)this.CompressionMethod;
            index      += 1;
            // ExtensionsLength
            Data[index]     = (byte)((this.ExtensionsLength & 0xff00) >> 8);
            Data[index + 1] = (byte)(this.ExtensionsLength & 0x00ff);
            index          += 2;
            // Extensions
            if (this.Extensions != null)
            {
                foreach (var e in this.Extensions)
                {
                    var extBytes = e.Data;
                    Buffer.BlockCopy(extBytes, 0, Data, index, extBytes.Length);
                    index += extBytes.Length;
                }
            }
        }
コード例 #32
0
		protected override void ProcessAsTls1()
		{
			// Read protocol version
			this.processProtocol(this.ReadInt16());
			
			// Read random  - Unix time + Random bytes
			this.random	= this.ReadBytes(32);
						
			// Read Session id
			int length = (int)ReadByte();
			if (length > 0)
			{
				this.sessionId = this.ReadBytes(length);
			}

			// Read cipher suite
			short cipherCode = this.ReadInt16();
			if (this.Context.SupportedCiphers.IndexOf(cipherCode) == -1)
			{
				// The server has sent an invalid ciphersuite
				throw new TlsException(AlertDescription.InsuficientSecurity, "Invalid cipher suite received from server");
			}
			this.cipherSuite = this.Context.SupportedCiphers[cipherCode];
			
			// Read compression methods ( always 0 )
			this.compressionMethod = (SecurityCompressionType)this.ReadByte();
		}
コード例 #33
0
ファイル: ServerConnection.cs プロジェクト: nagyist/mono-tls
        protected virtual void SelectCipher(TlsClientHello message)
        {
            var certificate = Config.Certificate;

            if (certificate == null)
            {
                throw new TlsException(AlertDescription.HandshakeFailure, "Missing server certificate");
            }

            CipherSuiteCollection requestedCiphers;

            if (Settings.RequestedCiphers != null)
            {
                requestedCiphers = new CipherSuiteCollection(Context.NegotiatedProtocol, Settings.RequestedCiphers);
            }
            else
            {
                requestedCiphers = CipherSuiteFactory.GetDefaultCiphers(Context.NegotiatedProtocol);
            }

            HandshakeParameters.SupportedCiphers = requestedCiphers.Filter(cipher => {
                                #if INSTRUMENTATION
                if (Context.HasInstrument(HandshakeInstrumentType.OverrideServerCertificateSelection))
                {
                    return(true);
                }
                                #endif
                var exchangeAlgorithm = CipherSuiteFactory.GetExchangeAlgorithmType(Context.NegotiatedProtocol, cipher);
                return(CertificateManager.VerifyServerCertificate(Context, certificate, exchangeAlgorithm));
            });

            CipherSuite selectedCipher = null;
            foreach (var code in message.ClientCiphers)
            {
                var idx = HandshakeParameters.SupportedCiphers.IndexOf(code);
                if (idx < 0)
                {
                    continue;
                }
                var cipher = HandshakeParameters.SupportedCiphers [idx];
                selectedCipher = CipherSuiteFactory.CreateCipherSuite(Context.NegotiatedProtocol, cipher);
                break;
            }

            if (selectedCipher == null)
            {
                throw new TlsException(AlertDescription.HandshakeFailure, "Invalid cipher suite received from client");
            }

                        #if DEBUG_FULL
            if (Context.EnableDebugging)
            {
                selectedCipher.EnableDebugging = true;
            }
                        #endif

                        #if DEBUG_FULL
            if (Context.EnableDebugging)
            {
                DebugHelper.WriteLine("Selected Cipher: {0}", selectedCipher);
            }
                        #endif

            // FIXME: Select best one.
            Session.PendingCrypto = selectedCipher.Initialize(true, Context.NegotiatedProtocol);
            Session.PendingCrypto.ServerCertificates = new X509CertificateCollection();
            Session.PendingCrypto.ServerCertificates.Add(certificate);
        }
コード例 #34
0
        public void TLSv10Test()
        {
            byte[] finished1eb1 = new byte[] {
                0x16, 0x03, 0x01, 0x00, 0x30, 0x78, 0x02, 0x93,
                0x89, 0x26, 0x70, 0xDD, 0x57, 0x12, 0xD5, 0x47,
                0xC5, 0xE3, 0x9E, 0xE7, 0x03, 0x2A, 0x41, 0x35,
                0x46, 0xE3, 0x13, 0x06, 0xBB, 0x4F, 0x21, 0xEB,
                0x3D, 0x5F, 0x42, 0xF6, 0xBF, 0x89, 0x4B, 0x43,
                0x8C, 0x77, 0x29, 0xF9, 0x54, 0xDC, 0xCB, 0x0E,
                0xE6, 0xA4, 0xA0, 0x13, 0xF8
            };
            byte[] finished1eb2 = new byte[] {
                0x16, 0x03, 0x01, 0x00, 0x40, 0x78, 0x02, 0x93,
                0x89, 0x26, 0x70, 0xdd, 0x57, 0x12, 0xd5, 0x47,
                0xc5, 0xe3, 0x9e, 0xe7, 0x03, 0x2a, 0x41, 0x35,
                0x46, 0xe3, 0x13, 0x06, 0xbb, 0x4f, 0x21, 0xeb,
                0x3d, 0x5f, 0x42, 0xf6, 0xbf, 0x1f, 0x91, 0x7c,
                0xf3, 0xf5, 0x07, 0x84, 0xc4, 0x51, 0x89, 0x73,
                0xbb, 0xb1, 0x88, 0x35, 0xcd, 0x21, 0xa9, 0x2a,
                0x1a, 0x08, 0xfc, 0x23, 0x4b, 0x9f, 0x9b, 0x0a,
                0x83, 0x47, 0x2c, 0x2e, 0x81
            };
            byte[] finished2eb = new byte[] {
                0x16, 0x03, 0x01, 0x00, 0x30, 0xde, 0x54, 0x89,
                0x2f, 0x60, 0x2f, 0x3e, 0x88, 0x6f, 0x78, 0xac,
                0xed, 0xf9, 0xf8, 0x56, 0x31, 0xbd, 0x55, 0x3f,
                0x7f, 0x82, 0x41, 0xfa, 0x49, 0x4c, 0x16, 0x01,
                0x13, 0x91, 0xcb, 0xcc, 0x78, 0x3f, 0x89, 0x86,
                0xaa, 0x58, 0xd1, 0x73, 0x76, 0xb3, 0xa2, 0x82,
                0x99, 0x02, 0x07, 0x95, 0x56
            };
            byte[] finished1db = new byte[] {
                0x16, 0x03, 0x01, 0x00, 0x10, 0x14, 0x00, 0x00,
                0x0C, 0x21, 0x39, 0xB0, 0xD0, 0x3F, 0x12, 0x1F,
                0x3B, 0x76, 0x1A, 0xE7, 0x71
            };
            byte[] finished2db = new byte[] {
                0x16, 0x03, 0x01, 0x00, 0x10, 0x14, 0x00, 0x00,
                0x0C, 0xDE, 0x0C, 0x18, 0x26, 0x54, 0x99, 0x6F,
                0x29, 0xA2, 0x72, 0x91, 0xC4
            };
            byte[] crandom = new byte[] {
                0x4e, 0x60, 0xe1, 0xed, 0x13, 0x2c, 0x19, 0xe5,
                0x44, 0xaf, 0xb2, 0xe1, 0x1d, 0x97, 0x67, 0x47,
                0xaf, 0x5a, 0xb8, 0xf4, 0x7e, 0xcb, 0xbe, 0x42,
                0x4f, 0x3b, 0x24, 0x9e, 0xff, 0x0f, 0x5d, 0x87
            };
            byte[] srandom = new byte[] {
                0x4e, 0x60, 0xe2, 0xa4, 0x9e, 0x37, 0xea, 0x2a,
                0xc1, 0xbe, 0xe9, 0x3d, 0x05, 0x04, 0xb9, 0x83,
                0x57, 0x2a, 0x03, 0xf0, 0x1a, 0x6a, 0xe5, 0x53,
                0x08, 0xa9, 0x01, 0xb0, 0x06, 0x2a, 0x9a, 0x79
            };
            byte[] master = new byte[] {
                0xB2, 0xEC, 0xD1, 0x59, 0x9C, 0x97, 0x49, 0x58,
                0xFB, 0x86, 0x9A, 0x65, 0xEB, 0x8F, 0x91, 0x31,
                0x54, 0xAC, 0x41, 0xCD, 0xF8, 0x12, 0x8F, 0xCA,
                0x25, 0xF0, 0x06, 0x91, 0xFE, 0xF3, 0x09, 0x7F,
                0x04, 0x6F, 0x9D, 0x75, 0x24, 0x52, 0xCD, 0xC5,
                0x69, 0xE2, 0x0C, 0xB2, 0xB3, 0xCD, 0xA0, 0x02
            };

            Record finished1 = GetRecord(finished1db);
            Record finished2 = GetRecord(finished2eb);

            CipherSuitePluginManager pluginManager = GetPluginManager();
            RecordHandler            recordHandler = new RecordHandler(ProtocolVersion.SSL3_0, true);

            CipherSuite cipherSuite = pluginManager.GetCipherSuite(ProtocolVersion.TLS1_0, 0x002f);

            Assert.IsNotNull(cipherSuite);

            // Set correct cipher suite
            ConnectionState connectionState = new ConnectionState(crandom, srandom, master);

            recordHandler.SetCipherSuite(cipherSuite, connectionState);

            // Test that initial state doesn't modify records
            recordHandler.ProcessOutputRecord(finished1);
            recordHandler.ProcessInputRecord(finished2);
            Assert.AreEqual(finished1db, finished1.GetBytes());
            Assert.AreEqual(finished2eb, finished2.GetBytes());

            recordHandler.ChangeLocalState();
            recordHandler.ProcessOutputRecord(finished1);
            recordHandler.ChangeRemoteState();
            recordHandler.ProcessInputRecord(finished2);

            if (finished1.GetBytes().Length == finished1eb1.Length)
            {
                Assert.AreEqual(finished1eb1, finished1.GetBytes());
            }
            else
            {
                Assert.AreEqual(finished1eb2, finished1.GetBytes());
            }
            Assert.AreEqual(finished2db, finished2.GetBytes());
        }
コード例 #35
0
ファイル: DefaultTlsClient.cs プロジェクト: Arsslensoft/ALFX
 public virtual void NotifySelectedCipherSuite(CipherSuite selectedCipherSuite)
 {
     this.selectedCipherSuite = selectedCipherSuite;
 }
コード例 #36
0
 public static void Write(this EndianBinaryWriter writer, CipherSuite value)
 {
     writer.Write((ushort)value);
 }
コード例 #37
0
        /// <summary>
        /// Reads this object in from an array, returning how many bytes were read, or 0 if there is an error or not enough data
        /// </summary>
        /// <param name="bData"></param>
        /// <param name="nStartAt"></param>
        /// <returns></returns>
        public uint ReadFromArray(byte[] bData, int nStartAt)
        {
            uint nReadSoFar = 0;
            if (bData.Length < (nStartAt + 35))
                return 0;

            Version = ByteHelper.ReadUshortBigEndian(bData, (int)(nStartAt + nReadSoFar)); nReadSoFar += 2;

            nReadSoFar += RandomStruct.ReadFromArray(bData, (int) (nStartAt+nReadSoFar));

            SessionIDLength = bData[nStartAt + nReadSoFar]; nReadSoFar += 1;
            if (SessionIDLength > 0)
            {
                if (bData.Length < (nStartAt + nReadSoFar + SessionIDLength)) return 0;
                this.SessionID = ByteHelper.ReadByteArray(bData, (int)(nStartAt + nReadSoFar), (int)SessionIDLength); nReadSoFar += SessionIDLength;
            }

            CipherSuite = (CipherSuite) ByteHelper.ReadUshortBigEndian(bData, (int)(nStartAt + nReadSoFar)); nReadSoFar += 2;
            CompressionMethod = (CompressionMethod) ByteHelper.ReadByte(bData, (int)(nStartAt + nReadSoFar)); nReadSoFar += 1;

            return nReadSoFar;
        }
コード例 #38
0
    /*
     * Print the report on the provided writer (text version for
     * humans).
     */
    internal void Print(TextWriter w)
    {
        w.WriteLine("Connection: {0}:{1}", connName, connPort);
        if (sni == null)
        {
            w.WriteLine("No SNI sent");
        }
        else
        {
            w.WriteLine("SNI: {0}", sni);
        }
        if (ssl2Suites != null && ssl2Suites.Length > 0)
        {
            w.WriteLine("  {0}", M.VersionString(M.SSLv20));
            foreach (int s in ssl2Suites)
            {
                w.WriteLine("     {0}",
                            CipherSuite.ToNameV2(s));
            }
        }
        SupportedCipherSuites last = null;

        foreach (int v in suites.Keys)
        {
            w.Write("  {0}:", M.VersionString(v));
            SupportedCipherSuites scs = suites[v];
            if (scs.Equals(last))
            {
                w.WriteLine(" idem");
                continue;
            }
            last = scs;
            w.WriteLine();
            w.Write("     server selection: ");
            if (scs.PrefClient)
            {
                w.WriteLine("uses client preferences");
            }
            else if (scs.PrefServer)
            {
                w.WriteLine("enforce server preferences");
            }
            else
            {
                w.WriteLine("complex");
            }
            foreach (int s in scs.Suites)
            {
                CipherSuite cs;
                string      strength;
                string      fsf;
                string      anon;
                string      kt;
                if (CipherSuite.ALL.TryGetValue(s, out cs))
                {
                    strength = cs.Strength.ToString();
                    fsf      = cs.HasForwardSecrecy ? "f" : "-";
                    anon     = cs.IsAnonymous ? "A" : "-";
                    kt       = cs.ServerKeyType;
                }
                else
                {
                    strength = "?";
                    fsf      = "?";
                    anon     = "?";
                    kt       = "?";
                }
                w.WriteLine("     {0}{1}{2} (key: {3,4})  {4}",
                            strength, fsf, anon, kt,
                            CipherSuite.ToName(s));
            }
        }
        w.WriteLine("=========================================");
        if (ssl2Chain != null)
        {
            w.WriteLine("+++++ SSLv2 certificate");
            PrintCert(w, ssl2Chain, 0);
        }
        w.WriteLine("+++++ SSLv3/TLS: {0} certificate chain(s)",
                    chains.Count);
        foreach (X509Chain xchain in chains.Values)
        {
            int n = xchain.Elements.Length;
            w.WriteLine("+++ chain: length={0}", n);
            if (xchain.Decodable)
            {
                w.WriteLine("names match:        {0}",
                            xchain.NamesMatch ? "yes" : "no");
                w.WriteLine("includes root:      {0}",
                            xchain.IncludesRoot ? "yes" : "no");
                w.Write("signature hash(es):");
                foreach (string name in xchain.SignHashes)
                {
                    w.Write(" {0}", name);
                }
                w.WriteLine();
            }
            else if (n == 0)
            {
                w.WriteLine("CHAIN IS EMPTY");
            }
            else
            {
                w.WriteLine("CHAIN PROCESSING ERROR");
            }
            for (int i = 0; i < n; i++)
            {
                w.WriteLine("+ certificate order: {0}", i);
                PrintCert(w, xchain, i);
            }
        }
        w.WriteLine("=========================================");
        w.WriteLine("Server compression support: {0}",
                    DeflateCompress ? "yes" : "no");
        if (serverTimeOffset == Int64.MinValue)
        {
            w.WriteLine("Server does not send its system time.");
        }
        else if (serverTimeOffset == Int64.MaxValue)
        {
            w.WriteLine("Server sends a random system time.");
        }
        else
        {
            DateTime dt = DateTime.UtcNow;
            dt = dt.AddMilliseconds((double)serverTimeOffset);
            w.WriteLine("Server time: {0:yyyy-MM-dd HH:mm:ss} UTC"
                        + " (offset: {1} ms)", dt, serverTimeOffset);
        }
        w.WriteLine("Secure renegotiation support: {0}",
                    doesRenego ? "yes" : "no");
        w.WriteLine("SSLv2 ClientHello format (for SSLv3+): {0}",
                    helloV2 ? "yes" : "no");
        if (minDHSize > 0)
        {
            w.WriteLine("Minimum DH size: {0}", minDHSize);
            w.WriteLine("DH parameter reuse: {0}",
                        kxReuseDH ? "yes" : " no");
        }
        if (minECSize > 0)
        {
            w.WriteLine("Minimum EC size (no extension):   {0}",
                        minECSize);
        }
        if (minECSizeExt > 0)
        {
            w.WriteLine("Minimum EC size (with extension): {0}",
                        minECSizeExt);
            if (minECSize == 0)
            {
                w.WriteLine("Server does not use EC without"
                            + " the client extension");
            }
        }
        if (minECSize > 0 || minECSizeExt > 0)
        {
            w.WriteLine("ECDH parameter reuse: {0}",
                        kxReuseECDH ? "yes" : " no");
        }
        if (namedCurves != null && namedCurves.Length > 0)
        {
            w.WriteLine("Supported curves (size and name)"
                        + " ('*' = selected by server):");
            foreach (SSLCurve nc in namedCurves)
            {
                w.WriteLine("  {0} {1,3}  {2}",
                            IsSpontaneous(nc) ? "*" : " ",
                            nc.Size, nc.Name);
            }
            if (curveExplicitPrime > 0)
            {
                w.WriteLine("  explicit prime, size = {0}",
                            curveExplicitPrime);
            }
            if (curveExplicitChar2 > 0)
            {
                w.WriteLine("  explicit char2, size = {0}",
                            curveExplicitChar2);
            }
        }

        w.WriteLine("=========================================");
        if (warnings == null)
        {
            Analyse();
        }
        if (warnings.Count == 0)
        {
            w.WriteLine("No warning.");
        }
        else
        {
            foreach (string k in warnings.Keys)
            {
                w.WriteLine("WARN[{0}]: {1}", k, warnings[k]);
            }
        }
    }
コード例 #39
0
		public virtual void NotifySelectedCipherSuite(CipherSuite selectedCipherSuite)
		{
			this.selectedCipherSuite = selectedCipherSuite;
		}
コード例 #40
0
    /*
     * Encode the report as JSON.
     */
    internal void Print(JSON js)
    {
        js.OpenInit(false);
        js.AddPair("connectionName", connName);
        js.AddPair("connectionPort", connPort);
        js.AddPair("SNI", sni);
        if (ssl2Suites != null && ssl2Suites.Length > 0)
        {
            js.OpenPairObject("SSLv2");
            js.OpenPairArray("suites");
            foreach (int s in ssl2Suites)
            {
                js.OpenElementObject();
                js.AddPair("id", s);
                js.AddPair("name", CipherSuite.ToNameV2(s));
                js.Close();
            }
            js.Close();
            js.Close();
        }

        foreach (int v in suites.Keys)
        {
            js.OpenPairObject(M.VersionString(v));
            SupportedCipherSuites scs = suites[v];
            string sel;
            if (scs.PrefClient)
            {
                sel = "client";
            }
            else if (scs.PrefServer)
            {
                sel = "server";
            }
            else
            {
                sel = "complex";
            }
            js.AddPair("suiteSelection", sel);
            js.OpenPairArray("suites");
            foreach (int s in scs.Suites)
            {
                js.OpenElementObject();
                js.AddPair("id", s);
                js.AddPair("name", CipherSuite.ToName(s));
                CipherSuite cs;
                if (CipherSuite.ALL.TryGetValue(s, out cs))
                {
                    js.AddPair("strength", cs.Strength);
                    js.AddPair("forwardSecrecy",
                               cs.HasForwardSecrecy);
                    js.AddPair("anonymous",
                               cs.IsAnonymous);
                    js.AddPair("serverKeyType",
                               cs.ServerKeyType);
                }
                js.Close();
            }
            js.Close();
            js.Close();
        }

        if (ssl2Chain != null)
        {
            js.OpenPairObject("ssl2Cert");
            PrintCert(js, ssl2Chain, 0);
            js.Close();
        }

        js.OpenPairArray("ssl3Chains");
        foreach (X509Chain xchain in chains.Values)
        {
            js.OpenElementObject();
            int n = xchain.Elements.Length;
            js.AddPair("length", n);
            js.AddPair("decoded", xchain.Decodable);
            if (xchain.Decodable)
            {
                js.AddPair("namesMatch", xchain.NamesMatch);
                js.AddPair("includesRoot", xchain.IncludesRoot);
                js.OpenPairArray("signHashes");
                foreach (string name in xchain.SignHashes)
                {
                    js.AddElement(name);
                }
                js.Close();
            }
            js.OpenPairArray("certificates");
            for (int i = 0; i < n; i++)
            {
                js.OpenElementObject();
                PrintCert(js, xchain, i);
                js.Close();
            }
            js.Close();
            js.Close();
        }
        js.Close();

        js.AddPair("deflateCompress", DeflateCompress);
        if (serverTimeOffset == Int64.MinValue)
        {
            js.AddPair("serverTime", "none");
        }
        else if (serverTimeOffset == Int64.MaxValue)
        {
            js.AddPair("serverTime", "random");
        }
        else
        {
            DateTime dt = DateTime.UtcNow;
            dt = dt.AddMilliseconds((double)serverTimeOffset);
            js.AddPair("serverTime", string.Format(
                           "{0:yyyy-MM-dd HH:mm:ss} UTC", dt));
            js.AddPair("serverTimeOffsetMillis",
                       serverTimeOffset);
        }
        js.AddPair("secureRenegotiation", doesRenego);
        js.AddPair("ssl2HelloFormat", helloV2);
        if (minDHSize > 0)
        {
            js.AddPair("minDHSize", minDHSize);
            js.AddPair("kxReuseDH", kxReuseDH);
        }
        if (minECSize > 0)
        {
            js.AddPair("minECSize", minECSize);
        }
        if (minECSizeExt > 0)
        {
            js.AddPair("minECSizeExt", minECSizeExt);
        }
        if (minECSize > 0 || minECSizeExt > 0)
        {
            js.AddPair("kxReuseECDH", kxReuseECDH);
        }

        if ((namedCurves != null && namedCurves.Length > 0) ||
            curveExplicitPrime > 0 || curveExplicitChar2 > 0)
        {
            js.OpenPairArray("namedCurves");
            foreach (SSLCurve nc in namedCurves)
            {
                js.OpenElementObject();
                js.AddPair("name", nc.Name);
                js.AddPair("size", nc.Size);
                js.AddPair("spontaneous", IsSpontaneous(nc));
                js.Close();
            }
            if (curveExplicitPrime > 0)
            {
                js.OpenElementObject();
                js.AddPair("name", "explicitPrime");
                js.AddPair("size", curveExplicitPrime);
                js.Close();
            }
            if (curveExplicitChar2 > 0)
            {
                js.OpenElementObject();
                js.AddPair("name", "explicitChar2");
                js.AddPair("size", curveExplicitChar2);
                js.Close();
            }
            js.Close();
        }

        if (warnings == null)
        {
            Analyse();
        }
        js.OpenPairArray("warnings");
        foreach (string k in warnings.Keys)
        {
            js.OpenElementObject();
            js.AddPair("id", k);
            js.AddPair("text", warnings[k]);
            js.Close();
        }
        js.Close();
        js.Close();
    }
コード例 #41
0
ファイル: HandshakeLayer.cs プロジェクト: jasenkin/netmq
        private void AddServerHelloMessage(OutgoingMessageBag outgoingMessages, CipherSuite[] cipherSuites)
        {
            ServerHelloMessage serverHelloMessage = new ServerHelloMessage();
              serverHelloMessage.RandomNumber = new byte[RandomNumberLength];
              m_rng.GetBytes(serverHelloMessage.RandomNumber);

              SecurityParameters.ServerRandom = serverHelloMessage.RandomNumber;

              // in case their is no much the server will return this defaul
              serverHelloMessage.CipherSuite = CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA;

              foreach (CipherSuite cipherSuite in cipherSuites)
              {
            if (AllowedCipherSuites.Contains(cipherSuite))
            {
              serverHelloMessage.CipherSuite = cipherSuite;
              SetCipherSuite(cipherSuite);
              break;
            }
              }

              NetMQMessage outgoingMessage = serverHelloMessage.ToNetMQMessage();
              HashLocalAndRemote(outgoingMessage);
              outgoingMessages.AddHandshakeMessage(outgoingMessage);
            m_lastSentMessage = HandshakeType.ServerHello;
        }
コード例 #42
0
        public static CipherSuite InitializeCipherSuite(byte[] master, byte[] clientrnd, byte[] serverrnd, CipherDefinition definition, ConnectionEnd entity)
        {
            CipherSuite        ret  = new CipherSuite();
            SymmetricAlgorithm bulk = (SymmetricAlgorithm)Activator.CreateInstance(definition.BulkCipherAlgorithm);

            if (definition.BulkIVSize > 0)
            {
                bulk.Mode = CipherMode.CBC;
            }
            bulk.Padding   = PaddingMode.None;
            bulk.BlockSize = definition.BulkIVSize * 8;
            // get the keys and IVs
            byte[]          client_mac, server_mac, client_key, server_key, client_iv, server_iv;
            Ssl3DeriveBytes prf = new Ssl3DeriveBytes(master, clientrnd, serverrnd, false);

            client_mac = prf.GetBytes(definition.HashSize);
            server_mac = prf.GetBytes(definition.HashSize);
            client_key = prf.GetBytes(definition.BulkKeySize);
            server_key = prf.GetBytes(definition.BulkKeySize);
            client_iv  = prf.GetBytes(definition.BulkIVSize);
            server_iv  = prf.GetBytes(definition.BulkIVSize);
            prf.Dispose();
            if (definition.Exportable)               // make some extra modifications if the keys are exportable
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                md5.TransformBlock(client_key, 0, client_key.Length, client_key, 0);
                md5.TransformBlock(clientrnd, 0, clientrnd.Length, clientrnd, 0);
                md5.TransformFinalBlock(serverrnd, 0, serverrnd.Length);
                client_key = new byte[definition.BulkExpandedSize];
                Array.Copy(md5.Hash, 0, client_key, 0, client_key.Length);
                md5.Initialize();
                md5.TransformBlock(server_key, 0, server_key.Length, server_key, 0);
                md5.TransformBlock(serverrnd, 0, serverrnd.Length, serverrnd, 0);
                md5.TransformFinalBlock(clientrnd, 0, clientrnd.Length);
                server_key = new byte[definition.BulkExpandedSize];
                Array.Copy(md5.Hash, 0, server_key, 0, server_key.Length);
                md5.Initialize();
                md5.TransformBlock(clientrnd, 0, clientrnd.Length, clientrnd, 0);
                md5.TransformFinalBlock(serverrnd, 0, serverrnd.Length);
                client_iv = new byte[definition.BulkIVSize];
                Array.Copy(md5.Hash, 0, client_iv, 0, client_iv.Length);
                md5.Initialize();
                md5.TransformBlock(serverrnd, 0, serverrnd.Length, serverrnd, 0);
                md5.TransformFinalBlock(clientrnd, 0, clientrnd.Length);
                server_iv = new byte[definition.BulkIVSize];
                Array.Copy(md5.Hash, 0, server_iv, 0, server_iv.Length);
                md5.Clear();
            }
            // generate the cipher objects
            if (entity == ConnectionEnd.Client)
            {
                ret.Encryptor    = bulk.CreateEncryptor(client_key, client_iv);
                ret.Decryptor    = bulk.CreateDecryptor(server_key, server_iv);
                ret.LocalHasher  = new Ssl3RecordMAC(definition.HashAlgorithmType, client_mac);
                ret.RemoteHasher = new Ssl3RecordMAC(definition.HashAlgorithmType, server_mac);
            }
            else
            {
                ret.Encryptor    = bulk.CreateEncryptor(server_key, server_iv);
                ret.Decryptor    = bulk.CreateDecryptor(client_key, client_iv);
                ret.LocalHasher  = new Ssl3RecordMAC(definition.HashAlgorithmType, server_mac);
                ret.RemoteHasher = new Ssl3RecordMAC(definition.HashAlgorithmType, client_mac);
            }
            // clear sensitive data
            Array.Clear(client_mac, 0, client_mac.Length);
            Array.Clear(server_mac, 0, server_mac.Length);
            Array.Clear(client_key, 0, client_key.Length);
            Array.Clear(server_key, 0, server_key.Length);
            Array.Clear(client_iv, 0, client_iv.Length);
            Array.Clear(server_iv, 0, server_iv.Length);
            return(ret);
        }
コード例 #43
0
ファイル: HandshakeLayer.cs プロジェクト: jasenkin/netmq
        private void SetCipherSuite(CipherSuite cipher)
        {
            switch (cipher)
              {
            case CipherSuite.TLS_NULL_WITH_NULL_NULL:
            case CipherSuite.TLS_RSA_WITH_NULL_SHA:
              case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
              SecurityParameters.BulkCipherAlgorithm = BulkCipherAlgorithm.Null;
              SecurityParameters.FixedIVLength = 0;
              SecurityParameters.EncKeyLength = 0;
              SecurityParameters.BlockLength = 0;
              SecurityParameters.RecordIVLength = 0;
              break;
            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
              SecurityParameters.BulkCipherAlgorithm = BulkCipherAlgorithm.AES;
              SecurityParameters.FixedIVLength = 0;
              SecurityParameters.EncKeyLength = 16;
              SecurityParameters.BlockLength = 16;
              SecurityParameters.RecordIVLength = 16;
              break;
            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
              SecurityParameters.BulkCipherAlgorithm = BulkCipherAlgorithm.AES;
              SecurityParameters.FixedIVLength = 0;
              SecurityParameters.EncKeyLength = 32;
              SecurityParameters.BlockLength = 16;
              SecurityParameters.RecordIVLength = 16;
              break;
            default:
              throw new ArgumentOutOfRangeException("cipher");
              }

              switch (cipher)
              {
            case CipherSuite.TLS_NULL_WITH_NULL_NULL:
              SecurityParameters.MACAlgorithm = MACAlgorithm.Null;
              SecurityParameters.MACKeyLength = 0;
              SecurityParameters.MACLength = 0;
              break;
            case CipherSuite.TLS_RSA_WITH_NULL_SHA:
            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA:
            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA:
              SecurityParameters.MACAlgorithm = MACAlgorithm.HMACSha1;
              SecurityParameters.MACKeyLength = 20;
              SecurityParameters.MACLength = 20;
              break;
            case CipherSuite.TLS_RSA_WITH_NULL_SHA256:
            case CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256:
            case CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256:
              SecurityParameters.MACAlgorithm = MACAlgorithm.HMACSha256;
              SecurityParameters.MACKeyLength = 32;
              SecurityParameters.MACLength = 32;
              break;
            default:
              throw new ArgumentOutOfRangeException("cipher");
              }
        }
コード例 #44
0
 public MyGaloisCounterCipher(bool isServer, TlsProtocolCode protocol, CipherSuite cipher, byte[] iv)
     : base(isServer, protocol, cipher)
 {
     this.iv = iv;
 }
コード例 #45
0
		private static bool ArrayContains(CipherSuite[] a, CipherSuite n)
		{
			for (int i = 0; i < a.Length; ++i)
			{
				if (a[i] == n)
					return true;
			}
			return false;
		}
コード例 #46
0
    public static void UpdateReportAggregator(ReportAggregator aggregator, Report report)
    {
        String serverUnderTest = $"{report.ConnName}:{report.ConnPort}";

        if (report.SSLv2Chain != null)
        {
            aggregator.AddSsl2Cert(serverUnderTest, report.SSLv2Chain);
            X509Cert xc = report.SSLv2Chain.ElementsRev[0];
            if (xc != null && xc.ValidTo.CompareTo(DateTime.Now) < 0)
            {
                aggregator.AddOverduedCertificate(serverUnderTest, xc.ValidTo);
            }
        }

        if (report.ssl2Suites != null && report.ssl2Suites.Length > 0)
        {
            aggregator.AddSuportedSslVersion(M.VersionString(M.SSLv20));
            foreach (int s in report.ssl2Suites)
            {
                aggregator.AddSupportedCipherSuite(CipherSuite.ToNameV2(s));
            }
        }

        aggregator.AddSsl3Certs(serverUnderTest, report.chains.Values);
        InspectCerts(aggregator, report, serverUnderTest);

        foreach (int v in report.suites.Keys)
        {
            aggregator.AddSuportedSslVersion(M.VersionString(v));
            SupportedCipherSuites scs = report.suites[v];
            if (scs.PrefClient)
            {
                aggregator.AddCipherSuiteSelectionMode("uses client preferences");
            }
            else if (scs.PrefServer)
            {
                aggregator.AddCipherSuiteSelectionMode("enforce server preferences");
            }
            else
            {
                aggregator.AddCipherSuiteSelectionMode("complex");
            }
            foreach (int s in scs.Suites)
            {
                CipherSuite cs;
                string      strength;
                string      fsf;
                string      anon;
                string      kt;
                if (CipherSuite.ALL.TryGetValue(s, out cs))
                {
                    strength = cs.Strength.ToString();
                    fsf      = cs.HasForwardSecrecy ? "f" : "-";
                    anon     = cs.IsAnonymous ? "A" : "-";
                    kt       = cs.ServerKeyType;
                }
                else
                {
                    strength = "?";
                    fsf      = "?";
                    anon     = "?";
                    kt       = "?";
                }
                aggregator.AddSupportedCipherSuite($"{strength}{fsf}{anon} (key: {kt,4})  {CipherSuite.ToName(s)}");
            }
        }

        foreach (var warning in report.Warnings)
        {
            aggregator.AddWarning(warning.Value);
        }
    }