diff options
author | bartonjs <jbarton@microsoft.com> | 2015-09-30 17:51:20 +0300 |
---|---|---|
committer | bartonjs <jbarton@microsoft.com> | 2015-10-03 05:18:39 +0300 |
commit | 9d76e965d781a12fabb2eaa5d503119912f8ebec (patch) | |
tree | c2b4d9c8bce51f9dc9f98781e3674d58636f4fef /src/System.Security.Cryptography.Encoding | |
parent | c942505ba2012140fefad34128347e256ba88683 (diff) |
Use a fixed dictionary for common OIDs to remove platform differences.
Use a classic Dictionary for the most common (non-localized) OID values, then a ConcurrentDictionary for on-the-fly memoization to save on p/invoke and repeated parsing.
The "common values" dictionaries ensure that Windows FriendlyName values resolve on Unix, and that OID -> FriendlyName gives a consistent result for those cases where someone is likely to have tried writing matching logic.
The Oid class tests were refactored and spruced up a bit as a part of this change.
Diffstat (limited to 'src/System.Security.Cryptography.Encoding')
7 files changed, 664 insertions, 169 deletions
diff --git a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs index d7afa49349..d2195e845f 100644 --- a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs +++ b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs @@ -2,33 +2,37 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Diagnostics; +using System.Runtime.InteropServices; using System.Security.Cryptography; -using System.Text; namespace Internal.Cryptography { internal static partial class OidLookup { - private static string NativeOidToFriendlyName(string oid, OidGroup oidGroup, bool fallBackToAllGroups) + private static bool ShouldUseCache(OidGroup oidGroup) { - // We're going to call OBJ_txt2nid, then OBJ_nid2obj. Anyone proficient in factor/label reduction - // would see that this should be equivalent to OBJ_txt2obj, but it isn't. - // - // OBJ_txt2obj, when given an OID value dotted string will decode the dotted string and return - // a blank(ish) object (which would need to be freed). We could then pass that to OBJ_obj2nid to - // look up the internal identifier. Then, if we got a NID which wasn't NID_undef we would know - // there was a match, and could call OBJ_nid2obj to get the shared pointer to the definition. - // - // In this case, the composition of functions that we want is OBJ_obj2nid(OBJ_txt2obj) => OBJ_txt2nid. + return true; + } - int nid = Interop.libcrypto.OBJ_txt2nid(oid); + private static string NativeOidToFriendlyName(string oid, OidGroup oidGroup, bool fallBackToAllGroups) + { + IntPtr friendlyNamePtr = IntPtr.Zero; + int result = Interop.Crypto.LookupFriendlyNameByOid(oid, ref friendlyNamePtr); - if (nid == Interop.libcrypto.NID_undef) + switch (result) { - return null; - } + case 1: /* Success */ + Debug.Assert(friendlyNamePtr != IntPtr.Zero, "friendlyNamePtr != IntPtr.Zero"); - return Interop.libcrypto.OBJ_nid2ln(nid); + // The pointer is to a shared string, so marshalling it out is all that's required. + return Marshal.PtrToStringAnsi(friendlyNamePtr); + case -1: /* OpenSSL internal error */ + throw Interop.libcrypto.CreateOpenSslCryptographicException(); + default: + Debug.Assert(result == 0, "LookupFriendlyNameByOid returned unexpected result " + result); + return null; + } } private static string NativeFriendlyNameToOid(string friendlyName, OidGroup oidGroup, bool fallBackToAllGroups) @@ -55,19 +59,6 @@ namespace Internal.Cryptography return Interop.libcrypto.OBJ_obj2txt_helper(sharedObject); } - private static string FindFriendlyNameAlias(string userValue) - { - foreach (FriendlyNameAlias alias in s_friendlyNameAliases) - { - if (userValue.Equals(alias.Windows, StringComparison.OrdinalIgnoreCase)) - { - return alias.OpenSsl; - } - } - - return null; - } - // ----------------------------- // ---- PAL layer ends here ---- // ----------------------------- diff --git a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Windows.cs b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Windows.cs index ad6d19d897..74b82906cf 100644 --- a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Windows.cs +++ b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Windows.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; using System.Security.Cryptography; using Internal.NativeCrypto; @@ -10,6 +9,11 @@ namespace Internal.Cryptography { internal static partial class OidLookup { + private static bool ShouldUseCache(OidGroup oidGroup) + { + return oidGroup == OidGroup.All; + } + private static string NativeOidToFriendlyName(string oid, OidGroup oidGroup, bool fallBackToAllGroups) { CRYPT_OID_INFO oidInfo = OidInfo.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid, oidGroup, fallBackToAllGroups); @@ -22,19 +26,6 @@ namespace Internal.Cryptography return oidInfo.OID; } - private static string FindFriendlyNameAlias(string userValue) - { - foreach (FriendlyNameAlias alias in s_friendlyNameAliases) - { - if (userValue.Equals(alias.OpenSsl, StringComparison.OrdinalIgnoreCase)) - { - return alias.Windows; - } - } - - return null; - } - // ----------------------------- // ---- PAL layer ends here ---- // ----------------------------- diff --git a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs index 44ec448233..edda0196aa 100644 --- a/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs +++ b/src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs @@ -2,39 +2,20 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Linq; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Security.Cryptography; namespace Internal.Cryptography { internal static partial class OidLookup { - private struct FriendlyNameAlias - { - internal string Windows { get; set; } - internal string OpenSsl { get; set; } - } - - // The Windows cryptography API "Friendly Names" don't use the same name as the OIDs were given - // in their declaring RFCs. If a .NET developer learned to call the algorithm "sha1RSA" then we - // want to understand that it should be called "sha1WithRSAEncryption" when calling into OpenSSL. - // - // The canonical form of the Windows versions come from https://msdn.microsoft.com/en-us/library/ff635603.aspx - private static readonly FriendlyNameAlias[] s_friendlyNameAliases = - { - new FriendlyNameAlias { Windows = "RSA", OpenSsl = "rsaEncryption" }, // RFC 2313 - new FriendlyNameAlias { Windows = "md2RSA", OpenSsl = "md2WithRSAEncryption" }, // RFC 2313 - new FriendlyNameAlias { Windows = "md4RSA", OpenSsl = "md4WithRSAEncryption" }, // RFC 2313 - new FriendlyNameAlias { Windows = "md5RSA", OpenSsl = "md5WithRSAEncryption" }, // RFC 2313 - new FriendlyNameAlias { Windows = "sha1RSA", OpenSsl = "sha1WithRSAEncryption" }, // RFC 3447 - new FriendlyNameAlias { Windows = "sha256RSA", OpenSsl = "sha256WithRSAEncryption" }, // RFC 3447 - new FriendlyNameAlias { Windows = "sha384RSA", OpenSsl = "sha384WithRSAEncryption" }, // RFC 3447 - new FriendlyNameAlias { Windows = "sha512RSA", OpenSsl = "sha512WithRSAEncryption" }, // RFC 3447 - - new FriendlyNameAlias { Windows = "DSA", OpenSsl = "dsaEncryption" }, // RFC 3370 calls this "id-dsa" - new FriendlyNameAlias { Windows = "sha1DSA", OpenSsl = "dsaWithSHA1" }, // RFC 3370 calls this "id-dsa-with-sha1" + private static readonly ConcurrentDictionary<string, string> s_lateBoundOidToFriendlyName = + new ConcurrentDictionary<string, string>(); - // We can keep going for as many things as we want to support. - }; + private static readonly ConcurrentDictionary<string, string> s_lateBoundFriendlyNameToOid = + new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase); // // Attempts to map a friendly name to an OID. Returns null if not a known name. @@ -44,7 +25,35 @@ namespace Internal.Cryptography if (oid == null) throw new ArgumentNullException("oid"); - return NativeOidToFriendlyName(oid, oidGroup, fallBackToAllGroups); + string mappedName; + bool shouldUseCache = ShouldUseCache(oidGroup); + + // On Unix shouldUseCache is always true, so no matter what OidGroup is passed in the Windows + // friendly name will be returned. + // + // On Windows shouldUseCache is only true for OidGroup.All, because otherwise the OS may filter + // out the answer based on the group criteria. + if (shouldUseCache) + { + if (s_oidToFriendlyName.TryGetValue(oid, out mappedName) || + s_compatOids.TryGetValue(oid, out mappedName) || + s_lateBoundOidToFriendlyName.TryGetValue(oid, out mappedName)) + { + return mappedName; + } + } + + mappedName = NativeOidToFriendlyName(oid, oidGroup, fallBackToAllGroups); + + if (shouldUseCache && mappedName != null) + { + s_lateBoundOidToFriendlyName.TryAdd(oid, mappedName); + + // Don't add the reverse here. Just because oid => name doesn't mean name => oid. + // And don't bother doing the reverse lookup proactively, just wait until they ask for it. + } + + return mappedName; } // @@ -55,19 +64,168 @@ namespace Internal.Cryptography if (friendlyName == null) throw new ArgumentNullException("friendlyName"); - string oid = NativeFriendlyNameToOid(friendlyName, oidGroup, fallBackToAllGroups); + string mappedOid; + bool shouldUseCache = ShouldUseCache(oidGroup); - if (oid == null) + if (shouldUseCache) { - string alias = FindFriendlyNameAlias(friendlyName); - - if (alias != null) + if (s_friendlyNameToOid.TryGetValue(friendlyName, out mappedOid) || + s_lateBoundFriendlyNameToOid.TryGetValue(friendlyName, out mappedOid)) { - oid = NativeFriendlyNameToOid(alias, oidGroup, fallBackToAllGroups); + return mappedOid; } } - return oid; + mappedOid = NativeFriendlyNameToOid(friendlyName, oidGroup, fallBackToAllGroups); + + if (shouldUseCache && mappedOid != null) + { + s_lateBoundFriendlyNameToOid.TryAdd(friendlyName, mappedOid); + + // Don't add the reverse here. Friendly Name => OID is a case insensitive search, + // so the casing provided as input here may not be the 'correct' one. Just let + // ToFriendlyName capture the response and cache it itself. + } + + return mappedOid; } + + // This table was originally built by extracting every szOID #define out of wincrypt.h, + // and running them through new Oid(string) on Windows 10. Then, take the list of everything + // which produced a FriendlyName value, and run it through two other languages. If all 3 agree + // on the mapping, consider the value to be non-localized. + // + // This original list was produced on English (Win10), cross-checked with Spanish (Win8.1) and + // Japanese (Win10). + // + // Sometimes wincrypt.h has more than one OID which results in the same name. The OIDs whose value + // doesn't roundtrip (new Oid(new Oid(value).FriendlyName).Value) are contained in s_compatOids. + // + // X-Plat: The names (and casing) in this table come from Windows. Part of the intent of this table + // is to prevent issues wherein an identifier is different between CoreFX\Windows and CoreFX\Unix; + // since any existing code would be using the Windows identifier, it is the de facto standard. + private static readonly Dictionary<string, string> s_friendlyNameToOid = + new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) + { + { "3des", "1.2.840.113549.3.7" }, + { "aes128", "2.16.840.1.101.3.4.1.2" }, + { "aes128wrap", "2.16.840.1.101.3.4.1.5" }, + { "aes192", "2.16.840.1.101.3.4.1.22" }, + { "aes192wrap", "2.16.840.1.101.3.4.1.25" }, + { "aes256", "2.16.840.1.101.3.4.1.42" }, + { "aes256wrap", "2.16.840.1.101.3.4.1.45" }, + { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" }, + { "brainpoolP160t1", "1.3.36.3.3.2.8.1.1.2" }, + { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" }, + { "brainpoolP192t1", "1.3.36.3.3.2.8.1.1.4" }, + { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" }, + { "brainpoolP224t1", "1.3.36.3.3.2.8.1.1.6" }, + { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" }, + { "brainpoolP256t1", "1.3.36.3.3.2.8.1.1.8" }, + { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" }, + { "brainpoolP320t1", "1.3.36.3.3.2.8.1.1.10" }, + { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11" }, + { "brainpoolP384t1", "1.3.36.3.3.2.8.1.1.12" }, + { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13" }, + { "brainpoolP512t1", "1.3.36.3.3.2.8.1.1.14" }, + { "C", "2.5.4.6" }, + { "CMS3DESwrap", "1.2.840.113549.1.9.16.3.6" }, + { "CMSRC2wrap", "1.2.840.113549.1.9.16.3.7" }, + { "CN", "2.5.4.3" }, + { "CPS", "1.3.6.1.5.5.7.2.1" }, + { "DC", "0.9.2342.19200300.100.1.25" }, + { "des", "1.3.14.3.2.7" }, + { "Description", "2.5.4.13" }, + { "DH", "1.2.840.10046.2.1" }, + { "dnQualifier", "2.5.4.46" }, + { "DSA", "1.2.840.10040.4.1" }, + { "dsaSHA1", "1.3.14.3.2.27" }, + { "E", "1.2.840.113549.1.9.1" }, + { "ec192wapi", "1.2.156.11235.1.1.2.1" }, + { "ECC", "1.2.840.10045.2.1" }, + { "ECDH_STD_SHA1_KDF", "1.3.133.16.840.63.0.2" }, + { "ECDH_STD_SHA256_KDF", "1.3.132.1.11.1" }, + { "ECDH_STD_SHA384_KDF", "1.3.132.1.11.2" }, + { "ECDSA_P256", "1.2.840.10045.3.1.7" }, + { "ECDSA_P384", "1.3.132.0.34" }, + { "ECDSA_P521", "1.3.132.0.35" }, + { "ESDH", "1.2.840.113549.1.9.16.3.5" }, + { "G", "2.5.4.42" }, + { "I", "2.5.4.43" }, + { "L", "2.5.4.7" }, + { "md2", "1.2.840.113549.2.2" }, + { "md2RSA", "1.2.840.113549.1.1.2" }, + { "md4", "1.2.840.113549.2.4" }, + { "md4RSA", "1.2.840.113549.1.1.3" }, + { "md5", "1.2.840.113549.2.5" }, + { "md5RSA", "1.2.840.113549.1.1.4" }, + { "mgf1", "1.2.840.113549.1.1.8" }, + { "mosaicKMandUpdSig", "2.16.840.1.101.2.1.1.20" }, + { "mosaicUpdatedSig", "2.16.840.1.101.2.1.1.19" }, + { "nistP192", "1.2.840.10045.3.1.1" }, + { "nistP224", "1.3.132.0.33" }, + { "NO_SIGN", "1.3.6.1.5.5.7.6.2" }, + { "O", "2.5.4.10" }, + { "OU", "2.5.4.11" }, + { "Phone", "2.5.4.20" }, + { "POBox", "2.5.4.18" }, + { "PostalCode", "2.5.4.17" }, + { "rc2", "1.2.840.113549.3.2" }, + { "rc4", "1.2.840.113549.3.4" }, + { "RSA", "1.2.840.113549.1.1.1" }, + { "RSAES_OAEP", "1.2.840.113549.1.1.7" }, + { "RSASSA-PSS", "1.2.840.113549.1.1.10" }, + { "S", "2.5.4.8" }, + { "secP160k1", "1.3.132.0.9" }, + { "secP160r1", "1.3.132.0.8" }, + { "secP160r2", "1.3.132.0.30" }, + { "secP192k1", "1.3.132.0.31" }, + { "secP224k1", "1.3.132.0.32" }, + { "secP256k1", "1.3.132.0.10" }, + { "SERIALNUMBER", "2.5.4.5" }, + { "sha1", "1.3.14.3.2.26" }, + { "sha1DSA", "1.2.840.10040.4.3" }, + { "sha1ECDSA", "1.2.840.10045.4.1" }, + { "sha1RSA", "1.2.840.113549.1.1.5" }, + { "sha256", "2.16.840.1.101.3.4.2.1" }, + { "sha256ECDSA", "1.2.840.10045.4.3.2" }, + { "sha256RSA", "1.2.840.113549.1.1.11" }, + { "sha384", "2.16.840.1.101.3.4.2.2" }, + { "sha384ECDSA", "1.2.840.10045.4.3.3" }, + { "sha384RSA", "1.2.840.113549.1.1.12" }, + { "sha512", "2.16.840.1.101.3.4.2.3" }, + { "sha512ECDSA", "1.2.840.10045.4.3.4" }, + { "sha512RSA", "1.2.840.113549.1.1.13" }, + { "SN", "2.5.4.4" }, + { "specifiedECDSA", "1.2.840.10045.4.3" }, + { "STREET", "2.5.4.9" }, + { "T", "2.5.4.12" }, + { "wtls9", "2.23.43.1.4.9" }, + { "X21Address", "2.5.4.24" }, + { "x962P192v2", "1.2.840.10045.3.1.2" }, + { "x962P192v3", "1.2.840.10045.3.1.3" }, + { "x962P239v1", "1.2.840.10045.3.1.4" }, + { "x962P239v2", "1.2.840.10045.3.1.5" }, + { "x962P239v3", "1.2.840.10045.3.1.6" }, + }; + + private static readonly Dictionary<string, string> s_oidToFriendlyName = + s_friendlyNameToOid.ToDictionary(kvp => kvp.Value, kvp => kvp.Key); + + private static readonly Dictionary<string, string> s_compatOids = + new Dictionary<string, string> + { + { "1.2.840.113549.1.3.1", "DH" }, + { "1.3.14.3.2.12", "DSA" }, + { "1.3.14.3.2.13", "sha1DSA" }, + { "1.3.14.3.2.15", "shaRSA" }, + { "1.3.14.3.2.18", "sha" }, + { "1.3.14.3.2.2", "md4RSA" }, + { "1.3.14.3.2.22", "RSA_KEYX" }, + { "1.3.14.3.2.29", "sha1RSA" }, + { "1.3.14.3.2.3", "md5RSA" }, + { "1.3.14.3.2.4", "md4RSA" }, + { "1.3.14.7.2.3.1", "md2RSA" }, + }; } } diff --git a/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj b/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj index d3aa99334f..62e9e92436 100644 --- a/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj +++ b/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj @@ -76,11 +76,14 @@ <Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.ERR.cs"> <Link>Common\Interop\Unix\libcrypto\Interop.ERR.cs</Link> </Compile> + <Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.X509Ext.cs"> + <Link>Common\Interop\Unix\libcrypto\Interop.X509Ext.cs</Link> + </Compile> <Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs"> <Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs</Link> </Compile> - <Compile Include="$(CommonPath)\Interop\Unix\libcrypto\Interop.X509Ext.cs"> - <Link>Common\Interop\Unix\libcrypto\Interop.X509Ext.cs</Link> + <Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.LookupFriendlyNameByOid.cs"> + <Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.LookupFriendlyNameByOid.cs</Link> </Compile> <Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\Asn1SafeHandles.Unix.cs"> <Link>Common\Microsoft\Win32\SafeHandles\Asn1SafeHandles.Unix.cs</Link> diff --git a/src/System.Security.Cryptography.Encoding/src/project.json b/src/System.Security.Cryptography.Encoding/src/project.json index 5dfb234523..ffe85594fe 100644 --- a/src/System.Security.Cryptography.Encoding/src/project.json +++ b/src/System.Security.Cryptography.Encoding/src/project.json @@ -1,8 +1,11 @@ { "dependencies": { + "System.Collections": "4.0.0", + "System.Collections.Concurrent": "4.0.0", "System.Diagnostics.Contracts": "4.0.0", "System.Diagnostics.Debug": "4.0.10", "System.IO": "4.0.10", + "System.Linq": "4.0.0", "System.Resources.ResourceManager": "4.0.0", "System.Runtime": "4.0.20", "System.Runtime.InteropServices": "4.0.20" diff --git a/src/System.Security.Cryptography.Encoding/src/project.lock.json b/src/System.Security.Cryptography.Encoding/src/project.lock.json index 3bcb5b99bf..9d2c2b3ae5 100644 --- a/src/System.Security.Cryptography.Encoding/src/project.lock.json +++ b/src/System.Security.Cryptography.Encoding/src/project.lock.json @@ -3,6 +3,25 @@ "version": 1, "targets": { "DNXCore,Version=v5.0": { + "System.Collections/4.0.0": { + "type": "package", + "dependencies": { + "System.Runtime": "4.0.0" + }, + "compile": { + "ref/dotnet/System.Collections.dll": {} + } + }, + "System.Collections.Concurrent/4.0.0": { + "type": "package", + "dependencies": { + "System.Runtime": "4.0.0", + "System.Threading.Tasks": "4.0.0" + }, + "compile": { + "ref/dotnet/System.Collections.Concurrent.dll": {} + } + }, "System.Diagnostics.Contracts/4.0.0": { "type": "package", "dependencies": { @@ -50,6 +69,22 @@ "lib/DNXCore50/System.IO.dll": {} } }, + "System.Linq/4.0.0": { + "type": "package", + "dependencies": { + "System.Collections": "4.0.10", + "System.Diagnostics.Debug": "4.0.10", + "System.Resources.ResourceManager": "4.0.0", + "System.Runtime": "4.0.20", + "System.Runtime.Extensions": "4.0.10" + }, + "compile": { + "ref/dotnet/System.Linq.dll": {} + }, + "runtime": { + "lib/dotnet/System.Linq.dll": {} + } + }, "System.Private.Uri/4.0.0": { "type": "package", "compile": { @@ -108,6 +143,18 @@ "lib/DNXCore50/System.Runtime.dll": {} } }, + "System.Runtime.Extensions/4.0.10": { + "type": "package", + "dependencies": { + "System.Runtime": "4.0.20" + }, + "compile": { + "ref/dotnet/System.Runtime.Extensions.dll": {} + }, + "runtime": { + "lib/DNXCore50/System.Runtime.Extensions.dll": {} + } + }, "System.Runtime.Handles/4.0.0": { "type": "package", "dependencies": { @@ -156,6 +203,100 @@ } }, "libraries": { + "System.Collections/4.0.0": { + "type": "package", + "sha512": "i2vsGDIEbWdHcUSNDPKZP/ZWod6o740el7mGTCy0dqbCxQh74W4QoC+klUwPEtGEFuvzJ7bJgvwJqscosVNyZQ==", + "files": [ + "lib/MonoAndroid10/_._", + "lib/MonoTouch10/_._", + "lib/net45/_._", + "lib/win8/_._", + "lib/wp80/_._", + "lib/wpa81/_._", + "lib/xamarinios10/_._", + "lib/xamarinmac20/_._", + "License.rtf", + "ref/dotnet/de/System.Collections.xml", + "ref/dotnet/es/System.Collections.xml", + "ref/dotnet/fr/System.Collections.xml", + "ref/dotnet/it/System.Collections.xml", + "ref/dotnet/ja/System.Collections.xml", + "ref/dotnet/ko/System.Collections.xml", + "ref/dotnet/ru/System.Collections.xml", + "ref/dotnet/System.Collections.dll", + "ref/dotnet/System.Collections.xml", + "ref/dotnet/zh-hans/System.Collections.xml", + "ref/dotnet/zh-hant/System.Collections.xml", + "ref/MonoAndroid10/_._", + "ref/MonoTouch10/_._", + "ref/net45/_._", + "ref/netcore50/de/System.Collections.xml", + "ref/netcore50/es/System.Collections.xml", + "ref/netcore50/fr/System.Collections.xml", + "ref/netcore50/it/System.Collections.xml", + "ref/netcore50/ja/System.Collections.xml", + "ref/netcore50/ko/System.Collections.xml", + "ref/netcore50/ru/System.Collections.xml", + "ref/netcore50/System.Collections.dll", + "ref/netcore50/System.Collections.xml", + "ref/netcore50/zh-hans/System.Collections.xml", + "ref/netcore50/zh-hant/System.Collections.xml", + "ref/win8/_._", + "ref/wp80/_._", + "ref/wpa81/_._", + "ref/xamarinios10/_._", + "ref/xamarinmac20/_._", + "System.Collections.4.0.0.nupkg", + "System.Collections.4.0.0.nupkg.sha512", + "System.Collections.nuspec" + ] + }, + "System.Collections.Concurrent/4.0.0": { + "type": "package", + "sha512": "1f5SWoX7UlFkvUt7A8JoG5lXgZDw4cRAcKG8Eaxa+3Sq6e/UgVWl2YWew1evJv+p+edNNlIIorDfREKcoEDHGw==", + "files": [ + "lib/MonoAndroid10/_._", + "lib/MonoTouch10/_._", + "lib/net45/_._", + "lib/win8/_._", + "lib/wpa81/_._", + "lib/xamarinios10/_._", + "lib/xamarinmac20/_._", + "License.rtf", + "ref/dotnet/de/System.Collections.Concurrent.xml", + "ref/dotnet/es/System.Collections.Concurrent.xml", + "ref/dotnet/fr/System.Collections.Concurrent.xml", + "ref/dotnet/it/System.Collections.Concurrent.xml", + "ref/dotnet/ja/System.Collections.Concurrent.xml", + "ref/dotnet/ko/System.Collections.Concurrent.xml", + "ref/dotnet/ru/System.Collections.Concurrent.xml", + "ref/dotnet/System.Collections.Concurrent.dll", + "ref/dotnet/System.Collections.Concurrent.xml", + "ref/dotnet/zh-hans/System.Collections.Concurrent.xml", + "ref/dotnet/zh-hant/System.Collections.Concurrent.xml", + "ref/MonoAndroid10/_._", + "ref/MonoTouch10/_._", + "ref/net45/_._", + "ref/netcore50/de/System.Collections.Concurrent.xml", + "ref/netcore50/es/System.Collections.Concurrent.xml", + "ref/netcore50/fr/System.Collections.Concurrent.xml", + "ref/netcore50/it/System.Collections.Concurrent.xml", + "ref/netcore50/ja/System.Collections.Concurrent.xml", + "ref/netcore50/ko/System.Collections.Concurrent.xml", + "ref/netcore50/ru/System.Collections.Concurrent.xml", + "ref/netcore50/System.Collections.Concurrent.dll", + "ref/netcore50/System.Collections.Concurrent.xml", + "ref/netcore50/zh-hans/System.Collections.Concurrent.xml", + "ref/netcore50/zh-hant/System.Collections.Concurrent.xml", + "ref/win8/_._", + "ref/wpa81/_._", + "ref/xamarinios10/_._", + "ref/xamarinmac20/_._", + "System.Collections.Concurrent.4.0.0.nupkg", + "System.Collections.Concurrent.4.0.0.nupkg.sha512", + "System.Collections.Concurrent.nuspec" + ] + }, "System.Diagnostics.Contracts/4.0.0": { "type": "package", "sha512": "lMc7HNmyIsu0pKTdA4wf+FMq5jvouUd+oUpV4BdtyqoV0Pkbg9u/7lTKFGqpjZRQosWHq1+B32Lch2wf4AmloA==", @@ -305,6 +446,39 @@ "System.IO.nuspec" ] }, + "System.Linq/4.0.0": { + "type": "package", + "serviceable": true, + "sha512": "r6Hlc+ytE6m/9UBr+nNRRdoJEWjoeQiT3L3lXYFDHoXk3VYsRBCDNXrawcexw7KPLaH0zamQLiAb6avhZ50cGg==", + "files": [ + "lib/dotnet/System.Linq.dll", + "lib/net45/_._", + "lib/netcore50/System.Linq.dll", + "lib/win8/_._", + "lib/wp80/_._", + "lib/wpa81/_._", + "ref/dotnet/de/System.Linq.xml", + "ref/dotnet/es/System.Linq.xml", + "ref/dotnet/fr/System.Linq.xml", + "ref/dotnet/it/System.Linq.xml", + "ref/dotnet/ja/System.Linq.xml", + "ref/dotnet/ko/System.Linq.xml", + "ref/dotnet/ru/System.Linq.xml", + "ref/dotnet/System.Linq.dll", + "ref/dotnet/System.Linq.xml", + "ref/dotnet/zh-hans/System.Linq.xml", + "ref/dotnet/zh-hant/System.Linq.xml", + "ref/net45/_._", + "ref/netcore50/System.Linq.dll", + "ref/netcore50/System.Linq.xml", + "ref/win8/_._", + "ref/wp80/_._", + "ref/wpa81/_._", + "System.Linq.4.0.0.nupkg", + "System.Linq.4.0.0.nupkg.sha512", + "System.Linq.nuspec" + ] + }, "System.Private.Uri/4.0.0": { "type": "package", "serviceable": true, @@ -470,6 +644,40 @@ "System.Runtime.nuspec" ] }, + "System.Runtime.Extensions/4.0.10": { + "type": "package", + "serviceable": true, + "sha512": "5dsEwf3Iml7d5OZeT20iyOjT+r+okWpN7xI2v+R4cgd3WSj4DeRPTvPFjDpacbVW4skCAZ8B9hxXJYgkCFKJ1A==", + "files": [ + "lib/DNXCore50/System.Runtime.Extensions.dll", + "lib/MonoAndroid10/_._", + "lib/MonoTouch10/_._", + "lib/net46/_._", + "lib/netcore50/System.Runtime.Extensions.dll", + "lib/xamarinios10/_._", + "lib/xamarinmac20/_._", + "ref/dotnet/de/System.Runtime.Extensions.xml", + "ref/dotnet/es/System.Runtime.Extensions.xml", + "ref/dotnet/fr/System.Runtime.Extensions.xml", + "ref/dotnet/it/System.Runtime.Extensions.xml", + "ref/dotnet/ja/System.Runtime.Extensions.xml", + "ref/dotnet/ko/System.Runtime.Extensions.xml", + "ref/dotnet/ru/System.Runtime.Extensions.xml", + "ref/dotnet/System.Runtime.Extensions.dll", + "ref/dotnet/System.Runtime.Extensions.xml", + "ref/dotnet/zh-hans/System.Runtime.Extensions.xml", + "ref/dotnet/zh-hant/System.Runtime.Extensions.xml", + "ref/MonoAndroid10/_._", + "ref/MonoTouch10/_._", + "ref/net46/_._", + "ref/xamarinios10/_._", + "ref/xamarinmac20/_._", + "runtimes/win8-aot/lib/netcore50/System.Runtime.Extensions.dll", + "System.Runtime.Extensions.4.0.10.nupkg", + "System.Runtime.Extensions.4.0.10.nupkg.sha512", + "System.Runtime.Extensions.nuspec" + ] + }, "System.Runtime.Handles/4.0.0": { "type": "package", "serviceable": true, @@ -637,9 +845,12 @@ }, "projectFileDependencyGroups": { "": [ + "System.Collections >= 4.0.0", + "System.Collections.Concurrent >= 4.0.0", "System.Diagnostics.Contracts >= 4.0.0", "System.Diagnostics.Debug >= 4.0.10", "System.IO >= 4.0.10", + "System.Linq >= 4.0.0", "System.Resources.ResourceManager >= 4.0.0", "System.Runtime >= 4.0.20", "System.Runtime.InteropServices >= 4.0.20" diff --git a/src/System.Security.Cryptography.Encoding/tests/Oid.cs b/src/System.Security.Cryptography.Encoding/tests/Oid.cs index 7339b29c50..b408edea8d 100644 --- a/src/System.Security.Cryptography.Encoding/tests/Oid.cs +++ b/src/System.Security.Cryptography.Encoding/tests/Oid.cs @@ -1,68 +1,97 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.IO; -using System.Text; +using System.Collections.Generic; using Xunit; namespace System.Security.Cryptography.Encoding.Tests { - public class OidTests + public static class OidTests { - [Fact] - public static void TestStrConstructor() + [Theory] + [MemberData("ValidOidFriendlyNamePairs")] + public static void LookupOidByValue_Ctor(string oidValue, string friendlyName) { - Oid oid; - - Assert.Throws<ArgumentNullException>(() => oid = new Oid((string)null)); + Oid oid = new Oid(oidValue); - oid = new Oid(SHA1_Oid); - Assert.Equal(SHA1_Name, oid.FriendlyName); - Assert.Equal(SHA1_Oid, oid.Value); + Assert.Equal(oidValue, oid.Value); + Assert.Equal(friendlyName, oid.FriendlyName); + } - // Though the parameter is supposed to be an OID, the constructor will also accept a friendly name. - oid = new Oid(SHA1_Name); - Assert.Equal(SHA1_Name, oid.FriendlyName); - Assert.Equal(SHA1_Oid, oid.Value); + [Theory] + [MemberData("ValidOidFriendlyNamePairs")] + public static void LookupOidByFriendlyName_Ctor(string oidValue, string friendlyName) + { + Oid oid = new Oid(friendlyName); - // No validation done on OID (other than the null check.) - oid = new Oid(Bogus_Name); - Assert.Equal(null, oid.FriendlyName); - Assert.Equal(Bogus_Name, oid.Value); + Assert.Equal(oidValue, oid.Value); + Assert.Equal(friendlyName, oid.FriendlyName); + } - return; + [Fact] + public static void LookupNullOid() + { + Assert.Throws<ArgumentNullException>(() => new Oid((string)null)); } [Fact] - public static void TestStrStrConstructor() + public static void LookupUnknownOid() { - Oid oid; + Oid oid = new Oid(Bogus_Name); + + Assert.Equal(Bogus_Name, oid.Value); + Assert.Null(oid.FriendlyName); + } + [Fact] + public static void Oid_StringString_BothNull() + { // No validation at all. - oid = new Oid((string)null, (string)null); - Assert.Equal(null, oid.FriendlyName); - Assert.Equal(null, oid.Value); + Oid oid = new Oid(null, null); + Assert.Null(oid.Value); + Assert.Null(oid.FriendlyName); + } + + [Theory] + [MemberData("ValidOidFriendlyNamePairs")] + public static void Oid_StringString_NullFriendlyName(string oidValue, string expectedFriendlyName) + { // Can omit friendly-name - FriendlyName property demand-computes it. - oid = new Oid(SHA1_Oid, (string)null); - Assert.Equal(SHA1_Name, oid.FriendlyName); - Assert.Equal(SHA1_Oid, oid.Value); + Oid oid = new Oid(oidValue, null); - oid = new Oid(SHA1_Oid, "BOGUS-NAME"); - Assert.Equal("BOGUS-NAME", oid.FriendlyName); - Assert.Equal(SHA1_Oid, oid.Value); + Assert.Equal(oidValue, oid.Value); + Assert.Equal(expectedFriendlyName, oid.FriendlyName); + } + [Theory] + [InlineData(SHA1_Name)] + [InlineData(SHA256_Name)] + [InlineData(Bogus_Name)] + public static void Oid_StringString_NullValue(string friendlyName) + { // Can omit oid, Value property does no on-demand conversion. - oid = new Oid((string)null, SHA1_Name); - Assert.Equal(SHA1_Name, oid.FriendlyName); - Assert.Equal(null, oid.Value); + Oid oid = new Oid(null, friendlyName); - oid = new Oid("BOGUS-OID", SHA1_Name); - Assert.Equal(SHA1_Name, oid.FriendlyName); - Assert.Equal("BOGUS-OID", oid.Value); + Assert.Null(oid.Value); + Assert.Equal(friendlyName, oid.FriendlyName); + } + [Theory] + [InlineData(SHA1_Oid, SHA256_Name)] + [InlineData(SHA256_Oid, SHA1_Name)] + [InlineData(SHA256_Name, SHA1_Name)] + [InlineData(SHA256_Name, Bogus_Name)] + [InlineData(Bogus_Name, SHA256_Oid)] + public static void Oid_StringString_BothSpecified(string oidValue, string friendlyName) + { + // The values are taken as true, not verified at all. + // The data for this test series should be mismatched OID-FriendlyName pairs, and + // sometimes the OID isn't a legal OID. + Oid oid = new Oid(oidValue, friendlyName); - return; + Assert.Equal(oidValue, oid.Value); + Assert.Equal(friendlyName, oid.FriendlyName); } [Fact] @@ -77,8 +106,6 @@ namespace System.Security.Cryptography.Encoding.Tests oid.Value = null; Assert.Equal(null, oid.Value); - - return; } [Fact] @@ -116,79 +143,187 @@ namespace System.Security.Cryptography.Encoding.Tests Assert.Equal(SHA256_Name, oid.FriendlyName); Assert.Equal(SHA256_Oid, oid.Value); } - - [Fact] - [ActiveIssue(1863, PlatformID.AnyUnix)] - public static void TestFromFriendlyName() + + [Theory] + [MemberData("ValidOidFriendlyNameHashAlgorithmPairs")] + public static void LookupOidByValue_Method_HashAlgorithm(string oidValue, string friendlyName) { - Oid oid; + Oid oid = Oid.FromOidValue(oidValue, OidGroup.HashAlgorithm); - oid = Oid.FromFriendlyName(SHA1_Name, OidGroup.HashAlgorithm); - Assert.Equal(SHA1_Name, oid.FriendlyName); - Assert.Equal(SHA1_Oid, oid.Value); + Assert.Equal(oidValue, oid.Value); + Assert.Equal(friendlyName, oid.FriendlyName); + } - oid = Oid.FromFriendlyName(SHA256_Name, OidGroup.HashAlgorithm); - Assert.Equal(SHA256_Name, oid.FriendlyName); - Assert.Equal(SHA256_Oid, oid.Value); + [Theory] + [MemberData("ValidOidFriendlyNameEncryptionAlgorithmPairs")] + public static void LookupOidByValue_Method_EncryptionAlgorithm(string oidValue, string friendlyName) + { + Oid oid = Oid.FromOidValue(oidValue, OidGroup.EncryptionAlgorithm); - Assert.Throws<ArgumentNullException>(() => Oid.FromFriendlyName(null, OidGroup.HashAlgorithm)); - Assert.Throws<CryptographicException>(() => Oid.FromFriendlyName(Bogus_Name, OidGroup.HashAlgorithm)); + Assert.Equal(oidValue, oid.Value); + Assert.Equal(friendlyName, oid.FriendlyName); + } + [Theory] + [MemberData("ValidOidFriendlyNameHashAlgorithmPairs")] + [PlatformSpecific(PlatformID.Windows)] + public static void LookupOidByValue_Method_WrongGroup(string oidValue, string friendlyName) + { // Oid group is implemented strictly - no fallback to OidGroup.All as with many other parts of Crypto. - Assert.Throws<CryptographicException>(() => Oid.FromFriendlyName(SHA1_Name, OidGroup.Policy)); + Assert.Throws<CryptographicException>(() => Oid.FromOidValue(oidValue, OidGroup.EncryptionAlgorithm)); } [Fact] - [ActiveIssue(1863, PlatformID.AnyUnix)] - public static void TestFromOidValue() + public static void LookupOidByValue_Method_NullInput() { - Oid oid; + Assert.Throws<ArgumentNullException>(() => Oid.FromOidValue(null, OidGroup.HashAlgorithm)); + } - oid = Oid.FromOidValue(SHA1_Oid, OidGroup.HashAlgorithm); - Assert.Equal(SHA1_Name, oid.FriendlyName); - Assert.Equal(SHA1_Oid, oid.Value); + [Theory] + [InlineData(SHA1_Name)] // Friendly names are not coerced into OID values from the method. + [InlineData(Bogus_Name)] + public static void LookupOidByValue_Method_BadInput(string badInput) + { + Assert.Throws<CryptographicException>(() => Oid.FromOidValue(badInput, OidGroup.HashAlgorithm)); + } - oid = Oid.FromOidValue(SHA256_Oid, OidGroup.HashAlgorithm); - Assert.Equal(SHA256_Name, oid.FriendlyName); - Assert.Equal(SHA256_Oid, oid.Value); + [Theory] + [MemberData("ValidOidFriendlyNameHashAlgorithmPairs")] + public static void LookupOidByFriendlyName_Method_HashAlgorithm(string oidValue, string friendlyName) + { + Oid oid = Oid.FromFriendlyName(friendlyName, OidGroup.HashAlgorithm); - Assert.Throws<ArgumentNullException>(() => Oid.FromOidValue(null, OidGroup.HashAlgorithm)); - Assert.Throws<CryptographicException>(() => Oid.FromOidValue(Bogus_Name, OidGroup.HashAlgorithm)); + Assert.Equal(oidValue, oid.Value); + Assert.Equal(friendlyName, oid.FriendlyName); + } + + [Theory] + [MemberData("ValidOidFriendlyNameEncryptionAlgorithmPairs")] + public static void LookupOidByFriendlyName_Method_EncryptionAlgorithm(string oidValue, string friendlyName) + { + Oid oid = Oid.FromFriendlyName(friendlyName, OidGroup.EncryptionAlgorithm); + + Assert.Equal(oidValue, oid.Value); + Assert.Equal(friendlyName, oid.FriendlyName); + } + + [Theory] + [MemberData("ValidOidFriendlyNamePairs")] + public static void LookupOidByFriendlyName_Method_InverseCase(string oidValue, string friendlyName) + { + // Note that oid lookup is case-insensitive, and we store the name in the form it was + // input to the constructor (rather than "normalizing" it to the official casing.) + string inverseCasedName = InvertCase(friendlyName); + Oid oid = Oid.FromFriendlyName(inverseCasedName, OidGroup.All); + + Assert.Equal(oidValue, oid.Value); + Assert.Equal(inverseCasedName, oid.FriendlyName); + } + [Theory] + [MemberData("ValidOidFriendlyNameHashAlgorithmPairs")] + [PlatformSpecific(PlatformID.Windows)] + public static void LookupOidByFriendlyName_Method_WrongGroup(string oidValue, string friendlyName) + { // Oid group is implemented strictly - no fallback to OidGroup.All as with many other parts of Crypto. - Assert.Throws<CryptographicException>(() => Oid.FromOidValue(SHA1_Oid, OidGroup.Policy)); + Assert.Throws<CryptographicException>(() => Oid.FromFriendlyName(friendlyName, OidGroup.EncryptionAlgorithm)); } [Fact] - [ActiveIssue(1863, PlatformID.AnyUnix)] - public static void TestKnownValues() + public static void LookupOidByFriendlyName_Method_NullInput() { - Oid oid; - oid = Oid.FromFriendlyName(SHA1_Name, OidGroup.All); - Assert.Equal(SHA1_Name, oid.FriendlyName); - Assert.Equal(SHA1_Oid, oid.Value); + Assert.Throws<ArgumentNullException>(() => Oid.FromFriendlyName(null, OidGroup.HashAlgorithm)); + } - oid = Oid.FromFriendlyName(SHA256_Name, OidGroup.All); - Assert.Equal(SHA256_Name, oid.FriendlyName); - Assert.Equal(SHA256_Oid, oid.Value); + [Theory] + [InlineData(SHA1_Oid)] // OIDs are not coerced into friendly names values from the method. + [InlineData(Bogus_Name)] + public static void LookupOidByFriendlyName_Method_BadInput(string badInput) + { + Assert.Throws<CryptographicException>(() => Oid.FromFriendlyName(badInput, OidGroup.HashAlgorithm)); + } - // Note that oid lookup is case-insensitive, and we store the name in the form it was input to the constructor (rather than "normalizing" it - // to the official casing.) - oid = Oid.FromFriendlyName("MD5", OidGroup.All); - Assert.Equal("MD5", oid.FriendlyName); - Assert.Equal("1.2.840.113549.2.5", oid.Value); + [Fact] + [PlatformSpecific(PlatformID.AnyUnix)] + public static void LookupOidByValue_Method_UnixOnly() + { + // This needs to be an OID not in the static lookup table. The purpose is to verify the + // NativeOidToFriendlyName fallback for Unix. For Windows this is accomplished by + // using FromOidValue with an OidGroup other than OidGroup.All. + + Oid oid = Oid.FromOidValue(ObsoleteSmime3desWrap_Oid, OidGroup.All); + + Assert.Equal(ObsoleteSmime3desWrap_Oid, oid.Value); + Assert.Equal(ObsoleteSmime3desWrap_Name, oid.FriendlyName); + } - oid = Oid.FromFriendlyName("sha384", OidGroup.All); - Assert.Equal("sha384", oid.FriendlyName); - Assert.Equal("2.16.840.1.101.3.4.2.2", oid.Value); + [Fact] + [PlatformSpecific(PlatformID.AnyUnix)] + public static void LookupOidByFriendlyName_Method_UnixOnly() + { + // This needs to be a name not in the static lookup table. The purpose is to verify the + // NativeFriendlyNameToOid fallback for Unix. For Windows this is accomplished by + // using FromOidValue with an OidGroup other than OidGroup.All. + Oid oid = Oid.FromFriendlyName(ObsoleteSmime3desWrap_Name, OidGroup.All); - oid = Oid.FromFriendlyName("sha512", OidGroup.All); - Assert.Equal("sha512", oid.FriendlyName); - Assert.Equal("2.16.840.1.101.3.4.2.3", oid.Value); + Assert.Equal(ObsoleteSmime3desWrap_Oid, oid.Value); + Assert.Equal(ObsoleteSmime3desWrap_Name, oid.FriendlyName); + } - oid = Oid.FromFriendlyName("3des", OidGroup.All); - Assert.Equal("3des", oid.FriendlyName); - Assert.Equal("1.2.840.113549.3.7", oid.Value); + public static IEnumerable<string[]> ValidOidFriendlyNamePairs + { + get + { + List<string[]> data = new List<string[]>(ValidOidFriendlyNameHashAlgorithmPairs); + data.AddRange(ValidOidFriendlyNameEncryptionAlgorithmPairs); + + return data; + } + } + + public static IEnumerable<string[]> ValidOidFriendlyNameHashAlgorithmPairs + { + get + { + return new[] + { + new[] { SHA1_Oid, SHA1_Name }, + new[] { SHA256_Oid, SHA256_Name }, + new[] { "1.2.840.113549.2.5", "md5" }, + new[] { "2.16.840.1.101.3.4.2.2", "sha384" }, + new[] { "2.16.840.1.101.3.4.2.3", "sha512" }, + }; + } + } + + public static IEnumerable<string[]> ValidOidFriendlyNameEncryptionAlgorithmPairs + { + get + { + return new[] + { + new[] { "1.2.840.113549.3.7", "3des" }, + }; + } + } + + private static string InvertCase(string existing) + { + char[] chars = existing.ToCharArray(); + + for (int i = 0; i < chars.Length; i++) + { + if (char.IsUpper(chars[i])) + { + chars[i] = char.ToLowerInvariant(chars[i]); + } + else if (char.IsLower(chars[i])) + { + chars[i] = char.ToUpperInvariant(chars[i]); + } + } + + return new string(chars); } private const string SHA1_Name = "sha1"; @@ -198,5 +333,8 @@ namespace System.Security.Cryptography.Encoding.Tests private const string SHA256_Oid = "2.16.840.1.101.3.4.2.1"; private const string Bogus_Name = "BOGUS_BOGUS_BOGUS_BOGUS"; + + private const string ObsoleteSmime3desWrap_Oid = "1.2.840.113549.1.9.16.3.3"; + private const string ObsoleteSmime3desWrap_Name = "id-smime-alg-3DESwrap"; } -}
\ No newline at end of file +} |