private static unsafe int FindKeyUsageCallback(Cryptography.SafeCertContextHandle safeCertContextHandle, object pvCallbackData) { CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle()); uint dwUsages = 0; if (!CAPI.CertGetIntendedKeyUsage(CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, pCertContext.pCertInfo, new IntPtr(&dwUsages), 4 /* sizeof(DWORD) */)) return CAPI.S_OK; // no key usage means it is valid for all key usages. uint dwCheckUsage = Convert.ToUInt32(pvCallbackData, null); if ((dwUsages & dwCheckUsage) == dwCheckUsage) return CAPI.S_OK; return CAPI.S_FALSE; }
private static unsafe int FindCertificatePolicyCallback(Cryptography.SafeCertContextHandle safeCertContextHandle, object pvCallbackData) { string certPolicy = (string) pvCallbackData; if (certPolicy.Length == 0) return CAPI.S_FALSE; CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle()); CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO)); IntPtr pExtension = CAPI.CertFindExtension(CAPI.szOID_CERT_POLICIES, pCertInfo.cExtension, pCertInfo.rgExtension); if (pExtension == IntPtr.Zero) return CAPI.S_FALSE; CAPI.CERT_EXTENSION extension = (CAPI.CERT_EXTENSION) Marshal.PtrToStructure(pExtension, typeof(CAPI.CERT_EXTENSION)); byte[] rawData = new byte[extension.Value.cbData]; Marshal.Copy(extension.Value.pbData, rawData, 0, rawData.Length); uint cbDecoded = 0; SafeLocalAllocHandle decoded = null; // Decode the extension. bool result = CAPI.DecodeObject(new IntPtr(CAPI.X509_CERT_POLICIES), rawData, out decoded, out cbDecoded); if (result) { CAPI.CERT_POLICIES_INFO pInfo = (CAPI.CERT_POLICIES_INFO) Marshal.PtrToStructure(decoded.DangerousGetHandle(), typeof(CAPI.CERT_POLICIES_INFO)); for (int index = 0; index < pInfo.cPolicyInfo; index++) { IntPtr pPolicyInfoPtr = new IntPtr((long) pInfo.rgPolicyInfo + index * Marshal.SizeOf(typeof(CAPI.CERT_POLICY_INFO))); CAPI.CERT_POLICY_INFO pPolicyInfo = (CAPI.CERT_POLICY_INFO) Marshal.PtrToStructure(pPolicyInfoPtr, typeof(CAPI.CERT_POLICY_INFO)); if (String.Compare(certPolicy, pPolicyInfo.pszPolicyIdentifier, StringComparison.OrdinalIgnoreCase) == 0) return CAPI.S_OK; } } return CAPI.S_FALSE; }
private static unsafe int FindExtensionCallback(Cryptography.SafeCertContextHandle safeCertContextHandle, object pvCallbackData) { CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle()); CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO)); IntPtr pExtension = CAPI.CertFindExtension((string) pvCallbackData, pCertInfo.cExtension, pCertInfo.rgExtension); if (pExtension == IntPtr.Zero) return CAPI.S_FALSE; return CAPI.S_OK; }
private static unsafe int FindTemplateNameCallback(Cryptography.SafeCertContextHandle safeCertContextHandle, object pvCallbackData) { IntPtr pV1Template = IntPtr.Zero; IntPtr pV2Template = IntPtr.Zero; CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle()); CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO)); pV1Template = CAPI.CertFindExtension(CAPI.szOID_ENROLL_CERTTYPE_EXTENSION, pCertInfo.cExtension, pCertInfo.rgExtension); pV2Template = CAPI.CertFindExtension(CAPI.szOID_CERTIFICATE_TEMPLATE, pCertInfo.cExtension, pCertInfo.rgExtension); if (pV1Template == IntPtr.Zero && pV2Template == IntPtr.Zero) return CAPI.S_FALSE; if (pV1Template != IntPtr.Zero) { CAPI.CERT_EXTENSION extension = (CAPI.CERT_EXTENSION) Marshal.PtrToStructure(pV1Template, typeof(CAPI.CERT_EXTENSION)); byte[] rawData = new byte[extension.Value.cbData]; Marshal.Copy(extension.Value.pbData, rawData, 0, rawData.Length); uint cbDecoded = 0; SafeLocalAllocHandle decoded = null; // Decode the extension. bool result = CAPI.DecodeObject(new IntPtr(CAPI.X509_UNICODE_ANY_STRING), rawData, out decoded, out cbDecoded); if (result) { CAPI.CERT_NAME_VALUE pNameValue = (CAPI.CERT_NAME_VALUE) Marshal.PtrToStructure(decoded.DangerousGetHandle(), typeof(CAPI.CERT_NAME_VALUE)); string s = Marshal.PtrToStringUni(pNameValue.Value.pbData); if (String.Compare(s, (string) pvCallbackData, StringComparison.OrdinalIgnoreCase) == 0) return CAPI.S_OK; } } if (pV2Template != IntPtr.Zero) { CAPI.CERT_EXTENSION extension = (CAPI.CERT_EXTENSION) Marshal.PtrToStructure(pV2Template, typeof(CAPI.CERT_EXTENSION)); byte[] rawData = new byte[extension.Value.cbData]; Marshal.Copy(extension.Value.pbData, rawData, 0, rawData.Length); uint cbDecoded = 0; SafeLocalAllocHandle decoded = null; // Decode the extension. bool result = CAPI.DecodeObject(new IntPtr(CAPI.X509_CERTIFICATE_TEMPLATE), rawData, out decoded, out cbDecoded); if (result) { CAPI.CERT_TEMPLATE_EXT pTemplate = (CAPI.CERT_TEMPLATE_EXT) Marshal.PtrToStructure(decoded.DangerousGetHandle(), typeof(CAPI.CERT_TEMPLATE_EXT)); // If we were passed the friendly name, retrieve the value string. string oidValue = X509Utils.FindOidInfoWithFallback(CAPI.CRYPT_OID_INFO_NAME_KEY, (string)pvCallbackData, Cryptography.OidGroup.Template); if (oidValue == null) oidValue = (string) pvCallbackData; if (String.Compare(pTemplate.pszObjId, oidValue, StringComparison.OrdinalIgnoreCase) == 0) return CAPI.S_OK; } } return CAPI.S_FALSE; }
private static unsafe int FindApplicationPolicyCallback(Cryptography.SafeCertContextHandle safeCertContextHandle, object pvCallbackData) { string eku = (string) pvCallbackData; if (eku.Length == 0) return CAPI.S_FALSE; IntPtr pCertContext = safeCertContextHandle.DangerousGetHandle(); int cNumOIDs = 0; uint cbOIDs = 0; SafeLocalAllocHandle rghOIDs = SafeLocalAllocHandle.InvalidHandle; if (!CAPI.CertGetValidUsages(1, new IntPtr(&pCertContext), new IntPtr(&cNumOIDs), rghOIDs, new IntPtr(&cbOIDs))) return CAPI.S_FALSE; rghOIDs = CAPI.LocalAlloc(CAPI.LMEM_FIXED, new IntPtr(cbOIDs)); if (!CAPI.CertGetValidUsages(1, new IntPtr(&pCertContext), new IntPtr(&cNumOIDs), rghOIDs, new IntPtr(&cbOIDs))) return CAPI.S_FALSE; // -1 means the certificate is good for all usages. if (cNumOIDs == -1) return CAPI.S_OK; for (int index = 0; index < cNumOIDs; index++) { IntPtr pszOid = Marshal.ReadIntPtr(new IntPtr((long) rghOIDs.DangerousGetHandle() + index * Marshal.SizeOf(typeof(IntPtr)))); string oidValue = Marshal.PtrToStringAnsi(pszOid); if (String.Compare(eku, oidValue, StringComparison.OrdinalIgnoreCase) == 0) return CAPI.S_OK; } return CAPI.S_FALSE; }
private static unsafe int FindTimeNotBeforeCallback(Cryptography.SafeCertContextHandle safeCertContextHandle, object pvCallbackData) { _FILETIME ft = (_FILETIME) pvCallbackData; CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle()); if (CAPI.CertVerifyTimeValidity(ref ft, pCertContext.pCertInfo) == -1) return CAPI.S_OK; return CAPI.S_FALSE; }
private static unsafe int FindSerialNumberCallback(Cryptography.SafeCertContextHandle safeCertContextHandle, object pvCallbackData) { CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle()); CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO)); byte[] hex = new byte[pCertInfo.SerialNumber.cbData]; Marshal.Copy(pCertInfo.SerialNumber.pbData, hex, 0, hex.Length); int size = X509Utils.GetHexArraySize(hex); byte[] serialNumber = (byte[]) pvCallbackData; if (serialNumber.Length != size) return CAPI.S_FALSE; for (int index = 0; index < serialNumber.Length; index++) { if (serialNumber[index] != hex[index]) return CAPI.S_FALSE; } return CAPI.S_OK; }
private static unsafe uint GetVersion (Cryptography.SafeCertContextHandle safeCertContextHandle) { CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle()); CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO)); return (pCertInfo.dwVersion + 1); }
private static unsafe Oid GetSignatureAlgorithm (Cryptography.SafeCertContextHandle safeCertContextHandle) { CAPI.CERT_CONTEXT pCertContext = *((CAPI.CERT_CONTEXT*) safeCertContextHandle.DangerousGetHandle()); CAPI.CERT_INFO pCertInfo = (CAPI.CERT_INFO) Marshal.PtrToStructure(pCertContext.pCertInfo, typeof(CAPI.CERT_INFO)); return new Oid(pCertInfo.SignatureAlgorithm.pszObjId, Cryptography.OidGroup.SignatureAlgorithm, false); }
private static void RemoveCertificateFromStore(Cryptography.SafeCertStoreHandle safeCertStoreHandle, Cryptography.SafeCertContextHandle safeCertContext) { if (safeCertContext == null || safeCertContext.IsInvalid) return; if (safeCertStoreHandle == null || safeCertStoreHandle.IsInvalid || safeCertStoreHandle.IsClosed) throw new CryptographicException(SR.GetString(SR.Cryptography_X509_StoreNotOpen)); // Find the certificate in the store. Cryptography.SafeCertContextHandle safeCertContext2 = CAPI.CertFindCertificateInStore(safeCertStoreHandle, CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING, 0, CAPI.CERT_FIND_EXISTING, safeCertContext.DangerousGetHandle(), Cryptography.SafeCertContextHandle.InvalidHandle); // The certificate is not present in the store, simply return. if (safeCertContext2 == null || safeCertContext2.IsInvalid) return; // CertDeleteCertificateFromStore always releases the context regardless of success // or failure so we don't need to manually release it GC.SuppressFinalize(safeCertContext2); // Remove from the store. if (!CAPI.CertDeleteCertificateFromStore(safeCertContext2)) throw new CryptographicException(Marshal.GetLastWin32Error()); }