You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
10 KiB
282 lines
10 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
using System.Collections; |
|
using System.Globalization; |
|
using System.Security.Cryptography; |
|
|
|
using BestHTTP.PlatformSupport.Memory; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Iana; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Misc; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Rosstandart; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Macs; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Paddings; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities; |
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Security |
|
{ |
|
/// <remarks> |
|
/// Utility class for creating HMac object from their names/Oids |
|
/// </remarks> |
|
public sealed class MacUtilities |
|
{ |
|
private MacUtilities() |
|
{ |
|
} |
|
|
|
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 MacUtilities() |
|
{ |
|
algorithms[IanaObjectIdentifiers.HmacMD5.Id] = "HMAC-MD5"; |
|
algorithms[IanaObjectIdentifiers.HmacRipeMD160.Id] = "HMAC-RIPEMD160"; |
|
algorithms[IanaObjectIdentifiers.HmacSha1.Id] = "HMAC-SHA1"; |
|
algorithms[IanaObjectIdentifiers.HmacTiger.Id] = "HMAC-TIGER"; |
|
|
|
algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "HMAC-SHA1"; |
|
algorithms[MiscObjectIdentifiers.HMAC_SHA1.Id] = "HMAC-SHA1"; |
|
algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "HMAC-SHA224"; |
|
algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "HMAC-SHA256"; |
|
algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "HMAC-SHA384"; |
|
algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "HMAC-SHA512"; |
|
|
|
algorithms[NistObjectIdentifiers.IdHMacWithSha3_224.Id] = "HMAC-SHA3-224"; |
|
algorithms[NistObjectIdentifiers.IdHMacWithSha3_256.Id] = "HMAC-SHA3-256"; |
|
algorithms[NistObjectIdentifiers.IdHMacWithSha3_384.Id] = "HMAC-SHA3-384"; |
|
algorithms[NistObjectIdentifiers.IdHMacWithSha3_512.Id] = "HMAC-SHA3-512"; |
|
|
|
algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_256.Id] = "HMAC-GOST3411-2012-256"; |
|
algorithms[RosstandartObjectIdentifiers.id_tc26_hmac_gost_3411_12_512.Id] = "HMAC-GOST3411-2012-512"; |
|
|
|
// TODO AESMAC? |
|
|
|
algorithms["DES"] = "DESMAC"; |
|
algorithms["DES/CFB8"] = "DESMAC/CFB8"; |
|
algorithms["DES64"] = "DESMAC64"; |
|
algorithms["DESEDE"] = "DESEDEMAC"; |
|
algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDEMAC"; |
|
algorithms["DESEDE/CFB8"] = "DESEDEMAC/CFB8"; |
|
algorithms["DESISO9797MAC"] = "DESWITHISO9797"; |
|
algorithms["DESEDE64"] = "DESEDEMAC64"; |
|
|
|
algorithms["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; |
|
algorithms["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; |
|
algorithms["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING"; |
|
|
|
algorithms["ISO9797ALG3"] = "ISO9797ALG3MAC"; |
|
algorithms["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING"; |
|
|
|
algorithms["SKIPJACK"] = "SKIPJACKMAC"; |
|
algorithms["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8"; |
|
algorithms["IDEA"] = "IDEAMAC"; |
|
algorithms["IDEA/CFB8"] = "IDEAMAC/CFB8"; |
|
algorithms["RC2"] = "RC2MAC"; |
|
algorithms["RC2/CFB8"] = "RC2MAC/CFB8"; |
|
algorithms["RC5"] = "RC5MAC"; |
|
algorithms["RC5/CFB8"] = "RC5MAC/CFB8"; |
|
algorithms["GOST28147"] = "GOST28147MAC"; |
|
algorithms["VMPC"] = "VMPCMAC"; |
|
algorithms["VMPC-MAC"] = "VMPCMAC"; |
|
algorithms["SIPHASH"] = "SIPHASH-2-4"; |
|
|
|
algorithms["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1"; |
|
algorithms["1.3.14.3.2.26"] = "PBEWITHHMACSHA1"; |
|
} |
|
|
|
// /// <summary> |
|
// /// Returns a ObjectIdentifier for a given digest mechanism. |
|
// /// </summary> |
|
// /// <param name="mechanism">A string representation of the digest meanism.</param> |
|
// /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns> |
|
// public static DerObjectIdentifier GetObjectIdentifier( |
|
// string mechanism) |
|
// { |
|
// mechanism = (string) algorithms[BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(mechanism)]; |
|
// |
|
// if (mechanism != null) |
|
// { |
|
// return (DerObjectIdentifier)oids[mechanism]; |
|
// } |
|
// |
|
// return null; |
|
// } |
|
|
|
// public static ICollection Algorithms |
|
// { |
|
// get { return oids.Keys; } |
|
// } |
|
|
|
public static IMac GetMac( |
|
DerObjectIdentifier id) |
|
{ |
|
return GetMac(id.Id); |
|
} |
|
|
|
public static IMac GetMac( |
|
string algorithm) |
|
{ |
|
string upper = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.ToUpperInvariant(algorithm); |
|
|
|
string mechanism = (string) algorithms[upper]; |
|
|
|
if (mechanism == null) |
|
{ |
|
mechanism = upper; |
|
} |
|
|
|
if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "PBEWITH")) |
|
{ |
|
mechanism = mechanism.Substring("PBEWITH".Length); |
|
} |
|
|
|
if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC")) |
|
{ |
|
string digestName; |
|
if (BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC-") || BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.StartsWith(mechanism, "HMAC/")) |
|
{ |
|
digestName = mechanism.Substring(5); |
|
} |
|
else |
|
{ |
|
digestName = mechanism.Substring(4); |
|
} |
|
|
|
return new HMac(DigestUtilities.GetDigest(digestName)); |
|
} |
|
|
|
if (mechanism == "AESCMAC") |
|
{ |
|
return new CMac(new AesEngine()); |
|
} |
|
if (mechanism == "DESMAC") |
|
{ |
|
return new CbcBlockCipherMac(new DesEngine()); |
|
} |
|
if (mechanism == "DESMAC/CFB8") |
|
{ |
|
return new CfbBlockCipherMac(new DesEngine()); |
|
} |
|
if (mechanism == "DESMAC64") |
|
{ |
|
return new CbcBlockCipherMac(new DesEngine(), 64); |
|
} |
|
if (mechanism == "DESEDECMAC") |
|
{ |
|
return new CMac(new DesEdeEngine()); |
|
} |
|
if (mechanism == "DESEDEMAC") |
|
{ |
|
return new CbcBlockCipherMac(new DesEdeEngine()); |
|
} |
|
if (mechanism == "DESEDEMAC/CFB8") |
|
{ |
|
return new CfbBlockCipherMac(new DesEdeEngine()); |
|
} |
|
if (mechanism == "DESEDEMAC64") |
|
{ |
|
return new CbcBlockCipherMac(new DesEdeEngine(), 64); |
|
} |
|
if (mechanism == "DESEDEMAC64WITHISO7816-4PADDING") |
|
{ |
|
return new CbcBlockCipherMac(new DesEdeEngine(), 64, new ISO7816d4Padding()); |
|
} |
|
if (mechanism == "DESWITHISO9797" |
|
|| mechanism == "ISO9797ALG3MAC") |
|
{ |
|
return new ISO9797Alg3Mac(new DesEngine()); |
|
} |
|
if (mechanism == "ISO9797ALG3WITHISO7816-4PADDING") |
|
{ |
|
return new ISO9797Alg3Mac(new DesEngine(), new ISO7816d4Padding()); |
|
} |
|
if (mechanism == "SKIPJACKMAC") |
|
{ |
|
return new CbcBlockCipherMac(new SkipjackEngine()); |
|
} |
|
if (mechanism == "SKIPJACKMAC/CFB8") |
|
{ |
|
return new CfbBlockCipherMac(new SkipjackEngine()); |
|
} |
|
if (mechanism == "IDEAMAC") |
|
{ |
|
return new CbcBlockCipherMac(new IdeaEngine()); |
|
} |
|
if (mechanism == "IDEAMAC/CFB8") |
|
{ |
|
return new CfbBlockCipherMac(new IdeaEngine()); |
|
} |
|
if (mechanism == "RC2MAC") |
|
{ |
|
return new CbcBlockCipherMac(new RC2Engine()); |
|
} |
|
if (mechanism == "RC2MAC/CFB8") |
|
{ |
|
return new CfbBlockCipherMac(new RC2Engine()); |
|
} |
|
if (mechanism == "RC5MAC") |
|
{ |
|
return new CbcBlockCipherMac(new RC532Engine()); |
|
} |
|
if (mechanism == "RC5MAC/CFB8") |
|
{ |
|
return new CfbBlockCipherMac(new RC532Engine()); |
|
} |
|
if (mechanism == "GOST28147MAC") |
|
{ |
|
return new Gost28147Mac(); |
|
} |
|
if (mechanism == "VMPCMAC") |
|
{ |
|
return new VmpcMac(); |
|
} |
|
if (mechanism == "SIPHASH-2-4") |
|
{ |
|
return new SipHash(); |
|
} |
|
throw new SecurityUtilityException("Mac " + mechanism + " not recognised."); |
|
} |
|
|
|
public static string GetAlgorithmName( |
|
DerObjectIdentifier oid) |
|
{ |
|
return (string) algorithms[oid.Id]; |
|
} |
|
|
|
public static byte[] CalculateMac(string algorithm, ICipherParameters cp, byte[] input) |
|
{ |
|
IMac mac = GetMac(algorithm); |
|
mac.Init(cp); |
|
mac.BlockUpdate(input, 0, input.Length); |
|
return DoFinal(mac); |
|
} |
|
|
|
public static byte[] DoFinal(IMac mac) |
|
{ |
|
byte[] b = new byte[mac.GetMacSize()]; |
|
mac.DoFinal(b, 0); |
|
return b; |
|
} |
|
|
|
public static BufferSegment DoFinalOptimized(IMac mac) |
|
{ |
|
int length = mac.GetMacSize(); |
|
byte[] b = BufferPool.Get(length, true); |
|
mac.DoFinal(b, 0); |
|
return new BufferSegment(b, 0, length); |
|
} |
|
|
|
public static byte[] DoFinal(IMac mac, byte[] input) |
|
{ |
|
mac.BlockUpdate(input, 0, input.Length); |
|
return DoFinal(mac); |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|