Exemplo n.º 1
0
        public static string GenEncrypedPin(string pin, string pinToken, string sessionId, RsaPrivateCrtKeyParameters rsa, ulong it)
        {
            ulong time = (ulong)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

            var bPinToken = Convert.FromBase64String(pinToken);


            IAsymmetricBlockCipher cipherRsa = new RsaBlindedEngine();

            cipherRsa = new OaepEncoding(cipherRsa, new Sha256Digest(), new Sha256Digest(), Encoding.ASCII.GetBytes(sessionId));
            BufferedAsymmetricBlockCipher cipher = new BufferedAsymmetricBlockCipher(cipherRsa);

            cipher.Init(false, rsa);
            cipher.ProcessBytes(bPinToken, 0, bPinToken.Length);
            var key = cipher.DoFinal();


            var bPin      = Encoding.ASCII.GetBytes(pin);
            var btime     = BitConverter.GetBytes(time);
            var biterator = BitConverter.GetBytes(it);


            int len = bPin.Length + btime.Length + biterator.Length;

            IBlockCipher cipherAes    = new AesEngine();
            int          bsize        = cipherAes.GetBlockSize();
            KeyParameter keyParameter = new KeyParameter(key);


            int nPadding = bsize - len % bsize;
            var bPadding = new byte[nPadding];

            len += (len % bsize == 0 ? 0 : nPadding);


            var blocks = new byte[len];

            Array.Copy(bPin, blocks, bPin.Length);
            Array.Copy(btime, 0, blocks, bPin.Length, btime.Length);
            Array.Copy(biterator, 0, blocks, bPin.Length + btime.Length, biterator.Length);
            Array.Copy(bPadding, 0, blocks, bPin.Length + btime.Length + biterator.Length, nPadding);

            var iv = new byte[bsize];

            random.NextBytes(iv);

            CbcBlockCipher   cbcBc            = new CbcBlockCipher(cipherAes);
            ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, iv);

            BufferedBlockCipher bc = new BufferedBlockCipher(cbcBc);

            bc.Init(true, parametersWithIV);
            var bOut = bc.ProcessBytes(blocks);
            var rz   = new byte[bOut.Length + bsize];

            Array.Copy(iv, rz, iv.Length);
            Array.Copy(bOut, 0, rz, iv.Length, bOut.Length);

            return(Convert.ToBase64String(rz));
        }
Exemplo n.º 2
0
        private void checkForPkcs1Exception(RsaKeyParameters pubParameters, RsaKeyParameters privParameters, byte[] inputData, string expectedMessage)
        {
            IAsymmetricBlockCipher eng = new RsaBlindedEngine();

            eng.Init(true, privParameters);

            byte[] data = null;

            try
            {
                data = eng.ProcessBlock(inputData, 0, inputData.Length);
            }
            catch (Exception e)
            {
                Fail("RSA: failed - exception " + e.ToString(), e);
            }

            eng = new Pkcs1Encoding(eng);

            eng.Init(false, pubParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);

                Fail("missing data block not recognised");
            }
            catch (InvalidCipherTextException e)
            {
                if (!e.Message.Equals(expectedMessage))
                {
                    Fail("RSA: failed - exception " + e.ToString(), e);
                }
            }
        }
Exemplo n.º 3
0
        public bool Verify(byte[] signature, byte[] data, uint160 nonce)
        {
            byte[]       output    = new byte[256];
            var          msg       = Utils.Combine(nonce.ToBytes(), data);
            Sha512Digest sha512    = new Sha512Digest();
            var          generator = new Mgf1BytesGenerator(sha512);

            generator.Init(new MgfParameters(msg));
            generator.GenerateBytes(output, 0, output.Length);
            var input = new BigInteger(1, output);

            if (input.CompareTo(_Key.Modulus) >= 0)
            {
                return(false);
            }
            if (signature.Length > 256)
            {
                return(false);
            }
            var signatureInt = new BigInteger(1, signature);

            if (signatureInt.CompareTo(_Key.Modulus) >= 0)
            {
                return(false);
            }
            var engine = new RsaBlindedEngine();

            engine.Init(false, _Key);
            return(input.Equals(engine.ProcessBlock(signatureInt)));
        }
Exemplo n.º 4
0
        private void doTestStrictPkcs1Length(RsaKeyParameters pubParameters, RsaKeyParameters privParameters)
        {
            IAsymmetricBlockCipher eng = new RsaBlindedEngine();

            eng.Init(true, privParameters);

            byte[] data = null;

            try
            {
                data = eng.ProcessBlock(oversizedSig, 0, oversizedSig.Length);
            }
            catch (Exception e)
            {
                Fail("RSA: failed - exception " + e.ToString(), e);
            }

            eng = new Pkcs1Encoding(eng);

            eng.Init(false, pubParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);

                Fail("oversized signature block not recognised");
            }
            catch (InvalidCipherTextException e)
            {
                if (!e.Message.Equals("block incorrect size"))
                {
                    Fail("RSA: failed - exception " + e.ToString(), e);
                }
            }


            // Create the encoding with StrictLengthEnabled=false (done thru environment in Java version)
            Pkcs1Encoding.StrictLengthEnabled = false;

            eng = new Pkcs1Encoding(new RsaBlindedEngine());

            eng.Init(false, pubParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (InvalidCipherTextException e)
            {
                Fail("RSA: failed - exception " + e.ToString(), e);
            }

            Pkcs1Encoding.StrictLengthEnabled = true;
        }
Exemplo n.º 5
0
        public static byte[] RsaProcessMessage(
            bool forEncryption,
            byte[] message,
            AsymmetricKeyParameter key)
        {
            IAsymmetricBlockCipher cipher = new RsaBlindedEngine();

            cipher.Init(forEncryption, key);

            return(cipher.ProcessBlock(message, 0, message.Length));
        }
Exemplo n.º 6
0
        internal BigInteger Decrypt(BigInteger encrypted)
        {
            if (encrypted == null)
            {
                throw new ArgumentNullException(nameof(encrypted));
            }
            if (encrypted.CompareTo(_Key.Modulus) >= 0)
            {
                throw new DataLengthException("input too large for RSA cipher.");
            }

            RsaBlindedEngine engine = new RsaBlindedEngine();

            engine.Init(false, _Key);
            return(engine.ProcessBlock(encrypted));
        }
Exemplo n.º 7
0
        internal BigInteger Encrypt(BigInteger data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (data.CompareTo(_Key.Modulus) >= 0)
            {
                throw new ArgumentException("input too large for RSA cipher.");
            }

            RsaBlindedEngine engine = new RsaBlindedEngine();

            engine.Init(true, _Key);
            return(engine.ProcessBlock(data));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Generate cipher. The cipher can be reused.
        /// </summary>
        /// <param name="padding">Asymmetric algorithm padding mode.</param>
        /// <param name="asymmetricKey">Asymmetric public key or private key.</param>
        /// <returns></returns>
        /// <exception cref="Exception"/>
        public IAsymmetricBlockCipher GenerateCipher(AsymmetricPaddingMode padding, AsymmetricKeyParameter asymmetricKey)
        {
            IAsymmetricBlockCipher cipher = new RsaBlindedEngine();

            switch (padding)
            {
            case AsymmetricPaddingMode.NoPadding: break;

            case AsymmetricPaddingMode.PKCS1: cipher = new Pkcs1Encoding(cipher); break;

            case AsymmetricPaddingMode.OAEP: cipher = new OaepEncoding(cipher); break;

            case AsymmetricPaddingMode.ISO9796_1: cipher = new ISO9796d1Encoding(cipher); break;

            default: throw new System.Security.Cryptography.CryptographicException("Unsupported padding mode.");
            }
            cipher.Init(!asymmetricKey.IsPrivate, asymmetricKey);
            return(cipher);
        }
Exemplo n.º 9
0
            public bool HasTestPassed(AsymmetricCipherKeyPair kp)
            {
                byte[] data = Hex.Decode("576a1f885e3420128c8a656097ba7d8bb4c6f1b1853348cf2ba976971dbdbefc");

                RsaBlindedEngine rsaEngine = new RsaBlindedEngine();

                rsaEngine.Init(true, kp.Public);

                byte[] encrypted = rsaEngine.ProcessBlock(data, 0, data.Length);

                if (Arrays.AreEqual(data, encrypted))
                {
                    return(false);
                }

                rsaEngine.Init(false, new ParametersWithRandom(kp.Private, Utils.testRandom));

                byte[] decrypted = rsaEngine.ProcessBlock(encrypted, 0, encrypted.Length);

                return(Arrays.AreEqual(FipsKats.Values[FipsKats.Vec.RsaKeyPairConsistencyCheck], data));
            }
Exemplo n.º 10
0
        public byte[] Sign(byte[] data, out uint160 nonce)
        {
            while (true)
            {
                byte[] output = new byte[256];
                nonce = new uint160(RandomUtils.GetBytes(20));
                Sha512Digest sha512    = new Sha512Digest();
                var          msg       = Utils.Combine(nonce.ToBytes(), data);
                var          generator = new Mgf1BytesGenerator(sha512);
                generator.Init(new MgfParameters(msg));
                generator.GenerateBytes(output, 0, output.Length);
                var input = new BigInteger(1, output);
                if (input.CompareTo(_Key.Modulus) >= 0)
                {
                    continue;
                }
                var engine = new RsaBlindedEngine();
                engine.Init(true, _Key);

                return(engine.ConvertOutput(engine.ProcessBlock(input)));
            }
        }
Exemplo n.º 11
0
        public void DoFullMessageTest()
        {
            BigInteger       modulus    = new BigInteger(1, Hex.Decode("CDCBDABBF93BE8E8294E32B055256BBD0397735189BF75816341BB0D488D05D627991221DF7D59835C76A4BB4808ADEEB779E7794504E956ADC2A661B46904CDC71337DD29DDDD454124EF79CFDD7BC2C21952573CEFBA485CC38C6BD2428809B5A31A898A6B5648CAA4ED678D9743B589134B7187478996300EDBA16271A861"));
            BigInteger       pubExp     = new BigInteger(1, Hex.Decode("010001"));
            BigInteger       privExp    = new BigInteger(1, Hex.Decode("4BA6432AD42C74AA5AFCB6DF60FD57846CBC909489994ABD9C59FE439CC6D23D6DE2F3EA65B8335E796FD7904CA37C248367997257AFBD82B26F1A30525C447A236C65E6ADE43ECAAF7283584B2570FA07B340D9C9380D88EAACFFAEEFE7F472DBC9735C3FF3A3211E8A6BBFD94456B6A33C17A2C4EC18CE6335150548ED126D"));
            RsaKeyParameters pubParams  = new RsaKeyParameters(false, modulus, pubExp);
            RsaKeyParameters privParams = new RsaKeyParameters(true, modulus, privExp);

            IAsymmetricBlockCipher rsaEngine = new RsaBlindedEngine();

            // set challenge to all zero's for verification
            byte[] challenge = new byte[8];

            Iso9796d2PssSigner pssSign = new Iso9796d2PssSigner(new RsaEngine(), new Sha256Digest(), 20, true);

            pssSign.Init(true, privParams);

            pssSign.BlockUpdate(challenge, 0, challenge.Length);

            byte[] sig = pssSign.GenerateSignature();

            pssSign.Init(false, pubParams);

            pssSign.UpdateWithRecoveredMessage(sig);

            if (!pssSign.VerifySignature(sig))
            {
                Fail("challenge PSS sig verification failed.");
            }

            byte[] mm = pssSign.GetRecoveredMessage();

            if (!Arrays.AreEqual(challenge, mm))
            {
                Fail("challenge partial PSS recovery failed");
            }
        }
Exemplo n.º 12
0
        public override void PerformTest()
        {
            RsaKeyParameters pubParameters  = new RsaKeyParameters(false, mod, pubExp);
            RsaKeyParameters privParameters = new RsaPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef);

            byte[] data = Hex.Decode(edgeInput);

            //
            // RAW
            //
            IAsymmetricBlockCipher eng = new RsaBlindedEngine();

            eng.Init(true, pubParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("RSA: failed - exception " + e.ToString(), e);
            }

            eng.Init(false, privParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            if (!edgeInput.Equals(Hex.ToHexString(data)))
            {
                Fail("failed RAW edge Test");
            }

            data = Hex.Decode(input);

            eng.Init(true, pubParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            eng.Init(false, privParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            if (!input.Equals(Hex.ToHexString(data)))
            {
                Fail("failed RAW Test");
            }

            //
            // PKCS1 - public encrypt, private decrypt
            //
            eng = new Pkcs1Encoding(eng);

            eng.Init(true, pubParameters);

            if (eng.GetOutputBlockSize() != ((Pkcs1Encoding)eng).GetUnderlyingCipher().GetOutputBlockSize())
            {
                Fail("PKCS1 output block size incorrect");
            }

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            eng.Init(false, privParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            if (!input.Equals(Hex.ToHexString(data)))
            {
                Fail("failed PKCS1 public/private Test");
            }

            //
            // PKCS1 - private encrypt, public decrypt
            //
            eng = new Pkcs1Encoding(((Pkcs1Encoding)eng).GetUnderlyingCipher());

            eng.Init(true, privParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            eng.Init(false, pubParameters);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            if (!input.Equals(Hex.ToHexString(data)))
            {
                Fail("failed PKCS1 private/public Test");
            }

            //
            // key generation test
            //
            RsaKeyPairGenerator        pGen     = new RsaKeyPairGenerator();
            RsaKeyGenerationParameters genParam = new RsaKeyGenerationParameters(
                BigInteger.ValueOf(0x11), new SecureRandom(), 768, 25);

            pGen.Init(genParam);

            AsymmetricCipherKeyPair pair = pGen.GenerateKeyPair();

            eng = new RsaBlindedEngine();

            if (((RsaKeyParameters)pair.Public).Modulus.BitLength < 768)
            {
                Fail("failed key generation (768) length test");
            }

            eng.Init(true, pair.Public);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            eng.Init(false, pair.Private);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            if (!input.Equals(Hex.ToHexString(data)))
            {
                Fail("failed key generation (768) Test");
            }

            genParam = new RsaKeyGenerationParameters(BigInteger.ValueOf(0x11), new SecureRandom(), 1024, 25);

            pGen.Init(genParam);
            pair = pGen.GenerateKeyPair();

            eng.Init(true, pair.Public);

            if (((RsaKeyParameters)pair.Public).Modulus.BitLength < 1024)
            {
                Fail("failed key generation (1024) length test");
            }

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            eng.Init(false, pair.Private);

            try
            {
                data = eng.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            if (!input.Equals(Hex.ToHexString(data)))
            {
                Fail("failed key generation (1024) test");
            }

            doTestOaep(pubParameters, privParameters);
            doTestStrictPkcs1Length(pubParameters, privParameters);
            doTestDudPkcs1Block(pubParameters, privParameters);
            doTestMissingDataPkcs1Block(pubParameters, privParameters);
            doTestTruncatedPkcs1Block(pubParameters, privParameters);
            doTestWrongPaddingPkcs1Block(pubParameters, privParameters);

            try
            {
                new RsaBlindedEngine().ProcessBlock(new byte[] { 1 }, 0, 1);
                Fail("failed initialisation check");
            }
            catch (InvalidOperationException)
            {
                // expected
            }
        }
Exemplo n.º 13
0
        private bool DoVerify(
            AsymmetricKeyParameter key)
        {
            string  digestName = Helper.GetDigestAlgName(this.DigestAlgOid);
            IDigest digest     = Helper.GetDigestInstance(digestName);

            DerObjectIdentifier sigAlgOid = this.encryptionAlgorithm.Algorithm;
            Asn1Encodable       sigParams = this.encryptionAlgorithm.Parameters;
            ISigner             sig;

            if (sigAlgOid.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdRsassaPss))
            {
                // RFC 4056 2.2
                // When the id-RSASSA-PSS algorithm identifier is used for a signature,
                // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params.
                if (sigParams == null)
                {
                    throw new CmsException("RSASSA-PSS signature must specify algorithm parameters");
                }

                try
                {
                    // TODO Provide abstract configuration mechanism
                    // (via alternate SignerUtilities.GetSigner method taking ASN.1 params)

                    Asn1.Pkcs.RsassaPssParameters pss = Asn1.Pkcs.RsassaPssParameters.GetInstance(
                        sigParams.ToAsn1Object());

                    if (!pss.HashAlgorithm.Algorithm.Equals(this.digestAlgorithm.Algorithm))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified incorrect hash algorithm");
                    }
                    if (!pss.MaskGenAlgorithm.Algorithm.Equals(Asn1.Pkcs.PkcsObjectIdentifiers.IdMgf1))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters specified unknown MGF");
                    }

                    IDigest pssDigest  = DigestUtilities.GetDigest(pss.HashAlgorithm.Algorithm);
                    int     saltLength = pss.SaltLength.IntValueExact;

                    // RFC 4055 3.1
                    // The value MUST be 1, which represents the trailer field with hexadecimal value 0xBC
                    if (!Asn1.Pkcs.RsassaPssParameters.DefaultTrailerField.Equals(pss.TrailerField))
                    {
                        throw new CmsException("RSASSA-PSS signature parameters must have trailerField of 1");
                    }

                    IAsymmetricBlockCipher rsa = new RsaBlindedEngine();

                    if (signedAttributeSet == null && digestCalculator != null)
                    {
                        sig = PssSigner.CreateRawSigner(rsa, pssDigest, pssDigest, saltLength, PssSigner.TrailerImplicit);
                    }
                    else
                    {
                        sig = new PssSigner(rsa, pssDigest, saltLength);
                    }
                }
                catch (Exception e)
                {
                    throw new CmsException("failed to set RSASSA-PSS signature parameters", e);
                }
            }
            else
            {
                // TODO Probably too strong a check at the moment
//				if (sigParams != null)
//					throw new CmsException("unrecognised signature parameters provided");

                string signatureName = digestName + "with" + Helper.GetEncryptionAlgName(this.EncryptionAlgOid);

                sig = Helper.GetSignatureInstance(signatureName);

                //sig = Helper.GetSignatureInstance(this.EncryptionAlgOid);
                //sig = SignerUtilities.GetSigner(sigAlgOid);
            }

            try
            {
                if (digestCalculator != null)
                {
                    resultDigest = digestCalculator.GetDigest();
                }
                else
                {
                    if (content != null)
                    {
                        content.Write(new DigestSink(digest));
                    }
                    else if (signedAttributeSet == null)
                    {
                        // TODO Get rid of this exception and just treat content==null as empty not missing?
                        throw new CmsException("data not encapsulated in signature - use detached constructor.");
                    }

                    resultDigest = DigestUtilities.DoFinal(digest);
                }
            }
            catch (IOException e)
            {
                throw new CmsException("can't process mime object to create signature.", e);
            }

            // RFC 3852 11.1 Check the content-type attribute is correct
            {
                Asn1Object validContentType = GetSingleValuedSignedAttribute(
                    CmsAttributes.ContentType, "content-type");
                if (validContentType == null)
                {
                    if (!isCounterSignature && signedAttributeSet != null)
                    {
                        throw new CmsException("The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
                    }
                }
                else
                {
                    if (isCounterSignature)
                    {
                        throw new CmsException("[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
                    }

                    if (!(validContentType is DerObjectIdentifier))
                    {
                        throw new CmsException("content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
                    }

                    DerObjectIdentifier signedContentType = (DerObjectIdentifier)validContentType;

                    if (!signedContentType.Equals(contentType))
                    {
                        throw new CmsException("content-type attribute value does not match eContentType");
                    }
                }
            }

            // RFC 3852 11.2 Check the message-digest attribute is correct
            {
                Asn1Object validMessageDigest = GetSingleValuedSignedAttribute(
                    CmsAttributes.MessageDigest, "message-digest");
                if (validMessageDigest == null)
                {
                    if (signedAttributeSet != null)
                    {
                        throw new CmsException("the message-digest signed attribute type MUST be present when there are any signed attributes present");
                    }
                }
                else
                {
                    if (!(validMessageDigest is Asn1OctetString))
                    {
                        throw new CmsException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
                    }

                    Asn1OctetString signedMessageDigest = (Asn1OctetString)validMessageDigest;

                    if (!Arrays.AreEqual(resultDigest, signedMessageDigest.GetOctets()))
                    {
                        throw new CmsException("message-digest attribute value does not match calculated value");
                    }
                }
            }

            // RFC 3852 11.4 Validate countersignature attribute(s)
            {
                Asn1.Cms.AttributeTable signedAttrTable = this.SignedAttributes;
                if (signedAttrTable != null &&
                    signedAttrTable.GetAll(CmsAttributes.CounterSignature).Count > 0)
                {
                    throw new CmsException("A countersignature attribute MUST NOT be a signed attribute");
                }

                Asn1.Cms.AttributeTable unsignedAttrTable = this.UnsignedAttributes;
                if (unsignedAttrTable != null)
                {
                    foreach (Asn1.Cms.Attribute csAttr in unsignedAttrTable.GetAll(CmsAttributes.CounterSignature))
                    {
                        if (csAttr.AttrValues.Count < 1)
                        {
                            throw new CmsException("A countersignature attribute MUST contain at least one AttributeValue");
                        }

                        // Note: We don't recursively validate the countersignature value
                    }
                }
            }

            try
            {
                sig.Init(false, key);

                if (signedAttributeSet == null)
                {
                    if (digestCalculator != null)
                    {
                        if (sig is PssSigner)
                        {
                            sig.BlockUpdate(resultDigest, 0, resultDigest.Length);
                        }
                        else
                        {
                            // need to decrypt signature and check message bytes
                            return(VerifyDigest(resultDigest, key, this.GetSignature()));
                        }
                    }
                    else if (content != null)
                    {
                        try
                        {
                            // TODO Use raw signature of the hash value instead
                            content.Write(new SignerSink(sig));
                        }
                        catch (SignatureException e)
                        {
                            throw new CmsStreamException("signature problem: " + e);
                        }
                    }
                }
                else
                {
                    byte[] tmp = this.GetEncodedSignedAttributes();
                    sig.BlockUpdate(tmp, 0, tmp.Length);
                }

                return(sig.VerifySignature(this.GetSignature()));
            }
            catch (InvalidKeyException e)
            {
                throw new CmsException("key not appropriate to signature in message.", e);
            }
            catch (IOException e)
            {
                throw new CmsException("can't process mime object to create signature.", e);
            }
            catch (SignatureException e)
            {
                throw new CmsException("invalid signature format in message: " + e.Message, e);
            }
        }
Exemplo n.º 14
0
        public static IBufferedCipher GetCipher(
            string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            algorithm = Platform.ToUpperInvariant(algorithm);

            {
                string aliased = (string)algorithms[algorithm];

                if (aliased != null)
                {
                    algorithm = aliased;
                }
            }

            IBasicAgreement iesAgreement = null;

            if (algorithm == "IES")
            {
                iesAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                iesAgreement = new ECDHBasicAgreement();
            }

            if (iesAgreement != null)
            {
                return(new BufferedIesCipher(
                           new IesEngine(
                               iesAgreement,
                               new Kdf2BytesGenerator(
                                   new Sha1Digest()),
                               new HMac(
                                   new Sha1Digest()))));
            }



            if (Platform.StartsWith(algorithm, "PBE"))
            {
                if (Platform.EndsWith(algorithm, "-CBC"))
                {
                    if (algorithm == "PBEWITHSHA1ANDDES-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new DesEngine())));
                    }
                    else if (algorithm == "PBEWITHSHA1ANDRC2-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new RC2Engine())));
                    }
                    else if (Strings.IsOneOf(algorithm,
                                             "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new DesEdeEngine())));
                    }
                    else if (Strings.IsOneOf(algorithm,
                                             "PBEWITHSHAAND128BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new RC2Engine())));
                    }
                }
                else if (Platform.EndsWith(algorithm, "-BC") || Platform.EndsWith(algorithm, "-OPENSSL"))
                {
                    if (Strings.IsOneOf(algorithm,
                                        "PBEWITHSHAAND128BITAES-CBC-BC",
                                        "PBEWITHSHAAND192BITAES-CBC-BC",
                                        "PBEWITHSHAAND256BITAES-CBC-BC",
                                        "PBEWITHSHA256AND128BITAES-CBC-BC",
                                        "PBEWITHSHA256AND192BITAES-CBC-BC",
                                        "PBEWITHSHA256AND256BITAES-CBC-BC",
                                        "PBEWITHMD5AND128BITAES-CBC-OPENSSL",
                                        "PBEWITHMD5AND192BITAES-CBC-OPENSSL",
                                        "PBEWITHMD5AND256BITAES-CBC-OPENSSL"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new AesFastEngine())));
                    }
                }
            }



            string[] parts = algorithm.Split('/');

            IBlockCipher           blockCipher     = null;
            IAsymmetricBlockCipher asymBlockCipher = null;
            IStreamCipher          streamCipher    = null;

            string algorithmName = parts[0];

            {
                string aliased = (string)algorithms[algorithmName];

                if (aliased != null)
                {
                    algorithmName = aliased;
                }
            }

            CipherAlgorithm cipherAlgorithm;

            try
            {
                cipherAlgorithm = (CipherAlgorithm)Enums.GetEnumValue(typeof(CipherAlgorithm), algorithmName);
            }
            catch (ArgumentException)
            {
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            switch (cipherAlgorithm)
            {
            case CipherAlgorithm.AES:
                blockCipher = new AesFastEngine();
                break;

            case CipherAlgorithm.ARC4:
                streamCipher = new RC4Engine();
                break;

            case CipherAlgorithm.BLOWFISH:
                blockCipher = new BlowfishEngine();
                break;

            case CipherAlgorithm.CAMELLIA:
                blockCipher = new CamelliaEngine();
                break;

            case CipherAlgorithm.CAST5:
                blockCipher = new Cast5Engine();
                break;

            case CipherAlgorithm.CAST6:
                blockCipher = new Cast6Engine();
                break;

            case CipherAlgorithm.DES:
                blockCipher = new DesEngine();
                break;

            case CipherAlgorithm.DESEDE:
                blockCipher = new DesEdeEngine();
                break;

            case CipherAlgorithm.ELGAMAL:
                asymBlockCipher = new ElGamalEngine();
                break;

            case CipherAlgorithm.GOST28147:
                blockCipher = new Gost28147Engine();
                break;

            case CipherAlgorithm.HC128:
                streamCipher = new HC128Engine();
                break;

            case CipherAlgorithm.HC256:
                streamCipher = new HC256Engine();
                break;

            case CipherAlgorithm.IDEA:
                blockCipher = new IdeaEngine();
                break;

            case CipherAlgorithm.NOEKEON:
                blockCipher = new NoekeonEngine();
                break;

            case CipherAlgorithm.PBEWITHSHAAND128BITRC4:
            case CipherAlgorithm.PBEWITHSHAAND40BITRC4:
                streamCipher = new RC4Engine();
                break;

            case CipherAlgorithm.RC2:
                blockCipher = new RC2Engine();
                break;

            case CipherAlgorithm.RC5:
                blockCipher = new RC532Engine();
                break;

            case CipherAlgorithm.RC5_64:
                blockCipher = new RC564Engine();
                break;

            case CipherAlgorithm.RC6:
                blockCipher = new RC6Engine();
                break;

            case CipherAlgorithm.RIJNDAEL:
                blockCipher = new RijndaelEngine();
                break;

            case CipherAlgorithm.RSA:
                asymBlockCipher = new RsaBlindedEngine();
                break;

            case CipherAlgorithm.SALSA20:
                streamCipher = new Salsa20Engine();
                break;

            case CipherAlgorithm.SEED:
                blockCipher = new SeedEngine();
                break;

            case CipherAlgorithm.SERPENT:
                blockCipher = new SerpentEngine();
                break;

            case CipherAlgorithm.SKIPJACK:
                blockCipher = new SkipjackEngine();
                break;

            case CipherAlgorithm.TEA:
                blockCipher = new TeaEngine();
                break;

            case CipherAlgorithm.THREEFISH_256:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
                break;

            case CipherAlgorithm.THREEFISH_512:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
                break;

            case CipherAlgorithm.THREEFISH_1024:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
                break;

            case CipherAlgorithm.TNEPRES:
                blockCipher = new TnepresEngine();
                break;

            case CipherAlgorithm.TWOFISH:
                blockCipher = new TwofishEngine();
                break;

            case CipherAlgorithm.VMPC:
                streamCipher = new VmpcEngine();
                break;

            case CipherAlgorithm.VMPC_KSA3:
                streamCipher = new VmpcKsa3Engine();
                break;

            case CipherAlgorithm.XTEA:
                blockCipher = new XteaEngine();
                break;

            default:
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            if (streamCipher != null)
            {
                if (parts.Length > 1)
                {
                    throw new ArgumentException("Modes and paddings not used for stream ciphers");
                }

                return(new BufferedStreamCipher(streamCipher));
            }


            bool cts    = false;
            bool padded = true;
            IBlockCipherPadding padding         = null;
            IAeadBlockCipher    aeadBlockCipher = null;

            if (parts.Length > 2)
            {
                if (streamCipher != null)
                {
                    throw new ArgumentException("Paddings not used for stream ciphers");
                }

                string paddingName = parts[2];

                CipherPadding cipherPadding;
                if (paddingName == "")
                {
                    cipherPadding = CipherPadding.RAW;
                }
                else if (paddingName == "X9.23PADDING")
                {
                    cipherPadding = CipherPadding.X923PADDING;
                }
                else
                {
                    try
                    {
                        cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), paddingName);
                    }
                    catch (ArgumentException)
                    {
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }

                switch (cipherPadding)
                {
                case CipherPadding.NOPADDING:
                    padded = false;
                    break;

                case CipherPadding.RAW:
                    break;

                case CipherPadding.ISO10126PADDING:
                case CipherPadding.ISO10126D2PADDING:
                case CipherPadding.ISO10126_2PADDING:
                    padding = new ISO10126d2Padding();
                    break;

                case CipherPadding.ISO7816_4PADDING:
                case CipherPadding.ISO9797_1PADDING:
                    padding = new ISO7816d4Padding();
                    break;

                case CipherPadding.ISO9796_1:
                case CipherPadding.ISO9796_1PADDING:
                    asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
                    break;

                case CipherPadding.OAEP:
                case CipherPadding.OAEPPADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher);
                    break;

                case CipherPadding.OAEPWITHMD5ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
                    break;

                case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
                    break;

                case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
                    break;

                case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
                    break;

                case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
                    break;

                case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
                    break;

                case CipherPadding.PKCS1:
                case CipherPadding.PKCS1PADDING:
                    asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
                    break;

                case CipherPadding.PKCS5:
                case CipherPadding.PKCS5PADDING:
                case CipherPadding.PKCS7:
                case CipherPadding.PKCS7PADDING:
                    padding = new Pkcs7Padding();
                    break;

                case CipherPadding.TBCPADDING:
                    padding = new TbcPadding();
                    break;

                case CipherPadding.WITHCTS:
                    cts = true;
                    break;

                case CipherPadding.X923PADDING:
                    padding = new X923Padding();
                    break;

                case CipherPadding.ZEROBYTEPADDING:
                    padding = new ZeroBytePadding();
                    break;

                default:
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            string mode = "";

            if (parts.Length > 1)
            {
                mode = parts[1];

                int    di       = GetDigitIndex(mode);
                string modeName = di >= 0 ? mode.Substring(0, di) : mode;

                try
                {
                    CipherMode cipherMode = modeName == ""
                        ? CipherMode.NONE
                        : (CipherMode)Enums.GetEnumValue(typeof(CipherMode), modeName);

                    switch (cipherMode)
                    {
                    case CipherMode.ECB:
                    case CipherMode.NONE:
                        break;

                    case CipherMode.CBC:
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

                    case CipherMode.CCM:
                        aeadBlockCipher = new CcmBlockCipher(blockCipher);
                        break;

                    case CipherMode.CFB:
                    {
                        int bits = (di < 0)
                                ?       8 * blockCipher.GetBlockSize()
                                :       int.Parse(mode.Substring(di));

                        blockCipher = new CfbBlockCipher(blockCipher, bits);
                        break;
                    }

                    case CipherMode.CTR:
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;

                    case CipherMode.CTS:
                        cts         = true;
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

                    case CipherMode.EAX:
                        aeadBlockCipher = new EaxBlockCipher(blockCipher);
                        break;

                    case CipherMode.GCM:
                        aeadBlockCipher = new GcmBlockCipher(blockCipher);
                        break;

                    case CipherMode.GOFB:
                        blockCipher = new GOfbBlockCipher(blockCipher);
                        break;

                    case CipherMode.OCB:
                        aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
                        break;

                    case CipherMode.OFB:
                    {
                        int bits = (di < 0)
                                ?       8 * blockCipher.GetBlockSize()
                                :       int.Parse(mode.Substring(di));

                        blockCipher = new OfbBlockCipher(blockCipher, bits);
                        break;
                    }

                    case CipherMode.OPENPGPCFB:
                        blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
                        break;

                    case CipherMode.SIC:
                        if (blockCipher.GetBlockSize() < 16)
                        {
                            throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
                        }
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;

                    default:
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }
                catch (ArgumentException)
                {
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            if (aeadBlockCipher != null)
            {
                if (cts)
                {
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                }
                if (padded && parts.Length > 2 && parts[2] != "")
                {
                    throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");
                }

                return(new BufferedAeadBlockCipher(aeadBlockCipher));
            }

            if (blockCipher != null)
            {
                if (cts)
                {
                    return(new CtsBlockCipher(blockCipher));
                }

                if (padding != null)
                {
                    return(new PaddedBufferedBlockCipher(blockCipher, padding));
                }

                if (!padded || blockCipher.IsPartialBlockOkay)
                {
                    return(new BufferedBlockCipher(blockCipher));
                }

                return(new PaddedBufferedBlockCipher(blockCipher));
            }

            if (asymBlockCipher != null)
            {
                return(new BufferedAsymmetricBlockCipher(asymBlockCipher));
            }

            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }
Exemplo n.º 15
0
        public static ISigner GetSigner(
            string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            algorithm = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm);

            string mechanism = (string)algorithms[algorithm];

            if (mechanism == null)
            {
                mechanism = algorithm;
            }

            if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "Ed"))
            {
                if (mechanism.Equals("Ed25519"))
                {
                    return(new Ed25519Signer());
                }
                if (mechanism.Equals("Ed25519ctx"))
                {
                    return(new Ed25519ctxSigner(Arrays.EmptyBytes));
                }
                if (mechanism.Equals("Ed25519ph"))
                {
                    return(new Ed25519phSigner(Arrays.EmptyBytes));
                }
                if (mechanism.Equals("Ed448"))
                {
                    return(new Ed448Signer(Arrays.EmptyBytes));
                }
                if (mechanism.Equals("Ed448ph"))
                {
                    return(new Ed448phSigner(Arrays.EmptyBytes));
                }
            }

            if (mechanism.Equals("RSA"))
            {
                return(new RsaDigestSigner(new NullDigest(), (AlgorithmIdentifier)null));
            }
            if (mechanism.Equals("RAWRSASSA-PSS"))
            {
                // TODO Add support for other parameter settings
                return(PssSigner.CreateRawSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (mechanism.Equals("PSSwithRSA"))
            {
                // TODO The Sha1Digest here is a default. In JCE version, the actual digest
                // to be used can be overridden by subsequent parameter settings.
                return(new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "withRSA"))
            {
                string  digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
                IDigest digest     = DigestUtilities.GetDigest(digestName);
                return(new RsaDigestSigner(digest));
            }
            if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "withRSAandMGF1"))
            {
                string  digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
                IDigest digest     = DigestUtilities.GetDigest(digestName);
                return(new PssSigner(new RsaBlindedEngine(), digest));
            }

            if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "withDSA"))
            {
                string  digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
                IDigest digest     = DigestUtilities.GetDigest(digestName);
                return(new DsaDigestSigner(new DsaSigner(), digest));
            }

            if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "withECDSA"))
            {
                string  digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
                IDigest digest     = DigestUtilities.GetDigest(digestName);
                return(new DsaDigestSigner(new ECDsaSigner(), digest));
            }

            if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "withCVC-ECDSA") ||
                BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "withPLAIN-ECDSA"))
            {
                string  digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
                IDigest digest     = DigestUtilities.GetDigest(digestName);
                return(new DsaDigestSigner(new ECDsaSigner(), digest, PlainDsaEncoding.Instance));
            }

            if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "withECNR"))
            {
                string  digestName = mechanism.Substring(0, mechanism.LastIndexOf("with"));
                IDigest digest     = DigestUtilities.GetDigest(digestName);
                return(new DsaDigestSigner(new ECNRSigner(), digest));
            }

            if (mechanism.Equals("GOST3410"))
            {
                return(new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest()));
            }
            if (mechanism.Equals("ECGOST3410"))
            {
                return(new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()));
            }

            if (mechanism.Equals("SHA1WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true));
            }
            if (mechanism.Equals("MD5WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true));
            }
            if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true));
            }

            if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(mechanism, "/X9.31"))
            {
                string x931    = mechanism.Substring(0, mechanism.Length - "/X9.31".Length);
                int    withPos = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.IndexOf(x931, "WITH");
                if (withPos > 0)
                {
                    int endPos = withPos + "WITH".Length;

                    string  digestName = x931.Substring(0, withPos);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);

                    string cipherName = x931.Substring(endPos, x931.Length - endPos);
                    if (cipherName.Equals("RSA"))
                    {
                        IAsymmetricBlockCipher cipher = new RsaBlindedEngine();
                        return(new X931Signer(cipher, digest));
                    }
                }
            }

            throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
        }
Exemplo n.º 16
0
 public RsaDigestSigner(RsaBlindedEngine rsaEngine, IDigest digest)
     : this(rsaEngine, digest, (DerObjectIdentifier)oidMap[digest.AlgorithmName])
 {
 }
Exemplo n.º 17
0
 public RsaDigestSigner(RsaBlindedEngine rsaEngine, IDigest digest, DerObjectIdentifier digestOid)
     : this(rsaEngine, digest, new AlgorithmIdentifier(digestOid, DerNull.Instance))
 {
 }
Exemplo n.º 18
0
        public static ISigner GetSigner(string algorithm)
        {
            //IL_0008: Unknown result type (might be due to invalid IL or missing references)
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            algorithm = Platform.ToUpperInvariant(algorithm);
            string text = (string)algorithms.get_Item((object)algorithm);

            if (text == null)
            {
                text = algorithm;
            }
            if (text.Equals("RSA"))
            {
                return(new RsaDigestSigner((IDigest) new NullDigest(), (AlgorithmIdentifier)null));
            }
            if (text.Equals("MD2withRSA"))
            {
                return(new RsaDigestSigner(new MD2Digest()));
            }
            if (text.Equals("MD4withRSA"))
            {
                return(new RsaDigestSigner(new MD4Digest()));
            }
            if (text.Equals("MD5withRSA"))
            {
                return(new RsaDigestSigner(new MD5Digest()));
            }
            if (text.Equals("SHA-1withRSA"))
            {
                return(new RsaDigestSigner(new Sha1Digest()));
            }
            if (text.Equals("SHA-224withRSA"))
            {
                return(new RsaDigestSigner(new Sha224Digest()));
            }
            if (text.Equals("SHA-256withRSA"))
            {
                return(new RsaDigestSigner(new Sha256Digest()));
            }
            if (text.Equals("SHA-384withRSA"))
            {
                return(new RsaDigestSigner(new Sha384Digest()));
            }
            if (text.Equals("SHA-512withRSA"))
            {
                return(new RsaDigestSigner(new Sha512Digest()));
            }
            if (text.Equals("RIPEMD128withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD128Digest()));
            }
            if (text.Equals("RIPEMD160withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD160Digest()));
            }
            if (text.Equals("RIPEMD256withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD256Digest()));
            }
            if (text.Equals("RAWRSASSA-PSS"))
            {
                return(PssSigner.CreateRawSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (text.Equals("PSSwithRSA"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (text.Equals("SHA-1withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (text.Equals("SHA-224withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha224Digest()));
            }
            if (text.Equals("SHA-256withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha256Digest()));
            }
            if (text.Equals("SHA-384withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha384Digest()));
            }
            if (text.Equals("SHA-512withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha512Digest()));
            }
            if (text.Equals("NONEwithDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new NullDigest()));
            }
            if (text.Equals("SHA-1withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha1Digest()));
            }
            if (text.Equals("SHA-224withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha224Digest()));
            }
            if (text.Equals("SHA-256withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha256Digest()));
            }
            if (text.Equals("SHA-384withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha384Digest()));
            }
            if (text.Equals("SHA-512withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha512Digest()));
            }
            if (text.Equals("NONEwithECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new NullDigest()));
            }
            if (text.Equals("SHA-1withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha1Digest()));
            }
            if (text.Equals("SHA-224withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha224Digest()));
            }
            if (text.Equals("SHA-256withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha256Digest()));
            }
            if (text.Equals("SHA-384withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha384Digest()));
            }
            if (text.Equals("SHA-512withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest()));
            }
            if (text.Equals("RIPEMD160withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new RipeMD160Digest()));
            }
            if (text.Equals("SHA1WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha1Digest()));
            }
            if (text.Equals("SHA224WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha224Digest()));
            }
            if (text.Equals("SHA256WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha256Digest()));
            }
            if (text.Equals("SHA384WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha384Digest()));
            }
            if (text.Equals("SHA512WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha512Digest()));
            }
            if (text.Equals("GOST3410"))
            {
                return(new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest()));
            }
            if (text.Equals("ECGOST3410"))
            {
                return(new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()));
            }
            if (text.Equals("SHA1WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), isImplicit: true));
            }
            if (text.Equals("MD5WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), isImplicit: true));
            }
            if (text.Equals("RIPEMD160WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), isImplicit: true));
            }
            if (Platform.EndsWith(text, "/X9.31"))
            {
                string text2 = text.Substring(0, text.get_Length() - "/X9.31".get_Length());
                int    num   = Platform.IndexOf(text2, "WITH");
                if (num > 0)
                {
                    int     num2       = num + "WITH".get_Length();
                    string  algorithm2 = text2.Substring(0, num);
                    IDigest digest     = DigestUtilities.GetDigest(algorithm2);
                    string  text3      = text2.Substring(num2, text2.get_Length() - num2);
                    if (text3.Equals("RSA"))
                    {
                        IAsymmetricBlockCipher cipher = new RsaBlindedEngine();
                        return(new X931Signer(cipher, digest));
                    }
                }
            }
            throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
        }
Exemplo n.º 19
0
        private void processHandshake()
        {
            bool read;

            do
            {
                read = false;

                /*
                 * We need the first 4 bytes, they contain type and length of
                 * the message.
                 */
                if (handshakeQueue.Available >= 4)
                {
                    byte[] beginning = new byte[4];
                    handshakeQueue.Read(beginning, 0, 4, 0);
                    MemoryStream bis  = new MemoryStream(beginning, false);
                    short        type = TlsUtilities.ReadUint8(bis);
                    int          len  = TlsUtilities.ReadUint24(bis);

                    /*
                     * Check if we have enough bytes in the buffer to read
                     * the full message.
                     */
                    if (handshakeQueue.Available >= (len + 4))
                    {
                        /*
                         * Read the message.
                         */
                        byte[] buf = new byte[len];
                        handshakeQueue.Read(buf, 0, len, 4);
                        handshakeQueue.RemoveData(len + 4);

                        /*
                         * If it is not a finished message, update our hashes
                         * we prepare for the finish message.
                         */
                        if (type != HP_FINISHED)
                        {
                            rs.hash1.BlockUpdate(beginning, 0, 4);
                            rs.hash2.BlockUpdate(beginning, 0, 4);
                            rs.hash1.BlockUpdate(buf, 0, len);
                            rs.hash2.BlockUpdate(buf, 0, len);
                        }

                        /*
                         * Now, parse the message.
                         */
                        MemoryStream inStr = new MemoryStream(buf, false);

                        /*
                         * Check the type.
                         */
                        switch (type)
                        {
                        case HP_CERTIFICATE:
                        {
                            switch (connection_state)
                            {
                            case CS_SERVER_HELLO_RECEIVED:
                            {
                                /*
                                 * Parse the certificates.
                                 */
                                Certificate cert = Certificate.Parse(inStr);
                                AssertEmpty(inStr);

                                X509CertificateStructure x509Cert = cert.certs[0];
                                SubjectPublicKeyInfo     keyInfo  = x509Cert.SubjectPublicKeyInfo;

                                try
                                {
                                    this.serverPublicKey = PublicKeyFactory.CreateKey(keyInfo);
                                }
                                catch (Exception)
                                {
                                    this.FailWithError(AL_fatal, AP_unsupported_certificate);
                                }

                                // Sanity check the PublicKeyFactory
                                if (this.serverPublicKey.IsPrivate)
                                {
                                    this.FailWithError(AL_fatal, AP_internal_error);
                                }

                                /*
                                 * Perform various checks per RFC2246 7.4.2
                                 * TODO "Unless otherwise specified, the signing algorithm for the certificate
                                 * must be the same as the algorithm for the certificate key."
                                 */
                                switch (this.chosenCipherSuite.KeyExchangeAlgorithm)
                                {
                                case TlsCipherSuite.KE_RSA:
                                    if (!(this.serverPublicKey is RsaKeyParameters))
                                    {
                                        this.FailWithError(AL_fatal, AP_certificate_unknown);
                                    }
                                    validateKeyUsage(x509Cert, KeyUsage.KeyEncipherment);
                                    break;

                                case TlsCipherSuite.KE_DHE_RSA:
                                    if (!(this.serverPublicKey is RsaKeyParameters))
                                    {
                                        this.FailWithError(AL_fatal, AP_certificate_unknown);
                                    }
                                    validateKeyUsage(x509Cert, KeyUsage.DigitalSignature);
                                    break;

                                case TlsCipherSuite.KE_DHE_DSS:
                                    if (!(this.serverPublicKey is DsaPublicKeyParameters))
                                    {
                                        this.FailWithError(AL_fatal, AP_certificate_unknown);
                                    }
                                    break;

                                default:
                                    this.FailWithError(AL_fatal, AP_unsupported_certificate);
                                    break;
                                }

                                /*
                                 * Verify them.
                                 */
                                if (!this.verifyer.IsValid(cert.GetCerts()))
                                {
                                    this.FailWithError(AL_fatal, AP_user_canceled);
                                }

                                break;
                            }

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }

                            connection_state = CS_SERVER_CERTIFICATE_RECEIVED;
                            read             = true;
                            break;
                        }

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

                                /*
                                 * Calculate our own checksum.
                                 */
                                byte[] checksum   = new byte[12];
                                byte[] md5andsha1 = new byte[16 + 20];
                                rs.hash2.DoFinal(md5andsha1, 0);
                                TlsUtilities.PRF(this.ms, TlsUtilities.ToByteArray("server finished"), md5andsha1, checksum);

                                /*
                                 * Compare both checksums.
                                 */
                                for (int i = 0; i < receivedChecksum.Length; i++)
                                {
                                    if (receivedChecksum[i] != checksum[i])
                                    {
                                        /*
                                         * Wrong checksum in the finished message.
                                         */
                                        this.FailWithError(AL_fatal, AP_handshake_failure);
                                    }
                                }

                                connection_state = CS_DONE;

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

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }
                            break;

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

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

                                /*
                                 * Currently, we don't support session ids
                                 */
                                short  sessionIdLength = TlsUtilities.ReadUint8(inStr);
                                byte[] sessionId       = new byte[sessionIdLength];
                                TlsUtilities.ReadFully(sessionId, inStr);

                                /*
                                 * Find out which ciphersuite the server has
                                 * chosen. If we don't support this ciphersuite,
                                 * the TlsCipherSuiteManager will throw an
                                 * exception.
                                 */
                                this.chosenCipherSuite = TlsCipherSuiteManager.GetCipherSuite(
                                    TlsUtilities.ReadUint16(inStr), this);

                                /*
                                 * We support only the null compression which
                                 * means no compression.
                                 */
                                short compressionMethod = TlsUtilities.ReadUint8(inStr);
                                if (compressionMethod != 0)
                                {
                                    this.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_illegal_parameter);
                                }
                                AssertEmpty(inStr);

                                connection_state = CS_SERVER_HELLO_RECEIVED;
                                read             = true;
                                break;

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }
                            break;

                        case HP_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
                                     * that we are doing RSA key exchange.
                                     */
                                    if (this.chosenCipherSuite.KeyExchangeAlgorithm != TlsCipherSuite.KE_RSA)
                                    {
                                        this.FailWithError(AL_fatal, AP_unexpected_message);
                                    }
                                }

                                AssertEmpty(inStr);
                                bool isCertReq = (connection_state == CS_CERTIFICATE_REQUEST_RECEIVED);
                                connection_state = CS_SERVER_HELLO_DONE_RECEIVED;

                                if (isCertReq)
                                {
                                    sendClientCertificate();
                                }

                                /*
                                 * Send the client key exchange message, depending
                                 * on the key exchange we are using in our
                                 * ciphersuite.
                                 */
                                switch (this.chosenCipherSuite.KeyExchangeAlgorithm)
                                {
                                case TlsCipherSuite.KE_RSA:
                                {
                                    /*
                                     * We are doing RSA key exchange. We will
                                     * choose a pre master secret and send it
                                     * rsa encrypted to the server.
                                     *
                                     * Prepare pre master secret.
                                     */
                                    pms    = new byte[48];
                                    pms[0] = 3;
                                    pms[1] = 1;
                                    random.NextBytes(pms, 2, 46);

                                    /*
                                     * Encode the pms and send it to the server.
                                     *
                                     * Prepare an Pkcs1Encoding with good random
                                     * padding.
                                     */
                                    RsaBlindedEngine rsa      = new RsaBlindedEngine();
                                    Pkcs1Encoding    encoding = new Pkcs1Encoding(rsa);
                                    encoding.Init(true, new ParametersWithRandom(this.serverPublicKey, this.random));
                                    byte[] encrypted = null;
                                    try
                                    {
                                        encrypted = encoding.ProcessBlock(pms, 0, pms.Length);
                                    }
                                    catch (InvalidCipherTextException)
                                    {
                                        /*
                                         * This should never happen, only during decryption.
                                         */
                                        this.FailWithError(AL_fatal, AP_internal_error);
                                    }

                                    /*
                                     * Send the encrypted pms.
                                     */
                                    sendClientKeyExchange(encrypted);
                                    break;
                                }

                                case TlsCipherSuite.KE_DHE_DSS:
                                case TlsCipherSuite.KE_DHE_RSA:
                                {
                                    /*
                                     * Send the Client Key Exchange message for
                                     * DHE key exchange.
                                     */
                                    byte[] YcByte = BigIntegers.AsUnsignedByteArray(this.Yc);

                                    sendClientKeyExchange(YcByte);

                                    break;
                                }

                                default:
                                    /*
                                     * Problem during handshake, we don't know
                                     * how to handle this key exchange method.
                                     */
                                    this.FailWithError(AL_fatal, AP_unexpected_message);
                                    break;
                                }

                                connection_state = CS_CLIENT_KEY_EXCHANGE_SEND;

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

                                connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC_SEND;

                                /*
                                 * Calculate the ms
                                 */
                                this.ms = new byte[48];
                                byte[] randBytes = new byte[clientRandom.Length + serverRandom.Length];
                                Array.Copy(clientRandom, 0, randBytes, 0, clientRandom.Length);
                                Array.Copy(serverRandom, 0, randBytes, clientRandom.Length, serverRandom.Length);
                                TlsUtilities.PRF(pms, TlsUtilities.ToByteArray("master secret"), randBytes, this.ms);

                                /*
                                 * Initialize our cipher suite
                                 */
                                rs.writeSuite = this.chosenCipherSuite;
                                rs.writeSuite.Init(this.ms, clientRandom, serverRandom);

                                /*
                                 * Send our finished message.
                                 */
                                byte[] checksum   = new byte[12];
                                byte[] md5andsha1 = new byte[16 + 20];
                                rs.hash1.DoFinal(md5andsha1, 0);
                                TlsUtilities.PRF(this.ms, TlsUtilities.ToByteArray("client finished"), md5andsha1, checksum);

                                MemoryStream bos2 = new MemoryStream();
                                TlsUtilities.WriteUint8(HP_FINISHED, bos2);
                                TlsUtilities.WriteUint24(12, bos2);
                                bos2.Write(checksum, 0, checksum.Length);
                                byte[] message2 = bos2.ToArray();

                                rs.WriteMessage((short)RL_HANDSHAKE, message2, 0, message2.Length);

                                this.connection_state = CS_CLIENT_FINISHED_SEND;
                                read = true;
                                break;

                            default:
                                this.FailWithError(AL_fatal, AP_handshake_failure);
                                break;
                            }
                            break;

                        case HP_SERVER_KEY_EXCHANGE:
                        {
                            switch (connection_state)
                            {
                            case CS_SERVER_CERTIFICATE_RECEIVED:
                            {
                                /*
                                 * Check that we are doing DHE key exchange
                                 */
                                switch (this.chosenCipherSuite.KeyExchangeAlgorithm)
                                {
                                case TlsCipherSuite.KE_DHE_RSA:
                                {
                                    processDHEKeyExchange(inStr, new TlsRsaSigner());
                                    break;
                                }

                                case TlsCipherSuite.KE_DHE_DSS:
                                {
                                    processDHEKeyExchange(inStr, new TlsDssSigner());
                                    break;
                                }

                                default:
                                    this.FailWithError(AL_fatal, AP_unexpected_message);
                                    break;
                                }
                                break;
                            }

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }

                            this.connection_state = CS_SERVER_KEY_EXCHANGE_RECEIVED;
                            read = true;
                            break;
                        }

                        case HP_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
                                     * that we are doing RSA key exchange.
                                     */
                                    if (this.chosenCipherSuite.KeyExchangeAlgorithm != TlsCipherSuite.KE_RSA)
                                    {
                                        this.FailWithError(AL_fatal, AP_unexpected_message);
                                    }
                                }

                                int    typesLength = TlsUtilities.ReadUint8(inStr);
                                byte[] types       = new byte[typesLength];
                                TlsUtilities.ReadFully(types, inStr);

                                int    authsLength = TlsUtilities.ReadUint16(inStr);
                                byte[] auths       = new byte[authsLength];
                                TlsUtilities.ReadFully(auths, inStr);

                                AssertEmpty(inStr);
                                break;
                            }

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }

                            this.connection_state = CS_CERTIFICATE_REQUEST_RECEIVED;
                            read = true;
                            break;

                        case HP_HELLO_REQUEST:
                        case HP_CLIENT_KEY_EXCHANGE:
                        case HP_CERTIFICATE_VERIFY:
                        case HP_CLIENT_HELLO:
                        default:
                            // We do not support this!
                            this.FailWithError(AL_fatal, AP_unexpected_message);
                            break;
                        }
                    }
                }
            }while (read);
        }
        public static IBufferedCipher GetCipher(
            string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            algorithm = algorithm.ToUpper(CultureInfo.InvariantCulture);

            string aliased = (string)algorithms[algorithm];

            if (aliased != null)
            {
                algorithm = aliased;
            }



            IBasicAgreement iesAgreement = null;

            if (algorithm == "IES")
            {
                iesAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                iesAgreement = new ECDHBasicAgreement();
            }

            if (iesAgreement != null)
            {
                return(new BufferedIesCipher(
                           new IesEngine(
                               iesAgreement,
                               new Kdf2BytesGenerator(
                                   new Sha1Digest()),
                               new HMac(
                                   new Sha1Digest()))));
            }



            if (algorithm.StartsWith("PBE"))
            {
                switch (algorithm)
                {
                case "PBEWITHSHAAND2-KEYTRIPLEDES-CBC":
                case "PBEWITHSHAAND3-KEYTRIPLEDES-CBC":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new DesEdeEngine())));

                case "PBEWITHSHAAND128BITRC2-CBC":
                case "PBEWITHSHAAND40BITRC2-CBC":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new RC2Engine())));

                case "PBEWITHSHAAND128BITAES-CBC-BC":
                case "PBEWITHSHAAND192BITAES-CBC-BC":
                case "PBEWITHSHAAND256BITAES-CBC-BC":
                case "PBEWITHSHA256AND128BITAES-CBC-BC":
                case "PBEWITHSHA256AND192BITAES-CBC-BC":
                case "PBEWITHSHA256AND256BITAES-CBC-BC":
                case "PBEWITHMD5AND128BITAES-CBC-OPENSSL":
                case "PBEWITHMD5AND192BITAES-CBC-OPENSSL":
                case "PBEWITHMD5AND256BITAES-CBC-OPENSSL":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new AesFastEngine())));

                case "PBEWITHSHA1ANDDES-CBC":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new DesEngine())));

                case "PBEWITHSHA1ANDRC2-CBC":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new RC2Engine())));
                }
            }



            string[] parts = algorithm.Split('/');

            IBlockCipher           blockCipher     = null;
            IAsymmetricBlockCipher asymBlockCipher = null;
            IStreamCipher          streamCipher    = null;

            switch (parts[0])
            {
            case "AES":
                blockCipher = new AesFastEngine();
                break;

            case "ARC4":
                streamCipher = new RC4Engine();
                break;

            case "BLOWFISH":
                blockCipher = new BlowfishEngine();
                break;

            case "CAMELLIA":
                blockCipher = new CamelliaEngine();
                break;

            case "CAST5":
                blockCipher = new Cast5Engine();
                break;

            case "CAST6":
                blockCipher = new Cast6Engine();
                break;

            case "DES":
                blockCipher = new DesEngine();
                break;

            case "DESEDE":
                blockCipher = new DesEdeEngine();
                break;

            case "ELGAMAL":
                asymBlockCipher = new ElGamalEngine();
                break;

            case "GOST28147":
                blockCipher = new Gost28147Engine();
                break;

            case "HC128":
                streamCipher = new HC128Engine();
                break;

            case "HC256":
                streamCipher = new HC256Engine();
                break;

#if INCLUDE_IDEA
            case "IDEA":
                blockCipher = new IdeaEngine();
                break;
#endif
            case "NOEKEON":
                blockCipher = new NoekeonEngine();
                break;

            case "PBEWITHSHAAND128BITRC4":
            case "PBEWITHSHAAND40BITRC4":
                streamCipher = new RC4Engine();
                break;

            case "RC2":
                blockCipher = new RC2Engine();
                break;

            case "RC5":
                blockCipher = new RC532Engine();
                break;

            case "RC5-64":
                blockCipher = new RC564Engine();
                break;

            case "RC6":
                blockCipher = new RC6Engine();
                break;

            case "RIJNDAEL":
                blockCipher = new RijndaelEngine();
                break;

            case "RSA":
                asymBlockCipher = new RsaBlindedEngine();
                break;

            case "SALSA20":
                streamCipher = new Salsa20Engine();
                break;

            case "SEED":
                blockCipher = new SeedEngine();
                break;

            case "SERPENT":
                blockCipher = new SerpentEngine();
                break;

            case "SKIPJACK":
                blockCipher = new SkipjackEngine();
                break;

            case "TEA":
                blockCipher = new TeaEngine();
                break;

            case "TWOFISH":
                blockCipher = new TwofishEngine();
                break;

            case "VMPC":
                streamCipher = new VmpcEngine();
                break;

            case "VMPC-KSA3":
                streamCipher = new VmpcKsa3Engine();
                break;

            case "XTEA":
                blockCipher = new XteaEngine();
                break;

            default:
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            if (streamCipher != null)
            {
                if (parts.Length > 1)
                {
                    throw new ArgumentException("Modes and paddings not used for stream ciphers");
                }

                return(new BufferedStreamCipher(streamCipher));
            }


            bool cts    = false;
            bool padded = true;
            IBlockCipherPadding padding         = null;
            IAeadBlockCipher    aeadBlockCipher = null;

            if (parts.Length > 2)
            {
                if (streamCipher != null)
                {
                    throw new ArgumentException("Paddings not used for stream ciphers");
                }

                switch (parts[2])
                {
                case "NOPADDING":
                    padded = false;
                    break;

                case "":
                case "RAW":
                    break;

                case "ISO10126PADDING":
                case "ISO10126D2PADDING":
                case "ISO10126-2PADDING":
                    padding = new ISO10126d2Padding();
                    break;

                case "ISO7816-4PADDING":
                case "ISO9797-1PADDING":
                    padding = new ISO7816d4Padding();
                    break;

                case "ISO9796-1":
                case "ISO9796-1PADDING":
                    asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
                    break;

                case "OAEP":
                case "OAEPPADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher);
                    break;

                case "OAEPWITHMD5ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
                    break;

                case "OAEPWITHSHA1ANDMGF1PADDING":
                case "OAEPWITHSHA-1ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
                    break;

                case "OAEPWITHSHA224ANDMGF1PADDING":
                case "OAEPWITHSHA-224ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
                    break;

                case "OAEPWITHSHA256ANDMGF1PADDING":
                case "OAEPWITHSHA-256ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
                    break;

                case "OAEPWITHSHA384ANDMGF1PADDING":
                case "OAEPWITHSHA-384ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
                    break;

                case "OAEPWITHSHA512ANDMGF1PADDING":
                case "OAEPWITHSHA-512ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
                    break;

                case "PKCS1":
                case "PKCS1PADDING":
                    asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
                    break;

                case "PKCS5":
                case "PKCS5PADDING":
                case "PKCS7":
                case "PKCS7PADDING":
                    // NB: Padding defaults to Pkcs7Padding already
                    break;

                case "TBCPADDING":
                    padding = new TbcPadding();
                    break;

                case "WITHCTS":
                    cts = true;
                    break;

                case "X9.23PADDING":
                case "X923PADDING":
                    padding = new X923Padding();
                    break;

                case "ZEROBYTEPADDING":
                    padding = new ZeroBytePadding();
                    break;

                default:
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            string mode = "";
            if (parts.Length > 1)
            {
                mode = parts[1];

                int    di       = GetDigitIndex(mode);
                string modeName = di >= 0 ? mode.Substring(0, di) : mode;

                switch (modeName)
                {
                case "":
                case "ECB":
                case "NONE":
                    break;

                case "CBC":
                    blockCipher = new CbcBlockCipher(blockCipher);
                    break;

                case "CCM":
                    aeadBlockCipher = new CcmBlockCipher(blockCipher);
                    break;

                case "CFB":
                {
                    int bits = (di < 0)
                                                        ?       8 * blockCipher.GetBlockSize()
                                                        :       int.Parse(mode.Substring(di));

                    blockCipher = new CfbBlockCipher(blockCipher, bits);
                    break;
                }

                case "CTR":
                    blockCipher = new SicBlockCipher(blockCipher);
                    break;

                case "CTS":
                    cts         = true;
                    blockCipher = new CbcBlockCipher(blockCipher);
                    break;

                case "EAX":
                    aeadBlockCipher = new EaxBlockCipher(blockCipher);
                    break;

                case "GCM":
                    aeadBlockCipher = new GcmBlockCipher(blockCipher);
                    break;

                case "GOFB":
                    blockCipher = new GOfbBlockCipher(blockCipher);
                    break;

                case "OFB":
                {
                    int bits = (di < 0)
                                                        ?       8 * blockCipher.GetBlockSize()
                                                        :       int.Parse(mode.Substring(di));

                    blockCipher = new OfbBlockCipher(blockCipher, bits);
                    break;
                }

                case "OPENPGPCFB":
                    blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
                    break;

                case "SIC":
                    if (blockCipher.GetBlockSize() < 16)
                    {
                        throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
                    }
                    blockCipher = new SicBlockCipher(blockCipher);
                    break;

                default:
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            if (aeadBlockCipher != null)
            {
                if (cts)
                {
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                }
                if (padded && parts.Length > 1 && parts[2] != "")
                {
                    throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");
                }

                return(new BufferedAeadBlockCipher(aeadBlockCipher));
            }

            if (blockCipher != null)
            {
                if (cts)
                {
                    return(new CtsBlockCipher(blockCipher));
                }

                if (!padded || blockCipher.IsPartialBlockOkay)
                {
                    return(new BufferedBlockCipher(blockCipher));
                }

                if (padding != null)
                {
                    return(new PaddedBufferedBlockCipher(blockCipher, padding));
                }

                return(new PaddedBufferedBlockCipher(blockCipher));
            }

            if (asymBlockCipher != null)
            {
                return(new BufferedAsymmetricBlockCipher(asymBlockCipher));
            }

            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }
Exemplo n.º 21
0
        public static ISigner GetSigner(string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            algorithm = Platform.ToUpperInvariant(algorithm);
            string text = (string)SignerUtilities.algorithms[algorithm];

            if (text == null)
            {
                text = algorithm;
            }
            if (text.Equals("RSA"))
            {
                return(new RsaDigestSigner(new NullDigest(), null));
            }
            if (text.Equals("MD2withRSA"))
            {
                return(new RsaDigestSigner(new MD2Digest()));
            }
            if (text.Equals("MD4withRSA"))
            {
                return(new RsaDigestSigner(new MD4Digest()));
            }
            if (text.Equals("MD5withRSA"))
            {
                return(new RsaDigestSigner(new MD5Digest()));
            }
            if (text.Equals("SHA-1withRSA"))
            {
                return(new RsaDigestSigner(new Sha1Digest()));
            }
            if (text.Equals("SHA-224withRSA"))
            {
                return(new RsaDigestSigner(new Sha224Digest()));
            }
            if (text.Equals("SHA-256withRSA"))
            {
                return(new RsaDigestSigner(new Sha256Digest()));
            }
            if (text.Equals("SHA-384withRSA"))
            {
                return(new RsaDigestSigner(new Sha384Digest()));
            }
            if (text.Equals("SHA-512withRSA"))
            {
                return(new RsaDigestSigner(new Sha512Digest()));
            }
            if (text.Equals("RIPEMD128withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD128Digest()));
            }
            if (text.Equals("RIPEMD160withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD160Digest()));
            }
            if (text.Equals("RIPEMD256withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD256Digest()));
            }
            if (text.Equals("RAWRSASSA-PSS"))
            {
                return(PssSigner.CreateRawSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (text.Equals("PSSwithRSA"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (text.Equals("SHA-1withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (text.Equals("SHA-224withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha224Digest()));
            }
            if (text.Equals("SHA-256withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha256Digest()));
            }
            if (text.Equals("SHA-384withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha384Digest()));
            }
            if (text.Equals("SHA-512withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha512Digest()));
            }
            if (text.Equals("NONEwithDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new NullDigest()));
            }
            if (text.Equals("SHA-1withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha1Digest()));
            }
            if (text.Equals("SHA-224withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha224Digest()));
            }
            if (text.Equals("SHA-256withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha256Digest()));
            }
            if (text.Equals("SHA-384withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha384Digest()));
            }
            if (text.Equals("SHA-512withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha512Digest()));
            }
            if (text.Equals("NONEwithECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new NullDigest()));
            }
            if (text.Equals("SHA-1withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha1Digest()));
            }
            if (text.Equals("SHA-224withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha224Digest()));
            }
            if (text.Equals("SHA-256withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha256Digest()));
            }
            if (text.Equals("SHA-384withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha384Digest()));
            }
            if (text.Equals("SHA-512withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest()));
            }
            if (text.Equals("RIPEMD160withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new RipeMD160Digest()));
            }
            if (text.Equals("SHA1WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha1Digest()));
            }
            if (text.Equals("SHA224WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha224Digest()));
            }
            if (text.Equals("SHA256WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha256Digest()));
            }
            if (text.Equals("SHA384WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha384Digest()));
            }
            if (text.Equals("SHA512WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha512Digest()));
            }
            if (text.Equals("GOST3410"))
            {
                return(new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest()));
            }
            if (text.Equals("ECGOST3410"))
            {
                return(new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()));
            }
            if (text.Equals("SHA1WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true));
            }
            if (text.Equals("MD5WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true));
            }
            if (text.Equals("RIPEMD160WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true));
            }
            if (text.EndsWith("/X9.31"))
            {
                string text2 = text.Substring(0, text.Length - "/X9.31".Length);
                int    num   = text2.IndexOf("WITH");
                if (num > 0)
                {
                    int     num2       = num + "WITH".Length;
                    string  algorithm2 = text2.Substring(0, num);
                    IDigest digest     = DigestUtilities.GetDigest(algorithm2);
                    string  text3      = text2.Substring(num2, text2.Length - num2);
                    if (text3.Equals("RSA"))
                    {
                        IAsymmetricBlockCipher cipher = new RsaBlindedEngine();
                        return(new X931Signer(cipher, digest));
                    }
                }
            }
            throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
        }
Exemplo n.º 22
0
 public RsaDigestSigner(RsaBlindedEngine rsaEngine, IDigest digest, AlgorithmIdentifier algId)
 {
     this.digest    = digest;
     this.algId     = algId;
     this.rsaEngine = new Pkcs1Encoding(rsaEngine);
 }
Exemplo n.º 23
0
        private void processHandshake()
        {
            bool read;

            do
            {
                read = false;

                /*
                 * We need the first 4 bytes, they contain type and length of
                 * the message.
                 */
                if (handshakeQueue.Available >= 4)
                {
                    byte[] beginning = new byte[4];
                    handshakeQueue.Read(beginning, 0, 4, 0);
                    MemoryStream bis  = new MemoryStream(beginning, false);
                    short        type = TlsUtilities.ReadUint8(bis);
                    int          len  = TlsUtilities.ReadUint24(bis);

                    /*
                     * Check if we have enough bytes in the buffer to read
                     * the full message.
                     */
                    if (handshakeQueue.Available >= (len + 4))
                    {
                        /*
                         * Read the message.
                         */
                        byte[] buf = new byte[len];
                        handshakeQueue.Read(buf, 0, len, 4);
                        handshakeQueue.RemoveData(len + 4);

                        /*
                         * If it is not a finished message, update our hashes
                         * we prepare for the finish message.
                         */
                        if (type != HP_FINISHED)
                        {
                            rs.hash1.BlockUpdate(beginning, 0, 4);
                            rs.hash2.BlockUpdate(beginning, 0, 4);
                            rs.hash1.BlockUpdate(buf, 0, len);
                            rs.hash2.BlockUpdate(buf, 0, len);
                        }

                        /*
                         * Now, parse the message.
                         */
                        MemoryStream inStr = new MemoryStream(buf, false);

                        /*
                         * Check the type.
                         */
                        switch (type)
                        {
                        case HP_CERTIFICATE:
                            switch (connection_state)
                            {
                            case CS_SERVER_HELLO_RECEIVED:
                                /*
                                 * Parse the certificates.
                                 */
                                Certificate cert = Certificate.Parse(inStr);
                                AssertEmpty(inStr);

                                /*
                                 * Verify them.
                                 */
                                if (!this.verifyer.IsValid(cert.GetCerts()))
                                {
                                    this.FailWithError(AL_fatal, AP_user_canceled);
                                }

                                /*
                                 * We only support RSA certificates. Lets hope
                                 * this is one.
                                 */
                                RsaPublicKeyStructure rsaKey = null;
                                try
                                {
                                    rsaKey = RsaPublicKeyStructure.GetInstance(
                                        cert.certs[0].TbsCertificate.SubjectPublicKeyInfo.GetPublicKey());
                                }
                                catch (Exception)
                                {
                                    /*
                                     * Sorry, we have to fail ;-(
                                     */
                                    this.FailWithError(AL_fatal, AP_unsupported_certificate);
                                }

                                /*
                                 * Parse the servers public RSA key.
                                 */
                                this.serverRsaKey = new RsaKeyParameters(
                                    false,
                                    rsaKey.Modulus,
                                    rsaKey.PublicExponent);

                                connection_state = CS_SERVER_CERTIFICATE_RECEIVED;
                                read             = true;
                                break;

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }
                            break;

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

                                /*
                                 * Calculate our owne checksum.
                                 */
                                byte[] checksum   = new byte[12];
                                byte[] md5andsha1 = new byte[16 + 20];
                                rs.hash2.DoFinal(md5andsha1, 0);
                                TlsUtilities.PRF(this.ms, TlsUtilities.ToByteArray("server finished"), md5andsha1, checksum);

                                /*
                                 * Compare both checksums.
                                 */
                                for (int i = 0; i < receivedChecksum.Length; i++)
                                {
                                    if (receivedChecksum[i] != checksum[i])
                                    {
                                        /*
                                         * Wrong checksum in the finished message.
                                         */
                                        this.FailWithError(AL_fatal, AP_handshake_failure);
                                    }
                                }

                                connection_state = CS_DONE;

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

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }
                            break;

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

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

                                /*
                                 * Currenty, we don't support session ids
                                 */
                                short  sessionIdLength = TlsUtilities.ReadUint8(inStr);
                                byte[] sessionId       = new byte[sessionIdLength];
                                TlsUtilities.ReadFully(sessionId, inStr);

                                /*
                                 * Find out which ciphersuite the server has
                                 * choosen. If we don't support this ciphersuite,
                                 * the TlsCipherSuiteManager will throw an
                                 * exception.
                                 */
                                this.choosenCipherSuite = TlsCipherSuiteManager.GetCipherSuite(
                                    TlsUtilities.ReadUint16(inStr), this);

                                /*
                                 * We support only the null compression which
                                 * means no compression.
                                 */
                                short compressionMethod = TlsUtilities.ReadUint8(inStr);
                                if (compressionMethod != 0)
                                {
                                    this.FailWithError(TlsProtocolHandler.AL_fatal, TlsProtocolHandler.AP_illegal_parameter);
                                }
                                AssertEmpty(inStr);

                                connection_state = CS_SERVER_HELLO_RECEIVED;
                                read             = true;
                                break;

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }
                            break;

                        case HP_SERVER_HELLO_DONE:
                            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
                                     * that we are doing RSA key exchange.
                                     */
                                    if (this.choosenCipherSuite.KeyExchangeAlgorithm != TlsCipherSuite.KE_RSA)
                                    {
                                        this.FailWithError(AL_fatal, AP_unexpected_message);
                                    }
                                }

                                AssertEmpty(inStr);
                                connection_state = CS_SERVER_HELLO_DONE_RECEIVED;

                                /*
                                 * Send the client key exchange message, depending
                                 * on the key exchange we are using in our
                                 * ciphersuite.
                                 */
                                short ke = this.choosenCipherSuite.KeyExchangeAlgorithm;

                                switch (ke)
                                {
                                case TlsCipherSuite.KE_RSA:
                                    /*
                                     * We are doing RSA key exchange. We will
                                     * choose a pre master secret and send it
                                     * rsa encrypted to the server.
                                     *
                                     * Prepare pre master secret.
                                     */
                                    pms    = new byte[48];
                                    pms[0] = 3;
                                    pms[1] = 1;
                                    random.NextBytes(pms, 2, 46);

                                    /*
                                     * Encode the pms and send it to the server.
                                     *
                                     * Prepare an Pkcs1Encoding with good random
                                     * padding.
                                     */
                                    RsaBlindedEngine rsa      = new RsaBlindedEngine();
                                    Pkcs1Encoding    encoding = new Pkcs1Encoding(rsa);
                                    encoding.Init(true, new ParametersWithRandom(this.serverRsaKey, this.random));
                                    byte[] encrypted = null;
                                    try
                                    {
                                        encrypted = encoding.ProcessBlock(pms, 0, pms.Length);
                                    }
                                    catch (InvalidCipherTextException)
                                    {
                                        /*
                                         * This should never happen, only during decryption.
                                         */
                                        this.FailWithError(AL_fatal, AP_internal_error);
                                    }

                                    /*
                                     * Send the encrypted pms.
                                     */
                                    MemoryStream bos = new MemoryStream();
                                    TlsUtilities.WriteUint8(HP_CLIENT_KEY_EXCHANGE, bos);
                                    TlsUtilities.WriteUint24(encrypted.Length + 2, bos);
                                    TlsUtilities.WriteUint16(encrypted.Length, bos);
                                    bos.Write(encrypted, 0, encrypted.Length);
                                    byte[] message = bos.ToArray();

                                    rs.WriteMessage((short)RL_HANDSHAKE, message, 0, message.Length);
                                    break;

                                case TlsCipherSuite.KE_DHE_RSA:
                                    /*
                                     * Send the Client Key Exchange message for
                                     * DHE key exchange.
                                     */
                                    byte[]       YcByte = this.Yc.ToByteArray();
                                    MemoryStream DHbos  = new MemoryStream();
                                    TlsUtilities.WriteUint8(HP_CLIENT_KEY_EXCHANGE, DHbos);
                                    TlsUtilities.WriteUint24(YcByte.Length + 2, DHbos);
                                    TlsUtilities.WriteUint16(YcByte.Length, DHbos);
                                    DHbos.Write(YcByte, 0, YcByte.Length);
                                    byte[] DHmessage = DHbos.ToArray();

                                    rs.WriteMessage((short)RL_HANDSHAKE, DHmessage, 0, DHmessage.Length);

                                    break;

                                default:
                                    /*
                                     * Proble during handshake, we don't know
                                     * how to thandle this key exchange method.
                                     */
                                    this.FailWithError(AL_fatal, AP_unexpected_message);
                                    break;
                                }

                                connection_state = CS_CLIENT_KEY_EXCHANGE_SEND;

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

                                connection_state = CS_CLIENT_CHANGE_CIPHER_SPEC_SEND;

                                /*
                                 * Calculate the ms
                                 */
                                this.ms = new byte[48];
                                byte[] randBytes = new byte[clientRandom.Length + serverRandom.Length];
                                Array.Copy(clientRandom, 0, randBytes, 0, clientRandom.Length);
                                Array.Copy(serverRandom, 0, randBytes, clientRandom.Length, serverRandom.Length);
                                TlsUtilities.PRF(pms, TlsUtilities.ToByteArray("master secret"), randBytes, this.ms);

                                /*
                                 * Initialize our cipher suite
                                 */
                                rs.writeSuite = this.choosenCipherSuite;
                                rs.writeSuite.Init(this.ms, clientRandom, serverRandom);

                                /*
                                 * Send our finished message.
                                 */
                                byte[] checksum   = new byte[12];
                                byte[] md5andsha1 = new byte[16 + 20];
                                rs.hash1.DoFinal(md5andsha1, 0);
                                TlsUtilities.PRF(this.ms, TlsUtilities.ToByteArray("client finished"), md5andsha1, checksum);

                                MemoryStream bos2 = new MemoryStream();
                                TlsUtilities.WriteUint8(HP_FINISHED, bos2);
                                TlsUtilities.WriteUint24(12, bos2);
                                bos2.Write(checksum, 0, checksum.Length);
                                byte[] message2 = bos2.ToArray();

                                rs.WriteMessage((short)RL_HANDSHAKE, message2, 0, message2.Length);

                                this.connection_state = CS_CLIENT_FINISHED_SEND;
                                read = true;
                                break;

                            default:
                                this.FailWithError(AL_fatal, AP_handshake_failure);
                                break;
                            }
                            break;

                        case HP_SERVER_KEY_EXCHANGE:
                            switch (connection_state)
                            {
                            case CS_SERVER_CERTIFICATE_RECEIVED:
                                /*
                                 * Check that we are doing DHE key exchange
                                 */
                                if (this.choosenCipherSuite.KeyExchangeAlgorithm != TlsCipherSuite.KE_DHE_RSA)
                                {
                                    this.FailWithError(AL_fatal, AP_unexpected_message);
                                }

                                /*
                                 * Parse the Structure
                                 */
                                int    pLength = TlsUtilities.ReadUint16(inStr);
                                byte[] pByte   = new byte[pLength];
                                TlsUtilities.ReadFully(pByte, inStr);

                                int    gLength = TlsUtilities.ReadUint16(inStr);
                                byte[] gByte   = new byte[gLength];
                                TlsUtilities.ReadFully(gByte, inStr);

                                int    YsLength = TlsUtilities.ReadUint16(inStr);
                                byte[] YsByte   = new byte[YsLength];
                                TlsUtilities.ReadFully(YsByte, inStr);

                                int    sigLength = TlsUtilities.ReadUint16(inStr);
                                byte[] sigByte   = new byte[sigLength];
                                TlsUtilities.ReadFully(sigByte, inStr);

                                this.AssertEmpty(inStr);

                                /*
                                 * Verify the Signature.
                                 *
                                 * First, calculate the hash.
                                 */
                                CombinedHash sigDigest  = new CombinedHash();
                                MemoryStream signedData = new MemoryStream();
                                TlsUtilities.WriteUint16(pLength, signedData);
                                signedData.Write(pByte, 0, pByte.Length);
                                TlsUtilities.WriteUint16(gLength, signedData);
                                signedData.Write(gByte, 0, gByte.Length);
                                TlsUtilities.WriteUint16(YsLength, signedData);
                                signedData.Write(YsByte, 0, YsByte.Length);
                                byte[] signed = signedData.ToArray();

                                sigDigest.BlockUpdate(this.clientRandom, 0, this.clientRandom.Length);
                                sigDigest.BlockUpdate(this.serverRandom, 0, this.serverRandom.Length);
                                sigDigest.BlockUpdate(signed, 0, signed.Length);
                                byte[] hash = new byte[sigDigest.GetDigestSize()];
                                sigDigest.DoFinal(hash, 0);

                                /*
                                 * Now, do the RSA operation
                                 */
                                RsaBlindedEngine rsa      = new RsaBlindedEngine();
                                Pkcs1Encoding    encoding = new Pkcs1Encoding(rsa);
                                encoding.Init(false, this.serverRsaKey);

                                /*
                                 * The data which was signed
                                 */
                                byte[] sigHash = null;

                                try
                                {
                                    sigHash = encoding.ProcessBlock(sigByte, 0, sigByte.Length);
                                }
                                catch (InvalidCipherTextException)
                                {
                                    this.FailWithError(AL_fatal, AP_bad_certificate);
                                }

                                /*
                                 * Check if the data which was signed is equal to
                                 * the hash we calculated.
                                 */
                                if (sigHash.Length != hash.Length)
                                {
                                    this.FailWithError(AL_fatal, AP_bad_certificate);
                                }

                                for (int i = 0; i < sigHash.Length; i++)
                                {
                                    if (sigHash[i] != hash[i])
                                    {
                                        this.FailWithError(AL_fatal, AP_bad_certificate);
                                    }
                                }

                                /*
                                 * OK, Signature was correct.
                                 *
                                 * Do the DH calculation.
                                 */
                                BigInteger p  = new BigInteger(1, pByte);
                                BigInteger g  = new BigInteger(1, gByte);
                                BigInteger Ys = new BigInteger(1, YsByte);
                                BigInteger x  = new BigInteger(p.BitLength - 1, this.random);
                                Yc       = g.ModPow(x, p);
                                this.pms = (Ys.ModPow(x, p)).ToByteArray();

                                /*
                                 * Remove leading zero byte, if present.
                                 */
                                if (this.pms[0] == 0)
                                {
                                    byte[] tmp = new byte[this.pms.Length - 1];
                                    Array.Copy(this.pms, 1, tmp, 0, tmp.Length);
                                    this.pms = tmp;
                                }

                                this.connection_state = CS_SERVER_KEY_EXCHANGE_RECEIVED;
                                read = true;
                                break;

                            default:
                                this.FailWithError(AL_fatal, AP_unexpected_message);
                                break;
                            }
                            break;

                        case HP_HELLO_REQUEST:
                        case HP_CLIENT_KEY_EXCHANGE:
                        case HP_CERTIFICATE_REQUEST:
                        case HP_CERTIFICATE_VERIFY:
                        case HP_CLIENT_HELLO:
                        default:
                            // We do not support this!
                            this.FailWithError(AL_fatal, AP_unexpected_message);
                            break;
                        }
                    }
                }
            }while (read);
        }
Exemplo n.º 24
0
        public void DoTest13()
        {
            BigInteger modulus = new BigInteger(1, Hex.Decode("CDCBDABBF93BE8E8294E32B055256BBD0397735189BF75816341BB0D488D05D627991221DF7D59835C76A4BB4808ADEEB779E7794504E956ADC2A661B46904CDC71337DD29DDDD454124EF79CFDD7BC2C21952573CEFBA485CC38C6BD2428809B5A31A898A6B5648CAA4ED678D9743B589134B7187478996300EDBA16271A861"));
            BigInteger pubExp  = new BigInteger(1, Hex.Decode("010001"));
            BigInteger privExp = new BigInteger(1, Hex.Decode("4BA6432AD42C74AA5AFCB6DF60FD57846CBC909489994ABD9C59FE439CC6D23D6DE2F3EA65B8335E796FD7904CA37C248367997257AFBD82B26F1A30525C447A236C65E6ADE43ECAAF7283584B2570FA07B340D9C9380D88EAACFFAEEFE7F472DBC9735C3FF3A3211E8A6BBFD94456B6A33C17A2C4EC18CE6335150548ED126D"));

            RsaKeyParameters pubParams  = new RsaKeyParameters(false, modulus, pubExp);
            RsaKeyParameters privParams = new RsaKeyParameters(true, modulus, privExp);

            IAsymmetricBlockCipher rsaEngine = new RsaBlindedEngine();
            IDigest digest = new Sha256Digest();

            // set challenge to all zero's for verification
            byte[] challenge = new byte[8];

            // DOES NOT USE FINAL BOOLEAN TO INDICATE RECOVERY
            Iso9796d2Signer signer = new Iso9796d2Signer(rsaEngine, digest, false);

            // sign
            signer.Init(true, privParams);
            signer.BlockUpdate(challenge, 0, challenge.Length);

            byte[] sig = signer.GenerateSignature();

            // verify
            signer.Init(false, pubParams);
            signer.BlockUpdate(challenge, 0, challenge.Length);

            if (!signer.VerifySignature(sig))
            {
                Fail("basic verification failed");
            }

            // === LETS ACTUALLY DO SOME RECOVERY, USING INPUT FROM INTERNAL AUTHENTICATE ===

            signer.Reset();

            string args0 = "482E20D1EDDED34359C38F5E7C01203F9D6B2641CDCA5C404D49ADAEDE034C7481D781D043722587761C90468DE69C6585A1E8B9C322F90E1B580EEDAB3F6007D0C366CF92B4DB8B41C8314929DCE2BE889C0129123484D2FD3D12763D2EBFD12AC8E51D7061AFCA1A53DEDEC7B9A617472A78C952CCC72467AE008E5F132994";

            digest = new Sha1Digest();

            signer = new Iso9796d2Signer(rsaEngine, digest, true);


            signer.Init(false, pubParams);
            byte[] signature = Hex.Decode(args0);
            signer.UpdateWithRecoveredMessage(signature);
            signer.BlockUpdate(challenge, 0, challenge.Length);

            if (!signer.VerifySignature(signature))
            {
                Fail("recovered + challenge signature failed");
            }

            // === FINALLY, USING SHA-256 ===

            signer.Reset();

            digest = new Sha256Digest();

            // NOTE setting implicit to false does not actually do anything for verification !!!
            signer = new Iso9796d2Signer(rsaEngine, digest, false);


            signer.Init(true, privParams);
            // generate NONCE of correct length using some inner knowledge
            int nonceLength = modulus.BitLength / 8 - 1 - digest.GetDigestSize() - 2;

            byte[]       nonce = new byte[nonceLength];
            SecureRandom rnd   = new SecureRandom();

            rnd.NextBytes(nonce);

            signer.BlockUpdate(nonce, 0, nonce.Length);
            signer.BlockUpdate(challenge, 0, challenge.Length);
            byte[] sig3 = signer.GenerateSignature();

            signer.Init(false, pubParams);
            signer.UpdateWithRecoveredMessage(sig3);
            signer.BlockUpdate(challenge, 0, challenge.Length);
            if (signer.VerifySignature(sig3))
            {
                if (signer.HasFullMessage())
                {
                    Fail("signer indicates full message");
                }
                byte[] recoverableMessage = signer.GetRecoveredMessage();

                // sanity check, normally the nonce is ignored in eMRTD specs (PKI Technical Report)
                if (!Arrays.AreEqual(nonce, recoverableMessage))
                {
                    Fail("Nonce compare with recoverable part of message failed");
                }
            }
            else
            {
                Fail("recoverable + nonce failed.");
            }
        }
Exemplo n.º 25
0
        public static ISigner GetSigner(
            string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            algorithm = Platform.ToUpperInvariant(algorithm);

            string mechanism = (string)algorithms[algorithm];

            if (mechanism == null)
            {
                mechanism = algorithm;
            }

            if (mechanism.Equals("RSA"))
            {
                return(new RsaDigestSigner(new NullDigest(), (AlgorithmIdentifier)null));
            }
            if (mechanism.Equals("MD2withRSA"))
            {
                return(new RsaDigestSigner(new MD2Digest()));
            }
            if (mechanism.Equals("MD4withRSA"))
            {
                return(new RsaDigestSigner(new MD4Digest()));
            }
            if (mechanism.Equals("MD5withRSA"))
            {
                return(new RsaDigestSigner(new MD5Digest()));
            }
            if (mechanism.Equals("SHA-1withRSA"))
            {
                return(new RsaDigestSigner(new Sha1Digest()));
            }
            if (mechanism.Equals("SHA-224withRSA"))
            {
                return(new RsaDigestSigner(new Sha224Digest()));
            }
            if (mechanism.Equals("SHA-256withRSA"))
            {
                return(new RsaDigestSigner(new Sha256Digest()));
            }
            if (mechanism.Equals("SHA-384withRSA"))
            {
                return(new RsaDigestSigner(new Sha384Digest()));
            }
            if (mechanism.Equals("SHA-512withRSA"))
            {
                return(new RsaDigestSigner(new Sha512Digest()));
            }
            if (mechanism.Equals("RIPEMD128withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD128Digest()));
            }
            if (mechanism.Equals("RIPEMD160withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD160Digest()));
            }
            if (mechanism.Equals("RIPEMD256withRSA"))
            {
                return(new RsaDigestSigner(new RipeMD256Digest()));
            }

            if (mechanism.Equals("RAWRSASSA-PSS"))
            {
                // TODO Add support for other parameter settings
                return(PssSigner.CreateRawSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (mechanism.Equals("PSSwithRSA"))
            {
                // TODO The Sha1Digest here is a default. In JCE version, the actual digest
                // to be used can be overridden by subsequent parameter settings.
                return(new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (mechanism.Equals("SHA-1withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
            }
            if (mechanism.Equals("SHA-224withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha224Digest()));
            }
            if (mechanism.Equals("SHA-256withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha256Digest()));
            }
            if (mechanism.Equals("SHA-384withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha384Digest()));
            }
            if (mechanism.Equals("SHA-512withRSAandMGF1"))
            {
                return(new PssSigner(new RsaBlindedEngine(), new Sha512Digest()));
            }

            if (mechanism.Equals("NONEwithDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new NullDigest()));
            }
            if (mechanism.Equals("SHA-1withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha1Digest()));
            }
            if (mechanism.Equals("SHA-224withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha224Digest()));
            }
            if (mechanism.Equals("SHA-256withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha256Digest()));
            }
            if (mechanism.Equals("SHA-384withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha384Digest()));
            }
            if (mechanism.Equals("SHA-512withDSA"))
            {
                return(new DsaDigestSigner(new DsaSigner(), new Sha512Digest()));
            }

            if (mechanism.Equals("NONEwithECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new NullDigest()));
            }
            if (mechanism.Equals("SHA-1withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha1Digest()));
            }
            if (mechanism.Equals("SHA-224withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha224Digest()));
            }
            if (mechanism.Equals("SHA-256withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha256Digest()));
            }
            if (mechanism.Equals("SHA-384withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha384Digest()));
            }
            if (mechanism.Equals("SHA-512withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest()));
            }

            if (mechanism.Equals("RIPEMD160withECDSA"))
            {
                return(new DsaDigestSigner(new ECDsaSigner(), new RipeMD160Digest()));
            }

            if (mechanism.Equals("SHA1WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha1Digest()));
            }
            if (mechanism.Equals("SHA224WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha224Digest()));
            }
            if (mechanism.Equals("SHA256WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha256Digest()));
            }
            if (mechanism.Equals("SHA384WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha384Digest()));
            }
            if (mechanism.Equals("SHA512WITHECNR"))
            {
                return(new DsaDigestSigner(new ECNRSigner(), new Sha512Digest()));
            }

            if (mechanism.Equals("GOST3410"))
            {
                return(new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest()));
            }
            if (mechanism.Equals("ECGOST3410"))
            {
                return(new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest()));
            }

            if (mechanism.Equals("SHA1WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true));
            }
            if (mechanism.Equals("MD5WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true));
            }
            if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2"))
            {
                return(new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true));
            }

            if (Platform.EndsWith(mechanism, "/X9.31"))
            {
                string x931    = mechanism.Substring(0, mechanism.Length - "/X9.31".Length);
                int    withPos = Platform.IndexOf(x931, "WITH");
                if (withPos > 0)
                {
                    int endPos = withPos + "WITH".Length;

                    string  digestName = x931.Substring(0, withPos);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);

                    string cipherName = x931.Substring(endPos, x931.Length - endPos);
                    if (cipherName.Equals("RSA"))
                    {
                        IAsymmetricBlockCipher cipher = new RsaBlindedEngine();
                        return(new X931Signer(cipher, digest));
                    }
                }
            }

            throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
        }
Exemplo n.º 26
0
        public static IBufferedCipher GetCipher(string algorithm)
        {
            //IL_0008: Unknown result type (might be due to invalid IL or missing references)
            //IL_0469: Unknown result type (might be due to invalid IL or missing references)
            //IL_0495: Unknown result type (might be due to invalid IL or missing references)
            //IL_07f1: Unknown result type (might be due to invalid IL or missing references)
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            algorithm = Platform.ToUpperInvariant(algorithm);
            string text = (string)algorithms.get_Item((object)algorithm);

            if (text != null)
            {
                algorithm = text;
            }
            IBasicAgreement basicAgreement = null;

            if (algorithm == "IES")
            {
                basicAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                basicAgreement = new ECDHBasicAgreement();
            }
            if (basicAgreement != null)
            {
                return(new BufferedIesCipher(new IesEngine(basicAgreement, new Kdf2BytesGenerator(new Sha1Digest()), new HMac(new Sha1Digest()))));
            }
            if (Platform.StartsWith(algorithm, "PBE"))
            {
                if (Platform.EndsWith(algorithm, "-CBC"))
                {
                    if (algorithm == "PBEWITHSHA1ANDDES-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new DesEngine())));
                    }
                    if (algorithm == "PBEWITHSHA1ANDRC2-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new RC2Engine())));
                    }
                    if (Strings.IsOneOf(algorithm, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new DesEdeEngine())));
                    }
                    if (Strings.IsOneOf(algorithm, "PBEWITHSHAAND128BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new RC2Engine())));
                    }
                }
                else if ((Platform.EndsWith(algorithm, "-BC") || Platform.EndsWith(algorithm, "-OPENSSL")) && Strings.IsOneOf(algorithm, "PBEWITHSHAAND128BITAES-CBC-BC", "PBEWITHSHAAND192BITAES-CBC-BC", "PBEWITHSHAAND256BITAES-CBC-BC", "PBEWITHSHA256AND128BITAES-CBC-BC", "PBEWITHSHA256AND192BITAES-CBC-BC", "PBEWITHSHA256AND256BITAES-CBC-BC", "PBEWITHMD5AND128BITAES-CBC-OPENSSL", "PBEWITHMD5AND192BITAES-CBC-OPENSSL", "PBEWITHMD5AND256BITAES-CBC-OPENSSL"))
                {
                    return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesFastEngine())));
                }
            }
            string[] array = algorithm.Split(new char[1] {
                '/'
            });
            IBlockCipher           blockCipher           = null;
            IAsymmetricBlockCipher asymmetricBlockCipher = null;
            IStreamCipher          streamCipher          = null;
            string text2 = array[0];
            string text3 = (string)algorithms.get_Item((object)text2);

            if (text3 != null)
            {
                text2 = text3;
            }
            CipherAlgorithm cipherAlgorithm;

            try
            {
                cipherAlgorithm = (CipherAlgorithm)Enums.GetEnumValue(typeof(CipherAlgorithm), text2);
            }
            catch (ArgumentException)
            {
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }
            switch (cipherAlgorithm)
            {
            case CipherAlgorithm.AES:
                blockCipher = new AesFastEngine();
                break;

            case CipherAlgorithm.ARC4:
                streamCipher = new RC4Engine();
                break;

            case CipherAlgorithm.BLOWFISH:
                blockCipher = new BlowfishEngine();
                break;

            case CipherAlgorithm.CAMELLIA:
                blockCipher = new CamelliaEngine();
                break;

            case CipherAlgorithm.CAST5:
                blockCipher = new Cast5Engine();
                break;

            case CipherAlgorithm.CAST6:
                blockCipher = new Cast6Engine();
                break;

            case CipherAlgorithm.DES:
                blockCipher = new DesEngine();
                break;

            case CipherAlgorithm.DESEDE:
                blockCipher = new DesEdeEngine();
                break;

            case CipherAlgorithm.ELGAMAL:
                asymmetricBlockCipher = new ElGamalEngine();
                break;

            case CipherAlgorithm.GOST28147:
                blockCipher = new Gost28147Engine();
                break;

            case CipherAlgorithm.HC128:
                streamCipher = new HC128Engine();
                break;

            case CipherAlgorithm.HC256:
                streamCipher = new HC256Engine();
                break;

            case CipherAlgorithm.IDEA:
                blockCipher = new IdeaEngine();
                break;

            case CipherAlgorithm.NOEKEON:
                blockCipher = new NoekeonEngine();
                break;

            case CipherAlgorithm.PBEWITHSHAAND128BITRC4:
            case CipherAlgorithm.PBEWITHSHAAND40BITRC4:
                streamCipher = new RC4Engine();
                break;

            case CipherAlgorithm.RC2:
                blockCipher = new RC2Engine();
                break;

            case CipherAlgorithm.RC5:
                blockCipher = new RC532Engine();
                break;

            case CipherAlgorithm.RC5_64:
                blockCipher = new RC564Engine();
                break;

            case CipherAlgorithm.RC6:
                blockCipher = new RC6Engine();
                break;

            case CipherAlgorithm.RIJNDAEL:
                blockCipher = new RijndaelEngine();
                break;

            case CipherAlgorithm.RSA:
                asymmetricBlockCipher = new RsaBlindedEngine();
                break;

            case CipherAlgorithm.SALSA20:
                streamCipher = new Salsa20Engine();
                break;

            case CipherAlgorithm.SEED:
                blockCipher = new SeedEngine();
                break;

            case CipherAlgorithm.SERPENT:
                blockCipher = new SerpentEngine();
                break;

            case CipherAlgorithm.SKIPJACK:
                blockCipher = new SkipjackEngine();
                break;

            case CipherAlgorithm.TEA:
                blockCipher = new TeaEngine();
                break;

            case CipherAlgorithm.THREEFISH_256:
                blockCipher = new ThreefishEngine(256);
                break;

            case CipherAlgorithm.THREEFISH_512:
                blockCipher = new ThreefishEngine(512);
                break;

            case CipherAlgorithm.THREEFISH_1024:
                blockCipher = new ThreefishEngine(1024);
                break;

            case CipherAlgorithm.TNEPRES:
                blockCipher = new TnepresEngine();
                break;

            case CipherAlgorithm.TWOFISH:
                blockCipher = new TwofishEngine();
                break;

            case CipherAlgorithm.VMPC:
                streamCipher = new VmpcEngine();
                break;

            case CipherAlgorithm.VMPC_KSA3:
                streamCipher = new VmpcKsa3Engine();
                break;

            case CipherAlgorithm.XTEA:
                blockCipher = new XteaEngine();
                break;

            default:
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }
            if (streamCipher != null)
            {
                if (array.Length > 1)
                {
                    throw new ArgumentException("Modes and paddings not used for stream ciphers");
                }
                return(new BufferedStreamCipher(streamCipher));
            }
            bool flag  = false;
            bool flag2 = true;
            IBlockCipherPadding blockCipherPadding = null;
            IAeadBlockCipher    aeadBlockCipher    = null;

            if (array.Length > 2)
            {
                if (streamCipher != null)
                {
                    throw new ArgumentException("Paddings not used for stream ciphers");
                }
                string        text4 = array[2];
                CipherPadding cipherPadding;
                if (text4 == "")
                {
                    cipherPadding = CipherPadding.RAW;
                }
                else if (text4 == "X9.23PADDING")
                {
                    cipherPadding = CipherPadding.X923PADDING;
                }
                else
                {
                    try
                    {
                        cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), text4);
                    }
                    catch (ArgumentException)
                    {
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }
                switch (cipherPadding)
                {
                case CipherPadding.NOPADDING:
                    flag2 = false;
                    break;

                case CipherPadding.ISO10126PADDING:
                case CipherPadding.ISO10126D2PADDING:
                case CipherPadding.ISO10126_2PADDING:
                    blockCipherPadding = new ISO10126d2Padding();
                    break;

                case CipherPadding.ISO7816_4PADDING:
                case CipherPadding.ISO9797_1PADDING:
                    blockCipherPadding = new ISO7816d4Padding();
                    break;

                case CipherPadding.ISO9796_1:
                case CipherPadding.ISO9796_1PADDING:
                    asymmetricBlockCipher = new ISO9796d1Encoding(asymmetricBlockCipher);
                    break;

                case CipherPadding.OAEP:
                case CipherPadding.OAEPPADDING:
                    asymmetricBlockCipher = new OaepEncoding(asymmetricBlockCipher);
                    break;

                case CipherPadding.OAEPWITHMD5ANDMGF1PADDING:
                    asymmetricBlockCipher = new OaepEncoding(asymmetricBlockCipher, new MD5Digest());
                    break;

                case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING:
                    asymmetricBlockCipher = new OaepEncoding(asymmetricBlockCipher, new Sha1Digest());
                    break;

                case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING:
                    asymmetricBlockCipher = new OaepEncoding(asymmetricBlockCipher, new Sha224Digest());
                    break;

                case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING:
                    asymmetricBlockCipher = new OaepEncoding(asymmetricBlockCipher, new Sha256Digest());
                    break;

                case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING:
                    asymmetricBlockCipher = new OaepEncoding(asymmetricBlockCipher, new Sha384Digest());
                    break;

                case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING:
                    asymmetricBlockCipher = new OaepEncoding(asymmetricBlockCipher, new Sha512Digest());
                    break;

                case CipherPadding.PKCS1:
                case CipherPadding.PKCS1PADDING:
                    asymmetricBlockCipher = new Pkcs1Encoding(asymmetricBlockCipher);
                    break;

                case CipherPadding.PKCS5:
                case CipherPadding.PKCS5PADDING:
                case CipherPadding.PKCS7:
                case CipherPadding.PKCS7PADDING:
                    blockCipherPadding = new Pkcs7Padding();
                    break;

                case CipherPadding.TBCPADDING:
                    blockCipherPadding = new TbcPadding();
                    break;

                case CipherPadding.WITHCTS:
                    flag = true;
                    break;

                case CipherPadding.X923PADDING:
                    blockCipherPadding = new X923Padding();
                    break;

                case CipherPadding.ZEROBYTEPADDING:
                    blockCipherPadding = new ZeroBytePadding();
                    break;

                default:
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");

                case CipherPadding.RAW:
                    break;
                }
            }
            string text5 = "";

            if (array.Length > 1)
            {
                text5 = array[1];
                int    digitIndex = GetDigitIndex(text5);
                string text6      = ((digitIndex >= 0) ? text5.Substring(0, digitIndex) : text5);
                try
                {
                    switch ((text6 == "") ? CipherMode.NONE : ((CipherMode)Enums.GetEnumValue(typeof(CipherMode), text6)))
                    {
                    case CipherMode.CBC:
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

                    case CipherMode.CCM:
                        aeadBlockCipher = new CcmBlockCipher(blockCipher);
                        break;

                    case CipherMode.CFB:
                    {
                        int bitBlockSize = ((digitIndex < 0) ? (8 * blockCipher.GetBlockSize()) : int.Parse(text5.Substring(digitIndex)));
                        blockCipher = new CfbBlockCipher(blockCipher, bitBlockSize);
                        break;
                    }

                    case CipherMode.CTR:
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;

                    case CipherMode.CTS:
                        flag        = true;
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

                    case CipherMode.EAX:
                        aeadBlockCipher = new EaxBlockCipher(blockCipher);
                        break;

                    case CipherMode.GCM:
                        aeadBlockCipher = new GcmBlockCipher(blockCipher);
                        break;

                    case CipherMode.GOFB:
                        blockCipher = new GOfbBlockCipher(blockCipher);
                        break;

                    case CipherMode.OCB:
                        aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
                        break;

                    case CipherMode.OFB:
                    {
                        int blockSize = ((digitIndex < 0) ? (8 * blockCipher.GetBlockSize()) : int.Parse(text5.Substring(digitIndex)));
                        blockCipher = new OfbBlockCipher(blockCipher, blockSize);
                        break;
                    }

                    case CipherMode.OPENPGPCFB:
                        blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
                        break;

                    case CipherMode.SIC:
                        if (blockCipher.GetBlockSize() < 16)
                        {
                            throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
                        }
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;

                    default:
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");

                    case CipherMode.ECB:
                    case CipherMode.NONE:
                        break;
                    }
                }
                catch (ArgumentException)
                {
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }
            if (aeadBlockCipher != null)
            {
                if (flag)
                {
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                }
                if (flag2 && array.Length > 2 && array[2] != "")
                {
                    throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");
                }
                return(new BufferedAeadBlockCipher(aeadBlockCipher));
            }
            if (blockCipher != null)
            {
                if (flag)
                {
                    return(new CtsBlockCipher(blockCipher));
                }
                if (blockCipherPadding != null)
                {
                    return(new PaddedBufferedBlockCipher(blockCipher, blockCipherPadding));
                }
                if (!flag2 || blockCipher.IsPartialBlockOkay)
                {
                    return(new BufferedBlockCipher(blockCipher));
                }
                return(new PaddedBufferedBlockCipher(blockCipher));
            }
            if (asymmetricBlockCipher != null)
            {
                return(new BufferedAsymmetricBlockCipher(asymmetricBlockCipher));
            }
            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }