diff --git a/src/core/itextsharp.csproj b/src/core/itextsharp.csproj index 77febba..53665b5 100644 --- a/src/core/itextsharp.csproj +++ b/src/core/itextsharp.csproj @@ -1,7 +1,7 @@ @@ -6181,6 +6181,11 @@ SubType = "Code" BuildAction = "Compile" /> + * Can be used for normal closure too. * diff --git a/src/core/srcbc/openssl/PEMException.cs b/src/core/srcbc/openssl/PEMException.cs new file mode 100644 index 0000000..977382b --- /dev/null +++ b/src/core/srcbc/openssl/PEMException.cs @@ -0,0 +1,22 @@ +using System; +using System.IO; + +namespace Org.BouncyCastle.OpenSsl +{ + public class PemException + : IOException + { + public PemException( + string message) + : base(message) + { + } + + public PemException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/src/core/srcbc/openssl/PEMReader.cs b/src/core/srcbc/openssl/PEMReader.cs index 9f3d5dc..48cb930 100644 --- a/src/core/srcbc/openssl/PEMReader.cs +++ b/src/core/srcbc/openssl/PEMReader.cs @@ -213,7 +213,7 @@ namespace Org.BouncyCastle.OpenSsl } catch (Exception e) { - throw new IOException("problem parsing cert: " + e.ToString()); + throw new PemException("problem parsing cert: " + e.ToString()); } } @@ -234,7 +234,7 @@ namespace Org.BouncyCastle.OpenSsl } catch (Exception e) { - throw new IOException("problem parsing cert: " + e.ToString()); + throw new PemException("problem parsing cert: " + e.ToString()); } } @@ -255,7 +255,7 @@ namespace Org.BouncyCastle.OpenSsl } catch (Exception e) { - throw new IOException("problem parsing cert: " + e.ToString()); + throw new PemException("problem parsing cert: " + e.ToString()); } } @@ -293,7 +293,7 @@ namespace Org.BouncyCastle.OpenSsl } catch (Exception e) { - throw new IOException("problem parsing PKCS7 object: " + e.ToString()); + throw new PemException("problem parsing PKCS7 object: " + e.ToString()); } } @@ -377,7 +377,7 @@ namespace Org.BouncyCastle.OpenSsl } catch (Exception e) { - throw new IOException( + throw new PemException( "problem creating " + type + " private key: " + e.ToString()); } } @@ -446,7 +446,7 @@ namespace Org.BouncyCastle.OpenSsl } catch (Exception e) { - throw new IOException("problem parsing EC private key.", e); + throw new PemException("problem parsing EC private key.", e); } } } diff --git a/src/core/srcbc/security/CipherUtilities.cs b/src/core/srcbc/security/CipherUtilities.cs index 10e6849..8e45662 100644 --- a/src/core/srcbc/security/CipherUtilities.cs +++ b/src/core/srcbc/security/CipherUtilities.cs @@ -1,577 +1,579 @@ -using System; -using System.Collections; -using System.Globalization; - -using Org.BouncyCastle.Asn1; -using Org.BouncyCastle.Asn1.CryptoPro; -using Org.BouncyCastle.Asn1.Kisa; -using Org.BouncyCastle.Asn1.Nist; -using Org.BouncyCastle.Asn1.Ntt; -using Org.BouncyCastle.Asn1.Oiw; -using Org.BouncyCastle.Asn1.Pkcs; -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Agreement; -using Org.BouncyCastle.Crypto.Digests; -using Org.BouncyCastle.Crypto.Encodings; -using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Generators; -using Org.BouncyCastle.Crypto.Macs; -using Org.BouncyCastle.Crypto.Modes; -using Org.BouncyCastle.Crypto.Paddings; - -namespace Org.BouncyCastle.Security -{ - /// - /// Cipher Utility class contains methods that can not be specifically grouped into other classes. - /// - public sealed class CipherUtilities - { - private static readonly Hashtable algorithms = new Hashtable(); - private static readonly Hashtable oids = new Hashtable(); - - static CipherUtilities() - { - // TODO Flesh out the list of aliases - - algorithms[NistObjectIdentifiers.IdAes128Ecb.Id] = "AES/ECB/PKCS7PADDING"; - algorithms[NistObjectIdentifiers.IdAes192Ecb.Id] = "AES/ECB/PKCS7PADDING"; - algorithms[NistObjectIdentifiers.IdAes256Ecb.Id] = "AES/ECB/PKCS7PADDING"; - algorithms["AES/ECB/PKCS7"] = "AES/ECB/PKCS7PADDING"; - algorithms["AES//PKCS7"] = "AES/ECB/PKCS7PADDING"; - algorithms["AES//PKCS7PADDING"] = "AES/ECB/PKCS7PADDING"; - algorithms["AES/ECB/PKCS5"] = "AES/ECB/PKCS7PADDING"; - algorithms["AES/ECB/PKCS5PADDING"] = "AES/ECB/PKCS7PADDING"; - algorithms["AES//PKCS5"] = "AES/ECB/PKCS7PADDING"; - algorithms["AES//PKCS5PADDING"] = "AES/ECB/PKCS7PADDING"; - - algorithms[NistObjectIdentifiers.IdAes128Cbc.Id] = "AES/CBC/PKCS7PADDING"; - algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "AES/CBC/PKCS7PADDING"; - algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "AES/CBC/PKCS7PADDING"; - algorithms["AES/CBC/PKCS7"] = "AES/CBC/PKCS7PADDING"; - algorithms["AES/CBC/PKCS5"] = "AES/CBC/PKCS7PADDING"; - algorithms["AES/CBC/PKCS5PADDING"] = "AES/CBC/PKCS7PADDING"; - - algorithms[NistObjectIdentifiers.IdAes128Ofb.Id] = "AES/OFB/PKCS7PADDING"; - algorithms[NistObjectIdentifiers.IdAes192Ofb.Id] = "AES/OFB/PKCS7PADDING"; - algorithms[NistObjectIdentifiers.IdAes256Ofb.Id] = "AES/OFB/PKCS7PADDING"; - algorithms["AES/OFB/PKCS7"] = "AES/OFB/PKCS7PADDING"; - algorithms["AES/OFB/PKCS5"] = "AES/OFB/PKCS7PADDING"; - algorithms["AES/OFB/PKCS5PADDING"] = "AES/OFB/PKCS7PADDING"; - - algorithms[NistObjectIdentifiers.IdAes128Cfb.Id] = "AES/CFB/PKCS7PADDING"; - algorithms[NistObjectIdentifiers.IdAes192Cfb.Id] = "AES/CFB/PKCS7PADDING"; - algorithms[NistObjectIdentifiers.IdAes256Cfb.Id] = "AES/CFB/PKCS7PADDING"; - algorithms["AES/CFB/PKCS7"] = "AES/CFB/PKCS7PADDING"; - algorithms["AES/CFB/PKCS5"] = "AES/CFB/PKCS7PADDING"; - algorithms["AES/CFB/PKCS5PADDING"] = "AES/CFB/PKCS7PADDING"; - - algorithms["RSA//PKCS1"] = "RSA//PKCS1PADDING"; - algorithms["RSA/ECB/PKCS1"] = "RSA//PKCS1PADDING"; - algorithms["RSA/ECB/PKCS1PADDING"] = "RSA//PKCS1PADDING"; - algorithms[PkcsObjectIdentifiers.RsaEncryption.Id] = "RSA//PKCS1PADDING"; - - algorithms[OiwObjectIdentifiers.DesCbc.Id] = "DES/CBC"; - algorithms[OiwObjectIdentifiers.DesCfb.Id] = "DES/CFB"; - algorithms[OiwObjectIdentifiers.DesEcb.Id] = "DES/ECB"; - algorithms[OiwObjectIdentifiers.DesOfb.Id] = "DES/OFB"; - algorithms[OiwObjectIdentifiers.DesEde.Id] = "DESEDE"; - algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDE/CBC"; - algorithms[PkcsObjectIdentifiers.RC2Cbc.Id] = "RC2/CBC"; - algorithms["1.3.6.1.4.1.188.7.1.1.2"] = "IDEA/CBC"; - algorithms["1.2.840.113533.7.66.10"] = "CAST5/CBC"; - - algorithms["RC4"] = "ARC4"; - algorithms["ARCFOUR"] = "ARC4"; - algorithms["1.2.840.113549.3.4"] = "ARC4"; - - - - algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEWITHSHAAND128BITRC4"; - algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEWITHSHAAND128BITRC4"; - algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEWITHSHAAND40BITRC4"; - algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEWITHSHAAND40BITRC4"; - - algorithms["PBEWITHSHA1ANDDES"] = "PBEWITHSHA1ANDDES-CBC"; - algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEWITHSHA1ANDDES-CBC"; - algorithms["PBEWITHSHA1ANDRC2"] = "PBEWITHSHA1ANDRC2-CBC"; - algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEWITHSHA1ANDRC2-CBC"; - - algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; - algorithms["PBEWITHSHAAND3KEYTRIPLEDES"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; - algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; - algorithms["PBEWITHSHA1ANDDESEDE"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; - - algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"; - algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"; - - algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEWITHSHAAND128BITRC2-CBC"; - algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEWITHSHAAND128BITRC2-CBC"; - - algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEWITHSHAAND40BITRC2-CBC"; - algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEWITHSHAAND40BITRC2-CBC"; - - algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC"; - algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC"; - - algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC"; - algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC"; - - algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC"; - algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC"; - - algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEWITHSHA256AND128BITAES-CBC-BC"; - algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEWITHSHA256AND192BITAES-CBC-BC"; - algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEWITHSHA256AND256BITAES-CBC-BC"; - - - algorithms["GOST"] = "GOST28147"; - algorithms["GOST-28147"] = "GOST28147"; - algorithms[CryptoProObjectIdentifiers.GostR28147Cbc.Id] = "GOST28147/CBC/PKCS7PADDING"; - - algorithms["RC5-32"] = "RC5"; - - algorithms[NttObjectIdentifiers.IdCamellia128Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; - algorithms[NttObjectIdentifiers.IdCamellia192Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; - algorithms[NttObjectIdentifiers.IdCamellia256Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; - - algorithms[KisaObjectIdentifiers.IdSeedCbc.Id] = "SEED/CBC/PKCS7PADDING"; - } - - private CipherUtilities() - { - } - - /// - /// Returns a ObjectIdentifier for a give encoding. - /// - /// A string representation of the encoding. - /// A DerObjectIdentifier, null if the Oid is not available. - // TODO Don't really want to support this - public static DerObjectIdentifier GetObjectIdentifier( - string mechanism) - { - if (mechanism == null) - throw new ArgumentNullException("mechanism"); - - mechanism = mechanism.ToUpper(CultureInfo.InvariantCulture); - string aliased = (string) algorithms[mechanism]; - - if (aliased != null) - mechanism = aliased; - - return (DerObjectIdentifier) oids[mechanism]; - } - - public static ICollection Algorithms - { - get { return oids.Keys; } - } - - public static IBufferedCipher GetCipher( - DerObjectIdentifier oid) - { - return GetCipher(oid.Id); - } - - public static IBufferedCipher GetCipher( - string algorithm) - { - if (algorithm == null) - throw new ArgumentNullException("algorithm"); - - algorithm = algorithm.ToUpper(CultureInfo.InvariantCulture); - - string aliased = (string) algorithms[algorithm]; - - if (aliased != null) - algorithm = aliased; - - - - IBasicAgreement iesAgreement = null; - if (algorithm == "IES") - { - iesAgreement = new DHBasicAgreement(); - } - else if (algorithm == "ECIES") - { - iesAgreement = new ECDHBasicAgreement(); - } - - if (iesAgreement != null) - { - return new BufferedIesCipher( - new IesEngine( - iesAgreement, - new Kdf2BytesGenerator( - new Sha1Digest()), - new HMac( - new Sha1Digest()))); - } - - - - if (algorithm.StartsWith("PBE")) - { - switch (algorithm) - { - case "PBEWITHSHAAND2-KEYTRIPLEDES-CBC": - case "PBEWITHSHAAND3-KEYTRIPLEDES-CBC": - return new PaddedBufferedBlockCipher( - new CbcBlockCipher(new DesEdeEngine())); - - case "PBEWITHSHAAND128BITRC2-CBC": - case "PBEWITHSHAAND40BITRC2-CBC": - return new PaddedBufferedBlockCipher( - new CbcBlockCipher(new RC2Engine())); - - case "PBEWITHSHAAND128BITAES-CBC-BC": - case "PBEWITHSHAAND192BITAES-CBC-BC": - case "PBEWITHSHAAND256BITAES-CBC-BC": - case "PBEWITHSHA256AND128BITAES-CBC-BC": - case "PBEWITHSHA256AND192BITAES-CBC-BC": - case "PBEWITHSHA256AND256BITAES-CBC-BC": - case "PBEWITHMD5AND128BITAES-CBC-OPENSSL": - case "PBEWITHMD5AND192BITAES-CBC-OPENSSL": - case "PBEWITHMD5AND256BITAES-CBC-OPENSSL": - return new PaddedBufferedBlockCipher( - new CbcBlockCipher(new AesFastEngine())); - - case "PBEWITHSHA1ANDDES-CBC": - return new PaddedBufferedBlockCipher( - new CbcBlockCipher(new DesEngine())); - - case "PBEWITHSHA1ANDRC2-CBC": - return new PaddedBufferedBlockCipher( - new CbcBlockCipher(new RC2Engine())); - } - } - - - - string[] parts = algorithm.Split('/'); - - IBlockCipher blockCipher = null; - IAsymmetricBlockCipher asymBlockCipher = null; - IStreamCipher streamCipher = null; - - switch (parts[0]) - { - case "AES": - blockCipher = new AesFastEngine(); - break; - case "ARC4": - streamCipher = new RC4Engine(); - break; - case "BLOWFISH": - blockCipher = new BlowfishEngine(); - break; - case "CAMELLIA": - blockCipher = new CamelliaEngine(); - break; - case "CAST5": - blockCipher = new Cast5Engine(); - break; - case "CAST6": - blockCipher = new Cast6Engine(); - break; - case "DES": - blockCipher = new DesEngine(); - break; - case "DESEDE": - blockCipher = new DesEdeEngine(); - break; - case "ELGAMAL": - asymBlockCipher = new ElGamalEngine(); - break; - case "GOST28147": - blockCipher = new Gost28147Engine(); - break; - case "HC128": - streamCipher = new HC128Engine(); - break; - case "HC256": - streamCipher = new HC256Engine(); - break; -#if INCLUDE_IDEA - case "IDEA": - blockCipher = new IdeaEngine(); - break; -#endif - case "NOEKEON": - blockCipher = new NoekeonEngine(); - break; - case "PBEWITHSHAAND128BITRC4": - case "PBEWITHSHAAND40BITRC4": - streamCipher = new RC4Engine(); - break; - case "RC2": - blockCipher = new RC2Engine(); - break; - case "RC5": - blockCipher = new RC532Engine(); - break; - case "RC5-64": - blockCipher = new RC564Engine(); - break; - case "RC6": - blockCipher = new RC6Engine(); - break; - case "RIJNDAEL": - blockCipher = new RijndaelEngine(); - break; - case "RSA": - asymBlockCipher = new RsaBlindedEngine(); - break; - case "SALSA20": - streamCipher = new Salsa20Engine(); - break; - case "SEED": - blockCipher = new SeedEngine(); - break; - case "SERPENT": - blockCipher = new SerpentEngine(); - break; - case "SKIPJACK": - blockCipher = new SkipjackEngine(); - break; - case "TEA": - blockCipher = new TeaEngine(); - break; - case "TWOFISH": - blockCipher = new TwofishEngine(); - break; - case "VMPC": - streamCipher = new VmpcEngine(); - break; - case "VMPC-KSA3": - streamCipher = new VmpcKsa3Engine(); - break; - case "XTEA": - blockCipher = new XteaEngine(); - break; - default: - throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); - } - - if (streamCipher != null) - { - if (parts.Length > 1) - throw new ArgumentException("Modes and paddings not used for stream ciphers"); - - return new BufferedStreamCipher(streamCipher); - } - - - bool cts = false; - bool padded = true; - IBlockCipherPadding padding = null; - IAeadBlockCipher aeadBlockCipher = null; - - if (parts.Length > 2) - { - if (streamCipher != null) - throw new ArgumentException("Paddings not used for stream ciphers"); - - switch (parts[2]) - { - case "NOPADDING": - padded = false; - break; - case "": - case "RAW": - break; - case "ISO10126PADDING": - case "ISO10126D2PADDING": - case "ISO10126-2PADDING": - padding = new ISO10126d2Padding(); - break; - case "ISO7816-4PADDING": - case "ISO9797-1PADDING": - padding = new ISO7816d4Padding(); - break; - case "ISO9796-1": - case "ISO9796-1PADDING": - asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher); - break; - case "OAEP": - case "OAEPPADDING": - asymBlockCipher = new OaepEncoding(asymBlockCipher); - break; - case "OAEPWITHMD5ANDMGF1PADDING": - asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest()); - break; - case "OAEPWITHSHA1ANDMGF1PADDING": - case "OAEPWITHSHA-1ANDMGF1PADDING": - asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest()); - break; - case "OAEPWITHSHA224ANDMGF1PADDING": - case "OAEPWITHSHA-224ANDMGF1PADDING": - asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest()); - break; - case "OAEPWITHSHA256ANDMGF1PADDING": - case "OAEPWITHSHA-256ANDMGF1PADDING": - asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest()); - break; - case "OAEPWITHSHA384ANDMGF1PADDING": - case "OAEPWITHSHA-384ANDMGF1PADDING": - asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest()); - break; - case "OAEPWITHSHA512ANDMGF1PADDING": - case "OAEPWITHSHA-512ANDMGF1PADDING": - asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest()); - break; - case "PKCS1": - case "PKCS1PADDING": - asymBlockCipher = new Pkcs1Encoding(asymBlockCipher); - break; - case "PKCS5": - case "PKCS5PADDING": - case "PKCS7": - case "PKCS7PADDING": - // NB: Padding defaults to Pkcs7Padding already - break; - case "TBCPADDING": - padding = new TbcPadding(); - break; - case "WITHCTS": - cts = true; - break; - case "X9.23PADDING": - case "X923PADDING": - padding = new X923Padding(); - break; - case "ZEROBYTEPADDING": - padding = new ZeroBytePadding(); - break; - default: - throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); - } - } - - string mode = ""; - if (parts.Length > 1) - { - mode = parts[1]; - - int di = GetDigitIndex(mode); - string modeName = di >= 0 ? mode.Substring(0, di) : mode; - - switch (modeName) - { - case "": - case "ECB": - case "NONE": - break; - case "CBC": - blockCipher = new CbcBlockCipher(blockCipher); - break; - case "CCM": - aeadBlockCipher = new CcmBlockCipher(blockCipher); - break; - case "CFB": - { - int bits = (di < 0) - ? 8 * blockCipher.GetBlockSize() - : int.Parse(mode.Substring(di)); - - blockCipher = new CfbBlockCipher(blockCipher, bits); - break; - } - case "CTR": - blockCipher = new SicBlockCipher(blockCipher); - break; - case "CTS": - cts = true; - blockCipher = new CbcBlockCipher(blockCipher); - break; - case "EAX": - aeadBlockCipher = new EaxBlockCipher(blockCipher); - break; - case "GCM": - aeadBlockCipher = new GcmBlockCipher(blockCipher); - break; - case "GOFB": - blockCipher = new GOfbBlockCipher(blockCipher); - break; - case "OFB": - { - int bits = (di < 0) - ? 8 * blockCipher.GetBlockSize() - : int.Parse(mode.Substring(di)); - - blockCipher = new OfbBlockCipher(blockCipher, bits); - break; - } - case "OPENPGPCFB": - blockCipher = new OpenPgpCfbBlockCipher(blockCipher); - break; - case "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)"); - } - blockCipher = new SicBlockCipher(blockCipher); - break; - default: - throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); - } - } - - if (aeadBlockCipher != null) - { - if (cts) - throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers."); - if (padded && parts.Length > 1 && parts[2] != "") - throw new SecurityUtilityException("Bad padding specified for AEAD cipher."); - - return new BufferedAeadBlockCipher(aeadBlockCipher); - } - - if (blockCipher != null) - { - if (cts) - { - return new CtsBlockCipher(blockCipher); - } - - if (!padded || blockCipher.IsPartialBlockOkay) - { - return new BufferedBlockCipher(blockCipher); - } - - if (padding != null) - { - return new PaddedBufferedBlockCipher(blockCipher, padding); - } - - return new PaddedBufferedBlockCipher(blockCipher); - } - - if (asymBlockCipher != null) - { - return new BufferedAsymmetricBlockCipher(asymBlockCipher); - } - - throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); - } - - public static string GetAlgorithmName( - DerObjectIdentifier oid) - { - return (string) algorithms[oid.Id]; - } - - private static int GetDigitIndex( - string s) - { - for (int i = 0; i < s.Length; ++i) - { - if (char.IsDigit(s[i])) - return i; - } - - return -1; - } - } -} +using System; +using System.Collections; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Agreement; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Encodings; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; + +namespace Org.BouncyCastle.Security +{ + /// + /// Cipher Utility class contains methods that can not be specifically grouped into other classes. + /// + public sealed class CipherUtilities + { + private static readonly Hashtable algorithms = new Hashtable(); + private static readonly Hashtable oids = new Hashtable(); + + static CipherUtilities() + { + // TODO Flesh out the list of aliases + + algorithms[NistObjectIdentifiers.IdAes128Ecb.Id] = "AES/ECB/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes192Ecb.Id] = "AES/ECB/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes256Ecb.Id] = "AES/ECB/PKCS7PADDING"; + algorithms["AES/ECB/PKCS7"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES//PKCS7"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES//PKCS7PADDING"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES/ECB/PKCS5"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES/ECB/PKCS5PADDING"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES//PKCS5"] = "AES/ECB/PKCS7PADDING"; + algorithms["AES//PKCS5PADDING"] = "AES/ECB/PKCS7PADDING"; + + algorithms[NistObjectIdentifiers.IdAes128Cbc.Id] = "AES/CBC/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "AES/CBC/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "AES/CBC/PKCS7PADDING"; + algorithms["AES/CBC/PKCS7"] = "AES/CBC/PKCS7PADDING"; + algorithms["AES/CBC/PKCS5"] = "AES/CBC/PKCS7PADDING"; + algorithms["AES/CBC/PKCS5PADDING"] = "AES/CBC/PKCS7PADDING"; + + algorithms[NistObjectIdentifiers.IdAes128Ofb.Id] = "AES/OFB/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes192Ofb.Id] = "AES/OFB/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes256Ofb.Id] = "AES/OFB/PKCS7PADDING"; + algorithms["AES/OFB/PKCS7"] = "AES/OFB/PKCS7PADDING"; + algorithms["AES/OFB/PKCS5"] = "AES/OFB/PKCS7PADDING"; + algorithms["AES/OFB/PKCS5PADDING"] = "AES/OFB/PKCS7PADDING"; + + algorithms[NistObjectIdentifiers.IdAes128Cfb.Id] = "AES/CFB/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes192Cfb.Id] = "AES/CFB/PKCS7PADDING"; + algorithms[NistObjectIdentifiers.IdAes256Cfb.Id] = "AES/CFB/PKCS7PADDING"; + algorithms["AES/CFB/PKCS7"] = "AES/CFB/PKCS7PADDING"; + algorithms["AES/CFB/PKCS5"] = "AES/CFB/PKCS7PADDING"; + algorithms["AES/CFB/PKCS5PADDING"] = "AES/CFB/PKCS7PADDING"; + + algorithms["RSA//PKCS1"] = "RSA//PKCS1PADDING"; + algorithms["RSA/ECB/PKCS1"] = "RSA//PKCS1PADDING"; + algorithms["RSA/ECB/PKCS1PADDING"] = "RSA//PKCS1PADDING"; + algorithms[PkcsObjectIdentifiers.RsaEncryption.Id] = "RSA//PKCS1PADDING"; + + algorithms[OiwObjectIdentifiers.DesCbc.Id] = "DES/CBC"; + algorithms[OiwObjectIdentifiers.DesCfb.Id] = "DES/CFB"; + algorithms[OiwObjectIdentifiers.DesEcb.Id] = "DES/ECB"; + algorithms[OiwObjectIdentifiers.DesOfb.Id] = "DES/OFB"; + algorithms[OiwObjectIdentifiers.DesEde.Id] = "DESEDE"; + algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDE/CBC"; + algorithms[PkcsObjectIdentifiers.RC2Cbc.Id] = "RC2/CBC"; + algorithms["1.3.6.1.4.1.188.7.1.1.2"] = "IDEA/CBC"; + algorithms["1.2.840.113533.7.66.10"] = "CAST5/CBC"; + + algorithms["RC4"] = "ARC4"; + algorithms["ARCFOUR"] = "ARC4"; + algorithms["1.2.840.113549.3.4"] = "ARC4"; + + + + algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEWITHSHAAND128BITRC4"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEWITHSHAAND128BITRC4"; + algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEWITHSHAAND40BITRC4"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEWITHSHAAND40BITRC4"; + + algorithms["PBEWITHSHA1ANDDES"] = "PBEWITHSHA1ANDDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEWITHSHA1ANDDES-CBC"; + algorithms["PBEWITHSHA1ANDRC2"] = "PBEWITHSHA1ANDRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEWITHSHA1ANDRC2-CBC"; + + algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; + algorithms["PBEWITHSHAAND3KEYTRIPLEDES"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; + algorithms["PBEWITHSHA1ANDDESEDE"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"; + + algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC"; + + algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEWITHSHAAND128BITRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEWITHSHAAND128BITRC2-CBC"; + + algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEWITHSHAAND40BITRC2-CBC"; + algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEWITHSHAAND40BITRC2-CBC"; + + algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC"; + + algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC"; + + algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC"; + algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC"; + + algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEWITHSHA256AND128BITAES-CBC-BC"; + algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEWITHSHA256AND192BITAES-CBC-BC"; + algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEWITHSHA256AND256BITAES-CBC-BC"; + + + algorithms["GOST"] = "GOST28147"; + algorithms["GOST-28147"] = "GOST28147"; + algorithms[CryptoProObjectIdentifiers.GostR28147Cbc.Id] = "GOST28147/CBC/PKCS7PADDING"; + + algorithms["RC5-32"] = "RC5"; + + algorithms[NttObjectIdentifiers.IdCamellia128Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; + algorithms[NttObjectIdentifiers.IdCamellia192Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; + algorithms[NttObjectIdentifiers.IdCamellia256Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING"; + + algorithms[KisaObjectIdentifiers.IdSeedCbc.Id] = "SEED/CBC/PKCS7PADDING"; + + algorithms["1.3.6.1.4.1.3029.1.2"] = "BLOWFISH/CBC"; + } + + private CipherUtilities() + { + } + + /// + /// Returns a ObjectIdentifier for a give encoding. + /// + /// A string representation of the encoding. + /// A DerObjectIdentifier, null if the Oid is not available. + // TODO Don't really want to support this + public static DerObjectIdentifier GetObjectIdentifier( + string mechanism) + { + if (mechanism == null) + throw new ArgumentNullException("mechanism"); + + mechanism = mechanism.ToUpper(CultureInfo.InvariantCulture); + string aliased = (string) algorithms[mechanism]; + + if (aliased != null) + mechanism = aliased; + + return (DerObjectIdentifier) oids[mechanism]; + } + + public static ICollection Algorithms + { + get { return oids.Keys; } + } + + public static IBufferedCipher GetCipher( + DerObjectIdentifier oid) + { + return GetCipher(oid.Id); + } + + public static IBufferedCipher GetCipher( + string algorithm) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + algorithm = algorithm.ToUpper(CultureInfo.InvariantCulture); + + string aliased = (string) algorithms[algorithm]; + + if (aliased != null) + algorithm = aliased; + + + + IBasicAgreement iesAgreement = null; + if (algorithm == "IES") + { + iesAgreement = new DHBasicAgreement(); + } + else if (algorithm == "ECIES") + { + iesAgreement = new ECDHBasicAgreement(); + } + + if (iesAgreement != null) + { + return new BufferedIesCipher( + new IesEngine( + iesAgreement, + new Kdf2BytesGenerator( + new Sha1Digest()), + new HMac( + new Sha1Digest()))); + } + + + + if (algorithm.StartsWith("PBE")) + { + switch (algorithm) + { + case "PBEWITHSHAAND2-KEYTRIPLEDES-CBC": + case "PBEWITHSHAAND3-KEYTRIPLEDES-CBC": + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new DesEdeEngine())); + + case "PBEWITHSHAAND128BITRC2-CBC": + case "PBEWITHSHAAND40BITRC2-CBC": + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new RC2Engine())); + + case "PBEWITHSHAAND128BITAES-CBC-BC": + case "PBEWITHSHAAND192BITAES-CBC-BC": + case "PBEWITHSHAAND256BITAES-CBC-BC": + case "PBEWITHSHA256AND128BITAES-CBC-BC": + case "PBEWITHSHA256AND192BITAES-CBC-BC": + case "PBEWITHSHA256AND256BITAES-CBC-BC": + case "PBEWITHMD5AND128BITAES-CBC-OPENSSL": + case "PBEWITHMD5AND192BITAES-CBC-OPENSSL": + case "PBEWITHMD5AND256BITAES-CBC-OPENSSL": + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new AesFastEngine())); + + case "PBEWITHSHA1ANDDES-CBC": + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new DesEngine())); + + case "PBEWITHSHA1ANDRC2-CBC": + return new PaddedBufferedBlockCipher( + new CbcBlockCipher(new RC2Engine())); + } + } + + + + string[] parts = algorithm.Split('/'); + + IBlockCipher blockCipher = null; + IAsymmetricBlockCipher asymBlockCipher = null; + IStreamCipher streamCipher = null; + + switch (parts[0]) + { + case "AES": + blockCipher = new AesFastEngine(); + break; + case "ARC4": + streamCipher = new RC4Engine(); + break; + case "BLOWFISH": + blockCipher = new BlowfishEngine(); + break; + case "CAMELLIA": + blockCipher = new CamelliaEngine(); + break; + case "CAST5": + blockCipher = new Cast5Engine(); + break; + case "CAST6": + blockCipher = new Cast6Engine(); + break; + case "DES": + blockCipher = new DesEngine(); + break; + case "DESEDE": + blockCipher = new DesEdeEngine(); + break; + case "ELGAMAL": + asymBlockCipher = new ElGamalEngine(); + break; + case "GOST28147": + blockCipher = new Gost28147Engine(); + break; + case "HC128": + streamCipher = new HC128Engine(); + break; + case "HC256": + streamCipher = new HC256Engine(); + break; +#if INCLUDE_IDEA + case "IDEA": + blockCipher = new IdeaEngine(); + break; +#endif + case "NOEKEON": + blockCipher = new NoekeonEngine(); + break; + case "PBEWITHSHAAND128BITRC4": + case "PBEWITHSHAAND40BITRC4": + streamCipher = new RC4Engine(); + break; + case "RC2": + blockCipher = new RC2Engine(); + break; + case "RC5": + blockCipher = new RC532Engine(); + break; + case "RC5-64": + blockCipher = new RC564Engine(); + break; + case "RC6": + blockCipher = new RC6Engine(); + break; + case "RIJNDAEL": + blockCipher = new RijndaelEngine(); + break; + case "RSA": + asymBlockCipher = new RsaBlindedEngine(); + break; + case "SALSA20": + streamCipher = new Salsa20Engine(); + break; + case "SEED": + blockCipher = new SeedEngine(); + break; + case "SERPENT": + blockCipher = new SerpentEngine(); + break; + case "SKIPJACK": + blockCipher = new SkipjackEngine(); + break; + case "TEA": + blockCipher = new TeaEngine(); + break; + case "TWOFISH": + blockCipher = new TwofishEngine(); + break; + case "VMPC": + streamCipher = new VmpcEngine(); + break; + case "VMPC-KSA3": + streamCipher = new VmpcKsa3Engine(); + break; + case "XTEA": + blockCipher = new XteaEngine(); + break; + default: + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + + if (streamCipher != null) + { + if (parts.Length > 1) + throw new ArgumentException("Modes and paddings not used for stream ciphers"); + + return new BufferedStreamCipher(streamCipher); + } + + + bool cts = false; + bool padded = true; + IBlockCipherPadding padding = null; + IAeadBlockCipher aeadBlockCipher = null; + + if (parts.Length > 2) + { + if (streamCipher != null) + throw new ArgumentException("Paddings not used for stream ciphers"); + + switch (parts[2]) + { + case "NOPADDING": + padded = false; + break; + case "": + case "RAW": + break; + case "ISO10126PADDING": + case "ISO10126D2PADDING": + case "ISO10126-2PADDING": + padding = new ISO10126d2Padding(); + break; + case "ISO7816-4PADDING": + case "ISO9797-1PADDING": + padding = new ISO7816d4Padding(); + break; + case "ISO9796-1": + case "ISO9796-1PADDING": + asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher); + break; + case "OAEP": + case "OAEPPADDING": + asymBlockCipher = new OaepEncoding(asymBlockCipher); + break; + case "OAEPWITHMD5ANDMGF1PADDING": + asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest()); + break; + case "OAEPWITHSHA1ANDMGF1PADDING": + case "OAEPWITHSHA-1ANDMGF1PADDING": + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest()); + break; + case "OAEPWITHSHA224ANDMGF1PADDING": + case "OAEPWITHSHA-224ANDMGF1PADDING": + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest()); + break; + case "OAEPWITHSHA256ANDMGF1PADDING": + case "OAEPWITHSHA-256ANDMGF1PADDING": + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest()); + break; + case "OAEPWITHSHA384ANDMGF1PADDING": + case "OAEPWITHSHA-384ANDMGF1PADDING": + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest()); + break; + case "OAEPWITHSHA512ANDMGF1PADDING": + case "OAEPWITHSHA-512ANDMGF1PADDING": + asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest()); + break; + case "PKCS1": + case "PKCS1PADDING": + asymBlockCipher = new Pkcs1Encoding(asymBlockCipher); + break; + case "PKCS5": + case "PKCS5PADDING": + case "PKCS7": + case "PKCS7PADDING": + // NB: Padding defaults to Pkcs7Padding already + break; + case "TBCPADDING": + padding = new TbcPadding(); + break; + case "WITHCTS": + cts = true; + break; + case "X9.23PADDING": + case "X923PADDING": + padding = new X923Padding(); + break; + case "ZEROBYTEPADDING": + padding = new ZeroBytePadding(); + break; + default: + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + } + + string mode = ""; + if (parts.Length > 1) + { + mode = parts[1]; + + int di = GetDigitIndex(mode); + string modeName = di >= 0 ? mode.Substring(0, di) : mode; + + switch (modeName) + { + case "": + case "ECB": + case "NONE": + break; + case "CBC": + blockCipher = new CbcBlockCipher(blockCipher); + break; + case "CCM": + aeadBlockCipher = new CcmBlockCipher(blockCipher); + break; + case "CFB": + { + int bits = (di < 0) + ? 8 * blockCipher.GetBlockSize() + : int.Parse(mode.Substring(di)); + + blockCipher = new CfbBlockCipher(blockCipher, bits); + break; + } + case "CTR": + blockCipher = new SicBlockCipher(blockCipher); + break; + case "CTS": + cts = true; + blockCipher = new CbcBlockCipher(blockCipher); + break; + case "EAX": + aeadBlockCipher = new EaxBlockCipher(blockCipher); + break; + case "GCM": + aeadBlockCipher = new GcmBlockCipher(blockCipher); + break; + case "GOFB": + blockCipher = new GOfbBlockCipher(blockCipher); + break; + case "OFB": + { + int bits = (di < 0) + ? 8 * blockCipher.GetBlockSize() + : int.Parse(mode.Substring(di)); + + blockCipher = new OfbBlockCipher(blockCipher, bits); + break; + } + case "OPENPGPCFB": + blockCipher = new OpenPgpCfbBlockCipher(blockCipher); + break; + case "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)"); + } + blockCipher = new SicBlockCipher(blockCipher); + break; + default: + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + } + + if (aeadBlockCipher != null) + { + if (cts) + throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers."); + if (padded && parts.Length > 1 && parts[2] != "") + throw new SecurityUtilityException("Bad padding specified for AEAD cipher."); + + return new BufferedAeadBlockCipher(aeadBlockCipher); + } + + if (blockCipher != null) + { + if (cts) + { + return new CtsBlockCipher(blockCipher); + } + + if (!padded || blockCipher.IsPartialBlockOkay) + { + return new BufferedBlockCipher(blockCipher); + } + + if (padding != null) + { + return new PaddedBufferedBlockCipher(blockCipher, padding); + } + + return new PaddedBufferedBlockCipher(blockCipher); + } + + if (asymBlockCipher != null) + { + return new BufferedAsymmetricBlockCipher(asymBlockCipher); + } + + throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); + } + + public static string GetAlgorithmName( + DerObjectIdentifier oid) + { + return (string) algorithms[oid.Id]; + } + + private static int GetDigitIndex( + string s) + { + for (int i = 0; i < s.Length; ++i) + { + if (char.IsDigit(s[i])) + return i; + } + + return -1; + } + } +} diff --git a/src/core/srcbc/security/GeneratorUtilities.cs b/src/core/srcbc/security/GeneratorUtilities.cs index 513195f..b20092b 100644 --- a/src/core/srcbc/security/GeneratorUtilities.cs +++ b/src/core/srcbc/security/GeneratorUtilities.cs @@ -1,357 +1,372 @@ -using System.Collections; -using System.Globalization; - -using Org.BouncyCastle.Asn1; -using Org.BouncyCastle.Asn1.CryptoPro; -using Org.BouncyCastle.Asn1.Iana; -using Org.BouncyCastle.Asn1.Kisa; -using Org.BouncyCastle.Asn1.Nist; -using Org.BouncyCastle.Asn1.Ntt; -using Org.BouncyCastle.Asn1.Oiw; -using Org.BouncyCastle.Asn1.Pkcs; -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Generators; - -namespace Org.BouncyCastle.Security -{ - public sealed class GeneratorUtilities - { - private GeneratorUtilities() - { - } - - private static readonly Hashtable kgAlgorithms = new Hashtable(); - private static readonly Hashtable kpgAlgorithms = new Hashtable(); - - static GeneratorUtilities() - { - // - // key generators. - // - AddKgAlgorithm("AES", - "AESWRAP"); - AddKgAlgorithm("AES128", - "2.16.840.1.101.3.4.2", - NistObjectIdentifiers.IdAes128Cbc, - NistObjectIdentifiers.IdAes128Cfb, - NistObjectIdentifiers.IdAes128Ecb, - NistObjectIdentifiers.IdAes128Ofb, - NistObjectIdentifiers.IdAes128Wrap); - AddKgAlgorithm("AES192", - "2.16.840.1.101.3.4.22", - NistObjectIdentifiers.IdAes192Cbc, - NistObjectIdentifiers.IdAes192Cfb, - NistObjectIdentifiers.IdAes192Ecb, - NistObjectIdentifiers.IdAes192Ofb, - NistObjectIdentifiers.IdAes192Wrap); - AddKgAlgorithm("AES256", - "2.16.840.1.101.3.4.42", - NistObjectIdentifiers.IdAes256Cbc, - NistObjectIdentifiers.IdAes256Cfb, - NistObjectIdentifiers.IdAes256Ecb, - NistObjectIdentifiers.IdAes256Ofb, - NistObjectIdentifiers.IdAes256Wrap); - AddKgAlgorithm("BLOWFISH"); - AddKgAlgorithm("CAMELLIA", - "CAMELLIAWRAP"); - AddKgAlgorithm("CAMELLIA128", - NttObjectIdentifiers.IdCamellia128Cbc, - NttObjectIdentifiers.IdCamellia128Wrap); - AddKgAlgorithm("CAMELLIA192", - NttObjectIdentifiers.IdCamellia192Cbc, - NttObjectIdentifiers.IdCamellia192Wrap); - AddKgAlgorithm("CAMELLIA256", - NttObjectIdentifiers.IdCamellia256Cbc, - NttObjectIdentifiers.IdCamellia256Wrap); - AddKgAlgorithm("CAST5", - "1.2.840.113533.7.66.10"); - AddKgAlgorithm("CAST6"); - AddKgAlgorithm("DES", - OiwObjectIdentifiers.DesCbc, - OiwObjectIdentifiers.DesCfb, - OiwObjectIdentifiers.DesEcb, - OiwObjectIdentifiers.DesOfb); - AddKgAlgorithm("DESEDE", - "DESEDEWRAP", - OiwObjectIdentifiers.DesEde, - PkcsObjectIdentifiers.IdAlgCms3DesWrap); - AddKgAlgorithm("DESEDE3", - PkcsObjectIdentifiers.DesEde3Cbc); - AddKgAlgorithm("GOST28147", - "GOST", - "GOST-28147", - CryptoProObjectIdentifiers.GostR28147Cbc); - AddKgAlgorithm("HC128"); - AddKgAlgorithm("HC256"); - AddKgAlgorithm("IDEA", - "1.3.6.1.4.1.188.7.1.1.2"); - AddKgAlgorithm("NOEKEON"); - AddKgAlgorithm("RC2", - PkcsObjectIdentifiers.RC2Cbc, - PkcsObjectIdentifiers.IdAlgCmsRC2Wrap); - AddKgAlgorithm("RC4", - "ARC4", - "1.2.840.113549.3.4"); - AddKgAlgorithm("RC5", - "RC5-32"); - AddKgAlgorithm("RC5-64"); - AddKgAlgorithm("RC6"); - AddKgAlgorithm("RIJNDAEL"); - AddKgAlgorithm("SALSA20"); - AddKgAlgorithm("SEED", - KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap, - KisaObjectIdentifiers.IdSeedCbc); - AddKgAlgorithm("SERPENT"); - AddKgAlgorithm("SKIPJACK"); - AddKgAlgorithm("TEA"); - AddKgAlgorithm("TWOFISH"); - AddKgAlgorithm("VMPC"); - AddKgAlgorithm("VMPC-KSA3"); - AddKgAlgorithm("XTEA"); - - // - // HMac key generators - // - AddHMacKeyGenerator("MD2"); - AddHMacKeyGenerator("MD4"); - AddHMacKeyGenerator("MD5", - IanaObjectIdentifiers.HmacMD5); - AddHMacKeyGenerator("SHA1", - PkcsObjectIdentifiers.IdHmacWithSha1, - IanaObjectIdentifiers.HmacSha1); - AddHMacKeyGenerator("SHA224", - PkcsObjectIdentifiers.IdHmacWithSha224); - AddHMacKeyGenerator("SHA256", - PkcsObjectIdentifiers.IdHmacWithSha256); - AddHMacKeyGenerator("SHA384", - PkcsObjectIdentifiers.IdHmacWithSha384); - AddHMacKeyGenerator("SHA512", - PkcsObjectIdentifiers.IdHmacWithSha512); - AddHMacKeyGenerator("RIPEMD128"); - AddHMacKeyGenerator("RIPEMD160", - IanaObjectIdentifiers.HmacRipeMD160); - AddHMacKeyGenerator("TIGER", - IanaObjectIdentifiers.HmacTiger); - - - - // - // key pair generators. - // - AddKpgAlgorithm("DH", - "DIFFIEHELLMAN"); - AddKpgAlgorithm("DSA"); - AddKpgAlgorithm("EC"); - AddKpgAlgorithm("ECDH", - "ECIES"); - AddKpgAlgorithm("ECDHC"); - AddKpgAlgorithm("ECDSA"); - AddKpgAlgorithm("ECGOST3410", - "ECGOST-3410", - "GOST-3410-2001"); - AddKpgAlgorithm("ELGAMAL"); - AddKpgAlgorithm("GOST3410", - "GOST-3410", - "GOST-3410-94"); - AddKpgAlgorithm("RSA", - "1.2.840.113549.1.1.1"); - } - - private static void AddKgAlgorithm( - string canonicalName, - params object[] aliases) - { - kgAlgorithms[canonicalName] = canonicalName; - - foreach (object alias in aliases) - { - kgAlgorithms[alias.ToString()] = canonicalName; - } - } - - private static void AddKpgAlgorithm( - string canonicalName, - params object[] aliases) - { - kpgAlgorithms[canonicalName] = canonicalName; - - foreach (object alias in aliases) - { - kpgAlgorithms[alias.ToString()] = canonicalName; - } - } - - private static void AddHMacKeyGenerator( - string algorithm, - params object[] aliases) - { - string mainName = "HMAC" + algorithm; - - kgAlgorithms[mainName] = mainName; - kgAlgorithms["HMAC-" + algorithm] = mainName; - kgAlgorithms["HMAC/" + algorithm] = mainName; - - foreach (object alias in aliases) - { - kgAlgorithms[alias.ToString()] = mainName; - } - } - - // TODO Consider making this public - internal static string GetCanonicalKeyGeneratorAlgorithm( - string algorithm) - { - return (string) kgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)]; - } - - // TODO Consider making this public - internal static string GetCanonicalKeyPairGeneratorAlgorithm( - string algorithm) - { - return (string) kpgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)]; - } - - public static CipherKeyGenerator GetKeyGenerator( - DerObjectIdentifier oid) - { - return GetKeyGenerator(oid.Id); - } - - public static CipherKeyGenerator GetKeyGenerator( - string algorithm) - { - string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm); - - if (canonicalName == null) - throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised."); - - switch (canonicalName) - { - case "DES": - return new DesKeyGenerator(64); - case "DESEDE": - return new DesEdeKeyGenerator(128); - case "DESEDE3": - return new DesEdeKeyGenerator(192); - case "AES": - return new CipherKeyGenerator(192); - case "AES128": - return new CipherKeyGenerator(128); - case "AES192": - return new CipherKeyGenerator(192); - case "AES256": - return new CipherKeyGenerator(256); - case "BLOWFISH": - return new CipherKeyGenerator(448); - case "CAMELLIA": - return new CipherKeyGenerator(256); - case "CAMELLIA128": - return new CipherKeyGenerator(128); - case "CAMELLIA192": - return new CipherKeyGenerator(192); - case "CAMELLIA256": - return new CipherKeyGenerator(256); - case "CAST5": - return new CipherKeyGenerator(128); - case "CAST6": - return new CipherKeyGenerator(256); - case "GOST28147": - return new CipherKeyGenerator(256); - case "HC128": - return new CipherKeyGenerator(128); - case "HC256": - return new CipherKeyGenerator(256); - case "HMACMD2": - case "HMACMD4": - case "HMACMD5": - return new CipherKeyGenerator(128); - case "HMACSHA1": - return new CipherKeyGenerator(160); - case "HMACSHA224": - return new CipherKeyGenerator(224); - case "HMACSHA256": - return new CipherKeyGenerator(256); - case "HMACSHA384": - return new CipherKeyGenerator(384); - case "HMACSHA512": - return new CipherKeyGenerator(512); - case "HMACRIPEMD128": - return new CipherKeyGenerator(128); - case "HMACRIPEMD160": - return new CipherKeyGenerator(160); - case "HMACTIGER": - return new CipherKeyGenerator(192); - case "IDEA": - return new CipherKeyGenerator(128); - case "NOEKEON": - return new CipherKeyGenerator(128); - case "RC2": - case "RC4": - case "RC5": - return new CipherKeyGenerator(128); - case "RC5-64": - case "RC6": - return new CipherKeyGenerator(256); - case "RIJNDAEL": - return new CipherKeyGenerator(192); - case "SALSA20": - return new CipherKeyGenerator(128); - case "SEED": - return new CipherKeyGenerator(128); - case "SERPENT": - return new CipherKeyGenerator(192); - case "SKIPJACK": - return new CipherKeyGenerator(80); - case "TEA": - case "XTEA": - return new CipherKeyGenerator(128); - case "TWOFISH": - return new CipherKeyGenerator(256); - case "VMPC": - case "VMPC-KSA3": - return new CipherKeyGenerator(128); - } - - throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised."); - } - - public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator( - DerObjectIdentifier oid) - { - return GetKeyPairGenerator(oid.Id); - } - - public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator( - string algorithm) - { - string canonicalName = GetCanonicalKeyPairGeneratorAlgorithm(algorithm); - - if (canonicalName == null) - throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised."); - - switch (canonicalName) - { - case "DH": - return new DHKeyPairGenerator(); - case "DSA": - return new DsaKeyPairGenerator(); - case "EC": - case "ECDH": - case "ECDHC": - case "ECDSA": - case "ECGOST3410": - return new ECKeyPairGenerator(canonicalName); - case "ELGAMAL": - return new ElGamalKeyPairGenerator(); - case "GOST3410": - return new Gost3410KeyPairGenerator(); - case "RSA": - return new RsaKeyPairGenerator(); - default: - break; - } - - throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised."); - } - } -} +using System.Collections; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Iana; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Generators; + +namespace Org.BouncyCastle.Security +{ + public sealed class GeneratorUtilities + { + private GeneratorUtilities() + { + } + + private static readonly Hashtable kgAlgorithms = new Hashtable(); + private static readonly Hashtable kpgAlgorithms = new Hashtable(); + + static GeneratorUtilities() + { + // + // key generators. + // + AddKgAlgorithm("AES", + "AESWRAP"); + AddKgAlgorithm("AES128", + "2.16.840.1.101.3.4.2", + NistObjectIdentifiers.IdAes128Cbc, + NistObjectIdentifiers.IdAes128Cfb, + NistObjectIdentifiers.IdAes128Ecb, + NistObjectIdentifiers.IdAes128Ofb, + NistObjectIdentifiers.IdAes128Wrap); + AddKgAlgorithm("AES192", + "2.16.840.1.101.3.4.22", + NistObjectIdentifiers.IdAes192Cbc, + NistObjectIdentifiers.IdAes192Cfb, + NistObjectIdentifiers.IdAes192Ecb, + NistObjectIdentifiers.IdAes192Ofb, + NistObjectIdentifiers.IdAes192Wrap); + AddKgAlgorithm("AES256", + "2.16.840.1.101.3.4.42", + NistObjectIdentifiers.IdAes256Cbc, + NistObjectIdentifiers.IdAes256Cfb, + NistObjectIdentifiers.IdAes256Ecb, + NistObjectIdentifiers.IdAes256Ofb, + NistObjectIdentifiers.IdAes256Wrap); + AddKgAlgorithm("BLOWFISH", + "1.3.6.1.4.1.3029.1.2"); + AddKgAlgorithm("CAMELLIA", + "CAMELLIAWRAP"); + AddKgAlgorithm("CAMELLIA128", + NttObjectIdentifiers.IdCamellia128Cbc, + NttObjectIdentifiers.IdCamellia128Wrap); + AddKgAlgorithm("CAMELLIA192", + NttObjectIdentifiers.IdCamellia192Cbc, + NttObjectIdentifiers.IdCamellia192Wrap); + AddKgAlgorithm("CAMELLIA256", + NttObjectIdentifiers.IdCamellia256Cbc, + NttObjectIdentifiers.IdCamellia256Wrap); + AddKgAlgorithm("CAST5", + "1.2.840.113533.7.66.10"); + AddKgAlgorithm("CAST6"); + AddKgAlgorithm("DES", + OiwObjectIdentifiers.DesCbc, + OiwObjectIdentifiers.DesCfb, + OiwObjectIdentifiers.DesEcb, + OiwObjectIdentifiers.DesOfb); + AddKgAlgorithm("DESEDE", + "DESEDEWRAP", + OiwObjectIdentifiers.DesEde, + PkcsObjectIdentifiers.IdAlgCms3DesWrap); + AddKgAlgorithm("DESEDE3", + PkcsObjectIdentifiers.DesEde3Cbc); + AddKgAlgorithm("GOST28147", + "GOST", + "GOST-28147", + CryptoProObjectIdentifiers.GostR28147Cbc); + AddKgAlgorithm("HC128"); + AddKgAlgorithm("HC256"); + AddKgAlgorithm("IDEA", + "1.3.6.1.4.1.188.7.1.1.2"); + AddKgAlgorithm("NOEKEON"); + AddKgAlgorithm("RC2", + PkcsObjectIdentifiers.RC2Cbc, + PkcsObjectIdentifiers.IdAlgCmsRC2Wrap); + AddKgAlgorithm("RC4", + "ARC4", + "1.2.840.113549.3.4"); + AddKgAlgorithm("RC5", + "RC5-32"); + AddKgAlgorithm("RC5-64"); + AddKgAlgorithm("RC6"); + AddKgAlgorithm("RIJNDAEL"); + AddKgAlgorithm("SALSA20"); + AddKgAlgorithm("SEED", + KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap, + KisaObjectIdentifiers.IdSeedCbc); + AddKgAlgorithm("SERPENT"); + AddKgAlgorithm("SKIPJACK"); + AddKgAlgorithm("TEA"); + AddKgAlgorithm("TWOFISH"); + AddKgAlgorithm("VMPC"); + AddKgAlgorithm("VMPC-KSA3"); + AddKgAlgorithm("XTEA"); + + // + // HMac key generators + // + AddHMacKeyGenerator("MD2"); + AddHMacKeyGenerator("MD4"); + AddHMacKeyGenerator("MD5", + IanaObjectIdentifiers.HmacMD5); + AddHMacKeyGenerator("SHA1", + PkcsObjectIdentifiers.IdHmacWithSha1, + IanaObjectIdentifiers.HmacSha1); + AddHMacKeyGenerator("SHA224", + PkcsObjectIdentifiers.IdHmacWithSha224); + AddHMacKeyGenerator("SHA256", + PkcsObjectIdentifiers.IdHmacWithSha256); + AddHMacKeyGenerator("SHA384", + PkcsObjectIdentifiers.IdHmacWithSha384); + AddHMacKeyGenerator("SHA512", + PkcsObjectIdentifiers.IdHmacWithSha512); + AddHMacKeyGenerator("RIPEMD128"); + AddHMacKeyGenerator("RIPEMD160", + IanaObjectIdentifiers.HmacRipeMD160); + AddHMacKeyGenerator("TIGER", + IanaObjectIdentifiers.HmacTiger); + + + + // + // key pair generators. + // + AddKpgAlgorithm("DH", + "DIFFIEHELLMAN"); + AddKpgAlgorithm("DSA"); + AddKpgAlgorithm("EC"); + AddKpgAlgorithm("ECDH", + "ECIES"); + AddKpgAlgorithm("ECDHC"); + AddKpgAlgorithm("ECDSA"); + AddKpgAlgorithm("ECGOST3410", + "ECGOST-3410", + "GOST-3410-2001"); + AddKpgAlgorithm("ELGAMAL"); + AddKpgAlgorithm("GOST3410", + "GOST-3410", + "GOST-3410-94"); + AddKpgAlgorithm("RSA", + "1.2.840.113549.1.1.1"); + } + + private static void AddKgAlgorithm( + string canonicalName, + params object[] aliases) + { + kgAlgorithms[canonicalName] = canonicalName; + + foreach (object alias in aliases) + { + kgAlgorithms[alias.ToString()] = canonicalName; + } + } + + private static void AddKpgAlgorithm( + string canonicalName, + params object[] aliases) + { + kpgAlgorithms[canonicalName] = canonicalName; + + foreach (object alias in aliases) + { + kpgAlgorithms[alias.ToString()] = canonicalName; + } + } + + private static void AddHMacKeyGenerator( + string algorithm, + params object[] aliases) + { + string mainName = "HMAC" + algorithm; + + kgAlgorithms[mainName] = mainName; + kgAlgorithms["HMAC-" + algorithm] = mainName; + kgAlgorithms["HMAC/" + algorithm] = mainName; + + foreach (object alias in aliases) + { + kgAlgorithms[alias.ToString()] = mainName; + } + } + + // TODO Consider making this public + internal static string GetCanonicalKeyGeneratorAlgorithm( + string algorithm) + { + return (string) kgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)]; + } + + // TODO Consider making this public + internal static string GetCanonicalKeyPairGeneratorAlgorithm( + string algorithm) + { + return (string) kpgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)]; + } + + public static CipherKeyGenerator GetKeyGenerator( + DerObjectIdentifier oid) + { + return GetKeyGenerator(oid.Id); + } + + public static CipherKeyGenerator GetKeyGenerator( + string algorithm) + { + string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm); + + if (canonicalName == null) + throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised."); + + int defaultKeySize = FindDefaultKeySize(canonicalName); + if (defaultKeySize == -1) + throw new SecurityUtilityException("KeyGenerator " + algorithm + + " (" + canonicalName + ") not supported."); + + switch (canonicalName) + { + case "DES": + return new DesKeyGenerator(defaultKeySize); + case "DESEDE": + case "DESEDE3": + return new DesEdeKeyGenerator(defaultKeySize); + default: + return new CipherKeyGenerator(defaultKeySize); + } + } + + public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator( + DerObjectIdentifier oid) + { + return GetKeyPairGenerator(oid.Id); + } + + public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator( + string algorithm) + { + string canonicalName = GetCanonicalKeyPairGeneratorAlgorithm(algorithm); + + if (canonicalName == null) + throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised."); + + switch (canonicalName) + { + case "DH": + return new DHKeyPairGenerator(); + case "DSA": + return new DsaKeyPairGenerator(); + case "EC": + case "ECDH": + case "ECDHC": + case "ECDSA": + case "ECGOST3410": + return new ECKeyPairGenerator(canonicalName); + case "ELGAMAL": + return new ElGamalKeyPairGenerator(); + case "GOST3410": + return new Gost3410KeyPairGenerator(); + case "RSA": + return new RsaKeyPairGenerator(); + default: + break; + } + + throw new SecurityUtilityException("KeyPairGenerator " + algorithm + + " (" + canonicalName + ") not supported."); + } + + internal static int GetDefaultKeySize( + DerObjectIdentifier oid) + { + return GetDefaultKeySize(oid.Id); + } + + internal static int GetDefaultKeySize( + string algorithm) + { + string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm); + + if (canonicalName == null) + throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised."); + + int defaultKeySize = FindDefaultKeySize(canonicalName); + if (defaultKeySize == -1) + throw new SecurityUtilityException("KeyGenerator " + algorithm + + " (" + canonicalName + ") not supported."); + + return defaultKeySize; + } + + private static int FindDefaultKeySize( + string canonicalName) + { + switch (canonicalName) + { + case "DES": + return 64; + case "BLOWFISH": + case "SKIPJACK": + return 80; + case "AES128": + case "CAMELLIA128": + case "CAST5": + case "DESEDE": + case "HC128": + case "HMACMD2": + case "HMACMD4": + case "HMACMD5": + case "HMACRIPEMD128": + case "IDEA": + case "NOEKEON": + case "RC2": + case "RC4": + case "RC5": + case "SALSA20": + case "SEED": + case "TEA": + case "XTEA": + case "VMPC": + case "VMPC-KSA3": + return 128; + case "HMACRIPEMD160": + case "HMACSHA1": + return 160; + case "AES": + case "AES192": + case "CAMELLIA192": + case "DESEDE3": + case "HMACTIGER": + case "RIJNDAEL": + case "SERPENT": + return 192; + case "HMACSHA224": + return 224; + case "AES256": + case "CAMELLIA": + case "CAMELLIA256": + case "CAST6": + case "GOST28147": + case "HC256": + case "HMACSHA256": + case "RC5-64": + case "RC6": + case "TWOFISH": + return 256; + case "HMACSHA384": + return 384; + case "HMACSHA512": + return 512; + default: + return -1; + } + } + } +} diff --git a/src/core/srcbc/security/ParameterUtilities.cs b/src/core/srcbc/security/ParameterUtilities.cs index ddc0b2b..3365df4 100644 --- a/src/core/srcbc/security/ParameterUtilities.cs +++ b/src/core/srcbc/security/ParameterUtilities.cs @@ -1,322 +1,324 @@ -using System; -using System.Collections; -using System.Globalization; - -using Org.BouncyCastle.Asn1; -using Org.BouncyCastle.Asn1.CryptoPro; -using Org.BouncyCastle.Asn1.Kisa; -using Org.BouncyCastle.Asn1.Misc; -using Org.BouncyCastle.Asn1.Nist; -using Org.BouncyCastle.Asn1.Ntt; -using Org.BouncyCastle.Asn1.Oiw; -using Org.BouncyCastle.Asn1.Pkcs; -using Org.BouncyCastle.Crypto; -using Org.BouncyCastle.Crypto.Parameters; - -namespace Org.BouncyCastle.Security -{ - public sealed class ParameterUtilities - { - private ParameterUtilities() - { - } - - private static readonly Hashtable algorithms = new Hashtable(); - - static ParameterUtilities() - { - AddAlgorithm("AES", - "AESWRAP"); - AddAlgorithm("AES128", - "2.16.840.1.101.3.4.2", - NistObjectIdentifiers.IdAes128Cbc, - NistObjectIdentifiers.IdAes128Cfb, - NistObjectIdentifiers.IdAes128Ecb, - NistObjectIdentifiers.IdAes128Ofb, - NistObjectIdentifiers.IdAes128Wrap); - AddAlgorithm("AES192", - "2.16.840.1.101.3.4.22", - NistObjectIdentifiers.IdAes192Cbc, - NistObjectIdentifiers.IdAes192Cfb, - NistObjectIdentifiers.IdAes192Ecb, - NistObjectIdentifiers.IdAes192Ofb, - NistObjectIdentifiers.IdAes192Wrap); - AddAlgorithm("AES256", - "2.16.840.1.101.3.4.42", - NistObjectIdentifiers.IdAes256Cbc, - NistObjectIdentifiers.IdAes256Cfb, - NistObjectIdentifiers.IdAes256Ecb, - NistObjectIdentifiers.IdAes256Ofb, - NistObjectIdentifiers.IdAes256Wrap); - AddAlgorithm("BLOWFISH"); - AddAlgorithm("CAMELLIA", - "CAMELLIAWRAP"); - AddAlgorithm("CAMELLIA128", - NttObjectIdentifiers.IdCamellia128Cbc, - NttObjectIdentifiers.IdCamellia128Wrap); - AddAlgorithm("CAMELLIA192", - NttObjectIdentifiers.IdCamellia192Cbc, - NttObjectIdentifiers.IdCamellia192Wrap); - AddAlgorithm("CAMELLIA256", - NttObjectIdentifiers.IdCamellia256Cbc, - NttObjectIdentifiers.IdCamellia256Wrap); - AddAlgorithm("CAST5", - "1.2.840.113533.7.66.10"); - AddAlgorithm("CAST6"); - AddAlgorithm("DES", - OiwObjectIdentifiers.DesCbc, - OiwObjectIdentifiers.DesCfb, - OiwObjectIdentifiers.DesEcb, - OiwObjectIdentifiers.DesOfb); - AddAlgorithm("DESEDE", - "DESEDEWRAP", - OiwObjectIdentifiers.DesEde, - PkcsObjectIdentifiers.IdAlgCms3DesWrap); - AddAlgorithm("DESEDE3", - PkcsObjectIdentifiers.DesEde3Cbc); - AddAlgorithm("GOST28147", - "GOST", - "GOST-28147", - CryptoProObjectIdentifiers.GostR28147Cbc); - AddAlgorithm("HC128"); - AddAlgorithm("HC256"); - AddAlgorithm("IDEA", - "1.3.6.1.4.1.188.7.1.1.2"); - AddAlgorithm("NOEKEON"); - AddAlgorithm("RC2", - PkcsObjectIdentifiers.RC2Cbc, - PkcsObjectIdentifiers.IdAlgCmsRC2Wrap); - AddAlgorithm("RC4", - "ARC4", - "1.2.840.113549.3.4"); - AddAlgorithm("RC5", - "RC5-32"); - AddAlgorithm("RC5-64"); - AddAlgorithm("RC6"); - AddAlgorithm("RIJNDAEL"); - AddAlgorithm("SALSA20"); - AddAlgorithm("SEED", - KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap, - KisaObjectIdentifiers.IdSeedCbc); - AddAlgorithm("SERPENT"); - AddAlgorithm("SKIPJACK"); - AddAlgorithm("TEA"); - AddAlgorithm("TWOFISH"); - AddAlgorithm("VMPC"); - AddAlgorithm("VMPC-KSA3"); - AddAlgorithm("XTEA"); - } - - private static void AddAlgorithm( - string canonicalName, - params object[] aliases) - { - algorithms[canonicalName] = canonicalName; - - foreach (object alias in aliases) - { - algorithms[alias.ToString()] = canonicalName; - } - } - - public static string GetCanonicalAlgorithmName( - string algorithm) - { - return (string) algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)]; - } - - public static KeyParameter CreateKeyParameter( - DerObjectIdentifier algOid, - byte[] keyBytes) - { - return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length); - } - - public static KeyParameter CreateKeyParameter( - string algorithm, - byte[] keyBytes) - { - return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length); - } - - public static KeyParameter CreateKeyParameter( - DerObjectIdentifier algOid, - byte[] keyBytes, - int offset, - int length) - { - return CreateKeyParameter(algOid.Id, keyBytes, offset, length); - } - - public static KeyParameter CreateKeyParameter( - string algorithm, - byte[] keyBytes, - int offset, - int length) - { - if (algorithm == null) - throw new ArgumentNullException("algorithm"); - - string canonical = GetCanonicalAlgorithmName(algorithm); - - if (canonical == null) - throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); - - switch (canonical) - { - case "DES": - return new DesParameters(keyBytes, offset, length); - case "DESEDE": - case "DESEDE3": - return new DesEdeParameters(keyBytes, offset, length); - case "RC2": - return new RC2Parameters(keyBytes, offset, length); - default: - return new KeyParameter(keyBytes, offset, length); - } - } - - public static ICipherParameters GetCipherParameters( - DerObjectIdentifier algOid, - ICipherParameters key, - Asn1Object asn1Params) - { - return GetCipherParameters(algOid.Id, key, asn1Params); - } - - public static ICipherParameters GetCipherParameters( - string algorithm, - ICipherParameters key, - Asn1Object asn1Params) - { - if (algorithm == null) - throw new ArgumentNullException("algorithm"); - - string canonical = GetCanonicalAlgorithmName(algorithm); - - if (canonical == null) - throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); - - byte[] iv = null; - - try - { - switch (canonical) - { - case "AES": - case "AES128": - case "AES192": - case "AES256": - case "BLOWFISH": - case "CAMELLIA": - case "CAMELLIA128": - case "CAMELLIA192": - case "CAMELLIA256": - case "DES": - case "DESEDE": - case "DESEDE3": - case "NOEKEON": - case "RIJNDAEL": - case "SEED": - case "SKIPJACK": - case "TWOFISH": - iv = ((Asn1OctetString) asn1Params).GetOctets(); - break; - case "RC2": - iv = RC2CbcParameter.GetInstance(asn1Params).GetIV(); - break; - case "IDEA": - iv = IdeaCbcPar.GetInstance(asn1Params).GetIV(); - break; - case "CAST5": - iv = Cast5CbcParameters.GetInstance(asn1Params).GetIV(); - break; - } - } - catch (Exception e) - { - throw new ArgumentException("Could not process ASN.1 parameters", e); - } - - if (iv != null) - { - return new ParametersWithIV(key, iv); - } - - throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); - } - - public static Asn1Encodable GenerateParameters( - DerObjectIdentifier algID, - SecureRandom random) - { - return GenerateParameters(algID.Id, random); - } - - public static Asn1Encodable GenerateParameters( - string algorithm, - SecureRandom random) - { - if (algorithm == null) - throw new ArgumentNullException("algorithm"); - - string canonical = GetCanonicalAlgorithmName(algorithm); - - if (canonical == null) - throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); - - switch (canonical) - { - // TODO These algorithms support an IV (see GetCipherParameters) - // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them -// case "BLOWFISH": -// case "RIJNDAEL": -// case "SKIPJACK": -// case "TWOFISH": - - case "AES": - case "AES128": - case "AES192": - case "AES256": - return CreateIVOctetString(random, 16); - case "CAMELLIA": - case "CAMELLIA128": - case "CAMELLIA192": - case "CAMELLIA256": - return CreateIVOctetString(random, 16); - case "CAST5": - return new Cast5CbcParameters(CreateIV(random, 8), 128); - case "DES": - case "DESEDE": - case "DESEDE3": - return CreateIVOctetString(random, 8); - case "IDEA": - return new IdeaCbcPar(CreateIV(random, 8)); - case "NOEKEON": - return CreateIVOctetString(random, 16); - case "RC2": - return new RC2CbcParameter(CreateIV(random, 8)); - case "SEED": - return CreateIVOctetString(random, 16); - } - - throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); - } - - private static Asn1OctetString CreateIVOctetString( - SecureRandom random, - int ivLength) - { - return new DerOctetString(CreateIV(random, ivLength)); - } - - private static byte[] CreateIV( - SecureRandom random, - int ivLength) - { - byte[] iv = new byte[ivLength]; - random.NextBytes(iv); - return iv; - } - } -} +using System; +using System.Collections; +using System.Globalization; + +using Org.BouncyCastle.Asn1; +using Org.BouncyCastle.Asn1.CryptoPro; +using Org.BouncyCastle.Asn1.Kisa; +using Org.BouncyCastle.Asn1.Misc; +using Org.BouncyCastle.Asn1.Nist; +using Org.BouncyCastle.Asn1.Ntt; +using Org.BouncyCastle.Asn1.Oiw; +using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; + +namespace Org.BouncyCastle.Security +{ + public sealed class ParameterUtilities + { + private ParameterUtilities() + { + } + + private static readonly Hashtable algorithms = new Hashtable(); + + static ParameterUtilities() + { + AddAlgorithm("AES", + "AESWRAP"); + AddAlgorithm("AES128", + "2.16.840.1.101.3.4.2", + NistObjectIdentifiers.IdAes128Cbc, + NistObjectIdentifiers.IdAes128Cfb, + NistObjectIdentifiers.IdAes128Ecb, + NistObjectIdentifiers.IdAes128Ofb, + NistObjectIdentifiers.IdAes128Wrap); + AddAlgorithm("AES192", + "2.16.840.1.101.3.4.22", + NistObjectIdentifiers.IdAes192Cbc, + NistObjectIdentifiers.IdAes192Cfb, + NistObjectIdentifiers.IdAes192Ecb, + NistObjectIdentifiers.IdAes192Ofb, + NistObjectIdentifiers.IdAes192Wrap); + AddAlgorithm("AES256", + "2.16.840.1.101.3.4.42", + NistObjectIdentifiers.IdAes256Cbc, + NistObjectIdentifiers.IdAes256Cfb, + NistObjectIdentifiers.IdAes256Ecb, + NistObjectIdentifiers.IdAes256Ofb, + NistObjectIdentifiers.IdAes256Wrap); + AddAlgorithm("BLOWFISH", + "1.3.6.1.4.1.3029.1.2"); + AddAlgorithm("CAMELLIA", + "CAMELLIAWRAP"); + AddAlgorithm("CAMELLIA128", + NttObjectIdentifiers.IdCamellia128Cbc, + NttObjectIdentifiers.IdCamellia128Wrap); + AddAlgorithm("CAMELLIA192", + NttObjectIdentifiers.IdCamellia192Cbc, + NttObjectIdentifiers.IdCamellia192Wrap); + AddAlgorithm("CAMELLIA256", + NttObjectIdentifiers.IdCamellia256Cbc, + NttObjectIdentifiers.IdCamellia256Wrap); + AddAlgorithm("CAST5", + "1.2.840.113533.7.66.10"); + AddAlgorithm("CAST6"); + AddAlgorithm("DES", + OiwObjectIdentifiers.DesCbc, + OiwObjectIdentifiers.DesCfb, + OiwObjectIdentifiers.DesEcb, + OiwObjectIdentifiers.DesOfb); + AddAlgorithm("DESEDE", + "DESEDEWRAP", + OiwObjectIdentifiers.DesEde, + PkcsObjectIdentifiers.IdAlgCms3DesWrap); + AddAlgorithm("DESEDE3", + PkcsObjectIdentifiers.DesEde3Cbc); + AddAlgorithm("GOST28147", + "GOST", + "GOST-28147", + CryptoProObjectIdentifiers.GostR28147Cbc); + AddAlgorithm("HC128"); + AddAlgorithm("HC256"); + AddAlgorithm("IDEA", + "1.3.6.1.4.1.188.7.1.1.2"); + AddAlgorithm("NOEKEON"); + AddAlgorithm("RC2", + PkcsObjectIdentifiers.RC2Cbc, + PkcsObjectIdentifiers.IdAlgCmsRC2Wrap); + AddAlgorithm("RC4", + "ARC4", + "1.2.840.113549.3.4"); + AddAlgorithm("RC5", + "RC5-32"); + AddAlgorithm("RC5-64"); + AddAlgorithm("RC6"); + AddAlgorithm("RIJNDAEL"); + AddAlgorithm("SALSA20"); + AddAlgorithm("SEED", + KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap, + KisaObjectIdentifiers.IdSeedCbc); + AddAlgorithm("SERPENT"); + AddAlgorithm("SKIPJACK"); + AddAlgorithm("TEA"); + AddAlgorithm("TWOFISH"); + AddAlgorithm("VMPC"); + AddAlgorithm("VMPC-KSA3"); + AddAlgorithm("XTEA"); + } + + private static void AddAlgorithm( + string canonicalName, + params object[] aliases) + { + algorithms[canonicalName] = canonicalName; + + foreach (object alias in aliases) + { + algorithms[alias.ToString()] = canonicalName; + } + } + + public static string GetCanonicalAlgorithmName( + string algorithm) + { + return (string) algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)]; + } + + public static KeyParameter CreateKeyParameter( + DerObjectIdentifier algOid, + byte[] keyBytes) + { + return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length); + } + + public static KeyParameter CreateKeyParameter( + string algorithm, + byte[] keyBytes) + { + return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length); + } + + public static KeyParameter CreateKeyParameter( + DerObjectIdentifier algOid, + byte[] keyBytes, + int offset, + int length) + { + return CreateKeyParameter(algOid.Id, keyBytes, offset, length); + } + + public static KeyParameter CreateKeyParameter( + string algorithm, + byte[] keyBytes, + int offset, + int length) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + string canonical = GetCanonicalAlgorithmName(algorithm); + + if (canonical == null) + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + + switch (canonical) + { + case "DES": + return new DesParameters(keyBytes, offset, length); + case "DESEDE": + case "DESEDE3": + return new DesEdeParameters(keyBytes, offset, length); + case "RC2": + return new RC2Parameters(keyBytes, offset, length); + default: + return new KeyParameter(keyBytes, offset, length); + } + } + + public static ICipherParameters GetCipherParameters( + DerObjectIdentifier algOid, + ICipherParameters key, + Asn1Object asn1Params) + { + return GetCipherParameters(algOid.Id, key, asn1Params); + } + + public static ICipherParameters GetCipherParameters( + string algorithm, + ICipherParameters key, + Asn1Object asn1Params) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + string canonical = GetCanonicalAlgorithmName(algorithm); + + if (canonical == null) + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + + byte[] iv = null; + + try + { + switch (canonical) + { + case "AES": + case "AES128": + case "AES192": + case "AES256": + case "BLOWFISH": + case "CAMELLIA": + case "CAMELLIA128": + case "CAMELLIA192": + case "CAMELLIA256": + case "DES": + case "DESEDE": + case "DESEDE3": + case "NOEKEON": + case "RIJNDAEL": + case "SEED": + case "SKIPJACK": + case "TWOFISH": + iv = ((Asn1OctetString) asn1Params).GetOctets(); + break; + case "RC2": + iv = RC2CbcParameter.GetInstance(asn1Params).GetIV(); + break; + case "IDEA": + iv = IdeaCbcPar.GetInstance(asn1Params).GetIV(); + break; + case "CAST5": + iv = Cast5CbcParameters.GetInstance(asn1Params).GetIV(); + break; + } + } + catch (Exception e) + { + throw new ArgumentException("Could not process ASN.1 parameters", e); + } + + if (iv != null) + { + return new ParametersWithIV(key, iv); + } + + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + } + + public static Asn1Encodable GenerateParameters( + DerObjectIdentifier algID, + SecureRandom random) + { + return GenerateParameters(algID.Id, random); + } + + public static Asn1Encodable GenerateParameters( + string algorithm, + SecureRandom random) + { + if (algorithm == null) + throw new ArgumentNullException("algorithm"); + + string canonical = GetCanonicalAlgorithmName(algorithm); + + if (canonical == null) + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + + switch (canonical) + { + // TODO These algorithms support an IV (see GetCipherParameters) + // but JCE doesn't seem to provide an AlgorithmParametersGenerator for them +// case "RIJNDAEL": +// case "SKIPJACK": +// case "TWOFISH": + + case "AES": + case "AES128": + case "AES192": + case "AES256": + return CreateIVOctetString(random, 16); + case "BLOWFISH": + return CreateIVOctetString(random, 8); + case "CAMELLIA": + case "CAMELLIA128": + case "CAMELLIA192": + case "CAMELLIA256": + return CreateIVOctetString(random, 16); + case "CAST5": + return new Cast5CbcParameters(CreateIV(random, 8), 128); + case "DES": + case "DESEDE": + case "DESEDE3": + return CreateIVOctetString(random, 8); + case "IDEA": + return new IdeaCbcPar(CreateIV(random, 8)); + case "NOEKEON": + return CreateIVOctetString(random, 16); + case "RC2": + return new RC2CbcParameter(CreateIV(random, 8)); + case "SEED": + return CreateIVOctetString(random, 16); + } + + throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised."); + } + + private static Asn1OctetString CreateIVOctetString( + SecureRandom random, + int ivLength) + { + return new DerOctetString(CreateIV(random, ivLength)); + } + + private static byte[] CreateIV( + SecureRandom random, + int ivLength) + { + byte[] iv = new byte[ivLength]; + random.NextBytes(iv); + return iv; + } + } +} diff --git a/src/core/srcbc/security/PrivateKeyFactory.cs b/src/core/srcbc/security/PrivateKeyFactory.cs index 7ace163..90d68e6 100644 --- a/src/core/srcbc/security/PrivateKeyFactory.cs +++ b/src/core/srcbc/security/PrivateKeyFactory.cs @@ -47,7 +47,11 @@ namespace Org.BouncyCastle.Security AlgorithmIdentifier algID = keyInfo.AlgorithmID; DerObjectIdentifier algOid = algID.ObjectID; - if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption)) + // TODO See RSAUtil.isRsaOid in Java build + if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) + || algOid.Equals(X509ObjectIdentifiers.IdEARsa) + || algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) + || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) { RsaPrivateKeyStructure keyStructure = new RsaPrivateKeyStructure( Asn1Sequence.GetInstance(keyInfo.PrivateKey)); diff --git a/src/core/srcbc/security/PublicKeyFactory.cs b/src/core/srcbc/security/PublicKeyFactory.cs index a38e58e..a8f16f2 100644 --- a/src/core/srcbc/security/PublicKeyFactory.cs +++ b/src/core/srcbc/security/PublicKeyFactory.cs @@ -47,8 +47,11 @@ namespace Org.BouncyCastle.Security AlgorithmIdentifier algID = keyInfo.AlgorithmID; DerObjectIdentifier algOid = algID.ObjectID; + // TODO See RSAUtil.isRsaOid in Java build if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) - || algOid.Equals(X509ObjectIdentifiers.IdEARsa)) + || algOid.Equals(X509ObjectIdentifiers.IdEARsa) + || algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) + || algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) { RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance( keyInfo.GetPublicKey());