init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,738 @@
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;
}
}