/// <summary>Return the next object in the stream, or null if the end is reached.</summary>
		/// <exception cref="IOException">On a parse error</exception>
        public PgpObject NextPgpObject()
        {
            PacketTag tag = bcpgIn.NextPacketTag();

            if ((int) tag == -1) return null;

            switch (tag)
            {
                case PacketTag.Signature:
                {
                    IList l = Platform.CreateArrayList();

                    while (bcpgIn.NextPacketTag() == PacketTag.Signature)
                    {
                        try
                        {
                            l.Add(new PgpSignature(bcpgIn));
                        }
                        catch (PgpException e)
                        {
                            throw new IOException("can't create signature object: " + e);
                        }
                    }

                    PgpSignature[] sigs = new PgpSignature[l.Count];
                    for (int i = 0; i < l.Count; ++i)
                    {
                        sigs[i] = (PgpSignature)l[i];
                    }
					return new PgpSignatureList(sigs);
                }
                case PacketTag.SecretKey:
                    try
                    {
                        return new PgpSecretKeyRing(bcpgIn);
                    }
                    catch (PgpException e)
                    {
                        throw new IOException("can't create secret key object: " + e);
                    }
                case PacketTag.PublicKey:
                    return new PgpPublicKeyRing(bcpgIn);
				// TODO Make PgpPublicKey a PgpObject or return a PgpPublicKeyRing
//				case PacketTag.PublicSubkey:
//					return PgpPublicKeyRing.ReadSubkey(bcpgIn);
                case PacketTag.CompressedData:
                    return new PgpCompressedData(bcpgIn);
                case PacketTag.LiteralData:
                    return new PgpLiteralData(bcpgIn);
                case PacketTag.PublicKeyEncryptedSession:
                case PacketTag.SymmetricKeyEncryptedSessionKey:
                    return new PgpEncryptedDataList(bcpgIn);
                case PacketTag.OnePassSignature:
                {
                    IList l = Platform.CreateArrayList();

                    while (bcpgIn.NextPacketTag() == PacketTag.OnePassSignature)
                    {
                        try
                        {
                            l.Add(new PgpOnePassSignature(bcpgIn));
                        }
                        catch (PgpException e)
                        {
							throw new IOException("can't create one pass signature object: " + e);
						}
                    }

                    PgpOnePassSignature[] sigs = new PgpOnePassSignature[l.Count];
                    for (int i = 0; i < l.Count; ++i)
                    {
                        sigs[i] = (PgpOnePassSignature)l[i];
                    }
					return new PgpOnePassSignatureList(sigs);
                }
                case PacketTag.Marker:
                    return new PgpMarker(bcpgIn);
                case PacketTag.Experimental1:
                case PacketTag.Experimental2:
                case PacketTag.Experimental3:
                case PacketTag.Experimental4:
					return new PgpExperimental(bcpgIn);
            }

            throw new IOException("unknown object in stream " + bcpgIn.NextPacketTag());
        }
		/// <summary>Verify the calculated signature against the passed in PgpSignature.</summary>
        public bool Verify(
            PgpSignature pgpSig)
        {
            byte[] trailer = pgpSig.GetSignatureTrailer();

			sig.BlockUpdate(trailer, 0, trailer.Length);

			return sig.VerifySignature(pgpSig.GetSignature());
        }
		public void SetEmbeddedSignature(
			bool			isCritical,
			PgpSignature	pgpSignature)
		{
			byte[] sig = pgpSignature.GetEncoded();
			byte[] data;

			// TODO Should be >= ?
			if (sig.Length - 1 > 256)
			{
				data = new byte[sig.Length - 3];
			}
			else
			{
				data = new byte[sig.Length - 2];
			}

			Array.Copy(sig, sig.Length - data.Length, data, 0, data.Length);

			list.Add(new EmbeddedSignature(isCritical, data));
		}
		/// <summary>Add a revocation or some other key certification to a key.</summary>
		/// <param name="key">The key the revocation is to be added to.</param>
		/// <param name="certification">The key signature to be added.</param>
		/// <returns>The new changed public key object.</returns>
        public static PgpPublicKey AddCertification(
            PgpPublicKey	key,
            PgpSignature	certification)
        {
            if (key.IsMasterKey)
            {
                if (certification.SignatureType == PgpSignature.SubkeyRevocation)
                {
                    throw new ArgumentException("signature type incorrect for master key revocation.");
                }
            }
            else
            {
                if (certification.SignatureType == PgpSignature.KeyRevocation)
                {
                    throw new ArgumentException("signature type incorrect for sub-key revocation.");
                }
            }

			PgpPublicKey returnKey = new PgpPublicKey(key);

			if (returnKey.subSigs != null)
            {
                returnKey.subSigs.Add(certification);
            }
            else
            {
                returnKey.keySigs.Add(certification);
            }

			return returnKey;
        }
		/// <summary>Remove a certification from the key.</summary>
		/// <param name="key">The key the certifications are to be removed from.</param>
		/// <param name="certification">The certfication to be removed.</param>
		/// <returns>The modified key, null if the certification was not found.</returns>
		public static PgpPublicKey RemoveCertification(
			PgpPublicKey	key,
			PgpSignature	certification)
		{
			PgpPublicKey returnKey = new PgpPublicKey(key);
			IList sigs = returnKey.subSigs != null
				?	returnKey.subSigs
				:	returnKey.keySigs;

//			bool found = sigs.Remove(certification);
			int pos = sigs.IndexOf(certification);
			bool found = pos >= 0;

			if (found)
			{
				sigs.RemoveAt(pos);
			}
			else
			{
				foreach (String id in key.GetUserIds())
				{
					foreach (object sig in key.GetSignaturesForId(id))
					{
						// TODO Is this the right type of equality test?
						if (certification == sig)
						{
							found = true;
							returnKey = PgpPublicKey.RemoveCertification(returnKey, id, certification);
						}
					}
				}

				if (!found)
				{
					foreach (PgpUserAttributeSubpacketVector id in key.GetUserAttributes())
					{
						foreach (object sig in key.GetSignaturesForUserAttribute(id))
						{
							// TODO Is this the right type of equality test?
							if (certification == sig)
							{
								found = true;
								returnKey = PgpPublicKey.RemoveCertification(returnKey, id, certification);
							}
						}
					}
				}
			}

			return returnKey;
		}
		/// <summary>Remove a certification associated with a given user attributes on a key.</summary>
		/// <param name="key">The key the certifications are to be removed from.</param>
		/// <param name="userAttributes">The user attributes that the certfication is to be removed from.</param>
		/// <param name="certification">The certification to be removed.</param>
		/// <returns>The re-certified key, or null if the certification was not found.</returns>
		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 returnKey = new PgpPublicKey(key);
            bool found = false;

			for (int i = 0; i < returnKey.ids.Count; i++)
            {
                if (id.Equals(returnKey.ids[i]))
                {
                    IList certs = (IList) returnKey.idSigs[i];
                    found = certs.Contains(certification);

					if (found)
					{
						certs.Remove(certification);
					}
                }
            }

			return found ? returnKey : null;
        }
		/// <summary>Remove a certification associated with a given ID on a key.</summary>
		/// <param name="key">The key the certifications are to be removed from.</param>
		/// <param name="id">The ID that the certfication is to be removed from.</param>
		/// <param name="certification">The certfication to be removed.</param>
		/// <returns>The re-certified key, or null if the certification was not found.</returns>
        public static PgpPublicKey RemoveCertification(
            PgpPublicKey	key,
            string			id,
            PgpSignature	certification)
        {
			return RemoveCert(key, id, certification);
		}
		private static PgpPublicKey AddCert(
			PgpPublicKey	key,
			object			id,
			PgpSignature	certification)
		{
			PgpPublicKey returnKey = new PgpPublicKey(key);
			IList sigList = null;

			for (int i = 0; i != returnKey.ids.Count; i++)
			{
				if (id.Equals(returnKey.ids[i]))
				{
					sigList = (IList) returnKey.idSigs[i];
				}
			}

			if (sigList != null)
			{
				sigList.Add(certification);
			}
			else
			{
				sigList = Platform.CreateArrayList();
				sigList.Add(certification);
				returnKey.ids.Add(id);
				returnKey.idTrusts.Add(null);
				returnKey.idSigs.Add(sigList);
			}

			return returnKey;
		}
Beispiel #10
0
 public PgpSignatureList(
     PgpSignature sig)
 {
     this.sigs = new PgpSignature[] { sig };
 }
		public PgpSignatureList(
            PgpSignature sig)
        {
			this.sigs = new PgpSignature[]{ sig };
        }
		public PgpSignatureList(
            PgpSignature[] sigs)
        {
            this.sigs = (PgpSignature[]) sigs.Clone();
        }