using System; using System.Collections; using System.IO; using Org.BouncyCastle.Bcpg.Sig; using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Bcpg.OpenPgp { /// Container for a list of signature subpackets. public class PgpSignatureSubpacketVector { public static PgpSignatureSubpacketVector FromSubpackets(SignatureSubpacket[] packets) { if (packets == null) { packets = new SignatureSubpacket[0]; } return new PgpSignatureSubpacketVector(packets); } 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 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 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); if (p == null) { throw new PgpException("SignatureCreationTime not available"); } return ((SignatureCreationTime)p).GetTime(); } /// /// 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 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) this.GetSubpacket(SignatureSubpacketTag.PrimaryUserId); if (primaryId != null) { return primaryId.IsPrimaryUserId(); } return false; } 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 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 Features GetFeatures() { SignatureSubpacket p = this.GetSubpacket(SignatureSubpacketTag.Features); if (p == null) return null; return new Features(p.IsCritical(), p.IsLongLength(), p.GetData()); } /// Return the number of packets this vector contains. public int Count { get { return packets.Length; } } internal SignatureSubpacket[] ToSubpacketArray() { return packets; } } }