diff options
Diffstat (limited to 'crypto/src/bcpg')
32 files changed, 816 insertions, 356 deletions
diff --git a/crypto/src/bcpg/BcpgInputStream.cs b/crypto/src/bcpg/BcpgInputStream.cs index 3c69fbdf5..2e08cd090 100644 --- a/crypto/src/bcpg/BcpgInputStream.cs +++ b/crypto/src/bcpg/BcpgInputStream.cs @@ -105,19 +105,15 @@ namespace Org.BouncyCastle.Bcpg next = true; } - if (nextB >= 0) + if (nextB < 0) + return (PacketTag)nextB; + + int maskB = nextB & 0x3f; + if ((nextB & 0x40) == 0) // old { - if ((nextB & 0x40) != 0) // new - { - return (PacketTag)(nextB & 0x3f); - } - else // old - { - return (PacketTag)((nextB & 0x3f) >> 2); - } + maskB >>= 2; } - - return (PacketTag) nextB; + return (PacketTag)maskB; } public Packet ReadPacket() diff --git a/crypto/src/bcpg/DsaPublicBcpgKey.cs b/crypto/src/bcpg/DsaPublicBcpgKey.cs index 61159567c..11294cc22 100644 --- a/crypto/src/bcpg/DsaPublicBcpgKey.cs +++ b/crypto/src/bcpg/DsaPublicBcpgKey.cs @@ -4,46 +4,46 @@ using Org.BouncyCastle.Math; namespace Org.BouncyCastle.Bcpg { - /// <remarks>Base class for a DSA public key.</remarks> - public class DsaPublicBcpgKey - : BcpgObject, IBcpgKey + /// <remarks>Base class for a DSA public key.</remarks> + public class DsaPublicBcpgKey + : BcpgObject, IBcpgKey { private readonly MPInteger p, q, g, y; - /// <param name="bcpgIn">The stream to read the packet from.</param> - public DsaPublicBcpgKey( - BcpgInputStream bcpgIn) - { - this.p = new MPInteger(bcpgIn); - this.q = new MPInteger(bcpgIn); - this.g = new MPInteger(bcpgIn); - this.y = new MPInteger(bcpgIn); - } + /// <param name="bcpgIn">The stream to read the packet from.</param> + public DsaPublicBcpgKey( + BcpgInputStream bcpgIn) + { + this.p = new MPInteger(bcpgIn); + this.q = new MPInteger(bcpgIn); + this.g = new MPInteger(bcpgIn); + this.y = new MPInteger(bcpgIn); + } - public DsaPublicBcpgKey( - BigInteger p, - BigInteger q, - BigInteger g, - BigInteger y) - { - this.p = new MPInteger(p); - this.q = new MPInteger(q); - this.g = new MPInteger(g); - this.y = new MPInteger(y); - } + public DsaPublicBcpgKey( + BigInteger p, + BigInteger q, + BigInteger g, + BigInteger y) + { + this.p = new MPInteger(p); + this.q = new MPInteger(q); + this.g = new MPInteger(g); + this.y = new MPInteger(y); + } - /// <summary>The format, as a string, always "PGP".</summary> - public string Format - { - get { return "PGP"; } - } + /// <summary>The format, as a string, always "PGP".</summary> + public string Format + { + get { return "PGP"; } + } - /// <summary>Return the standard PGP encoding of the key.</summary> + /// <summary>Return the standard PGP encoding of the key.</summary> public override byte[] GetEncoded() { try { - return base.GetEncoded(); + return base.GetEncoded(); } catch (Exception) { @@ -51,30 +51,30 @@ namespace Org.BouncyCastle.Bcpg } } - public override void Encode( - BcpgOutputStream bcpgOut) - { - bcpgOut.WriteObjects(p, q, g, y); - } + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObjects(p, q, g, y); + } - public BigInteger G - { - get { return g.Value; } - } + public BigInteger G + { + get { return g.Value; } + } - public BigInteger P - { - get { return p.Value; } - } + public BigInteger P + { + get { return p.Value; } + } - public BigInteger Q - { - get { return q.Value; } - } + public BigInteger Q + { + get { return q.Value; } + } - public BigInteger Y - { - get { return y.Value; } - } + public BigInteger Y + { + get { return y.Value; } + } } } diff --git a/crypto/src/bcpg/ECDHPublicBCPGKey.cs b/crypto/src/bcpg/ECDHPublicBCPGKey.cs new file mode 100644 index 000000000..dc225e31e --- /dev/null +++ b/crypto/src/bcpg/ECDHPublicBCPGKey.cs @@ -0,0 +1,102 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Bcpg +{ + /// <remarks>Base class for an ECDH Public Key.</remarks> + public class ECDHPublicBcpgKey + : ECPublicBcpgKey + { + private byte reserved; + private HashAlgorithmTag hashFunctionId; + private SymmetricKeyAlgorithmTag symAlgorithmId; + + /// <param name="bcpgIn">The stream to read the packet from.</param> + public ECDHPublicBcpgKey( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + int length = bcpgIn.ReadByte(); + byte[] kdfParameters = new byte[length]; + if (kdfParameters.Length != 3) + throw new InvalidOperationException("kdf parameters size of 3 expected."); + + bcpgIn.ReadFully(kdfParameters); + + reserved = kdfParameters[0]; + hashFunctionId = (HashAlgorithmTag)kdfParameters[1]; + symAlgorithmId = (SymmetricKeyAlgorithmTag)kdfParameters[2]; + + VerifyHashAlgorithm(); + VerifySymmetricKeyAlgorithm(); + } + + public ECDHPublicBcpgKey( + DerObjectIdentifier oid, + ECPoint point, + HashAlgorithmTag hashAlgorithm, + SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) + : base(oid, point) + { + reserved = 1; + hashFunctionId = hashAlgorithm; + symAlgorithmId = symmetricKeyAlgorithm; + + VerifyHashAlgorithm(); + VerifySymmetricKeyAlgorithm(); + } + + public virtual byte Reserved + { + get { return reserved; } + } + + public virtual HashAlgorithmTag HashAlgorithm + { + get { return hashFunctionId; } + } + + public virtual SymmetricKeyAlgorithmTag SymmetricKeyAlgorithm + { + get { return symAlgorithmId; } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + base.Encode(bcpgOut); + bcpgOut.WriteByte(0x3); + bcpgOut.WriteByte(reserved); + bcpgOut.WriteByte((byte)hashFunctionId); + bcpgOut.WriteByte((byte)symAlgorithmId); + } + + private void VerifyHashAlgorithm() + { + switch ((HashAlgorithmTag)hashFunctionId) + { + case HashAlgorithmTag.Sha256: + case HashAlgorithmTag.Sha384: + case HashAlgorithmTag.Sha512: + break; + default: + throw new InvalidOperationException("Hash algorithm must be SHA-256 or stronger."); + } + } + + private void VerifySymmetricKeyAlgorithm() + { + switch ((SymmetricKeyAlgorithmTag)symAlgorithmId) + { + case SymmetricKeyAlgorithmTag.Aes128: + case SymmetricKeyAlgorithmTag.Aes192: + case SymmetricKeyAlgorithmTag.Aes256: + break; + default: + throw new InvalidOperationException("Symmetric key algorithm must be AES-128 or stronger."); + } + } + } +} diff --git a/crypto/src/bcpg/ECDsaPublicBCPGKey.cs b/crypto/src/bcpg/ECDsaPublicBCPGKey.cs new file mode 100644 index 000000000..5f0c8ac55 --- /dev/null +++ b/crypto/src/bcpg/ECDsaPublicBCPGKey.cs @@ -0,0 +1,34 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Bcpg +{ + /// <remarks>Base class for an ECDSA Public Key.</remarks> + public class ECDsaPublicBcpgKey + : ECPublicBcpgKey + { + /// <param name="bcpgIn">The stream to read the packet from.</param> + protected internal ECDsaPublicBcpgKey( + BcpgInputStream bcpgIn) + : base(bcpgIn) + { + } + + public ECDsaPublicBcpgKey( + DerObjectIdentifier oid, + ECPoint point) + : base(oid, point) + { + } + + public ECDsaPublicBcpgKey( + DerObjectIdentifier oid, + BigInteger encodedPoint) + : base(oid, encodedPoint) + { + } + } +} diff --git a/crypto/src/bcpg/ECPublicBCPGKey.cs b/crypto/src/bcpg/ECPublicBCPGKey.cs new file mode 100644 index 000000000..f328f9dc3 --- /dev/null +++ b/crypto/src/bcpg/ECPublicBCPGKey.cs @@ -0,0 +1,97 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC; + +namespace Org.BouncyCastle.Bcpg +{ + /// <remarks>Base class for an EC Public Key.</remarks> + public abstract class ECPublicBcpgKey + : BcpgObject, IBcpgKey + { + internal DerObjectIdentifier oid; + internal BigInteger point; + + /// <param name="bcpgIn">The stream to read the packet from.</param> + protected ECPublicBcpgKey( + BcpgInputStream bcpgIn) + { + this.oid = DerObjectIdentifier.GetInstance(Asn1Object.FromByteArray(ReadBytesOfEncodedLength(bcpgIn))); + this.point = new MPInteger(bcpgIn).Value; + } + + protected ECPublicBcpgKey( + DerObjectIdentifier oid, + ECPoint point) + { + this.point = new BigInteger(1, point.GetEncoded()); + this.oid = oid; + } + + protected ECPublicBcpgKey( + DerObjectIdentifier oid, + BigInteger encodedPoint) + { + this.point = encodedPoint; + this.oid = oid; + } + + /// <summary>The format, as a string, always "PGP".</summary> + public string Format + { + get { return "PGP"; } + } + + /// <summary>Return the standard PGP encoding of the key.</summary> + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (IOException) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + byte[] oid = this.oid.GetEncoded(); + bcpgOut.Write(oid, 1, oid.Length - 1); + + MPInteger point = new MPInteger(this.point); + bcpgOut.WriteObject(point); + } + + public virtual BigInteger EncodedPoint + { + get { return point; } + } + + public virtual DerObjectIdentifier CurveOid + { + get { return oid; } + } + + protected static byte[] ReadBytesOfEncodedLength( + BcpgInputStream bcpgIn) + { + int length = bcpgIn.ReadByte(); + if (length == 0 || length == 0xFF) + { + throw new IOException("future extensions not yet implemented."); + } + + byte[] buffer = new byte[length + 2]; + bcpgIn.ReadFully(buffer, 2, buffer.Length - 2); + buffer[0] = (byte)0x06; + buffer[1] = (byte)length; + + return buffer; + } + } +} diff --git a/crypto/src/bcpg/ECSecretBCPGKey.cs b/crypto/src/bcpg/ECSecretBCPGKey.cs new file mode 100644 index 000000000..22e0a3473 --- /dev/null +++ b/crypto/src/bcpg/ECSecretBCPGKey.cs @@ -0,0 +1,56 @@ +using System; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Bcpg +{ + /// <remarks>Base class for an EC Secret Key.</remarks> + public class ECSecretBcpgKey + : BcpgObject, IBcpgKey + { + internal MPInteger x; + + public ECSecretBcpgKey( + BcpgInputStream bcpgIn) + { + this.x = new MPInteger(bcpgIn); + } + + public ECSecretBcpgKey( + BigInteger x) + { + this.x = new MPInteger(x); + } + + /// <summary>The format, as a string, always "PGP".</summary> + public string Format + { + get { return "PGP"; } + } + + /// <summary>Return the standard PGP encoding of the key.</summary> + public override byte[] GetEncoded() + { + try + { + return base.GetEncoded(); + } + catch (Exception) + { + return null; + } + } + + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WriteObject(x); + } + + public virtual BigInteger X + { + get { return x.Value; } + } + } +} diff --git a/crypto/src/bcpg/PublicKeyAlgorithmTags.cs b/crypto/src/bcpg/PublicKeyAlgorithmTags.cs index 85ae548eb..9e30b54f7 100644 --- a/crypto/src/bcpg/PublicKeyAlgorithmTags.cs +++ b/crypto/src/bcpg/PublicKeyAlgorithmTags.cs @@ -1,6 +1,8 @@ +using System; + namespace Org.BouncyCastle.Bcpg { - /// <remarks>Public Key Algorithm tag numbers.</remarks> + /// <remarks>Public Key Algorithm tag numbers.</remarks> public enum PublicKeyAlgorithmTag { RsaGeneral = 1, // RSA (Encrypt or Sign) @@ -8,21 +10,23 @@ namespace Org.BouncyCastle.Bcpg RsaSign = 3, // RSA Sign-Only ElGamalEncrypt = 16, // Elgamal (Encrypt-Only), see [ELGAMAL] Dsa = 17, // DSA (Digital Signature Standard) + [Obsolete("Use 'ECDH' instead")] EC = 18, // Reserved for Elliptic Curve + ECDH = 18, // Reserved for Elliptic Curve (actual algorithm name) ECDsa = 19, // Reserved for ECDSA ElGamalGeneral = 20, // Elgamal (Encrypt or Sign) DiffieHellman = 21, // Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME) - Experimental_1 = 100, - Experimental_2 = 101, - Experimental_3 = 102, - Experimental_4 = 103, - Experimental_5 = 104, - Experimental_6 = 105, - Experimental_7 = 106, - Experimental_8 = 107, - Experimental_9 = 108, - Experimental_10 = 109, - Experimental_11 = 110, - } + Experimental_1 = 100, + Experimental_2 = 101, + Experimental_3 = 102, + Experimental_4 = 103, + Experimental_5 = 104, + Experimental_6 = 105, + Experimental_7 = 106, + Experimental_8 = 107, + Experimental_9 = 108, + Experimental_10 = 109, + Experimental_11 = 110, + } } diff --git a/crypto/src/bcpg/PublicKeyEncSessionPacket.cs b/crypto/src/bcpg/PublicKeyEncSessionPacket.cs index d10605f1d..74d04f7aa 100644 --- a/crypto/src/bcpg/PublicKeyEncSessionPacket.cs +++ b/crypto/src/bcpg/PublicKeyEncSessionPacket.cs @@ -2,6 +2,8 @@ using System; using System.IO; using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; +using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Bcpg { @@ -12,7 +14,7 @@ namespace Org.BouncyCastle.Bcpg private int version; private long keyId; private PublicKeyAlgorithmTag algorithm; - private BigInteger[] data; + private byte[][] data; internal PublicKeyEncSessionPacket( BcpgInputStream bcpgIn) @@ -34,33 +36,41 @@ namespace Org.BouncyCastle.Bcpg { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaGeneral: - data = new BigInteger[]{ new MPInteger(bcpgIn).Value }; + data = new byte[][]{ new MPInteger(bcpgIn).GetEncoded() }; break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: - data = new BigInteger[] - { - new MPInteger(bcpgIn).Value, - new MPInteger(bcpgIn).Value - }; + MPInteger p = new MPInteger(bcpgIn); + MPInteger g = new MPInteger(bcpgIn); + data = new byte[][]{ + p.GetEncoded(), + g.GetEncoded(), + }; break; + case PublicKeyAlgorithmTag.ECDH: + data = new byte[][]{ Streams.ReadAll(bcpgIn) }; + break; default: throw new IOException("unknown PGP public key algorithm encountered"); } } - public PublicKeyEncSessionPacket( - long keyId, - PublicKeyAlgorithmTag algorithm, - BigInteger[] data) + public PublicKeyEncSessionPacket( + long keyId, + PublicKeyAlgorithmTag algorithm, + byte[][] data) { this.version = 3; this.keyId = keyId; this.algorithm = algorithm; - this.data = (BigInteger[]) data.Clone(); + this.data = new byte[data.Length][]; + for (int i = 0; i < data.Length; ++i) + { + this.data[i] = Arrays.Clone(data[i]); + } } - public int Version + public int Version { get { return version; } } @@ -75,12 +85,12 @@ namespace Org.BouncyCastle.Bcpg get { return algorithm; } } - public BigInteger[] GetEncSessionKey() + public byte[][] GetEncSessionKey() { - return (BigInteger[]) data.Clone(); + return data; } - public override void Encode( + public override void Encode( BcpgOutputStream bcpgOut) { MemoryStream bOut = new MemoryStream(); @@ -92,12 +102,14 @@ namespace Org.BouncyCastle.Bcpg pOut.WriteByte((byte)algorithm); - for (int i = 0; i != data.Length; i++) - { - MPInteger.Encode(pOut, data[i]); - } + for (int i = 0; i < data.Length; ++i) + { + pOut.Write(data[i]); + } + + pOut.Close(); - bcpgOut.WritePacket(PacketTag.PublicKeyEncryptedSession , bOut.ToArray(), true); + bcpgOut.WritePacket(PacketTag.PublicKeyEncryptedSession , bOut.ToArray(), true); } } } diff --git a/crypto/src/bcpg/PublicKeyPacket.cs b/crypto/src/bcpg/PublicKeyPacket.cs index 32d43149b..bbed941dc 100644 --- a/crypto/src/bcpg/PublicKeyPacket.cs +++ b/crypto/src/bcpg/PublicKeyPacket.cs @@ -5,11 +5,11 @@ using Org.BouncyCastle.Utilities.Date; namespace Org.BouncyCastle.Bcpg { - /// <remarks>Basic packet for a PGP public key.</remarks> + /// <remarks>Basic packet for a PGP public key.</remarks> public class PublicKeyPacket : ContainedPacket //, PublicKeyAlgorithmTag { - private int version; + private int version; private long time; private int validDays; private PublicKeyAlgorithmTag algorithm; @@ -44,49 +44,55 @@ namespace Org.BouncyCastle.Bcpg case PublicKeyAlgorithmTag.ElGamalGeneral: key = new ElGamalPublicBcpgKey(bcpgIn); break; + case PublicKeyAlgorithmTag.ECDH: + key = new ECDHPublicBcpgKey(bcpgIn); + break; + case PublicKeyAlgorithmTag.ECDsa: + key = new ECDsaPublicBcpgKey(bcpgIn); + break; default: throw new IOException("unknown PGP public key algorithm encountered"); } } - /// <summary>Construct a version 4 public key packet.</summary> + /// <summary>Construct a version 4 public key packet.</summary> public PublicKeyPacket( PublicKeyAlgorithmTag algorithm, DateTime time, IBcpgKey key) { - this.version = 4; + this.version = 4; this.time = DateTimeUtilities.DateTimeToUnixMs(time) / 1000L; this.algorithm = algorithm; this.key = key; } - public int Version + public virtual int Version { - get { return version; } + get { return version; } } - public PublicKeyAlgorithmTag Algorithm + public virtual PublicKeyAlgorithmTag Algorithm { - get { return algorithm; } + get { return algorithm; } } - public int ValidDays + public virtual int ValidDays { - get { return validDays; } + get { return validDays; } } - public DateTime GetTime() + public virtual DateTime GetTime() { return DateTimeUtilities.UnixMsToDateTime(time * 1000L); } - public IBcpgKey Key + public virtual IBcpgKey Key { - get { return key; } + get { return key; } } - public byte[] GetEncodedContents() + public virtual byte[] GetEncodedContents() { MemoryStream bOut = new MemoryStream(); BcpgOutputStream pOut = new BcpgOutputStream(bOut); @@ -94,22 +100,22 @@ namespace Org.BouncyCastle.Bcpg pOut.WriteByte((byte) version); pOut.WriteInt((int) time); - if (version <= 3) + if (version <= 3) { pOut.WriteShort((short) validDays); } - pOut.WriteByte((byte) algorithm); + pOut.WriteByte((byte) algorithm); - pOut.WriteObject((BcpgObject)key); + pOut.WriteObject((BcpgObject)key); - return bOut.ToArray(); + return bOut.ToArray(); } - public override void Encode( - BcpgOutputStream bcpgOut) - { - bcpgOut.WritePacket(PacketTag.PublicKey, GetEncodedContents(), true); - } - } + public override void Encode( + BcpgOutputStream bcpgOut) + { + bcpgOut.WritePacket(PacketTag.PublicKey, GetEncodedContents(), true); + } + } } diff --git a/crypto/src/bcpg/S2k.cs b/crypto/src/bcpg/S2k.cs index de08c016c..33fd792fe 100644 --- a/crypto/src/bcpg/S2k.cs +++ b/crypto/src/bcpg/S2k.cs @@ -16,6 +16,8 @@ namespace Org.BouncyCastle.Bcpg public const int Salted = 1; public const int SaltedAndIterated = 3; public const int GnuDummyS2K = 101; + public const int GnuProtectionModeNoPrivateKey = 1; + public const int GnuProtectionModeDivertToCard = 2; internal int type; internal HashAlgorithmTag algorithm; @@ -82,19 +84,19 @@ namespace Org.BouncyCastle.Bcpg this.itCount = itCount; } - public int Type + public virtual int Type { get { return type; } } /// <summary>The hash algorithm.</summary> - public HashAlgorithmTag HashAlgorithm + public virtual HashAlgorithmTag HashAlgorithm { get { return algorithm; } } /// <summary>The IV for the key generation algorithm.</summary> - public byte[] GetIV() + public virtual byte[] GetIV() { return Arrays.Clone(iv); } @@ -106,13 +108,13 @@ namespace Org.BouncyCastle.Bcpg } /// <summary>The iteration count</summary> - public long IterationCount + public virtual long IterationCount { get { return (16 + (itCount & 15)) << ((itCount >> 4) + ExpBias); } } /// <summary>The protection mode - only if GnuDummyS2K</summary> - public int ProtectionMode + public virtual int ProtectionMode { get { return protectionMode; } } diff --git a/crypto/src/bcpg/SignaturePacket.cs b/crypto/src/bcpg/SignaturePacket.cs index 605ce84c4..5b91c15a3 100644 --- a/crypto/src/bcpg/SignaturePacket.cs +++ b/crypto/src/bcpg/SignaturePacket.cs @@ -146,6 +146,11 @@ namespace Org.BouncyCastle.Bcpg MPInteger y = new MPInteger(bcpgIn); signature = new MPInteger[]{ p, g, y }; break; + case PublicKeyAlgorithmTag.ECDsa: + MPInteger ecR = new MPInteger(bcpgIn); + MPInteger ecS = new MPInteger(bcpgIn); + signature = new MPInteger[]{ ecR, ecS }; + break; default: if (keyAlgorithm >= PublicKeyAlgorithmTag.Experimental_1 && keyAlgorithm <= PublicKeyAlgorithmTag.Experimental_11) { diff --git a/crypto/src/bcpg/SignatureSubpacket.cs b/crypto/src/bcpg/SignatureSubpacket.cs index ac26f8a3c..d99315599 100644 --- a/crypto/src/bcpg/SignatureSubpacket.cs +++ b/crypto/src/bcpg/SignatureSubpacket.cs @@ -7,20 +7,22 @@ namespace Org.BouncyCastle.Bcpg { private readonly SignatureSubpacketTag type; private readonly bool critical; - - internal readonly byte[] data; + private readonly bool isLongLength; + internal byte[] data; protected internal SignatureSubpacket( SignatureSubpacketTag type, bool critical, + bool isLongLength, byte[] data) { this.type = type; this.critical = critical; + this.isLongLength = isLongLength; this.data = data; } - public SignatureSubpacketTag SubpacketType + public SignatureSubpacketTag SubpacketType { get { return type; } } @@ -30,7 +32,12 @@ namespace Org.BouncyCastle.Bcpg return critical; } - /// <summary>Return the generic data making up the packet.</summary> + public bool IsLongLength() + { + return isLongLength; + } + + /// <summary>Return the generic data making up the packet.</summary> public byte[] GetData() { return (byte[]) data.Clone(); @@ -41,18 +48,7 @@ namespace Org.BouncyCastle.Bcpg { int bodyLen = data.Length + 1; - if (bodyLen < 192) - { - os.WriteByte((byte)bodyLen); - } - else if (bodyLen <= 8383) - { - bodyLen -= 192; - - os.WriteByte((byte)(((bodyLen >> 8) & 0xff) + 192)); - os.WriteByte((byte)bodyLen); - } - else + if (isLongLength) { os.WriteByte(0xff); os.WriteByte((byte)(bodyLen >> 24)); @@ -60,6 +56,28 @@ namespace Org.BouncyCastle.Bcpg os.WriteByte((byte)(bodyLen >> 8)); os.WriteByte((byte)bodyLen); } + else + { + if (bodyLen < 192) + { + os.WriteByte((byte)bodyLen); + } + else if (bodyLen <= 8383) + { + bodyLen -= 192; + + os.WriteByte((byte)(((bodyLen >> 8) & 0xff) + 192)); + os.WriteByte((byte)bodyLen); + } + else + { + os.WriteByte(0xff); + os.WriteByte((byte)(bodyLen >> 24)); + os.WriteByte((byte)(bodyLen >> 16)); + os.WriteByte((byte)(bodyLen >> 8)); + os.WriteByte((byte)bodyLen); + } + } if (critical) { diff --git a/crypto/src/bcpg/SignatureSubpacketsReader.cs b/crypto/src/bcpg/SignatureSubpacketsReader.cs index 8dd1af332..80bedb07c 100644 --- a/crypto/src/bcpg/SignatureSubpacketsReader.cs +++ b/crypto/src/bcpg/SignatureSubpacketsReader.cs @@ -1,6 +1,8 @@ using System; using System.IO; + using Org.BouncyCastle.Bcpg.Sig; +using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Bcpg @@ -25,7 +27,9 @@ namespace Org.BouncyCastle.Bcpg return null; int bodyLen = 0; - if (l < 192) + bool isLongLength = false; + + if (l < 192) { bodyLen = l; } @@ -35,54 +39,90 @@ namespace Org.BouncyCastle.Bcpg } else if (l == 255) { + isLongLength = true; bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16) | (input.ReadByte() << 8) | input.ReadByte(); } else { - // TODO Error? + throw new IOException("unexpected length header"); } - int tag = input.ReadByte(); + int tag = input.ReadByte(); if (tag < 0) throw new EndOfStreamException("unexpected EOF reading signature sub packet"); - byte[] data = new byte[bodyLen - 1]; - if (Streams.ReadFully(input, data) < data.Length) - throw new EndOfStreamException(); + byte[] data = new byte[bodyLen - 1]; + + // + // this may seem a bit strange but it turns out some applications miscode the length + // in fixed length fields, so we check the length we do get, only throwing an exception if + // we really cannot continue + // + int bytesRead = Streams.ReadFully(input, data); + + bool isCritical = ((tag & 0x80) != 0); + SignatureSubpacketTag type = (SignatureSubpacketTag)(tag & 0x7f); - bool isCritical = ((tag & 0x80) != 0); - SignatureSubpacketTag type = (SignatureSubpacketTag)(tag & 0x7f); - switch (type) + if (bytesRead != data.Length) + { + switch (type) + { + case SignatureSubpacketTag.CreationTime: + data = CheckData(data, 4, bytesRead, "Signature Creation Time"); + break; + case SignatureSubpacketTag.IssuerKeyId: + data = CheckData(data, 8, bytesRead, "Issuer"); + break; + case SignatureSubpacketTag.KeyExpireTime: + data = CheckData(data, 4, bytesRead, "Signature Key Expiration Time"); + break; + case SignatureSubpacketTag.ExpireTime: + data = CheckData(data, 4, bytesRead, "Signature Expiration Time"); + break; + default: + throw new EndOfStreamException("truncated subpacket data."); + } + } + + switch (type) { case SignatureSubpacketTag.CreationTime: - return new SignatureCreationTime(isCritical, data); + return new SignatureCreationTime(isCritical, isLongLength, data); case SignatureSubpacketTag.KeyExpireTime: - return new KeyExpirationTime(isCritical, data); + return new KeyExpirationTime(isCritical, isLongLength, data); case SignatureSubpacketTag.ExpireTime: - return new SignatureExpirationTime(isCritical, data); + return new SignatureExpirationTime(isCritical, isLongLength, data); case SignatureSubpacketTag.Revocable: - return new Revocable(isCritical, data); + return new Revocable(isCritical, isLongLength, data); case SignatureSubpacketTag.Exportable: - return new Exportable(isCritical, data); + return new Exportable(isCritical, isLongLength, data); case SignatureSubpacketTag.IssuerKeyId: - return new IssuerKeyId(isCritical, data); + return new IssuerKeyId(isCritical, isLongLength, data); case SignatureSubpacketTag.TrustSig: - return new TrustSignature(isCritical, data); + return new TrustSignature(isCritical, isLongLength, data); case SignatureSubpacketTag.PreferredCompressionAlgorithms: case SignatureSubpacketTag.PreferredHashAlgorithms: case SignatureSubpacketTag.PreferredSymmetricAlgorithms: - return new PreferredAlgorithms(type, isCritical, data); + return new PreferredAlgorithms(type, isCritical, isLongLength, data); case SignatureSubpacketTag.KeyFlags: - return new KeyFlags(isCritical, data); + return new KeyFlags(isCritical, isLongLength, data); case SignatureSubpacketTag.PrimaryUserId: - return new PrimaryUserId(isCritical, data); + return new PrimaryUserId(isCritical, isLongLength, data); case SignatureSubpacketTag.SignerUserId: - return new SignerUserId(isCritical, data); + return new SignerUserId(isCritical, isLongLength, data); case SignatureSubpacketTag.NotationData: - return new NotationData(isCritical, data); + return new NotationData(isCritical, isLongLength, data); } - return new SignatureSubpacket(type, isCritical, data); + return new SignatureSubpacket(type, isCritical, isLongLength, data); } + + private byte[] CheckData(byte[] data, int expected, int bytesRead, string name) + { + if (bytesRead != expected) + throw new EndOfStreamException("truncated " + name + " subpacket data."); + + return Arrays.CopyOfRange(data, 0, expected); + } } } diff --git a/crypto/src/bcpg/UserAttributeSubpacket.cs b/crypto/src/bcpg/UserAttributeSubpacket.cs index bd49d2150..05f60ac17 100644 --- a/crypto/src/bcpg/UserAttributeSubpacket.cs +++ b/crypto/src/bcpg/UserAttributeSubpacket.cs @@ -10,40 +10,44 @@ namespace Org.BouncyCastle.Bcpg */ public class UserAttributeSubpacket { - private readonly UserAttributeSubpacketTag type; - private readonly byte[] data; + internal readonly UserAttributeSubpacketTag type; + private readonly bool longLength; // we preserve this as not everyone encodes length properly. + protected readonly byte[] data; - internal UserAttributeSubpacket( - UserAttributeSubpacketTag type, - byte[] data) + protected internal UserAttributeSubpacket(UserAttributeSubpacketTag type, byte[] data) + : this(type, false, data) + { + } + + protected internal UserAttributeSubpacket(UserAttributeSubpacketTag type, bool forceLongLength, byte[] data) { this.type = type; + this.longLength = forceLongLength; this.data = data; } - public UserAttributeSubpacketTag SubpacketType + public virtual UserAttributeSubpacketTag SubpacketType { get { return type; } } - /** + /** * return the generic data making up the packet. */ - public byte[] GetData() + public virtual byte[] GetData() { return data; } - public void Encode( - Stream os) + public virtual void Encode(Stream os) { int bodyLen = data.Length + 1; - if (bodyLen < 192) + if (bodyLen < 192 && !longLength) { os.WriteByte((byte)bodyLen); } - else if (bodyLen <= 8383) + else if (bodyLen <= 8383 && !longLength) { bodyLen -= 192; @@ -69,18 +73,18 @@ namespace Org.BouncyCastle.Bcpg if (obj == this) return true; - UserAttributeSubpacket other = obj as UserAttributeSubpacket; + UserAttributeSubpacket other = obj as UserAttributeSubpacket; - if (other == null) - return false; + if (other == null) + return false; - return type == other.type - && Arrays.AreEqual(data, other.data); + return type == other.type + && Arrays.AreEqual(data, other.data); } - public override int GetHashCode() + public override int GetHashCode() { - return type.GetHashCode() ^ Arrays.GetHashCode(data); + return type.GetHashCode() ^ Arrays.GetHashCode(data); } } } diff --git a/crypto/src/bcpg/UserAttributeSubpacketsReader.cs b/crypto/src/bcpg/UserAttributeSubpacketsReader.cs index 2e5ea0f3e..f0cc1b8e4 100644 --- a/crypto/src/bcpg/UserAttributeSubpacketsReader.cs +++ b/crypto/src/bcpg/UserAttributeSubpacketsReader.cs @@ -5,59 +5,61 @@ using Org.BouncyCastle.Utilities.IO; namespace Org.BouncyCastle.Bcpg { - /** - * reader for user attribute sub-packets - */ - public class UserAttributeSubpacketsParser - { - private readonly Stream input; + /** + * reader for user attribute sub-packets + */ + public class UserAttributeSubpacketsParser + { + private readonly Stream input; - public UserAttributeSubpacketsParser( - Stream input) - { - this.input = input; - } + public UserAttributeSubpacketsParser( + Stream input) + { + this.input = input; + } - public UserAttributeSubpacket ReadPacket() - { - int l = input.ReadByte(); - if (l < 0) - return null; + public virtual UserAttributeSubpacket ReadPacket() + { + int l = input.ReadByte(); + if (l < 0) + return null; - int bodyLen = 0; - if (l < 192) - { - bodyLen = l; - } - else if (l <= 223) - { - bodyLen = ((l - 192) << 8) + (input.ReadByte()) + 192; - } - else if (l == 255) - { - bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16) - | (input.ReadByte() << 8) | input.ReadByte(); - } - else - { - // TODO Error? - } + int bodyLen = 0; + bool longLength = false; + if (l < 192) + { + bodyLen = l; + } + else if (l <= 223) + { + bodyLen = ((l - 192) << 8) + (input.ReadByte()) + 192; + } + else if (l == 255) + { + bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16) + | (input.ReadByte() << 8) | input.ReadByte(); + longLength = true; + } + else + { + throw new IOException("unrecognised length reading user attribute sub packet"); + } - int tag = input.ReadByte(); - if (tag < 0) - throw new EndOfStreamException("unexpected EOF reading user attribute sub packet"); + int tag = input.ReadByte(); + if (tag < 0) + throw new EndOfStreamException("unexpected EOF reading user attribute sub packet"); - byte[] data = new byte[bodyLen - 1]; - if (Streams.ReadFully(input, data) < data.Length) - throw new EndOfStreamException(); + byte[] data = new byte[bodyLen - 1]; + if (Streams.ReadFully(input, data) < data.Length) + throw new EndOfStreamException(); - UserAttributeSubpacketTag type = (UserAttributeSubpacketTag) tag; - switch (type) - { - case UserAttributeSubpacketTag.ImageAttribute: - return new ImageAttrib(data); - } - return new UserAttributeSubpacket(type, data); - } - } + UserAttributeSubpacketTag type = (UserAttributeSubpacketTag) tag; + switch (type) + { + case UserAttributeSubpacketTag.ImageAttribute: + return new ImageAttrib(longLength, data); + } + return new UserAttributeSubpacket(type, longLength, data); + } + } } diff --git a/crypto/src/bcpg/attr/ImageAttrib.cs b/crypto/src/bcpg/attr/ImageAttrib.cs index 73490791c..2d0fef8b8 100644 --- a/crypto/src/bcpg/attr/ImageAttrib.cs +++ b/crypto/src/bcpg/attr/ImageAttrib.cs @@ -3,25 +3,29 @@ using System.IO; namespace Org.BouncyCastle.Bcpg.Attr { - /// <remarks>Basic type for a image attribute packet.</remarks> + /// <remarks>Basic type for a image attribute packet.</remarks> public class ImageAttrib - : UserAttributeSubpacket + : UserAttributeSubpacket { - public enum Format : byte - { - Jpeg = 1 - } + public enum Format : byte + { + Jpeg = 1 + } - private static readonly byte[] Zeroes = new byte[12]; + private static readonly byte[] Zeroes = new byte[12]; - private int hdrLength; + private int hdrLength; private int _version; private int _encoding; private byte[] imageData; - public ImageAttrib( - byte[] data) - : base(UserAttributeSubpacketTag.ImageAttribute, data) + public ImageAttrib(byte[] data) + : this(false, data) + { + } + + public ImageAttrib(bool forceLongLength, byte[] data) + : base(UserAttributeSubpacketTag.ImageAttribute, forceLongLength, data) { hdrLength = ((data[1] & 0xff) << 8) | (data[0] & 0xff); _version = data[2] & 0xff; @@ -31,36 +35,36 @@ namespace Org.BouncyCastle.Bcpg.Attr Array.Copy(data, hdrLength, imageData, 0, imageData.Length); } - public ImageAttrib( - Format imageType, - byte[] imageData) - : this(ToByteArray(imageType, imageData)) - { - } + public ImageAttrib( + Format imageType, + byte[] imageData) + : this(ToByteArray(imageType, imageData)) + { + } - private static byte[] ToByteArray( - Format imageType, - byte[] imageData) - { - MemoryStream bOut = new MemoryStream(); - bOut.WriteByte(0x10); bOut.WriteByte(0x00); bOut.WriteByte(0x01); - bOut.WriteByte((byte) imageType); - bOut.Write(Zeroes, 0, Zeroes.Length); - bOut.Write(imageData, 0, imageData.Length); - return bOut.ToArray(); - } + private static byte[] ToByteArray( + Format imageType, + byte[] imageData) + { + MemoryStream bOut = new MemoryStream(); + bOut.WriteByte(0x10); bOut.WriteByte(0x00); bOut.WriteByte(0x01); + bOut.WriteByte((byte) imageType); + bOut.Write(Zeroes, 0, Zeroes.Length); + bOut.Write(imageData, 0, imageData.Length); + return bOut.ToArray(); + } - public int Version + public virtual int Version { - get { return _version; } + get { return _version; } } - public int Encoding + public virtual int Encoding { - get { return _encoding; } + get { return _encoding; } } - public byte[] GetImageData() + public virtual byte[] GetImageData() { return imageData; } diff --git a/crypto/src/bcpg/sig/EmbeddedSignature.cs b/crypto/src/bcpg/sig/EmbeddedSignature.cs index e47604ac8..fffdaef73 100644 --- a/crypto/src/bcpg/sig/EmbeddedSignature.cs +++ b/crypto/src/bcpg/sig/EmbeddedSignature.cs @@ -10,8 +10,9 @@ namespace Org.BouncyCastle.Bcpg.Sig { public EmbeddedSignature( bool critical, + bool isLongLength, byte[] data) - : base(SignatureSubpacketTag.EmbeddedSignature, critical, data) + : base(SignatureSubpacketTag.EmbeddedSignature, critical, isLongLength, data) { } } diff --git a/crypto/src/bcpg/sig/Exportable.cs b/crypto/src/bcpg/sig/Exportable.cs index 4455c3814..4d030346f 100644 --- a/crypto/src/bcpg/sig/Exportable.cs +++ b/crypto/src/bcpg/sig/Exportable.cs @@ -1,7 +1,5 @@ using System; - - namespace Org.BouncyCastle.Bcpg.Sig { /** @@ -27,15 +25,16 @@ namespace Org.BouncyCastle.Bcpg.Sig public Exportable( bool critical, - byte[] data) - : base(SignatureSubpacketTag.Exportable, critical, data) + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.Exportable, critical, isLongLength, data) { } public Exportable( bool critical, bool isExportable) - : base(SignatureSubpacketTag.Exportable, critical, BooleanToByteArray(isExportable)) + : base(SignatureSubpacketTag.Exportable, critical, false, BooleanToByteArray(isExportable)) { } diff --git a/crypto/src/bcpg/sig/Features.cs b/crypto/src/bcpg/sig/Features.cs new file mode 100644 index 000000000..29584239a --- /dev/null +++ b/crypto/src/bcpg/sig/Features.cs @@ -0,0 +1,75 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Bcpg.Sig +{ + /** + * packet giving signature expiration time. + */ + public class Features + : SignatureSubpacket + { + /** Identifier for the modification detection feature */ + public static readonly byte FEATURE_MODIFICATION_DETECTION = 1; + + private static byte[] FeatureToByteArray(byte feature) + { + return new byte[]{ feature }; + } + + public Features( + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.Features, critical, isLongLength, data) + { + } + + public Features(bool critical, byte feature) + : base(SignatureSubpacketTag.Features, critical, false, FeatureToByteArray(feature)) + { + } + + /** + * Returns if modification detection is supported. + */ + public bool SupportsModificationDetection + { + get { return SupportsFeature(FEATURE_MODIFICATION_DETECTION); } + } + + /** + * Returns if a particular feature is supported. + */ + public bool SupportsFeature(byte feature) + { + return Array.IndexOf(data, feature) >= 0; + } + + /** + * Sets support for a particular feature. + */ + private void SetSupportsFeature(byte feature, bool support) + { + if (feature == 0) + throw new ArgumentException("cannot be 0", "feature"); + + int i = Array.IndexOf(data, feature); + if ((i >= 0) == support) + return; + + if (support) + { + data = Arrays.Append(data, feature); + } + else + { + byte[] temp = new byte[data.Length - 1]; + Array.Copy(data, 0, temp, 0, i); + Array.Copy(data, i + 1, temp, i, temp.Length - i); + data = temp; + } + } + } +} diff --git a/crypto/src/bcpg/sig/IssuerKeyId.cs b/crypto/src/bcpg/sig/IssuerKeyId.cs index 91490d33b..627ea3ecf 100644 --- a/crypto/src/bcpg/sig/IssuerKeyId.cs +++ b/crypto/src/bcpg/sig/IssuerKeyId.cs @@ -29,15 +29,16 @@ namespace Org.BouncyCastle.Bcpg.Sig public IssuerKeyId( bool critical, - byte[] data) - : base(SignatureSubpacketTag.IssuerKeyId, critical, data) + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.IssuerKeyId, critical, isLongLength, data) { } public IssuerKeyId( bool critical, - long keyId) - : base(SignatureSubpacketTag.IssuerKeyId, critical, KeyIdToBytes(keyId)) + long keyId) + : base(SignatureSubpacketTag.IssuerKeyId, critical, false, KeyIdToBytes(keyId)) { } diff --git a/crypto/src/bcpg/sig/KeyExpirationTime.cs b/crypto/src/bcpg/sig/KeyExpirationTime.cs index 23b4cac29..dfd3e76fd 100644 --- a/crypto/src/bcpg/sig/KeyExpirationTime.cs +++ b/crypto/src/bcpg/sig/KeyExpirationTime.cs @@ -1,7 +1,5 @@ using System; - - namespace Org.BouncyCastle.Bcpg.Sig { /** @@ -25,15 +23,16 @@ namespace Org.BouncyCastle.Bcpg.Sig public KeyExpirationTime( bool critical, - byte[] data) - : base(SignatureSubpacketTag.KeyExpireTime, critical, data) + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.KeyExpireTime, critical, isLongLength, data) { } public KeyExpirationTime( bool critical, - long seconds) - : base(SignatureSubpacketTag.KeyExpireTime, critical, TimeToBytes(seconds)) + long seconds) + : base(SignatureSubpacketTag.KeyExpireTime, critical, false, TimeToBytes(seconds)) { } diff --git a/crypto/src/bcpg/sig/KeyFlags.cs b/crypto/src/bcpg/sig/KeyFlags.cs index 0592301b3..5b5d85a72 100644 --- a/crypto/src/bcpg/sig/KeyFlags.cs +++ b/crypto/src/bcpg/sig/KeyFlags.cs @@ -40,15 +40,16 @@ namespace Org.BouncyCastle.Bcpg.Sig public KeyFlags( bool critical, - byte[] data) - : base(SignatureSubpacketTag.KeyFlags, critical, data) + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.KeyFlags, critical, isLongLength, data) { } public KeyFlags( - bool critical, - int flags) - : base(SignatureSubpacketTag.KeyFlags, critical, IntToByteArray(flags)) + bool critical, + int flags) + : base(SignatureSubpacketTag.KeyFlags, critical, false, IntToByteArray(flags)) { } diff --git a/crypto/src/bcpg/sig/NotationData.cs b/crypto/src/bcpg/sig/NotationData.cs index ccc9aa745..9ac6f89cf 100644 --- a/crypto/src/bcpg/sig/NotationData.cs +++ b/crypto/src/bcpg/sig/NotationData.cs @@ -17,8 +17,9 @@ namespace Org.BouncyCastle.Bcpg.Sig public NotationData( bool critical, - byte[] data) - : base(SignatureSubpacketTag.NotationData, critical, data) + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.NotationData, critical, isLongLength, data) { } @@ -27,12 +28,12 @@ namespace Org.BouncyCastle.Bcpg.Sig bool humanReadable, string notationName, string notationValue) - : base(SignatureSubpacketTag.NotationData, critical, - createData(humanReadable, notationName, notationValue)) + : base(SignatureSubpacketTag.NotationData, critical, false, + CreateData(humanReadable, notationName, notationValue)) { } - private static byte[] createData( + private static byte[] CreateData( bool humanReadable, string notationName, string notationValue) diff --git a/crypto/src/bcpg/sig/PreferredAlgorithms.cs b/crypto/src/bcpg/sig/PreferredAlgorithms.cs index 0f282a38c..9514bed2b 100644 --- a/crypto/src/bcpg/sig/PreferredAlgorithms.cs +++ b/crypto/src/bcpg/sig/PreferredAlgorithms.cs @@ -1,7 +1,5 @@ using System; - - namespace Org.BouncyCastle.Bcpg.Sig { /** @@ -24,24 +22,25 @@ namespace Org.BouncyCastle.Bcpg.Sig } public PreferredAlgorithms( - SignatureSubpacketTag type, - bool critical, - byte[] data) - : base(type, critical, data) + SignatureSubpacketTag type, + bool critical, + bool isLongLength, + byte[] data) + : base(type, critical, isLongLength, data) { } public PreferredAlgorithms( - SignatureSubpacketTag type, - bool critical, - int[] preferences) - : base(type, critical, IntToByteArray(preferences)) + SignatureSubpacketTag type, + bool critical, + int[] preferences) + : base(type, critical, false, IntToByteArray(preferences)) { } public int[] GetPreferences() { - int[] v = new int[data.Length]; + int[] v = new int[data.Length]; for (int i = 0; i != v.Length; i++) { diff --git a/crypto/src/bcpg/sig/PrimaryUserId.cs b/crypto/src/bcpg/sig/PrimaryUserId.cs index fc0353afd..1f16f40eb 100644 --- a/crypto/src/bcpg/sig/PrimaryUserId.cs +++ b/crypto/src/bcpg/sig/PrimaryUserId.cs @@ -1,7 +1,5 @@ using System; - - namespace Org.BouncyCastle.Bcpg.Sig { /** @@ -28,15 +26,16 @@ namespace Org.BouncyCastle.Bcpg.Sig public PrimaryUserId( bool critical, - byte[] data) - : base(SignatureSubpacketTag.PrimaryUserId, critical, data) + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.PrimaryUserId, critical, isLongLength, data) { } public PrimaryUserId( bool critical, bool isPrimaryUserId) - : base(SignatureSubpacketTag.PrimaryUserId, critical, BooleanToByteArray(isPrimaryUserId)) + : base(SignatureSubpacketTag.PrimaryUserId, critical, false, BooleanToByteArray(isPrimaryUserId)) { } diff --git a/crypto/src/bcpg/sig/Revocable.cs b/crypto/src/bcpg/sig/Revocable.cs index b5e94feec..7aa91391f 100644 --- a/crypto/src/bcpg/sig/Revocable.cs +++ b/crypto/src/bcpg/sig/Revocable.cs @@ -1,7 +1,5 @@ using System; - - namespace Org.BouncyCastle.Bcpg.Sig { /** @@ -28,16 +26,17 @@ namespace Org.BouncyCastle.Bcpg.Sig public Revocable( bool critical, - byte[] data) - : base(SignatureSubpacketTag.Revocable, critical, data) - { + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.Revocable, critical, isLongLength, data) + { } public Revocable( bool critical, bool isRevocable) - : base(SignatureSubpacketTag.Revocable, critical, BooleanToByteArray(isRevocable)) - { + : base(SignatureSubpacketTag.Revocable, critical, false, BooleanToByteArray(isRevocable)) + { } public bool IsRevocable() diff --git a/crypto/src/bcpg/sig/RevocationKey.cs b/crypto/src/bcpg/sig/RevocationKey.cs index 66982cb5a..11467d2af 100644 --- a/crypto/src/bcpg/sig/RevocationKey.cs +++ b/crypto/src/bcpg/sig/RevocationKey.cs @@ -14,17 +14,18 @@ namespace Org.BouncyCastle.Bcpg // 20 octets of fingerprint public RevocationKey( bool isCritical, - byte[] data) - : base(SignatureSubpacketTag.RevocationKey, isCritical, data) + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.RevocationKey, isCritical, isLongLength, data) { } - public RevocationKey( + public RevocationKey( bool isCritical, RevocationKeyTag signatureClass, PublicKeyAlgorithmTag keyAlgorithm, byte[] fingerprint) - : base(SignatureSubpacketTag.RevocationKey, isCritical, + : base(SignatureSubpacketTag.RevocationKey, isCritical, false, CreateData(signatureClass, keyAlgorithm, fingerprint)) { } diff --git a/crypto/src/bcpg/sig/RevocationReason.cs b/crypto/src/bcpg/sig/RevocationReason.cs index 98e9b0a3d..42afd5f5b 100644 --- a/crypto/src/bcpg/sig/RevocationReason.cs +++ b/crypto/src/bcpg/sig/RevocationReason.cs @@ -11,16 +11,16 @@ namespace Org.BouncyCastle.Bcpg public class RevocationReason : SignatureSubpacket { - public RevocationReason(bool isCritical, byte[] data) - : base(SignatureSubpacketTag.RevocationReason, isCritical, data) + public RevocationReason(bool isCritical, bool isLongLength, byte[] data) + : base(SignatureSubpacketTag.RevocationReason, isCritical, isLongLength, data) { } - public RevocationReason( - bool isCritical, - RevocationReasonTag reason, - string description) - : base(SignatureSubpacketTag.RevocationReason, isCritical, CreateData(reason, description)) + public RevocationReason( + bool isCritical, + RevocationReasonTag reason, + string description) + : base(SignatureSubpacketTag.RevocationReason, isCritical, false, CreateData(reason, description)) { } diff --git a/crypto/src/bcpg/sig/SignatureCreationTime.cs b/crypto/src/bcpg/sig/SignatureCreationTime.cs index e6f241f11..d172e5d52 100644 --- a/crypto/src/bcpg/sig/SignatureCreationTime.cs +++ b/crypto/src/bcpg/sig/SignatureCreationTime.cs @@ -21,18 +21,22 @@ namespace Org.BouncyCastle.Bcpg.Sig data[3] = (byte)t; return data; } + public SignatureCreationTime( - bool critical, - byte[] data) - : base(SignatureSubpacketTag.CreationTime, critical, data) + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.CreationTime, critical, isLongLength, data) { } + public SignatureCreationTime( - bool critical, - DateTime date) - : base(SignatureSubpacketTag.CreationTime, critical, TimeToBytes(date)) + bool critical, + DateTime date) + : base(SignatureSubpacketTag.CreationTime, critical, false, TimeToBytes(date)) { } + public DateTime GetTime() { long time = (long)( diff --git a/crypto/src/bcpg/sig/SignatureExpirationTime.cs b/crypto/src/bcpg/sig/SignatureExpirationTime.cs index 7fddf5743..24f0a9f8a 100644 --- a/crypto/src/bcpg/sig/SignatureExpirationTime.cs +++ b/crypto/src/bcpg/sig/SignatureExpirationTime.cs @@ -1,7 +1,5 @@ using System; - - namespace Org.BouncyCastle.Bcpg.Sig { /** @@ -11,29 +9,28 @@ namespace Org.BouncyCastle.Bcpg.Sig : SignatureSubpacket { protected static byte[] TimeToBytes( - long t) + long t) { - byte[] data = new byte[4]; - + byte[] data = new byte[4]; data[0] = (byte)(t >> 24); data[1] = (byte)(t >> 16); data[2] = (byte)(t >> 8); data[3] = (byte)t; - return data; } public SignatureExpirationTime( bool critical, - byte[] data) - : base(SignatureSubpacketTag.ExpireTime, critical, data) - { + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.ExpireTime, critical, isLongLength, data) + { } public SignatureExpirationTime( bool critical, - long seconds) - : base(SignatureSubpacketTag.ExpireTime, critical, TimeToBytes(seconds)) + long seconds) + : base(SignatureSubpacketTag.ExpireTime, critical, false, TimeToBytes(seconds)) { } diff --git a/crypto/src/bcpg/sig/SignerUserId.cs b/crypto/src/bcpg/sig/SignerUserId.cs index 98cc808e7..8ab62ed2e 100644 --- a/crypto/src/bcpg/sig/SignerUserId.cs +++ b/crypto/src/bcpg/sig/SignerUserId.cs @@ -24,20 +24,21 @@ namespace Org.BouncyCastle.Bcpg.Sig } public SignerUserId( - bool critical, - byte[] data) - : base(SignatureSubpacketTag.SignerUserId, critical, data) + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.SignerUserId, critical, isLongLength, data) { } - public SignerUserId( - bool critical, - string userId) - : base(SignatureSubpacketTag.SignerUserId, critical, UserIdToBytes(userId)) + public SignerUserId( + bool critical, + string userId) + : base(SignatureSubpacketTag.SignerUserId, critical, false, UserIdToBytes(userId)) { } - public string GetId() + public string GetId() { char[] chars = new char[data.Length]; diff --git a/crypto/src/bcpg/sig/TrustSignature.cs b/crypto/src/bcpg/sig/TrustSignature.cs index bbadd3067..91458826d 100644 --- a/crypto/src/bcpg/sig/TrustSignature.cs +++ b/crypto/src/bcpg/sig/TrustSignature.cs @@ -16,17 +16,18 @@ namespace Org.BouncyCastle.Bcpg.Sig } public TrustSignature( - bool critical, - byte[] data) - : base(SignatureSubpacketTag.TrustSig, critical, data) + bool critical, + bool isLongLength, + byte[] data) + : base(SignatureSubpacketTag.TrustSig, critical, isLongLength, data) { } public TrustSignature( - bool critical, - int depth, - int trustAmount) - : base(SignatureSubpacketTag.TrustSig, critical, IntToByteArray(depth, trustAmount)) + bool critical, + int depth, + int trustAmount) + : base(SignatureSubpacketTag.TrustSig, critical, false, IntToByteArray(depth, trustAmount)) { } |