summary refs log tree commit diff
path: root/crypto/src/openssl/MiscPemGenerator.cs
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-12-21 12:34:49 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-12-21 12:34:49 +0700
commit3c508655db514af6702bb51be63dc0b3d176e11b (patch)
tree2ae0176a5616ecc1b0b30a85a29f2805dc4b5241 /crypto/src/openssl/MiscPemGenerator.cs
parentAesWrap: update from bc-java (diff)
downloadBouncyCastle.NET-ed25519-3c508655db514af6702bb51be63dc0b3d176e11b.tar.xz
Span-based alternatives to char[]
Diffstat (limited to 'crypto/src/openssl/MiscPemGenerator.cs')
-rw-r--r--crypto/src/openssl/MiscPemGenerator.cs69
1 files changed, 56 insertions, 13 deletions
diff --git a/crypto/src/openssl/MiscPemGenerator.cs b/crypto/src/openssl/MiscPemGenerator.cs
index ada0b84ed..0e918f793 100644
--- a/crypto/src/openssl/MiscPemGenerator.cs
+++ b/crypto/src/openssl/MiscPemGenerator.cs
@@ -128,20 +128,62 @@ namespace Org.BouncyCastle.OpenSsl
             return new PemObject(type, encoding);
         }
 
-//		private string GetHexEncoded(byte[] bytes)
-//		{
-//			bytes = Hex.Encode(bytes);
-//
-//			char[] chars = new char[bytes.Length];
-//
-//			for (int i = 0; i != bytes.Length; i++)
-//			{
-//				chars[i] = (char)bytes[i];
-//			}
-//
-//			return new string(chars);
-//		}
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        private static PemObject CreatePemObject(object obj, string algorithm, ReadOnlySpan<char> password,
+            SecureRandom random)
+        {
+            if (obj == null)
+                throw new ArgumentNullException("obj");
+            if (algorithm == null)
+                throw new ArgumentNullException("algorithm");
+            if (random == null)
+                throw new ArgumentNullException("random");
+
+            if (obj is AsymmetricCipherKeyPair keyPair)
+            {
+                return CreatePemObject(keyPair.Private, algorithm, password, random);
+            }
+
+            string type = null;
+            byte[] keyData = null;
 
+            if (obj is AsymmetricKeyParameter akp)
+            {
+                if (akp.IsPrivate)
+                {
+                    keyData = EncodePrivateKey(akp, out type);
+                }
+            }
+
+            if (type == null || keyData == null)
+            {
+                // TODO Support other types?
+                throw new PemGenerationException("Object type not supported: " + Platform.GetTypeName(obj));
+            }
+
+
+            string dekAlgName = algorithm.ToUpperInvariant();
+
+            // Note: For backward compatibility
+            if (dekAlgName == "DESEDE")
+            {
+                dekAlgName = "DES-EDE3-CBC";
+            }
+
+            int ivLength = Platform.StartsWith(dekAlgName, "AES-") ? 16 : 8;
+
+            byte[] iv = new byte[ivLength];
+            random.NextBytes(iv);
+
+            byte[] encData = PemUtilities.Crypt(true, keyData, password, dekAlgName, iv);
+
+            var headers = new List<PemHeader>(2);
+            headers.Add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
+            headers.Add(new PemHeader("DEK-Info", dekAlgName + "," + Hex.ToHexString(iv).ToUpperInvariant()));
+
+            return new PemObject(type, headers, encData);
+        }
+#else
         private static PemObject CreatePemObject(
             object			obj,
             string			algorithm,
@@ -201,6 +243,7 @@ namespace Org.BouncyCastle.OpenSsl
 
             return new PemObject(type, headers, encData);
         }
+#endif
 
         private static byte[] EncodePrivateKey(
             AsymmetricKeyParameter	akp,