Initial Commit
This commit is contained in:
270
iTechSharp/srcbc/openpgp/PgpSecretKeyRingBundle.cs
Normal file
270
iTechSharp/srcbc/openpgp/PgpSecretKeyRingBundle.cs
Normal file
@@ -0,0 +1,270 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
using Org.BouncyCastle.Utilities.Collections;
|
||||
|
||||
namespace Org.BouncyCastle.Bcpg.OpenPgp
|
||||
{
|
||||
/// <remarks>
|
||||
/// Often a PGP key ring file is made up of a succession of master/sub-key key rings.
|
||||
/// If you want to read an entire secret key file in one hit this is the class for you.
|
||||
/// </remarks>
|
||||
public class PgpSecretKeyRingBundle
|
||||
{
|
||||
private readonly IDictionary secretRings;
|
||||
private readonly ArrayList order;
|
||||
|
||||
private PgpSecretKeyRingBundle(
|
||||
IDictionary secretRings,
|
||||
ArrayList order)
|
||||
{
|
||||
this.secretRings = secretRings;
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public PgpSecretKeyRingBundle(
|
||||
byte[] encoding)
|
||||
: this(new MemoryStream(encoding, false))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Build a PgpSecretKeyRingBundle from the passed in input stream.</summary>
|
||||
/// <param name="inputStream">Input stream containing data.</param>
|
||||
/// <exception cref="IOException">If a problem parsing the stream occurs.</exception>
|
||||
/// <exception cref="PgpException">If an object is encountered which isn't a PgpSecretKeyRing.</exception>
|
||||
public PgpSecretKeyRingBundle(
|
||||
Stream inputStream)
|
||||
: this(new PgpObjectFactory(inputStream).AllPgpObjects())
|
||||
{
|
||||
}
|
||||
|
||||
public PgpSecretKeyRingBundle(
|
||||
IEnumerable e)
|
||||
{
|
||||
this.secretRings = new Hashtable();
|
||||
this.order = new ArrayList();
|
||||
|
||||
foreach (object obj in e)
|
||||
{
|
||||
PgpSecretKeyRing pgpSecret = obj as PgpSecretKeyRing;
|
||||
|
||||
if (pgpSecret == null)
|
||||
{
|
||||
throw new PgpException(obj.GetType().FullName + " found where PgpSecretKeyRing expected");
|
||||
}
|
||||
|
||||
long key = pgpSecret.GetPublicKey().KeyId;
|
||||
secretRings.Add(key, pgpSecret);
|
||||
order.Add(key);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use 'Count' property instead")]
|
||||
public int Size
|
||||
{
|
||||
get { return order.Count; }
|
||||
}
|
||||
|
||||
/// <summary>Return the number of rings in this collection.</summary>
|
||||
public int Count
|
||||
{
|
||||
get { return order.Count; }
|
||||
}
|
||||
|
||||
/// <summary>Allow enumeration of the secret key rings making up this collection.</summary>
|
||||
public IEnumerable GetKeyRings()
|
||||
{
|
||||
return new EnumerableProxy(secretRings.Values);
|
||||
}
|
||||
|
||||
/// <summary>Allow enumeration of the key rings associated with the passed in userId.</summary>
|
||||
/// <param name="userId">The user ID to be matched.</param>
|
||||
/// <returns>An <c>IEnumerable</c> of key rings which matched (possibly none).</returns>
|
||||
public IEnumerable GetKeyRings(
|
||||
string userId)
|
||||
{
|
||||
return GetKeyRings(userId, false, false);
|
||||
}
|
||||
|
||||
/// <summary>Allow enumeration of the key rings associated with the passed in userId.</summary>
|
||||
/// <param name="userId">The user ID to be matched.</param>
|
||||
/// <param name="matchPartial">If true, userId need only be a substring of an actual ID string to match.</param>
|
||||
/// <returns>An <c>IEnumerable</c> of key rings which matched (possibly none).</returns>
|
||||
public IEnumerable GetKeyRings(
|
||||
string userId,
|
||||
bool matchPartial)
|
||||
{
|
||||
return GetKeyRings(userId, matchPartial, false);
|
||||
}
|
||||
|
||||
/// <summary>Allow enumeration of the key rings associated with the passed in userId.</summary>
|
||||
/// <param name="userId">The user ID to be matched.</param>
|
||||
/// <param name="matchPartial">If true, userId need only be a substring of an actual ID string to match.</param>
|
||||
/// <param name="ignoreCase">If true, case is ignored in user ID comparisons.</param>
|
||||
/// <returns>An <c>IEnumerable</c> of key rings which matched (possibly none).</returns>
|
||||
public IEnumerable GetKeyRings(
|
||||
string userId,
|
||||
bool matchPartial,
|
||||
bool ignoreCase)
|
||||
{
|
||||
IList rings = new ArrayList();
|
||||
|
||||
if (ignoreCase)
|
||||
{
|
||||
userId = userId.ToLower(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
foreach (PgpSecretKeyRing secRing in GetKeyRings())
|
||||
{
|
||||
foreach (string nextUserID in secRing.GetSecretKey().UserIds)
|
||||
{
|
||||
string next = nextUserID;
|
||||
if (ignoreCase)
|
||||
{
|
||||
next = next.ToLower(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
if (matchPartial)
|
||||
{
|
||||
if (next.IndexOf(userId) > -1)
|
||||
{
|
||||
rings.Add(secRing);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (next.Equals(userId))
|
||||
{
|
||||
rings.Add(secRing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new EnumerableProxy(rings);
|
||||
}
|
||||
|
||||
/// <summary>Return the PGP secret key associated with the given key id.</summary>
|
||||
/// <param name="keyId">The ID of the secret key to return.</param>
|
||||
public PgpSecretKey GetSecretKey(
|
||||
long keyId)
|
||||
{
|
||||
foreach (PgpSecretKeyRing secRing in GetKeyRings())
|
||||
{
|
||||
PgpSecretKey sec = secRing.GetSecretKey(keyId);
|
||||
|
||||
if (sec != null)
|
||||
{
|
||||
return sec;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Return the secret key ring which contains the key referred to by keyId</summary>
|
||||
/// <param name="keyId">The ID of the secret key</param>
|
||||
public PgpSecretKeyRing GetSecretKeyRing(
|
||||
long keyId)
|
||||
{
|
||||
long id = keyId;
|
||||
|
||||
if (secretRings.Contains(id))
|
||||
{
|
||||
return (PgpSecretKeyRing) secretRings[id];
|
||||
}
|
||||
|
||||
foreach (PgpSecretKeyRing secretRing in GetKeyRings())
|
||||
{
|
||||
PgpSecretKey secret = secretRing.GetSecretKey(keyId);
|
||||
|
||||
if (secret != null)
|
||||
{
|
||||
return secretRing;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] GetEncoded()
|
||||
{
|
||||
MemoryStream bOut = new MemoryStream();
|
||||
|
||||
Encode(bOut);
|
||||
|
||||
return bOut.ToArray();
|
||||
}
|
||||
|
||||
public void Encode(
|
||||
Stream outStr)
|
||||
{
|
||||
BcpgOutputStream bcpgOut = BcpgOutputStream.Wrap(outStr);
|
||||
|
||||
foreach (long key in order)
|
||||
{
|
||||
PgpSecretKeyRing pub = (PgpSecretKeyRing) secretRings[key];
|
||||
|
||||
pub.Encode(bcpgOut);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a new bundle containing the contents of the passed in bundle and
|
||||
/// the passed in secret key ring.
|
||||
/// </summary>
|
||||
/// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be added to.</param>
|
||||
/// <param name="secretKeyRing">The key ring to be added.</param>
|
||||
/// <returns>A new <c>PgpSecretKeyRingBundle</c> merging the current one with the passed in key ring.</returns>
|
||||
/// <exception cref="ArgumentException">If the keyId for the passed in key ring is already present.</exception>
|
||||
public static PgpSecretKeyRingBundle AddSecretKeyRing(
|
||||
PgpSecretKeyRingBundle bundle,
|
||||
PgpSecretKeyRing secretKeyRing)
|
||||
{
|
||||
long key = secretKeyRing.GetPublicKey().KeyId;
|
||||
|
||||
if (bundle.secretRings.Contains(key))
|
||||
{
|
||||
throw new ArgumentException("Collection already contains a key with a keyId for the passed in ring.");
|
||||
}
|
||||
|
||||
IDictionary newSecretRings = new Hashtable(bundle.secretRings);
|
||||
ArrayList newOrder = new ArrayList(bundle.order);
|
||||
|
||||
newSecretRings[key] = secretKeyRing;
|
||||
newOrder.Add(key);
|
||||
|
||||
return new PgpSecretKeyRingBundle(newSecretRings, newOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a new bundle containing the contents of the passed in bundle with
|
||||
/// the passed in secret key ring removed.
|
||||
/// </summary>
|
||||
/// <param name="bundle">The <c>PgpSecretKeyRingBundle</c> the key ring is to be removed from.</param>
|
||||
/// <param name="secretKeyRing">The key ring to be removed.</param>
|
||||
/// <returns>A new <c>PgpSecretKeyRingBundle</c> not containing the passed in key ring.</returns>
|
||||
/// <exception cref="ArgumentException">If the keyId for the passed in key ring is not present.</exception>
|
||||
public static PgpSecretKeyRingBundle RemoveSecretKeyRing(
|
||||
PgpSecretKeyRingBundle bundle,
|
||||
PgpSecretKeyRing secretKeyRing)
|
||||
{
|
||||
long key = secretKeyRing.GetPublicKey().KeyId;
|
||||
|
||||
if (!bundle.secretRings.Contains(key))
|
||||
{
|
||||
throw new ArgumentException("Collection does not contain a key with a keyId for the passed in ring.");
|
||||
}
|
||||
|
||||
IDictionary newSecretRings = new Hashtable(bundle.secretRings);
|
||||
ArrayList newOrder = new ArrayList(bundle.order);
|
||||
|
||||
newSecretRings.Remove(key);
|
||||
newOrder.Remove(key);
|
||||
|
||||
return new PgpSecretKeyRingBundle(newSecretRings, newOrder);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user