From e44ebc3ada821408d29c3bd52fd862db4067064d Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Mon, 13 May 2024 01:38:11 +0700 Subject: Refactor to use Enum.TryParse --- crypto/src/openssl/PEMUtilities.cs | 42 ++++----- crypto/src/security/CipherUtilities.cs | 159 ++++++++++++++------------------ crypto/src/security/DigestUtilities.cs | 103 ++++++++++----------- crypto/src/security/WrapperUtilities.cs | 9 +- crypto/src/util/Enums.cs | 35 ++++--- 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().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(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(dekAlgName, out baseAlg)) { - baseAlg = Enums.GetEnumValue(dekAlgName.Substring(0, pos)); - mode = Enums.GetEnumValue(dekAlgName.Substring(pos + 1)); + mode = PemMode.ECB; return; - } - } - catch (ArgumentException) + } + } + else { - } + int pos = dekAlgName.LastIndexOf('-'); + if (pos >= 0) + { + if (Enums.TryGetEnumValue(dekAlgName.Substring(0, pos), out baseAlg) && + Enums.TryGetEnumValue(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(algorithmName); - } - catch (ArgumentException) - { + if (!Enums.TryGetEnumValue(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(paddingName, out cipherPadding)) { - try - { - cipherPadding = Enums.GetEnumValue(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(modeName, out cipherMode)) { - CipherMode cipherMode = modeName == "" - ? CipherMode.NONE - : Enums.GetEnumValue(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(mechanism); + if (!Enums.TryGetEnumValue(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(mechanism, out var wrapAlgorithm)) { - WrapAlgorithm wrapAlgorithm = Enums.GetEnumValue(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(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(s, false); -#else - return (TEnum)Enum.Parse(typeof(TEnum), s, false); -#endif - } - - throw new ArgumentException(); - } - internal static TEnum[] GetEnumValues() 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(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(s, out result); + } + + result = default(TEnum); + return false; + } } } -- cgit 1.4.1