739 lines
18 KiB
C#
739 lines
18 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using Org.BouncyCastle.Asn1.X9;
|
|
using Org.BouncyCastle.Crypto;
|
|
using Org.BouncyCastle.Crypto.Generators;
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Math;
|
|
using Org.BouncyCastle.Math.EC;
|
|
using Org.BouncyCastle.Security;
|
|
using Org.BouncyCastle.Utilities;
|
|
using Org.BouncyCastle.Utilities.Collections;
|
|
|
|
namespace Org.BouncyCastle.Bcpg.OpenPgp;
|
|
|
|
public class PgpPublicKey
|
|
{
|
|
private static readonly int[] MasterKeyCertificationTypes = new int[4] { 19, 18, 17, 16 };
|
|
|
|
private long keyId;
|
|
|
|
private byte[] fingerprint;
|
|
|
|
private int keyStrength;
|
|
|
|
internal PublicKeyPacket publicPk;
|
|
|
|
internal TrustPacket trustPk;
|
|
|
|
internal IList keySigs = Platform.CreateArrayList();
|
|
|
|
internal IList ids = Platform.CreateArrayList();
|
|
|
|
internal IList idTrusts = Platform.CreateArrayList();
|
|
|
|
internal IList idSigs = Platform.CreateArrayList();
|
|
|
|
internal IList subSigs;
|
|
|
|
public int Version => publicPk.Version;
|
|
|
|
public DateTime CreationTime => publicPk.GetTime();
|
|
|
|
[Obsolete("Use 'GetValidSeconds' instead")]
|
|
public int ValidDays
|
|
{
|
|
get
|
|
{
|
|
if (publicPk.Version <= 3)
|
|
{
|
|
return publicPk.ValidDays;
|
|
}
|
|
long validSeconds = GetValidSeconds();
|
|
if (validSeconds <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
int val = (int)(validSeconds / 86400);
|
|
return System.Math.Max(1, val);
|
|
}
|
|
}
|
|
|
|
public long KeyId => keyId;
|
|
|
|
public bool IsEncryptionKey
|
|
{
|
|
get
|
|
{
|
|
switch (publicPk.Algorithm)
|
|
{
|
|
case PublicKeyAlgorithmTag.RsaGeneral:
|
|
case PublicKeyAlgorithmTag.RsaEncrypt:
|
|
case PublicKeyAlgorithmTag.ElGamalEncrypt:
|
|
case PublicKeyAlgorithmTag.EC:
|
|
case PublicKeyAlgorithmTag.ElGamalGeneral:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsMasterKey => subSigs == null;
|
|
|
|
public PublicKeyAlgorithmTag Algorithm => publicPk.Algorithm;
|
|
|
|
public int BitStrength => keyStrength;
|
|
|
|
public PublicKeyPacket PublicKeyPacket => publicPk;
|
|
|
|
public static byte[] CalculateFingerprint(PublicKeyPacket publicPk)
|
|
{
|
|
IBcpgKey key = publicPk.Key;
|
|
IDigest digest;
|
|
if (publicPk.Version <= 3)
|
|
{
|
|
RsaPublicBcpgKey rsaPublicBcpgKey = (RsaPublicBcpgKey)key;
|
|
try
|
|
{
|
|
digest = DigestUtilities.GetDigest("MD5");
|
|
UpdateDigest(digest, rsaPublicBcpgKey.Modulus);
|
|
UpdateDigest(digest, rsaPublicBcpgKey.PublicExponent);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new PgpException("can't encode key components: " + ex.Message, ex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
byte[] encodedContents = publicPk.GetEncodedContents();
|
|
digest = DigestUtilities.GetDigest("SHA1");
|
|
digest.Update(153);
|
|
digest.Update((byte)(encodedContents.Length >> 8));
|
|
digest.Update((byte)encodedContents.Length);
|
|
digest.BlockUpdate(encodedContents, 0, encodedContents.Length);
|
|
}
|
|
catch (Exception ex2)
|
|
{
|
|
throw new PgpException("can't encode key components: " + ex2.Message, ex2);
|
|
}
|
|
}
|
|
return DigestUtilities.DoFinal(digest);
|
|
}
|
|
|
|
private static void UpdateDigest(IDigest d, BigInteger b)
|
|
{
|
|
byte[] array = b.ToByteArrayUnsigned();
|
|
d.BlockUpdate(array, 0, array.Length);
|
|
}
|
|
|
|
private void Init()
|
|
{
|
|
IBcpgKey key = publicPk.Key;
|
|
fingerprint = CalculateFingerprint(publicPk);
|
|
if (publicPk.Version <= 3)
|
|
{
|
|
RsaPublicBcpgKey rsaPublicBcpgKey = (RsaPublicBcpgKey)key;
|
|
keyId = rsaPublicBcpgKey.Modulus.LongValue;
|
|
keyStrength = rsaPublicBcpgKey.Modulus.BitLength;
|
|
return;
|
|
}
|
|
keyId = (long)(((ulong)fingerprint[fingerprint.Length - 8] << 56) | ((ulong)fingerprint[fingerprint.Length - 7] << 48) | ((ulong)fingerprint[fingerprint.Length - 6] << 40) | ((ulong)fingerprint[fingerprint.Length - 5] << 32) | ((ulong)fingerprint[fingerprint.Length - 4] << 24) | ((ulong)fingerprint[fingerprint.Length - 3] << 16) | ((ulong)fingerprint[fingerprint.Length - 2] << 8) | fingerprint[fingerprint.Length - 1]);
|
|
if (key is RsaPublicBcpgKey)
|
|
{
|
|
keyStrength = ((RsaPublicBcpgKey)key).Modulus.BitLength;
|
|
}
|
|
else if (key is DsaPublicBcpgKey)
|
|
{
|
|
keyStrength = ((DsaPublicBcpgKey)key).P.BitLength;
|
|
}
|
|
else if (key is ElGamalPublicBcpgKey)
|
|
{
|
|
keyStrength = ((ElGamalPublicBcpgKey)key).P.BitLength;
|
|
}
|
|
else if (key is ECPublicBcpgKey)
|
|
{
|
|
keyStrength = ECKeyPairGenerator.FindECCurveByOid(((ECPublicBcpgKey)key).CurveOid).Curve.FieldSize;
|
|
}
|
|
}
|
|
|
|
public PgpPublicKey(PublicKeyAlgorithmTag algorithm, AsymmetricKeyParameter pubKey, DateTime time)
|
|
{
|
|
if (pubKey.IsPrivate)
|
|
{
|
|
throw new ArgumentException("Expected a public key", "pubKey");
|
|
}
|
|
IBcpgKey key;
|
|
if (pubKey is RsaKeyParameters)
|
|
{
|
|
RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)pubKey;
|
|
key = new RsaPublicBcpgKey(rsaKeyParameters.Modulus, rsaKeyParameters.Exponent);
|
|
}
|
|
else if (pubKey is DsaPublicKeyParameters)
|
|
{
|
|
DsaPublicKeyParameters dsaPublicKeyParameters = (DsaPublicKeyParameters)pubKey;
|
|
DsaParameters parameters = dsaPublicKeyParameters.Parameters;
|
|
key = new DsaPublicBcpgKey(parameters.P, parameters.Q, parameters.G, dsaPublicKeyParameters.Y);
|
|
}
|
|
else if (pubKey is ECPublicKeyParameters)
|
|
{
|
|
ECPublicKeyParameters eCPublicKeyParameters = (ECPublicKeyParameters)pubKey;
|
|
key = algorithm switch
|
|
{
|
|
PublicKeyAlgorithmTag.EC => new ECDHPublicBcpgKey(eCPublicKeyParameters.PublicKeyParamSet, eCPublicKeyParameters.Q, HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag.Aes128),
|
|
PublicKeyAlgorithmTag.ECDsa => new ECDsaPublicBcpgKey(eCPublicKeyParameters.PublicKeyParamSet, eCPublicKeyParameters.Q),
|
|
_ => throw new PgpException("unknown EC algorithm"),
|
|
};
|
|
}
|
|
else
|
|
{
|
|
if (!(pubKey is ElGamalPublicKeyParameters))
|
|
{
|
|
throw new PgpException("unknown key class");
|
|
}
|
|
ElGamalPublicKeyParameters elGamalPublicKeyParameters = (ElGamalPublicKeyParameters)pubKey;
|
|
ElGamalParameters parameters2 = elGamalPublicKeyParameters.Parameters;
|
|
key = new ElGamalPublicBcpgKey(parameters2.P, parameters2.G, elGamalPublicKeyParameters.Y);
|
|
}
|
|
publicPk = new PublicKeyPacket(algorithm, time, key);
|
|
ids = Platform.CreateArrayList();
|
|
idSigs = Platform.CreateArrayList();
|
|
try
|
|
{
|
|
Init();
|
|
}
|
|
catch (IOException exception)
|
|
{
|
|
throw new PgpException("exception calculating keyId", exception);
|
|
}
|
|
}
|
|
|
|
public PgpPublicKey(PublicKeyPacket publicPk)
|
|
: this(publicPk, Platform.CreateArrayList(), Platform.CreateArrayList())
|
|
{
|
|
}
|
|
|
|
internal PgpPublicKey(PublicKeyPacket publicPk, TrustPacket trustPk, IList sigs)
|
|
{
|
|
this.publicPk = publicPk;
|
|
this.trustPk = trustPk;
|
|
subSigs = sigs;
|
|
Init();
|
|
}
|
|
|
|
internal PgpPublicKey(PgpPublicKey key, TrustPacket trust, IList subSigs)
|
|
{
|
|
publicPk = key.publicPk;
|
|
trustPk = trust;
|
|
this.subSigs = subSigs;
|
|
fingerprint = key.fingerprint;
|
|
keyId = key.keyId;
|
|
keyStrength = key.keyStrength;
|
|
}
|
|
|
|
internal PgpPublicKey(PgpPublicKey pubKey)
|
|
{
|
|
publicPk = pubKey.publicPk;
|
|
keySigs = Platform.CreateArrayList(pubKey.keySigs);
|
|
ids = Platform.CreateArrayList(pubKey.ids);
|
|
idTrusts = Platform.CreateArrayList(pubKey.idTrusts);
|
|
idSigs = Platform.CreateArrayList(pubKey.idSigs.Count);
|
|
for (int i = 0; i != pubKey.idSigs.Count; i++)
|
|
{
|
|
idSigs.Add(Platform.CreateArrayList((IList)pubKey.idSigs[i]));
|
|
}
|
|
if (pubKey.subSigs != null)
|
|
{
|
|
subSigs = Platform.CreateArrayList(pubKey.subSigs.Count);
|
|
for (int j = 0; j != pubKey.subSigs.Count; j++)
|
|
{
|
|
subSigs.Add(pubKey.subSigs[j]);
|
|
}
|
|
}
|
|
fingerprint = pubKey.fingerprint;
|
|
keyId = pubKey.keyId;
|
|
keyStrength = pubKey.keyStrength;
|
|
}
|
|
|
|
internal PgpPublicKey(PublicKeyPacket publicPk, TrustPacket trustPk, IList keySigs, IList ids, IList idTrusts, IList idSigs)
|
|
{
|
|
this.publicPk = publicPk;
|
|
this.trustPk = trustPk;
|
|
this.keySigs = keySigs;
|
|
this.ids = ids;
|
|
this.idTrusts = idTrusts;
|
|
this.idSigs = idSigs;
|
|
Init();
|
|
}
|
|
|
|
internal PgpPublicKey(PublicKeyPacket publicPk, IList ids, IList idSigs)
|
|
{
|
|
this.publicPk = publicPk;
|
|
this.ids = ids;
|
|
this.idSigs = idSigs;
|
|
Init();
|
|
}
|
|
|
|
public byte[] GetTrustData()
|
|
{
|
|
if (trustPk == null)
|
|
{
|
|
return null;
|
|
}
|
|
return Arrays.Clone(trustPk.GetLevelAndTrustAmount());
|
|
}
|
|
|
|
public long GetValidSeconds()
|
|
{
|
|
if (publicPk.Version <= 3)
|
|
{
|
|
return (long)publicPk.ValidDays * 86400L;
|
|
}
|
|
if (IsMasterKey)
|
|
{
|
|
for (int i = 0; i != MasterKeyCertificationTypes.Length; i++)
|
|
{
|
|
long expirationTimeFromSig = GetExpirationTimeFromSig(selfSigned: true, MasterKeyCertificationTypes[i]);
|
|
if (expirationTimeFromSig >= 0)
|
|
{
|
|
return expirationTimeFromSig;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
long expirationTimeFromSig2 = GetExpirationTimeFromSig(selfSigned: false, 24);
|
|
if (expirationTimeFromSig2 >= 0)
|
|
{
|
|
return expirationTimeFromSig2;
|
|
}
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
private long GetExpirationTimeFromSig(bool selfSigned, int signatureType)
|
|
{
|
|
long num = -1L;
|
|
long num2 = -1L;
|
|
foreach (PgpSignature item in GetSignaturesOfType(signatureType))
|
|
{
|
|
if (selfSigned && item.KeyId != KeyId)
|
|
{
|
|
continue;
|
|
}
|
|
PgpSignatureSubpacketVector hashedSubPackets = item.GetHashedSubPackets();
|
|
if (hashedSubPackets == null)
|
|
{
|
|
continue;
|
|
}
|
|
long keyExpirationTime = hashedSubPackets.GetKeyExpirationTime();
|
|
if (item.KeyId == KeyId)
|
|
{
|
|
if (item.CreationTime.Ticks > num2)
|
|
{
|
|
num2 = item.CreationTime.Ticks;
|
|
num = keyExpirationTime;
|
|
}
|
|
}
|
|
else if (keyExpirationTime == 0 || keyExpirationTime > num)
|
|
{
|
|
num = keyExpirationTime;
|
|
}
|
|
}
|
|
return num;
|
|
}
|
|
|
|
public byte[] GetFingerprint()
|
|
{
|
|
return (byte[])fingerprint.Clone();
|
|
}
|
|
|
|
public AsymmetricKeyParameter GetKey()
|
|
{
|
|
try
|
|
{
|
|
switch (publicPk.Algorithm)
|
|
{
|
|
case PublicKeyAlgorithmTag.RsaGeneral:
|
|
case PublicKeyAlgorithmTag.RsaEncrypt:
|
|
case PublicKeyAlgorithmTag.RsaSign:
|
|
{
|
|
RsaPublicBcpgKey rsaPublicBcpgKey = (RsaPublicBcpgKey)publicPk.Key;
|
|
return new RsaKeyParameters(isPrivate: false, rsaPublicBcpgKey.Modulus, rsaPublicBcpgKey.PublicExponent);
|
|
}
|
|
case PublicKeyAlgorithmTag.Dsa:
|
|
{
|
|
DsaPublicBcpgKey dsaPublicBcpgKey = (DsaPublicBcpgKey)publicPk.Key;
|
|
return new DsaPublicKeyParameters(dsaPublicBcpgKey.Y, new DsaParameters(dsaPublicBcpgKey.P, dsaPublicBcpgKey.Q, dsaPublicBcpgKey.G));
|
|
}
|
|
case PublicKeyAlgorithmTag.ECDsa:
|
|
return GetECKey("ECDSA");
|
|
case PublicKeyAlgorithmTag.EC:
|
|
return GetECKey("ECDH");
|
|
case PublicKeyAlgorithmTag.ElGamalEncrypt:
|
|
case PublicKeyAlgorithmTag.ElGamalGeneral:
|
|
{
|
|
ElGamalPublicBcpgKey elGamalPublicBcpgKey = (ElGamalPublicBcpgKey)publicPk.Key;
|
|
return new ElGamalPublicKeyParameters(elGamalPublicBcpgKey.Y, new ElGamalParameters(elGamalPublicBcpgKey.P, elGamalPublicBcpgKey.G));
|
|
}
|
|
default:
|
|
throw new PgpException("unknown public key algorithm encountered");
|
|
}
|
|
}
|
|
catch (PgpException ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new PgpException("exception constructing public key", exception);
|
|
}
|
|
}
|
|
|
|
private ECPublicKeyParameters GetECKey(string algorithm)
|
|
{
|
|
ECPublicBcpgKey eCPublicBcpgKey = (ECPublicBcpgKey)publicPk.Key;
|
|
X9ECParameters x9ECParameters = ECKeyPairGenerator.FindECCurveByOid(eCPublicBcpgKey.CurveOid);
|
|
ECPoint q = x9ECParameters.Curve.DecodePoint(BigIntegers.AsUnsignedByteArray(eCPublicBcpgKey.EncodedPoint));
|
|
return new ECPublicKeyParameters(algorithm, q, eCPublicBcpgKey.CurveOid);
|
|
}
|
|
|
|
public IEnumerable GetUserIds()
|
|
{
|
|
IList list = Platform.CreateArrayList();
|
|
foreach (object id in ids)
|
|
{
|
|
if (id is string)
|
|
{
|
|
list.Add(id);
|
|
}
|
|
}
|
|
return new EnumerableProxy(list);
|
|
}
|
|
|
|
public IEnumerable GetUserAttributes()
|
|
{
|
|
IList list = Platform.CreateArrayList();
|
|
foreach (object id in ids)
|
|
{
|
|
if (id is PgpUserAttributeSubpacketVector)
|
|
{
|
|
list.Add(id);
|
|
}
|
|
}
|
|
return new EnumerableProxy(list);
|
|
}
|
|
|
|
public IEnumerable GetSignaturesForId(string id)
|
|
{
|
|
if (id == null)
|
|
{
|
|
throw new ArgumentNullException("id");
|
|
}
|
|
for (int i = 0; i != ids.Count; i++)
|
|
{
|
|
if (id.Equals(ids[i]))
|
|
{
|
|
return new EnumerableProxy((IList)idSigs[i]);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public IEnumerable GetSignaturesForUserAttribute(PgpUserAttributeSubpacketVector userAttributes)
|
|
{
|
|
for (int i = 0; i != ids.Count; i++)
|
|
{
|
|
if (userAttributes.Equals(ids[i]))
|
|
{
|
|
return new EnumerableProxy((IList)idSigs[i]);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public IEnumerable GetSignaturesOfType(int signatureType)
|
|
{
|
|
IList list = Platform.CreateArrayList();
|
|
foreach (PgpSignature signature in GetSignatures())
|
|
{
|
|
if (signature.SignatureType == signatureType)
|
|
{
|
|
list.Add(signature);
|
|
}
|
|
}
|
|
return new EnumerableProxy(list);
|
|
}
|
|
|
|
public IEnumerable GetSignatures()
|
|
{
|
|
IList list = subSigs;
|
|
if (list == null)
|
|
{
|
|
list = Platform.CreateArrayList(keySigs);
|
|
foreach (ICollection idSig in idSigs)
|
|
{
|
|
CollectionUtilities.AddRange(list, idSig);
|
|
}
|
|
}
|
|
return new EnumerableProxy(list);
|
|
}
|
|
|
|
public IEnumerable GetKeySignatures()
|
|
{
|
|
IList list = subSigs;
|
|
if (list == null)
|
|
{
|
|
list = Platform.CreateArrayList(keySigs);
|
|
}
|
|
return new EnumerableProxy(list);
|
|
}
|
|
|
|
public byte[] GetEncoded()
|
|
{
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
Encode(memoryStream);
|
|
return memoryStream.ToArray();
|
|
}
|
|
|
|
public void Encode(Stream outStr)
|
|
{
|
|
BcpgOutputStream bcpgOutputStream = BcpgOutputStream.Wrap(outStr);
|
|
bcpgOutputStream.WritePacket(publicPk);
|
|
if (trustPk != null)
|
|
{
|
|
bcpgOutputStream.WritePacket(trustPk);
|
|
}
|
|
if (subSigs == null)
|
|
{
|
|
foreach (PgpSignature keySig in keySigs)
|
|
{
|
|
keySig.Encode(bcpgOutputStream);
|
|
}
|
|
for (int i = 0; i != ids.Count; i++)
|
|
{
|
|
if (ids[i] is string)
|
|
{
|
|
string id = (string)ids[i];
|
|
bcpgOutputStream.WritePacket(new UserIdPacket(id));
|
|
}
|
|
else
|
|
{
|
|
PgpUserAttributeSubpacketVector pgpUserAttributeSubpacketVector = (PgpUserAttributeSubpacketVector)ids[i];
|
|
bcpgOutputStream.WritePacket(new UserAttributePacket(pgpUserAttributeSubpacketVector.ToSubpacketArray()));
|
|
}
|
|
if (idTrusts[i] != null)
|
|
{
|
|
bcpgOutputStream.WritePacket((ContainedPacket)idTrusts[i]);
|
|
}
|
|
foreach (PgpSignature item in (IList)idSigs[i])
|
|
{
|
|
item.Encode(bcpgOutputStream);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
foreach (PgpSignature subSig in subSigs)
|
|
{
|
|
subSig.Encode(bcpgOutputStream);
|
|
}
|
|
}
|
|
|
|
public bool IsRevoked()
|
|
{
|
|
int num = 0;
|
|
bool flag = false;
|
|
if (IsMasterKey)
|
|
{
|
|
while (!flag && num < keySigs.Count)
|
|
{
|
|
if (((PgpSignature)keySigs[num++]).SignatureType == 32)
|
|
{
|
|
flag = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (!flag && num < subSigs.Count)
|
|
{
|
|
if (((PgpSignature)subSigs[num++]).SignatureType == 40)
|
|
{
|
|
flag = true;
|
|
}
|
|
}
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
public static PgpPublicKey AddCertification(PgpPublicKey key, string id, PgpSignature certification)
|
|
{
|
|
return AddCert(key, id, certification);
|
|
}
|
|
|
|
public static PgpPublicKey AddCertification(PgpPublicKey key, PgpUserAttributeSubpacketVector userAttributes, PgpSignature certification)
|
|
{
|
|
return AddCert(key, userAttributes, certification);
|
|
}
|
|
|
|
private static PgpPublicKey AddCert(PgpPublicKey key, object id, PgpSignature certification)
|
|
{
|
|
PgpPublicKey pgpPublicKey = new PgpPublicKey(key);
|
|
IList list = null;
|
|
for (int i = 0; i != pgpPublicKey.ids.Count; i++)
|
|
{
|
|
if (id.Equals(pgpPublicKey.ids[i]))
|
|
{
|
|
list = (IList)pgpPublicKey.idSigs[i];
|
|
}
|
|
}
|
|
if (list != null)
|
|
{
|
|
list.Add(certification);
|
|
}
|
|
else
|
|
{
|
|
list = Platform.CreateArrayList();
|
|
list.Add(certification);
|
|
pgpPublicKey.ids.Add(id);
|
|
pgpPublicKey.idTrusts.Add(null);
|
|
pgpPublicKey.idSigs.Add(list);
|
|
}
|
|
return pgpPublicKey;
|
|
}
|
|
|
|
public static PgpPublicKey RemoveCertification(PgpPublicKey key, PgpUserAttributeSubpacketVector userAttributes)
|
|
{
|
|
return RemoveCert(key, userAttributes);
|
|
}
|
|
|
|
public static PgpPublicKey RemoveCertification(PgpPublicKey key, string id)
|
|
{
|
|
return RemoveCert(key, id);
|
|
}
|
|
|
|
private static PgpPublicKey RemoveCert(PgpPublicKey key, object id)
|
|
{
|
|
PgpPublicKey pgpPublicKey = new PgpPublicKey(key);
|
|
bool flag = false;
|
|
for (int i = 0; i < pgpPublicKey.ids.Count; i++)
|
|
{
|
|
if (id.Equals(pgpPublicKey.ids[i]))
|
|
{
|
|
flag = true;
|
|
pgpPublicKey.ids.RemoveAt(i);
|
|
pgpPublicKey.idTrusts.RemoveAt(i);
|
|
pgpPublicKey.idSigs.RemoveAt(i);
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
return null;
|
|
}
|
|
return pgpPublicKey;
|
|
}
|
|
|
|
public static PgpPublicKey RemoveCertification(PgpPublicKey key, string id, PgpSignature certification)
|
|
{
|
|
return RemoveCert(key, id, certification);
|
|
}
|
|
|
|
public static PgpPublicKey RemoveCertification(PgpPublicKey key, PgpUserAttributeSubpacketVector userAttributes, PgpSignature certification)
|
|
{
|
|
return RemoveCert(key, userAttributes, certification);
|
|
}
|
|
|
|
private static PgpPublicKey RemoveCert(PgpPublicKey key, object id, PgpSignature certification)
|
|
{
|
|
PgpPublicKey pgpPublicKey = new PgpPublicKey(key);
|
|
bool flag = false;
|
|
for (int i = 0; i < pgpPublicKey.ids.Count; i++)
|
|
{
|
|
if (id.Equals(pgpPublicKey.ids[i]))
|
|
{
|
|
IList list = (IList)pgpPublicKey.idSigs[i];
|
|
flag = list.Contains(certification);
|
|
if (flag)
|
|
{
|
|
list.Remove(certification);
|
|
}
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
return null;
|
|
}
|
|
return pgpPublicKey;
|
|
}
|
|
|
|
public static PgpPublicKey AddCertification(PgpPublicKey key, PgpSignature certification)
|
|
{
|
|
if (key.IsMasterKey)
|
|
{
|
|
if (certification.SignatureType == 40)
|
|
{
|
|
throw new ArgumentException("signature type incorrect for master key revocation.");
|
|
}
|
|
}
|
|
else if (certification.SignatureType == 32)
|
|
{
|
|
throw new ArgumentException("signature type incorrect for sub-key revocation.");
|
|
}
|
|
PgpPublicKey pgpPublicKey = new PgpPublicKey(key);
|
|
if (pgpPublicKey.subSigs != null)
|
|
{
|
|
pgpPublicKey.subSigs.Add(certification);
|
|
}
|
|
else
|
|
{
|
|
pgpPublicKey.keySigs.Add(certification);
|
|
}
|
|
return pgpPublicKey;
|
|
}
|
|
|
|
public static PgpPublicKey RemoveCertification(PgpPublicKey key, PgpSignature certification)
|
|
{
|
|
PgpPublicKey pgpPublicKey = new PgpPublicKey(key);
|
|
IList list = ((pgpPublicKey.subSigs != null) ? pgpPublicKey.subSigs : pgpPublicKey.keySigs);
|
|
int num = list.IndexOf(certification);
|
|
bool flag = num >= 0;
|
|
if (flag)
|
|
{
|
|
list.RemoveAt(num);
|
|
}
|
|
else
|
|
{
|
|
foreach (string userId in key.GetUserIds())
|
|
{
|
|
foreach (object item in key.GetSignaturesForId(userId))
|
|
{
|
|
if (certification == item)
|
|
{
|
|
flag = true;
|
|
pgpPublicKey = RemoveCertification(pgpPublicKey, userId, certification);
|
|
}
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
foreach (PgpUserAttributeSubpacketVector userAttribute in key.GetUserAttributes())
|
|
{
|
|
foreach (object item2 in key.GetSignaturesForUserAttribute(userAttribute))
|
|
{
|
|
if (certification == item2)
|
|
{
|
|
flag = true;
|
|
pgpPublicKey = RemoveCertification(pgpPublicKey, userAttribute, certification);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return pgpPublicKey;
|
|
}
|
|
}
|