using System;
using System.Collections.Generic;
using System.IO;
using Org.BouncyCastle.Bcpg.Sig;
namespace Org.BouncyCastle.Bcpg.OpenPgp
{
/// Container for a list of signature subpackets.
public class PgpSignatureSubpacketVector
{
public static PgpSignatureSubpacketVector FromSubpackets(SignatureSubpacket[] packets)
{
return new PgpSignatureSubpacketVector(packets ?? new SignatureSubpacket[0]);
}
private readonly SignatureSubpacket[] packets;
internal PgpSignatureSubpacketVector(SignatureSubpacket[] packets)
{
this.packets = packets;
}
public SignatureSubpacket GetSubpacket(SignatureSubpacketTag type)
{
for (int i = 0; i != packets.Length; i++)
{
if (packets[i].SubpacketType == type)
return packets[i];
}
return null;
}
/**
* Return true if a particular subpacket type exists.
*
* @param type type to look for.
* @return true if present, false otherwise.
*/
public bool HasSubpacket(SignatureSubpacketTag type)
{
return GetSubpacket(type) != null;
}
/**
* Return all signature subpackets of the passed in type.
* @param type subpacket type code
* @return an array of zero or more matching subpackets.
*/
public SignatureSubpacket[] GetSubpackets(SignatureSubpacketTag type)
{
int count = 0;
for (int i = 0; i < packets.Length; ++i)
{
if (packets[i].SubpacketType == type)
{
++count;
}
}
SignatureSubpacket[] result = new SignatureSubpacket[count];
int pos = 0;
for (int i = 0; i < packets.Length; ++i)
{
if (packets[i].SubpacketType == type)
{
result[pos++] = packets[i];
}
}
return result;
}
///
public PgpSignatureList GetEmbeddedSignatures()
{
SignatureSubpacket[] sigs = GetSubpackets(SignatureSubpacketTag.EmbeddedSignature);
PgpSignature[] l = new PgpSignature[sigs.Length];
for (int i = 0; i < sigs.Length; i++)
{
try
{
l[i] = new PgpSignature(SignaturePacket.FromByteArray(sigs[i].GetData()));
}
catch (IOException e)
{
throw new PgpException("Unable to parse signature packet: " + e.Message, e);
}
}
return new PgpSignatureList(l);
}
public NotationData[] GetNotationDataOccurrences()
{
SignatureSubpacket[] notations = GetSubpackets(SignatureSubpacketTag.NotationData);
NotationData[] vals = new NotationData[notations.Length];
for (int i = 0; i < notations.Length; i++)
{
vals[i] = (NotationData) notations[i];
}
return vals;
}
public NotationData[] GetNotationDataOccurrences(string notationName)
{
NotationData[] notations = GetNotationDataOccurrences();
var notationsWithName = new List();
for (int i = 0; i != notations.Length; i++)
{
NotationData notation = notations[i];
if (notation.GetNotationName().Equals(notationName))
{
notationsWithName.Add(notation);
}
}
return notationsWithName.ToArray();
}
public long GetIssuerKeyId()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.IssuerKeyId);
return p == null ? 0 : ((IssuerKeyId)p).KeyId;
}
public bool HasSignatureCreationTime()
{
return GetSubpacket(SignatureSubpacketTag.CreationTime) != null;
}
public DateTime GetSignatureCreationTime()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.CreationTime)
?? throw new PgpException("SignatureCreationTime not available");
return ((SignatureCreationTime)p).GetTime();
}
public bool HasSignatureExpirationTime()
{
return GetSubpacket(SignatureSubpacketTag.ExpireTime) != null;
}
///
/// Return the number of seconds a signature is valid for after its creation date.
/// A value of zero means the signature never expires.
///
/// Seconds a signature is valid for.
public long GetSignatureExpirationTime()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.ExpireTime);
return p == null ? 0 : ((SignatureExpirationTime)p).Time;
}
///
/// Return the number of seconds a key is valid for after its creation date.
/// A value of zero means the key never expires.
///
/// Seconds a signature is valid for.
public long GetKeyExpirationTime()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.KeyExpireTime);
return p == null ? 0 : ((KeyExpirationTime)p).Time;
}
public int[] GetPreferredHashAlgorithms()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.PreferredHashAlgorithms);
return p == null ? null : ((PreferredAlgorithms)p).GetPreferences();
}
public int[] GetPreferredSymmetricAlgorithms()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.PreferredSymmetricAlgorithms);
return p == null ? null : ((PreferredAlgorithms)p).GetPreferences();
}
public int[] GetPreferredCompressionAlgorithms()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.PreferredCompressionAlgorithms);
return p == null ? null : ((PreferredAlgorithms)p).GetPreferences();
}
public int[] GetPreferredAeadAlgorithms()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.PreferredAeadAlgorithms);
return p == null ? null : ((PreferredAlgorithms)p).GetPreferences();
}
public int GetKeyFlags()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.KeyFlags);
return p == null ? 0 : ((KeyFlags)p).Flags;
}
public string GetSignerUserId()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.SignerUserId);
return p == null ? null : ((SignerUserId)p).GetId();
}
public bool IsPrimaryUserId()
{
PrimaryUserId primaryId = (PrimaryUserId)GetSubpacket(SignatureSubpacketTag.PrimaryUserId);
return primaryId != null && primaryId.IsPrimaryUserId();
}
public SignatureSubpacketTag[] GetCriticalTags()
{
int count = 0;
for (int i = 0; i != packets.Length; i++)
{
if (packets[i].IsCritical())
{
count++;
}
}
SignatureSubpacketTag[] list = new SignatureSubpacketTag[count];
count = 0;
for (int i = 0; i != packets.Length; i++)
{
if (packets[i].IsCritical())
{
list[count++] = packets[i].SubpacketType;
}
}
return list;
}
public SignatureTarget GetSignatureTarget()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.SignatureTarget);
return p == null ? null : new SignatureTarget(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public Features GetFeatures()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.Features);
return p == null ? null : new Features(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public IssuerFingerprint GetIssuerFingerprint()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.IssuerFingerprint);
return p == null ? null : new IssuerFingerprint(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public IntendedRecipientFingerprint GetIntendedRecipientFingerprint()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.IntendedRecipientFingerprint);
return p == null ? null : new IntendedRecipientFingerprint(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public IntendedRecipientFingerprint[] GetIntendedRecipientFingerprints()
{
SignatureSubpacket[] subpackets = GetSubpackets(SignatureSubpacketTag.IntendedRecipientFingerprint);
IntendedRecipientFingerprint[] recipients = new IntendedRecipientFingerprint[subpackets.Length];
for (int i = 0; i < recipients.Length; i++)
{
SignatureSubpacket p = subpackets[i];
recipients[i] = new IntendedRecipientFingerprint(p.IsCritical(), p.IsLongLength(), p.GetData());
}
return recipients;
}
public Exportable GetExportable()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.Exportable);
return p == null ? null : new Exportable(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public bool IsExportable()
{
Exportable exportable = GetExportable();
return exportable == null || exportable.IsExportable();
}
public PolicyUrl GetPolicyUrl()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.PolicyUrl);
return p == null ? null : new PolicyUrl(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public PolicyUrl[] GetPolicyUrls()
{
SignatureSubpacket[] subpackets = GetSubpackets(SignatureSubpacketTag.PolicyUrl);
PolicyUrl[] policyUrls = new PolicyUrl[subpackets.Length];
for (int i = 0; i < subpackets.Length; i++)
{
SignatureSubpacket p = subpackets[i];
policyUrls[i] = new PolicyUrl(p.IsCritical(), p.IsLongLength(), p.GetData());
}
return policyUrls;
}
public RegularExpression GetRegularExpression()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.RegExp);
return p == null ? null : new RegularExpression(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public RegularExpression[] GetRegularExpressions()
{
SignatureSubpacket[] subpackets = GetSubpackets(SignatureSubpacketTag.RegExp);
RegularExpression[] regexes = new RegularExpression[subpackets.Length];
for (int i = 0; i < regexes.Length; i++)
{
SignatureSubpacket p = subpackets[i];
regexes[i] = new RegularExpression(p.IsCritical(), p.IsLongLength(), p.GetData());
}
return regexes;
}
public Revocable GetRevocable()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.Revocable);
return p == null ? null : new Revocable(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public bool IsRevocable()
{
Revocable revocable = GetRevocable();
return revocable == null || revocable.IsRevocable();
}
public RevocationKey[] GetRevocationKeys()
{
SignatureSubpacket[] subpackets = GetSubpackets(SignatureSubpacketTag.RevocationKey);
RevocationKey[] revocationKeys = new RevocationKey[subpackets.Length];
for (int i = 0; i < revocationKeys.Length; i++)
{
SignatureSubpacket p = subpackets[i];
revocationKeys[i] = new RevocationKey(p.IsCritical(), p.IsLongLength(), p.GetData());
}
return revocationKeys;
}
public RevocationReason GetRevocationReason()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.RevocationReason);
return p == null ? null : new RevocationReason(p.IsCritical(), p.IsLongLength(), p.GetData());
}
public TrustSignature GetTrust()
{
SignatureSubpacket p = GetSubpacket(SignatureSubpacketTag.TrustSig);
return p == null ? null : new TrustSignature(p.IsCritical(), p.IsLongLength(), p.GetData());
}
/// Return the number of packets this vector contains.
public int Count => packets.Length;
internal SignatureSubpacket[] ToSubpacketArray()
{
return packets;
}
/**
* Return a copy of the subpackets in this vector.
*
* @return an array containing the vector subpackets in order.
*/
public SignatureSubpacket[] ToArray()
{
return (SignatureSubpacket[])packets.Clone();
}
}
}