diff --git a/crypto/src/openpgp/PgpSecretKeyRing.cs b/crypto/src/openpgp/PgpSecretKeyRing.cs
index 3e646eaa1..70cd7217c 100644
--- a/crypto/src/openpgp/PgpSecretKeyRing.cs
+++ b/crypto/src/openpgp/PgpSecretKeyRing.cs
@@ -8,57 +8,57 @@ using Org.BouncyCastle.Utilities.Collections;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
- /// <remarks>
- /// Class to hold a single master secret key and its subkeys.
- /// <p>
- /// Often PGP keyring files consist of multiple master keys, if you are trying to process
- /// or construct one of these you should use the <c>PgpSecretKeyRingBundle</c> class.
- /// </p>
- /// </remarks>
- public class PgpSecretKeyRing
- : PgpKeyRing
+ /// <remarks>
+ /// Class to hold a single master secret key and its subkeys.
+ /// <p>
+ /// Often PGP keyring files consist of multiple master keys, if you are trying to process
+ /// or construct one of these you should use the <c>PgpSecretKeyRingBundle</c> class.
+ /// </p>
+ /// </remarks>
+ public class PgpSecretKeyRing
+ : PgpKeyRing
{
private readonly IList keys;
- private readonly IList extraPubKeys;
-
- internal PgpSecretKeyRing(
- IList keys)
- : this(keys, Platform.CreateArrayList())
- {
- }
-
- private PgpSecretKeyRing(
- IList keys,
- IList extraPubKeys)
- {
- this.keys = keys;
- this.extraPubKeys = extraPubKeys;
- }
-
- public PgpSecretKeyRing(
+ private readonly IList extraPubKeys;
+
+ internal PgpSecretKeyRing(
+ IList keys)
+ : this(keys, Platform.CreateArrayList())
+ {
+ }
+
+ private PgpSecretKeyRing(
+ IList keys,
+ IList extraPubKeys)
+ {
+ this.keys = keys;
+ this.extraPubKeys = extraPubKeys;
+ }
+
+ public PgpSecretKeyRing(
byte[] encoding)
: this(new MemoryStream(encoding))
{
}
- public PgpSecretKeyRing(
+ public PgpSecretKeyRing(
Stream inputStream)
{
- this.keys = Platform.CreateArrayList();
+ this.keys = Platform.CreateArrayList();
this.extraPubKeys = Platform.CreateArrayList();
- BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream);
+ BcpgInputStream bcpgInput = BcpgInputStream.Wrap(inputStream);
- PacketTag initialTag = bcpgInput.NextPacketTag();
- if (initialTag != PacketTag.SecretKey && initialTag != PacketTag.SecretSubkey)
+ PacketTag initialTag = bcpgInput.NextPacketTag();
+ if (initialTag != PacketTag.SecretKey && initialTag != PacketTag.SecretSubkey)
{
throw new IOException("secret key ring doesn't start with secret key tag: "
- + "tag 0x" + ((int)initialTag).ToString("X"));
+ + "tag 0x" + ((int)initialTag).ToString("X"));
}
- SecretKeyPacket secret = (SecretKeyPacket) bcpgInput.ReadPacket();
+ SecretKeyPacket secret = (SecretKeyPacket) bcpgInput.ReadPacket();
- //
+ //
// ignore GPG comment packets if found.
//
while (bcpgInput.NextPacketTag() == PacketTag.Experimental2)
@@ -66,65 +66,65 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
bcpgInput.ReadPacket();
}
- TrustPacket trust = ReadOptionalTrustPacket(bcpgInput);
+ TrustPacket trust = ReadOptionalTrustPacket(bcpgInput);
- // revocation and direct signatures
- IList keySigs = ReadSignaturesAndTrust(bcpgInput);
+ // revocation and direct signatures
+ IList keySigs = ReadSignaturesAndTrust(bcpgInput);
- IList ids, idTrusts, idSigs;
- ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs);
+ IList ids, idTrusts, idSigs;
+ ReadUserIDs(bcpgInput, out ids, out idTrusts, out idSigs);
- keys.Add(new PgpSecretKey(secret, new PgpPublicKey(secret.PublicKeyPacket, trust, keySigs, ids, idTrusts, idSigs)));
+ keys.Add(new PgpSecretKey(secret, new PgpPublicKey(secret.PublicKeyPacket, trust, keySigs, ids, idTrusts, idSigs)));
- // Read subkeys
- while (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey
- || bcpgInput.NextPacketTag() == PacketTag.PublicSubkey)
+ // Read subkeys
+ while (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey
+ || bcpgInput.NextPacketTag() == PacketTag.PublicSubkey)
{
- if (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey)
- {
- SecretSubkeyPacket sub = (SecretSubkeyPacket) bcpgInput.ReadPacket();
-
- //
- // ignore GPG comment packets if found.
- //
- while (bcpgInput.NextPacketTag() == PacketTag.Experimental2)
- {
- bcpgInput.ReadPacket();
- }
-
- TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput);
- IList sigList = ReadSignaturesAndTrust(bcpgInput);
-
- keys.Add(new PgpSecretKey(sub, new PgpPublicKey(sub.PublicKeyPacket, subTrust, sigList)));
- }
- else
- {
- PublicSubkeyPacket sub = (PublicSubkeyPacket) bcpgInput.ReadPacket();
-
- TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput);
- IList sigList = ReadSignaturesAndTrust(bcpgInput);
-
- extraPubKeys.Add(new PgpPublicKey(sub, subTrust, sigList));
- }
+ if (bcpgInput.NextPacketTag() == PacketTag.SecretSubkey)
+ {
+ SecretSubkeyPacket sub = (SecretSubkeyPacket) bcpgInput.ReadPacket();
+
+ //
+ // ignore GPG comment packets if found.
+ //
+ while (bcpgInput.NextPacketTag() == PacketTag.Experimental2)
+ {
+ bcpgInput.ReadPacket();
+ }
+
+ TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput);
+ IList sigList = ReadSignaturesAndTrust(bcpgInput);
+
+ keys.Add(new PgpSecretKey(sub, new PgpPublicKey(sub.PublicKeyPacket, subTrust, sigList)));
+ }
+ else
+ {
+ PublicSubkeyPacket sub = (PublicSubkeyPacket) bcpgInput.ReadPacket();
+
+ TrustPacket subTrust = ReadOptionalTrustPacket(bcpgInput);
+ IList sigList = ReadSignaturesAndTrust(bcpgInput);
+
+ extraPubKeys.Add(new PgpPublicKey(sub, subTrust, sigList));
+ }
}
}
- /// <summary>Return the public key for the master key.</summary>
+ /// <summary>Return the public key for the master key.</summary>
public PgpPublicKey GetPublicKey()
{
return ((PgpSecretKey) keys[0]).PublicKey;
}
- /// <summary>Return the master private key.</summary>
+ /// <summary>Return the master private key.</summary>
public PgpSecretKey GetSecretKey()
{
return (PgpSecretKey) keys[0];
}
- /// <summary>Allows enumeration of the secret keys.</summary>
- /// <returns>An <c>IEnumerable</c> of <c>PgpSecretKey</c> objects.</returns>
- public IEnumerable GetSecretKeys()
+ /// <summary>Allows enumeration of the secret keys.</summary>
+ /// <returns>An <c>IEnumerable</c> of <c>PgpSecretKey</c> objects.</returns>
+ public IEnumerable GetSecretKeys()
{
return new EnumerableProxy(keys);
}
@@ -132,29 +132,29 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
public PgpSecretKey GetSecretKey(
long keyId)
{
- foreach (PgpSecretKey k in keys)
- {
- if (keyId == k.KeyId)
- {
- return k;
- }
- }
-
- return null;
+ foreach (PgpSecretKey k in keys)
+ {
+ if (keyId == k.KeyId)
+ {
+ return k;
+ }
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Return an iterator of the public keys in the secret key ring that
+ /// have no matching private key. At the moment only personal certificate data
+ /// appears in this fashion.
+ /// </summary>
+ /// <returns>An <c>IEnumerable</c> of unattached, or extra, public keys.</returns>
+ public IEnumerable GetExtraPublicKeys()
+ {
+ return new EnumerableProxy(extraPubKeys);
}
- /// <summary>
- /// Return an iterator of the public keys in the secret key ring that
- /// have no matching private key. At the moment only personal certificate data
- /// appears in this fashion.
- /// </summary>
- /// <returns>An <c>IEnumerable</c> of unattached, or extra, public keys.</returns>
- public IEnumerable GetExtraPublicKeys()
- {
- return new EnumerableProxy(extraPubKeys);
- }
-
- public byte[] GetEncoded()
+ public byte[] GetEncoded()
{
MemoryStream bOut = new MemoryStream();
@@ -166,117 +166,124 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
public void Encode(
Stream outStr)
{
- if (outStr == null)
- throw new ArgumentNullException("outStr");
-
- foreach (PgpSecretKey key in keys)
- {
- key.Encode(outStr);
- }
- foreach (PgpPublicKey extraPubKey in extraPubKeys)
- {
- extraPubKey.Encode(outStr);
- }
+ if (outStr == null)
+ throw new ArgumentNullException("outStr");
+
+ foreach (PgpSecretKey key in keys)
+ {
+ key.Encode(outStr);
+ }
+ foreach (PgpPublicKey extraPubKey in extraPubKeys)
+ {
+ extraPubKey.Encode(outStr);
+ }
}
- /// <summary>
- /// Replace the public key set on the secret ring with the corresponding key off the public ring.
- /// </summary>
- /// <param name="secretRing">Secret ring to be changed.</param>
- /// <param name="publicRing">Public ring containing the new public key set.</param>
- public static PgpSecretKeyRing ReplacePublicKeys(
- PgpSecretKeyRing secretRing,
- PgpPublicKeyRing publicRing)
- {
+ /// <summary>
+ /// Replace the public key set on the secret ring with the corresponding key off the public ring.
+ /// </summary>
+ /// <param name="secretRing">Secret ring to be changed.</param>
+ /// <param name="publicRing">Public ring containing the new public key set.</param>
+ public static PgpSecretKeyRing ReplacePublicKeys(
+ PgpSecretKeyRing secretRing,
+ PgpPublicKeyRing publicRing)
+ {
IList newList = Platform.CreateArrayList(secretRing.keys.Count);
- foreach (PgpSecretKey sk in secretRing.keys)
- {
- PgpPublicKey pk = publicRing.GetPublicKey(sk.KeyId);
-
- newList.Add(PgpSecretKey.ReplacePublicKey(sk, pk));
- }
-
- return new PgpSecretKeyRing(newList);
- }
-
- /// <summary>
- /// Return a copy of the passed in secret key ring, with the master key and sub keys encrypted
- /// using a new password and the passed in algorithm.
- /// </summary>
- /// <param name="ring">The <c>PgpSecretKeyRing</c> to be copied.</param>
- /// <param name="oldPassPhrase">The current password for key.</param>
- /// <param name="newPassPhrase">The new password for the key.</param>
- /// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param>
- /// <param name="rand">Source of randomness.</param>
- public static PgpSecretKeyRing CopyWithNewPassword(
- PgpSecretKeyRing ring,
- char[] oldPassPhrase,
- char[] newPassPhrase,
- SymmetricKeyAlgorithmTag newEncAlgorithm,
- SecureRandom rand)
- {
+ foreach (PgpSecretKey sk in secretRing.keys)
+ {
+ PgpPublicKey pk = publicRing.GetPublicKey(sk.KeyId);
+
+ newList.Add(PgpSecretKey.ReplacePublicKey(sk, pk));
+ }
+
+ return new PgpSecretKeyRing(newList);
+ }
+
+ /// <summary>
+ /// Return a copy of the passed in secret key ring, with the master key and sub keys encrypted
+ /// using a new password and the passed in algorithm.
+ /// </summary>
+ /// <param name="ring">The <c>PgpSecretKeyRing</c> to be copied.</param>
+ /// <param name="oldPassPhrase">The current password for key.</param>
+ /// <param name="newPassPhrase">The new password for the key.</param>
+ /// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param>
+ /// <param name="rand">Source of randomness.</param>
+ public static PgpSecretKeyRing CopyWithNewPassword(
+ PgpSecretKeyRing ring,
+ char[] oldPassPhrase,
+ char[] newPassPhrase,
+ SymmetricKeyAlgorithmTag newEncAlgorithm,
+ SecureRandom rand)
+ {
IList newKeys = Platform.CreateArrayList(ring.keys.Count);
- foreach (PgpSecretKey secretKey in ring.GetSecretKeys())
- {
- newKeys.Add(PgpSecretKey.CopyWithNewPassword(secretKey, oldPassPhrase, newPassPhrase, newEncAlgorithm, rand));
- }
-
- return new PgpSecretKeyRing(newKeys, ring.extraPubKeys);
- }
-
- /// <summary>
- /// Returns a new key ring with the secret key passed in either added or
- /// replacing an existing one with the same key ID.
- /// </summary>
- /// <param name="secRing">The secret key ring to be modified.</param>
- /// <param name="secKey">The secret key to be inserted.</param>
- /// <returns>A new <c>PgpSecretKeyRing</c></returns>
- public static PgpSecretKeyRing InsertSecretKey(
+ foreach (PgpSecretKey secretKey in ring.GetSecretKeys())
+ {
+ if (secretKey.IsPrivateKeyEmpty)
+ {
+ newKeys.Add(secretKey);
+ }
+ else
+ {
+ newKeys.Add(PgpSecretKey.CopyWithNewPassword(secretKey, oldPassPhrase, newPassPhrase, newEncAlgorithm, rand));
+ }
+ }
+
+ return new PgpSecretKeyRing(newKeys, ring.extraPubKeys);
+ }
+
+ /// <summary>
+ /// Returns a new key ring with the secret key passed in either added or
+ /// replacing an existing one with the same key ID.
+ /// </summary>
+ /// <param name="secRing">The secret key ring to be modified.</param>
+ /// <param name="secKey">The secret key to be inserted.</param>
+ /// <returns>A new <c>PgpSecretKeyRing</c></returns>
+ public static PgpSecretKeyRing InsertSecretKey(
PgpSecretKeyRing secRing,
PgpSecretKey secKey)
{
IList keys = Platform.CreateArrayList(secRing.keys);
bool found = false;
- bool masterFound = false;
+ bool masterFound = false;
- for (int i = 0; i != keys.Count; i++)
+ for (int i = 0; i != keys.Count; i++)
{
PgpSecretKey key = (PgpSecretKey) keys[i];
- if (key.KeyId == secKey.KeyId)
+ if (key.KeyId == secKey.KeyId)
{
found = true;
keys[i] = secKey;
}
- if (key.IsMasterKey)
- {
- masterFound = true;
- }
- }
+ if (key.IsMasterKey)
+ {
+ masterFound = true;
+ }
+ }
if (!found)
{
- if (secKey.IsMasterKey)
- {
- if (masterFound)
- throw new ArgumentException("cannot add a master key to a ring that already has one");
-
- keys.Insert(0, secKey);
- }
- else
- {
- keys.Add(secKey);
- }
+ if (secKey.IsMasterKey)
+ {
+ if (masterFound)
+ throw new ArgumentException("cannot add a master key to a ring that already has one");
+
+ keys.Insert(0, secKey);
+ }
+ else
+ {
+ keys.Add(secKey);
+ }
}
- return new PgpSecretKeyRing(keys, secRing.extraPubKeys);
- }
+ return new PgpSecretKeyRing(keys, secRing.extraPubKeys);
+ }
- /// <summary>Returns a new key ring with the secret key passed in removed from the key ring.</summary>
- /// <param name="secRing">The secret key ring to be modified.</param>
- /// <param name="secKey">The secret key to be removed.</param>
- /// <returns>A new <c>PgpSecretKeyRing</c>, or null if secKey is not found.</returns>
+ /// <summary>Returns a new key ring with the secret key passed in removed from the key ring.</summary>
+ /// <param name="secRing">The secret key ring to be modified.</param>
+ /// <param name="secKey">The secret key to be removed.</param>
+ /// <returns>A new <c>PgpSecretKeyRing</c>, or null if secKey is not found.</returns>
public static PgpSecretKeyRing RemoveSecretKey(
PgpSecretKeyRing secRing,
PgpSecretKey secKey)
@@ -284,18 +291,18 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp
IList keys = Platform.CreateArrayList(secRing.keys);
bool found = false;
- for (int i = 0; i < keys.Count; i++)
+ for (int i = 0; i < keys.Count; i++)
{
PgpSecretKey key = (PgpSecretKey)keys[i];
- if (key.KeyId == secKey.KeyId)
+ if (key.KeyId == secKey.KeyId)
{
found = true;
keys.RemoveAt(i);
}
}
- return found ? new PgpSecretKeyRing(keys, secRing.extraPubKeys) : null;
+ return found ? new PgpSecretKeyRing(keys, secRing.extraPubKeys) : null;
}
}
}
|