Often a PGP key ring file is made up of a succession of master/sub-key key rings. If you want to read an entire secret key file in one hit this is the class for you.
Exemple #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PgpDecrypter" /> class.
        /// </summary>
        /// <param name="secretKeyRingBundle">The secret key ring.</param>
        /// <param name="passPhraseChars">The pass phrase chars.</param>
        /// <exception cref="System.ArgumentNullException">secretKeyRingBundle</exception>
        public PgpDecrypter(PgpSecretKeyRingBundle secretKeyRingBundle, char[] passPhraseChars)
        {
            if (secretKeyRingBundle == null) throw new ArgumentNullException("secretKeyRingBundle");
            if (passPhraseChars == null) throw new ArgumentNullException("passPhraseChars");

            _secretKeyRingBundle = secretKeyRingBundle;
            _passPhraseChars = passPhraseChars;
        }
        //private static string Password = ConfigurationManager.AppSettings["Password"];
        //public static string PublicKey = ConfigurationManager.AppSettings["PublicKey"];
        //public static string PublicKeyPath = IoHelper.BasePath + @"\" + PublicKey;
        //// note: this should be changed if the private key is not located in the current executables path
        //private static string PrivateKeyOnly = ConfigurationManager.AppSettings["PrivateKeyOnly"];
        //private static string PrivateKeyOnlyPath = IoHelper.BasePath + @"\" + PrivateKeyOnly;

        // The majority of the functionality encrypting/decrypting came from this answer: http://stackoverflow.com/a/10210465

        private static PgpPrivateKey FindSecretKey(PgpSecretKeyRingBundle pgpSec, long keyId, char[] pass)
        {
            PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyId);
            if (pgpSecKey == null)
            {
                return null;
            }

            return pgpSecKey.ExtractPrivateKey(pass);
        }
 /// <summary>
 /// Return the first key we can use to encrypt.
 /// Note: A file can contain multiple keys (stored in "key rings")
 /// </summary>
 private PgpSecretKey GetFirstSecretKey(PgpSecretKeyRingBundle secretKeyRingBundle)
 {
     foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings())
     {
         PgpSecretKey key = kRing.GetSecretKeys()
             .Cast<PgpSecretKey>()
             .Where(k => k.IsSigningKey)
             .FirstOrDefault();
         if (key != null)
             return key;
     }
     return null;
 }
 private PgpSecretKey ReadSecretKey(string privateKeyPath)
 {
     using (Stream keyIn = File.OpenRead(privateKeyPath))
     {
         using (Stream inputStream = PgpUtilities.GetDecoderStream(keyIn))
         {
             PgpSecretKeyRingBundle secretKeyRingBundle = new PgpSecretKeyRingBundle(inputStream);
             PgpSecretKey foundKey = GetFirstSecretKey(secretKeyRingBundle);
             if (foundKey != null)
                 return foundKey;
         }
     }
     throw new ArgumentException("Can't find signing key in key ring.");
 }
        public static PgpSecretKeyRingBundle RemoveSecretKeyRing(PgpSecretKeyRingBundle bundle, PgpSecretKeyRing secretKeyRing)
        {
            //IL_0024: Unknown result type (might be due to invalid IL or missing references)
            long keyId = secretKeyRing.GetPublicKey().KeyId;

            if (!bundle.secretRings.Contains((object)keyId))
            {
                throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring.");
            }
            IDictionary val = Platform.CreateHashtable(bundle.secretRings);

            global::System.Collections.IList list = Platform.CreateArrayList((global::System.Collections.ICollection)bundle.order);
            val.Remove((object)keyId);
            list.Remove((object)keyId);
            return(new PgpSecretKeyRingBundle(val, list));
        }
        /// <summary>
        /// Return a new bundle containing the contents of the passed in bundle with
        /// the passed in secret key ring removed.
        /// </summary>
        /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be removed from.</param>
        /// <param name="secretKeyRing">The key ring to be removed.</param>
        /// <returns>A new <c>PgpSecretKeyRingBundle</c> not containing the passed in key ring.</returns>
        /// <exception cref="ArgumentException">If the keyId for the passed in key ring is not present.</exception>
        public static PgpSecretKeyRingBundle RemoveSecretKeyRing(PgpSecretKeyRingBundle bundle, PgpSecretKeyRing secretKeyRing)
        {
            var key = secretKeyRing.GetPublicKey().KeyId;

            if (!bundle._secretRings.Contains(key))
            {
                throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring.");
            }

            var newSecretRings = Platform.CreateHashtable(bundle._secretRings);
            var newOrder       = Platform.CreateArrayList(bundle._order);

            newSecretRings.Remove(key);
            newOrder.Remove(key);

            return(new PgpSecretKeyRingBundle(newSecretRings, newOrder));
        }
        private static PgpSecretKey ReadSecretKey(Stream inputStream)
        {
            var decodedInputStream = PgpUtilities.GetDecoderStream(inputStream);
            var secretKeyRingBundle = new PgpSecretKeyRingBundle(decodedInputStream);

            // we just loop through the collection till we find a key suitable for encryption, in the real
            // world you would probably want to be a bit smarter about this.
            foreach (PgpSecretKeyRing keyRing in secretKeyRingBundle.GetKeyRings())
            {
                foreach (PgpSecretKey key in keyRing.GetSecretKeys())
                {
                    if (key.IsSigningKey)
                        return key;
                }
            }

            throw new ArgumentException("Can't find signing key in key ring.");
        }
Exemple #8
0
        /// <summary>
        /// Return a new bundle containing the contents of the passed in bundle and
        /// the passed in secret key ring.
        /// </summary>
        /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be added to.</param>
        /// <param name="secretKeyRing">The key ring to be added.</param>
        /// <returns>A new <c>PgpSecretKeyRingBundle</c> merging the current one with the passed in key ring.</returns>
        /// <exception cref="ArgumentException">If the keyId for the passed in key ring is already present.</exception>
        public static PgpSecretKeyRingBundle AddSecretKeyRing(
            PgpSecretKeyRingBundle bundle,
            PgpSecretKeyRing secretKeyRing)
        {
            long key = secretKeyRing.GetPublicKey().KeyId;

            if (bundle.secretRings.Contains(key))
            {
                throw new ArgumentException("Collection already contains a key with a keyId for the passed in ring.");
            }

            IDictionary newSecretRings = Platform.CreateHashtable(bundle.secretRings);
            IList       newOrder       = Platform.CreateArrayList(bundle.order);

            newSecretRings[key] = secretKeyRing;
            newOrder.Add(key);

            return(new PgpSecretKeyRingBundle(newSecretRings, newOrder));
        }
        /// <summary>
        /// Return a new bundle containing the contents of the passed in bundle with
        /// the passed in secret key ring removed.
        /// </summary>
        /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be removed from.</param>
        /// <param name="secretKeyRing">The key ring to be removed.</param>
        /// <returns>A new <c>PgpSecretKeyRingBundle</c> not containing the passed in key ring.</returns>
        /// <exception cref="ArgumentException">If the keyId for the passed in key ring is not present.</exception>
        public static PgpSecretKeyRingBundle RemoveSecretKeyRing(
            PgpSecretKeyRingBundle bundle,
            PgpSecretKeyRing secretKeyRing)
        {
            long key = secretKeyRing.GetPublicKey().KeyId;

            if (!bundle.secretRings.Contains(key))
            {
                throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring.");
            }

            IDictionary newSecretRings = new Hashtable(bundle.secretRings);
            ArrayList   newOrder       = new ArrayList(bundle.order);

            newSecretRings.Remove(key);
            newOrder.Remove(key);

            return(new PgpSecretKeyRingBundle(newSecretRings, newOrder));
        }
Exemple #10
0
        private static Tuple <PgpPublicKeyEncryptedData, PgpObjectFactory> Decrypt(PgpEncryptedDataList pgpEncryptedDatalist, Stream privateKeyStream, string praKeyPwd)
        {
            var pkstream = Org.BouncyCastle.Bcpg.OpenPgp.PgpUtilities.GetDecoderStream(privateKeyStream);
            var bundle   = new Org.BouncyCastle.Bcpg.OpenPgp.PgpSecretKeyRingBundle(pkstream);

            foreach (PgpPublicKeyEncryptedData encryptedData in pgpEncryptedDatalist.GetEncryptedDataObjects())
            {
                var privateKey = bundle.GetSecretKey(encryptedData.KeyId)?.ExtractPrivateKey(praKeyPwd.ToCharArray());
                if (privateKey == null)
                {
                    continue;
                }
                using (var tmp = encryptedData.GetDataStream(privateKey))
                {
                    return(Tuple.Create(encryptedData, new PgpObjectFactory(tmp)));
                }
            }
            throw new ArgumentException("未能正常读取到加密文件内容,请检查文件及密钥");
        }
        public static bool ValidatePassPhrase(byte[] privateKey, string passPhrase) {
            using (MemoryStream privateKeyStream = new MemoryStream(privateKey))
            {
                PgpSecretKeyRingBundle pgpKeyRing = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));
                var items = pgpKeyRing.GetKeyRings();
                foreach (var item in items)
                {
                    try {
                        var i = (PgpSecretKeyRing) item;
                        var key = i.GetSecretKey().ExtractPrivateKey(passPhrase.ToCharArray());
                        return true;
					} catch (Exception ex){
						Insights.Report(ex);
                        return false;
                    }
                }
            }

            return true;
        }
        /// <summary>
        /// Return a new bundle containing the contents of the passed in bundle and
        /// the passed in secret key ring.
        /// </summary>
        /// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be added to.</param>
        /// <param name="secretKeyRing">The key ring to be added.</param>
        /// <returns>A new <c>PgpSecretKeyRingBundle</c> merging the current one with the passed in key ring.</returns>
        /// <exception cref="ArgumentException">If the keyId for the passed in key ring is already present.</exception>
        public static PgpSecretKeyRingBundle AddSecretKeyRing(
            PgpSecretKeyRingBundle  bundle,
            PgpSecretKeyRing        secretKeyRing)
        {
            long key = secretKeyRing.GetPublicKey().KeyId;

            if (bundle.secretRings.Contains(key))
            {
                throw new ArgumentException("Collection already contains a key with a keyId for the passed in ring.");
            }

            IDictionary newSecretRings = new Hashtable(bundle.secretRings);
            ArrayList newOrder = new ArrayList(bundle.order);

            newSecretRings[key] = secretKeyRing;
            newOrder.Add(key);

            return new PgpSecretKeyRingBundle(newSecretRings, newOrder);
        }
        public PgpSecretKey GetSecretKey(long Id)
        {
            using (var inputStream = File.OpenRead(Context.PrivateKeyRingFile))
            {
                using (var decoderStream = PgpUtilities.GetDecoderStream(inputStream))
                {
                    var pgpPub = new PgpSecretKeyRingBundle(decoderStream);

                    foreach (PgpSecretKeyRing kRing in pgpPub.GetKeyRings())
                    {
                        foreach (PgpSecretKey k in kRing.GetSecretKeys())
                        {
                            if (k.KeyId == Id)
                                return k;
                        }
                    }

                    return null;
                }
            }
        }
    public static Stream PgpDecrypt(this Stream encryptedData, string armoredPrivateKey, string privateKeyPassword, Encoding armorEncoding = null)
    {
        var stream = PgpUtilities.GetDecoderStream(encryptedData);
        var layeredStreams = new List<Stream> { stream }; //this is to clean up/ dispose of any layered streams.
        var dataObjectFactory = new PgpObjectFactory(stream);
        var dataObject = dataObjectFactory.NextPgpObject();
        Dictionary<long, PgpSecretKey> secretKeys;

        using (var privateKeyStream = armoredPrivateKey.Streamify(armorEncoding ?? Encoding.UTF8))
        using (var decoderStream = PgpUtilities.GetDecoderStream(privateKeyStream))
        {
            secretKeys =
                new PgpSecretKeyRingBundle(decoderStream)
                .GetKeyRings()
                .OfType<PgpSecretKeyRing>()
                .SelectMany(x => x.GetSecretKeys().OfType<PgpSecretKey>())
                .ToDictionary(key => key.KeyId, value => value);

            if (!secretKeys.Any()) throw new ArgumentException("No secret keys found.");
        }

        while (!(dataObject is PgpLiteralData) && dataObject != null)
        {
            try
            {
                var compressedData = dataObject as PgpCompressedData;

                var listedData = dataObject as PgpEncryptedDataList;

                //strip away the compression stream
                if (compressedData != null)
                {
                    stream = compressedData.GetDataStream();

                    layeredStreams.Add(stream);

                    dataObjectFactory = new PgpObjectFactory(stream);
                }

                //strip the PgpEncryptedDataList
                if (listedData != null)
                {
                    var encryptedDataList =
                        listedData.
                        GetEncryptedDataObjects()
                        .OfType<PgpPublicKeyEncryptedData>()
                        .First();

                    var decryptionKey =
                        secretKeys[encryptedDataList.KeyId]
                        .ExtractPrivateKey(privateKeyPassword.ToCharArray());

                    stream = encryptedDataList.GetDataStream(decryptionKey);

                    layeredStreams.Add(stream);

                    dataObjectFactory = new PgpObjectFactory(stream);
                }

                dataObject = dataObjectFactory.NextPgpObject();
            }
            catch (Exception ex)
            {
                //Log exception here.
                throw new PgpException("Failed to strip encapsulating streams.", ex);
            }
        }

        foreach (var layeredStream in layeredStreams)
        {
            layeredStream.Close();
            layeredStream.Dispose();
        }

        if (dataObject == null) return null;

        return (dataObject as PgpLiteralData).GetInputStream();
    }
Exemple #15
0
		        /**
        * decrypt the passed in message stream
        */
        private static void DecryptFile(
            Stream	inputStream,
            Stream	keyIn,
			char[]	passwd,
			string	pathToDecryptedFile)		//DC 
		{
			try
			{
	            inputStream = PgpUtilities.GetDecoderStream(inputStream);
	
	            try
	            {
	                PgpObjectFactory pgpF = new PgpObjectFactory(inputStream);
	                PgpEncryptedDataList enc;
	
	                PgpObject o = pgpF.NextPgpObject();
	                //
	                // the first object might be a PGP marker packet.
	                //
	                
	                if (o is PgpEncryptedDataList)
	                {
	                    enc = (PgpEncryptedDataList)o;
	                }
	                else
	                {
	                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
	                }
	
	                //
	                // find the secret key
	                //
	                PgpPrivateKey sKey = null;
	                PgpPublicKeyEncryptedData pbe = null;
					PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
						PgpUtilities.GetDecoderStream(keyIn));
	
					foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
	                {
	                    sKey = OpenPgp_HelperMethods.FindSecretKey(pgpSec, pked.KeyId, passwd);
	
	                    if (sKey != null)
	                    {
	                        pbe = pked;
	                        break;
	                    }
	                }
	
					if (sKey == null)
	                {
	                    throw new ArgumentException("secret key for message not found.");
	                }
	
	                Stream clear = pbe.GetDataStream(sKey);
	
	                PgpObjectFactory plainFact = new PgpObjectFactory(clear);
	
	                PgpObject message = plainFact.NextPgpObject();
					
					PgpObjectFactory pgpFact = null;
					
	                if (message is PgpCompressedData)
	                {
	                    PgpCompressedData cData = (PgpCompressedData)message;
	                    pgpFact = new PgpObjectFactory(cData.GetDataStream());
	
	                    message = pgpFact.NextPgpObject();
	                }
					
					if (message is PgpOnePassSignatureList)		// DC
					{											// DC
						message = pgpFact.NextPgpObject();		// DC
					}											// DC
					
	                if (message is PgpLiteralData)
	                {	                	
	                    PgpLiteralData ld = (PgpLiteralData)message;
							
						Stream fOut = File.Create(pathToDecryptedFile);		//DC (modified to use the name provided in pathToDecryptedFile
						Stream unc = ld.GetInputStream();
						Streams.PipeAll(unc, fOut);						
						fOut.Close();
	                }
	                else if (message is PgpOnePassSignatureList)
	                {
	                    "[API_OpenPgp][DecryptFile] encrypted message contains a signed message - not literal data.".error();	                  
	                    return ;	                    
	                }
	                else
	                {
	                    "[API_OpenPgp][DecryptFile] message is not a simple encrypted file - type unknown.".error();
	                    return;
	                }
	
	                if (pbe.IsIntegrityProtected())
	                {
	                    if (!pbe.Verify())
	                    {
	                        "[API_OpenPgp][DecryptFile] message failed integrity check".error();
	                    }
	                    else
	                    {
	                        "[API_OpenPgp][DecryptFile] message integrity check passed".debug();
	                    }
	                }
	                else
	                {
	                    "[API_OpenPgp][DecryptFile] no message integrity check".error();
	                }
	            }
	            catch (PgpException e)
	            {
	            	e.log("[API_OpenPgp] in DecryptFile: " + e.StackTrace );
	            	
	                /*Console.Error.WriteLine(e);
	
	                Exception underlyingException = e.InnerException;
	                if (underlyingException != null)
	                {
	                    Console.Error.WriteLine(underlyingException.Message);
	                    Console.Error.WriteLine(underlyingException.StackTrace);
	                }*/
	            }
			}
			catch (Exception ex)
			{
				ex.log("[API_OpenPgp] in DecryptFile  : " + ex.StackTrace );
			}
        }
Exemple #16
0
		public static PgpSecretKey ReadSecretKey(
            Stream inputStream)
        {
            inputStream = PgpUtilities.GetDecoderStream(inputStream);

            PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(inputStream);

			//
            // we just loop through the collection till we find a key suitable for encryption, in the real
            // world you would probably want to be a bit smarter about this.
            //

			foreach (PgpSecretKeyRing kRing in pgpSec.GetKeyRings())
            {
                foreach (PgpSecretKey k in kRing.GetSecretKeys())
                {
                    if (k.IsSigningKey)
                    {
                        return k;
                    }
                }
            }

			throw new ArgumentException("Can't find signing key in key ring.");
        }
        public PgpSecretKey GetSecretKeyForSigning(string email)
        {
            using (var inputStream = File.OpenRead(Context.PrivateKeyRingFile))
            {
                using (var decoderStream = PgpUtilities.GetDecoderStream(inputStream))
                {
                    var pgpPub = new PgpSecretKeyRingBundle(decoderStream);
                    var emailSearch = "<" + email.ToLower().Trim() + ">";

                    foreach (PgpSecretKeyRing kRing in pgpPub.GetKeyRings())
                    {
                        foreach (PgpSecretKey k in kRing.GetSecretKeys())
                        {
                            if (!IsSigningKey(k.PublicKey))
                                continue;

                            if (!k.IsMasterKey)
                            {
                                foreach (PgpSignature sig in k.PublicKey.GetSignaturesOfType(24))
                                {
                                    var pubKey = this.GetPublicKey(sig.KeyId);
                                    if (!pubKey.IsMasterKey)
                                        continue;

                                    foreach (string id in pubKey.GetUserIds())
                                    {
                                        if (id.ToLower().IndexOf(emailSearch) > -1)
                                            return k;
                                    }
                                }
                            }

                            foreach (string id in k.PublicKey.GetUserIds())
                            {
                                if (id.ToLower().IndexOf(emailSearch) > -1)
                                    return k;
                            }
                        }
                    }

                    return null;
                }
            }
        }
Exemple #18
0
 public PgpSecretKey LoadSecKey(string path)
 {
     using (Stream keyIn = File.OpenRead(path)) {
         Stream decStream = PgpUtilities.GetDecoderStream (keyIn);
         PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle (decStream);
         foreach (PgpSecretKeyRing keyRing in pgpSec.GetKeyRings()) {
             foreach (PgpSecretKey key in keyRing.GetSecretKeys()) {
                 if (key.IsSigningKey) {
                     return key;
                 }
             }
         }
         throw new ArgumentException ("Can't find signing key in key ring.");
     }
 }
        public string[] GetSecretKeyUserIds()
        {
            using (var inputStream = File.OpenRead(Context.PrivateKeyRingFile))
            {
                using (var decoderStream = PgpUtilities.GetDecoderStream(inputStream))
                {
                    var pgpPub = new PgpSecretKeyRingBundle(decoderStream);
                    var keyUserIds = new List<string>();

                    foreach (PgpSecretKeyRing kRing in pgpPub.GetKeyRings())
                    {
                        foreach (PgpSecretKey k in kRing.GetSecretKeys())
                        {
                            if (!k.IsMasterKey)
                            {
                                foreach (PgpSignature sig in k.PublicKey.GetSignaturesOfType(24))
                                {
                                    var pubKey = this.GetPublicKey(sig.KeyId);
                                    if (!pubKey.IsMasterKey)
                                        continue;

                                    foreach (string id in pubKey.GetUserIds())
                                    {
                                        if (!keyUserIds.Contains(id))
                                            keyUserIds.Add(id);
                                    }
                                }
                            }

                            foreach (string id in k.PublicKey.GetUserIds())
                            {
                                if(!keyUserIds.Contains(id))
                                    keyUserIds.Add(id);
                            }
                        }
                    }

                    return keyUserIds.ToArray();
                }
            }
        }
Exemple #20
0
    /// <summary>
    /// Decrypt a PGP message (i.e. "-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----")
    /// using the supplied private key.
    /// </summary>
    /// <param name="armoredCipher">PGP message to decrypt</param>
    /// <param name="armoredPrivateKey">PGP private key</param>
    /// <param name="keyPassword">PGP private key password or null if none</param>
    /// <returns>decrypted plain text</returns>
    public static string PGPDecrypt(string armoredCipher, string armoredPrivateKey, string keyPassword)
    {
      // decode the private key
      PgpPrivateKey privateKey = null;
      using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(armoredPrivateKey)))
      {
        using (Stream dis = PgpUtilities.GetDecoderStream(ms))
        {
          PgpSecretKeyRingBundle bundle = new PgpSecretKeyRingBundle(dis);
          foreach (PgpSecretKeyRing keyring in bundle.GetKeyRings())
          {
            foreach (PgpSecretKey key in keyring.GetSecretKeys())
            {
              privateKey = key.ExtractPrivateKey(keyPassword != null ? keyPassword.ToCharArray() : null);
              break;
            }
          }
        }
      }

      // decrypt armored block using our private key
      byte[] cipher = Encoding.ASCII.GetBytes(armoredCipher);
      using (MemoryStream decryptedStream = new MemoryStream())
      {
        using (MemoryStream inputStream = new MemoryStream(cipher))
        {
          using (ArmoredInputStream ais = new ArmoredInputStream(inputStream))
          {
            PgpObject message = new PgpObjectFactory(ais).NextPgpObject();
            if (message is PgpEncryptedDataList)
            {
              foreach (PgpPublicKeyEncryptedData pked in ((PgpEncryptedDataList)message).GetEncryptedDataObjects())
              {
                message = new PgpObjectFactory(pked.GetDataStream(privateKey)).NextPgpObject();
              }
            }
            if (message is PgpCompressedData)
            {
              message = new PgpObjectFactory(((PgpCompressedData)message).GetDataStream()).NextPgpObject();
            }
            if (message is PgpLiteralData)
            {
              byte[] buffer = new byte[4096];
              using (Stream stream = ((PgpLiteralData)message).GetInputStream())
              {
                int read;
                while ((read = stream.Read(buffer, 0, 4096)) > 0)
                {
                  decryptedStream.Write(buffer, 0, read);
                }
              }
            }

            return Encoding.UTF8.GetString(decryptedStream.ToArray());
          }
        }
      }
		}
        private static PgpPrivateKey FindSecretKey(
            Stream keyIn,
            long keyId,
            char[] pass)
        {
            PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
                PgpUtilities.GetDecoderStream(keyIn));

            PgpSecretKey pgpSecKey = pgpSec.GetSecretKey(keyId);

            if (pgpSecKey == null)
            {
                return null;
            }

            return pgpSecKey.ExtractPrivateKey(pass);
        }
        /// <summary>
        /// Return the first key we can use to encrypt.
        /// Note: A file can contain multiple keys (stored in "key rings")
        /// </summary>
        private PgpSecretKey getFirstSecretKey(PgpSecretKeyRingBundle secretKeyRingBundle)
        {
            foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings())
            {
                // Note: You may need to use something other than the first key
                //  in your key ring. Keep that in mind.
                // ex: .Where(k => !k.IsSigningKey)
                PgpSecretKey key = kRing.GetSecretKeys()
                    .Cast<PgpSecretKey>()
                    //.Where(k => k.IsSigningKey)
                    .Where(k => !k.IsSigningKey)
                    .FirstOrDefault();

                if (key != null)
                {
                    return key;
                }
            }

            return null;
        }
		/// <summary>
		/// Imports secret pgp keys from the specified stream.
		/// </summary>
		/// <remarks>
		/// Imports secret pgp keys from the specified stream.
		/// </remarks>
		/// <param name="rawData">The raw key data.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="rawData"/> is <c>null</c>.
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// <para>An error occurred while parsing the raw key-ring data</para>
		/// <para>-or-</para>
		/// <para>An error occured while saving the public key-ring bundle.</para>
		/// </exception>
		public virtual void ImportSecretKeys (Stream rawData)
		{
			if (rawData == null)
				throw new ArgumentNullException ("rawData");

			using (var armored = new ArmoredInputStream (rawData)) {
				var imported = new PgpSecretKeyRingBundle (armored);
				if (imported.Count == 0)
					return;

				int secretKeysAdded = 0;

				foreach (PgpSecretKeyRing secring in imported.GetKeyRings ()) {
					if (!SecretKeyRingBundle.Contains (secring.GetSecretKey ().KeyId)) {
						SecretKeyRingBundle = PgpSecretKeyRingBundle.AddSecretKeyRing (SecretKeyRingBundle, secring);
						secretKeysAdded++;
					}
				}

				if (secretKeysAdded > 0)
					SaveSecretKeyRingBundle ();
			}
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.OpenPgpContext"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="OpenPgpContext"/> using the specified public and private keyring paths.
		/// </remarks>
		/// <param name="pubring">The public keyring file path.</param>
		/// <param name="secring">The secret keyring file path.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="pubring"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="secring"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An error occurred while reading one of the keyring files.
		/// </exception>
		/// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException">
		/// An error occurred while parsing one of the keyring files.
		/// </exception>
		protected OpenPgpContext (string pubring, string secring)
		{
			if (pubring == null)
				throw new ArgumentNullException ("pubring");

			if (secring == null)
				throw new ArgumentNullException ("secring");

			PublicKeyRingPath = pubring;
			SecretKeyRingPath = secring;

			if (File.Exists (pubring)) {
				using (var file = File.OpenRead (pubring)) {
					PublicKeyRingBundle = new PgpPublicKeyRingBundle (file);
				}
			} else {
				PublicKeyRingBundle = new PgpPublicKeyRingBundle (new byte[0]);
			}

			if (File.Exists (secring)) {
				using (var file = File.OpenRead (secring)) {
					SecretKeyRingBundle = new PgpSecretKeyRingBundle (file);
				}
			} else {
				SecretKeyRingBundle = new PgpSecretKeyRingBundle (new byte[0]);
			}
		}
        public static void SignAndEncryptFile(string actualFileName, string embeddedFileName,
             Stream privateKeyStream, string passPhrase, Stream publicKeyStream,
             bool armor, bool withIntegrityCheck, Stream outputStream)
        {
            const int BUFFER_SIZE = 1 << 16; // should always be power of 2

            if (armor)
                outputStream = new ArmoredOutputStream(outputStream);

            PgpPublicKey pubKey = ReadPublicKey(publicKeyStream);

            // Init encrypted data generator
            PgpEncryptedDataGenerator encryptedDataGenerator =
                new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
            encryptedDataGenerator.AddMethod(pubKey);
            Stream encryptedOut = encryptedDataGenerator.Open(outputStream, new byte[BUFFER_SIZE]);

            // Init compression
            PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
            Stream compressedOut = compressedDataGenerator.Open(encryptedOut);

            // Init signature
            PgpSecretKeyRingBundle pgpSecBundle = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));

            var pgpSecKey = ReadSecretKey(pgpSecBundle);
            if (pgpSecKey == null)
                throw new ArgumentException(pubKey.KeyId.ToString("X") + " could not be found in specified key ring bundle.", "keyId");

            PgpPrivateKey pgpPrivKey = pgpSecKey.ExtractPrivateKey(passPhrase.ToCharArray());
            PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
            signatureGenerator.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
            var userIds = pgpSecKey.PublicKey.GetUserIds();

            string userId = null;
            foreach (string value in userIds)
            {
                // Just the first one!
                userId = value;
                break;
            }

            if (string.IsNullOrEmpty(userId))
            {
                throw new ArgumentException(string.Format("Can't find userId in signing key. KeyId '{0}'.", pubKey.KeyId.ToString("X")));
            }

            PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();
            spGen.SetSignerUserId(false, userId);
            signatureGenerator.SetHashedSubpackets(spGen.Generate());

            signatureGenerator.GenerateOnePassVersion(false).Encode(compressedOut);

            // Create the Literal Data generator output stream
            PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator();

            // NOTE: Commented this out because it uses FileInfo to get stats on files and won't work properly

            FileInfo embeddedFile = new FileInfo(embeddedFileName);
            FileInfo actualFile = new FileInfo(actualFileName);

            if (!actualFile.Exists)
            {
                throw new FileNotFoundException(actualFile.FullName);
            }

            // TODO: Use lastwritetime from source file
            Stream literalOut = literalDataGenerator.Open(compressedOut, PgpLiteralData.Binary, embeddedFile.Name, actualFile.LastWriteTime, new byte[BUFFER_SIZE]);

            // Open the input file
            FileStream inputStream = actualFile.OpenRead();

            byte[] buf = new byte[BUFFER_SIZE];
            int len;
            while ((len = inputStream.Read(buf, 0, buf.Length)) > 0)
            {
                literalOut.Write(buf, 0, len);
                signatureGenerator.Update(buf, 0, len);
            }

            literalOut.Close();
            literalDataGenerator.Close();
            signatureGenerator.Generate().Encode(compressedOut);
            compressedOut.Close();
            compressedDataGenerator.Close();
            encryptedOut.Close();
            encryptedDataGenerator.Close();
            inputStream.Close();

            if (armor)
                outputStream.Close();
        }
 /// <summary>
 /// Return the first key we can use to encrypt.
 /// Note: A file can contain multiple keys (stored in "key rings")
 /// </summary>
 private PgpSecretKey GetFirstSecretKey(PgpSecretKeyRingBundle secretKeyRingBundle)
 {
     foreach (PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings())
     {
         PgpSecretKey key = null;
         foreach(PgpSecretKey k in kRing.GetSecretKeys())
         {
             /*.Cast<PgpSecretKey>()
             .Where(k >= k.IsSigningKey)
             .FirstOrDefault();*/
             if (k.IsSigningKey)
             {
                 key = k;
                 break;
             }
         }
         if (key != null)
             return key;
     }
     return null;
 }
Exemple #27
0
        public void VerifySignature(Stream input, string outputpath)
        {
            input = PgpUtilities.GetDecoderStream(input);
            PgpObjectFactory pgpObjF = new PgpObjectFactory(input);

            //IList collection = pgpObjF.AllPgpObjects();

            PgpEncryptedDataList enc = (PgpEncryptedDataList) pgpObjF.NextPgpObject();

            PgpPrivateKey sKey = null;
            PgpPublicKeyEncryptedData pbe = null;
            PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.
                GetDecoderStream(File.OpenRead(m_encryptionKeys.PrivateKeyPathd)));

            foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
            {
                sKey = FindSecretKey(pgpSec, pked.KeyId, m_encryptionKeys.PassPhrase.ToCharArray());

                if (sKey != null)
                {
                    pbe = pked;
                    break;
                }
            }

            if (sKey == null)
            {
                throw new ArgumentException("secret key for message not found.");
            }

            Stream clear = pbe.GetDataStream(sKey);
            PgpObjectFactory plainFact = new PgpObjectFactory(clear);
            PgpCompressedData cData = (PgpCompressedData)plainFact.NextPgpObject();
            PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream());
            PgpObject message = pgpFact.NextPgpObject();

            if (message is PgpOnePassSignatureList)
            {
                PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)message;
                PgpOnePassSignature ops = p1[0];

                PgpLiteralData p2 = (PgpLiteralData)pgpFact.NextPgpObject();
                Stream dIn = p2.GetInputStream();

                PgpPublicKeyRingBundle pgpRing = new PgpPublicKeyRingBundle(PgpUtilities.
                            GetDecoderStream(File.OpenRead(m_encryptionKeys.PublicKeyPathd)));
                PgpPublicKey key = pgpRing.GetPublicKey(ops.KeyId);

                Stream fos = File.Create(p2.FileName);

                ops.InitVerify(key);

                int ch;
                while ((ch = dIn.ReadByte()) >= 0)
                {
                    ops.Update((byte)ch);
                    fos.WriteByte((byte)ch);
                }
                fos.Close();

                PgpSignatureList p3 = (PgpSignatureList)pgpFact.NextPgpObject();
                PgpSignature firstSig = p3[0];
                if (ops.Verify(firstSig))
                {

                    throw new PgpException("signature verified.");
                }
                else
                {

                    throw new PgpException("signature verification failed.");
                }

            }
        }
		/**
        * decrypt the passed in message stream
        */
        private static void DecryptFile(
            Stream	inputStream,
            Stream	keyIn,
			char[]	passwd,
			string	defaultFileName)
		{
            inputStream = PgpUtilities.GetDecoderStream(inputStream);

            try
            {
                PgpObjectFactory        pgpF = new PgpObjectFactory(inputStream);
                PgpEncryptedDataList    enc;

                PgpObject o = pgpF.NextPgpObject();
                //
                // the first object might be a PGP marker packet.
                //
                if (o is PgpEncryptedDataList)
                {
                    enc = (PgpEncryptedDataList)o;
                }
                else
                {
                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();
                }

                //
                // find the secret key
                //
                PgpPrivateKey sKey = null;
                PgpPublicKeyEncryptedData pbe = null;
				PgpSecretKeyRingBundle pgpSec = new PgpSecretKeyRingBundle(
					PgpUtilities.GetDecoderStream(keyIn));

				foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
                {
                    sKey = PgpExampleUtilities.FindSecretKey(pgpSec, pked.KeyId, passwd);

                    if (sKey != null)
                    {
                        pbe = pked;
                        break;
                    }
                }

                if (sKey == null)
                {
                    throw new ArgumentException("secret key for message not found.");
                }

                Stream clear = pbe.GetDataStream(sKey);

                PgpObjectFactory plainFact = new PgpObjectFactory(clear);

                PgpCompressedData cData = (PgpCompressedData) plainFact.NextPgpObject();

                PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream());

                PgpObject message = pgpFact.NextPgpObject();

                if (message is PgpLiteralData)
                {
                    PgpLiteralData ld = (PgpLiteralData)message;

					string outFileName = ld.FileName;
					if (outFileName.Length == 0)
					{
						outFileName = defaultFileName;
					}

					Stream fOut = File.Create(outFileName);
                    Stream unc = ld.GetInputStream();
					Streams.PipeAll(unc, fOut);
					fOut.Close();
                }
                else if (message is PgpOnePassSignatureList)
                {
                    throw new PgpException("encrypted message contains a signed message - not literal data.");
                }
                else
                {
                    throw new PgpException("message is not a simple encrypted file - type unknown.");
                }

                if (pbe.IsIntegrityProtected())
                {
                    if (!pbe.Verify())
                    {
                        Console.Error.WriteLine("message failed integrity check");
                    }
                    else
                    {
                        Console.Error.WriteLine("message integrity check passed");
                    }
                }
                else
                {
                    Console.Error.WriteLine("no message integrity check");
                }
            }
            catch (PgpException e)
            {
                Console.Error.WriteLine(e);

                Exception underlyingException = e.InnerException;
                if (underlyingException != null)
                {
                    Console.Error.WriteLine(underlyingException.Message);
                    Console.Error.WriteLine(underlyingException.StackTrace);
                }
            }
        }
		/// <summary>
		/// Return a new bundle containing the contents of the passed in bundle with
		/// the passed in secret key ring removed.
		/// </summary>
		/// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be removed from.</param>
		/// <param name="secretKeyRing">The key ring to be removed.</param>
		/// <returns>A new <c>PgpSecretKeyRingBundle</c> not containing the passed in key ring.</returns>
		/// <exception cref="ArgumentException">If the keyId for the passed in key ring is not present.</exception>
        public static PgpSecretKeyRingBundle RemoveSecretKeyRing(
            PgpSecretKeyRingBundle  bundle,
            PgpSecretKeyRing        secretKeyRing)
        {
            long key = secretKeyRing.GetPublicKey().KeyId;

			if (!bundle.secretRings.Contains(key))
            {
                throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring.");
            }

            IDictionary newSecretRings = Platform.CreateHashtable(bundle.secretRings);
            IList newOrder = Platform.CreateArrayList(bundle.order);

			newSecretRings.Remove(key);
			newOrder.Remove(key);

			return new PgpSecretKeyRingBundle(newSecretRings, newOrder);
        }
        /*
        * decrypt a given stream.
        */
        public static void Decrypt(Stream inputStream, Stream privateKeyStream, string passPhrase, string outputFile)
        {
            try
            {
                PgpObjectFactory pgpF = null;
                PgpEncryptedDataList enc = null;
                PgpObject o = null;
                PgpPrivateKey sKey = null;
                PgpPublicKeyEncryptedData pbe = null;
                PgpSecretKeyRingBundle pgpSec = null;

                pgpF = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream));
                // find secret key
                pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));

                if (pgpF != null)
                    o = pgpF.NextPgpObject();

                // the first object might be a PGP marker packet.
                if (o is PgpEncryptedDataList)
                    enc = (PgpEncryptedDataList)o;
                else
                    enc = (PgpEncryptedDataList)pgpF.NextPgpObject();

                // decrypt
                foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects())
                {
                    sKey = FindSecretKey(pgpSec, pked.KeyId, passPhrase.ToCharArray());

                    if (sKey != null)
                    {
                        pbe = pked;
                        break;
                    }
                }

                if (sKey == null)
                    throw new ArgumentException("Secret key for message not found.");

                PgpObjectFactory plainFact = null;

                using (Stream clear = pbe.GetDataStream(sKey))
                {
                    plainFact = new PgpObjectFactory(clear);
                }

                PgpObject message = plainFact.NextPgpObject();

                if (message is PgpCompressedData)
                {
                    PgpCompressedData cData = (PgpCompressedData)message;
                    PgpObjectFactory of = null;

                    using (Stream compDataIn = cData.GetDataStream())
                    {
                        of = new PgpObjectFactory(compDataIn);
                    }

                    message = of.NextPgpObject();
                    if (message is PgpOnePassSignatureList)
                    {
                        message = of.NextPgpObject();
                        PgpLiteralData Ld = null;
                        Ld = (PgpLiteralData)message;
                        using (Stream output = File.Create(outputFile))
                        {
                            Stream unc = Ld.GetInputStream();
                            Streams.PipeAll(unc, output);
                        }
                    }
                    else
                    {
                        PgpLiteralData Ld = null;
                        Ld = (PgpLiteralData)message;
                        using (Stream output = File.Create(outputFile))
                        {
                            Stream unc = Ld.GetInputStream();
                            Streams.PipeAll(unc, output);
                        }
                    }
                }
                else if (message is PgpLiteralData)
                {
                    PgpLiteralData ld = (PgpLiteralData)message;
                    string outFileName = ld.FileName;

                    using (Stream fOut = File.Create(outputFile))
                    {
                        Stream unc = ld.GetInputStream();
                        Streams.PipeAll(unc, fOut);
                    }
                }
                else if (message is PgpOnePassSignatureList)
                    throw new PgpException("Encrypted message contains a signed message - not literal data.");
                else
                    throw new PgpException("Message is not a simple encrypted file - type unknown.");

                #region commented code
                //if (pbe.IsIntegrityProtected())
                //{
                //    if (!pbe.Verify())
                //        msg = "message failed integrity check.";
                //    //Console.Error.WriteLine("message failed integrity check");
                //    else
                //        msg = "message integrity check passed.";
                //    //Console.Error.WriteLine("message integrity check passed");
                //}
                //else
                //{
                //    msg = "no message integrity check.";
                //    //Console.Error.WriteLine("no message integrity check");
                //}
                #endregion

            }
            catch (PgpException ex)
            {
                throw ex;
            }
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.OpenPgpContext"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="OpenPgpContext"/> using the specified public and private keyring paths.
		/// </remarks>
		/// <param name="pubring">The public keyring file path.</param>
		/// <param name="secring">The secret keyring file path.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="pubring"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="secring"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An error occurred while reading one of the keyring files.
		/// </exception>
		/// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException">
		/// An error occurred while parsing one of the keyring files.
		/// </exception>
		protected OpenPgpContext (string pubring, string secring) : this ()
		{
			if (pubring == null)
				throw new ArgumentNullException (nameof (pubring));

			if (secring == null)
				throw new ArgumentNullException (nameof (secring));

			PublicKeyRingPath = pubring;
			SecretKeyRingPath = secring;

			if (File.Exists (pubring)) {
				using (var file = File.Open (pubring, FileMode.Open, FileAccess.Read)) {
					PublicKeyRingBundle = new PgpPublicKeyRingBundle (file);
				}
			} else {
				PublicKeyRingBundle = new PgpPublicKeyRingBundle (new byte[0]);
			}

			if (File.Exists (secring)) {
				using (var file = File.Open (secring, FileMode.Open, FileAccess.Read)) {
					SecretKeyRingBundle = new PgpSecretKeyRingBundle (file);
				}
			} else {
				SecretKeyRingBundle = new PgpSecretKeyRingBundle (new byte[0]);
			}
		}
		private PgpSecretKey readSecretKey(Stream privateKeyStream)
		{
			PgpSecretKeyRingBundle pgpSec;
			try
			{
				pgpSec = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));
			}
			catch (Exception e)
			{
				throw new Exception("Invalid private key stream, reason: " + e.Message);
			}
			
			var keyRings = pgpSec.GetKeyRings();
			foreach( PgpSecretKeyRing keyRing in keyRings)
			{
				foreach(PgpSecretKey key in keyRing.GetSecretKeys())
				{
					if( key.IsSigningKey )
						return key;
				}
			}
			
			throw new Exception("Could not find a valid signing key");
		}
		/// <summary>
		/// Imports a secret pgp keyring bundle.
		/// </summary>
		/// <remarks>
		/// Imports a secret pgp keyring bundle.
		/// </remarks>
		/// <param name="bundle">The pgp keyring bundle.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="bundle"/> is <c>null</c>.
		/// </exception>
		public void Import (PgpSecretKeyRingBundle bundle)
		{
			if (bundle == null)
				throw new ArgumentNullException (nameof (bundle));

			int secretKeysAdded = 0;

			foreach (PgpSecretKeyRing secring in bundle.GetKeyRings ()) {
				if (!SecretKeyRingBundle.Contains (secring.GetSecretKey ().KeyId)) {
					SecretKeyRingBundle = PgpSecretKeyRingBundle.AddSecretKeyRing (SecretKeyRingBundle, secring);
					secretKeysAdded++;
				}
			}

			if (secretKeysAdded > 0)
				SaveSecretKeyRingBundle ();
		}
        public static Stream DecryptPgpData(Stream inputStream, Stream privateKeyStream, string privateKeyPassPhrase)
        {

            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }
            if (privateKeyStream == null)
            {
                throw new ArgumentNullException("privateKeyStream");
            }

            PgpObjectFactory pgpFactory = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream));

            // find secret key
            PgpSecretKeyRingBundle pgpKeyRing = new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream));

            PgpObject pgp = null;
            if (pgpFactory != null)
            {
                pgp = pgpFactory.NextPgpObject();
            }

            // the first object might be a PGP marker packet.
            PgpEncryptedDataList encryptedData = null;
            if (pgp is PgpEncryptedDataList)
            {
                encryptedData = (PgpEncryptedDataList)pgp;
            }
            else
            {
                encryptedData = (PgpEncryptedDataList)pgpFactory.NextPgpObject();
            }

            // decrypt
            PgpPrivateKey privateKey = null;
            PgpPublicKeyEncryptedData pubKeyData = null;
            var encryptedObjects = encryptedData.GetEncryptedDataObjects();
            foreach (PgpPublicKeyEncryptedData pubKeyDataItem in encryptedData.GetEncryptedDataObjects())
            {
                privateKey = FindSecretKey(pgpKeyRing, pubKeyDataItem.KeyId, privateKeyPassPhrase.ToCharArray());

                if (privateKey != null)
                {
                    pubKeyData = pubKeyDataItem;
                    break;
                }
            }

            if (privateKey == null)
            {
                throw new ArgumentException("Secret key for message not found.");
            }

            PgpObjectFactory plainFact = null;
            using (Stream clear = pubKeyData.GetDataStream(privateKey))
            {
                plainFact = new PgpObjectFactory(clear);
            }

            PgpObject message = plainFact.NextPgpObject();

            if (message is PgpCompressedData)
            {
                PgpCompressedData compressedData = (PgpCompressedData)message;
                PgpObjectFactory pgpCompressedFactory = null;

                using (Stream compDataIn = compressedData.GetDataStream())
                {
                    pgpCompressedFactory = new PgpObjectFactory(compDataIn);
                }

                message = pgpCompressedFactory.NextPgpObject();
                PgpLiteralData literalData = null;
                if (message is PgpOnePassSignatureList)
                {
                    message = pgpCompressedFactory.NextPgpObject();
                }

                literalData = (PgpLiteralData)message;

                return literalData.GetInputStream();

                //using (Stream unc = literalData.GetInputStream())
                //{
                //    StreamHelper.WriteStream(unc, ref output);
                //}

            }
            else if (message is PgpLiteralData)
            {
                PgpLiteralData literalData = (PgpLiteralData)message;
                return literalData.GetInputStream();

                //using (Stream unc = literalData.GetInputStream())
                //{
                //     StreamHelper.WriteStream(unc, ref output);
                //}
            }
            else if (message is PgpOnePassSignatureList)
            {
                throw new PgpException("Encrypted message contains a signed message - not literal data.");
            }
            else
            {
                throw new PgpException("Message is not a simple encrypted file - type unknown.");
            }

            //return output;
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Cryptography.OpenPgpContext"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new <see cref="OpenPgpContext"/> using the specified public and private keyrings.
		/// </remarks>
		/// <param name="pubring">The public keyring.</param>
		/// <param name="secring">The secret keyring.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <para><paramref name="pubring"/> is <c>null</c>.</para>
		/// <para>-or-</para>
		/// <para><paramref name="secring"/> is <c>null</c>.</para>
		/// </exception>
		/// <exception cref="System.IO.IOException">
		/// An error occurred while reading one of the keyring files.
		/// </exception>
		/// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException">
		/// An error occurred while parsing one of the keyring files.
		/// </exception>
		protected OpenPgpContext (Stream pubring, Stream secring) : this ()
		{
			if (pubring == null)
				throw new ArgumentNullException ("pubring");

			if (secring == null)
				throw new ArgumentNullException ("secring");

			PublicKeyRing = pubring;
			SecretKeyRing = secring;

			PublicKeyRingBundle = new PgpPublicKeyRingBundle (pubring);
			SecretKeyRingBundle = new PgpSecretKeyRingBundle (secring);

			if (pubring.CanSeek)
				pubring.Seek (0, SeekOrigin.Begin);

			if (secring.CanSeek)
				secring.Seek (0, SeekOrigin.Begin);
		}