summary refs log tree commit diff
path: root/crypto/src/bcpg
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2015-04-18 21:22:01 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2015-04-18 21:22:01 +0700
commit216ccd1126d4f924bc65ac6c7dfa8faa4a8a793f (patch)
tree3bf0a0e4d7de5c8b521aff8870cb0f67c26ecf2a /crypto/src/bcpg
parentRemove overly strict check on ECC extensions (diff)
downloadBouncyCastle.NET-ed25519-216ccd1126d4f924bc65ac6c7dfa8faa4a8a793f.tar.xz
Port recent Java updates
Diffstat (limited to 'crypto/src/bcpg')
-rw-r--r--crypto/src/bcpg/ECDHPublicBCPGKey.cs102
-rw-r--r--crypto/src/bcpg/ECDsaPublicBCPGKey.cs34
-rw-r--r--crypto/src/bcpg/ECPublicBCPGKey.cs97
-rw-r--r--crypto/src/bcpg/ECSecretBCPGKey.cs56
-rw-r--r--crypto/src/bcpg/PublicKeyPacket.cs6
-rw-r--r--crypto/src/bcpg/SignaturePacket.cs5
6 files changed, 300 insertions, 0 deletions
diff --git a/crypto/src/bcpg/ECDHPublicBCPGKey.cs b/crypto/src/bcpg/ECDHPublicBCPGKey.cs
new file mode 100644
index 000000000..b85379586
--- /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 byte hashFunctionId;
+        private byte 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 = kdfParameters[1];
+            symAlgorithmId = kdfParameters[2];
+
+            VerifyHashAlgorithm();
+            VerifySymmetricKeyAlgorithm();
+        }
+
+        public ECDHPublicBcpgKey(
+            DerObjectIdentifier oid,
+            ECPoint point,
+            int hashAlgorithm,
+            int symmetricKeyAlgorithm)
+            : base(oid, point)
+        {
+            reserved = 1;
+            hashFunctionId = (byte)hashAlgorithm;
+            symAlgorithmId = (byte)symmetricKeyAlgorithm;
+
+            VerifyHashAlgorithm();
+            VerifySymmetricKeyAlgorithm();
+        }
+
+        public virtual byte Reserved
+        {
+            get { return reserved; }
+        }
+
+        public virtual byte HashAlgorithm
+        {
+            get { return hashFunctionId; }
+        }
+
+        public virtual byte SymmetricKeyAlgorithm
+        {
+            get { return symAlgorithmId; }
+        }
+
+        public override void Encode(
+            BcpgOutputStream bcpgOut)
+        {
+            base.Encode(bcpgOut);
+            bcpgOut.WriteByte(0x3);
+            bcpgOut.WriteByte(reserved);
+            bcpgOut.WriteByte(hashFunctionId);
+            bcpgOut.WriteByte(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/PublicKeyPacket.cs b/crypto/src/bcpg/PublicKeyPacket.cs
index a45aeb469..cea5c8ed2 100644
--- a/crypto/src/bcpg/PublicKeyPacket.cs
+++ b/crypto/src/bcpg/PublicKeyPacket.cs
@@ -44,6 +44,12 @@ namespace Org.BouncyCastle.Bcpg
                 case PublicKeyAlgorithmTag.ElGamalGeneral:
                     key = new ElGamalPublicBcpgKey(bcpgIn);
                     break;
+                case PublicKeyAlgorithmTag.EC:
+                    key = new ECDHPublicBcpgKey(bcpgIn);
+                    break;
+                case PublicKeyAlgorithmTag.ECDsa:
+                    key = new ECDsaPublicBcpgKey(bcpgIn);
+                    break;
                 default:
                     throw new IOException("unknown PGP public key algorithm encountered");
             }
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)
 					{