summary refs log tree commit diff
path: root/crypto/src/pkcs
diff options
context:
space:
mode:
authorDavid Hook <dgh@bouncycastle.org>2019-01-15 11:01:18 +1100
committerDavid Hook <dgh@bouncycastle.org>2019-01-15 11:01:18 +1100
commitf25f7bed6807096d9a67d31f547398c1f6f213e4 (patch)
treee05afc98f495985870a7b4edbf8ab45f63a75e68 /crypto/src/pkcs
parentadded alg constructor (diff)
downloadBouncyCastle.NET-ed25519-f25f7bed6807096d9a67d31f547398c1f6f213e4.tar.xz
first cut on Pkcs8
Diffstat (limited to 'crypto/src/pkcs')
-rw-r--r--crypto/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs106
-rw-r--r--crypto/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs52
-rw-r--r--crypto/src/pkcs/PkcsException.cs18
-rw-r--r--crypto/src/pkcs/PkcsIOException.cs19
4 files changed, 195 insertions, 0 deletions
diff --git a/crypto/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs b/crypto/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs
new file mode 100644
index 000000000..4c4ae83eb
--- /dev/null
+++ b/crypto/src/pkcs/Pkcs8EncryptedPrivateKeyInfo.cs
@@ -0,0 +1,106 @@
+
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Utilities.IO;
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Pkcs
+{
+    /// <summary>
+    /// A holding class for a PKCS#8 encrypted private key info object that allows for its decryption.
+    /// </summary>
+    public class Pkcs8EncryptedPrivateKeyInfo
+    {
+        private EncryptedPrivateKeyInfo encryptedPrivateKeyInfo;
+
+        private static EncryptedPrivateKeyInfo parseBytes(byte[] pkcs8Encoding)
+        {
+            try
+            {
+                return EncryptedPrivateKeyInfo.GetInstance(pkcs8Encoding);
+            }
+
+            catch (ArgumentException e)
+            {
+                throw new PkcsIOException("malformed data: " + e.Message, e);
+            }
+            catch (Exception e)
+            {
+                throw new PkcsIOException("malformed data: " + e.Message, e);
+            }
+        }
+
+        /// <summary>
+        /// Base constructor from a PKCS#8 EncryptedPrivateKeyInfo object.
+        /// </summary>
+        /// <param name="encryptedPrivateKeyInfo">A PKCS#8 EncryptedPrivateKeyInfo object.</param>
+        public Pkcs8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo encryptedPrivateKeyInfo)
+        {
+            this.encryptedPrivateKeyInfo = encryptedPrivateKeyInfo;
+        }
+
+        /// <summary>
+        /// Base constructor from a BER encoding of a PKCS#8 EncryptedPrivateKeyInfo object.
+        /// </summary>
+        /// <param name="encryptedPrivateKeyInfo">A BER encoding of a PKCS#8 EncryptedPrivateKeyInfo objects.</param>
+        public Pkcs8EncryptedPrivateKeyInfo(byte[] encryptedPrivateKeyInfo) : this(parseBytes(encryptedPrivateKeyInfo))
+        {
+
+        }
+
+        /// <summary>
+        /// Returns the underlying ASN.1 structure inside this object.
+        /// </summary>
+        /// <returns>Return the EncryptedPrivateKeyInfo structure in this object.</returns>
+        public EncryptedPrivateKeyInfo ToAsn1Structure()
+        {
+            return encryptedPrivateKeyInfo;
+        }
+
+        /// <summary>
+        /// Returns a copy of the encrypted data in this structure.
+        /// </summary>
+        /// <returns>Return a copy of the encrypted data in this object.</returns>
+        public byte[] GetEncryptedData()
+        {
+            return encryptedPrivateKeyInfo.GetEncryptedData();
+        }
+
+        /// <summary>
+        /// Return a binary ASN.1 encoding of the EncryptedPrivateKeyInfo structure in this object.
+        /// </summary>
+        /// <returns>A byte array containing the encoded object.</returns>
+        public byte[] GetEncoded()
+        {
+            return encryptedPrivateKeyInfo.GetEncoded();
+        }
+
+        /// <summary>
+        /// Get a decryptor from the passed in provider and decrypt the encrypted private key info, returning the result.
+        /// </summary>
+        /// <param name="inputDecryptorProvider">A provider to query for decryptors for the object.</param>
+        /// <returns>The decrypted private key info structure.</returns>
+        public PrivateKeyInfo DecryptPrivateKeyInfo(IDecryptorBuilderProvider inputDecryptorProvider)
+        {
+            try
+            {
+                ICipherBuilder decryptorBuilder = inputDecryptorProvider.CreateDecryptorBuilder(encryptedPrivateKeyInfo.EncryptionAlgorithm);
+
+                ICipher encIn = decryptorBuilder.BuildCipher(new MemoryInputStream(encryptedPrivateKeyInfo.GetEncryptedData()));
+
+                using (Stream strm = encIn.Stream)
+                {
+                    byte[] data = Streams.ReadAll(encIn.Stream);
+           
+                    return PrivateKeyInfo.GetInstance(data);
+                }
+            }
+            catch (Exception e)
+            {
+                throw new PkcsException("unable to read encrypted data: " + e.Message, e);
+            }
+        }
+    }
+}
diff --git a/crypto/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs b/crypto/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs
new file mode 100644
index 000000000..3b05deea7
--- /dev/null
+++ b/crypto/src/pkcs/Pkcs8EncryptedPrivateKeyInfoBuilder.cs
@@ -0,0 +1,52 @@
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Utilities.IO;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Org.BouncyCastle.Pkcs
+{
+    public class Pkcs8EncryptedPrivateKeyInfoBuilder
+    {
+        private PrivateKeyInfo privateKeyInfo;
+
+        public Pkcs8EncryptedPrivateKeyInfoBuilder(byte[] privateKeyInfo):  this(PrivateKeyInfo.GetInstance(privateKeyInfo))
+        {
+        }
+
+        public Pkcs8EncryptedPrivateKeyInfoBuilder(PrivateKeyInfo privateKeyInfo)
+        {
+            this.privateKeyInfo = privateKeyInfo;
+        }
+
+        /// <summary>
+        /// Create the encrypted private key info using the passed in encryptor.
+        /// </summary>
+        /// <param name="encryptor">The encryptor to use.</param>
+        /// <returns>An encrypted private key info containing the original private key info.</returns>
+        public Pkcs8EncryptedPrivateKeyInfo Build(
+            ICipherBuilder encryptor)
+        {
+            try
+            {
+                MemoryStream bOut = new MemoryOutputStream();
+                ICipher cOut = encryptor.BuildCipher(bOut);
+                byte[] keyData = privateKeyInfo.GetEncoded();
+
+                using (var str = cOut.Stream)
+                {
+                    str.Write(keyData, 0, keyData.Length);
+                }
+
+                return new Pkcs8EncryptedPrivateKeyInfo(new EncryptedPrivateKeyInfo((AlgorithmIdentifier)encryptor.AlgorithmDetails, bOut.ToArray()));
+            }
+            catch (IOException)
+            {
+                throw new InvalidOperationException("cannot encode privateKeyInfo");
+            }
+        }
+    }
+}
diff --git a/crypto/src/pkcs/PkcsException.cs b/crypto/src/pkcs/PkcsException.cs
new file mode 100644
index 000000000..f82d36724
--- /dev/null
+++ b/crypto/src/pkcs/PkcsException.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace Org.BouncyCastle.Pkcs
+{
+    /// <summary>
+    /// Base exception for PKCS related issues.
+    /// </summary>
+    public class PkcsException : Exception
+    {
+        public PkcsException(String message) : base(message)
+        {
+        }
+
+        public PkcsException(String message, Exception underlying) : base(message, underlying)
+        {
+        }
+    }
+}
diff --git a/crypto/src/pkcs/PkcsIOException.cs b/crypto/src/pkcs/PkcsIOException.cs
new file mode 100644
index 000000000..19f17a394
--- /dev/null
+++ b/crypto/src/pkcs/PkcsIOException.cs
@@ -0,0 +1,19 @@
+using System;
+using System.IO;
+
+namespace Org.BouncyCastle.Pkcs
+{
+    /// <summary>
+    /// Base exception for parsing related issues in the PKCS namespace.
+    /// </summary>
+    public class PkcsIOException: IOException
+    {
+        public PkcsIOException(String message) : base(message)
+        {
+        }
+
+        public PkcsIOException(String message, Exception underlying) : base(message, underlying)
+        {
+        }
+    }
+}