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");
        }
Exemplo n.º 2
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);

		}
Exemplo n.º 3
0
		public void UnicodeUtf8PageTest()
		{
			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 clearSig = crypto.SignClear(clear, "*****@*****.**", Encoding.UTF8, new Dictionary<string, string>());
			var ret = crypto.VerifyClear(Encoding.UTF8.GetBytes(clearSig));

			Assert.IsTrue(ret);
		}
        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();
        }
		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);
			}
		}