private static void EnumerateProviders() { if (Providers != null) { return; } lock (Locker) { if (Providers != null) { return; } Providers = new List <ProviderInfo>(); var dwIndex = 0; int dwType = 1; int cbName = 0; while (CryptoApiEx.CryptEnumProviders(dwIndex, IntPtr.Zero, 0, ref dwType, null, ref cbName)) { var pszName = new StringBuilder((int)cbName + 1); if (!CryptoApiEx.CryptEnumProviders(dwIndex++, IntPtr.Zero, 0, ref dwType, pszName, ref cbName)) { continue; } Providers.Add(new ProviderInfo() { ProviderType = dwType, ProviderName = pszName.ToString() }); } foreach (var providerInfo in Providers) { providerInfo.Initialize(); } } }
public void Initialize() { var reOid = new Regex("^[0-9]+([.][0-9]+)+$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); IntPtr cspHandler = IntPtr.Zero; IntPtr pnt = IntPtr.Zero; try { if (!CryptoApi.CryptAcquireContext(ref cspHandler, null, ProviderName, ProviderType, Constants.CryptVerifycontext)) { throw new Win32Exception(); } int dwDataLen = Marshal.SizeOf(typeof(CryptoApiEx.PROV_ENUMALGS_EX)) * 2; pnt = Marshal.AllocHGlobal(dwDataLen); uint dwFlags = 1; while (CryptoApiEx.CryptGetProvParam(cspHandler, Constants.PP_ENUMALGS_EX, pnt, ref dwDataLen, dwFlags)) { var data = (CryptoApiEx.PROV_ENUMALGS_EX)Marshal.PtrToStructure(pnt, typeof(CryptoApiEx.PROV_ENUMALGS_EX)); IntPtr oidPtr = CryptoApiEx.CertAlgIdToOID(data.aiAlgid); var oid = Marshal.PtrToStringAnsi(oidPtr); if (string.IsNullOrEmpty(oid) || !reOid.IsMatch(oid)) { oid = string.Empty; } this.Add(new ProviderAlgo() { AlgId = data.aiAlgid, Oid = oid, Name = data.szName, LongName = data.szLongName, MinLen = data.dwMinLen, MaxLen = data.dwMaxLen, DefaultLen = data.dwDefaultLen, Protocols = data.dwProtocols }); dwFlags = 2; } } finally { if (pnt != IntPtr.Zero) { Marshal.FreeHGlobal(pnt); } if (cspHandler != IntPtr.Zero) { CryptoApi.CryptReleaseContext(cspHandler, 0); } } }
private void LookForSignatureGroup(ProviderAlgo hashAlgo, ProviderAlgo signAlgo) { int[] algIds = new[] { hashAlgo.AlgId, signAlgo.AlgId }; var ptr = CryptoApiEx.CryptFindOIDInfo(CryptoApiEx.CRYPT_OID_INFO_SIGN_KEY, algIds, CryptoApiEx.CRYPT_SIGN_ALG_OID_GROUP_ID); if (ptr == IntPtr.Zero) { return; } var oidInfo = (CryptoApiEx.CRYPT_OID_INFO)Marshal.PtrToStructure(ptr, typeof(CryptoApiEx.CRYPT_OID_INFO)); var oid = Marshal.PtrToStringAnsi(oidInfo.pszOID); // SignGroups.Add(new ProviderSignGroup() { AlgId = oidInfo.Algid, HashAlgo = hashAlgo, SignAlgo = signAlgo, Oid = oid, Name = Marshal.PtrToStringUni(oidInfo.pwszName) }); }