Пример #1
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 + "\".");

			PgpSecretKey senderMasterSignkey;
			var senderSignKey = GetSecretKeyForSigning(key, out senderMasterSignkey);
			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(GetSymAlgTagFromString(Context.Cipher), 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,
				GetHashAlgTagFromString(Context.Digest));
			signatureData.InitSign(
				isBinary ? PgpSignature.BinaryDocument : PgpSignature.CanonicalTextDocument,
				senderSignKey.ExtractPrivateKey(Context.PasswordCallback(senderMasterSignkey, senderSignKey)));

			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());
			}
		}
Пример #2
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)
		{
			logger.Trace("Sign({0}, {1})", data.Length, key);

			Context = new CryptoContext(Context);

			PgpSecretKey senderMasterKey;
			var senderKey = GetSecretKeyForSigning(key, out senderMasterKey);
			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, GetHashAlgTagFromString(Context.Digest));
			signatureData.InitSign(PgpSignature.BinaryDocument, senderKey.ExtractPrivateKey(Context.PasswordCallback(senderMasterKey, senderKey)));

			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());
			}
		}
Пример #3
0
		/// <summary>
		/// Sign data using key
		/// </summary>
		/// <param name="data">Data to sign</param>
		/// <param name="key">Email address of key</param>
		/// <param name="headers">Headers to add to signed message</param>
		/// <param name="wrapLines">Automatically wrap lines that are too long</param>
		/// <param name="encoding">s</param>
		/// <returns>Returns ascii armored signature</returns>
		public string SignClear(string data, string key, Encoding encoding, Dictionary<string, string> headers, bool wrapLines = true)
		{
			Context = new CryptoContext(Context);

			PgpSecretKey senderMasterKey;
			var senderKey = GetSecretKeyForSigning(key, out senderMasterKey);
			if (senderKey == null)
				throw new SecretKeyNotFoundException("Error, unable to locate signing key \"" + key + "\".");

			// Setup signature stuff //
			var signatureData = new PgpSignatureGenerator(senderKey.PublicKey.Algorithm, GetHashAlgTagFromString(Context.Digest));
			signatureData.InitSign(PgpSignature.CanonicalTextDocument, senderKey.ExtractPrivateKey(Context.PasswordCallback(senderMasterKey, senderKey)));

			foreach (string userId in senderKey.PublicKey.GetUserIds())
			{
				var subPacketGenerator = new PgpSignatureSubpacketGenerator();

				subPacketGenerator.SetSignerUserId(false, userId);
				signatureData.SetHashedSubpackets(subPacketGenerator.Generate());

				// Just the first one!
				break;
			}

			// Split any long lines if we are asked to do so.

			var mailLines = data.Split('\n');

			if (wrapLines && mailLines.Any(line => line.Length > 70))
			{
				var lines = new List<string>(mailLines);
				for (var i = 0; i < lines.Count; i++)
				{
					var line = lines[i];
					if (line.Length <= 70) continue;
					
					var newLine = line.Substring(70);
					line = line.Substring(0, 70);

					lines[i] = line;
					lines.Insert(i + 1, newLine);
				}

				var sb = new StringBuilder(data.Length + 20);
				foreach (var line in lines)
					sb.AppendLine(line.TrimEnd('\r', '\n'));

				data = sb.ToString();
			}

			// Now lets do our signing stuff

			using (var sout = new MemoryStream())
			{
				using (var armoredOut = new ArmoredOutputStream(sout))
				{
					foreach (var header in headers)
						armoredOut.SetHeader(header.Key, header.Value);

					armoredOut.BeginClearText(GetHashAlgTagFromString(Context.Digest));

					// 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(' ', '\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());
			}
		}
Пример #4
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);

			PgpSecretKey senderMasterKey;
			var senderKey = GetSecretKeyForSigning(key, out senderMasterKey);
			if (senderKey == null)
				throw new SecretKeyNotFoundException("Error, unable to locate signing key \"" + key + "\".");

			// Setup signature stuff //
			var signatureData = new PgpSignatureGenerator(senderKey.PublicKey.Algorithm, GetHashAlgTagFromString(Context.Digest));
			signatureData.InitSign(PgpSignature.CanonicalTextDocument, senderKey.ExtractPrivateKey(Context.PasswordCallback(senderMasterKey, senderKey)));

			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(GetHashAlgTagFromString(Context.Digest));

					// 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());
			}
		}