Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Bcpg/SignaturePacket.cs
2025-10-09 09:57:24 +09:00

339 lines
10 KiB
C#

using System;
using System.Collections;
using System.IO;
using Org.BouncyCastle.Bcpg.Sig;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Date;
namespace Org.BouncyCastle.Bcpg;
public class SignaturePacket : ContainedPacket
{
private int version;
private int signatureType;
private long creationTime;
private long keyId;
private PublicKeyAlgorithmTag keyAlgorithm;
private HashAlgorithmTag hashAlgorithm;
private MPInteger[] signature;
private byte[] fingerprint;
private SignatureSubpacket[] hashedData;
private SignatureSubpacket[] unhashedData;
private byte[] signatureEncoding;
public int Version => version;
public int SignatureType => signatureType;
public long KeyId => keyId;
public PublicKeyAlgorithmTag KeyAlgorithm => keyAlgorithm;
public HashAlgorithmTag HashAlgorithm => hashAlgorithm;
public long CreationTime => creationTime;
internal SignaturePacket(BcpgInputStream bcpgIn)
{
version = bcpgIn.ReadByte();
if (version == 3 || version == 2)
{
bcpgIn.ReadByte();
signatureType = bcpgIn.ReadByte();
creationTime = (((long)bcpgIn.ReadByte() << 24) | ((long)bcpgIn.ReadByte() << 16) | ((long)bcpgIn.ReadByte() << 8) | (uint)bcpgIn.ReadByte()) * 1000;
keyId |= (long)bcpgIn.ReadByte() << 56;
keyId |= (long)bcpgIn.ReadByte() << 48;
keyId |= (long)bcpgIn.ReadByte() << 40;
keyId |= (long)bcpgIn.ReadByte() << 32;
keyId |= (long)bcpgIn.ReadByte() << 24;
keyId |= (long)bcpgIn.ReadByte() << 16;
keyId |= (long)bcpgIn.ReadByte() << 8;
keyId |= (uint)bcpgIn.ReadByte();
keyAlgorithm = (PublicKeyAlgorithmTag)bcpgIn.ReadByte();
hashAlgorithm = (HashAlgorithmTag)bcpgIn.ReadByte();
}
else
{
if (version != 4)
{
throw new Exception("unsupported version: " + version);
}
signatureType = bcpgIn.ReadByte();
keyAlgorithm = (PublicKeyAlgorithmTag)bcpgIn.ReadByte();
hashAlgorithm = (HashAlgorithmTag)bcpgIn.ReadByte();
int num = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte();
byte[] buffer = new byte[num];
bcpgIn.ReadFully(buffer);
SignatureSubpacketsParser signatureSubpacketsParser = new SignatureSubpacketsParser(new MemoryStream(buffer, writable: false));
IList list = Platform.CreateArrayList();
SignatureSubpacket value;
while ((value = signatureSubpacketsParser.ReadPacket()) != null)
{
list.Add(value);
}
hashedData = new SignatureSubpacket[list.Count];
for (int i = 0; i != hashedData.Length; i++)
{
SignatureSubpacket signatureSubpacket = (SignatureSubpacket)list[i];
if (signatureSubpacket is IssuerKeyId)
{
keyId = ((IssuerKeyId)signatureSubpacket).KeyId;
}
else if (signatureSubpacket is SignatureCreationTime)
{
creationTime = DateTimeUtilities.DateTimeToUnixMs(((SignatureCreationTime)signatureSubpacket).GetTime());
}
hashedData[i] = signatureSubpacket;
}
int num2 = (bcpgIn.ReadByte() << 8) | bcpgIn.ReadByte();
byte[] buffer2 = new byte[num2];
bcpgIn.ReadFully(buffer2);
signatureSubpacketsParser = new SignatureSubpacketsParser(new MemoryStream(buffer2, writable: false));
list.Clear();
while ((value = signatureSubpacketsParser.ReadPacket()) != null)
{
list.Add(value);
}
unhashedData = new SignatureSubpacket[list.Count];
for (int j = 0; j != unhashedData.Length; j++)
{
SignatureSubpacket signatureSubpacket2 = (SignatureSubpacket)list[j];
if (signatureSubpacket2 is IssuerKeyId)
{
keyId = ((IssuerKeyId)signatureSubpacket2).KeyId;
}
unhashedData[j] = signatureSubpacket2;
}
}
fingerprint = new byte[2];
bcpgIn.ReadFully(fingerprint);
switch (keyAlgorithm)
{
case PublicKeyAlgorithmTag.RsaGeneral:
case PublicKeyAlgorithmTag.RsaSign:
{
MPInteger mPInteger8 = new MPInteger(bcpgIn);
signature = new MPInteger[1] { mPInteger8 };
return;
}
case PublicKeyAlgorithmTag.Dsa:
{
MPInteger mPInteger6 = new MPInteger(bcpgIn);
MPInteger mPInteger7 = new MPInteger(bcpgIn);
signature = new MPInteger[2] { mPInteger6, mPInteger7 };
return;
}
case PublicKeyAlgorithmTag.ElGamalEncrypt:
case PublicKeyAlgorithmTag.ElGamalGeneral:
{
MPInteger mPInteger3 = new MPInteger(bcpgIn);
MPInteger mPInteger4 = new MPInteger(bcpgIn);
MPInteger mPInteger5 = new MPInteger(bcpgIn);
signature = new MPInteger[3] { mPInteger3, mPInteger4, mPInteger5 };
return;
}
case PublicKeyAlgorithmTag.ECDsa:
{
MPInteger mPInteger = new MPInteger(bcpgIn);
MPInteger mPInteger2 = new MPInteger(bcpgIn);
signature = new MPInteger[2] { mPInteger, mPInteger2 };
return;
}
}
if (keyAlgorithm >= PublicKeyAlgorithmTag.Experimental_1 && keyAlgorithm <= PublicKeyAlgorithmTag.Experimental_11)
{
signature = null;
MemoryStream memoryStream = new MemoryStream();
int num3;
while ((num3 = bcpgIn.ReadByte()) >= 0)
{
memoryStream.WriteByte((byte)num3);
}
signatureEncoding = memoryStream.ToArray();
return;
}
throw new IOException("unknown signature key algorithm: " + keyAlgorithm);
}
public SignaturePacket(int signatureType, long keyId, PublicKeyAlgorithmTag keyAlgorithm, HashAlgorithmTag hashAlgorithm, SignatureSubpacket[] hashedData, SignatureSubpacket[] unhashedData, byte[] fingerprint, MPInteger[] signature)
: this(4, signatureType, keyId, keyAlgorithm, hashAlgorithm, hashedData, unhashedData, fingerprint, signature)
{
}
public SignaturePacket(int version, int signatureType, long keyId, PublicKeyAlgorithmTag keyAlgorithm, HashAlgorithmTag hashAlgorithm, long creationTime, byte[] fingerprint, MPInteger[] signature)
: this(version, signatureType, keyId, keyAlgorithm, hashAlgorithm, null, null, fingerprint, signature)
{
this.creationTime = creationTime;
}
public SignaturePacket(int version, int signatureType, long keyId, PublicKeyAlgorithmTag keyAlgorithm, HashAlgorithmTag hashAlgorithm, SignatureSubpacket[] hashedData, SignatureSubpacket[] unhashedData, byte[] fingerprint, MPInteger[] signature)
{
this.version = version;
this.signatureType = signatureType;
this.keyId = keyId;
this.keyAlgorithm = keyAlgorithm;
this.hashAlgorithm = hashAlgorithm;
this.hashedData = hashedData;
this.unhashedData = unhashedData;
this.fingerprint = fingerprint;
this.signature = signature;
if (hashedData != null)
{
setCreationTime();
}
}
public byte[] GetSignatureTrailer()
{
byte[] array = null;
if (version == 3)
{
array = new byte[5];
long num = creationTime / 1000;
array[0] = (byte)signatureType;
array[1] = (byte)(num >> 24);
array[2] = (byte)(num >> 16);
array[3] = (byte)(num >> 8);
array[4] = (byte)num;
}
else
{
MemoryStream memoryStream = new MemoryStream();
memoryStream.WriteByte((byte)Version);
memoryStream.WriteByte((byte)SignatureType);
memoryStream.WriteByte((byte)KeyAlgorithm);
memoryStream.WriteByte((byte)HashAlgorithm);
MemoryStream memoryStream2 = new MemoryStream();
SignatureSubpacket[] hashedSubPackets = GetHashedSubPackets();
for (int i = 0; i != hashedSubPackets.Length; i++)
{
hashedSubPackets[i].Encode(memoryStream2);
}
byte[] array2 = memoryStream2.ToArray();
memoryStream.WriteByte((byte)(array2.Length >> 8));
memoryStream.WriteByte((byte)array2.Length);
memoryStream.Write(array2, 0, array2.Length);
byte[] array3 = memoryStream.ToArray();
memoryStream.WriteByte((byte)Version);
memoryStream.WriteByte(byte.MaxValue);
memoryStream.WriteByte((byte)(array3.Length >> 24));
memoryStream.WriteByte((byte)(array3.Length >> 16));
memoryStream.WriteByte((byte)(array3.Length >> 8));
memoryStream.WriteByte((byte)array3.Length);
array = memoryStream.ToArray();
}
return array;
}
public MPInteger[] GetSignature()
{
return signature;
}
public byte[] GetSignatureBytes()
{
if (signatureEncoding != null)
{
return (byte[])signatureEncoding.Clone();
}
MemoryStream memoryStream = new MemoryStream();
BcpgOutputStream bcpgOutputStream = new BcpgOutputStream(memoryStream);
MPInteger[] array = signature;
foreach (MPInteger bcpgObject in array)
{
try
{
bcpgOutputStream.WriteObject(bcpgObject);
}
catch (IOException ex)
{
throw new Exception("internal error: " + ex);
}
}
return memoryStream.ToArray();
}
public SignatureSubpacket[] GetHashedSubPackets()
{
return hashedData;
}
public SignatureSubpacket[] GetUnhashedSubPackets()
{
return unhashedData;
}
public override void Encode(BcpgOutputStream bcpgOut)
{
MemoryStream memoryStream = new MemoryStream();
BcpgOutputStream bcpgOutputStream = new BcpgOutputStream(memoryStream);
bcpgOutputStream.WriteByte((byte)version);
if (version == 3 || version == 2)
{
bcpgOutputStream.Write(5, (byte)signatureType);
bcpgOutputStream.WriteInt((int)(creationTime / 1000));
bcpgOutputStream.WriteLong(keyId);
bcpgOutputStream.Write((byte)keyAlgorithm, (byte)hashAlgorithm);
}
else
{
if (version != 4)
{
throw new IOException("unknown version: " + version);
}
bcpgOutputStream.Write((byte)signatureType, (byte)keyAlgorithm, (byte)hashAlgorithm);
EncodeLengthAndData(bcpgOutputStream, GetEncodedSubpackets(hashedData));
EncodeLengthAndData(bcpgOutputStream, GetEncodedSubpackets(unhashedData));
}
bcpgOutputStream.Write(fingerprint);
if (signature != null)
{
bcpgOutputStream.WriteObjects(signature);
}
else
{
bcpgOutputStream.Write(signatureEncoding);
}
bcpgOut.WritePacket(PacketTag.Signature, memoryStream.ToArray(), oldFormat: true);
}
private static void EncodeLengthAndData(BcpgOutputStream pOut, byte[] data)
{
pOut.WriteShort((short)data.Length);
pOut.Write(data);
}
private static byte[] GetEncodedSubpackets(SignatureSubpacket[] ps)
{
MemoryStream memoryStream = new MemoryStream();
foreach (SignatureSubpacket signatureSubpacket in ps)
{
signatureSubpacket.Encode(memoryStream);
}
return memoryStream.ToArray();
}
private void setCreationTime()
{
SignatureSubpacket[] array = hashedData;
foreach (SignatureSubpacket signatureSubpacket in array)
{
if (signatureSubpacket is SignatureCreationTime)
{
creationTime = DateTimeUtilities.DateTimeToUnixMs(((SignatureCreationTime)signatureSubpacket).GetTime());
break;
}
}
}
}