summary refs log tree commit diff
path: root/crypto/test/src/openpgp/examples/DirectKeySignature.cs
blob: 3926a787b5027175fadd8779f75497fdef7400e3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System;
using System.IO;

using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Bcpg.Sig;

namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
{
	/**
	* A simple utility class that directly signs a public key and writes the signed key to "SignedKey.asc" in 
	* the current working directory.
	* <p>
	* To sign a key: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue.<br/>
	* </p><p>
	* To display a NotationData packet from a publicKey previously signed: DirectKeySignature signedPublicKeyFile.<br/>
	* </p><p>
	* <b>Note</b>: this example will silently overwrite files, nor does it pay any attention to
	* the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
	* will have been used.
	* </p>
	*/
	public class DirectKeySignature
	{
		public static void Main(
			string[] args)
		{
			if (args.Length == 1)
			{
				Stream fis = File.OpenRead(args[0]);

				PgpPublicKeyRing ring = new PgpPublicKeyRing(
					PgpUtilities.GetDecoderStream(fis));
				PgpPublicKey key = ring.GetPublicKey();

				// iterate through all direct key signautures and look for NotationData subpackets
				foreach (PgpSignature sig in key.GetSignaturesOfType(PgpSignature.DirectKey))
				{
					Console.WriteLine("Signature date is: "
						+ sig.GetHashedSubPackets().GetSignatureCreationTime());

					NotationData[] data = sig.GetHashedSubPackets().GetNotationDataOccurrences();

					for (int i = 0; i < data.Length; i++)
					{
						Console.WriteLine("Found Notation named '" + data[i].GetNotationName()
							+"' with content '" + data[i].GetNotationValue() + "'.");
					}
				}

				fis.Close();
			}
			else if (args.Length == 5)
			{
				Stream secFis = File.OpenRead(args[0]);
				Stream pubFis = File.OpenRead(args[2]);

				// gather command line arguments
				PgpSecretKeyRing secRing = new PgpSecretKeyRing(
					PgpUtilities.GetDecoderStream(secFis));
				String secretKeyPass = args[1];
				PgpPublicKeyRing ring = new PgpPublicKeyRing(
					PgpUtilities.GetDecoderStream(pubFis));
				String notationName = args[3];
				String notationValue = args[4];

				// create the signed keyRing
				PgpPublicKeyRing sRing = null;
				sRing = new PgpPublicKeyRing(
					new MemoryStream(
						SignPublicKey(secRing.GetSecretKey(), secretKeyPass,
							ring.GetPublicKey(), notationName, notationValue, true),
						false));
				ring = sRing;

				secFis.Close();
				pubFis.Close();

				Stream fos = File.Create("SignedKey.asc");

				// write the created keyRing to file
				ArmoredOutputStream aOut = new ArmoredOutputStream(fos);
				sRing.Encode(aOut);
				aOut.Close();

				// Note: ArmoredOutputStream.Close() leaves underlying stream open
				fos.Close();
			}
			else
			{
				Console.Error.WriteLine("usage: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue");
				Console.Error.WriteLine("or: DirectKeySignature signedPublicKeyFile");
			}
		}

		private static byte[] SignPublicKey(
			PgpSecretKey	secretKey,
			string			secretKeyPass,
			PgpPublicKey	keyToBeSigned,
			string			notationName,
			string			notationValue,
			bool			armor)
		{
			Stream os = new MemoryStream();
			if (armor)
			{
				os = new ArmoredOutputStream(os);
			}

			PgpPrivateKey pgpPrivKey = secretKey.ExtractPrivateKey(
				secretKeyPass.ToCharArray());

			PgpSignatureGenerator sGen = new PgpSignatureGenerator(
				secretKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);

			sGen.InitSign(PgpSignature.DirectKey, pgpPrivKey);

			BcpgOutputStream bOut = new BcpgOutputStream(os);

			sGen.GenerateOnePassVersion(false).Encode(bOut);

			PgpSignatureSubpacketGenerator spGen = new PgpSignatureSubpacketGenerator();

			bool isHumanReadable = true;

			spGen.SetNotationData(true, isHumanReadable, notationName, notationValue);

			PgpSignatureSubpacketVector packetVector = spGen.Generate();
			sGen.SetHashedSubpackets(packetVector);

			bOut.Flush();

			if (armor)
			{
				os.Close();
			}

			return PgpPublicKey.AddCertification(keyToBeSigned, sGen.Generate()).GetEncoded();
		}
	}
}