private static void FindByCert(Cryptography.SafeCertStoreHandle safeSourceStoreHandle, 
                                        uint dwFindType, 
                                        IntPtr pvFindPara, 
                                        bool validOnly, 
                                        FindProcDelegate pfnCertCallback1, 
                                        FindProcDelegate pfnCertCallback2, 
                                        object pvCallbackData1, 
                                        object pvCallbackData2,
                                        Cryptography.SafeCertStoreHandle safeTargetStoreHandle) {

            int hr = CAPI.S_OK;

            Cryptography.SafeCertContextHandle pEnumContext = Cryptography.SafeCertContextHandle.InvalidHandle;
            pEnumContext = CAPI.CertFindCertificateInStore(safeSourceStoreHandle, 
                                                           CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                           0, 
                                                           dwFindType,
                                                           pvFindPara,
                                                           pEnumContext);

            while (pEnumContext != null && !pEnumContext.IsInvalid) {
                if (pfnCertCallback1 != null) {
                    hr = pfnCertCallback1(pEnumContext, pvCallbackData1);
                    if (hr == CAPI.S_FALSE) {
                        if (pfnCertCallback2 != null) 
                            hr = pfnCertCallback2(pEnumContext, pvCallbackData2);

                        if (hr == CAPI.S_FALSE) // skip this certificate
                            goto skip;
                    }

                    if (hr != CAPI.S_OK)
                        break;
                }

                if (validOnly) {
                    hr = X509Utils.VerifyCertificate(pEnumContext, 
                                           null,
                                           null,
                                           X509RevocationMode.NoCheck,
                                           X509RevocationFlag.ExcludeRoot,
                                           DateTime.Now,
                                           new TimeSpan(0, 0, 0), // default
                                           null,
                                           new IntPtr(CAPI.CERT_CHAIN_POLICY_BASE), 
                                           IntPtr.Zero);
                    if (hr == CAPI.S_FALSE) // skip this certificate
                        goto skip;

                    if (hr != CAPI.S_OK)
                        break;
                }

                //
                // We use CertAddCertificateLinkToStore to keep a link to the original store, so any property changes get
                // applied to the original store. This has a limit of 99 links per cert context however.
                //

                if (!CAPI.CertAddCertificateLinkToStore(safeTargetStoreHandle, 
                                                        pEnumContext, 
                                                        CAPI.CERT_STORE_ADD_ALWAYS,
                                                        Cryptography.SafeCertContextHandle.InvalidHandle)) {
                    hr = Marshal.GetHRForLastWin32Error();
                    break;
                }

skip:
                // CertFindCertificateInStore always releases the context regardless of success 
                // or failure so we don't need to manually release it
                GC.SuppressFinalize(pEnumContext);

                pEnumContext = CAPI.CertFindCertificateInStore(safeSourceStoreHandle, 
                                                               CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                               0, 
                                                               dwFindType, 
                                                               pvFindPara,
                                                               pEnumContext);
            }

            if (pEnumContext != null && !pEnumContext.IsInvalid)
                pEnumContext.Dispose();

            if (hr != CAPI.S_FALSE && hr != CAPI.S_OK)
                throw new CryptographicException(hr);
        }
        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;
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        private static void FindByCert(System.Security.Cryptography.SafeCertStoreHandle safeSourceStoreHandle, uint dwFindType, IntPtr pvFindPara, bool validOnly, FindProcDelegate pfnCertCallback1, FindProcDelegate pfnCertCallback2, object pvCallbackData1, object pvCallbackData2, System.Security.Cryptography.SafeCertStoreHandle safeTargetStoreHandle)
        {
            int hr = 0;

            System.Security.Cryptography.SafeCertContextHandle invalidHandle = System.Security.Cryptography.SafeCertContextHandle.InvalidHandle;
            invalidHandle = CAPI.CertFindCertificateInStore(safeSourceStoreHandle, 0x10001, 0, dwFindType, pvFindPara, invalidHandle);
            while ((invalidHandle != null) && !invalidHandle.IsInvalid)
            {
                if (pfnCertCallback1 != null)
                {
                    hr = pfnCertCallback1(invalidHandle, pvCallbackData1);
                    if (hr == 1)
                    {
                        if (pfnCertCallback2 != null)
                        {
                            hr = pfnCertCallback2(invalidHandle, pvCallbackData2);
                        }
                        if (hr == 1)
                        {
                            goto Label_008D;
                        }
                    }
                    if (hr != 0)
                    {
                        break;
                    }
                }
                if (validOnly)
                {
                    hr = System.Security.Cryptography.X509Certificates.X509Utils.VerifyCertificate(invalidHandle, null, null, X509RevocationMode.NoCheck, X509RevocationFlag.ExcludeRoot, DateTime.Now, new TimeSpan(0, 0, 0), null, new IntPtr(1L), IntPtr.Zero);
                    if (hr == 1)
                    {
                        goto Label_008D;
                    }
                    if (hr != 0)
                    {
                        break;
                    }
                }
                if (!CAPI.CertAddCertificateLinkToStore(safeTargetStoreHandle, invalidHandle, 4, System.Security.Cryptography.SafeCertContextHandle.InvalidHandle))
                {
                    hr = Marshal.GetHRForLastWin32Error();
                    break;
                }
Label_008D:
                GC.SuppressFinalize(invalidHandle);
                invalidHandle = CAPI.CertFindCertificateInStore(safeSourceStoreHandle, 0x10001, 0, dwFindType, pvFindPara, invalidHandle);
            }
            if ((invalidHandle != null) && !invalidHandle.IsInvalid)
            {
                invalidHandle.Dispose();
            }
            if ((hr != 1) && (hr != 0))
            {
                throw new CryptographicException(hr);
            }
        }
        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;
        }
 private static void FindByCert(System.Security.Cryptography.SafeCertStoreHandle safeSourceStoreHandle, uint dwFindType, IntPtr pvFindPara, bool validOnly, FindProcDelegate pfnCertCallback1, FindProcDelegate pfnCertCallback2, object pvCallbackData1, object pvCallbackData2, System.Security.Cryptography.SafeCertStoreHandle safeTargetStoreHandle)
 {
     int hr = 0;
     System.Security.Cryptography.SafeCertContextHandle invalidHandle = System.Security.Cryptography.SafeCertContextHandle.InvalidHandle;
     invalidHandle = CAPI.CertFindCertificateInStore(safeSourceStoreHandle, 0x10001, 0, dwFindType, pvFindPara, invalidHandle);
     while ((invalidHandle != null) && !invalidHandle.IsInvalid)
     {
         if (pfnCertCallback1 != null)
         {
             hr = pfnCertCallback1(invalidHandle, pvCallbackData1);
             if (hr == 1)
             {
                 if (pfnCertCallback2 != null)
                 {
                     hr = pfnCertCallback2(invalidHandle, pvCallbackData2);
                 }
                 if (hr == 1)
                 {
                     goto Label_008D;
                 }
             }
             if (hr != 0)
             {
                 break;
             }
         }
         if (validOnly)
         {
             hr = System.Security.Cryptography.X509Certificates.X509Utils.VerifyCertificate(invalidHandle, null, null, X509RevocationMode.NoCheck, X509RevocationFlag.ExcludeRoot, DateTime.Now, new TimeSpan(0, 0, 0), null, new IntPtr(1L), IntPtr.Zero);
             if (hr == 1)
             {
                 goto Label_008D;
             }
             if (hr != 0)
             {
                 break;
             }
         }
         if (!CAPI.CertAddCertificateLinkToStore(safeTargetStoreHandle, invalidHandle, 4, System.Security.Cryptography.SafeCertContextHandle.InvalidHandle))
         {
             hr = Marshal.GetHRForLastWin32Error();
             break;
         }
     Label_008D:
         GC.SuppressFinalize(invalidHandle);
         invalidHandle = CAPI.CertFindCertificateInStore(safeSourceStoreHandle, 0x10001, 0, dwFindType, pvFindPara, invalidHandle);
     }
     if ((invalidHandle != null) && !invalidHandle.IsInvalid)
     {
         invalidHandle.Dispose();
     }
     if ((hr != 1) && (hr != 0))
     {
         throw new CryptographicException(hr);
     }
 }