private void repeatHeaderTest() { MemoryStream bOut = new MemoryStream(); ArmoredOutputStream aOut = new ArmoredOutputStream(bOut); aOut.SetHeader("Comment", "Line 1"); aOut.AddHeader("Comment", "Line 2"); aOut.Write(sample, 0, sample.Length); aOut.Close(); MemoryStream bIn = new MemoryStream(bOut.ToArray(), false); ArmoredInputStream aIn = new ArmoredInputStream(bIn, true); string[] hdrs = aIn.GetArmorHeaders(); int count = 0; for (int i = 0; i != hdrs.Length; i++) { if (hdrs[i].IndexOf("Comment: ") == 0) { count++; } } IsEquals(2, count); }
/// <summary> /// Export the public keyring bundle. /// </summary> /// <remarks> /// Exports the public keyring bundle. /// </remarks> /// <param name="keys">The public keyring bundle to export.</param> /// <param name="stream">The output stream.</param> /// <param name="armor"><c>true</c> if the output should be armored; otherwise, <c>false</c>.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="keys"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public void Export(PgpPublicKeyRingBundle keys, Stream stream, bool armor) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (armor) { using (var armored = new ArmoredOutputStream(stream)) { armored.SetHeader("Version", null); keys.Encode(armored); armored.Flush(); } } else { keys.Encode(stream); } }
public string PublicKey(string email, Dictionary <string, string> headers) { Context = new CryptoContext(Context); var publicKey = GetPublicKeyForEncryption(email); var sigKey = GetSecretKeyForSigning(email); var literalData = new PgpLiteralDataGenerator(); var data = publicKey.GetEncoded(); using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) { armoredOut.SetHeader(header.Key, header.Value); } //using (var literalOut = literalData.Open( // armoredOut, // PgpLiteralData.Binary, // "email", // data.Length, // DateTime.UtcNow)) //{ // literalOut.Write(data, 0, data.Length); //} armoredOut.Write(data); } return(ASCIIEncoding.ASCII.GetString(sout.ToArray())); } }
/// <summary> /// Sign data using key /// </summary> /// <param name="data">Data to sign</param> /// <param name="key">Email address of key</param> /// <returns>Returns ascii armored signature</returns> public string Sign(byte[] data, string key, Dictionary <string, string> headers) { Context = new CryptoContext(Context); var senderKey = GetSecretKeyForSigning(key); if (senderKey == null) { throw new SecretKeyNotFoundException("Error, unable to locate signing key \"" + key + "\"."); } var compressedData = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip); var literalData = new PgpLiteralDataGenerator(); // Setup signature stuff // var tag = senderKey.PublicKey.Algorithm; var signatureData = new PgpSignatureGenerator(tag, HashAlgorithmTag.Sha256); signatureData.InitSign(PgpSignature.BinaryDocument, senderKey.ExtractPrivateKey(Context.Password)); foreach (string userId in senderKey.PublicKey.GetUserIds()) { var subPacketGenerator = new PgpSignatureSubpacketGenerator(); subPacketGenerator.SetSignerUserId(false, userId); signatureData.SetHashedSubpackets(subPacketGenerator.Generate()); // Just the first one! break; } // // using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) { armoredOut.SetHeader(header.Key, header.Value); } using (var compressedOut = compressedData.Open(armoredOut)) using (var outputStream = new BcpgOutputStream(compressedOut)) { signatureData.GenerateOnePassVersion(false).Encode(outputStream); using (var literalOut = literalData.Open(outputStream, 'b', "", data.Length, DateTime.Now)) { literalOut.Write(data, 0, data.Length); signatureData.Update(data); } signatureData.Generate().Encode(outputStream); } } return(ASCIIEncoding.ASCII.GetString(sout.ToArray())); } }
/// <summary> /// Encrypt data to a set of recipients /// </summary> /// <param name="data">Data to encrypt</param> /// <param name="recipients">List of email addresses</param> /// <param name="recipients">Headers to add to ascii armor</param> /// <returns>Returns ascii armored encrypted data</returns> public string Encrypt(byte[] data, IList <string> recipients, Dictionary <string, string> headers) { Context = new CryptoContext(Context); var compressedData = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip); var literalData = new PgpLiteralDataGenerator(); var cryptData = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, true, new SecureRandom()); foreach (var recipient in recipients) { var recipientKey = GetPublicKeyForEncryption(recipient); if (recipientKey == null) { throw new PublicKeyNotFoundException("Error, unable to find recipient key \"" + recipient + "\"."); } cryptData.AddMethod(recipientKey); } using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) { armoredOut.SetHeader(header.Key, header.Value); } using (var clearOut = new MemoryStream()) { using (var compressedOut = compressedData.Open(clearOut)) using (var literalOut = literalData.Open( compressedOut, PgpLiteralData.Binary, "email", data.Length, DateTime.UtcNow)) { literalOut.Write(data, 0, data.Length); } var clearData = clearOut.ToArray(); using (var encryptOut = cryptData.Open(armoredOut, clearData.Length)) { encryptOut.Write(clearData, 0, clearData.Length); } } } return(ASCIIEncoding.ASCII.GetString(sout.ToArray())); } }
public string PublicKey(string email, Dictionary <string, string> headers) { Context = new CryptoContext(Context); var publicKey = GetPublicKeyForEncryption(email); var data = publicKey.GetEncoded(); using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) { armoredOut.SetHeader(header.Key, header.Value); } armoredOut.Write(data); } return(ASCIIEncoding.ASCII.GetString(sout.ToArray())); } }
/// <summary> /// Signs then encrypts data using key and list of recipients. /// </summary> /// <param name="data">Data to encrypt</param> /// <param name="key">Signing key</param> /// <param name="recipients">List of keys to encrypt to</param> /// <returns>Returns ascii armored signed/encrypted data</returns> protected string SignAndEncrypt(byte[] data, string key, IList <string> recipients, Dictionary <string, string> headers, bool isBinary) { Context = new CryptoContext(Context); var senderKey = GetSecretKeyForEncryption(key); if (senderKey == null) { throw new SecretKeyNotFoundException("Error, Unable to locate sender encryption key \"" + key + "\"."); } var senderSignKey = GetSecretKeyForSigning(key); if (senderSignKey == null) { throw new SecretKeyNotFoundException("Error, Unable to locate sender signing key \"" + key + "\"."); } var compressedData = new PgpCompressedDataGenerator(CompressionAlgorithmTag.ZLib); var literalData = new PgpLiteralDataGenerator(); var cryptData = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, true, new SecureRandom()); foreach (var recipient in recipients) { var recipientKey = GetPublicKeyForEncryption(recipient); if (recipientKey == null) { throw new PublicKeyNotFoundException("Error, unable to find recipient key \"" + recipient + "\"."); } cryptData.AddMethod(recipientKey); } // Setup signature stuff // var signatureData = new PgpSignatureGenerator( senderSignKey.PublicKey.Algorithm, HashAlgorithmTag.Sha256); signatureData.InitSign( isBinary ? PgpSignature.BinaryDocument : PgpSignature.CanonicalTextDocument, senderSignKey.ExtractPrivateKey(Context.Password)); foreach (string userId in senderKey.PublicKey.GetUserIds()) { var subPacketGenerator = new PgpSignatureSubpacketGenerator(); subPacketGenerator.SetSignerUserId(false, userId); signatureData.SetHashedSubpackets(subPacketGenerator.Generate()); // Just the first one! break; } // // using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) { armoredOut.SetHeader(header.Key, header.Value); } using (var clearOut = new MemoryStream()) { using (var compressedOut = compressedData.Open(clearOut)) { signatureData.GenerateOnePassVersion(false).Encode(compressedOut); using (var literalOut = literalData.Open( compressedOut, isBinary ? PgpLiteralData.Binary : PgpLiteralData.Text, "", data.Length, DateTime.UtcNow)) { literalOut.Write(data, 0, data.Length); signatureData.Update(data, 0, data.Length); } signatureData.Generate().Encode(compressedOut); } var clearData = clearOut.ToArray(); using (var encryptOut = cryptData.Open(armoredOut, clearData.Length)) { encryptOut.Write(clearData, 0, clearData.Length); } } } return(ASCIIEncoding.ASCII.GetString(sout.ToArray())); } }
/// <summary> /// Sign data using key /// </summary> /// <param name="data">Data to sign</param> /// <param name="key">Email address of key</param> /// <returns>Returns ascii armored signature</returns> public string SignClear(string data, string key, Encoding encoding, Dictionary <string, string> headers) { Context = new CryptoContext(Context); var senderKey = GetSecretKeyForSigning(key); if (senderKey == null) { throw new SecretKeyNotFoundException("Error, unable to locate signing key \"" + key + "\"."); } // Setup signature stuff // var signatureData = new PgpSignatureGenerator(senderKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1); signatureData.InitSign(PgpSignature.CanonicalTextDocument, senderKey.ExtractPrivateKey(Context.Password)); foreach (string userId in senderKey.PublicKey.GetUserIds()) { var subPacketGenerator = new PgpSignatureSubpacketGenerator(); subPacketGenerator.SetSignerUserId(false, userId); signatureData.SetHashedSubpackets(subPacketGenerator.Generate()); // Just the first one! break; } // // using (var sout = new MemoryStream()) { using (var armoredOut = new ArmoredOutputStream(sout)) { foreach (var header in headers) { armoredOut.SetHeader(header.Key, header.Value); } armoredOut.BeginClearText(HashAlgorithmTag.Sha1); // Remove any extra trailing whitespace. // this should not include \r or \n. data = data.TrimEnd(null); using (var stringReader = new StringReader(data)) { do { var line = stringReader.ReadLine(); if (line == null) { break; } // Lines must have all white space removed line = line.TrimEnd(null); line = line.TrimEnd(new char[] { ' ', '\t', '\r', '\n' }); line += "\r\n"; signatureData.Update(encoding.GetBytes(line)); armoredOut.Write(encoding.GetBytes(line)); }while (true); } // Write extra line before signature block. armoredOut.Write(encoding.GetBytes("\r\n")); armoredOut.EndClearText(); using (var outputStream = new BcpgOutputStream(armoredOut)) { signatureData.Generate().Encode(outputStream); } } return(encoding.GetString(sout.ToArray())); } }
// Based on http://jopinblog.wordpress.com/2008/06/23/pgp-single-pass-sign-and-encrypt-with-bouncy-castle/ /// <summary> /// /// </summary> /// <param name="actualFileName"></param> /// <param name="embeddedFileName"></param> /// <param name="pgpSecKey"></param> /// <param name="outputFileName"></param> /// <param name="password"></param> /// <param name="armor"></param> /// <param name="withIntegrityCheck"></param> /// <param name="encKeys"></param> /// <param name="compressionName"></param> /// <param name="digestName"></param> public static void SignAndEncryptFile(string actualFileName, string embeddedFileName, PgpSecretKey pgpSecKey, string outputFileName, char[] password, bool armor, bool withIntegrityCheck, PgpPublicKey[] encKeys, string compressionName, string digestName) { CompressionAlgorithmTag comptype; if (string.Equals(compressionName, "Uncompressed", StringComparison.CurrentCultureIgnoreCase)) { comptype = CompressionAlgorithmTag.Uncompressed; } else if (string.Equals(compressionName, "Zip", StringComparison.CurrentCultureIgnoreCase)) { comptype = CompressionAlgorithmTag.Zip; } else if (string.Equals(compressionName, "Zlib", StringComparison.CurrentCultureIgnoreCase)) { comptype = CompressionAlgorithmTag.ZLib; } else if (string.Equals(compressionName, "BZip2", StringComparison.CurrentCultureIgnoreCase)) { comptype = CompressionAlgorithmTag.BZip2; } else { comptype = CompressionAlgorithmTag.Zip; } HashAlgorithmTag digest; if (string.Equals(digestName, "Sha256", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.Sha256; } else if (string.Equals(digestName, "Sha384", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.Sha384; } else if (string.Equals(digestName, "Sha512", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.Sha512; } else if (string.Equals(digestName, "MD5", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.MD5; } else if (string.Equals(digestName, "RipeMD160", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.RipeMD160; } else { digest = HashAlgorithmTag.Sha512; } const int bufferSize = 1 << 16; // should always be power of 2 Stream outputStream = File.Open(outputFileName, FileMode.Create); if (armor) { var aOutStream = new ArmoredOutputStream(outputStream); aOutStream.SetHeader("Version", "Posh-OpenPGP"); outputStream = aOutStream; } // Init encrypted data generator var encryptedDataGenerator = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom()); // add keys to encrypt to foreach (var encKey in encKeys) { encryptedDataGenerator.AddMethod(encKey); } var encryptedOut = encryptedDataGenerator.Open(outputStream, new byte[bufferSize]); // Init compression var compressedDataGenerator = new PgpCompressedDataGenerator(comptype); var compressedOut = compressedDataGenerator.Open(encryptedOut); // Init signature PgpPrivateKey pgpPrivKey; try { pgpPrivKey = pgpSecKey.ExtractPrivateKey(password); } catch { throw new PgpException("Wrong Passphrase, could not extract private key."); } var signatureGenerator = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, digest); signatureGenerator.InitSign(PgpSignature.BinaryDocument, pgpPrivKey); foreach (string userId in pgpSecKey.PublicKey.GetUserIds()) { var spGen = new PgpSignatureSubpacketGenerator(); spGen.SetSignerUserId(false, userId); signatureGenerator.SetHashedSubpackets(spGen.Generate()); // Just the first one! break; } signatureGenerator.GenerateOnePassVersion(false).Encode(compressedOut); // Create the Literal Data generator output stream var literalDataGenerator = new PgpLiteralDataGenerator(); var embeddedFile = new FileInfo(embeddedFileName); var actualFile = new FileInfo(actualFileName); var literalOut = literalDataGenerator.Open(compressedOut, PgpLiteralData.Binary, embeddedFile.Name, DateTime.UtcNow, new byte[bufferSize]); // Open the input file var inputStream = actualFile.OpenRead(); var buf = new byte[bufferSize]; 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> /// /// </summary> /// <param name="outputStream"></param> /// <param name="fileName"></param> /// <param name="encKeys"></param> /// <param name="armor"></param> /// <param name="withIntegrityCheck"></param> /// <param name="compressionName"></param> /// <param name="symmAlgorithm"></param> public static void EncryptFile( Stream outputStream, string fileName, PgpPublicKey[] encKeys, bool armor, bool withIntegrityCheck, string compressionName, string symmAlgorithm) { if (armor) { var aOutStream = new ArmoredOutputStream(outputStream); aOutStream.SetHeader("Version", "Posh-OpenPGP"); outputStream = aOutStream; } CompressionAlgorithmTag comptype; if (string.Equals(compressionName, "Uncompressed", StringComparison.CurrentCultureIgnoreCase)) { comptype = CompressionAlgorithmTag.Uncompressed; } else if (string.Equals(compressionName, "Zip", StringComparison.CurrentCultureIgnoreCase)) { comptype = CompressionAlgorithmTag.Zip; } else if (string.Equals(compressionName, "Zlib", StringComparison.CurrentCultureIgnoreCase)) { comptype = CompressionAlgorithmTag.ZLib; } else if (string.Equals(compressionName, "BZip2", StringComparison.CurrentCultureIgnoreCase)) { comptype = CompressionAlgorithmTag.BZip2; } else { comptype = CompressionAlgorithmTag.Zip; } SymmetricKeyAlgorithmTag symtype; if (string.Equals(symmAlgorithm, "Aes256", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.Aes256; } else if (string.Equals(symmAlgorithm, "Aes192", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.Aes192; } else if (string.Equals(symmAlgorithm, "Aes128", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.Aes128; } else if (string.Equals(symmAlgorithm, "Blowfish", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.Blowfish; } else if (string.Equals(symmAlgorithm, "Twofish", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.Twofish; } else if (string.Equals(symmAlgorithm, "Cast5", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.Cast5; } else if (string.Equals(symmAlgorithm, "Idea", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.Idea; } else if (string.Equals(symmAlgorithm, "DES", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.Des; } else if (string.Equals(symmAlgorithm, "3DES", StringComparison.CurrentCultureIgnoreCase)) { symtype = SymmetricKeyAlgorithmTag.TripleDes; } else { symtype = SymmetricKeyAlgorithmTag.Twofish; } var bOut = new MemoryStream(); var comData = new PgpCompressedDataGenerator( comptype); PgpUtilities.WriteFileToLiteralData( comData.Open(bOut), PgpLiteralData.Binary, new FileInfo(fileName)); comData.Close(); var cPk = new PgpEncryptedDataGenerator( symtype, withIntegrityCheck, new SecureRandom()); foreach (var encKey in encKeys) { cPk.AddMethod(encKey); } var bytes = bOut.ToArray(); var cOut = cPk.Open(outputStream, bytes.Length); cOut.Write(bytes, 0, bytes.Length); cOut.Close(); if (armor) { outputStream.Close(); } }
/* * create a clear text signed file. */ public static void SignFile( //string fileName, Stream fIn, PgpSecretKey pgpSecKey, Stream outputStream, char[] pass, string digestName, bool version = true ) { HashAlgorithmTag digest; if (string.Equals(digestName, "Sha256", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.Sha256; } else if (string.Equals(digestName, "Sha384", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.Sha384; } else if (string.Equals(digestName, "Sha512", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.Sha512; } else if (string.Equals(digestName, "MD5", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.MD5; } else if (string.Equals(digestName, "RipeMD160", StringComparison.CurrentCultureIgnoreCase)) { digest = HashAlgorithmTag.RipeMD160; } else { digest = HashAlgorithmTag.Sha512; } // Instanciate signature generator. var sGen = new PgpSignatureGenerator(pgpSecKey.PublicKey.Algorithm, digest); var spGen = new PgpSignatureSubpacketGenerator(); // Extract private key PgpPrivateKey pgpPrivKey; try { pgpPrivKey = pgpSecKey.ExtractPrivateKey(pass); sGen.InitSign(PgpSignature.CanonicalTextDocument, pgpPrivKey); } catch { throw new PgpException("Wrong Passphrase, could not extract private key."); } var enumerator = pgpSecKey.PublicKey.GetUserIds().GetEnumerator(); if (enumerator.MoveNext()) { spGen.SetSignerUserId(false, (string)enumerator.Current); sGen.SetHashedSubpackets(spGen.Generate()); } var aOut = new ArmoredOutputStream(outputStream); if (version) { aOut.SetHeader("Version", "Posh-OpenPGP"); } aOut.BeginClearText(digest); // // note the last \n/\r/\r\n in the file is ignored // var lineOut = new MemoryStream(); var lookAhead = ReadInputLine(lineOut, fIn); ProcessLine(aOut, sGen, lineOut.ToArray()); if (lookAhead != -1) { do { lookAhead = ReadInputLine(lineOut, lookAhead, fIn); sGen.Update((byte)'\r'); sGen.Update((byte)'\n'); ProcessLine(aOut, sGen, lineOut.ToArray()); }while (lookAhead != -1); } fIn.Close(); aOut.EndClearText(); var bOut = new BcpgOutputStream(aOut); sGen.Generate().Encode(bOut); aOut.Close(); }
public static void AddSignature(PgpPublicKey key, KeyStoreDB keyDb, string keyExportName, PgpSecretKey secKey, char[] passPhrase, SignatureOperation op, DateTime expiryDate, PgpSignature certLevel = null, string userId = "") { string fileData = string.Empty; bool useTemp = true; if (key == null) { throw new ArgumentNullException("key"); } if (keyDb == null) { throw new ArgumentNullException("keyDb"); } if (!Enum.IsDefined(typeof(SignatureOperation), op)) { throw new ArgumentOutOfRangeException(string.Format("op: {0}", op)); } AlgorithmAgreement algorithms = new AlgorithmAgreement(new List <PgpPublicKey>() { key }); PgpPrivateKey privateKey = secKey.ExtractPrivateKey(passPhrase); PgpSignatureGenerator sigGen = new PgpSignatureGenerator(key.Algorithm, algorithms.AgreedHashAlgorithm); switch (op) { case SignatureOperation.AddUserId: break; case SignatureOperation.RevokeKey: MemoryStream mStream = new MemoryStream(); using (ArmoredOutputStream outArmour = new ArmoredOutputStream(mStream)) { outArmour.SetHeader("Version", "Lynx Privacy"); sigGen.InitSign(PgpSignature.KeyRevocation, privateKey); PgpSignature sig = sigGen.GenerateCertification(secKey.PublicKey); PgpPublicKey.AddCertification(secKey.PublicKey, sig); sig.InitVerify(secKey.PublicKey); if (!sig.VerifyCertification(secKey.PublicKey)) { throw new PgpException("revocation verification failed."); } sig.Encode(outArmour); outArmour.Close(); } mStream.Position = 0; StreamReader srdr = new StreamReader(mStream); string armour = srdr.ReadToEnd(); string outstr = armour.Replace("BEGIN PGP SIGNATURE", "BEGIN PGP PUBLIC KEY BLOCK") .Replace("END PGP SIGNATURE", "END PGP PUBLIC KEY BLOCK"); mStream.Close(); if (string.IsNullOrEmpty(keyExportName)) { useTemp = true; string tempPath = Path.GetTempPath(); keyExportName = Path.Combine(tempPath, Guid.NewGuid().ToString() + ".tmppgp"); } File.WriteAllText(keyExportName, outstr); keyExportName = ""; //Debug.Assert(secKey.PublicKey.IsRevoked() == true); break; case SignatureOperation.SetKeyExpiry: break; case SignatureOperation.CertifyKey: break; default: break; } if (secKey.PublicKey != null) { if (string.IsNullOrEmpty(keyExportName)) { useTemp = true; string tempPath = Path.GetTempPath(); keyExportName = Path.Combine(tempPath, Guid.NewGuid().ToString() + ".tmppgp"); } ExportKey expKey = new ExportKey(keyDb); expKey.UpdateDbSecretKey(secKey, keyExportName); if (useTemp) { //File.Delete(keyExportName); } } }
/// <summary> /// /// </summary> /// <param name="SecretKey"></param> /// <param name="Passhrase"></param> /// <param name="Reason"></param> /// <param name="RevokeDescription"></param> /// <param name="OutFile"></param> public static void GenerateCertificate(PgpSecretKey SecretKey, char[] Passhrase, string Reason, string RevokeDescription, string OutFile) { RevocationReasonTag RevokeReason; if (string.Equals(Reason, "Compromised", StringComparison.CurrentCultureIgnoreCase)) { RevokeReason = RevocationReasonTag.KeyCompromised; } else if (string.Equals(Reason, "Retired", StringComparison.CurrentCultureIgnoreCase)) { RevokeReason = RevocationReasonTag.KeyRetired; } else if (string.Equals(Reason, "Superseded", StringComparison.CurrentCultureIgnoreCase)) { RevokeReason = RevocationReasonTag.KeySuperseded; } else if (string.Equals(Reason, "NoReason", StringComparison.CurrentCultureIgnoreCase)) { RevokeReason = RevocationReasonTag.NoReason; } else if (string.Equals(Reason, "Invalid", StringComparison.CurrentCultureIgnoreCase)) { RevokeReason = RevocationReasonTag.UserNoLongerValid; } else { RevokeReason = RevocationReasonTag.NoReason; } // Create the subpacket generators for the hashed and unhashed packets. var subHashGenerator = new PgpSignatureSubpacketGenerator(); var subUnHashGenerator = new PgpSignatureSubpacketGenerator(); // Extract the private key from the secret key. PgpPrivateKey privKey; try { privKey = SecretKey.ExtractPrivateKey(Passhrase); } catch { throw new PgpException("Wrong Passphrase, could not extract private key."); } // Create a signature generator and initialize it for key revocation. var generator = new PgpSignatureGenerator(SecretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha256); generator.InitSign(PgpSignature.KeyRevocation, privKey, new SecureRandom()); // Create the hashed and unhashed subpackets and add them to the signature generator. subHashGenerator.SetSignatureCreationTime(false, DateTime.UtcNow); subHashGenerator.SetRevocationReason(false, RevokeReason, RevokeDescription); subUnHashGenerator.SetRevocationKey(false, SecretKey.PublicKey.Algorithm, SecretKey.PublicKey.GetFingerprint()); generator.SetHashedSubpackets(subHashGenerator.Generate()); generator.SetUnhashedSubpackets(subUnHashGenerator.Generate()); // Generate the certification var signature = generator.GenerateCertification(SecretKey.PublicKey); // Create the armour output stream and set the headers var mStream = new MemoryStream(); using (var outAStream = new ArmoredOutputStream(mStream)) { outAStream.SetHeader("Version", "Posh-OpenPGP"); outAStream.SetHeader("Comment", "A revocation certificate should follow"); signature.Encode(outAStream); outAStream.Close(); } // Turn the stream in to armour text and make sure we replace the propper headers mStream.Position = 0; var sr = new StreamReader(mStream); var armour = sr.ReadToEnd(); var outstr = armour.Replace("BEGIN PGP SIGNATURE", "BEGIN PGP PUBLIC KEY BLOCK").Replace("END PGP SIGNATURE", "END PGP PUBLIC KEY BLOCK"); // Save the string to the specified file. System.IO.File.WriteAllText(OutFile, outstr); }