Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbartonjs <jbarton@microsoft.com>2015-09-30 17:51:20 +0300
committerbartonjs <jbarton@microsoft.com>2015-10-03 05:18:39 +0300
commit9d76e965d781a12fabb2eaa5d503119912f8ebec (patch)
treec2b4d9c8bce51f9dc9f98781e3674d58636f4fef /src/System.Security.Cryptography.Encoding
parentc942505ba2012140fefad34128347e256ba88683 (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')
-rw-r--r--src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Unix.cs49
-rw-r--r--src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.Windows.cs19
-rw-r--r--src/System.Security.Cryptography.Encoding/src/Internal/Cryptography/OidLookup.cs226
-rw-r--r--src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj7
-rw-r--r--src/System.Security.Cryptography.Encoding/src/project.json3
-rw-r--r--src/System.Security.Cryptography.Encoding/src/project.lock.json211
-rw-r--r--src/System.Security.Cryptography.Encoding/tests/Oid.cs318
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
+}