123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using System.Collections;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.CryptoPro;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Kisa;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nsri;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Ntt;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Oiw;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Encodings;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Paddings;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Security
- {
- /// <remarks>
- /// Cipher Utility class contains methods that can not be specifically grouped into other classes.
- /// </remarks>
- public sealed class CipherUtilities
- {
- private enum CipherAlgorithm {
- AES,
- ARC4,
- ARIA,
- BLOWFISH,
- CAMELLIA,
- CAST5,
- CAST6,
- CHACHA,
- CHACHA20_POLY1305,
- CHACHA7539,
- DES,
- DESEDE,
- ELGAMAL,
- GOST28147,
- HC128,
- HC256,
- IDEA,
- NOEKEON,
- PBEWITHSHAAND128BITRC4,
- PBEWITHSHAAND40BITRC4,
- RC2,
- RC5,
- RC5_64,
- RC6,
- RIJNDAEL,
- RSA,
- SALSA20,
- SEED,
- SERPENT,
- SKIPJACK,
- SM4,
- TEA,
- THREEFISH_256,
- THREEFISH_512,
- THREEFISH_1024,
- TNEPRES,
- TWOFISH,
- VMPC,
- VMPC_KSA3,
- XTEA,
- };
- private enum CipherMode { ECB, NONE, CBC, CCM, CFB, CTR, CTS, EAX, GCM, GOFB, OCB, OFB, OPENPGPCFB, SIC };
- private enum CipherPadding
- {
- NOPADDING,
- RAW,
- ISO10126PADDING,
- ISO10126D2PADDING,
- ISO10126_2PADDING,
- ISO7816_4PADDING,
- ISO9797_1PADDING,
- ISO9796_1,
- ISO9796_1PADDING,
- OAEP,
- OAEPPADDING,
- OAEPWITHMD5ANDMGF1PADDING,
- OAEPWITHSHA1ANDMGF1PADDING,
- OAEPWITHSHA_1ANDMGF1PADDING,
- OAEPWITHSHA224ANDMGF1PADDING,
- OAEPWITHSHA_224ANDMGF1PADDING,
- OAEPWITHSHA256ANDMGF1PADDING,
- OAEPWITHSHA_256ANDMGF1PADDING,
- OAEPWITHSHA256ANDMGF1WITHSHA256PADDING,
- OAEPWITHSHA_256ANDMGF1WITHSHA_256PADDING,
- OAEPWITHSHA256ANDMGF1WITHSHA1PADDING,
- OAEPWITHSHA_256ANDMGF1WITHSHA_1PADDING,
- OAEPWITHSHA384ANDMGF1PADDING,
- OAEPWITHSHA_384ANDMGF1PADDING,
- OAEPWITHSHA512ANDMGF1PADDING,
- OAEPWITHSHA_512ANDMGF1PADDING,
- PKCS1,
- PKCS1PADDING,
- PKCS5,
- PKCS5PADDING,
- PKCS7,
- PKCS7PADDING,
- TBCPADDING,
- WITHCTS,
- X923PADDING,
- ZEROBYTEPADDING,
- };
- private static readonly IDictionary algorithms = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
- private static readonly IDictionary oids = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
- static CipherUtilities()
- {
- // Signal to obfuscation tools not to change enum constants
- ((CipherAlgorithm)Enums.GetArbitraryValue(typeof(CipherAlgorithm))).ToString();
- ((CipherMode)Enums.GetArbitraryValue(typeof(CipherMode))).ToString();
- ((CipherPadding)Enums.GetArbitraryValue(typeof(CipherPadding))).ToString();
- // TODO Flesh out the list of aliases
- algorithms[NistObjectIdentifiers.IdAes128Cbc.Id] = "AES/CBC/PKCS7PADDING";
- algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "AES/CBC/PKCS7PADDING";
- algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "AES/CBC/PKCS7PADDING";
- algorithms[NistObjectIdentifiers.IdAes128Ccm.Id] = "AES/CCM/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes192Ccm.Id] = "AES/CCM/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes256Ccm.Id] = "AES/CCM/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes128Cfb.Id] = "AES/CFB/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes192Cfb.Id] = "AES/CFB/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes256Cfb.Id] = "AES/CFB/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes128Ecb.Id] = "AES/ECB/PKCS7PADDING";
- algorithms[NistObjectIdentifiers.IdAes192Ecb.Id] = "AES/ECB/PKCS7PADDING";
- algorithms[NistObjectIdentifiers.IdAes256Ecb.Id] = "AES/ECB/PKCS7PADDING";
- algorithms["AES//PKCS7"] = "AES/ECB/PKCS7PADDING";
- algorithms["AES//PKCS7PADDING"] = "AES/ECB/PKCS7PADDING";
- algorithms["AES//PKCS5"] = "AES/ECB/PKCS7PADDING";
- algorithms["AES//PKCS5PADDING"] = "AES/ECB/PKCS7PADDING";
- algorithms[NistObjectIdentifiers.IdAes128Gcm.Id] = "AES/GCM/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes192Gcm.Id] = "AES/GCM/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes256Gcm.Id] = "AES/GCM/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes128Ofb.Id] = "AES/OFB/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes192Ofb.Id] = "AES/OFB/NOPADDING";
- algorithms[NistObjectIdentifiers.IdAes256Ofb.Id] = "AES/OFB/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria128_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
- algorithms[NsriObjectIdentifiers.id_aria192_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
- algorithms[NsriObjectIdentifiers.id_aria256_cbc.Id] = "ARIA/CBC/PKCS7PADDING";
- algorithms[NsriObjectIdentifiers.id_aria128_ccm.Id] = "ARIA/CCM/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria192_ccm.Id] = "ARIA/CCM/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria256_ccm.Id] = "ARIA/CCM/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria128_cfb.Id] = "ARIA/CFB/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria192_cfb.Id] = "ARIA/CFB/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria256_cfb.Id] = "ARIA/CFB/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria128_ctr.Id] = "ARIA/CTR/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria192_ctr.Id] = "ARIA/CTR/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria256_ctr.Id] = "ARIA/CTR/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria128_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
- algorithms[NsriObjectIdentifiers.id_aria192_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
- algorithms[NsriObjectIdentifiers.id_aria256_ecb.Id] = "ARIA/ECB/PKCS7PADDING";
- algorithms["ARIA//PKCS7"] = "ARIA/ECB/PKCS7PADDING";
- algorithms["ARIA//PKCS7PADDING"] = "ARIA/ECB/PKCS7PADDING";
- algorithms["ARIA//PKCS5"] = "ARIA/ECB/PKCS7PADDING";
- algorithms["ARIA//PKCS5PADDING"] = "ARIA/ECB/PKCS7PADDING";
- algorithms[NsriObjectIdentifiers.id_aria128_gcm.Id] = "ARIA/GCM/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria192_gcm.Id] = "ARIA/GCM/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria256_gcm.Id] = "ARIA/GCM/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria128_ofb.Id] = "ARIA/OFB/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria192_ofb.Id] = "ARIA/OFB/NOPADDING";
- algorithms[NsriObjectIdentifiers.id_aria256_ofb.Id] = "ARIA/OFB/NOPADDING";
- algorithms["RSA/ECB/PKCS1"] = "RSA//PKCS1PADDING";
- algorithms["RSA/ECB/PKCS1PADDING"] = "RSA//PKCS1PADDING";
- algorithms[PkcsObjectIdentifiers.RsaEncryption.Id] = "RSA//PKCS1PADDING";
- algorithms[PkcsObjectIdentifiers.IdRsaesOaep.Id] = "RSA//OAEPPADDING";
- 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["TDEA"] = "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";
- algorithms["CHACHA20"] = "CHACHA7539";
- algorithms[PkcsObjectIdentifiers.IdAlgAeadChaCha20Poly1305.Id] = "CHACHA20-POLY1305";
- }
- private CipherUtilities()
- {
- }
- /// <summary>
- /// Returns a ObjectIdentifier for a give encoding.
- /// </summary>
- /// <param name="mechanism">A string representation of the encoding.</param>
- /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
- // TODO Don't really want to support this
- public static DerObjectIdentifier GetObjectIdentifier(
- string mechanism)
- {
- if (mechanism == null)
- throw new ArgumentNullException("mechanism");
- mechanism = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(mechanism);
- 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 = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm);
- {
- 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 (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(algorithm, "PBE"))
- {
- if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(algorithm, "-CBC"))
- {
- if (algorithm == "PBEWITHSHA1ANDDES-CBC")
- {
- return new PaddedBufferedBlockCipher(
- new CbcBlockCipher(new DesEngine()));
- }
- else if (algorithm == "PBEWITHSHA1ANDRC2-CBC")
- {
- return new PaddedBufferedBlockCipher(
- new CbcBlockCipher(new RC2Engine()));
- }
- else if (Strings.IsOneOf(algorithm,
- "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"))
- {
- return new PaddedBufferedBlockCipher(
- new CbcBlockCipher(new DesEdeEngine()));
- }
- else if (Strings.IsOneOf(algorithm,
- "PBEWITHSHAAND128BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"))
- {
- return new PaddedBufferedBlockCipher(
- new CbcBlockCipher(new RC2Engine()));
- }
- }
- else if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(algorithm, "-BC") || BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.EndsWith(algorithm, "-OPENSSL"))
- {
- if (Strings.IsOneOf(algorithm,
- "PBEWITHSHAAND128BITAES-CBC-BC",
- "PBEWITHSHAAND192BITAES-CBC-BC",
- "PBEWITHSHAAND256BITAES-CBC-BC",
- "PBEWITHSHA256AND128BITAES-CBC-BC",
- "PBEWITHSHA256AND192BITAES-CBC-BC",
- "PBEWITHSHA256AND256BITAES-CBC-BC",
- "PBEWITHMD5AND128BITAES-CBC-OPENSSL",
- "PBEWITHMD5AND192BITAES-CBC-OPENSSL",
- "PBEWITHMD5AND256BITAES-CBC-OPENSSL"))
- {
- return new PaddedBufferedBlockCipher(
- new CbcBlockCipher(new AesEngine()));
- }
- }
- }
- string[] parts = algorithm.Split('/');
- IAeadCipher aeadCipher = null;
- IBlockCipher blockCipher = null;
- IAsymmetricBlockCipher asymBlockCipher = null;
- IStreamCipher streamCipher = null;
- string algorithmName = parts[0];
- {
- string aliased = (string)algorithms[algorithmName];
- if (aliased != null)
- algorithmName = aliased;
- }
- CipherAlgorithm cipherAlgorithm;
- try
- {
- cipherAlgorithm = (CipherAlgorithm)Enums.GetEnumValue(typeof(CipherAlgorithm), algorithmName);
- }
- catch (ArgumentException)
- {
- throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
- }
- switch (cipherAlgorithm)
- {
- case CipherAlgorithm.AES:
- blockCipher = new AesEngine();
- break;
- case CipherAlgorithm.ARC4:
- streamCipher = new RC4Engine();
- break;
- case CipherAlgorithm.ARIA:
- blockCipher = new AriaEngine();
- break;
- case CipherAlgorithm.BLOWFISH:
- blockCipher = new BlowfishEngine();
- break;
- case CipherAlgorithm.CAMELLIA:
- blockCipher = new CamelliaEngine();
- break;
- case CipherAlgorithm.CAST5:
- blockCipher = new Cast5Engine();
- break;
- case CipherAlgorithm.CAST6:
- blockCipher = new Cast6Engine();
- break;
- case CipherAlgorithm.CHACHA:
- streamCipher = new ChaChaEngine();
- break;
- case CipherAlgorithm.CHACHA20_POLY1305:
- aeadCipher = new ChaCha20Poly1305();
- break;
- case CipherAlgorithm.CHACHA7539:
- streamCipher = new ChaCha7539Engine();
- break;
- case CipherAlgorithm.DES:
- blockCipher = new DesEngine();
- break;
- case CipherAlgorithm.DESEDE:
- blockCipher = new DesEdeEngine();
- break;
- case CipherAlgorithm.ELGAMAL:
- asymBlockCipher = new ElGamalEngine();
- break;
- case CipherAlgorithm.GOST28147:
- blockCipher = new Gost28147Engine();
- break;
- case CipherAlgorithm.HC128:
- streamCipher = new HC128Engine();
- break;
- case CipherAlgorithm.HC256:
- streamCipher = new HC256Engine();
- break;
- case CipherAlgorithm.IDEA:
- blockCipher = new IdeaEngine();
- break;
- case CipherAlgorithm.NOEKEON:
- blockCipher = new NoekeonEngine();
- break;
- case CipherAlgorithm.PBEWITHSHAAND128BITRC4:
- case CipherAlgorithm.PBEWITHSHAAND40BITRC4:
- streamCipher = new RC4Engine();
- break;
- case CipherAlgorithm.RC2:
- blockCipher = new RC2Engine();
- break;
- case CipherAlgorithm.RC5:
- blockCipher = new RC532Engine();
- break;
- case CipherAlgorithm.RC5_64:
- blockCipher = new RC564Engine();
- break;
- case CipherAlgorithm.RC6:
- blockCipher = new RC6Engine();
- break;
- case CipherAlgorithm.RIJNDAEL:
- blockCipher = new RijndaelEngine();
- break;
- case CipherAlgorithm.RSA:
- asymBlockCipher = new RsaBlindedEngine();
- break;
- case CipherAlgorithm.SALSA20:
- streamCipher = new Salsa20Engine();
- break;
- case CipherAlgorithm.SEED:
- blockCipher = new SeedEngine();
- break;
- case CipherAlgorithm.SERPENT:
- blockCipher = new SerpentEngine();
- break;
- case CipherAlgorithm.SKIPJACK:
- blockCipher = new SkipjackEngine();
- break;
- case CipherAlgorithm.SM4:
- blockCipher = new SM4Engine();
- break;
- case CipherAlgorithm.TEA:
- blockCipher = new TeaEngine();
- break;
- case CipherAlgorithm.THREEFISH_256:
- blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
- break;
- case CipherAlgorithm.THREEFISH_512:
- blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
- break;
- case CipherAlgorithm.THREEFISH_1024:
- blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
- break;
- case CipherAlgorithm.TNEPRES:
- blockCipher = new TnepresEngine();
- break;
- case CipherAlgorithm.TWOFISH:
- blockCipher = new TwofishEngine();
- break;
- case CipherAlgorithm.VMPC:
- streamCipher = new VmpcEngine();
- break;
- case CipherAlgorithm.VMPC_KSA3:
- streamCipher = new VmpcKsa3Engine();
- break;
- case CipherAlgorithm.XTEA:
- blockCipher = new XteaEngine();
- break;
- default:
- throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
- }
- if (aeadCipher != null)
- {
- if (parts.Length > 1)
- throw new ArgumentException("Modes and paddings cannot be applied to AEAD ciphers");
- return new BufferedAeadCipher(aeadCipher);
- }
- 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");
- string paddingName = parts[2];
- CipherPadding cipherPadding;
- if (paddingName == "")
- {
- cipherPadding = CipherPadding.RAW;
- }
- else if (paddingName == "X9.23PADDING")
- {
- cipherPadding = CipherPadding.X923PADDING;
- }
- else
- {
- try
- {
- cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), paddingName);
- }
- catch (ArgumentException)
- {
- throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
- }
- }
- switch (cipherPadding)
- {
- case CipherPadding.NOPADDING:
- padded = false;
- break;
- case CipherPadding.RAW:
- break;
- case CipherPadding.ISO10126PADDING:
- case CipherPadding.ISO10126D2PADDING:
- case CipherPadding.ISO10126_2PADDING:
- padding = new ISO10126d2Padding();
- break;
- case CipherPadding.ISO7816_4PADDING:
- case CipherPadding.ISO9797_1PADDING:
- padding = new ISO7816d4Padding();
- break;
- case CipherPadding.ISO9796_1:
- case CipherPadding.ISO9796_1PADDING:
- asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
- break;
- case CipherPadding.OAEP:
- case CipherPadding.OAEPPADDING:
- asymBlockCipher = new OaepEncoding(asymBlockCipher);
- break;
- case CipherPadding.OAEPWITHMD5ANDMGF1PADDING:
- asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
- break;
- case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING:
- case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING:
- asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
- break;
- case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING:
- case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING:
- asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
- break;
- case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING:
- case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING:
- case CipherPadding.OAEPWITHSHA256ANDMGF1WITHSHA256PADDING:
- case CipherPadding.OAEPWITHSHA_256ANDMGF1WITHSHA_256PADDING:
- asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
- break;
- case CipherPadding.OAEPWITHSHA256ANDMGF1WITHSHA1PADDING:
- case CipherPadding.OAEPWITHSHA_256ANDMGF1WITHSHA_1PADDING:
- asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest(), new Sha1Digest(), null);
- break;
- case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING:
- case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING:
- asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
- break;
- case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING:
- case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING:
- asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
- break;
- case CipherPadding.PKCS1:
- case CipherPadding.PKCS1PADDING:
- asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
- break;
- case CipherPadding.PKCS5:
- case CipherPadding.PKCS5PADDING:
- case CipherPadding.PKCS7:
- case CipherPadding.PKCS7PADDING:
- padding = new Pkcs7Padding();
- break;
- case CipherPadding.TBCPADDING:
- padding = new TbcPadding();
- break;
- case CipherPadding.WITHCTS:
- cts = true;
- break;
- case CipherPadding.X923PADDING:
- padding = new X923Padding();
- break;
- case CipherPadding.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;
- try
- {
- CipherMode cipherMode = modeName == ""
- ? CipherMode.NONE
- : (CipherMode)Enums.GetEnumValue(typeof(CipherMode), modeName);
- switch (cipherMode)
- {
- case CipherMode.ECB:
- case CipherMode.NONE:
- break;
- case CipherMode.CBC:
- blockCipher = 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));
-
- blockCipher = new CfbBlockCipher(blockCipher, bits);
- break;
- }
- case CipherMode.CTR:
- blockCipher = new SicBlockCipher(blockCipher);
- break;
- case CipherMode.CTS:
- cts = true;
- blockCipher = new CbcBlockCipher(blockCipher);
- break;
- case CipherMode.EAX:
- aeadBlockCipher = new EaxBlockCipher(blockCipher);
- break;
- case CipherMode.GCM:
- aeadBlockCipher = new GcmBlockCipher(blockCipher);
- break;
- case CipherMode.GOFB:
- blockCipher = 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));
-
- blockCipher = new OfbBlockCipher(blockCipher, bits);
- break;
- }
- case CipherMode.OPENPGPCFB:
- blockCipher = 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)");
- }
- blockCipher = new SicBlockCipher(blockCipher);
- break;
- default:
- throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
- }
- }
- catch (ArgumentException)
- {
- 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 > 2 && 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 (padding != null)
- {
- return new PaddedBufferedBlockCipher(blockCipher, padding);
- }
- if (!padded || blockCipher.IsPartialBlockOkay)
- {
- return new BufferedBlockCipher(blockCipher);
- }
- 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;
- }
- private static IBlockCipher CreateBlockCipher(CipherAlgorithm cipherAlgorithm)
- {
- switch (cipherAlgorithm)
- {
- case CipherAlgorithm.AES: return new AesEngine();
- case CipherAlgorithm.ARIA: return new AriaEngine();
- case CipherAlgorithm.BLOWFISH: return new BlowfishEngine();
- case CipherAlgorithm.CAMELLIA: return new CamelliaEngine();
- case CipherAlgorithm.CAST5: return new Cast5Engine();
- case CipherAlgorithm.CAST6: return new Cast6Engine();
- case CipherAlgorithm.DES: return new DesEngine();
- case CipherAlgorithm.DESEDE: return new DesEdeEngine();
- case CipherAlgorithm.GOST28147: return new Gost28147Engine();
- case CipherAlgorithm.IDEA: return new IdeaEngine();
- case CipherAlgorithm.NOEKEON: return new NoekeonEngine();
- case CipherAlgorithm.RC2: return new RC2Engine();
- case CipherAlgorithm.RC5: return new RC532Engine();
- case CipherAlgorithm.RC5_64: return new RC564Engine();
- case CipherAlgorithm.RC6: return new RC6Engine();
- case CipherAlgorithm.RIJNDAEL: return new RijndaelEngine();
- case CipherAlgorithm.SEED: return new SeedEngine();
- case CipherAlgorithm.SERPENT: return new SerpentEngine();
- case CipherAlgorithm.SKIPJACK: return new SkipjackEngine();
- case CipherAlgorithm.SM4: return new SM4Engine();
- case CipherAlgorithm.TEA: return new TeaEngine();
- case CipherAlgorithm.THREEFISH_256: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
- case CipherAlgorithm.THREEFISH_512: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
- case CipherAlgorithm.THREEFISH_1024: return new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
- case CipherAlgorithm.TNEPRES: return new TnepresEngine();
- case CipherAlgorithm.TWOFISH: return new TwofishEngine();
- case CipherAlgorithm.XTEA: return new XteaEngine();
- default:
- throw new SecurityUtilityException("Cipher " + cipherAlgorithm + " not recognised or not a block cipher");
- }
- }
- }
- }
- #pragma warning restore
- #endif
|