summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2024-05-13 01:38:11 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2024-05-13 01:38:11 +0700
commite44ebc3ada821408d29c3bd52fd862db4067064d (patch)
treec4e9d24fbb596123d338aa0c5902a9b0724111c1
parentUpdate release notes (diff)
downloadBouncyCastle.NET-ed25519-e44ebc3ada821408d29c3bd52fd862db4067064d.tar.xz
Refactor to use Enum.TryParse
-rw-r--r--crypto/src/openssl/PEMUtilities.cs42
-rw-r--r--crypto/src/security/CipherUtilities.cs159
-rw-r--r--crypto/src/security/DigestUtilities.cs103
-rw-r--r--crypto/src/security/WrapperUtilities.cs9
-rw-r--r--crypto/src/util/Enums.cs35
5 files changed, 154 insertions, 194 deletions
diff --git a/crypto/src/openssl/PEMUtilities.cs b/crypto/src/openssl/PEMUtilities.cs
index 4ff340b12..eaee4d9d8 100644
--- a/crypto/src/openssl/PEMUtilities.cs
+++ b/crypto/src/openssl/PEMUtilities.cs
@@ -20,32 +20,28 @@ namespace Org.BouncyCastle.OpenSsl
             Enums.GetArbitraryValue<PemMode>().ToString();
 		}
 
-		private static void ParseDekAlgName(
-			string			dekAlgName,
-			out PemBaseAlg	baseAlg,
-			out PemMode		mode)
-		{
-			try
-			{
-				mode = PemMode.ECB;
-
-				if (dekAlgName == "DES-EDE" || dekAlgName == "DES-EDE3")
-				{
-					baseAlg = Enums.GetEnumValue<PemBaseAlg>(dekAlgName);
-					return;
-				}
-
-				int pos = dekAlgName.LastIndexOf('-');
-				if (pos >= 0)
+        private static void ParseDekAlgName(string dekAlgName, out PemBaseAlg baseAlg, out PemMode mode)
+        {
+            if (dekAlgName == "DES-EDE" || dekAlgName == "DES-EDE3")
+            {
+				if (Enums.TryGetEnumValue<PemBaseAlg>(dekAlgName, out baseAlg))
 				{
-					baseAlg = Enums.GetEnumValue<PemBaseAlg>(dekAlgName.Substring(0, pos));
-                    mode = Enums.GetEnumValue<PemMode>(dekAlgName.Substring(pos + 1));
+                    mode = PemMode.ECB;
                     return;
-				}
-			}
-			catch (ArgumentException)
+                }
+            }
+			else
 			{
-			}
+                int pos = dekAlgName.LastIndexOf('-');
+                if (pos >= 0)
+                {
+                    if (Enums.TryGetEnumValue<PemBaseAlg>(dekAlgName.Substring(0, pos), out baseAlg) &&
+						Enums.TryGetEnumValue<PemMode>(dekAlgName.Substring(pos + 1), out mode))
+					{
+						return;
+					}
+                }
+            }
 
 			throw new EncryptionException("Unknown DEK algorithm: " + dekAlgName);
 		}
diff --git a/crypto/src/security/CipherUtilities.cs b/crypto/src/security/CipherUtilities.cs
index 715bd81fe..6a53c7a8e 100644
--- a/crypto/src/security/CipherUtilities.cs
+++ b/crypto/src/security/CipherUtilities.cs
@@ -411,15 +411,8 @@ namespace Org.BouncyCastle.Security
 
             string algorithmName = CollectionUtilities.GetValueOrKey(AlgorithmMap, parts[0]).ToUpperInvariant();
 
-            CipherAlgorithm cipherAlgorithm;
-            try
-            {
-                cipherAlgorithm = Enums.GetEnumValue<CipherAlgorithm>(algorithmName);
-            }
-            catch (ArgumentException)
-            {
+            if (!Enums.TryGetEnumValue<CipherAlgorithm>(algorithmName, out var cipherAlgorithm))
                 return null;
-            }
 
             switch (cipherAlgorithm)
             {
@@ -569,9 +562,6 @@ namespace Org.BouncyCastle.Security
 
             if (parts.Length > 2)
             {
-                if (streamCipher != null)
-                    throw new ArgumentException("Paddings not used for stream ciphers");
-
                 string paddingName = parts[2];
 
                 CipherPadding cipherPadding;
@@ -583,16 +573,9 @@ namespace Org.BouncyCastle.Security
                 {
                     cipherPadding = CipherPadding.X923PADDING;
                 }
-                else
+                else if (!Enums.TryGetEnumValue<CipherPadding>(paddingName, out cipherPadding))
                 {
-                    try
-                    {
-                        cipherPadding = Enums.GetEnumValue<CipherPadding>(paddingName);
-                    }
-                    catch (ArgumentException)
-                    {
-                        return null;
-                    }
+                    return null;
                 }
 
                 switch (cipherPadding)
@@ -684,76 +667,76 @@ namespace Org.BouncyCastle.Security
                 int di = GetDigitIndex(mode);
                 string modeName = di >= 0 ? mode.Substring(0, di) : mode;
 
-                try
+                CipherMode cipherMode;
+                if (modeName == "")
+                {
+                    cipherMode = CipherMode.NONE;
+                }
+                else if (!Enums.TryGetEnumValue<CipherMode>(modeName, out cipherMode))
                 {
-                    CipherMode cipherMode = modeName == ""
-                        ? CipherMode.NONE
-                        : Enums.GetEnumValue<CipherMode>(modeName);
+                    return null;
+                }
 
-                    switch (cipherMode)
-                    {
-                    case CipherMode.ECB:
-                    case CipherMode.NONE:
-                        break;
-                    case CipherMode.CBC:
-                        blockCipherMode = new CbcBlockCipher(blockCipher);
-                        break;
-                    case CipherMode.CCM:
-                        aeadBlockCipher = new CcmBlockCipher(blockCipher);
-                        break;
-                    case CipherMode.CFB:
-                    {
-                        int bits = (di < 0)
-                            ?	8 * blockCipher.GetBlockSize()
-                            :	int.Parse(mode.Substring(di));
+                switch (cipherMode)
+                {
+                case CipherMode.ECB:
+                case CipherMode.NONE:
+                    break;
+                case CipherMode.CBC:
+                    blockCipherMode = new CbcBlockCipher(blockCipher);
+                    break;
+                case CipherMode.CCM:
+                    aeadBlockCipher = new CcmBlockCipher(blockCipher);
+                    break;
+                case CipherMode.CFB:
+                {
+                    int bits = (di < 0)
+                        ?	8 * blockCipher.GetBlockSize()
+                        :	int.Parse(mode.Substring(di));
     
-                        blockCipherMode = new CfbBlockCipher(blockCipher, bits);
-                        break;
-                    }
-                    case CipherMode.CTR:
-                        blockCipherMode = new SicBlockCipher(blockCipher);
-                        break;
-                    case CipherMode.CTS:
-                        cts = true;
-                        blockCipherMode = new CbcBlockCipher(blockCipher);
-                        break;
-                    case CipherMode.EAX:
-                        aeadBlockCipher = new EaxBlockCipher(blockCipher);
-                        break;
-                    case CipherMode.GCM:
-                        aeadBlockCipher = new GcmBlockCipher(blockCipher);
-                        break;
-                    case CipherMode.GOFB:
-                        blockCipherMode = new GOfbBlockCipher(blockCipher);
-                        break;
-                    case CipherMode.OCB:
-                        aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
-                        break;
-                    case CipherMode.OFB:
-                    {
-                        int bits = (di < 0)
-                            ?	8 * blockCipher.GetBlockSize()
-                            :	int.Parse(mode.Substring(di));
+                    blockCipherMode = new CfbBlockCipher(blockCipher, bits);
+                    break;
+                }
+                case CipherMode.CTR:
+                    blockCipherMode = new SicBlockCipher(blockCipher);
+                    break;
+                case CipherMode.CTS:
+                    cts = true;
+                    blockCipherMode = new CbcBlockCipher(blockCipher);
+                    break;
+                case CipherMode.EAX:
+                    aeadBlockCipher = new EaxBlockCipher(blockCipher);
+                    break;
+                case CipherMode.GCM:
+                    aeadBlockCipher = new GcmBlockCipher(blockCipher);
+                    break;
+                case CipherMode.GOFB:
+                    blockCipherMode = new GOfbBlockCipher(blockCipher);
+                    break;
+                case CipherMode.OCB:
+                    aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
+                    break;
+                case CipherMode.OFB:
+                {
+                    int bits = (di < 0)
+                        ?	8 * blockCipher.GetBlockSize()
+                        :	int.Parse(mode.Substring(di));
     
-                        blockCipherMode = new OfbBlockCipher(blockCipher, bits);
-                        break;
-                    }
-                    case CipherMode.OPENPGPCFB:
-                        blockCipherMode = new OpenPgpCfbBlockCipher(blockCipher);
-                        break;
-                    case CipherMode.SIC:
-                        if (blockCipher.GetBlockSize() < 16)
-                        {
-                            throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
-                        }
-                        blockCipherMode = new SicBlockCipher(blockCipher);
-                        break;
-                    default:
-                        return null;
-                    }
+                    blockCipherMode = new OfbBlockCipher(blockCipher, bits);
+                    break;
                 }
-                catch (ArgumentException)
+                case CipherMode.OPENPGPCFB:
+                    blockCipherMode = new OpenPgpCfbBlockCipher(blockCipher);
+                    break;
+                case CipherMode.SIC:
                 {
+                    if (blockCipher.GetBlockSize() < 16)
+                        return null;
+
+                    blockCipherMode = new SicBlockCipher(blockCipher);
+                    break;
+                }
+                default:
                     return null;
                 }
             }
@@ -776,27 +759,19 @@ namespace Org.BouncyCastle.Security
                 }
 
                 if (cts)
-                {
                     return new CtsBlockCipher(blockCipherMode);
-                }
 
                 if (padding != null)
-                {
                     return new PaddedBufferedBlockCipher(blockCipherMode, padding);
-                }
 
                 if (!padded || blockCipherMode.IsPartialBlockOkay)
-                {
                     return new BufferedBlockCipher(blockCipherMode);
-                }
 
                 return new PaddedBufferedBlockCipher(blockCipherMode);
             }
 
             if (asymBlockCipher != null)
-            {
                 return new BufferedAsymmetricBlockCipher(asymBlockCipher);
-            }
 
             return null;
         }
diff --git a/crypto/src/security/DigestUtilities.cs b/crypto/src/security/DigestUtilities.cs
index 0c5e12994..1353ac108 100644
--- a/crypto/src/security/DigestUtilities.cs
+++ b/crypto/src/security/DigestUtilities.cs
@@ -286,63 +286,58 @@ namespace Org.BouncyCastle.Security
 
         private static IDigest GetDigestForMechanism(string mechanism)
         {
-            try
-            {
-                DigestAlgorithm digestAlgorithm = Enums.GetEnumValue<DigestAlgorithm>(mechanism);
+            if (!Enums.TryGetEnumValue<DigestAlgorithm>(mechanism, out var digestAlgorithm))
+                return null;
 
-                switch (digestAlgorithm)
-                {
-                case DigestAlgorithm.BLAKE2B_160: return new Blake2bDigest(160);
-                case DigestAlgorithm.BLAKE2B_256: return new Blake2bDigest(256);
-                case DigestAlgorithm.BLAKE2B_384: return new Blake2bDigest(384);
-                case DigestAlgorithm.BLAKE2B_512: return new Blake2bDigest(512);
-                case DigestAlgorithm.BLAKE2S_128: return new Blake2sDigest(128);
-                case DigestAlgorithm.BLAKE2S_160: return new Blake2sDigest(160);
-                case DigestAlgorithm.BLAKE2S_224: return new Blake2sDigest(224);
-                case DigestAlgorithm.BLAKE2S_256: return new Blake2sDigest(256);
-                case DigestAlgorithm.BLAKE3_256: return new Blake3Digest(256);
-                case DigestAlgorithm.DSTU7564_256: return new Dstu7564Digest(256);
-                case DigestAlgorithm.DSTU7564_384: return new Dstu7564Digest(384);
-                case DigestAlgorithm.DSTU7564_512: return new Dstu7564Digest(512);
-                case DigestAlgorithm.GOST3411: return new Gost3411Digest();
-                case DigestAlgorithm.GOST3411_2012_256: return new Gost3411_2012_256Digest();
-                case DigestAlgorithm.GOST3411_2012_512: return new Gost3411_2012_512Digest();
-                case DigestAlgorithm.KECCAK_224: return new KeccakDigest(224);
-                case DigestAlgorithm.KECCAK_256: return new KeccakDigest(256);
-                case DigestAlgorithm.KECCAK_288: return new KeccakDigest(288);
-                case DigestAlgorithm.KECCAK_384: return new KeccakDigest(384);
-                case DigestAlgorithm.KECCAK_512: return new KeccakDigest(512);
-                case DigestAlgorithm.MD2: return new MD2Digest();
-                case DigestAlgorithm.MD4: return new MD4Digest();
-                case DigestAlgorithm.MD5: return new MD5Digest();
-                case DigestAlgorithm.NONE: return new NullDigest();
-                case DigestAlgorithm.RIPEMD128: return new RipeMD128Digest();
-                case DigestAlgorithm.RIPEMD160: return new RipeMD160Digest();
-                case DigestAlgorithm.RIPEMD256: return new RipeMD256Digest();
-                case DigestAlgorithm.RIPEMD320: return new RipeMD320Digest();
-                case DigestAlgorithm.SHA_1: return new Sha1Digest();
-                case DigestAlgorithm.SHA_224: return new Sha224Digest();
-                case DigestAlgorithm.SHA_256: return new Sha256Digest();
-                case DigestAlgorithm.SHA_384: return new Sha384Digest();
-                case DigestAlgorithm.SHA_512: return new Sha512Digest();
-                case DigestAlgorithm.SHA_512_224: return new Sha512tDigest(224);
-                case DigestAlgorithm.SHA_512_256: return new Sha512tDigest(256);
-                case DigestAlgorithm.SHA3_224: return new Sha3Digest(224);
-                case DigestAlgorithm.SHA3_256: return new Sha3Digest(256);
-                case DigestAlgorithm.SHA3_384: return new Sha3Digest(384);
-                case DigestAlgorithm.SHA3_512: return new Sha3Digest(512);
-                case DigestAlgorithm.SHAKE128_256: return new ShakeDigest(128);
-                case DigestAlgorithm.SHAKE256_512: return new ShakeDigest(256);
-                case DigestAlgorithm.SM3: return new SM3Digest();
-                case DigestAlgorithm.TIGER: return new TigerDigest();
-                case DigestAlgorithm.WHIRLPOOL: return new WhirlpoolDigest();
-                }
-            }
-            catch (ArgumentException)
+            switch (digestAlgorithm)
             {
+            case DigestAlgorithm.BLAKE2B_160: return new Blake2bDigest(160);
+            case DigestAlgorithm.BLAKE2B_256: return new Blake2bDigest(256);
+            case DigestAlgorithm.BLAKE2B_384: return new Blake2bDigest(384);
+            case DigestAlgorithm.BLAKE2B_512: return new Blake2bDigest(512);
+            case DigestAlgorithm.BLAKE2S_128: return new Blake2sDigest(128);
+            case DigestAlgorithm.BLAKE2S_160: return new Blake2sDigest(160);
+            case DigestAlgorithm.BLAKE2S_224: return new Blake2sDigest(224);
+            case DigestAlgorithm.BLAKE2S_256: return new Blake2sDigest(256);
+            case DigestAlgorithm.BLAKE3_256: return new Blake3Digest(256);
+            case DigestAlgorithm.DSTU7564_256: return new Dstu7564Digest(256);
+            case DigestAlgorithm.DSTU7564_384: return new Dstu7564Digest(384);
+            case DigestAlgorithm.DSTU7564_512: return new Dstu7564Digest(512);
+            case DigestAlgorithm.GOST3411: return new Gost3411Digest();
+            case DigestAlgorithm.GOST3411_2012_256: return new Gost3411_2012_256Digest();
+            case DigestAlgorithm.GOST3411_2012_512: return new Gost3411_2012_512Digest();
+            case DigestAlgorithm.KECCAK_224: return new KeccakDigest(224);
+            case DigestAlgorithm.KECCAK_256: return new KeccakDigest(256);
+            case DigestAlgorithm.KECCAK_288: return new KeccakDigest(288);
+            case DigestAlgorithm.KECCAK_384: return new KeccakDigest(384);
+            case DigestAlgorithm.KECCAK_512: return new KeccakDigest(512);
+            case DigestAlgorithm.MD2: return new MD2Digest();
+            case DigestAlgorithm.MD4: return new MD4Digest();
+            case DigestAlgorithm.MD5: return new MD5Digest();
+            case DigestAlgorithm.NONE: return new NullDigest();
+            case DigestAlgorithm.RIPEMD128: return new RipeMD128Digest();
+            case DigestAlgorithm.RIPEMD160: return new RipeMD160Digest();
+            case DigestAlgorithm.RIPEMD256: return new RipeMD256Digest();
+            case DigestAlgorithm.RIPEMD320: return new RipeMD320Digest();
+            case DigestAlgorithm.SHA_1: return new Sha1Digest();
+            case DigestAlgorithm.SHA_224: return new Sha224Digest();
+            case DigestAlgorithm.SHA_256: return new Sha256Digest();
+            case DigestAlgorithm.SHA_384: return new Sha384Digest();
+            case DigestAlgorithm.SHA_512: return new Sha512Digest();
+            case DigestAlgorithm.SHA_512_224: return new Sha512tDigest(224);
+            case DigestAlgorithm.SHA_512_256: return new Sha512tDigest(256);
+            case DigestAlgorithm.SHA3_224: return new Sha3Digest(224);
+            case DigestAlgorithm.SHA3_256: return new Sha3Digest(256);
+            case DigestAlgorithm.SHA3_384: return new Sha3Digest(384);
+            case DigestAlgorithm.SHA3_512: return new Sha3Digest(512);
+            case DigestAlgorithm.SHAKE128_256: return new ShakeDigest(128);
+            case DigestAlgorithm.SHAKE256_512: return new ShakeDigest(256);
+            case DigestAlgorithm.SM3: return new SM3Digest();
+            case DigestAlgorithm.TIGER: return new TigerDigest();
+            case DigestAlgorithm.WHIRLPOOL: return new WhirlpoolDigest();
+            default:
+                throw new NotImplementedException();
             }
-
-            return null;
         }
 
         private static string GetMechanism(string algorithm)
diff --git a/crypto/src/security/WrapperUtilities.cs b/crypto/src/security/WrapperUtilities.cs
index 782259d9c..a9bf9ce64 100644
--- a/crypto/src/security/WrapperUtilities.cs
+++ b/crypto/src/security/WrapperUtilities.cs
@@ -88,10 +88,8 @@ namespace Org.BouncyCastle.Security
         {
             string mechanism = CollectionUtilities.GetValueOrKey(Algorithms, algorithm).ToUpperInvariant();
 
-            try
+            if (Enums.TryGetEnumValue<WrapAlgorithm>(mechanism, out var wrapAlgorithm))
             {
-                WrapAlgorithm wrapAlgorithm = Enums.GetEnumValue<WrapAlgorithm>(mechanism);
-
                 switch (wrapAlgorithm)
                 {
                 case WrapAlgorithm.AESRFC3211WRAP:
@@ -120,11 +118,10 @@ namespace Org.BouncyCastle.Security
                     return new RC2WrapEngine();
                 case WrapAlgorithm.SEEDWRAP:
                     return new SeedWrapEngine();
+                default:
+                    throw new NotImplementedException();
                 }
             }
-            catch (ArgumentException)
-            {
-            }
 
             // Create an IBufferedCipher and use it as IWrapper (via BufferedCipherWrapper)
             IBufferedCipher blockCipher = CipherUtilities.GetCipher(algorithm);
diff --git a/crypto/src/util/Enums.cs b/crypto/src/util/Enums.cs
index 1034b5b7e..01adf7f0a 100644
--- a/crypto/src/util/Enums.cs
+++ b/crypto/src/util/Enums.cs
@@ -6,25 +6,6 @@ namespace Org.BouncyCastle.Utilities
 {
     internal static class Enums
     {
-        internal static TEnum GetEnumValue<TEnum>(string s)
-            where TEnum : struct, Enum
-        {
-            // We only want to parse single named constants
-            if (s.Length > 0 && char.IsLetter(s[0]) && s.IndexOf(',') < 0)
-            {
-                s = s.Replace('-', '_');
-                s = s.Replace('/', '_');
-
-#if NETCOREAPP2_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-                return Enum.Parse<TEnum>(s, false);
-#else
-                return (TEnum)Enum.Parse(typeof(TEnum), s, false);
-#endif
-            }
-
-            throw new ArgumentException();
-        }
-
         internal static TEnum[] GetEnumValues<TEnum>()
             where TEnum : struct, Enum
         {
@@ -42,5 +23,21 @@ namespace Org.BouncyCastle.Utilities
             int pos = (int)(DateTimeUtilities.CurrentUnixMs() & int.MaxValue) % values.Length;
             return values[pos];
         }
+
+        internal static bool TryGetEnumValue<TEnum>(string s, out TEnum result)
+            where TEnum : struct, Enum
+        {
+            // We only want to parse single named constants
+            if (s.Length > 0 && char.IsLetter(s[0]) && s.IndexOf(',') < 0)
+            {
+                s = s.Replace('-', '_');
+                s = s.Replace('/', '_');
+
+                return Enum.TryParse<TEnum>(s, out result);
+            }
+
+            result = default(TEnum);
+            return false;
+        }
     }
 }