private static void DecryptFile( Stream inputStream, Stream keyIn, char[] passwd, string tempDir) { 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; foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) { sKey = FindSecretKey(keyIn, pked.KeyId, passwd); if (sKey != null) { pbe = pked; break; } } // Iterator it = enc.GetEncryptedDataObjects(); // // while (sKey == null && it.hasNext()) // { // pbe = (PgpPublicKeyEncryptedData)it.next(); // // sKey = FindSecretKey(keyIn, pbe.KeyID, passwd); // } 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(); if (message is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData)message; PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream()); message = pgpFact.NextPgpObject(); } if (message is PgpOnePassSignatureList) { //throw new PgpException("encrypted message contains a signed message - not literal data."); // // file is signed! // // verify signature here if you want. // // PGPOnePassSignatureList p1 = (PGPOnePassSignatureList) message; // PGPOnePassSignature ops = p1.get(0); // etc… message = plainFact.NextPgpObject(); } if (message is PgpLiteralData) { PgpLiteralData ld = (PgpLiteralData)message; //System.Diagnostics.EventLog.WriteEntry("PGPWrapper[Decrypt] DEBUG", "Decrypting to: " + ld.FileName); using (FileStream fOut = File.Create(Path.Combine(tempDir, ld.FileName))) { //System.Diagnostics.EventLog.WriteEntry("PGPWrapper[Decrypt] DEBUG", "Decrypted to: " + fOut.Name); Stream unc = ld.GetInputStream(); int ch; while ((ch = unc.ReadByte()) >= 0) { fOut.WriteByte((byte)ch); } fOut.Close(); } } 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); } } }
/** * decrypt the passed in message stream */ private static void DecryptFile( Stream inputStream, char[] passPhrase) { inputStream = PgpUtilities.GetDecoderStream(inputStream); PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); PgpObject o = pgpF.NextPgpObject(); // // the first object might be a PGP marker packet. // PgpEncryptedDataList enc = o as PgpEncryptedDataList; if (enc == null) { enc = (PgpEncryptedDataList)pgpF.NextPgpObject(); } PgpPbeEncryptedData pbe = (PgpPbeEncryptedData)enc[0]; Stream clear = pbe.GetDataStream(passPhrase); PgpObjectFactory pgpFact = new PgpObjectFactory(clear); // // if we're trying to read a file generated by someone other than us // the data might not be compressed, so we check the return type from // the factory and behave accordingly. // o = pgpFact.NextPgpObject(); if (o is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData) o; pgpFact = new PgpObjectFactory(cData.GetDataStream()); o = pgpFact.NextPgpObject(); } PgpLiteralData ld = (PgpLiteralData) o; Stream unc = ld.GetInputStream(); Stream fOut = File.Create(ld.FileName); Streams.PipeAll(unc, fOut); fOut.Close(); 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"); } }
private static PgpObject checkforOnePassSignatureList(PgpObject message, PgpObjectFactory compressedFactory) { message = compressedFactory.NextPgpObject(); if (message is PgpOnePassSignatureList) { message = compressedFactory.NextPgpObject(); } return message; }
private static Org.BouncyCastle.Bcpg.OpenPgp.PgpEncryptedDataList GetEncryptedDatalist(Stream inputStream) { var dstream = Org.BouncyCastle.Bcpg.OpenPgp.PgpUtilities.GetDecoderStream(inputStream); var pgpObjFacoty = new Org.BouncyCastle.Bcpg.OpenPgp.PgpObjectFactory(dstream); var obj = pgpObjFacoty.NextPgpObject(); var tmp = obj as Org.BouncyCastle.Bcpg.OpenPgp.PgpEncryptedDataList; if (tmp != null) { return(tmp); } return((Org.BouncyCastle.Bcpg.OpenPgp.PgpEncryptedDataList)pgpObjFacoty.NextPgpObject()); }
/** * verify the passed in file as being correctly signed. */ private static void VerifyFile( Stream inputStream, Stream keyIn) { inputStream = PgpUtilities.GetDecoderStream(inputStream); PgpObjectFactory pgpFact = new PgpObjectFactory(inputStream); PgpCompressedData c1 = (PgpCompressedData) pgpFact.NextPgpObject(); pgpFact = new PgpObjectFactory(c1.GetDataStream()); PgpOnePassSignatureList p1 = (PgpOnePassSignatureList) pgpFact.NextPgpObject(); PgpOnePassSignature ops = p1[0]; PgpLiteralData p2 = (PgpLiteralData) pgpFact.NextPgpObject(); Stream dIn = p2.GetInputStream(); PgpPublicKeyRingBundle pgpRing = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(keyIn)); 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)) { Console.Out.WriteLine("signature verified."); } else { Console.Out.WriteLine("signature verification failed."); } }
/** * decrypt the passed in message stream * * @param encrypted The message to be decrypted. * @param passPhrase Pass phrase (key) * * @return Clear text as a byte array. I18N considerations are * not handled by this routine * @exception IOException * @exception PgpException */ public static byte[] Decrypt( byte[] encrypted, char[] passPhrase) { Stream inputStream = new MemoryStream(encrypted); inputStream = PgpUtilities.GetDecoderStream(inputStream); PgpObjectFactory pgpF = new PgpObjectFactory(inputStream); PgpEncryptedDataList enc = null; 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(); } PgpPbeEncryptedData pbe = (PgpPbeEncryptedData)enc[0]; Stream clear = pbe.GetDataStream(passPhrase); PgpObjectFactory pgpFact = new PgpObjectFactory(clear); PgpCompressedData cData = (PgpCompressedData) pgpFact.NextPgpObject(); pgpFact = new PgpObjectFactory(cData.GetDataStream()); PgpLiteralData ld = (PgpLiteralData) pgpFact.NextPgpObject(); Stream unc = ld.GetInputStream(); return Streams.ReadAll(unc); }
/// <summary> /// Decrypt and verify signature of data. /// </summary> /// <param name="data">Data to decrypt and verify</param> /// <returns>Returns decrypted data if signature verifies.</returns> public byte[] DecryptAndVerify(byte[] data, bool ignoreIntegrityCheck = false) { Context = new CryptoContext(Context); var isArmored = ASCIIEncoding.ASCII.GetString(data).IndexOf("-----BEGIN PGP MESSAGE-----") > -1; using (var dataIn = new MemoryStream(data)) { if (isArmored) { using (var armoredIn = new ArmoredInputStream(dataIn)) { var factory = new PgpObjectFactory(armoredIn); while (true) { var obj = factory.NextPgpObject(); if (obj is PgpMarker) continue; var ret = DecryptHandlePgpObject(obj); if (Context.FailedIntegrityCheck && !ignoreIntegrityCheck) throw new VerifyException("Data not integrity protected."); return ret; } } } else { var factory = new PgpObjectFactory(dataIn); while (true) { var obj = factory.NextPgpObject(); if (obj is PgpMarker) continue; var ret = DecryptHandlePgpObject(obj); if (Context.FailedIntegrityCheck && !ignoreIntegrityCheck) throw new VerifyException("Data not integrity protected."); return ret; } } } }
/** * verify the signature in in against the file fileName. */ private static void VerifySignature( string fileName, Stream inputStream, Stream keyIn) { inputStream = PgpUtilities.GetDecoderStream(inputStream); PgpObjectFactory pgpFact = new PgpObjectFactory(inputStream); PgpSignatureList p3 = null; PgpObject o = pgpFact.NextPgpObject(); if (o is PgpCompressedData) { PgpCompressedData c1 = (PgpCompressedData)o; pgpFact = new PgpObjectFactory(c1.GetDataStream()); p3 = (PgpSignatureList)pgpFact.NextPgpObject(); } else { p3 = (PgpSignatureList)o; } PgpPublicKeyRingBundle pgpPubRingCollection = new PgpPublicKeyRingBundle( PgpUtilities.GetDecoderStream(keyIn)); Stream dIn = File.OpenRead(fileName); PgpSignature sig = p3[0]; PgpPublicKey key = pgpPubRingCollection.GetPublicKey(sig.KeyId); sig.InitVerify(key); int ch; while ((ch = dIn.ReadByte()) >= 0) { sig.Update((byte)ch); } dIn.Close(); if (sig.Verify()) { Console.WriteLine("signature verified."); } else { Console.WriteLine("signature verification failed."); } }
/// <summary> /// Decrypt and verify signature of data. /// </summary> /// <param name="data">Data to decrypt and verify</param> /// <returns>Returns decrypted data if signature verifies.</returns> public byte[] DecryptAndVerify(byte[] data) { Context = new CryptoContext(Context); var isArmored = ASCIIEncoding.ASCII.GetString(data).IndexOf("-----BEGIN PGP MESSAGE-----") > -1; using (var dataIn = new MemoryStream(data)) { if (isArmored) { using (var armoredIn = new ArmoredInputStream(dataIn)) { var factory = new PgpObjectFactory(armoredIn); while (true) { var obj = factory.NextPgpObject(); if (obj is PgpMarker) continue; var ret = DecryptHandlePgpObject(obj); return ret; } } } else { var factory = new PgpObjectFactory(dataIn); while (true) { var obj = factory.NextPgpObject(); if (obj is PgpMarker) continue; var ret = DecryptHandlePgpObject(obj); return ret; } } } }
/// <summary> /// Attempt to decrypt a PGP protected message using the matching private key. /// </summary> /// <param name="messageStream">Stream containing the message to decrypt.</param> /// <param name="decryptedMessageStream">Stream to write the decrypted message into.</param> /// <param name="recipientPrivateKey">The BouncyCastle private key to be used for decryption.</param> /// <remarks>The message should be passed in without ASCII Armor.</remarks> /// <returns>Whether the decryption completed successfully.</returns> public static bool Decrypt(Stream messageStream, Stream decryptedMessageStream, PgpPrivateKey recipientPrivateKey) { // Decode from Base-64. using (Stream decoderStream = PgpUtilities.GetDecoderStream(messageStream)) { // Extract the encrypted data list. PgpObjectFactory pgpObjectFactory = new PgpObjectFactory(decoderStream); PgpObject pgpObject = pgpObjectFactory.NextPgpObject(); while (!(pgpObject is PgpEncryptedDataList)) { pgpObject = pgpObjectFactory.NextPgpObject(); if (pgpObject == null) return false; } PgpEncryptedDataList pgpEncryptedDataList = pgpObject as PgpEncryptedDataList; // Attempt to extract the encrypted data stream. Stream decryptedStream = null; foreach (PgpPublicKeyEncryptedData pgpEncryptedData in pgpEncryptedDataList.GetEncryptedDataObjects().Cast<PgpPublicKeyEncryptedData>()){ if (pgpEncryptedData.KeyId == recipientPrivateKey.KeyId) decryptedStream = pgpEncryptedData.GetDataStream(recipientPrivateKey); } // If we're unable to decrypt any of the streams, fail. if (decryptedStream == null) return false; PgpObjectFactory clearPgpObjectFactory = new PgpObjectFactory(decryptedStream); PgpObject message = clearPgpObjectFactory.NextPgpObject(); // Deal with compression. if (message is PgpCompressedData) { PgpCompressedData compressedMessage = (PgpCompressedData)message; using (Stream compressedDataStream = compressedMessage.GetDataStream()) { PgpObjectFactory compressedPgpObjectFactory = new PgpObjectFactory(compressedDataStream); pgpObject = compressedPgpObjectFactory.NextPgpObject(); while (!(pgpObject is PgpLiteralData)) { pgpObject = compressedPgpObjectFactory.NextPgpObject(); if (pgpObject == null) return false; } } } else if (message is PgpLiteralData) { pgpObject = message; } else { // If not compressed and the following object isn't literal data, fail. decryptedStream.Dispose(); return false; } // If a literal data stream was found, extract the decrypted message. PgpLiteralData literalData = pgpObject as PgpLiteralData; if (literalData != null) { using (Stream literalDataStream = literalData.GetDataStream()) { literalDataStream.CopyTo(decryptedMessageStream); } decryptedStream.Dispose(); return true; } } return false; }
private static Stream DecryptFileAsStream( Stream inputStream, Stream keyIn, char[] passwd) { inputStream = PgpUtilities.GetDecoderStream(inputStream); MemoryStream outputStream = new MemoryStream(); 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; foreach (PgpPublicKeyEncryptedData pked in enc.GetEncryptedDataObjects()) { sKey = FindSecretKey(keyIn, pked.KeyId, passwd); if (sKey != null) { pbe = pked; break; } } // Iterator it = enc.GetEncryptedDataObjects(); // // while (sKey == null && it.hasNext()) // { // pbe = (PgpPublicKeyEncryptedData)it.next(); // // sKey = FindSecretKey(keyIn, pbe.KeyID, passwd); // } 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(); if (message is PgpCompressedData) { PgpCompressedData cData = (PgpCompressedData)message; PgpObjectFactory pgpFact = new PgpObjectFactory(cData.GetDataStream()); message = pgpFact.NextPgpObject(); if (message is PgpOnePassSignatureList) { //throw new PgpException("encrypted message contains a signed message - not literal data."); // // file is signed! // // verify signature here if you want. // PgpOnePassSignatureList p1 = (PgpOnePassSignatureList)message; PgpOnePassSignature ops = p1[0]; // etc… message = pgpFact.NextPgpObject(); } } if (message is PgpLiteralData) { PgpLiteralData ld = (PgpLiteralData)message; Stream unc = ld.GetInputStream(); int ch; while ((ch = unc.ReadByte()) >= 0) { outputStream.WriteByte((byte)ch); } outputStream.Seek(0, SeekOrigin.Begin); } 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"); } return outputStream; } catch (PgpException e) { Console.Error.WriteLine(e); Exception underlyingException = e.InnerException; if (underlyingException != null) { Console.Error.WriteLine(underlyingException.Message); Console.Error.WriteLine(underlyingException.StackTrace); } throw e; } }
/// <summary> /// Gets the encrypted data list object from within the encrypted stream. /// </summary> /// <param name="decoderStream">The decoder stream.</param> /// <returns>PgpEncryptedDataList</returns> private static PgpEncryptedDataList GetEncryptedDataList(Stream decoderStream) { PgpObject pgpObject; if (decoderStream == null) throw new ArgumentNullException("decoderStream"); var pgpObjectFactory = new PgpObjectFactory(decoderStream); while ((pgpObject = pgpObjectFactory.NextPgpObject()) != null) if (pgpObject is PgpEncryptedDataList) return pgpObject as PgpEncryptedDataList; throw new PgpException("No encrypted data list found in file (possibly corrupted)."); }
/// <summary> /// Verifies the specified content using the detached signatureData. /// </summary> /// <remarks> /// Verifies the specified content using the detached signatureData. /// </remarks> /// <returns>A list of digital signatures.</returns> /// <param name="content">The content.</param> /// <param name="signatureData">The signature data.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="content"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signatureData"/> is <c>null</c>.</para> /// </exception> public override DigitalSignatureCollection Verify (Stream content, Stream signatureData) { if (content == null) throw new ArgumentNullException ("content"); if (signatureData == null) throw new ArgumentNullException ("signatureData"); using (var armored = new ArmoredInputStream (signatureData)) { var factory = new PgpObjectFactory (armored); var data = factory.NextPgpObject (); PgpSignatureList signatureList; var compressed = data as PgpCompressedData; if (compressed != null) { factory = new PgpObjectFactory (compressed.GetDataStream ()); data = factory.NextPgpObject (); } signatureList = (PgpSignatureList) data; return GetDigitalSignatures (signatureList, content); } }
/// <summary> /// Decrypts the specified encryptedData and extracts the digital signers if the content was also signed. /// </summary> /// <remarks> /// Decrypts the specified encryptedData and extracts the digital signers if the content was also signed. /// </remarks> /// <returns>The decrypted stream.</returns> /// <param name="encryptedData">The encrypted data.</param> /// <param name="signatures">A list of digital signatures if the data was both signed and encrypted.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="encryptedData"/> is <c>null</c>. /// </exception> /// <exception cref="PrivateKeyNotFoundException"> /// The private key could not be found to decrypt the stream. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The user chose to cancel the password prompt. /// </exception> /// <exception cref="System.UnauthorizedAccessException"> /// 3 bad attempts were made to unlock the secret key. /// </exception> /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException"> /// An OpenPGP error occurred. /// </exception> public Stream GetDecryptedStream (Stream encryptedData, out DigitalSignatureCollection signatures) { if (encryptedData == null) throw new ArgumentNullException ("encryptedData"); using (var armored = new ArmoredInputStream (encryptedData)) { var factory = new PgpObjectFactory (armored); var obj = factory.NextPgpObject (); var list = obj as PgpEncryptedDataList; if (list == null) { // probably a PgpMarker... obj = factory.NextPgpObject (); list = obj as PgpEncryptedDataList; if (list == null) throw new PgpException ("Unexpected OpenPGP packet."); } PgpPublicKeyEncryptedData encrypted = null; PrivateKeyNotFoundException pkex = null; bool hasEncryptedPackets = false; PgpSecretKey secret = null; foreach (PgpEncryptedData data in list.GetEncryptedDataObjects ()) { if ((encrypted = data as PgpPublicKeyEncryptedData) == null) continue; hasEncryptedPackets = true; try { secret = GetSecretKey (encrypted.KeyId); break; } catch (PrivateKeyNotFoundException ex) { pkex = ex; } } if (!hasEncryptedPackets) throw new PgpException ("No encrypted packets found."); if (secret == null) throw pkex; factory = new PgpObjectFactory (encrypted.GetDataStream (GetPrivateKey (secret))); List<IDigitalSignature> onepassList = null; PgpSignatureList signatureList = null; PgpCompressedData compressed = null; var memory = new MemoryBlockStream (); obj = factory.NextPgpObject (); while (obj != null) { if (obj is PgpCompressedData) { if (compressed != null) throw new PgpException ("Recursive compression packets are not supported."); compressed = (PgpCompressedData) obj; factory = new PgpObjectFactory (compressed.GetDataStream ()); } else if (obj is PgpOnePassSignatureList) { if (memory.Length == 0) { var onepasses = (PgpOnePassSignatureList) obj; onepassList = new List<IDigitalSignature> (); for (int i = 0; i < onepasses.Count; i++) { var onepass = onepasses[i]; var pubkey = PublicKeyRingBundle.GetPublicKey (onepass.KeyId); if (pubkey == null) { // too messy, pretend we never found a one-pass signature list onepassList = null; break; } onepass.InitVerify (pubkey); var signature = new OpenPgpDigitalSignature (pubkey, onepass) { PublicKeyAlgorithm = GetPublicKeyAlgorithm (onepass.KeyAlgorithm), DigestAlgorithm = GetDigestAlgorithm (onepass.HashAlgorithm), }; onepassList.Add (signature); } } } else if (obj is PgpSignatureList) { signatureList = (PgpSignatureList) obj; } else if (obj is PgpLiteralData) { var literal = (PgpLiteralData) obj; using (var stream = literal.GetDataStream ()) { var buffer = new byte[4096]; int nread; while ((nread = stream.Read (buffer, 0, buffer.Length)) > 0) { if (onepassList != null) { // update our one-pass signatures... for (int index = 0; index < nread; index++) { byte c = buffer[index]; for (int i = 0; i < onepassList.Count; i++) { var pgp = (OpenPgpDigitalSignature) onepassList[i]; pgp.OnePassSignature.Update (c); } } } memory.Write (buffer, 0, nread); } } } obj = factory.NextPgpObject (); } memory.Position = 0; if (signatureList != null) { if (onepassList != null && signatureList.Count == onepassList.Count) { for (int i = 0; i < onepassList.Count; i++) { var pgp = (OpenPgpDigitalSignature) onepassList[i]; pgp.CreationDate = signatureList[i].CreationTime; pgp.Signature = signatureList[i]; } signatures = new DigitalSignatureCollection (onepassList); } else { signatures = GetDigitalSignatures (signatureList, memory); memory.Position = 0; } } else { signatures = null; } return memory; } }
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(); }
/** * 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 ); } }
/// <summary> /// Decrypt an encrypted stream. /// </summary> /// <returns>The decrypted <see cref="MimeKit.MimeEntity"/>.</returns> /// <param name="encryptedData">The encrypted data.</param> /// <param name="signatures">A list of digital signatures if the data was both signed and encrypted.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="encryptedData"/> is <c>null</c>. /// </exception> /// <exception cref="PrivateKeyNotFoundException"> /// The private key could not be found to decrypt the stream. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The user chose to cancel the password prompt. /// </exception> /// <exception cref="System.UnauthorizedAccessException"> /// 3 bad attempts were made to unlock the secret key. /// </exception> public MimeEntity Decrypt(Stream encryptedData, out DigitalSignatureCollection signatures) { if (encryptedData == null) throw new ArgumentNullException ("encryptedData"); // FIXME: document the exceptions that can be thrown by BouncyCastle using (var armored = new ArmoredInputStream (encryptedData)) { var factory = new PgpObjectFactory (armored); var obj = factory.NextPgpObject (); var list = obj as PgpEncryptedDataList; if (list == null) { // probably a PgpMarker... obj = factory.NextPgpObject (); list = obj as PgpEncryptedDataList; if (list == null) throw new Exception ("Unexpected pgp object"); } PgpPublicKeyEncryptedData encrypted = null; foreach (PgpEncryptedData data in list.GetEncryptedDataObjects ()) { if ((encrypted = data as PgpPublicKeyEncryptedData) != null) break; } if (encrypted == null) throw new Exception ("no encrypted data objects found?"); factory = new PgpObjectFactory (encrypted.GetDataStream (GetPrivateKey (encrypted.KeyId))); PgpOnePassSignatureList onepassList = null; PgpSignatureList signatureList = null; PgpCompressedData compressed = null; using (var memory = new MemoryStream ()) { obj = factory.NextPgpObject (); while (obj != null) { if (obj is PgpCompressedData) { if (compressed != null) throw new Exception ("recursive compression detected."); compressed = (PgpCompressedData) obj; factory = new PgpObjectFactory (compressed.GetDataStream ()); } else if (obj is PgpOnePassSignatureList) { onepassList = (PgpOnePassSignatureList) obj; } else if (obj is PgpSignatureList) { signatureList = (PgpSignatureList) obj; } else if (obj is PgpLiteralData) { var literal = (PgpLiteralData) obj; using (var stream = literal.GetDataStream ()) { stream.CopyTo (memory, 4096); } } obj = factory.NextPgpObject (); } memory.Position = 0; // FIXME: validate the OnePass signatures... and do what with them? // if (onepassList != null) { // for (int i = 0; i < onepassList.Count; i++) { // var onepass = onepassList[i]; // } // } if (signatureList != null) { signatures = GetDigitalSignatures (signatureList, memory); memory.Position = 0; } else { signatures = null; } return MimeEntity.Load (memory); } } }
/* * 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; } }
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."); } } }
/// <summary> /// Attempt to verify a PGP signed message using the matching public key. /// </summary> /// <param name="signedMessageStream">Stream containing the signed message.</param> /// <param name="signatureStream">Stream containing the signature.</param> /// <param name="publicKey">BouncyCastle public key to be used for verification.</param> /// <remarks>The message and signature should be passed in without ASCII Armor.</remarks> /// <returns>Whether the message's signature is verified.</returns> public static bool VerifySignature(Stream signedMessageStream, Stream signatureStream, PgpPublicKey publicKey) { // Decode from Base-64. using (Stream decoderStream = PgpUtilities.GetDecoderStream(signatureStream)) { // Extract the signature list. PgpObjectFactory pgpObjectFactory = new PgpObjectFactory(decoderStream); PgpObject pgpObject = pgpObjectFactory.NextPgpObject(); if (pgpObject is PgpSignatureList) { PgpSignatureList signatureList = pgpObject as PgpSignatureList; // Hydrate the signature object with the message to be verified. PgpSignature signature = signatureList[0]; signature.InitVerify(publicKey); signedMessageStream.Seek(0, SeekOrigin.Begin); for (int i = 0; i < signedMessageStream.Length; i++) { signature.Update((byte)signedMessageStream.ReadByte()); } // Return the result. return signature.Verify(); } else return false; } }
/// <summary> /// Verify signature /// </summary> /// <param name="data">Data to verify</param> /// <returns>Return true if signature validates, else false.</returns> public bool Verify(byte[] data) { Context = new CryptoContext(Context); using (var dataIn = new MemoryStream(data)) using (var armoredIn = new ArmoredInputStream(dataIn)) { if (!armoredIn.IsClearText()) { var factory = new PgpObjectFactory(armoredIn); DecryptHandlePgpObject(factory.NextPgpObject()); if (!Context.IsSigned) throw new CryptoException("Error, message is not signed."); return Context.SignatureValidated; } } return VerifyClear(data); }
/// <summary> /// Verifies the specified content using the detached signatureData. /// </summary> /// <remarks> /// Verifies the specified content using the detached signatureData. /// </remarks> /// <returns>A list of digital signatures.</returns> /// <param name="content">The content.</param> /// <param name="signatureData">The signature data.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="content"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signatureData"/> is <c>null</c>.</para> /// </exception> public override DigitalSignatureCollection Verify (Stream content, Stream signatureData) { if (content == null) throw new ArgumentNullException ("content"); if (signatureData == null) throw new ArgumentNullException ("signatureData"); using (var armored = new ArmoredInputStream (signatureData)) { var factory = new PgpObjectFactory (armored); var data = factory.NextPgpObject (); PgpSignatureList signatureList; var compressed = data as PgpCompressedData; if (compressed != null) { factory = new PgpObjectFactory (compressed.GetDataStream ()); signatureList = (PgpSignatureList) factory.NextPgpObject (); } else { // FIXME: this should probably throw a FormatException? Also needs docs. if ((signatureList = data as PgpSignatureList) == null) throw new Exception ("Unexpected pgp object"); } return GetDigitalSignatures (signatureList, content); } }
/// <summary> /// Verify signature for cleartext (e.g. emails) /// </summary> /// <param name="data">Data to verify</param> /// <returns>Return true if signature validates, else false.</returns> public bool VerifyClear(byte[] data) { Context = new CryptoContext(Context); var crlf = new byte[] { (byte)'\r', (byte)'\n' }; var encoding = ASCIIEncoding.UTF8; using (var dataIn = new MemoryStream(data)) using (var armoredIn = new ArmoredInputStream(dataIn)) { if (!armoredIn.IsClearText()) throw new CryptoException("Error, message is not armored clear-text."); var headers = armoredIn.GetArmorHeaders(); if(headers != null) { foreach (var header in headers) { if (Regex.IsMatch(header, @"Charset: ([^\s]*)")) { var encodingType = Regex.Match(header, @"Charset: ([^\s]*)").Groups[1].Value; encoding = Encoding.GetEncoding(encodingType); } } } using (var clearOut = new MemoryStream()) { using (var clearIn = new MemoryStream()) { int ch = 0; while ((ch = armoredIn.ReadByte()) >= 0 && armoredIn.IsClearText()) clearIn.WriteByte((byte)ch); clearIn.Position = 0; using (var stringIn = new StringReader(encoding.GetString(clearIn.ToArray()))) { do { var line = stringIn.ReadLine(); if (line == null) break; line = line .TrimEnd(null) .TrimEnd(new char[] { ' ', '\t', '\n', '\r' }) .TrimEnd(null) +"\r\n"; var buff = encoding.GetBytes(line); clearOut.Write(buff, 0, buff.Length); } while (true); } } clearOut.Position = 0; var factory = new PgpObjectFactory(armoredIn); var signatureList = (PgpSignatureList)factory.NextPgpObject(); var signature = signatureList[0]; Context.IsEncrypted = false; Context.IsSigned = true; Context.SignedBy = GetPublicKey(signature.KeyId); if (Context.SignedBy == null) throw new PublicKeyNotFoundException("Public key not found for key id \"" + signature.KeyId + "\"."); signature.InitVerify(GetPublicKey(signature.KeyId)); signature.Update(clearOut.ToArray(), 0, (int)(clearOut.Length - 2)); Context.SignatureValidated = signature.Verify(); return Context.SignatureValidated; } } }
/// <summary> /// Recursive PGP Object handler. /// </summary> /// <param name="obj">Object to handle</param> /// <returns>Returns decrypted data if any</returns> byte[] DecryptHandlePgpObject(PgpObject obj) { byte[] ret = null; if (obj is PgpEncryptedDataList) { Context.IsEncrypted = true; var dataList = obj as PgpEncryptedDataList; // Set once we have matched a keyid. bool secretKeyMatched = false; foreach (PgpPublicKeyEncryptedData encryptedData in dataList.GetEncryptedDataObjects()) { try { // NOTE: When content is encrypted to multiple reciepents, only one of these blocks // will match a known KeyId. If a match is never made, then there is a problem :) Context.SecretKey = GetSecretKey(encryptedData.KeyId); if (Context.SecretKey == null) continue; secretKeyMatched = true; using (var cleartextIn = encryptedData.GetDataStream(Context.SecretKey.ExtractPrivateKey(Context.Password))) { var clearFactory = new PgpObjectFactory(cleartextIn); var nextObj = clearFactory.NextPgpObject(); var r = DecryptHandlePgpObject(nextObj); if (r != null) ret = r; } if (!encryptedData.Verify()) throw new VerifyException("Verify of encrypted data failed!"); } catch (PgpException ex) { if (!(ex.InnerException is EndOfStreamException)) throw ex; } } if(!secretKeyMatched) throw new SecretKeyNotFoundException("Error, unable to locate decryption key."); } else if (obj is PgpCompressedData) { Context.IsCompressed = true; var compressedData = obj as PgpCompressedData; using (var compressedIn = compressedData.GetDataStream()) { var factory = new PgpObjectFactory(compressedIn); do { var nextObj = factory.NextPgpObject(); if (nextObj == null) break; var r = DecryptHandlePgpObject(nextObj); if (r != null) ret = r; } while (true); } } else if (obj is PgpOnePassSignatureList) { Context.IsSigned = true; var signatureList = obj as PgpOnePassSignatureList; if (signatureList.Count > 1) throw new CryptoException("Error, more than one signature present!"); Context.OnePassSignature = signatureList[0]; var publicKey = GetPublicKey(Context.OnePassSignature.KeyId); if (publicKey == null) { Context.OnePassSignature = null; } else Context.OnePassSignature.InitVerify(publicKey); } else if (obj is PgpSignatureList) { var signatureList = obj as PgpSignatureList; if (signatureList.Count > 1) throw new CryptoException("Error, more than one signature present!"); Context.Signature = signatureList[0]; if (Context.IsSigned && Context.OnePassSignature == null) { // We don't have signature key for validation Context.SignatureValidated = false; Context.SignedBy = null; } else if (Context.OnePassSignature == null) throw new CryptoException("Error, OnePassSignature was not found!"); else { if (Context.OnePassSignature.Verify(Context.Signature)) { Context.SignatureValidated = true; Context.SignedBy = GetPublicKey(Context.Signature.KeyId); } } } else if (obj is PgpLiteralData) { var literalData = obj as PgpLiteralData; using (var dataOut = new MemoryStream()) { using (var dataIn = literalData.GetInputStream()) dataIn.CopyTo(dataOut); dataOut.Position = 0; ret = dataOut.ToArray(); } if(Context.OnePassSignature != null) Context.OnePassSignature.Update(ret, 0, ret.Length); } else if (obj is PgpMarker) { // Skip, These packets are used by PGP 5.x to signal to earlier // versions of PGP (eg. 2.6.x) that the message requires newer // software to be read and understood. } else { throw new CryptoException("Unknown Pgp Object: " + obj.ToString()); } return ret; }
/** * 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); } } }
private static PgpEncryptedDataList getEncryptedDataList(Stream encodedFile) { PgpObjectFactory factory = new PgpObjectFactory(encodedFile); PgpObject pgpObject = factory.NextPgpObject(); PgpEncryptedDataList encryptedDataList; if (pgpObject is PgpEncryptedDataList) { encryptedDataList = (PgpEncryptedDataList)pgpObject; } else { encryptedDataList = (PgpEncryptedDataList)factory.NextPgpObject(); } return encryptedDataList; }
public string DecryptPgpString(Stream inputStream) { string sOutput; PgpObjectFactory pgpFactory = new PgpObjectFactory(PgpUtilities.GetDecoderStream(inputStream)); // find secret key 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; foreach (PgpPublicKeyEncryptedData pubKeyDataItem in encryptedData.GetEncryptedDataObjects()) { privateKey = FindSecretKey(pubKeyDataItem.KeyId); 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; using (Stream unc = literalData.GetInputStream()) { sOutput = this.getStringFromStream(unc); } } else if (message is PgpLiteralData) { PgpLiteralData literalData = (PgpLiteralData)message; using (Stream unc = literalData.GetInputStream()) { sOutput = this.getStringFromStream(unc); } } 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 sOutput; }
/* * verify a clear text signed file */ private static void VerifyFile( Stream inputStream, Stream keyIn, string resultName) { ArmoredInputStream aIn = new ArmoredInputStream(inputStream); Stream outStr = File.Create(resultName); // // write out signed section using the local line separator. // note: trailing white space needs to be removed from the end of // each line RFC 4880 Section 7.1 // MemoryStream lineOut = new MemoryStream(); int lookAhead = ReadInputLine(lineOut, aIn); byte[] lineSep = LineSeparator; if (lookAhead != -1 && aIn.IsClearText()) { byte[] line = lineOut.ToArray(); outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line)); outStr.Write(lineSep, 0, lineSep.Length); while (lookAhead != -1 && aIn.IsClearText()) { lookAhead = ReadInputLine(lineOut, lookAhead, aIn); line = lineOut.ToArray(); outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line)); outStr.Write(lineSep, 0, lineSep.Length); } } else { // a single line file if (lookAhead != -1) { byte[] line = lineOut.ToArray(); outStr.Write(line, 0, GetLengthWithoutSeparatorOrTrailingWhitespace(line)); outStr.Write(lineSep, 0, lineSep.Length); } } outStr.Close(); PgpPublicKeyRingBundle pgpRings = new PgpPublicKeyRingBundle(keyIn); PgpObjectFactory pgpFact = new PgpObjectFactory(aIn); PgpSignatureList p3 = (PgpSignatureList) pgpFact.NextPgpObject(); PgpSignature sig = p3[0]; sig.InitVerify(pgpRings.GetPublicKey(sig.KeyId)); // // read the input, making sure we ignore the last newline. // Stream sigIn = File.OpenRead(resultName); lookAhead = ReadInputLine(lineOut, sigIn); ProcessLine(sig, lineOut.ToArray()); if (lookAhead != -1) { do { lookAhead = ReadInputLine(lineOut, lookAhead, sigIn); sig.Update((byte) '\r'); sig.Update((byte) '\n'); ProcessLine(sig, lineOut.ToArray()); } while (lookAhead != -1); } sigIn.Close(); if (sig.Verify()) { Console.WriteLine("signature verified."); } else { Console.WriteLine("signature verification failed."); } }
public static bool ReadAndVerifyFile(Stream inputStream, Stream keyIn, out Stream cleartextOut) { // Count any exception as BouncyCastle failing to parse something, because of corruption maybe? try { // Disposing this will close the underlying stream, which we don't want to do var armouredInputStream = new ArmoredInputStream(inputStream); // This stream is returned, so is not disposed var cleartextStream = new MemoryStream(); int chr; while ((chr = armouredInputStream.ReadByte()) >= 0 && armouredInputStream.IsClearText()) { cleartextStream.WriteByte((byte)chr); } // Strip the trailing newline if set... cleartextStream.Position = Math.Max(0, cleartextStream.Position - 2); int count = 0; if (cleartextStream.ReadByte() == '\r') count++; if (cleartextStream.ReadByte() == '\n') count++; cleartextStream.SetLength(cleartextStream.Length - count); cleartextStream.Position = 0; // This will either return inputStream, or a new ArmouredStream(inputStream) // Either way, disposing it will close the underlying stream, which we don't want to do var decoderStream = PgpUtilities.GetDecoderStream(inputStream); var pgpObjectFactory = new PgpObjectFactory(decoderStream); var signatureList = (PgpSignatureList)pgpObjectFactory.NextPgpObject(); var signature = signatureList[0]; var publicKeyRing = new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(keyIn)); var publicKey = publicKeyRing.GetPublicKey(signature.KeyId); signature.InitVerify(publicKey); while ((chr = cleartextStream.ReadByte()) > 0) { signature.Update((byte)chr); } cleartextStream.Position = 0; cleartextOut = cleartextStream; return signature.Verify(); } catch { cleartextOut = null; return false; } }
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> /// Decrypts the specified input stream. /// </summary> /// <param name="inputStream">The input stream.</param> /// <returns>Decrypted stream</returns> /// <exception cref="System.ArgumentNullException">inputStream;inputStream is null.</exception> /// <exception cref="Org.BouncyCastle.Bcpg.OpenPgp.PgpException"> /// encrypted message contains a signed message - not literal data. /// or /// message is not a simple encrypted file - type unknown. /// </exception> public PgpLiteralData DecryptStream(Stream inputStream) { if (inputStream == null) throw new ArgumentNullException("inputStream", "inputStream is null."); var decoderStream = PgpUtilities.GetDecoderStream(inputStream); var encryptedDataList = GetEncryptedDataList(decoderStream); var encryptedDataStream = GetEncryptedDataStream(encryptedDataList); var plainFact = new PgpObjectFactory(encryptedDataStream); var pgpObject = plainFact.NextPgpObject(); if (pgpObject is PgpCompressedData) pgpObject = DecompressMessage(pgpObject as PgpCompressedData); if (pgpObject is PgpLiteralData) return pgpObject as PgpLiteralData; if (pgpObject is PgpOnePassSignatureList) throw new PgpException("encrypted message contains a signed message - not literal data."); throw new PgpException("message is not a simple encrypted file - type unknown."); }