PgpPublicKeyRing
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using System;
using System.Collections.Generic;
using System.IO;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
public class PgpPublicKeyRing : PgpKeyRing
{
private readonly IList<PgpPublicKey> keys;
public PgpPublicKeyRing(byte[] encoding)
: this(new MemoryStream(encoding, false))
{
}
internal PgpPublicKeyRing(IList<PgpPublicKey> pubKeys)
{
keys = pubKeys;
}
public PgpPublicKeyRing(Stream inputStream)
{
keys = new List<PgpPublicKey>();
BcpgInputStream bcpgInputStream = BcpgInputStream.Wrap(inputStream);
PacketTag packetTag = bcpgInputStream.SkipMarkerPackets();
if (packetTag != PacketTag.PublicKey && packetTag != PacketTag.PublicSubkey) {
int num = (int)packetTag;
throw new IOException("public key ring doesn't start with public key tag: tag 0x" + num.ToString("X"));
}
PublicKeyPacket publicPk = ReadPublicKeyPacket(bcpgInputStream);
TrustPacket trustPk = PgpKeyRing.ReadOptionalTrustPacket(bcpgInputStream);
IList<PgpSignature> keySigs = PgpKeyRing.ReadSignaturesAndTrust(bcpgInputStream);
PgpKeyRing.ReadUserIDs(bcpgInputStream, out IList<IUserDataPacket> ids, out IList<TrustPacket> idTrusts, out IList<IList<PgpSignature>> idSigs);
keys.Add(new PgpPublicKey(publicPk, trustPk, keySigs, ids, idTrusts, idSigs));
while (bcpgInputStream.NextPacketTag() == PacketTag.PublicSubkey) {
keys.Add(ReadSubkey(bcpgInputStream));
}
}
public virtual PgpPublicKey GetPublicKey()
{
return keys[0];
}
public virtual PgpPublicKey GetPublicKey(long keyId)
{
foreach (PgpPublicKey key in keys) {
if (keyId == key.KeyId)
return key;
}
return null;
}
public virtual IEnumerable<PgpPublicKey> GetPublicKeys()
{
return CollectionUtilities.Proxy(keys);
}
public virtual byte[] GetEncoded()
{
MemoryStream memoryStream = new MemoryStream();
Encode(memoryStream);
return memoryStream.ToArray();
}
public virtual void Encode(Stream outStr)
{
if (outStr == null)
throw new ArgumentNullException("outStr");
foreach (PgpPublicKey key in keys) {
key.Encode(outStr);
}
}
public static PgpPublicKeyRing InsertPublicKey(PgpPublicKeyRing pubRing, PgpPublicKey pubKey)
{
List<PgpPublicKey> list = new List<PgpPublicKey>(pubRing.keys);
bool flag = false;
bool flag2 = false;
for (int i = 0; i != list.Count; i++) {
PgpPublicKey pgpPublicKey = list[i];
if (pgpPublicKey.KeyId == pubKey.KeyId) {
flag = true;
list[i] = pubKey;
}
if (pgpPublicKey.IsMasterKey)
flag2 = true;
}
if (!flag) {
if (pubKey.IsMasterKey) {
if (flag2)
throw new ArgumentException("cannot add a master key to a ring that already has one");
list.Insert(0, pubKey);
} else
list.Add(pubKey);
}
return new PgpPublicKeyRing(list);
}
public static PgpPublicKeyRing RemovePublicKey(PgpPublicKeyRing pubRing, PgpPublicKey pubKey)
{
int count = pubRing.keys.Count;
long keyId = pubKey.KeyId;
List<PgpPublicKey> list = new List<PgpPublicKey>(count);
bool flag = false;
foreach (PgpPublicKey key in pubRing.keys) {
if (key.KeyId == keyId)
flag = true;
else
list.Add(key);
}
if (!flag)
return null;
return new PgpPublicKeyRing(list);
}
internal static PublicKeyPacket ReadPublicKeyPacket(BcpgInputStream bcpgInput)
{
Packet packet = bcpgInput.ReadPacket();
PublicKeyPacket obj = packet as PublicKeyPacket;
if (obj == null)
throw new IOException("unexpected packet in stream: " + packet?.ToString());
return obj;
}
internal static PgpPublicKey ReadSubkey(BcpgInputStream bcpgInput)
{
PublicKeyPacket publicPk = ReadPublicKeyPacket(bcpgInput);
TrustPacket trustPk = PgpKeyRing.ReadOptionalTrustPacket(bcpgInput);
IList<PgpSignature> sigs = PgpKeyRing.ReadSignaturesAndTrust(bcpgInput);
return new PgpPublicKey(publicPk, trustPk, sigs);
}
public static PgpPublicKeyRing Join(PgpPublicKeyRing first, PgpPublicKeyRing second)
{
return Join(first, second, false, false);
}
public static PgpPublicKeyRing Join(PgpPublicKeyRing first, PgpPublicKeyRing second, bool joinTrustPackets, bool allowSubkeySigsOnNonSubkey)
{
if (!Arrays.AreEqual(first.GetPublicKey().GetFingerprint(), second.GetPublicKey().GetFingerprint()))
throw new ArgumentException("Cannot merge certificates with differing primary keys.");
HashSet<long> hashSet = new HashSet<long>();
foreach (PgpPublicKey publicKey2 in second.GetPublicKeys()) {
hashSet.Add(publicKey2.KeyId);
}
List<PgpPublicKey> list = new List<PgpPublicKey>();
foreach (PgpPublicKey publicKey3 in first.GetPublicKeys()) {
PgpPublicKey publicKey = second.GetPublicKey(publicKey3.KeyId);
if (publicKey != null) {
list.Add(PgpPublicKey.Join(publicKey3, publicKey, joinTrustPackets, allowSubkeySigsOnNonSubkey));
hashSet.Remove(publicKey3.KeyId);
} else
list.Add(publicKey3);
}
foreach (long item in hashSet) {
list.Add(second.GetPublicKey(item));
}
return new PgpPublicKeyRing(list);
}
}
}