/// <summary>Initialise the generator for signing.</summary>
		public void InitSign(
			int				sigType,
			PgpPrivateKey	key,
			SecureRandom	random)
		{
			this.privKey = key;
			this.signatureType = sigType;

			try
			{
				ICipherParameters cp = key.Key;
				if (random != null)
				{
					cp = new ParametersWithRandom(key.Key, random);
				}

				sig.Init(true, cp);
			}
			catch (InvalidKeyException e)
			{
				throw new PgpException("invalid key.", e);
			}

			dig.Reset();
			lastb = 0;
		}
Esempio n. 2
0
 /// <summary>Create a key pair from a PgpPrivateKey and a PgpPublicKey.</summary>
 /// <param name="pub">The public key.</param>
 /// <param name="priv">The private key.</param>
 public PgpKeyPair(
     PgpPublicKey pub,
     PgpPrivateKey priv)
 {
     this.pub  = pub;
     this.priv = priv;
 }
        /// <summary>Initialise the generator for signing.</summary>
        public void InitSign(
            int sigType,
            PgpPrivateKey key,
            SecureRandom random)
        {
            this.privKey       = key;
            this.signatureType = sigType;

            try
            {
                ICipherParameters cp = key.Key;
                if (random != null)
                {
                    cp = new ParametersWithRandom(key.Key, random);
                }

                sig.Init(true, cp);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("invalid key.", e);
            }

            dig.Reset();
            lastb = 0;
        }
		/// <summary>
		/// Return the algorithm code for the symmetric algorithm used to encrypt the data.
		/// </summary>
		public SymmetricKeyAlgorithmTag GetSymmetricAlgorithm(
			PgpPrivateKey privKey)
		{
			byte[] plain = fetchSymmetricKeyData(privKey);

			return (SymmetricKeyAlgorithmTag) plain[0];
		}
        /// <summary>
        /// Return the algorithm code for the symmetric algorithm used to encrypt the data.
        /// </summary>
        public SymmetricKeyAlgorithmTag GetSymmetricAlgorithm(
            PgpPrivateKey privKey)
        {
            byte[] plain = fetchSymmetricKeyData(privKey);

            return((SymmetricKeyAlgorithmTag)plain[0]);
        }
Esempio n. 6
0
		/// <summary>Create a key pair from a PgpPrivateKey and a PgpPublicKey.</summary>
		/// <param name="pub">The public key.</param>
		/// <param name="priv">The private key.</param>
        public PgpKeyPair(
            PgpPublicKey	pub,
            PgpPrivateKey	priv)
        {
            this.pub = pub;
            this.priv = priv;
        }
Esempio n. 7
0
 public PgpKeyPair(
     PublicKeyAlgorithmTag algorithm,
     AsymmetricKeyParameter pubKey,
     AsymmetricKeyParameter privKey,
     DateTime time)
 {
     this.pub  = new PgpPublicKey(algorithm, pubKey, time);
     this.priv = new PgpPrivateKey(privKey, pub.KeyId);
 }
Esempio n. 8
0
		public PgpKeyPair(
            PublicKeyAlgorithmTag	algorithm,
            AsymmetricKeyParameter	pubKey,
            AsymmetricKeyParameter	privKey,
            DateTime				time)
        {
            this.pub = new PgpPublicKey(algorithm, pubKey, time);
			this.priv = new PgpPrivateKey(privKey, pub.KeyId);
        }
Esempio n. 9
0
 internal PgpSecretKey(
     PgpPrivateKey privKey,
     PgpPublicKey pubKey,
     SymmetricKeyAlgorithmTag encAlgorithm,
     char[]                                          passPhrase,
     bool useSha1,
     SecureRandom rand)
     : this(privKey, pubKey, encAlgorithm, passPhrase, useSha1, rand, false)
 {
 }
Esempio n. 10
0
		internal PgpSecretKey(
			PgpPrivateKey				privKey,
			PgpPublicKey				pubKey,
			SymmetricKeyAlgorithmTag	encAlgorithm,
			char[]						passPhrase,
			bool						useSha1,
			SecureRandom				rand)
			: this(privKey, pubKey, encAlgorithm, passPhrase, useSha1, rand, false)
		{
		}
        /// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
            byte[] plain = fetchSymmetricKeyData(privKey);

            IBufferedCipher c2;
            string          cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag)plain[0]);
            string          cName      = cipherName;

            try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
                    cName += "/CFB/NoPadding";
                }
                else
                {
                    cName += "/OpenPGPCFB/NoPadding";
                }

                c2 = CipherUtilities.GetCipher(cName);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

            if (c2 == null)
            {
                return(encData.GetInputStream());
            }

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter(
                    cipherName, plain, 1, plain.Length - 3);

                byte[] iv = new byte[c2.GetBlockSize()];

                c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null));

                if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);

                    string  digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
                    IDigest digest     = DigestUtilities.GetDigest(digestName);

                    encStream = new DigestStream(truncStream, digest, null);
                }

                if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

                if (v1 < 0 || v2 < 0)
                {
                    throw new EndOfStreamException("unexpected end of stream.");
                }

                // Note: the oracle attack on the "quick check" bytes is deemed
                // a security risk for typical public key encryption usages,
                // therefore we do not perform the check.

//				bool repeatCheckPassed =
//					iv[iv.Length - 2] == (byte)v1
//					&&	iv[iv.Length - 1] == (byte)v2;
//
//				// Note: some versions of PGP appear to produce 0 for the extra
//				// bytes rather than repeating the two previous bytes
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

                return(encStream);
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
        }
        private byte[] fetchSymmetricKeyData(
            PgpPrivateKey privKey)
        {
            IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm);

            try
            {
                c1.Init(false, privKey.Key);
            }
            catch (InvalidKeyException e)
            {
                throw new PgpException("error setting asymmetric cipher", e);
            }

            BigInteger[] keyD = keyData.GetEncSessionKey();

            if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt ||
                keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral)
            {
                c1.ProcessBytes(keyD[0].ToByteArrayUnsigned());
            }
            else
            {
                ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key;
                int size = (k.Parameters.P.BitLength + 7) / 8;

                byte[] bi = keyD[0].ToByteArray();

                int diff = bi.Length - size;
                if (diff >= 0)
                {
                    c1.ProcessBytes(bi, diff, size);
                }
                else
                {
                    byte[] zeros = new byte[-diff];
                    c1.ProcessBytes(zeros);
                    c1.ProcessBytes(bi);
                }

                bi = keyD[1].ToByteArray();

                diff = bi.Length - size;
                if (diff >= 0)
                {
                    c1.ProcessBytes(bi, diff, size);
                }
                else
                {
                    byte[] zeros = new byte[-diff];
                    c1.ProcessBytes(zeros);
                    c1.ProcessBytes(bi);
                }
            }

            byte[] plain;
            try
            {
                plain = c1.DoFinal();
            }
            catch (Exception e)
            {
                throw new PgpException("exception decrypting secret key", e);
            }

            if (!ConfirmCheckSum(plain))
            {
                throw new PgpKeyValidationException("key checksum failed");
            }

            return(plain);
        }
		private byte[] fetchSymmetricKeyData(
			PgpPrivateKey privKey)
		{
			IBufferedCipher c1 = GetKeyCipher(keyData.Algorithm);

			try
			{
				c1.Init(false, privKey.Key);
			}
			catch (InvalidKeyException e)
			{
				throw new PgpException("error setting asymmetric cipher", e);
			}

			BigInteger[] keyD = keyData.GetEncSessionKey();

			if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt
				|| keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral)
			{
				c1.ProcessBytes(keyD[0].ToByteArrayUnsigned());
			}
			else
			{
				ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key;
				int size = (k.Parameters.P.BitLength + 7) / 8;

				byte[] bi = keyD[0].ToByteArray();

				int diff = bi.Length - size;
				if (diff >= 0)
				{
					c1.ProcessBytes(bi, diff, size);
				}
				else
				{
					byte[] zeros = new byte[-diff];
					c1.ProcessBytes(zeros);
					c1.ProcessBytes(bi);
				}

				bi = keyD[1].ToByteArray();

				diff = bi.Length - size;
				if (diff >= 0)
				{
					c1.ProcessBytes(bi, diff, size);
				}
				else
				{
					byte[] zeros = new byte[-diff];
					c1.ProcessBytes(zeros);
					c1.ProcessBytes(bi);
				}
			}

			byte[] plain;
			try
			{
				plain = c1.DoFinal();
			}
			catch (Exception e)
			{
				throw new PgpException("exception decrypting secret key", e);
			}

			if (!ConfirmCheckSum(plain))
				throw new PgpKeyValidationException("key checksum failed");

			return plain;
		}
		/// <summary>Return the decrypted data stream for the packet.</summary>
        public Stream GetDataStream(
            PgpPrivateKey privKey)
        {
			byte[] plain = fetchSymmetricKeyData(privKey);

			IBufferedCipher c2;
			string cipherName = PgpUtilities.GetSymmetricCipherName((SymmetricKeyAlgorithmTag) plain[0]);
			string cName = cipherName;

			try
            {
                if (encData is SymmetricEncIntegrityPacket)
                {
					cName += "/CFB/NoPadding";
                }
                else
                {
					cName += "/OpenPGPCFB/NoPadding";
                }

				c2 = CipherUtilities.GetCipher(cName);
			}
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("exception creating cipher", e);
            }

			if (c2 == null)
				return encData.GetInputStream();

			try
            {
				KeyParameter key = ParameterUtilities.CreateKeyParameter(
					cipherName, plain, 1, plain.Length - 3);

				byte[] iv = new byte[c2.GetBlockSize()];

				c2.Init(false, new ParametersWithIV(key, iv));

                encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c2, null));

				if (encData is SymmetricEncIntegrityPacket)
                {
                    truncStream = new TruncatedStream(encStream);

					string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1);
					IDigest digest = DigestUtilities.GetDigest(digestName);

					encStream = new DigestStream(truncStream, digest, null);
                }

				if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length)
					throw new EndOfStreamException("unexpected end of stream.");

				int v1 = encStream.ReadByte();
                int v2 = encStream.ReadByte();

				if (v1 < 0 || v2 < 0)
                    throw new EndOfStreamException("unexpected end of stream.");

				// Note: the oracle attack on the "quick check" bytes is deemed
				// a security risk for typical public key encryption usages,
				// therefore we do not perform the check.

//				bool repeatCheckPassed =
//					iv[iv.Length - 2] == (byte)v1
//					&&	iv[iv.Length - 1] == (byte)v2;
//
//				// Note: some versions of PGP appear to produce 0 for the extra
//				// bytes rather than repeating the two previous bytes
//				bool zeroesCheckPassed =
//					v1 == 0
//					&&	v2 == 0;
//
//				if (!repeatCheckPassed && !zeroesCheckPassed)
//				{
//					throw new PgpDataValidationException("quick check failed.");
//				}

				return encStream;
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception starting decryption", e);
            }
		}
		/// <summary>Initialise the generator for signing.</summary>
        public void InitSign(
            int				sigType,
            PgpPrivateKey	key)
        {
			InitSign(sigType, key, null);
        }
Esempio n. 16
0
        internal PgpSecretKey(
            PgpPrivateKey privKey,
            PgpPublicKey pubKey,
            SymmetricKeyAlgorithmTag encAlgorithm,
            char[]                                              passPhrase,
            bool useSha1,
            SecureRandom rand,
            bool isMasterKey)
        {
            BcpgObject secKey;

            this.pub = pubKey;

            switch (pubKey.Algorithm)
            {
            case PublicKeyAlgorithmTag.RsaEncrypt:
            case PublicKeyAlgorithmTag.RsaSign:
            case PublicKeyAlgorithmTag.RsaGeneral:
                RsaPrivateCrtKeyParameters rsK = (RsaPrivateCrtKeyParameters)privKey.Key;
                secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q);
                break;

            case PublicKeyAlgorithmTag.Dsa:
                DsaPrivateKeyParameters dsK = (DsaPrivateKeyParameters)privKey.Key;
                secKey = new DsaSecretBcpgKey(dsK.X);
                break;

            case PublicKeyAlgorithmTag.ElGamalEncrypt:
            case PublicKeyAlgorithmTag.ElGamalGeneral:
                ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters)privKey.Key;
                secKey = new ElGamalSecretBcpgKey(esK.X);
                break;

            default:
                throw new PgpException("unknown key class");
            }

            try
            {
                MemoryStream     bOut = new MemoryStream();
                BcpgOutputStream pOut = new BcpgOutputStream(bOut);

                pOut.WriteObject(secKey);

                byte[] keyData       = bOut.ToArray();
                byte[] checksumBytes = Checksum(useSha1, keyData, keyData.Length);

                pOut.Write(checksumBytes);

                byte[] bOutData = bOut.ToArray();

                if (encAlgorithm == SymmetricKeyAlgorithmTag.Null)
                {
                    if (isMasterKey)
                    {
                        this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, bOutData);
                    }
                    else
                    {
                        this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, bOutData);
                    }
                }
                else
                {
                    S2k    s2k;
                    byte[] iv;
                    byte[] encData = EncryptKeyData(bOutData, encAlgorithm, passPhrase, rand, out s2k, out iv);

                    int s2kUsage = useSha1
                                                ?       SecretKeyPacket.UsageSha1
                                                :       SecretKeyPacket.UsageChecksum;

                    if (isMasterKey)
                    {
                        this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData);
                    }
                    else
                    {
                        this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData);
                    }
                }
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception encrypting key", e);
            }
        }
 /// <summary>Initialise the generator for signing.</summary>
 public void InitSign(
     int sigType,
     PgpPrivateKey key)
 {
     InitSign(sigType, key, null);
 }
Esempio n. 18
0
		internal PgpSecretKey(
			PgpPrivateKey				privKey,
			PgpPublicKey				pubKey,
			SymmetricKeyAlgorithmTag	encAlgorithm,
            char[]						passPhrase,
			bool						useSha1,
			SecureRandom				rand,
			bool						isMasterKey)
        {
			BcpgObject secKey;

			this.pub = pubKey;

			switch (pubKey.Algorithm)
            {
				case PublicKeyAlgorithmTag.RsaEncrypt:
				case PublicKeyAlgorithmTag.RsaSign:
				case PublicKeyAlgorithmTag.RsaGeneral:
					RsaPrivateCrtKeyParameters rsK = (RsaPrivateCrtKeyParameters) privKey.Key;
					secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q);
					break;
				case PublicKeyAlgorithmTag.Dsa:
					DsaPrivateKeyParameters dsK = (DsaPrivateKeyParameters) privKey.Key;
					secKey = new DsaSecretBcpgKey(dsK.X);
					break;
				case PublicKeyAlgorithmTag.ElGamalEncrypt:
				case PublicKeyAlgorithmTag.ElGamalGeneral:
					ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters) privKey.Key;
					secKey = new ElGamalSecretBcpgKey(esK.X);
					break;
				default:
					throw new PgpException("unknown key class");
            }

			try
            {
                MemoryStream bOut = new MemoryStream();
                BcpgOutputStream pOut = new BcpgOutputStream(bOut);

				pOut.WriteObject(secKey);

				byte[] keyData = bOut.ToArray();
				byte[] checksumBytes = Checksum(useSha1, keyData, keyData.Length);

				pOut.Write(checksumBytes);

				byte[] bOutData = bOut.ToArray();

				if (encAlgorithm == SymmetricKeyAlgorithmTag.Null)
				{
					if (isMasterKey)
					{
						this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, bOutData);
					}
					else
					{
						this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, bOutData);
					}
				}
				else
                {
					S2k s2k;
					byte[] iv;
					byte[] encData = EncryptKeyData(bOutData, encAlgorithm, passPhrase, rand, out s2k, out iv);

					int s2kUsage = useSha1
						?	SecretKeyPacket.UsageSha1
						:	SecretKeyPacket.UsageChecksum;

					if (isMasterKey)
					{
						this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData);
					}
					else
					{
						this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData);
					}
				}
            }
            catch (PgpException e)
            {
                throw e;
            }
            catch (Exception e)
            {
                throw new PgpException("Exception encrypting key", e);
            }
        }