<PackageReference Include="BouncyCastle.Cryptography" Version="2.3.0" />

PgpPublicKey

public class PgpPublicKey : PgpObject
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cryptlib; using Org.BouncyCastle.Asn1.EdEC; using Org.BouncyCastle.Asn1.Gnu; using Org.BouncyCastle.Asn1.X509; 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.Math.EC.Rfc8032; using Org.BouncyCastle.Security; 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 PgpPublicKey : PgpObject { private static readonly PgpKdfParameters DefaultKdfParameters = new PgpKdfParameters(HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag.Aes128); private static readonly int[] MasterKeyCertificationTypes = new int[5] { 19, 18, 17, 16, 31 }; internal PublicKeyPacket publicPk; internal TrustPacket trustPk; internal IList<PgpSignature> keySigs = new List<PgpSignature>(); internal IList<IUserDataPacket> ids = new List<IUserDataPacket>(); internal IList<TrustPacket> idTrusts = new List<TrustPacket>(); internal IList<IList<PgpSignature>> idSigs = new List<IList<PgpSignature>>(); internal IList<PgpSignature> subSigs; private long keyId; private byte[] fingerprint; private int keyStrength; public int Version => publicPk.Version; public DateTime CreationTime => publicPk.GetTime(); public long KeyId => keyId; public bool IsEncryptionKey { get { PublicKeyAlgorithmTag algorithm = publicPk.Algorithm; if ((uint)(algorithm - 1) > 1) { switch (algorithm) { case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ECDH: case PublicKeyAlgorithmTag.ElGamalGeneral: break; default: return false; } } return true; } } public bool IsMasterKey { get { if (!(publicPk is PublicSubkeyPacket)) { if (IsEncryptionKey) return publicPk.Algorithm == PublicKeyAlgorithmTag.RsaGeneral; return true; } return false; } } 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) try { byte[] encodedContents = publicPk.GetEncodedContents(); digest = PgpUtilities.CreateDigest(HashAlgorithmTag.Sha1); digest.Update(153); digest.Update((byte)(encodedContents.Length >> 8)); digest.Update((byte)encodedContents.Length); digest.BlockUpdate(encodedContents, 0, encodedContents.Length); } catch (Exception ex) { throw new PgpException("can't encode key components: " + ex.Message, ex); } else { RsaPublicBcpgKey rsaPublicBcpgKey = (RsaPublicBcpgKey)key; try { digest = PgpUtilities.CreateDigest(HashAlgorithmTag.MD5); UpdateDigest(digest, rsaPublicBcpgKey.Modulus); UpdateDigest(digest, rsaPublicBcpgKey.PublicExponent); } 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; } else { 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 { EdDsaPublicBcpgKey edDsaPublicBcpgKey = key as EdDsaPublicBcpgKey; if (edDsaPublicBcpgKey != null) { DerObjectIdentifier curveOid = edDsaPublicBcpgKey.CurveOid; if (EdECObjectIdentifiers.id_Ed25519.Equals(curveOid) || GnuObjectIdentifiers.Ed25519.Equals(curveOid) || EdECObjectIdentifiers.id_X25519.Equals(curveOid) || CryptlibObjectIdentifiers.curvey25519.Equals(curveOid)) keyStrength = 256; else if (EdECObjectIdentifiers.id_Ed448.Equals(curveOid) || EdECObjectIdentifiers.id_X448.Equals(curveOid)) { keyStrength = 448; } else { keyStrength = -1; } } else { ECPublicBcpgKey eCPublicBcpgKey = key as ECPublicBcpgKey; if (eCPublicBcpgKey != null) { X9ECParametersHolder x9ECParametersHolder = ECKeyPairGenerator.FindECCurveByOidLazy(eCPublicBcpgKey.CurveOid); if (x9ECParametersHolder != null) keyStrength = x9ECParametersHolder.Curve.FieldSize; else keyStrength = -1; } } } } } public PgpPublicKey(PublicKeyAlgorithmTag algorithm, AsymmetricKeyParameter pubKey, DateTime time) { if (pubKey.IsPrivate) throw new ArgumentException("Expected a public key", "pubKey"); RsaKeyParameters rsaKeyParameters = pubKey as RsaKeyParameters; IBcpgKey key; if (rsaKeyParameters != null) key = new RsaPublicBcpgKey(rsaKeyParameters.Modulus, rsaKeyParameters.Exponent); else { DsaPublicKeyParameters dsaPublicKeyParameters = pubKey as DsaPublicKeyParameters; if (dsaPublicKeyParameters != null) { DsaParameters parameters = dsaPublicKeyParameters.Parameters; key = new DsaPublicBcpgKey(parameters.P, parameters.Q, parameters.G, dsaPublicKeyParameters.Y); } else { ElGamalPublicKeyParameters elGamalPublicKeyParameters = pubKey as ElGamalPublicKeyParameters; if (elGamalPublicKeyParameters != null) { ElGamalParameters parameters2 = elGamalPublicKeyParameters.Parameters; key = new ElGamalPublicBcpgKey(parameters2.P, parameters2.G, elGamalPublicKeyParameters.Y); } else { ECPublicKeyParameters eCPublicKeyParameters = pubKey as ECPublicKeyParameters; if (eCPublicKeyParameters != null) { switch (algorithm) { case PublicKeyAlgorithmTag.ECDH: key = new ECDHPublicBcpgKey(eCPublicKeyParameters.PublicKeyParamSet, eCPublicKeyParameters.Q, HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag.Aes128); break; case PublicKeyAlgorithmTag.ECDsa: key = new ECDsaPublicBcpgKey(eCPublicKeyParameters.PublicKeyParamSet, eCPublicKeyParameters.Q); break; default: throw new PgpException("unknown EC algorithm"); } } else { Ed25519PublicKeyParameters ed25519PublicKeyParameters = pubKey as Ed25519PublicKeyParameters; if (ed25519PublicKeyParameters != null) { byte[] array = new byte[1 + Ed25519PublicKeyParameters.KeySize]; array[0] = 64; ed25519PublicKeyParameters.Encode(array, 1); key = new EdDsaPublicBcpgKey(GnuObjectIdentifiers.Ed25519, new BigInteger(1, array)); } else { Ed448PublicKeyParameters ed448PublicKeyParameters = pubKey as Ed448PublicKeyParameters; if (ed448PublicKeyParameters != null) { byte[] array2 = new byte[Ed448PublicKeyParameters.KeySize]; ed448PublicKeyParameters.Encode(array2, 0); key = new EdDsaPublicBcpgKey(EdECObjectIdentifiers.id_Ed448, new BigInteger(1, array2)); } else { X25519PublicKeyParameters x25519PublicKeyParameters = pubKey as X25519PublicKeyParameters; if (x25519PublicKeyParameters != null) { byte[] array3 = new byte[1 + X25519PublicKeyParameters.KeySize]; array3[0] = 64; x25519PublicKeyParameters.Encode(array3, 1); PgpKdfParameters defaultKdfParameters = DefaultKdfParameters; key = new ECDHPublicBcpgKey(CryptlibObjectIdentifiers.curvey25519, new BigInteger(1, array3), defaultKdfParameters.HashAlgorithm, defaultKdfParameters.SymmetricWrapAlgorithm); } else { X448PublicKeyParameters x448PublicKeyParameters = pubKey as X448PublicKeyParameters; if (x448PublicKeyParameters == null) throw new PgpException("unknown key class"); byte[] array4 = new byte[X448PublicKeyParameters.KeySize]; x448PublicKeyParameters.Encode(array4, 0); PgpKdfParameters defaultKdfParameters2 = DefaultKdfParameters; key = new ECDHPublicBcpgKey(EdECObjectIdentifiers.id_X448, new BigInteger(1, array4), defaultKdfParameters2.HashAlgorithm, defaultKdfParameters2.SymmetricWrapAlgorithm); } } } } } } } publicPk = new PublicKeyPacket(algorithm, time, key); ids = new List<IUserDataPacket>(); idSigs = new List<IList<PgpSignature>>(); try { Init(); } catch (IOException innerException) { throw new PgpException("exception calculating keyId", innerException); } } public PgpPublicKey(PublicKeyPacket publicPk) : this(publicPk, new List<IUserDataPacket>(), new List<IList<PgpSignature>>()) { } internal PgpPublicKey(PublicKeyPacket publicPk, TrustPacket trustPk, IList<PgpSignature> sigs) { this.publicPk = publicPk; this.trustPk = trustPk; subSigs = sigs; Init(); } internal PgpPublicKey(PgpPublicKey key, TrustPacket trust, IList<PgpSignature> 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 = new List<PgpSignature>(pubKey.keySigs); ids = new List<IUserDataPacket>(pubKey.ids); idTrusts = new List<TrustPacket>(pubKey.idTrusts); idSigs = new List<IList<PgpSignature>>(pubKey.idSigs.Count); for (int i = 0; i < pubKey.idSigs.Count; i++) { idSigs.Add(new List<PgpSignature>(pubKey.idSigs[i])); } if (pubKey.subSigs != null) subSigs = new List<PgpSignature>(pubKey.subSigs); fingerprint = pubKey.fingerprint; keyId = pubKey.keyId; keyStrength = pubKey.keyStrength; } internal PgpPublicKey(PublicKeyPacket publicPk, TrustPacket trustPk, IList<PgpSignature> keySigs, IList<IUserDataPacket> ids, IList<TrustPacket> idTrusts, IList<IList<PgpSignature>> 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<IUserDataPacket> ids, IList<IList<PgpSignature>> idSigs) { this.publicPk = publicPk; this.ids = ids; this.idSigs = idSigs; Init(); } internal PgpPublicKey(PgpPublicKey original, TrustPacket trustPk, List<PgpSignature> keySigs, List<IUserDataPacket> ids, List<TrustPacket> idTrusts, IList<IList<PgpSignature>> idSigs) { publicPk = original.publicPk; fingerprint = original.fingerprint; keyStrength = original.keyStrength; keyId = original.keyId; this.trustPk = trustPk; this.keySigs = keySigs; this.ids = ids; this.idTrusts = idTrusts; this.idSigs = idSigs; } public byte[] GetTrustData() { if (trustPk == null) return null; return Arrays.Clone(trustPk.GetLevelAndTrustAmount()); } public long GetValidSeconds() { if (publicPk.Version <= 3) return (long)publicPk.ValidDays * 86400; if (IsMasterKey) { for (int i = 0; i != MasterKeyCertificationTypes.Length; i++) { long expirationTimeFromSig = GetExpirationTimeFromSig(true, MasterKeyCertificationTypes[i]); if (expirationTimeFromSig >= 0) return expirationTimeFromSig; } } else { long expirationTimeFromSig2 = GetExpirationTimeFromSig(false, 24); if (expirationTimeFromSig2 >= 0) return expirationTimeFromSig2; expirationTimeFromSig2 = GetExpirationTimeFromSig(false, 31); if (expirationTimeFromSig2 >= 0) return expirationTimeFromSig2; } return 0; } private long GetExpirationTimeFromSig(bool selfSigned, int signatureType) { long num = -1; long num2 = -1; foreach (PgpSignature item in GetSignaturesOfType(signatureType)) { if (!selfSigned || item.KeyId == KeyId) { PgpSignatureSubpacketVector hashedSubPackets = item.GetHashedSubPackets(); if (hashedSubPackets != null && hashedSubPackets.HasSubpacket(SignatureSubpacketTag.KeyExpireTime)) { long keyExpirationTime = hashedSubPackets.GetKeyExpirationTime(); if (item.KeyId == KeyId) { DateTime creationTime = item.CreationTime; if (creationTime.Ticks > num2) { creationTime = item.CreationTime; num2 = 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 { PublicKeyAlgorithmTag algorithm = publicPk.Algorithm; if ((uint)(algorithm - 1) > 2) { switch (algorithm) { case PublicKeyAlgorithmTag.Dsa: { DsaPublicBcpgKey dsaPublicBcpgKey = (DsaPublicBcpgKey)publicPk.Key; return new DsaPublicKeyParameters(dsaPublicBcpgKey.Y, new DsaParameters(dsaPublicBcpgKey.P, dsaPublicBcpgKey.Q, dsaPublicBcpgKey.G)); } case PublicKeyAlgorithmTag.ECDsa: { ECDsaPublicBcpgKey ecK = (ECDsaPublicBcpgKey)publicPk.Key; return GetECKey("ECDSA", ecK); } case PublicKeyAlgorithmTag.ECDH: { ECDHPublicBcpgKey eCDHPublicBcpgKey = (ECDHPublicBcpgKey)publicPk.Key; DerObjectIdentifier curveOid2 = eCDHPublicBcpgKey.CurveOid; if (!EdECObjectIdentifiers.id_X25519.Equals(curveOid2) && !CryptlibObjectIdentifiers.curvey25519.Equals(curveOid2)) { if (!EdECObjectIdentifiers.id_X448.Equals(curveOid2)) return GetECKey("ECDH", eCDHPublicBcpgKey); byte[] array3 = BigIntegers.AsUnsignedByteArray(57, eCDHPublicBcpgKey.EncodedPoint); if (array3[0] != 64) throw new ArgumentException("Invalid X448 public key"); return PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(new AlgorithmIdentifier(curveOid2), Arrays.CopyOfRange(array3, 1, array3.Length))); } byte[] array4 = BigIntegers.AsUnsignedByteArray(33, eCDHPublicBcpgKey.EncodedPoint); if (array4[0] != 64) throw new ArgumentException("Invalid X25519 public key"); return PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(new AlgorithmIdentifier(curveOid2), Arrays.CopyOfRange(array4, 1, array4.Length))); } case PublicKeyAlgorithmTag.EdDsa: { EdDsaPublicBcpgKey edDsaPublicBcpgKey = (EdDsaPublicBcpgKey)publicPk.Key; DerObjectIdentifier curveOid = edDsaPublicBcpgKey.CurveOid; if (!EdECObjectIdentifiers.id_Ed25519.Equals(curveOid) && !GnuObjectIdentifiers.Ed25519.Equals(curveOid)) { if (!EdECObjectIdentifiers.id_Ed448.Equals(curveOid)) throw new InvalidOperationException(); byte[] array = BigIntegers.AsUnsignedByteArray(1 + Ed448.PublicKeySize, edDsaPublicBcpgKey.EncodedPoint); if (array[0] != 64) throw new ArgumentException("Invalid Ed448 public key"); return PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(new AlgorithmIdentifier(curveOid), Arrays.CopyOfRange(array, 1, array.Length))); } byte[] array2 = BigIntegers.AsUnsignedByteArray(1 + Ed25519.PublicKeySize, edDsaPublicBcpgKey.EncodedPoint); if (array2[0] != 64) throw new ArgumentException("Invalid Ed25519 public key"); return PublicKeyFactory.CreateKey(new SubjectPublicKeyInfo(new AlgorithmIdentifier(curveOid), Arrays.CopyOfRange(array2, 1, array2.Length))); } 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"); } } RsaPublicBcpgKey rsaPublicBcpgKey = (RsaPublicBcpgKey)publicPk.Key; return new RsaKeyParameters(false, rsaPublicBcpgKey.Modulus, rsaPublicBcpgKey.PublicExponent); } catch (PgpException) { throw; } catch (Exception innerException) { throw new PgpException("exception constructing public key", innerException); } } private ECPublicKeyParameters GetECKey(string algorithm, ECPublicBcpgKey ecK) { X9ECParameters x9ECParameters = ECKeyPairGenerator.FindECCurveByOid(ecK.CurveOid); BigInteger encodedPoint = ecK.EncodedPoint; ECPoint q = x9ECParameters.Curve.DecodePoint(BigIntegers.AsUnsignedByteArray(encodedPoint)); return new ECPublicKeyParameters(algorithm, q, ecK.CurveOid); } public IEnumerable<string> GetUserIds() { List<string> list = new List<string>(); foreach (IUserDataPacket id in ids) { UserIdPacket userIdPacket = id as UserIdPacket; if (userIdPacket != null) list.Add(userIdPacket.GetId()); } return CollectionUtilities.Proxy(list); } public IEnumerable<byte[]> GetRawUserIds() { List<byte[]> list = new List<byte[]>(); foreach (IUserDataPacket id in ids) { UserIdPacket userIdPacket = id as UserIdPacket; if (userIdPacket != null) list.Add(userIdPacket.GetRawId()); } return CollectionUtilities.Proxy(list); } public IEnumerable<PgpUserAttributeSubpacketVector> GetUserAttributes() { List<PgpUserAttributeSubpacketVector> list = new List<PgpUserAttributeSubpacketVector>(); foreach (IUserDataPacket id in ids) { PgpUserAttributeSubpacketVector pgpUserAttributeSubpacketVector = id as PgpUserAttributeSubpacketVector; if (pgpUserAttributeSubpacketVector != null) list.Add(pgpUserAttributeSubpacketVector); } return CollectionUtilities.Proxy(list); } public IEnumerable<PgpSignature> GetSignaturesForId(string id) { if (id == null) throw new ArgumentNullException("id"); return GetSignaturesForId(new UserIdPacket(id)); } public IEnumerable<PgpSignature> GetSignaturesForId(byte[] rawId) { if (rawId == null) throw new ArgumentNullException("rawId"); return GetSignaturesForId(new UserIdPacket(rawId)); } private IEnumerable<PgpSignature> GetSignaturesForId(UserIdPacket id) { List<PgpSignature> list = new List<PgpSignature>(); bool flag = false; for (int i = 0; i != ids.Count; i++) { if (id.Equals(ids[i])) { flag = true; list.AddRange(idSigs[i]); } } if (!flag) return null; return list; } public IEnumerable<PgpSignature> GetSignaturesForKeyID(long keyID) { List<PgpSignature> list = new List<PgpSignature>(); foreach (PgpSignature signature in GetSignatures()) { if (signature.KeyId == keyID) list.Add(signature); } return CollectionUtilities.Proxy(list); } public IEnumerable<PgpSignature> GetSignaturesForUserAttribute(PgpUserAttributeSubpacketVector userAttributes) { if (userAttributes == null) throw new ArgumentNullException("userAttributes"); List<PgpSignature> list = new List<PgpSignature>(); bool flag = false; for (int i = 0; i != ids.Count; i++) { if (userAttributes.Equals(ids[i])) { flag = true; list.AddRange(idSigs[i]); } } if (!flag) return null; return CollectionUtilities.Proxy(list); } public IEnumerable<PgpSignature> GetSignaturesOfType(int signatureType) { List<PgpSignature> list = new List<PgpSignature>(); foreach (PgpSignature signature in GetSignatures()) { if (signature.SignatureType == signatureType) list.Add(signature); } return CollectionUtilities.Proxy(list); } public IEnumerable<PgpSignature> GetSignatures() { IList<PgpSignature> list = subSigs; if (list == null) { List<PgpSignature> list2 = new List<PgpSignature>(keySigs); foreach (IList<PgpSignature> idSig in idSigs) { list2.AddRange(idSig); } list = list2; } return CollectionUtilities.Proxy(list); } public IEnumerable<PgpSignature> GetKeySignatures() { return CollectionUtilities.Proxy(subSigs ?? new List<PgpSignature>(keySigs)); } public byte[] GetEncoded() { MemoryStream memoryStream = new MemoryStream(); Encode(memoryStream); return memoryStream.ToArray(); } public void Encode(Stream outStr) { Encode(outStr, false); } public void Encode(Stream outStr, bool forTransfer) { BcpgOutputStream bcpgOutputStream = BcpgOutputStream.Wrap(outStr); bcpgOutputStream.WritePacket(publicPk); if (!forTransfer && trustPk != null) bcpgOutputStream.WritePacket(trustPk); if (subSigs == null) { foreach (PgpSignature keySig in keySigs) { keySig.Encode(bcpgOutputStream); } for (int i = 0; i != ids.Count; i++) { UserIdPacket userIdPacket = ids[i] as UserIdPacket; if (userIdPacket != null) bcpgOutputStream.WritePacket(userIdPacket); else { PgpUserAttributeSubpacketVector pgpUserAttributeSubpacketVector = (PgpUserAttributeSubpacketVector)ids[i]; bcpgOutputStream.WritePacket(new UserAttributePacket(pgpUserAttributeSubpacketVector.ToSubpacketArray())); } if (!forTransfer && idTrusts[i] != null) bcpgOutputStream.WritePacket(idTrusts[i]); foreach (PgpSignature item in idSigs[i]) { item.Encode(bcpgOutputStream, forTransfer); } } } else { foreach (PgpSignature subSig in subSigs) { subSig.Encode(bcpgOutputStream); } } } public bool IsRevoked() { int num = 0; bool flag = false; if (!IsMasterKey) { while (!flag && num < subSigs.Count) { if (subSigs[num++].SignatureType == 40) flag = true; } } else { while (!flag && num < keySigs.Count) { if (keySigs[num++].SignatureType == 32) flag = true; } } return flag; } public static PgpPublicKey AddCertification(PgpPublicKey key, string id, PgpSignature certification) { return AddCert(key, new UserIdPacket(id), certification); } public static PgpPublicKey AddCertification(PgpPublicKey key, PgpUserAttributeSubpacketVector userAttributes, PgpSignature certification) { return AddCert(key, userAttributes, certification); } private static PgpPublicKey AddCert(PgpPublicKey key, IUserDataPacket id, PgpSignature certification) { PgpPublicKey pgpPublicKey = new PgpPublicKey(key); IList<PgpSignature> list = null; for (int i = 0; i != pgpPublicKey.ids.Count; i++) { if (id.Equals(pgpPublicKey.ids[i])) list = pgpPublicKey.idSigs[i]; } if (list != null) list.Add(certification); else { list = new List<PgpSignature>(); 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, new UserIdPacket(id)); } public static PgpPublicKey RemoveCertification(PgpPublicKey key, byte[] rawId) { return RemoveCert(key, new UserIdPacket(rawId)); } private static PgpPublicKey RemoveCert(PgpPublicKey key, IUserDataPacket 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, byte[] id, PgpSignature certification) { return RemoveCert(key, new UserIdPacket(id), certification); } public static PgpPublicKey RemoveCertification(PgpPublicKey key, string id, PgpSignature certification) { return RemoveCert(key, new UserIdPacket(id), certification); } public static PgpPublicKey RemoveCertification(PgpPublicKey key, PgpUserAttributeSubpacketVector userAttributes, PgpSignature certification) { return RemoveCert(key, userAttributes, certification); } private static PgpPublicKey RemoveCert(PgpPublicKey key, IUserDataPacket 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])) flag |= pgpPublicKey.idSigs[i].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); (pgpPublicKey.subSigs ?? pgpPublicKey.keySigs).Add(certification); return pgpPublicKey; } public static PgpPublicKey RemoveCertification(PgpPublicKey key, PgpSignature certification) { PgpPublicKey pgpPublicKey = new PgpPublicKey(key); bool flag = (pgpPublicKey.subSigs ?? pgpPublicKey.keySigs).Remove(certification); foreach (IList<PgpSignature> idSig in pgpPublicKey.idSigs) { flag |= idSig.Remove(certification); } if (!flag) return null; return pgpPublicKey; } public static PgpPublicKey Join(PgpPublicKey key, PgpPublicKey copy, bool joinTrustPackets, bool allowSubkeySigsOnNonSubkey) { if (key.KeyId != copy.keyId) throw new ArgumentException("Key-ID mismatch."); TrustPacket trustPacket = key.trustPk; List<PgpSignature> list = new List<PgpSignature>(key.keySigs); List<IUserDataPacket> list2 = new List<IUserDataPacket>(key.ids); List<TrustPacket> list3 = new List<TrustPacket>(key.idTrusts); List<IList<PgpSignature>> list4 = new List<IList<PgpSignature>>(key.idSigs); List<PgpSignature> list5 = (key.subSigs == null) ? null : new List<PgpSignature>(key.subSigs); if (joinTrustPackets && copy.trustPk != null) trustPacket = copy.trustPk; foreach (PgpSignature keySig in copy.keySigs) { bool flag = false; for (int i = 0; i < list.Count; i++) { PgpSignature sig = list[i]; if (PgpSignature.IsSignatureEncodingEqual(sig, keySig)) { flag = true; sig = (list[i] = PgpSignature.Join(sig, keySig)); break; } } if (flag) break; list.Add(keySig); } for (int j = 0; j < copy.ids.Count; j++) { IUserDataPacket userDataPacket = copy.ids[j]; List<PgpSignature> list6 = new List<PgpSignature>(copy.idSigs[j]); TrustPacket trustPacket2 = copy.idTrusts[j]; int num = -1; for (int k = 0; k < list2.Count; k++) { if (list2[k].Equals(userDataPacket)) { num = k; break; } } if (num == -1) { list2.Add(userDataPacket); list4.Add(list6); list3.Add(joinTrustPackets ? trustPacket2 : null); } else { if (joinTrustPackets && trustPacket2 != null) { TrustPacket trustPacket3 = list3[num]; if (trustPacket3 == null || Arrays.AreEqual(trustPacket2.GetLevelAndTrustAmount(), trustPacket3.GetLevelAndTrustAmount())) list3[num] = trustPacket2; } IList<PgpSignature> list7 = list4[num]; foreach (PgpSignature item in list6) { bool flag2 = false; for (int l = 0; l < list7.Count; l++) { PgpSignature pgpSignature2 = list7[l]; if (PgpSignature.IsSignatureEncodingEqual(item, pgpSignature2)) { flag2 = true; pgpSignature2 = (list7[l] = PgpSignature.Join(pgpSignature2, item)); break; } } if (!flag2) list7.Add(item); } } } if (copy.subSigs != null) { if ((list5 == null) & allowSubkeySigsOnNonSubkey) list5 = new List<PgpSignature>(copy.subSigs); else { foreach (PgpSignature subSig in copy.subSigs) { bool flag3 = false; int num2 = 0; while (list5 != null) { if (num2 >= list5.Count) break; PgpSignature sig2 = list5[num2]; if (PgpSignature.IsSignatureEncodingEqual(sig2, subSig)) { flag3 = true; sig2 = (list5[num2] = PgpSignature.Join(sig2, subSig)); break; } num2++; } if (!flag3) list5?.Add(subSig); } } } return new PgpPublicKey(key, trustPacket, list, list2, list3, list4) { subSigs = list5 }; } } }