private unsafe static Cryptography.SafeCertStoreHandle FindCertInStore(Cryptography.SafeCertStoreHandle safeSourceStoreHandle, X509FindType findType, Object findValue, bool validOnly) { if (findValue == null) throw new ArgumentNullException("findValue"); IntPtr pvFindPara = IntPtr.Zero; object pvCallbackData1 = null; object pvCallbackData2 = null; FindProcDelegate pfnCertCallback1 = null; FindProcDelegate pfnCertCallback2 = null; uint dwFindType = CAPI.CERT_FIND_ANY; string subject, issuer; CAPI.CRYPTOAPI_BLOB HashBlob = new CAPI.CRYPTOAPI_BLOB(); SafeLocalAllocHandle pb = SafeLocalAllocHandle.InvalidHandle; _FILETIME ft = new _FILETIME(); string oidValue = null; switch(findType) { case X509FindType.FindByThumbprint: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); byte[] hex = X509Utils.DecodeHexString((string) findValue); pb = X509Utils.ByteToPtr(hex); HashBlob.pbData = pb.DangerousGetHandle(); HashBlob.cbData = (uint) hex.Length; dwFindType = CAPI.CERT_FIND_HASH; pvFindPara = new IntPtr(&HashBlob); break; case X509FindType.FindBySubjectName: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); subject = (string) findValue; dwFindType = CAPI.CERT_FIND_SUBJECT_STR; pb = X509Utils.StringToUniPtr(subject); pvFindPara = pb.DangerousGetHandle(); break; case X509FindType.FindBySubjectDistinguishedName: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); subject = (string) findValue; pfnCertCallback1 = new FindProcDelegate(FindSubjectDistinguishedNameCallback); pvCallbackData1 = subject; break; case X509FindType.FindByIssuerName: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); issuer = (string) findValue; dwFindType = CAPI.CERT_FIND_ISSUER_STR; pb = X509Utils.StringToUniPtr(issuer); pvFindPara = pb.DangerousGetHandle(); break; case X509FindType.FindByIssuerDistinguishedName: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); issuer = (string) findValue; pfnCertCallback1 = new FindProcDelegate(FindIssuerDistinguishedNameCallback); pvCallbackData1 = issuer; break; case X509FindType.FindBySerialNumber: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); pfnCertCallback1 = new FindProcDelegate(FindSerialNumberCallback); pfnCertCallback2 = new FindProcDelegate(FindSerialNumberCallback); BigInt h = new BigInt(); h.FromHexadecimal((string) findValue); pvCallbackData1 = (byte[]) h.ToByteArray(); h.FromDecimal((string) findValue); pvCallbackData2 = (byte[]) h.ToByteArray(); break; case X509FindType.FindByTimeValid: if (findValue.GetType() != typeof(DateTime)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); *((long*) &ft) = ((DateTime) findValue).ToFileTime(); pfnCertCallback1 = new FindProcDelegate(FindTimeValidCallback); pvCallbackData1 = ft; break; case X509FindType.FindByTimeNotYetValid: if (findValue.GetType() != typeof(DateTime)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); *((long*) &ft) = ((DateTime) findValue).ToFileTime(); pfnCertCallback1 = new FindProcDelegate(FindTimeNotBeforeCallback); pvCallbackData1 = ft; break; case X509FindType.FindByTimeExpired: if (findValue.GetType() != typeof(DateTime)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); *((long*) &ft) = ((DateTime) findValue).ToFileTime(); pfnCertCallback1 = new FindProcDelegate(FindTimeNotAfterCallback); pvCallbackData1 = ft; break; case X509FindType.FindByTemplateName: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); pvCallbackData1 = (string) findValue; pfnCertCallback1 = new FindProcDelegate(FindTemplateNameCallback); break; case X509FindType.FindByApplicationPolicy: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); // If we were passed the friendly name, retrieve the value string. oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string) findValue, Cryptography.OidGroup.Policy); if (oidValue == null) { oidValue = (string) findValue; X509Utils.ValidateOidValue(oidValue); } pvCallbackData1 = oidValue; pfnCertCallback1 = new FindProcDelegate(FindApplicationPolicyCallback); break; case X509FindType.FindByCertificatePolicy: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); // If we were passed the friendly name, retrieve the value string. oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string)findValue, Cryptography.OidGroup.Policy); if (oidValue == null) { oidValue = (string) findValue; X509Utils.ValidateOidValue(oidValue); } pvCallbackData1 = oidValue; pfnCertCallback1 = new FindProcDelegate(FindCertificatePolicyCallback); break; case X509FindType.FindByExtension: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); // If we were passed the friendly name, retrieve the value string. oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string)findValue, Cryptography.OidGroup.ExtensionOrAttribute); if (oidValue == null) { oidValue = (string) findValue; X509Utils.ValidateOidValue(oidValue); } pvCallbackData1 = oidValue; pfnCertCallback1 = new FindProcDelegate(FindExtensionCallback); break; case X509FindType.FindByKeyUsage: // The findValue object can be either a friendly name, a X509KeyUsageFlags enum or an integer. if (findValue.GetType() == typeof(string)) { CAPI.KEY_USAGE_STRUCT[] KeyUsages = new CAPI.KEY_USAGE_STRUCT[] { new CAPI.KEY_USAGE_STRUCT("DigitalSignature", CAPI.CERT_DIGITAL_SIGNATURE_KEY_USAGE), new CAPI.KEY_USAGE_STRUCT("NonRepudiation", CAPI.CERT_NON_REPUDIATION_KEY_USAGE), new CAPI.KEY_USAGE_STRUCT("KeyEncipherment", CAPI.CERT_KEY_ENCIPHERMENT_KEY_USAGE), new CAPI.KEY_USAGE_STRUCT("DataEncipherment", CAPI.CERT_DATA_ENCIPHERMENT_KEY_USAGE), new CAPI.KEY_USAGE_STRUCT("KeyAgreement", CAPI.CERT_KEY_AGREEMENT_KEY_USAGE), new CAPI.KEY_USAGE_STRUCT("KeyCertSign", CAPI.CERT_KEY_CERT_SIGN_KEY_USAGE), new CAPI.KEY_USAGE_STRUCT("CrlSign", CAPI.CERT_CRL_SIGN_KEY_USAGE), new CAPI.KEY_USAGE_STRUCT("EncipherOnly", CAPI.CERT_ENCIPHER_ONLY_KEY_USAGE), new CAPI.KEY_USAGE_STRUCT("DecipherOnly", CAPI.CERT_DECIPHER_ONLY_KEY_USAGE) }; for (uint index = 0; index < KeyUsages.Length; index++) { if (String.Compare(KeyUsages[index].pwszKeyUsage, (string) findValue, StringComparison.OrdinalIgnoreCase) == 0) { pvCallbackData1 = KeyUsages[index].dwKeyUsageBit; break; } } if (pvCallbackData1 == null) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType)); } else if (findValue.GetType() == typeof(X509KeyUsageFlags)) { pvCallbackData1 = findValue; } else if (findValue.GetType() == typeof(uint) || findValue.GetType() == typeof(int)) { // We got the actual DWORD pvCallbackData1 = findValue; } else throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType)); pfnCertCallback1 = new FindProcDelegate(FindKeyUsageCallback); break; case X509FindType.FindBySubjectKeyIdentifier: if (findValue.GetType() != typeof(string)) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindValue)); pvCallbackData1 = (byte[]) X509Utils.DecodeHexString((string) findValue); pfnCertCallback1 = new FindProcDelegate(FindSubjectKeyIdentifierCallback); break; default: throw new CryptographicException(SR.GetString(SR.Cryptography_X509_InvalidFindType)); } // First, create a memory store Cryptography.SafeCertStoreHandle safeTargetStoreHandle = CAPI.CertOpenStore(new IntPtr(CAPI.CERT_STORE_PROV_MEMORY), CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, IntPtr.Zero, CAPI.CERT_STORE_ENUM_ARCHIVED_FLAG | CAPI.CERT_STORE_CREATE_NEW_FLAG, null); if (safeTargetStoreHandle == null || safeTargetStoreHandle.IsInvalid) throw new CryptographicException(Marshal.GetLastWin32Error()); // FindByCert will throw an exception in case of failures. FindByCert(safeSourceStoreHandle, dwFindType, pvFindPara, validOnly, pfnCertCallback1, pfnCertCallback2, pvCallbackData1, pvCallbackData2, safeTargetStoreHandle); pb.Dispose(); return safeTargetStoreHandle; }
private static unsafe System.Security.Cryptography.SafeCertStoreHandle FindCertInStore(System.Security.Cryptography.SafeCertStoreHandle safeSourceStoreHandle, X509FindType findType, object findValue, bool validOnly) { string str; string str2; System.Security.Cryptography.SafeCertStoreHandle handle2; if (findValue == null) { throw new ArgumentNullException("findValue"); } IntPtr zero = IntPtr.Zero; object dwKeyUsageBit = null; object obj3 = null; FindProcDelegate delegate2 = null; FindProcDelegate delegate3 = null; uint dwFindType = 0; CAPIBase.CRYPTOAPI_BLOB cryptoapi_blob = new CAPIBase.CRYPTOAPI_BLOB(); SafeLocalAllocHandle invalidHandle = SafeLocalAllocHandle.InvalidHandle; System.Runtime.InteropServices.ComTypes.FILETIME filetime = new System.Runtime.InteropServices.ComTypes.FILETIME(); string keyValue = null; switch (findType) { case X509FindType.FindByThumbprint: { if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } byte[] managed = System.Security.Cryptography.X509Certificates.X509Utils.DecodeHexString((string) findValue); cryptoapi_blob.pbData = System.Security.Cryptography.X509Certificates.X509Utils.ByteToPtr(managed).DangerousGetHandle(); cryptoapi_blob.cbData = (uint) managed.Length; dwFindType = 0x10000; zero = new IntPtr((void*) &cryptoapi_blob); goto Label_0703; } case X509FindType.FindBySubjectName: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } str = (string) findValue; dwFindType = 0x80007; zero = System.Security.Cryptography.X509Certificates.X509Utils.StringToUniPtr(str).DangerousGetHandle(); goto Label_0703; case X509FindType.FindBySubjectDistinguishedName: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } str = (string) findValue; delegate2 = new FindProcDelegate(X509Certificate2Collection.FindSubjectDistinguishedNameCallback); dwKeyUsageBit = str; goto Label_0703; case X509FindType.FindByIssuerName: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } str2 = (string) findValue; dwFindType = 0x80004; invalidHandle = System.Security.Cryptography.X509Certificates.X509Utils.StringToUniPtr(str2); zero = invalidHandle.DangerousGetHandle(); goto Label_0703; case X509FindType.FindByIssuerDistinguishedName: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } str2 = (string) findValue; delegate2 = new FindProcDelegate(X509Certificate2Collection.FindIssuerDistinguishedNameCallback); dwKeyUsageBit = str2; goto Label_0703; case X509FindType.FindBySerialNumber: { if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } delegate2 = new FindProcDelegate(X509Certificate2Collection.FindSerialNumberCallback); delegate3 = new FindProcDelegate(X509Certificate2Collection.FindSerialNumberCallback); BigInt num2 = new BigInt(); num2.FromHexadecimal((string) findValue); dwKeyUsageBit = num2.ToByteArray(); num2.FromDecimal((string) findValue); obj3 = num2.ToByteArray(); goto Label_0703; } case X509FindType.FindByTimeValid: if (findValue.GetType() != typeof(DateTime)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } *((long*) &filetime) = ((DateTime) findValue).ToFileTime(); delegate2 = new FindProcDelegate(X509Certificate2Collection.FindTimeValidCallback); dwKeyUsageBit = filetime; goto Label_0703; case X509FindType.FindByTimeNotYetValid: if (findValue.GetType() != typeof(DateTime)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } *((long*) &filetime) = ((DateTime) findValue).ToFileTime(); delegate2 = new FindProcDelegate(X509Certificate2Collection.FindTimeNotBeforeCallback); dwKeyUsageBit = filetime; goto Label_0703; case X509FindType.FindByTimeExpired: if (findValue.GetType() != typeof(DateTime)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } *((long*) &filetime) = ((DateTime) findValue).ToFileTime(); delegate2 = new FindProcDelegate(X509Certificate2Collection.FindTimeNotAfterCallback); dwKeyUsageBit = filetime; goto Label_0703; case X509FindType.FindByTemplateName: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } dwKeyUsageBit = (string) findValue; delegate2 = new FindProcDelegate(X509Certificate2Collection.FindTemplateNameCallback); goto Label_0703; case X509FindType.FindByApplicationPolicy: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } keyValue = System.Security.Cryptography.X509Certificates.X509Utils.FindOidInfo(2, (string) findValue, System.Security.Cryptography.OidGroup.Policy); if (keyValue == null) { keyValue = (string) findValue; System.Security.Cryptography.X509Certificates.X509Utils.ValidateOidValue(keyValue); } dwKeyUsageBit = keyValue; delegate2 = new FindProcDelegate(X509Certificate2Collection.FindApplicationPolicyCallback); goto Label_0703; case X509FindType.FindByCertificatePolicy: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } keyValue = System.Security.Cryptography.X509Certificates.X509Utils.FindOidInfo(2, (string) findValue, System.Security.Cryptography.OidGroup.Policy); if (keyValue == null) { keyValue = (string) findValue; System.Security.Cryptography.X509Certificates.X509Utils.ValidateOidValue(keyValue); } dwKeyUsageBit = keyValue; delegate2 = new FindProcDelegate(X509Certificate2Collection.FindCertificatePolicyCallback); goto Label_0703; case X509FindType.FindByExtension: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } keyValue = System.Security.Cryptography.X509Certificates.X509Utils.FindOidInfo(2, (string) findValue, System.Security.Cryptography.OidGroup.ExtensionOrAttribute); if (keyValue == null) { keyValue = (string) findValue; System.Security.Cryptography.X509Certificates.X509Utils.ValidateOidValue(keyValue); } dwKeyUsageBit = keyValue; delegate2 = new FindProcDelegate(X509Certificate2Collection.FindExtensionCallback); goto Label_0703; case X509FindType.FindByKeyUsage: { if (!(findValue.GetType() == typeof(string))) { if (findValue.GetType() == typeof(X509KeyUsageFlags)) { dwKeyUsageBit = findValue; } else { if (!(findValue.GetType() == typeof(uint)) && !(findValue.GetType() == typeof(int))) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindType")); } dwKeyUsageBit = findValue; } goto Label_06A2; } CAPIBase.KEY_USAGE_STRUCT[] key_usage_structArray = new CAPIBase.KEY_USAGE_STRUCT[] { new CAPIBase.KEY_USAGE_STRUCT("DigitalSignature", 0x80), new CAPIBase.KEY_USAGE_STRUCT("NonRepudiation", 0x40), new CAPIBase.KEY_USAGE_STRUCT("KeyEncipherment", 0x20), new CAPIBase.KEY_USAGE_STRUCT("DataEncipherment", 0x10), new CAPIBase.KEY_USAGE_STRUCT("KeyAgreement", 8), new CAPIBase.KEY_USAGE_STRUCT("KeyCertSign", 4), new CAPIBase.KEY_USAGE_STRUCT("CrlSign", 2), new CAPIBase.KEY_USAGE_STRUCT("EncipherOnly", 1), new CAPIBase.KEY_USAGE_STRUCT("DecipherOnly", 0x8000) }; for (uint i = 0; i < key_usage_structArray.Length; i++) { if (string.Compare(key_usage_structArray[i].pwszKeyUsage, (string) findValue, StringComparison.OrdinalIgnoreCase) == 0) { dwKeyUsageBit = key_usage_structArray[i].dwKeyUsageBit; break; } } break; } case X509FindType.FindBySubjectKeyIdentifier: if (findValue.GetType() != typeof(string)) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindValue")); } dwKeyUsageBit = System.Security.Cryptography.X509Certificates.X509Utils.DecodeHexString((string) findValue); delegate2 = new FindProcDelegate(X509Certificate2Collection.FindSubjectKeyIdentifierCallback); goto Label_0703; default: throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindType")); } if (dwKeyUsageBit == null) { throw new CryptographicException(SR.GetString("Cryptography_X509_InvalidFindType")); } Label_06A2: delegate2 = new FindProcDelegate(X509Certificate2Collection.FindKeyUsageCallback); Label_0703: handle2 = CAPI.CertOpenStore(new IntPtr(2L), 0x10001, IntPtr.Zero, 0x2200, null); if ((handle2 == null) || handle2.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } FindByCert(safeSourceStoreHandle, dwFindType, zero, validOnly, delegate2, delegate3, dwKeyUsageBit, obj3, handle2); invalidHandle.Dispose(); return handle2; }