summary refs log tree commit diff
path: root/crypto/src/openpgp/PgpKeyRingGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/openpgp/PgpKeyRingGenerator.cs')
-rw-r--r--crypto/src/openpgp/PgpKeyRingGenerator.cs167
1 files changed, 167 insertions, 0 deletions
diff --git a/crypto/src/openpgp/PgpKeyRingGenerator.cs b/crypto/src/openpgp/PgpKeyRingGenerator.cs
new file mode 100644
index 000000000..e85fc2eef
--- /dev/null
+++ b/crypto/src/openpgp/PgpKeyRingGenerator.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Collections;
+
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+
+namespace Org.BouncyCastle.Bcpg.OpenPgp
+{
+	/// <remarks>
+	/// Generator for a PGP master and subkey ring.
+	/// This class will generate both the secret and public key rings
+	/// </remarks>
+    public class PgpKeyRingGenerator
+    {
+        private IList					    keys = Platform.CreateArrayList();
+        private string                      id;
+        private SymmetricKeyAlgorithmTag	encAlgorithm;
+        private int                         certificationLevel;
+        private char[]                      passPhrase;
+		private bool						useSha1;
+		private PgpKeyPair                  masterKey;
+        private PgpSignatureSubpacketVector hashedPacketVector;
+        private PgpSignatureSubpacketVector unhashedPacketVector;
+        private SecureRandom				rand;
+
+		/// <summary>
+		/// Create a new key ring generator using old style checksumming. It is recommended to use
+		/// SHA1 checksumming where possible.
+		/// </summary>
+		/// <param name="certificationLevel">The certification level for keys on this ring.</param>
+		/// <param name="masterKey">The master key pair.</param>
+		/// <param name="id">The id to be associated with the ring.</param>
+		/// <param name="encAlgorithm">The algorithm to be used to protect secret keys.</param>
+		/// <param name="passPhrase">The passPhrase to be used to protect secret keys.</param>
+		/// <param name="hashedPackets">Packets to be included in the certification hash.</param>
+		/// <param name="unhashedPackets">Packets to be attached unhashed to the certification.</param>
+		/// <param name="rand">input secured random.</param>
+		public PgpKeyRingGenerator(
+			int							certificationLevel,
+			PgpKeyPair					masterKey,
+			string						id,
+			SymmetricKeyAlgorithmTag	encAlgorithm,
+			char[]						passPhrase,
+			PgpSignatureSubpacketVector	hashedPackets,
+			PgpSignatureSubpacketVector	unhashedPackets,
+			SecureRandom				rand)
+			: this(certificationLevel, masterKey, id, encAlgorithm, passPhrase, false, hashedPackets, unhashedPackets, rand)
+		{
+		}
+
+		/// <summary>
+		/// Create a new key ring generator.
+		/// </summary>
+		/// <param name="certificationLevel">The certification level for keys on this ring.</param>
+		/// <param name="masterKey">The master key pair.</param>
+		/// <param name="id">The id to be associated with the ring.</param>
+		/// <param name="encAlgorithm">The algorithm to be used to protect secret keys.</param>
+		/// <param name="passPhrase">The passPhrase to be used to protect secret keys.</param>
+		/// <param name="useSha1">Checksum the secret keys with SHA1 rather than the older 16 bit checksum.</param>
+		/// <param name="hashedPackets">Packets to be included in the certification hash.</param>
+		/// <param name="unhashedPackets">Packets to be attached unhashed to the certification.</param>
+		/// <param name="rand">input secured random.</param>
+        public PgpKeyRingGenerator(
+            int							certificationLevel,
+            PgpKeyPair					masterKey,
+            string						id,
+            SymmetricKeyAlgorithmTag	encAlgorithm,
+            char[]						passPhrase,
+			bool						useSha1,
+			PgpSignatureSubpacketVector	hashedPackets,
+            PgpSignatureSubpacketVector	unhashedPackets,
+            SecureRandom				rand)
+        {
+            this.certificationLevel = certificationLevel;
+            this.masterKey = masterKey;
+            this.id = id;
+            this.encAlgorithm = encAlgorithm;
+            this.passPhrase = passPhrase;
+			this.useSha1 = useSha1;
+			this.hashedPacketVector = hashedPackets;
+            this.unhashedPacketVector = unhashedPackets;
+            this.rand = rand;
+
+			keys.Add(new PgpSecretKey(certificationLevel, masterKey, id, encAlgorithm, passPhrase, useSha1, hashedPackets, unhashedPackets, rand));
+        }
+
+		/// <summary>Add a subkey to the key ring to be generated with default certification.</summary>
+        public void AddSubKey(
+            PgpKeyPair keyPair)
+        {
+			AddSubKey(keyPair, this.hashedPacketVector, this.unhashedPacketVector);
+		}
+
+		/// <summary>
+		/// Add a subkey with specific hashed and unhashed packets associated with it and
+		/// default certification.
+		/// </summary>
+		/// <param name="keyPair">Public/private key pair.</param>
+		/// <param name="hashedPackets">Hashed packet values to be included in certification.</param>
+		/// <param name="unhashedPackets">Unhashed packets values to be included in certification.</param>
+		/// <exception cref="PgpException"></exception>
+		public void AddSubKey(
+			PgpKeyPair					keyPair,
+			PgpSignatureSubpacketVector	hashedPackets,
+			PgpSignatureSubpacketVector	unhashedPackets)
+		{
+			try
+            {
+                PgpSignatureGenerator sGen = new PgpSignatureGenerator(
+					masterKey.PublicKey.Algorithm, HashAlgorithmTag.Sha1);
+
+				//
+                // Generate the certification
+                //
+                sGen.InitSign(PgpSignature.SubkeyBinding, masterKey.PrivateKey);
+
+				sGen.SetHashedSubpackets(hashedPackets);
+                sGen.SetUnhashedSubpackets(unhashedPackets);
+
+				IList subSigs = Platform.CreateArrayList();
+
+				subSigs.Add(sGen.GenerateCertification(masterKey.PublicKey, keyPair.PublicKey));
+
+				keys.Add(new PgpSecretKey(keyPair.PrivateKey, new PgpPublicKey(keyPair.PublicKey, null, subSigs), encAlgorithm, passPhrase, useSha1, rand));
+			}
+            catch (PgpException e)
+            {
+                throw e;
+            }
+            catch (Exception e)
+            {
+                throw new PgpException("exception adding subkey: ", e);
+            }
+        }
+
+		/// <summary>Return the secret key ring.</summary>
+        public PgpSecretKeyRing GenerateSecretKeyRing()
+        {
+            return new PgpSecretKeyRing(keys);
+        }
+
+		/// <summary>Return the public key ring that corresponds to the secret key ring.</summary>
+        public PgpPublicKeyRing GeneratePublicKeyRing()
+        {
+            IList pubKeys = Platform.CreateArrayList();
+
+            IEnumerator enumerator = keys.GetEnumerator();
+            enumerator.MoveNext();
+
+			PgpSecretKey pgpSecretKey = (PgpSecretKey) enumerator.Current;
+			pubKeys.Add(pgpSecretKey.PublicKey);
+
+			while (enumerator.MoveNext())
+            {
+                pgpSecretKey = (PgpSecretKey) enumerator.Current;
+
+				PgpPublicKey k = new PgpPublicKey(pgpSecretKey.PublicKey);
+				k.publicPk = new PublicSubkeyPacket(
+					k.Algorithm, k.CreationTime, k.publicPk.Key);
+
+				pubKeys.Add(k);
+			}
+
+			return new PgpPublicKeyRing(pubKeys);
+        }
+    }
+}