private static unsafe byte[] ToBigEndianByteArray(CapiNative.CRYPTOAPI_BLOB blob) { int count = blob.cbData; byte[] data = new byte[count]; Marshal.Copy(blob.pbData, data, 0, count); Array.Reverse(data); return(data); }
private static byte[] CalculateSignerPublicKeyToken(AsymmetricAlgorithm key) { Debug.Assert(key != null, "key != null"); ICspAsymmetricAlgorithm cspAlgorithm = key as ICspAsymmetricAlgorithm; if (cspAlgorithm == null) { return(null); } byte[] publicKey = cspAlgorithm.ExportCspBlob(false); SafeAxlBufferHandle tokenBuffer; unsafe { fixed(byte *pPublicKey = publicKey) { // Safe, since we're ensuring the CAPI buffer going in is sized correctly CapiNative.CRYPTOAPI_BLOB keyBlob = new CapiNative.CRYPTOAPI_BLOB(); keyBlob.cbData = publicKey.Length; keyBlob.pbData = new IntPtr(pPublicKey); int hrToken = CapiNative.UnsafeNativeMethods._AxlPublicKeyBlobToPublicKeyToken(ref keyBlob, out tokenBuffer); if (((uint)hrToken & 0x80000000) != 0) { return(null); } } } bool acquired = false; RuntimeHelpers.PrepareConstrainedRegions(); try { tokenBuffer.DangerousAddRef(ref acquired); return(HexStringToBytes(Marshal.PtrToStringUni(tokenBuffer.DangerousGetHandle()))); } finally { if (acquired) { tokenBuffer.DangerousRelease(); } } }
private static unsafe byte[] CalculateSignerPublicKeyToken(AsymmetricAlgorithm key) { SafeAxlBufferHandle handle; byte[] buffer2; ICspAsymmetricAlgorithm algorithm = key as ICspAsymmetricAlgorithm; if (algorithm == null) { return(null); } byte[] buffer = algorithm.ExportCspBlob(false); fixed(byte *numRef = buffer) { CapiNative.CRYPTOAPI_BLOB pCspPublicKeyBlob = new CapiNative.CRYPTOAPI_BLOB { cbData = buffer.Length, pbData = new IntPtr((void *)numRef) }; if ((CapiNative.UnsafeNativeMethods._AxlPublicKeyBlobToPublicKeyToken(ref pCspPublicKeyBlob, out handle) & -2147483648) != 0) { return(null); } } bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { handle.DangerousAddRef(ref success); buffer2 = HexStringToBytes(Marshal.PtrToStringUni(handle.DangerousGetHandle())); } finally { if (success) { handle.DangerousRelease(); } } return(buffer2); }
private AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { Debug.Assert(signatureNode != null, "signatureNode != null"); // See if there is an Authenticode signature on the manifest XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license", m_namespaceManager) as XmlElement; if (licenseNode == null) { return(null); } // Make sure that the signature is for this manifest SignatureVerificationResult identityVerification = VerifyAuthenticodeSignatureIdentity(licenseNode); if (identityVerification != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(identityVerification)); } SignatureVerificationResult hashVerification = VerifyAuthenticodeExpectedHash(licenseNode); if (hashVerification != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(hashVerification)); } // Verify the signature, extracting information about it AuthenticodeSignatureInformation authenticodeSignature = null; X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO(); signer.cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO)); X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO(); timestamper.cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO)); RuntimeHelpers.PrepareConstrainedRegions(); try { byte[] licenseXml = Encoding.UTF8.GetBytes(licenseNode.OuterXml); X509Native.AxlVerificationFlags verificationFlags = MapRevocationFlags(revocationFlag, revocationMode); unsafe { fixed(byte *pLicenseXml = licenseXml) { // Safe since we're verifying the size of this buffer is correct CapiNative.CRYPTOAPI_BLOB xmlBlob = new CapiNative.CRYPTOAPI_BLOB(); xmlBlob.cbData = licenseXml.Length; xmlBlob.pbData = new IntPtr(pLicenseXml); int hrVerify = X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref xmlBlob, verificationFlags, ref signer, ref timestamper); if (hrVerify == (int)SignatureVerificationResult.MissingSignature) { return(new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature)); } } } X509Chain signatureChain = BuildSignatureChain(signer, licenseNode, revocationFlag, revocationMode); TimestampInformation timestamp = GetTimestampInformation(timestamper, licenseNode); authenticodeSignature = new AuthenticodeSignatureInformation(signer, signatureChain, timestamp); } finally { X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref signer); X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref timestamper); } // Verify the signing certificate matches the expected publisher Debug.Assert(authenticodeSignature != null, "authenticodeSignature != null"); if (authenticodeSignature.SigningCertificate == null) { return(new AuthenticodeSignatureInformation(authenticodeSignature.VerificationResult)); } SignatureVerificationResult publisherMatch = VerifyAuthenticodePublisher(authenticodeSignature.SigningCertificate); if (publisherMatch != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(publisherMatch)); } return(authenticodeSignature); }
internal static SafeCertificateContextHandle CreateSelfSignedCertificate(SafeNCryptKeyHandle key, byte[] subjectName, X509CertificateCreationOptions creationOptions, string signatureAlgorithmOid, DateTime startTime, DateTime endTime, X509ExtensionCollection extensions) { Debug.Assert(key != null, "key != null"); Debug.Assert(!key.IsClosed && !key.IsInvalid, "!key.IsClosed && !key.IsInvalid"); Debug.Assert(subjectName != null, "subjectName != null"); Debug.Assert(!String.IsNullOrEmpty(signatureAlgorithmOid), "!String.IsNullOrEmpty(signatureAlgorithmOid)"); Debug.Assert(extensions != null, "extensions != null"); // Create an algorithm identifier structure for the signature algorithm CapiNative.CRYPT_ALGORITHM_IDENTIFIER nativeSignatureAlgorithm = new CapiNative.CRYPT_ALGORITHM_IDENTIFIER(); nativeSignatureAlgorithm.pszObjId = signatureAlgorithmOid; nativeSignatureAlgorithm.Parameters = new CapiNative.CRYPTOAPI_BLOB(); nativeSignatureAlgorithm.Parameters.cbData = 0; nativeSignatureAlgorithm.Parameters.pbData = IntPtr.Zero; // Convert the begin and expire dates to system time structures Win32Native.SYSTEMTIME nativeStartTime = new Win32Native.SYSTEMTIME(startTime); Win32Native.SYSTEMTIME nativeEndTime = new Win32Native.SYSTEMTIME(endTime); // Map the extensions into CERT_EXTENSIONS. This involves several steps to get the // CERT_EXTENSIONS ready for interop with the native APIs. // 1. Build up the CERT_EXTENSIONS structure in managed code // 2. For each extension, create a managed CERT_EXTENSION structure; this requires allocating // native memory for the blob pointer in the CERT_EXTENSION. These extensions are stored in // the nativeExtensionArray variable. // 3. Get a block of native memory that can hold a native array of CERT_EXTENSION structures. // This is the block referenced by the CERT_EXTENSIONS structure. // 4. For each of the extension structures created in step 2, marshal the extension into the // native buffer allocated in step 3. CERT_EXTENSIONS nativeExtensions = new CERT_EXTENSIONS(); nativeExtensions.cExtension = extensions.Count; CERT_EXTENSION[] nativeExtensionArray = new CERT_EXTENSION[extensions.Count]; // Run this in a CER to ensure that we release any native memory allocated for the certificate // extensions. RuntimeHelpers.PrepareConstrainedRegions(); try { // Copy over each extension into a native extension structure, including allocating native // memory for its blob if necessary. for (int i = 0; i < extensions.Count; ++i) { nativeExtensionArray[i] = new CERT_EXTENSION(); nativeExtensionArray[i].pszObjId = extensions[i].Oid.Value; nativeExtensionArray[i].fCritical = extensions[i].Critical; nativeExtensionArray[i].Value = new CapiNative.CRYPTOAPI_BLOB(); nativeExtensionArray[i].Value.cbData = extensions[i].RawData.Length; if (nativeExtensionArray[i].Value.cbData > 0) { nativeExtensionArray[i].Value.pbData = Marshal.AllocCoTaskMem(nativeExtensionArray[i].Value.cbData); Marshal.Copy(extensions[i].RawData, 0, nativeExtensionArray[i].Value.pbData, nativeExtensionArray[i].Value.cbData); } } // Now that we've built up the extension array, create a block of native memory to marshal // them into. if (nativeExtensionArray.Length > 0) { checked { // CERT_EXTENSION structures end with a pointer field, which means on all supported // platforms they won't require any padding between elements of the array. nativeExtensions.rgExtension = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(CERT_EXTENSION)) * nativeExtensionArray.Length); for (int i = 0; i < nativeExtensionArray.Length; ++i) { ulong offset = (uint)i * (uint)Marshal.SizeOf(typeof(CERT_EXTENSION)); ulong next = offset + (ulong)nativeExtensions.rgExtension.ToInt64(); IntPtr nextExtensionAddr = new IntPtr((long)next); Marshal.StructureToPtr(nativeExtensionArray[i], nextExtensionAddr, false); } } } // // Now that all of the needed data structures are setup, we can create the certificate // unsafe { fixed(byte *pSubjectName = &subjectName[0]) { // Create a CRYPTOAPI_BLOB for the subject of the cert CapiNative.CRYPTOAPI_BLOB nativeSubjectName = new CapiNative.CRYPTOAPI_BLOB(); nativeSubjectName.cbData = subjectName.Length; nativeSubjectName.pbData = new IntPtr(pSubjectName); // Now that we've converted all the inputs to native data structures, we can generate // the self signed certificate for the input key. SafeCertificateContextHandle selfSignedCertHandle = UnsafeNativeMethods.CertCreateSelfSignCertificate(key, ref nativeSubjectName, creationOptions, IntPtr.Zero, ref nativeSignatureAlgorithm, ref nativeStartTime, ref nativeEndTime, ref nativeExtensions); if (selfSignedCertHandle.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } return(selfSignedCertHandle); } } } finally { // // In order to release all resources held by the CERT_EXTENSIONS we need to do three things // 1. Destroy each structure marshaled into the native CERT_EXTENSION array // 2. Release the memory used for the CERT_EXTENSION array // 3. Release the memory used in each individual CERT_EXTENSION // // Release each extension marshaled into the native buffer as well if (nativeExtensions.rgExtension != IntPtr.Zero) { for (int i = 0; i < nativeExtensionArray.Length; ++i) { ulong offset = (uint)i * (uint)Marshal.SizeOf(typeof(CERT_EXTENSION)); ulong next = offset + (ulong)nativeExtensions.rgExtension.ToInt64(); IntPtr nextExtensionAddr = new IntPtr((long)next); Marshal.DestroyStructure(nextExtensionAddr, typeof(CERT_EXTENSION)); } Marshal.FreeCoTaskMem(nativeExtensions.rgExtension); } // If we allocated memory for any extensions, make sure to free it now for (int i = 0; i < nativeExtensionArray.Length; ++i) { if (nativeExtensionArray[i].Value.pbData != IntPtr.Zero) { Marshal.FreeCoTaskMem(nativeExtensionArray[i].Value.pbData); } } } }
internal static extern SafeCertificateContextHandle CertCreateSelfSignCertificate(SafeNCryptKeyHandle hCryptProvOrNCryptKey, [In] ref CapiNative.CRYPTOAPI_BLOB pSubjectIssuerBlob, X509CertificateCreationOptions dwFlags, IntPtr pKeyProvInfo, // PCRYPT_KEY_PROV_INFO [In] ref CapiNative.CRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, [In] ref Win32Native.SYSTEMTIME pStartTime, [In] ref Win32Native.SYSTEMTIME pEndTime, [In] ref CERT_EXTENSIONS pExtensions);
public static extern int CertVerifyAuthenticodeLicense(ref CapiNative.CRYPTOAPI_BLOB pLicenseBlob, AxlVerificationFlags dwFlags, [In, Out] ref AXL_AUTHENTICODE_SIGNER_INFO pSignerInfo, [In, Out] ref AXL_AUTHENTICODE_TIMESTAMPER_INFO pTimestamperInfo);
private AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { Debug.Assert(signatureNode != null, "signatureNode != null"); // See if there is an Authenticode signature on the manifest XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license", m_namespaceManager) as XmlElement; if (licenseNode == null) { return null; } // Make sure that the signature is for this manifest SignatureVerificationResult identityVerification = VerifyAuthenticodeSignatureIdentity(licenseNode); if (identityVerification != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(identityVerification); } SignatureVerificationResult hashVerification = VerifyAuthenticodeExpectedHash(licenseNode); if (hashVerification != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(hashVerification); } // Verify the signature, extracting information about it AuthenticodeSignatureInformation authenticodeSignature = null; X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO(); signer.cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO)); X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO(); timestamper.cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO)); RuntimeHelpers.PrepareConstrainedRegions(); try { byte[] licenseXml = Encoding.UTF8.GetBytes(licenseNode.OuterXml); X509Native.AxlVerificationFlags verificationFlags = MapRevocationFlags(revocationFlag, revocationMode); unsafe { fixed (byte* pLicenseXml = licenseXml) { // Safe since we're verifying the size of this buffer is correct CapiNative.CRYPTOAPI_BLOB xmlBlob = new CapiNative.CRYPTOAPI_BLOB(); xmlBlob.cbData = licenseXml.Length; xmlBlob.pbData = new IntPtr(pLicenseXml); int hrVerify = X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref xmlBlob, verificationFlags, ref signer, ref timestamper); if (hrVerify == (int)SignatureVerificationResult.MissingSignature) { return new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature); } } } X509Chain signatureChain = BuildSignatureChain(signer, licenseNode, revocationFlag, revocationMode); TimestampInformation timestamp = GetTimestampInformation(timestamper, licenseNode); authenticodeSignature = new AuthenticodeSignatureInformation(signer, signatureChain, timestamp); } finally { X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref signer); X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref timestamper); } // Verify the signing certificate matches the expected publisher Debug.Assert(authenticodeSignature != null, "authenticodeSignature != null"); if (authenticodeSignature.SigningCertificate == null) { return new AuthenticodeSignatureInformation(authenticodeSignature.VerificationResult); } SignatureVerificationResult publisherMatch = VerifyAuthenticodePublisher(authenticodeSignature.SigningCertificate); if (publisherMatch != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(publisherMatch); } return authenticodeSignature; }
private static byte[] CalculateSignerPublicKeyToken(AsymmetricAlgorithm key) { Debug.Assert(key != null, "key != null"); ICspAsymmetricAlgorithm cspAlgorithm = key as ICspAsymmetricAlgorithm; if (cspAlgorithm == null) { return null; } byte[] publicKey = cspAlgorithm.ExportCspBlob(false); SafeAxlBufferHandle tokenBuffer; unsafe { fixed (byte* pPublicKey = publicKey) { // Safe, since we're ensuring the CAPI buffer going in is sized correctly CapiNative.CRYPTOAPI_BLOB keyBlob = new CapiNative.CRYPTOAPI_BLOB(); keyBlob.cbData = publicKey.Length; keyBlob.pbData = new IntPtr(pPublicKey); int hrToken = CapiNative.UnsafeNativeMethods._AxlPublicKeyBlobToPublicKeyToken(ref keyBlob, out tokenBuffer); if (((uint)hrToken & 0x80000000) != 0) { return null; } } } bool acquired = false; RuntimeHelpers.PrepareConstrainedRegions(); try { tokenBuffer.DangerousAddRef(ref acquired); return HexStringToBytes(Marshal.PtrToStringUni(tokenBuffer.DangerousGetHandle())); } finally { if (acquired) { tokenBuffer.DangerousRelease(); } } }
internal static SafeCertContextHandle CreateSelfSignedCertificate(CngKey key, bool takeOwnershipOfKey, byte[] subjectName, X509CertificateCreationOptions creationOptions, string signatureAlgorithmOid, DateTime startTime, DateTime endTime, X509ExtensionCollection extensions) { Debug.Assert(key != null, "key != null"); Debug.Assert(subjectName != null, "subjectName != null"); Debug.Assert(!String.IsNullOrEmpty(signatureAlgorithmOid), "!String.IsNullOrEmpty(signatureAlgorithmOid)"); Debug.Assert(extensions != null, "extensions != null"); // Create an algorithm identifier structure for the signature algorithm CapiNative.CRYPT_ALGORITHM_IDENTIFIER nativeSignatureAlgorithm = new CapiNative.CRYPT_ALGORITHM_IDENTIFIER(); nativeSignatureAlgorithm.pszObjId = signatureAlgorithmOid; nativeSignatureAlgorithm.Parameters = new CapiNative.CRYPTOAPI_BLOB(); nativeSignatureAlgorithm.Parameters.cbData = 0; nativeSignatureAlgorithm.Parameters.pbData = IntPtr.Zero; // Convert the begin and expire dates to system time structures Win32Native.SYSTEMTIME nativeStartTime = new Win32Native.SYSTEMTIME(startTime); Win32Native.SYSTEMTIME nativeEndTime = new Win32Native.SYSTEMTIME(endTime); // Map the extensions into CERT_EXTENSIONS. This involves several steps to get the // CERT_EXTENSIONS ready for interop with the native APIs. // 1. Build up the CERT_EXTENSIONS structure in managed code // 2. For each extension, create a managed CERT_EXTENSION structure; this requires allocating // native memory for the blob pointer in the CERT_EXTENSION. These extensions are stored in // the nativeExtensionArray variable. // 3. Get a block of native memory that can hold a native array of CERT_EXTENSION structures. // This is the block referenced by the CERT_EXTENSIONS structure. // 4. For each of the extension structures created in step 2, marshal the extension into the // native buffer allocated in step 3. CERT_EXTENSIONS nativeExtensions = new CERT_EXTENSIONS(); nativeExtensions.cExtension = extensions.Count; CERT_EXTENSION[] nativeExtensionArray = new CERT_EXTENSION[extensions.Count]; // Run this in a CER to ensure that we release any native memory allocated for the certificate // extensions. RuntimeHelpers.PrepareConstrainedRegions(); try { // Copy over each extension into a native extension structure, including allocating native // memory for its blob if necessary. for (int i = 0; i < extensions.Count; ++i) { nativeExtensionArray[i] = new CERT_EXTENSION(); nativeExtensionArray[i].pszObjId = extensions[i].Oid.Value; nativeExtensionArray[i].fCritical = extensions[i].Critical; nativeExtensionArray[i].Value = new CapiNative.CRYPTOAPI_BLOB(); nativeExtensionArray[i].Value.cbData = extensions[i].RawData.Length; if (nativeExtensionArray[i].Value.cbData > 0) { nativeExtensionArray[i].Value.pbData = Marshal.AllocCoTaskMem(nativeExtensionArray[i].Value.cbData); Marshal.Copy(extensions[i].RawData, 0, nativeExtensionArray[i].Value.pbData, nativeExtensionArray[i].Value.cbData); } } // Now that we've built up the extension array, create a block of native memory to marshal // them into. if (nativeExtensionArray.Length > 0) { checked { // CERT_EXTENSION structures end with a pointer field, which means on all supported // platforms they won't require any padding between elements of the array. nativeExtensions.rgExtension = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(CERT_EXTENSION)) * nativeExtensionArray.Length); for (int i = 0; i < nativeExtensionArray.Length; ++i) { ulong offset = (uint)i * (uint)Marshal.SizeOf(typeof(CERT_EXTENSION)); ulong next = offset + (ulong)nativeExtensions.rgExtension.ToInt64(); IntPtr nextExtensionAddr = new IntPtr((long)next); Marshal.StructureToPtr(nativeExtensionArray[i], nextExtensionAddr, false); } } } // Setup a CRYPT_KEY_PROV_INFO for the key CRYPT_KEY_PROV_INFO keyProvInfo = new CRYPT_KEY_PROV_INFO(); keyProvInfo.pwszContainerName = key.UniqueName; keyProvInfo.pwszProvName = key.Provider.Provider; keyProvInfo.dwProvType = 0; // NCRYPT keyProvInfo.dwFlags = 0; keyProvInfo.cProvParam = 0; keyProvInfo.rgProvParam = IntPtr.Zero; keyProvInfo.dwKeySpec = 0; // // Now that all of the needed data structures are setup, we can create the certificate // SafeCertContextHandle selfSignedCertHandle = null; unsafe { fixed(byte *pSubjectName = &subjectName[0]) { // Create a CRYPTOAPI_BLOB for the subject of the cert CapiNative.CRYPTOAPI_BLOB nativeSubjectName = new CapiNative.CRYPTOAPI_BLOB(); nativeSubjectName.cbData = subjectName.Length; nativeSubjectName.pbData = new IntPtr(pSubjectName); // Now that we've converted all the inputs to native data structures, we can generate // the self signed certificate for the input key. using (SafeNCryptKeyHandle keyHandle = key.Handle) { selfSignedCertHandle = UnsafeNativeMethods.CertCreateSelfSignCertificate(keyHandle, ref nativeSubjectName, creationOptions, ref keyProvInfo, ref nativeSignatureAlgorithm, ref nativeStartTime, ref nativeEndTime, ref nativeExtensions); if (selfSignedCertHandle.IsInvalid) { throw new CryptographicException(Marshal.GetLastWin32Error()); } } } } Debug.Assert(selfSignedCertHandle != null, "selfSignedCertHandle != null"); // Attach a key context to the certificate which will allow Windows to find the private key // associated with the certificate if the NCRYPT_KEY_HANDLE is ephemeral. // is done. using (SafeNCryptKeyHandle keyHandle = key.Handle) { CERT_KEY_CONTEXT keyContext = new CERT_KEY_CONTEXT(); keyContext.cbSize = Marshal.SizeOf(typeof(CERT_KEY_CONTEXT)); keyContext.hNCryptKey = keyHandle.DangerousGetHandle(); keyContext.dwKeySpec = KeySpec.NCryptKey; bool attachedProperty = false; int setContextError = 0; // Run in a CER to ensure accurate tracking of the transfer of handle ownership RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { CertificatePropertySetFlags flags = CertificatePropertySetFlags.None; if (!takeOwnershipOfKey) { // If the certificate is not taking ownership of the key handle, then it should // not release the handle when the context is released. flags |= CertificatePropertySetFlags.NoCryptRelease; } attachedProperty = UnsafeNativeMethods.CertSetCertificateContextProperty(selfSignedCertHandle, CertificateProperty.KeyContext, flags, ref keyContext); setContextError = Marshal.GetLastWin32Error(); // If we succesfully transferred ownership of the key to the certificate, // then we need to ensure that we no longer release its handle. if (attachedProperty && takeOwnershipOfKey) { keyHandle.SetHandleAsInvalid(); } } if (!attachedProperty) { throw new CryptographicException(setContextError); } } return(selfSignedCertHandle); } finally { // // In order to release all resources held by the CERT_EXTENSIONS we need to do three things // 1. Destroy each structure marshaled into the native CERT_EXTENSION array // 2. Release the memory used for the CERT_EXTENSION array // 3. Release the memory used in each individual CERT_EXTENSION // // Release each extension marshaled into the native buffer as well if (nativeExtensions.rgExtension != IntPtr.Zero) { for (int i = 0; i < nativeExtensionArray.Length; ++i) { ulong offset = (uint)i * (uint)Marshal.SizeOf(typeof(CERT_EXTENSION)); ulong next = offset + (ulong)nativeExtensions.rgExtension.ToInt64(); IntPtr nextExtensionAddr = new IntPtr((long)next); Marshal.DestroyStructure(nextExtensionAddr, typeof(CERT_EXTENSION)); } Marshal.FreeCoTaskMem(nativeExtensions.rgExtension); } // If we allocated memory for any extensions, make sure to free it now for (int i = 0; i < nativeExtensionArray.Length; ++i) { if (nativeExtensionArray[i].Value.pbData != IntPtr.Zero) { Marshal.FreeCoTaskMem(nativeExtensionArray[i].Value.pbData); } } } }
private static unsafe byte[] CalculateSignerPublicKeyToken(AsymmetricAlgorithm key) { SafeAxlBufferHandle handle; byte[] buffer2; ICspAsymmetricAlgorithm algorithm = key as ICspAsymmetricAlgorithm; if (algorithm == null) { return null; } byte[] buffer = algorithm.ExportCspBlob(false); fixed (byte* numRef = buffer) { CapiNative.CRYPTOAPI_BLOB pCspPublicKeyBlob = new CapiNative.CRYPTOAPI_BLOB { cbData = buffer.Length, pbData = new IntPtr((void*) numRef) }; if ((CapiNative.UnsafeNativeMethods._AxlPublicKeyBlobToPublicKeyToken(ref pCspPublicKeyBlob, out handle) & -2147483648) != 0) { return null; } } bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { handle.DangerousAddRef(ref success); buffer2 = HexStringToBytes(Marshal.PtrToStringUni(handle.DangerousGetHandle())); } finally { if (success) { handle.DangerousRelease(); } } return buffer2; }
private unsafe AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license", this.m_namespaceManager) as XmlElement; if (licenseNode == null) { return null; } SignatureVerificationResult error = this.VerifyAuthenticodeSignatureIdentity(licenseNode); if (error != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(error); } SignatureVerificationResult result2 = this.VerifyAuthenticodeExpectedHash(licenseNode); if (result2 != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(result2); } AuthenticodeSignatureInformation information = null; X509Native.AXL_AUTHENTICODE_SIGNER_INFO pSignerInfo = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO { cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO)) }; X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO pTimestamperInfo = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO { cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO)) }; RuntimeHelpers.PrepareConstrainedRegions(); try { byte[] bytes = Encoding.UTF8.GetBytes(licenseNode.OuterXml); X509Native.AxlVerificationFlags dwFlags = MapRevocationFlags(revocationFlag, revocationMode); try { fixed (byte* numRef = bytes) { CapiNative.CRYPTOAPI_BLOB pLicenseBlob = new CapiNative.CRYPTOAPI_BLOB { cbData = bytes.Length, pbData = new IntPtr((void*) numRef) }; if (X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref pLicenseBlob, dwFlags, ref pSignerInfo, ref pTimestamperInfo) == -2146762496) { return new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature); } } } finally { numRef = null; } X509Chain signatureChain = this.BuildSignatureChain(pSignerInfo, licenseNode, revocationFlag, revocationMode); TimestampInformation timestampInformation = this.GetTimestampInformation(pTimestamperInfo, licenseNode); information = new AuthenticodeSignatureInformation(pSignerInfo, signatureChain, timestampInformation); } finally { X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref pSignerInfo); X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref pTimestamperInfo); } if (information.SigningCertificate == null) { return new AuthenticodeSignatureInformation(information.VerificationResult); } SignatureVerificationResult result3 = this.VerifyAuthenticodePublisher(information.SigningCertificate); if (result3 != SignatureVerificationResult.Valid) { return new AuthenticodeSignatureInformation(result3); } return information; }
private unsafe AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license", this.m_namespaceManager) as XmlElement; if (licenseNode == null) { return(null); } SignatureVerificationResult error = this.VerifyAuthenticodeSignatureIdentity(licenseNode); if (error != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(error)); } SignatureVerificationResult result2 = this.VerifyAuthenticodeExpectedHash(licenseNode); if (result2 != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(result2)); } AuthenticodeSignatureInformation information = null; X509Native.AXL_AUTHENTICODE_SIGNER_INFO pSignerInfo = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO { cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO)) }; X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO pTimestamperInfo = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO { cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO)) }; RuntimeHelpers.PrepareConstrainedRegions(); try { byte[] bytes = Encoding.UTF8.GetBytes(licenseNode.OuterXml); X509Native.AxlVerificationFlags dwFlags = MapRevocationFlags(revocationFlag, revocationMode); try { fixed(byte *numRef = bytes) { CapiNative.CRYPTOAPI_BLOB pLicenseBlob = new CapiNative.CRYPTOAPI_BLOB { cbData = bytes.Length, pbData = new IntPtr((void *)numRef) }; if (X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref pLicenseBlob, dwFlags, ref pSignerInfo, ref pTimestamperInfo) == -2146762496) { return(new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature)); } } } finally { numRef = null; } X509Chain signatureChain = this.BuildSignatureChain(pSignerInfo, licenseNode, revocationFlag, revocationMode); TimestampInformation timestampInformation = this.GetTimestampInformation(pTimestamperInfo, licenseNode); information = new AuthenticodeSignatureInformation(pSignerInfo, signatureChain, timestampInformation); } finally { X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref pSignerInfo); X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref pTimestamperInfo); } if (information.SigningCertificate == null) { return(new AuthenticodeSignatureInformation(information.VerificationResult)); } SignatureVerificationResult result3 = this.VerifyAuthenticodePublisher(information.SigningCertificate); if (result3 != SignatureVerificationResult.Valid) { return(new AuthenticodeSignatureInformation(result3)); } return(information); }