diff options
Diffstat (limited to 'crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs')
-rw-r--r-- | crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs b/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs new file mode 100644 index 000000000..7fb00a3b7 --- /dev/null +++ b/crypto/test/src/openpgp/examples/KeyBasedLargeFileProcessor.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections; +using System.IO; + +using Org.BouncyCastle.Bcpg.OpenPgp; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples +{ + /** + * A simple utility class that encrypts/decrypts public key based + * encryption large files. + * <p> + * To encrypt a file: KeyBasedLargeFileProcessor -e [-a|-ai] fileName publicKeyFile.<br/> + * If -a is specified the output file will be "ascii-armored". + * If -i is specified the output file will be have integrity checking added.</p> + * <p> + * To decrypt: KeyBasedLargeFileProcessor -d fileName secretKeyFile passPhrase.</p> + * <p> + * Note 1: this example will silently overwrite files, nor does it pay any attention to + * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase + * will have been used.</p> + * <p> + * Note 2: this example Generates partial packets to encode the file, the output it Generates + * will not be readable by older PGP products or products that don't support partial packet + * encoding.</p> + * <p> + * Note 3: if an empty file name has been specified in the literal data object contained in the + * encrypted packet a file with the name filename.out will be generated in the current working directory.</p> + */ + public sealed class KeyBasedLargeFileProcessor + { + private KeyBasedLargeFileProcessor() + { + } + + private static void DecryptFile( + string inputFileName, + string keyFileName, + char[] passwd, + string defaultFileName) + { + using (Stream input = File.OpenRead(inputFileName), + keyIn = File.OpenRead(keyFileName)) + { + DecryptFile(input, keyIn, passwd, defaultFileName); + } + } + + /** + * 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 void EncryptFile( + string outputFileName, + string inputFileName, + string encKeyFileName, + bool armor, + bool withIntegrityCheck) + { + PgpPublicKey encKey = PgpExampleUtilities.ReadPublicKey(encKeyFileName); + + using (Stream output = File.Create(outputFileName)) + { + EncryptFile(output, inputFileName, encKey, armor, withIntegrityCheck); + } + } + + private static void EncryptFile( + Stream outputStream, + string fileName, + PgpPublicKey encKey, + bool armor, + bool withIntegrityCheck) + { + if (armor) + { + outputStream = new ArmoredOutputStream(outputStream); + } + + try + { + PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom()); + + cPk.AddMethod(encKey); + + Stream cOut = cPk.Open(outputStream, new byte[1 << 16]); + + PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator( + CompressionAlgorithmTag.Zip); + + PgpUtilities.WriteFileToLiteralData( + comData.Open(cOut), + PgpLiteralData.Binary, + new FileInfo(fileName), + new byte[1 << 16]); + + comData.Close(); + + cOut.Close(); + + if (armor) + { + outputStream.Close(); + } + } + catch (PgpException e) + { + Console.Error.WriteLine(e); + + Exception underlyingException = e.InnerException; + if (underlyingException != null) + { + Console.Error.WriteLine(underlyingException.Message); + Console.Error.WriteLine(underlyingException.StackTrace); + } + } + } + + public static void Main( + string[] args) + { + if (args.Length == 0) + { + Console.Error.WriteLine("usage: KeyBasedLargeFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); + return; + } + + if (args[0].Equals("-e")) + { + if (args[1].Equals("-a") || args[1].Equals("-ai") || args[1].Equals("-ia")) + { + EncryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].IndexOf('i') > 0)); + } + else if (args[1].Equals("-i")) + { + EncryptFile(args[2] + ".bpg", args[2], args[3], false, true); + } + else + { + EncryptFile(args[1] + ".bpg", args[1], args[2], false, false); + } + } + else if (args[0].Equals("-d")) + { + DecryptFile(args[1], args[2], args[3].ToCharArray(), new FileInfo(args[1]).Name + ".out"); + } + else + { + Console.Error.WriteLine("usage: KeyBasedLargeFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]"); + } + } + } +} |