Beispiel #1
0
        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()));
            }
        }
		public void DecryptHiddenRecipient()
		{
			var asc = @"-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.13 (MingW32)

hQEMAwAAAAAAAAAAAQgAjccvC3wJSL/FDp0yBkq3ktYHzFDk31whvAG6JX2ZoJzP
4bqkPxEOYKFur+ioxHN1TKrwRMQsjAHrfsBVkWxFNx/UqDeZSGGlreRPcn/Vv83x
Cs8J/5OaE/8iVzXSplENPI8o7Ahb8+7ewllJdmzr6E0gOl5VCUoFTTLq8rkzXg6c
VzdFC71QMr0x+Ef37zJwxkBsRWOBq6Kdwa7o5DXeyVJ54QsBwJJXesF3zKKmjE8y
8kdzLJqbK78yzmif0fa/IVizf+rQTYhiFuqGdnKjIpNr5YVbLofTgDveNSTB7XOg
Yw5/Va1VG6Om1puPeVBAXwr3ZVwZehG4H5xL2dhFONJ+AejHz6CeT8Fz1badKW92
VFL2bm1FZYHwjZjwIGXMR1CAbE/rQs+iS9b2bNLWPOAg/FB5zcUQ6Cc7IkH4hd3H
4PWtXsmwqLB1kKl+DYvy16rCvFPhvHdJO0Z3z/yn5520yx+TQ0brUWGUEkF0WbMR
3ioXxFhpcXhmPmTYqctK
=s0gQ
-----END PGP MESSAGE-----
";

			var context = new CryptoContext(GetPasswordCallback, Pubring, Secring, "rsa", "sha-1");
			var crypto = new PgpCrypto(context);

			var clear = crypto.DecryptAndVerify(Encoding.UTF8.GetBytes(asc));

			Assert.NotNull(clear);
			Assert.AreEqual(File.ReadAllText(Path.Combine(Data, "msg1.bin")),
				Encoding.UTF8.GetString(clear));
		}
Beispiel #3
0
        /// <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.FailedIntegrityCheck)
                        {
                            throw new VerifyException("Error, failed validation check.");
                        }

                        if (!Context.IsSigned)
                        {
                            throw new CryptoException("Error, message is not signed.");
                        }

                        return(Context.SignatureValidated);
                    }
                }

            return(VerifyClear(data));
        }
		public void DecryptAndVerifyCryptix()
		{
			var asc = @"-----BEGIN PGP MESSAGE-----
Version: Cryptix OpenPGP 0.20050418

hIwDblSySC/BGaQBBACXq8hOXnGCsCrBt3YU3XgxR+KBrwNh5U/hseMODMY+Gg+w
jHARa7h9r7ekw+UEw3e2CJzoI0TL1LYM7o3N79mBqUJMIRjyV+dFaE8/it+Xphv3
+B+DyyrlO7Y013MM9v8o7UF5wJyxyIMedeodfboVYOuEYZGMOCZNeP9WgbZIa6Tv
qC+dKk++UQH1nAq7PWl2hrXHl3wWK/kZ+O/bGMFDEpbDL2PenLEy47kvQT4fGRZT
iB+O4gP38rpoPF/s1agFtwfNkWHBGlwHOqBpjuT1ya56aPfkDsNGTW0/Jp+dnTIH
YYGwwCEOQLJemt5ELK8+BZEMRi/5zCmxF/4z9yRUP6IqrotQMWuxjm2d8Z4QhecK
j/nOOPQyDT/WQLFFOI4whGy9D8QHkXNrqsGHY1YORN3s8Di0+ARkSFtRMhjEgzA0
+U+RVtsnaH4pw8pzbHEpZS9Znt75ep+Vune/cyiPfJuvw5uQlns9bLAtHKtt9NY=
=uF5e
-----END PGP MESSAGE-----
";
			var context = new CryptoContext(GetPasswordCallback, Pubring, Secring, "rsa", "sha-1");
			var crypto = new PgpCrypto(context);

			var clear = crypto.DecryptAndVerify(Encoding.UTF8.GetBytes(asc), true);

			Assert.NotNull(clear);
			Assert.AreEqual("This is a test message.\r\nThis is another line.\r\n",
				Encoding.UTF8.GetString(clear));
		}
		public void UnicodeWithNonUnicodePageTest()
		{
			var clear = @"Hi Meddington,

i think i have found the issue.
I write this mail as - only text - message.
If another receive this email, my signature email and webaddress are i
nterpreted as links and will be changed by outlook to html elements.


Mit freundlichen Grüßen,
Sebastian Lutz

Baebeca Solutions - Lutz
E-Mail: [email protected]
Tel. Büro: 02261 - 9202935
Tel. Mobil: 0171 - 6431821
Web: https://www.baebeca.de
PGP Key: 0x5AD0240C
";

			var context = new CryptoContext(GetPasswordCallback, Pubring, Secring, "rsa", "sha-1");
			var crypto = new PgpCrypto(context);
			var encoding = Encoding.GetEncoding(28591);

			var clearSig = crypto.SignClear(clear, "*****@*****.**", encoding, new Dictionary<string, string>());
			var ret = crypto.VerifyClear(encoding.GetBytes(clearSig));

			Assert.IsTrue(ret);
		}
Beispiel #6
0
        /// <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()));
            }
        }
        static void Main(string[] args)
        {
            var context = new CryptoContext(args[0].ToCharArray());
            var crypto = new PgpCrypto(context);

            if (crypto.VerifyClear(File.ReadAllBytes(args[1])))
                Console.WriteLine("Valid");
            else
                Console.WriteLine("Invalid");
        }
Beispiel #8
0
        /// <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);
                    }
                }
            }
        }
Beispiel #9
0
        /// <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()));
            }
        }
Beispiel #10
0
        static void Main(string[] args)
        {
            var context = new CryptoContext(args[0].ToCharArray());
            var crypto = new PgpCrypto(context);

            Console.WriteLine(ASCIIEncoding.ASCII.GetString(crypto.DecryptAndVerify(File.ReadAllBytes(args[1]), true)));

            if (context.FailedIntegrityCheck)
                Console.WriteLine("Failed integrity check");

            Console.WriteLine("Done");
        }
Beispiel #11
0
		public void CorrectEncryptKeyTest()
		{
			var context = new CryptoContext(
				GetPasswordCallback,
				@"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\pubring.gpg",
				@"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\secring.gpg",
				"rsa", "sha-1");
			var crypto = new PgpCrypto(context);

			var key = crypto.GetSecretKeyForEncryption("*****@*****.**");

			Assert.AreEqual(long.Parse("BED5C89E8F3ABF8E", NumberStyles.HexNumber), key.KeyId);
		}
Beispiel #12
0
		public void CorrectSignKeyTest()
		{
			var context = new CryptoContext(
				GetPasswordCallback,
				@"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\pubring.gpg",
				@"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\secring.gpg",
				"rsa", "sha-1");
			var crypto = new PgpCrypto(context);

			PgpSecretKey masterKey;
			var signKey = crypto.GetSecretKeyForSigning("*****@*****.**", out masterKey);

			Assert.AreEqual(long.Parse("FB3B2D2D92C7039A", NumberStyles.HexNumber), signKey.KeyId);
		}
Beispiel #13
0
        /// <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;
                    }
                }
            }
        }
        public CryptoContext(CryptoContext context)
        {
            if (context == null)
                throw new Exception("Error, crypto context is null.");

            IsEncrypted = false;
            IsSigned = false;
            SignatureValidated = false;
            IsCompressed = false;
            OnePassSignature = null;
            Signature = null;
            SignedBy = null;

            Password = context.Password;
            PublicKeyRingFile = context.PublicKeyRingFile;
            PrivateKeyRingFile = context.PrivateKeyRingFile;
        }
Beispiel #15
0
		public void ExportPublicKey()
		{
			var expectedOutput = @"-----BEGIN PGP PUBLIC KEY BLOCK-----

mQENBFY1R3kBCADPO0yyqcHmBt7tXs28sjiXW+xnSoqgD7x63f5ePUsJ2emDff/Z
FwvmW+EAlgQ17AYBetz8uuFHgo41uNfOEVDphzBVOuZ9r/wtNOzhaT2fXyo4HTA0
6K5/c5/WcyXg/AnvM2SHQ1WfqV4MZ3l/umrKawFLZVuRKmQQmcuMvPJTq5lI6nDz
L98b62DUXb/3pZCVFuJNjdoxAy2KsTKl5g0rxDM/I6V7t4t4udWZ08Gk0iuOSRON
aG91C/H63KIOEwHtxpjQmS7QCb6H9BUKsO0JwvQYvfUYFQxPjL1GU7Wpg9xY6mT3
qJJLQ4XTlwcUENbeOzgnyqUnlGNibxmB1JFrABEBAAG0F1JzYSBKaWxsIDxyc2FA
amlsbC5jb20+iQE4BBMBAgAiBQJWNUd5AhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIe
AQIXgAAKCRD7Oy0tkscDmvBACACFsrLKVJ1bOMMNGmXWwyy6ftnlpNIUI1D02tKN
ZD4sR1sRHQT79TBaYG39DeJjZpXPNBpKqFV6Ux6R9xPnr0oyschxSFj855Cu08Ls
7MHIzM+CGGsF//mxPzJoNQWLsYWeoDnwHSqAMj4ApdTENZQoOZK2jBM68V/fwQKB
c9FhE5I26Sc2/fkH+CqCfkqh1MIzbz2Me6QPEVDVmYwwHkKmKfB6HTL1o/+iNeFb
9/813HhvpUK+iYKsIW3A17bANr3ex4j4gFS6nnGSd4zm5RvHxcp0iZW08SiaEgrF
dUXA3GVNMgjJbxdp9t1NulolXPcDiO5yfjIgouj3oVdM+lF8sAIAA7kBDQRWNUd5
AQgAzDaJVBd1Yh3GchXpVmYPQOFK7HHX7D1/Yn+YvfkbO4EKEzVZ1iIoekCzXeZl
Q5hO0cpyhblXaJJAUGNJmKLL5z/OkcfG7FUsZgnhdkXNVejVXWJZv+HoHKDHXdjJ
i3c4no2cqzzeLBut3fsqThargLLqrWyadvGQRkxOtTsQVHLrgnID33Jdh9hsYMvB
3/mHUT4g+ZU98ekA5vTKZii/dcy2160GKOMP1PmvcKrOm0m399OZgyh0sTeQylZu
MPrVFU6KxA+g5708OpLrpasFkWDnzwfCAl6l+GdU29QfW1rfLOPj81Ip39ppanhQ
xkjmgqgpARK96cnfZ126HWx1GwARAQABiQEfBBgBAgAJBQJWNUd5AhsMAAoJEPs7
LS2SxwOav9MIAJyfqlXPTrxtnXvB85/qXyhB6KWkhOT9TPR3H9UHzSDyZVus0aza
W/Qe59QqpSjLPBvKJs+FhhLPHjS4qPjExHIo/jSWZ5nKW15UPdQdhj+JGRKXLZRd
7ENvjw9Md922G+M/z9V0mqSZlwDwnMLy5/dQmduZdysIXeqvPQk3ZDQbH2kyPxHF
oa3UhjC8/UZYVfD0EmO6b9wtWDCfgr0z47TMr7myn1NMwWSn13ZXYvwXdlpSx1Ps
l1ISDLDE94wcCDzbnPvXXCFJ26ATYlX8PPI6jmp9VHU/FdQtfVd9+3TprboR9JVl
qVpBT5OoBs9xe9FVirifzbAZ4JCrWcAJ1eKwAgAD
=uWzT
-----END PGP PUBLIC KEY BLOCK-----
";

			var context = new CryptoContext(
				GetPasswordCallback,
				@"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\pubring.gpg",
				@"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\secring.gpg",
				"rsa", "sha-1");
			var crypto = new PgpCrypto(context);

			var key = crypto.PublicKey("*****@*****.**", new Dictionary<string,string>());

			Assert.AreEqual(expectedOutput, key);
		}
Beispiel #16
0
        public CryptoContext(CryptoContext context)
        {
            if (context == null)
            {
                throw new Exception("Error, crypto context is null.");
            }

            IsEncrypted        = false;
            IsSigned           = false;
            SignatureValidated = false;
            IsCompressed       = false;
            OnePassSignature   = null;
            Signature          = null;
            SignedBy           = null;

            Password           = context.Password;
            PublicKeyRingFile  = context.PublicKeyRingFile;
            PrivateKeyRingFile = context.PrivateKeyRingFile;
        }
Beispiel #17
0
        /// <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).Contains("-----BEGIN PGP MESSAGE-----");

            using (var dataIn = new MemoryStream(data))
            {
                if (!isArmored)
                {
                    return(DecryptBytes(ignoreIntegrityCheck, dataIn));
                }

                using (var armoredIn = new ArmoredInputStream(dataIn))
                {
                    return(DecryptBytes(ignoreIntegrityCheck, armoredIn));
                }
            }
        }
        /// <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;
                    }
                }
            }
        }
Beispiel #19
0
        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()));
            }
        }
Beispiel #20
0
		public void VerifyEmail()
		{
			var asc = @"-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

i think i have found the issue.
I write this mail as - only text - message.
If another receive this email, my signature email and webaddress are i

nterpreted as links and will be changed by outlook to html elements.


Mit freundlichen Grüßen,
Sebastian Lutz

Baebeca Solutions - Lutz
E-Mail: [email protected] <mailto:[email protected]> Tel. Büro: 02261 - 9202935 Tel. Mobil: 0171 - 6431821
Web: https://www.baebeca.de <https://www.baebeca.de> PGP Key: 0x5AD0240C

-----BEGIN PGP SIGNATURE-----

iQEcBAEBCAAGBQJWPGGdAAoJEEKN+AfqKr312lEIAJ6i2C/8ZWoU3K2T0JWUXLRJ
Rycl2f9IqZkTOA4/x39QX+MuJ8N20ek5YDDeljZZdZnuEkBKvWZUZ/E6f49JJv6p
MBpNZgPua13fjERPIlNNV5CLxXDqhaH+jFaP8hCzthuNMKuW4iPy2wppX4f+EXbH
O5NMNUOtwD149S8y3DDx90Y6RdvQL9HYijDzHHpko1RqRL2lrkxrzOyTk0R0JoS2
C4h6ab6bixbmV6QBCtzOFpp6nkxWT27CFRIN0yz9t6psGZQgEVYP7RQlmFqS0jr4
9pTfjB6djoxrLxNiQMHsaH0UKeC+3AQdfvAloaIljULuBfa9BV8U5CXJBy1JUiM=
=K83z
-----END PGP SIGNATURE-----
";
			var context = new CryptoContext(GetPasswordCallback, Pubring, Secring, "rsa", "sha-1");
			var crypto = new PgpCrypto(context);
			var encoding = Encoding.GetEncoding(28591);

			var ret = crypto.VerifyClear(encoding.GetBytes(asc));

			Assert.IsTrue(ret);

		}
		internal void VerifyEmail(Outlook.MailItem mailItem)
		{
			string mail = mailItem.Body;
			Outlook.OlBodyFormat mailType = mailItem.BodyFormat;

			if (Regex.IsMatch(mailItem.Body, _pgpSignedHeader) == false)
			{
				MessageBox.Show(
					Localized.ErrorMsgNotSigned,
					"Mail is not signed",
					MessageBoxButtons.OK,
					MessageBoxIcon.Exclamation);

				return;
			}

			var Context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest);
			var Crypto = new PgpCrypto(Context);

			try
			{
				if (Crypto.Verify(_encoding.GetBytes(mail)))
				{
					Context = Crypto.Context;

					var message = "** " + string.Format(Localized.MsgValidSig,
						Context.SignedByUserId, Context.SignedByKeyId) + "\n\n";

					if (mailType == Outlook.OlBodyFormat.olFormatPlain)
					{
						mailItem.Body = message + mailItem.Body;
					}
				}
				else
				{
					Context = Crypto.Context;

					var message = "** " + string.Format(Localized.MsgInvalidSig,
						Context.SignedByUserId, Context.SignedByKeyId) + "\n\n";

					if (mailType == Outlook.OlBodyFormat.olFormatPlain)
					{
						mailItem.Body = message + mailItem.Body;
					}
				}
			}
			catch (PublicKeyNotFoundException)
			{
				Context = Crypto.Context;

				string message = "** "+ Localized.MsgSigMissingPubKey+"\n\n";

				if (mailType == Outlook.OlBodyFormat.olFormatPlain)
				{
					mailItem.Body = message + mailItem.Body;
				}
			}
			catch (Exception ex)
			{
				WriteErrorData("VerifyEmail", ex);
				MessageBox.Show(
					ex.Message,
					"Outlook Privacy Error",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error);
			}
		}
        /// <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);
        }
Beispiel #23
0
        /// <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()));
            }
        }
        /// <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;
                }
            }
        }
Beispiel #25
0
 public PgpCrypto(CryptoContext context)
 {
     Context = context;
 }
		private string SignAndEncryptAttachment(byte[] data, string key, IList<string> recipients)
		{
			try
			{
				var context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest);
				var crypto = new PgpCrypto(context);
				var headers = new Dictionary<string, string>();
				headers["Version"] = "Outlook Privacy Plugin";
				headers["Charset"] = _encoding.WebName;

				return crypto.SignAndEncryptBinary(data, key, recipients, headers);
			}
			catch (Exception ex)
			{
				MessageBox.Show(
					ex.Message,
					"Outlook Privacy Error",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error);

				throw;
			}
		}
		internal void VerifyEmail(Outlook.MailItem mailItem)
		{
			var encoding = GetEncodingFromMail(mailItem);
			var mail = string.Empty;

			// Try two different methods to get the message body
			try
			{
				mail = encoding.GetString(
					(byte[])mailItem.PropertyAccessor.GetProperty(
						"http://schemas.microsoft.com/mapi/string/{4E3A7680-B77A-11D0-9DA5-00C04FD65685}/Internet Charset Body/0x00000102"));
			}
			catch (Exception)
			{
				try
				{
					mail = (string)mailItem.PropertyAccessor.GetProperty(
							"http://schemas.microsoft.com/mapi/proptag/0x1000001F"); // PR_BODY
				}
				catch (Exception)
				{
					mail = mailItem.Body;
				}
			}

			if (Regex.IsMatch(mail, _pgpSignedHeader) == false)
			{
				MessageBox.Show(
					Localized.ErrorMsgNotSigned,
					Localized.ErrorDialogTitle,
					MessageBoxButtons.OK,
					MessageBoxIcon.Exclamation);

				return;
			}

			var context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest);
			var crypto = new PgpCrypto(context);
			mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatPlain;

			try
			{
				var message = string.Empty;

				if (crypto.Verify(_encoding.GetBytes(mail)))
					message = "** " + string.Format(Localized.MsgValidSig,
						crypto.Context.SignedByUserId, crypto.Context.SignedByKeyId) + "\n\n";

				else
					message = "** " + string.Format(Localized.MsgInvalidSig,
						crypto.Context.SignedByUserId, crypto.Context.SignedByKeyId) + "\n\n";

				mailItem.Body = message + mailItem.Body;
			}
			catch (PublicKeyNotFoundException)
			{
				var message = "** "+ Localized.MsgSigMissingPubKey+"\n\n";

				mailItem.Body = message + mailItem.Body;
			}
			catch (Exception ex)
			{
				WriteErrorData("VerifyEmail", ex);
				MessageBox.Show(
					ex.Message,
					Localized.ErrorDialogTitle,
					MessageBoxButtons.OK,
					MessageBoxIcon.Error);
			}
		}
		private string SignEmail(string data, string key, bool wrapLines = true)
		{
			try
			{
				var context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest);
				var crypto = new PgpCrypto(context);
				var headers = new Dictionary<string, string>();
				headers["Version"] = Localized.DialogTitle;

				return crypto.SignClear(data, key, this._encoding, headers, wrapLines);
			}
			catch (CryptoException ex)
			{
				WriteErrorData("SignEmail", ex);
				MessageBox.Show(
					ex.Message,
					Localized.ErrorDialogTitle,
					MessageBoxButtons.OK,
					MessageBoxIcon.Error);

				return null;
			}
		}
Beispiel #29
0
        /// <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);
                    }
                }
        }
        private string SignEmail(string data, string key)
        {
            try
            {
                if (!PromptForPasswordAndKey())
                    return null;

                var context = new CryptoContext(Passphrase);
                var crypto = new PgpCrypto(context);
                var headers = new Dictionary<string, string>();
                headers["Version"] = "Outlook Privacy Plugin";

                return crypto.SignClear(data, key, this._encoding, headers);
            }
            catch (CryptoException ex)
            {
                this.Passphrase = null;

                WriteErrorData("SignEmail", ex);
                MessageBox.Show(
                    ex.Message,
                    "Outlook Privacy Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                return null;
            }
        }
        private string SignAndEncryptEmail(byte[] data, string key, IList<string> recipients)
        {
            try
            {
                if (!PromptForPasswordAndKey())
                    return null;

                var context = new CryptoContext(this.Passphrase);
                var crypto = new PgpCrypto(context);
                var headers = new Dictionary<string, string>();
                headers["Version"] = "Outlook Privacy Plugin";
                headers["Charset"] = _encoding.WebName;

                return crypto.SignAndEncryptText(data, key, recipients, headers);
            }
            catch (Exception ex)
            {
                this.Passphrase = null;

                WriteErrorData("SignAndEncryptEmail", ex);
                MessageBox.Show(
                    ex.Message,
                    "Outlook Privacy Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                throw;
            }
        }
		void HandlePgpMime(Outlook.MailItem mailItem, Outlook.Attachment encryptedMime,
			Outlook.Attachment sigMime, string sigHash = "sha1")
		{
			logger.Trace("> HandlePgpMime");
			CryptoContext Context = null;

			byte[] cyphertext = null;
			byte[] clearbytes = null;
			var cleartext = mailItem.Body;

			// 1. Decrypt attachement

			if (encryptedMime != null)
			{
				logger.Trace("Decrypting cypher text.");

				var tempfile = Path.GetTempFileName();
				encryptedMime.SaveAsFile(tempfile);
				cyphertext = File.ReadAllBytes(tempfile);
				File.Delete(tempfile);

				clearbytes = DecryptAndVerify(mailItem.To, cyphertext, out Context);
				if (clearbytes == null)
					return;

				cleartext = this._encoding.GetString(clearbytes);
			}

			// 2. Verify signature

			if (sigMime != null)
			{
				Context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest);
				var Crypto = new PgpCrypto(Context);
				var mailType = mailItem.BodyFormat;

				try
				{
					logger.Trace("Verify detached signature");

					var tempfile = Path.GetTempFileName();
					sigMime.SaveAsFile(tempfile);
					var detachedsig = File.ReadAllText(tempfile);
					File.Delete(tempfile);

					// Build up a clearsignature format for validation
					// the rules for are the same with the addition of two heaer fields.
					// Ultimately we need to get these fields out of email itself.

					// NOTE: encoding could be uppercase or lowercase. Try both.
					//       this is definetly hacky :/

					var encoding = GetEncodingFromMail(mailItem);
					var body = string.Empty;

					// Try two different methods to get the mime body
					try
					{
						body = encoding.GetString(
							(byte[])mailItem.PropertyAccessor.GetProperty(
								"http://schemas.microsoft.com/mapi/string/{4E3A7680-B77A-11D0-9DA5-00C04FD65685}/Internet Charset Body/0x00000102"));
					}
					catch (Exception)
					{
						body = (string)mailItem.PropertyAccessor.GetProperty(
								"http://schemas.microsoft.com/mapi/proptag/0x1000001F"); // PR_BODY
					}

					var clearsigUpper = new StringBuilder();

					clearsigUpper.Append(string.Format("-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: {0}\r\nCharset: {1}\r\n\r\n", sigHash, encoding.BodyName.ToUpper()));
					clearsigUpper.Append("Content-Type: text/plain; charset=");
					clearsigUpper.Append(encoding.BodyName.ToUpper());
					clearsigUpper.Append("\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n");

					clearsigUpper.Append(PgpClearDashEscapeAndQuoteEncode(body));

					clearsigUpper.Append("\r\n");
					clearsigUpper.Append(detachedsig);

					var clearsigLower = new StringBuilder(clearsigUpper.Length);

					clearsigLower.Append(string.Format("-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: {0}\r\nCharset: {1}\r\n\r\n", sigHash, encoding.BodyName.ToUpper()));
					clearsigLower.Append("Content-Type: text/plain; charset=");
					clearsigLower.Append(encoding.BodyName.ToLower());
					clearsigLower.Append("\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n");

					clearsigLower.Append(PgpClearDashEscapeAndQuoteEncode(body));

					clearsigLower.Append("\r\n");
					clearsigLower.Append(detachedsig);

					logger.Trace(clearsigUpper.ToString());

					if (Crypto.VerifyClear(_encoding.GetBytes(clearsigUpper.ToString())) || Crypto.VerifyClear(_encoding.GetBytes(clearsigLower.ToString())))
					{
						Context = Crypto.Context;

						var message = "** " + string.Format(Localized.MsgValidSig,
							Context.SignedByUserId, Context.SignedByKeyId) + "\n\n";

						if (mailType == Outlook.OlBodyFormat.olFormatPlain)
							mailItem.Body = message + mailItem.Body;
						else
							mailItem.HTMLBody = AddMessageToHtmlBody(mailItem.HTMLBody, message);
					}
					else
					{
						Context = Crypto.Context;

						var message = "** " + string.Format(Localized.MsgInvalidSig,
							Context.SignedByUserId, Context.SignedByKeyId) + "\n\n";

						if (mailType == Outlook.OlBodyFormat.olFormatPlain)
							mailItem.Body = message + mailItem.Body;
						else
							mailItem.HTMLBody = AddMessageToHtmlBody(mailItem.HTMLBody, message);
					}
				}
				catch (PublicKeyNotFoundException ex)
				{
					logger.Debug(ex.ToString());

					Context = Crypto.Context;

					var message = "** " + Localized.MsgSigMissingPubKey + "\n\n";

					if (mailType == Outlook.OlBodyFormat.olFormatPlain)
						mailItem.Body = message + mailItem.Body;
					else
						mailItem.HTMLBody = AddMessageToHtmlBody(mailItem.HTMLBody, message);
				}
				catch (Exception ex)
				{
					logger.Debug(ex.ToString());

					WriteErrorData("VerifyEmail", ex);
					MessageBox.Show(
						ex.Message,
						Localized.ErrorDialogTitle,
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
				}

				return;

			}

			if (Context == null)
				return;

			// Extract files from MIME data

			MimeMessage msg = null;
			TextPart textPart = null;
			MimeEntity htmlPart = null;
			var isHtml = false;

			using(var sin = new MemoryStream(clearbytes))
			{
				var parser = new MimeParser(sin);
				msg = parser.ParseMessage();
				var iter = new MimeIterator(msg);

				while(iter.MoveNext())
				{
					var part = iter.Current as TextPart;
					if (part == null)
						continue;

					if (part.IsAttachment)
						continue;

					// message could include both text and html
					// if we find html use that over text.
					if (part.IsHtml)
					{
						htmlPart = part;
						isHtml = true;
					}
					else
					{
						textPart = part;
					}
				}
			}

			var DecryptAndVerifyHeaderMessage = "** ";

			if (Context.IsEncrypted)
				DecryptAndVerifyHeaderMessage += Localized.MsgDecrypt + " ";

			if (Context.FailedIntegrityCheck)
				DecryptAndVerifyHeaderMessage += Localized.MsgFailedIntegrityCheck + " ";

			if (Context.IsSigned && Context.SignatureValidated)
			{
				DecryptAndVerifyHeaderMessage += string.Format(Localized.MsgValidSig,
					Context.SignedByUserId, Context.SignedByKeyId);
			}
			else if (Context.IsSigned)
			{
				DecryptAndVerifyHeaderMessage +=  string.Format(Localized.MsgInvalidSig,
					Context.SignedByUserId, Context.SignedByKeyId);
			}
			else
				DecryptAndVerifyHeaderMessage += Localized.MsgUnsigned;

			DecryptAndVerifyHeaderMessage += "\n\n";

			if(isHtml)
			{
				var htmlBody = msg.HtmlBody;
				var related = msg.Body as MultipartRelated;
				var doc = new HtmlAgilityPack.HtmlDocument();
				var savedImages = new List<MimePart>();

				doc.LoadHtml(htmlBody);

				// Find any embedded images
				foreach (var img in doc.DocumentNode.SelectNodes("//img[@src]"))
				{
					var src = img.Attributes["src"];
					Uri uri;

					if (src == null || src.Value == null)
						continue;

					// parse the <img src=...> attribute value into a Uri
					if (Uri.IsWellFormedUriString(src.Value, UriKind.Absolute))
						uri = new Uri(src.Value, UriKind.Absolute);
					else
						uri = new Uri(src.Value, UriKind.Relative);

					// locate the index of the attachment within the multipart/related (if it exists)
					string imageCid = src.Value.Substring(4);

					var iter = new MimeIterator(msg);
					MimePart attachment = null;
					while (iter.MoveNext())
					{
						if (iter.Current.ContentId == imageCid)
						{
							attachment = iter.Current as MimePart;
							break;
						}
					}

					if (attachment == null)
						continue;

					string fileName;

					// save the attachment (if we haven't already saved it)
					if (!savedImages.Contains(attachment))
					{
						fileName = attachment.FileName;

						if (string.IsNullOrEmpty(fileName))
							fileName = Guid.NewGuid().ToString();

						using (var stream = File.Create(fileName))
							attachment.ContentObject.DecodeTo(stream);

						try
						{
							var att = mailItem.Attachments.Add(fileName, Outlook.OlAttachmentType.olEmbeddeditem, null, "");
							att.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", imageCid);
							savedImages.Add(attachment);
						}
						finally
						{
							// try not to leak temp files :)
							File.Delete(fileName);
						}
					}
				}

				mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
				mailItem.HTMLBody = AddMessageToHtmlBody(htmlBody, DecryptAndVerifyHeaderMessage);
			}
			else
			{
				// NOTE: For some reason we cannot change the BodyFormat once it's set.
				//       So if we are set to HTML we need to wrap the plain text so it's
				//       displayed okay. Also of course prevent XSS.

				if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatPlain)
				{
					mailItem.Body = DecryptAndVerifyHeaderMessage + msg.TextBody;
				}
				else
				{
					var sb = new StringBuilder(msg.TextBody.Length + 100);
					sb.Append("<html><body><pre>");
					sb.Append(WebUtility.HtmlEncode(DecryptAndVerifyHeaderMessage));
					sb.Append(WebUtility.HtmlEncode(msg.TextBody));
					sb.Append("</pre></body></html>");

					mailItem.HTMLBody = sb.ToString();
				}
			}

			// NOTE: Removing existing attachments is perminant, even if the message
			//       is not saved.

			foreach (var mimeAttachment in msg.Attachments)
			{
				var fileName = mimeAttachment.FileName;
				var tempFile = Path.Combine(Path.GetTempPath(), fileName);

				using (var fout = File.OpenWrite(tempFile))
				{
					mimeAttachment.ContentObject.DecodeTo(fout);
				}

				mailItem.Attachments.Add(tempFile, Outlook.OlAttachmentType.olByValue, 1, fileName);

				File.Delete(tempFile);
			}
		}
        /// <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());
            }
        }
Beispiel #34
0
        /// <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()));
            }
        }
        internal void VerifyEmail(Outlook.MailItem mailItem)
        {
            string mail = mailItem.Body;
            Outlook.OlBodyFormat mailType = mailItem.BodyFormat;

            if (Regex.IsMatch(mailItem.Body, _pgpSignedHeader) == false)
            {
                MessageBox.Show(
                    "Outlook Privacy cannot help here.",
                    "Mail is not signed",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);

                return;
            }

            var Context = new CryptoContext(Passphrase);
            var Crypto = new PgpCrypto(Context);

            try
            {
                if (Crypto.Verify(_encoding.GetBytes(mail)))
                {
                    Context = Crypto.Context;

                    var message = "** Valid signature from \"" + Context.SignedByUserId +
                        "\" with KeyId " + Context.SignedByKeyId + ".\n\n";

                    if (mailType == Outlook.OlBodyFormat.olFormatPlain)
                    {
                        mailItem.Body = message + mailItem.Body;
                    }
                }
                else
                {
                    Context = Crypto.Context;

                    var message = "** Invalid signature from \"" + Context.SignedByUserId +
                        "\" with KeyId " + Context.SignedByKeyId + ".\n\n";

                    if (mailType == Outlook.OlBodyFormat.olFormatPlain)
                    {
                        mailItem.Body = message + mailItem.Body;
                    }
                }
            }
            catch (PublicKeyNotFoundException ex)
            {
                Context = Crypto.Context;

                var message = "** Unable to verify signature, missing public key.\n\n";

                if (mailType == Outlook.OlBodyFormat.olFormatPlain)
                {
                    mailItem.Body = message + mailItem.Body;
                }
            }
            catch (Exception ex)
            {
                this.Passphrase = null;

                WriteErrorData("VerifyEmail", ex);
                MessageBox.Show(
                    ex.Message,
                    "Outlook Privacy Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }
		private string SignAndEncryptEmail(byte[] data, string key, IList<string> recipients)
		{
			try
			{
				var context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest);
				var crypto = new PgpCrypto(context);
				var headers = new Dictionary<string, string>();
				headers["Version"] = Localized.DialogTitle;
				headers["Charset"] = _encoding.WebName;

				return crypto.SignAndEncryptText(data, key, recipients, headers);
			}
			catch (Exception ex)
			{
				WriteErrorData("SignAndEncryptEmail", ex);
				MessageBox.Show(
					ex.Message,
					Localized.ErrorDialogTitle,
					MessageBoxButtons.OK,
					MessageBoxIcon.Error);

				throw;
			}
		}
        byte[] DecryptAndVerify(string to, byte[] data, out CryptoContext outContext)
        {
            DecryptAndVerifyHeaderMessage = "";
            outContext = null;

            if (!PromptForPasswordAndKey())
                return null;

            var Context = new CryptoContext(Passphrase);
            var Crypto = new PgpCrypto(Context);

            try
            {
                var cleartext = Crypto.DecryptAndVerify(data, _settings.IgnoreIntegrityCheck);
                Context = Crypto.Context;

                // NOT USED YET.

                //DecryptAndVerifyHeaderMessage = "** ";

                //if (Context.IsEncrypted)
                //	DecryptAndVerifyHeaderMessage += "Message decrypted. ";

                //if (Context.IsSigned && Context.SignatureValidated)
                //{
                //	DecryptAndVerifyHeaderMessage += "Valid signature from \"" + Context.SignedByUserId +
                //		"\" with KeyId " + Context.SignedByKeyId;
                //}
                //else if (Context.IsSigned)
                //{
                //	DecryptAndVerifyHeaderMessage += "Invalid signature from \"" + Context.SignedByUserId +
                //		"\" with KeyId " + Context.SignedByKeyId + ".";
                //}
                //else
                //	DecryptAndVerifyHeaderMessage += "Message was unsigned.";

                //DecryptAndVerifyHeaderMessage += "\n\n";

                outContext = Context;
                return cleartext;
            }
            catch (CryptoException ex)
            {
                this.Passphrase = null;

                WriteErrorData("DecryptAndVerify", ex);
                MessageBox.Show(
                    ex.Message,
                    "Outlook Privacy Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

            }
            catch (Exception e)
            {
                this.Passphrase = null;
                WriteErrorData("DecryptAndVerify", e);

                if (e.Message.ToLower().StartsWith("checksum"))
                {
                    MessageBox.Show(
                        "Incorrect passphrase possibly entered.",
                        "Outlook Privacy Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
                else
                {
                    MessageBox.Show(
                        e.Message,
                        "Outlook Privacy Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
            }

            return null;
        }
        private string EncryptEmail(byte[] data, IList<string> recipients)
        {
            try
            {
                var context = new CryptoContext();
                var crypto = new PgpCrypto(context);
                var headers = new Dictionary<string, string>();
                headers["Version"] = "Outlook Privacy Plugin";
                headers["Charset"] = _encoding.WebName;

                return crypto.Encrypt(data, recipients, headers);
            }
            catch (CryptoException ex)
            {
                this.Passphrase = null;

                WriteErrorData("EncryptEmail", ex);
                MessageBox.Show(
                    ex.Message,
                    "Outlook Privacy Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                return null;
            }
            catch (Exception e)
            {
                this.Passphrase = null;

                WriteErrorData("EncryptEmail", e);
                MessageBox.Show(
                    e.Message,
                    "Outlook Privacy Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                return null;
            }
        }
Beispiel #39
0
		// Not working yet
		//[Test]
		public void ClearTextSignTest()
		{
			var context = new CryptoContext(
				GetPasswordCallback, 
				@"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\pubring.gpg",
				@"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\secring.gpg",
				"rsa", "sha-1");
			var crypto = new PgpCrypto(context);

			var dataDir = @"C:\projects\OutlookPrivacyPlugin\Deja.Crypto.Test\data";
			var signKey = "*****@*****.**";
			var sign = string.Empty;

			foreach (var file in Directory.EnumerateFiles(dataDir, "*.bin"))
			{
				Console.WriteLine("ClearTextSignTest: " + file);

				context.Digest = "sha-1";
				sign = crypto.SignClear(File.ReadAllText(file), signKey, Encoding.UTF8, new Dictionary<string, string>());
				File.WriteAllText(@"c:\temp\test.bin", sign);
				Assert.AreEqual(File.ReadAllText(file + ".rsa.sha1.clearsign"), sign);

				context.Digest = "SHA-256";
				sign = crypto.SignClear(File.ReadAllText(file), signKey, Encoding.UTF8, new Dictionary<string, string>());
				Assert.AreEqual(File.ReadAllText(file + ".rsa.sha256.clearsign"), sign);

				context.Digest = "SHA-1";
				sign = crypto.Sign(File.ReadAllBytes(file), signKey, new Dictionary<string, string>());
				File.WriteAllText(@"c:\temp\test.bin", sign);
				Assert.AreEqual(File.ReadAllText(file + ".rsa.sha1.sign"), sign);
			}
		}
        void HandlePgpMime(Outlook.MailItem mailItem, Microsoft.Office.Interop.Outlook.Attachment encryptedMime,
            Microsoft.Office.Interop.Outlook.Attachment sigMime, string sigHash = "sha1")
        {
            logger.Trace("> HandlePgpMime");
            CryptoContext Context = null;

            string sig = null;
            byte[] cyphertext = null;
            string cleartext = mailItem.Body;

            // 1. Decrypt attachement

            if (encryptedMime != null)
            {
                logger.Trace("Decrypting cypher text.");

            var tempfile = Path.GetTempFileName();
            encryptedMime.SaveAsFile(tempfile);
                cyphertext = File.ReadAllBytes(tempfile);
                File.Delete(tempfile);

                var clearbytes = DecryptAndVerify(mailItem.To, cyphertext, out Context);
                if (clearbytes == null)
                    return;

                cleartext = this._encoding.GetString(clearbytes);
            }

            // 2. Verify signature

            if (sigMime != null)
            {
                Context = new CryptoContext(Passphrase);
                var Crypto = new PgpCrypto(Context);
                Outlook.OlBodyFormat mailType = mailItem.BodyFormat;

                try
                {
                    logger.Trace("Verify detached signature");

                    var tempfile = Path.GetTempFileName();
                    sigMime.SaveAsFile(tempfile);
                    var detachedsig = File.ReadAllText(tempfile);
                    File.Delete(tempfile);

                    // Build up a clearsignature format for validation
                    // the rules for are the same with the addition of two heaer fields.
                    // Ultimately we need to get these fields out of email itself.

                    var encoding = GetEncodingFromMail(mailItem);

                    var clearsig = string.Format("-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: {0}\r\n\r\n", sigHash);
                    //clearsig += "Content-Type: text/plain; charset=ISO-8859-1\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n";
                    clearsig += "Content-Type: text/plain; charset=" +
                        encoding.BodyName.ToUpper()+
                        "\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n";

                    clearsig += PgpClearDashEscapeAndQuoteEncode(
                        encoding.GetString(
                        (byte[])mailItem.PropertyAccessor.GetProperty(
                            "http://schemas.microsoft.com/mapi/string/{4E3A7680-B77A-11D0-9DA5-00C04FD65685}/Internet Charset Body/0x00000102")));

                    clearsig += "\r\n"+detachedsig;

                    logger.Trace(clearsig);

                    if (Crypto.VerifyClear(_encoding.GetBytes(clearsig)))
                    {
                        Context = Crypto.Context;

                        var message = "** Valid signature from \"" + Context.SignedByUserId +
                            "\" with KeyId " + Context.SignedByKeyId + ".\n\n";

                        if (mailType == Outlook.OlBodyFormat.olFormatPlain)
                        {
                            mailItem.Body = message + mailItem.Body;
                        }
                    }
                    else
                    {
                        Context = Crypto.Context;

                        var message = "** Invalid signature from \"" + Context.SignedByUserId +
                            "\" with KeyId " + Context.SignedByKeyId + ".\n\n";

                        if (mailType == Outlook.OlBodyFormat.olFormatPlain)
                        {
                            mailItem.Body = message + mailItem.Body;
                        }
                    }
                }
                catch (PublicKeyNotFoundException ex)
                {
                    logger.Debug(ex.ToString());

                    Context = Crypto.Context;

                    var message = "** Unable to verify signature, missing public key.\n\n";

                    if (mailType == Outlook.OlBodyFormat.olFormatPlain)
                    {
                        mailItem.Body = message + mailItem.Body;
                    }
                }
                catch (Exception ex)
                {
                    logger.Debug(ex.ToString());

                    this.Passphrase = null;

                    WriteErrorData("VerifyEmail", ex);
                    MessageBox.Show(
                        ex.Message,
                        "Outlook Privacy Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }

                return;

            }

            if (Context == null)
                return;

            // Extract files from MIME data

            SharpMessage msg = new SharpMessage(cleartext);
            string body = mailItem.Body;

            var DecryptAndVerifyHeaderMessage = "** ";

            if (Context.IsEncrypted)
                DecryptAndVerifyHeaderMessage += "Message decrypted. ";

            if (Context.FailedIntegrityCheck)
                DecryptAndVerifyHeaderMessage += "Failed integrity check! ";

            if (Context.IsSigned && Context.SignatureValidated)
            {
                DecryptAndVerifyHeaderMessage += "Valid signature from \"" + Context.SignedByUserId +
                    "\" with KeyId " + Context.SignedByKeyId;
            }
            else if (Context.IsSigned)
            {
                DecryptAndVerifyHeaderMessage += "Invalid signature from \"" + Context.SignedByUserId +
                    "\" with KeyId " + Context.SignedByKeyId + ".";
            }
            else
                DecryptAndVerifyHeaderMessage += "Message was unsigned.";

            DecryptAndVerifyHeaderMessage += "\n\n";

            if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatPlain)
            {
                mailItem.Body = DecryptAndVerifyHeaderMessage + msg.Body;
            }
            else if (mailItem.BodyFormat == Outlook.OlBodyFormat.olFormatHTML)
            {
                if (!msg.Body.TrimStart().ToLower().StartsWith("<html"))
                {
                    body = DecryptAndVerifyHeaderMessage + msg.Body;
                    body = System.Net.WebUtility.HtmlEncode(body);
                    body = body.Replace("\n", "<br />");

                    mailItem.HTMLBody = "<html><head></head><body>" + body + "</body></html>";
                }
                else
                {
                    // Find <body> tag and insert our message.

                    var matches = Regex.Match(msg.Body, @"(<body[^<]*>)", RegexOptions.IgnoreCase);
                    if (matches.Success)
                    {
                        var bodyTag = matches.Groups[1].Value;

                        // Insert decryption message.
                        mailItem.HTMLBody = msg.Body.Replace(
                            bodyTag,
                            bodyTag + DecryptAndVerifyHeaderMessage.Replace("\n", "<br />"));
                    }
                    else
                        mailItem.HTMLBody = msg.Body;
                }
            }
            else
            {
                // May cause mail item not to open correctly

                mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatPlain;
                mailItem.Body = msg.Body;
            }

            foreach (SharpAttachment mimeAttachment in msg.Attachments)
            {
                mimeAttachment.Stream.Position = 0;
                var fileName = mimeAttachment.Name;
                var tempFile = Path.Combine(Path.GetTempPath(), fileName);

                using (FileStream fout = File.OpenWrite(tempFile))
                {
                    mimeAttachment.Stream.CopyTo(fout);
                }

                mailItem.Attachments.Add(tempFile, Outlook.OlAttachmentType.olByValue, 1, fileName);
            }

            //mailItem.Save();
        }
		byte[] DecryptAndVerify(string to, byte[] data, out CryptoContext outContext)
		{
			DecryptAndVerifyHeaderMessage = "";
			outContext = null;

			var Context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest);
			var Crypto = new PgpCrypto(Context);

			try
			{
				var cleartext = Crypto.DecryptAndVerify(data, _settings.IgnoreIntegrityCheck);
				Context = Crypto.Context;

				DecryptAndVerifyHeaderMessage = "** ";

				if (Context.IsEncrypted)
					DecryptAndVerifyHeaderMessage += Localized.MsgDecrypt + " ";

				if (Context.IsSigned && Context.SignatureValidated)
				{
					DecryptAndVerifyHeaderMessage += string.Format(Localized.MsgValidSig,
						Context.SignedByUserId, Context.SignedByKeyId);
				}
				else if (Context.IsSigned)
				{
					DecryptAndVerifyHeaderMessage += string.Format(Localized.MsgInvalidSig,
						Context.SignedByUserId, Context.SignedByKeyId);
				}
				else
					DecryptAndVerifyHeaderMessage += Localized.MsgUnsigned;

				DecryptAndVerifyHeaderMessage += "\n\n";

				outContext = Context;
				return cleartext;
			}
			catch (CryptoException ex)
			{
				WriteErrorData("DecryptAndVerify", ex);
				MessageBox.Show(
					ex.Message,
					Localized.ErrorDialogTitle,
					MessageBoxButtons.OK,
					MessageBoxIcon.Error);

			}
			catch (Exception e)
			{
				WriteErrorData("DecryptAndVerify", e);

				if (e.Message.ToLower().StartsWith("checksum"))
				{
					ClearLastPassword();

					MessageBox.Show(
						Localized.ErrorBadPassphrase,
						Localized.ErrorDialogTitle,
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
				}
				else
				{
					MessageBox.Show(
						e.Message,
						Localized.ErrorDialogTitle,
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
				}
			}

			return null;
		}
		private string SignEmail(string data, string key)
		{
			try
			{
				var context = new CryptoContext(PasswordCallback, _settings.Cipher, _settings.Digest);
				var crypto = new PgpCrypto(context);
				var headers = new Dictionary<string, string>();
				headers["Version"] = "Outlook Privacy Plugin";

				return crypto.SignClear(data, key, this._encoding, headers);
			}
			catch (CryptoException ex)
			{
				WriteErrorData("SignEmail", ex);
				MessageBox.Show(
					ex.Message,
					"Outlook Privacy Error",
					MessageBoxButtons.OK,
					MessageBoxIcon.Error);

				return null;
			}
		}