Inheritance: IAsymmetricBlockCipher
コード例 #1
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;
		}
コード例 #2
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 (algorithm.StartsWith("PBE"))
            {
                if (algorithm.EndsWith("-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 (algorithm.EndsWith("-BC") || algorithm.EndsWith("-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.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.");
        }
コード例 #3
0
        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":
                        padding = new Pkcs7Padding();
                        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 > 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.");
        }
コード例 #4
0
ファイル: ISO9796Test.cs プロジェクト: KimikoMuffin/bc-csharp
        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");
            }
        }
コード例 #5
0
ファイル: ISO9796Test.cs プロジェクト: KimikoMuffin/bc-csharp
        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.");
            }
        }
コード例 #6
0
ファイル: SignerUtilities.cs プロジェクト: ubberkid/PeerATT
        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 (mechanism.EndsWith("/X9.31"))
            {
                string x931 = mechanism.Substring(0, mechanism.Length - "/X9.31".Length);
                int withPos = x931.IndexOf("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.");
        }
コード例 #7
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
			}
		}
コード例 #8
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);
				}
			}
		}
コード例 #9
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);
        }
コード例 #10
0
ファイル: TlsProtocolHandler.cs プロジェクト: pusp/o2platform
		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:
											case TlsCipherSuite.KE_SRP_RSA:
												if (!(this.serverPublicKey is RsaKeyParameters))
												{
													this.FailWithError(AL_fatal, AP_certificate_unknown);
												}
												validateKeyUsage(x509Cert, KeyUsage.DigitalSignature);
												break;
											case TlsCipherSuite.KE_DHE_DSS:
											case TlsCipherSuite.KE_SRP_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
										*/
										byte[] sessionId = TlsUtilities.ReadOpaque8(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);
										}

	                                    /*
	                                     * RFC4366 2.2
	                                     * The extended server hello message format MAY be sent
	                                     * in place of the server hello message when the client
	                                     * has requested extended functionality via the extended
	                                     * client hello message specified in Section 2.1.
	                                     */
	                                    if (extendedClientHello && inStr.Position < inStr.Length)
	                                    {
	                                        // Process extensions from extended server hello
	                                        byte[] extBytes = TlsUtilities.ReadOpaque16(inStr);
	
	                                        // Int32 -> byte[]
	                                        Hashtable serverExtensions = new Hashtable();

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

	                                            serverExtensions[extType] = extValue;
	                                        }

	                                        // TODO Validate/process serverExtensions (via client?)
	                                        // TODO[SRP]
	                                    }

										/*
										* Process any extensions
										*/
										// TODO[SRP]
//										if (inStr.Position < inStr.Length)
//										{
//											int extensionsLength = TlsUtilities.ReadUint16(inStr);
//											byte[] extensions = new byte[extensionsLength];
//											TlsUtilities.ReadFully(extensions, inStr);
//
//											// TODO Validate/process
//										}

										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;
											}
											case TlsCipherSuite.KE_SRP:
											case TlsCipherSuite.KE_SRP_RSA:
											case TlsCipherSuite.KE_SRP_DSS:
											{
												/*
												* Send the Client Key Exchange message for
												* SRP key exchange.
												*/
												byte[] bytes = BigIntegers.AsUnsignedByteArray(this.SRP_A);

												sendClientKeyExchange(bytes);

												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_HELLO_RECEIVED:
									case CS_SERVER_CERTIFICATE_RECEIVED:
									{
										// NB: Original code used case label fall-through
										if (connection_state == CS_SERVER_HELLO_RECEIVED)
										{
											/*
											* There was no server certificate message, check
											* that we are doing SRP key exchange.
											*/
											if (this.chosenCipherSuite.KeyExchangeAlgorithm != TlsCipherSuite.KE_SRP)
											{
												this.FailWithError(AL_fatal, AP_unexpected_message);
											}
										}

										/*
										* 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;
											}
											case TlsCipherSuite.KE_SRP:
											{
												processSRPKeyExchange(inStr, null);
												break;
											}
											case TlsCipherSuite.KE_SRP_RSA:
											{
												processSRPKeyExchange(inStr, new TlsRsaSigner());
												break;
											}
											case TlsCipherSuite.KE_SRP_DSS:
											{
												processSRPKeyExchange(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);
											}
										}

										byte[] types = TlsUtilities.ReadOpaque8(inStr);
										byte[] auths = TlsUtilities.ReadOpaque8(inStr);

										// TODO Validate/process

										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);
		}
コード例 #11
0
ファイル: AWiz.cs プロジェクト: burstas/rmps
 private void CreateAcryptoEngine()
 {
     IAsymmetricBlockCipher engine;
     switch (_MSec.Algorithm)
     {
         case ESec.ACRYPTO_ELGAMAL:
             engine = new ElGamalEngine();
             break;
         case ESec.ACRYPTO_NACCACHESTERN:
             engine = new NaccacheSternEngine();
             break;
         case ESec.ACRYPTO_RSABLINDED:
             engine = new RsaBlindedEngine();
             break;
         case ESec.ACRYPTO_RSABLINDING:
             engine = new RsaBlindingEngine();
             break;
         case ESec.ACRYPTO_RSA:
             engine = new RsaEngine();
             break;
     }
 }