internal AuthenticodeSignatureInformation(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer,
                                                  X509Chain signatureChain,
                                                  TimestampInformation timestamp) {
            m_verificationResult = (SignatureVerificationResult)signer.dwError;
            m_hashAlgorithmId = signer.algHash;

            if (signer.pwszDescription != IntPtr.Zero) {
                m_description = Marshal.PtrToStringUni(signer.pwszDescription);
            }
            if (signer.pwszDescriptionUrl != IntPtr.Zero) {
                string descriptionUrl = Marshal.PtrToStringUni(signer.pwszDescriptionUrl);
                Uri.TryCreate(descriptionUrl, UriKind.RelativeOrAbsolute, out m_descriptionUrl);
            }

            m_signatureChain = signatureChain;

            // If there was a timestamp, and it was not valid we need to invalidate the entire Authenticode
            // signature as well, since we cannot assume that the signature would have verified without
            // the timestamp.
            if (timestamp != null && timestamp.VerificationResult != SignatureVerificationResult.MissingSignature) {
                if (timestamp.IsValid) {
                    m_timestamp = timestamp;
                }
                else {
                    m_verificationResult = SignatureVerificationResult.InvalidTimestamp;
                }
            }
            else {
                m_timestamp = null;
            }
        }
Пример #2
0
        public static X509Certificate2 CreateSelfSignedCertificate(this CngKey key,
                                                                   X509Certificates.X509CertificateCreationParameters creationParameters)
        {
            if (creationParameters == null)
            {
                throw new ArgumentNullException("creationParameters");
            }

            // If we are not being asked to hand ownership of the key over to the certificate, then we need
            // ensure that we are running in a trusted context as we have no way to ensure that the caller
            // will not force the key to be cleaned up and then continue to use the dangling handle left in
            // the certificate.
            if (!creationParameters.TakeOwnershipOfKey)
            {
                new PermissionSet(PermissionState.Unrestricted).Demand();
            }

            using (SafeCertContextHandle selfSignedCertHandle =
                       X509Native.CreateSelfSignedCertificate(key,
                                                              creationParameters.TakeOwnershipOfKey,
                                                              creationParameters.SubjectName.RawData,
                                                              creationParameters.CertificateCreationOptions,
                                                              X509Native.MapCertificateSignatureAlgorithm(creationParameters.SignatureAlgorithm),
                                                              creationParameters.StartTime,
                                                              creationParameters.EndTime,
                                                              creationParameters.ExtensionsNoDemand))
            {
                // We need to get the raw handle out of the safe handle because X509Certificate2 only
                // exposes an IntPtr constructor.  To do that we'll temporarially bump the ref count on
                // the handle.
                //
                // X509Certificate2 will duplicate the handle value in the .ctor, so once we've created
                // the certificate object, we can safely drop the ref count and dispose of our handle.
                X509Certificate2 certificate = null;
                bool             addedRef    = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    selfSignedCertHandle.DangerousAddRef(ref addedRef);
                    certificate = new X509Certificate2(selfSignedCertHandle.DangerousGetHandle());
                }
                finally
                {
                    if (addedRef)
                    {
                        selfSignedCertHandle.DangerousRelease();
                    }
                }

                // If we passed ownership of the key to the certificate, than destroy the key
                // now so that we don't continue to use it beyond the liftime of the cert.
                if (creationParameters.TakeOwnershipOfKey)
                {
                    key.Dispose();
                }

                return(certificate);
            }
        }
Пример #3
0
        internal static SafeCertContextHandle GetCertificateContext(X509Certificate certificate)
        {
            SafeCertContextHandle certContext = X509Native.DuplicateCertContext(certificate.Handle);

            // Make sure to keep the X509Certificate object alive until after its certificate context is
            // duplicated, otherwise it could end up being closed out from underneath us before we get a
            // chance to duplicate the handle.
            GC.KeepAlive(certificate);

            return(certContext);
        }
Пример #4
0
 internal static CngKey GetCngPrivateKey(X509Certificate2 certificate)
 {
     using (var certContext = GetCertificateContext(certificate))
         using (SafeNCryptKeyHandle privateKeyHandle = X509Native.AcquireCngPrivateKey(certContext))
         {
             // We need to assert for full trust when opening the CNG key because
             // CngKey.Open(SafeNCryptKeyHandle) does a full demand for full trust, and we want to allow
             // access to a certificate's private key by anyone who has access to the certificate itself.
             new PermissionSet(PermissionState.Unrestricted).Assert();
             return(CngKey.Open(privateKeyHandle, CngKeyHandleOpenOptions.None));
         }
 }
        internal TimestampInformation(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper) {
            m_hashAlgorithmId = timestamper.algHash;
            m_verificationResult = (SignatureVerificationResult)timestamper.dwError;

            ulong filetime = ((ulong)((uint)timestamper.ftTimestamp.dwHighDateTime) << 32)  |
                              (ulong)((uint)timestamper.ftTimestamp.dwLowDateTime);
            m_timestamp = DateTime.FromFileTimeUtc((long)filetime);

            if (timestamper.pChainContext != IntPtr.Zero) {
                m_timestampChain = new X509Chain(timestamper.pChainContext);
            }
        }
Пример #6
0
        public static X509Certificate2 CreateSelfSignedCertificate(this CngKey key,
                                                                   X509CertificateCreationParameters creationParameters)
        {
            if (creationParameters == null)
            {
                throw new ArgumentNullException("creationParameters");
            }

            using (SafeNCryptKeyHandle keyHandle = key.Handle)
            {
                using (SafeCertificateContextHandle selfSignedCertHandle =
                           X509Native.CreateSelfSignedCertificate(keyHandle,
                                                                  creationParameters.SubjectName.RawData,
                                                                  creationParameters.CertificateCreationOptions,
                                                                  X509Native.MapCertificateSignatureAlgorithm(creationParameters.SignatureAlgorithm),
                                                                  creationParameters.StartTime,
                                                                  creationParameters.EndTime,
                                                                  creationParameters.ExtensionsNoDemand))
                {
                    // We need to get the raw handle out of the safe handle because X509Certificate2 only
                    // exposes an IntPtr constructor.  To do that we'll temporarially bump the ref count on
                    // the handle.
                    //
                    // X509Certificate2 will duplicate the handle value in the .ctor, so once we've created
                    // the certificate object, we can safely drop the ref count and dispose of our handle.
                    bool addedRef = false;
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        selfSignedCertHandle.DangerousAddRef(ref addedRef);
                        return(new X509Certificate2(selfSignedCertHandle.DangerousGetHandle()));
                    }
                    finally
                    {
                        if (addedRef)
                        {
                            selfSignedCertHandle.DangerousRelease();
                        }
                    }
                }
            }
        }
        private X509Chain BuildSignatureChain(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer,
                                              XmlElement licenseNode,
                                              X509RevocationFlag revocationFlag,
                                              X509RevocationMode revocationMode) {
            Debug.Assert(licenseNode != null, "licenseNode != null");

            X509Chain signatureChain = null;

            if (signer.pChainContext != IntPtr.Zero) {
                signatureChain = new X509Chain(signer.pChainContext);
            }
            else if (signer.dwError == (int)SignatureVerificationResult.UntrustedRootCertificate) {
                // CertVerifyAuthenticodeLicense will not return the certificate chain for self signed certificates
                // so we'll need to extract the certificate from the signature ourselves.

                XmlElement x509Data = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:KeyInfo/ds:X509Data",
                                                                   m_namespaceManager) as XmlElement;
                if (x509Data != null) {
                    XmlNodeList certificateNodes = x509Data.SelectNodes("ds:X509Certificate", m_namespaceManager);

                    // A manifest could have many X509Certificate nodes in its X509Data, which may include the
                    // signing certificate, links on the chain to a root, or certificates not used at all in
                    // the chain.  Since we don't know which certificate actually did the signing, we only
                    // process the chain if we have a single certificate.
                    if (certificateNodes.Count == 1 && certificateNodes[0] is XmlElement) {
                        byte[] rawCertificate = Convert.FromBase64String(certificateNodes[0].InnerText.Trim());
                        X509Certificate2 signingCertificate = new X509Certificate2(rawCertificate);

                        signatureChain = new X509Chain();
                        signatureChain.ChainPolicy.RevocationFlag = revocationFlag;
                        signatureChain.ChainPolicy.RevocationMode = revocationMode;

                        signatureChain.Build(signingCertificate);
                    }
                }
            }

            return signatureChain;
        }
 private X509Chain BuildSignatureChain(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer, XmlElement licenseNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode)
 {
     X509Chain chain = null;
     if (signer.dwError == -2146762487)
     {
         XmlElement element = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:KeyInfo/ds:X509Data", this.m_namespaceManager) as XmlElement;
         if (element != null)
         {
             X509Certificate2 certificate = new X509Certificate2(Convert.FromBase64String(element.InnerText.Trim()));
             chain = new X509Chain {
                 ChainPolicy = { RevocationFlag = revocationFlag, RevocationMode = revocationMode }
             };
             chain.Build(certificate);
         }
         return chain;
     }
     if (signer.pChainContext != IntPtr.Zero)
     {
         chain = new X509Chain(signer.pChainContext);
     }
     return chain;
 }
        private TimestampInformation GetTimestampInformation(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper,
                                                             XmlElement licenseNode) {
            Debug.Assert(licenseNode != null, "licenseNode != null");

            TimestampInformation timestamp = null;

            // If the timestamper is a trusted publisher, then CAPI has done the work for us;
            // If the leaf certificate is not explicitly a trusted publisher, CAPI will not process
            // the timestamp information so we will verify it ourselves. In any other case, we will
            // return no timestamp information.
            if (timestamper.dwError == (int)SignatureVerificationResult.Valid) {
                timestamp = new TimestampInformation(timestamper);
            }
            else if (timestamper.dwError == (int)SignatureVerificationResult.CertificateNotExplicitlyTrusted ||
                     timestamper.dwError == (int)SignatureVerificationResult.MissingSignature) {

                XmlElement timestampElement = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:Object/as:Timestamp",
                                                                           m_namespaceManager) as XmlElement;
                if (timestampElement != null) {
                    // The timestamp is held as a parameter of a base64 encoded PKCS7 message in the signature
                    byte[] timestampBlob = Convert.FromBase64String(timestampElement.InnerText);

                    try {
                        SignedCms timestampCms = new SignedCms();
                        timestampCms.Decode(timestampBlob);
                        timestampCms.CheckSignature(true);

                        // The SignedCms class does not expose a way to read arbitrary properties from the
                        // message, nor does it expose the HCRYPTMSG to P/Invoke with. We cannot access the
                        // actual timestamp because of this, so for signatures which are not created by a
                        // trusted publisher, we will return a null timestamp. This should be corrected in
                        // v3 of the CLR, as we can extend SignedCms to have the properties we need to
                        // pull all of this information.
                        timestamp = null;
                    }
                    catch (CryptographicException e) {
                        timestamp = new TimestampInformation((SignatureVerificationResult)Marshal.GetHRForException(e));
                    }
                }
            }
            else {
                timestamp = null;
            }

            return timestamp;
        }
 private TimestampInformation GetTimestampInformation(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper, XmlElement licenseNode)
 {
     TimestampInformation information = null;
     if (timestamper.dwError == 0)
     {
         return new TimestampInformation(timestamper);
     }
     if ((timestamper.dwError == -2146762748) || (timestamper.dwError == -2146762496))
     {
         XmlElement element = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:Object/as:Timestamp", this.m_namespaceManager) as XmlElement;
         if (element == null)
         {
             return information;
         }
         byte[] encodedMessage = Convert.FromBase64String(element.InnerText);
         try
         {
             SignedCms cms = new SignedCms();
             cms.Decode(encodedMessage);
             cms.CheckSignature(true);
             return null;
         }
         catch (CryptographicException exception)
         {
             return new TimestampInformation((SignatureVerificationResult) Marshal.GetHRForException(exception));
         }
     }
     return null;
 }
 public static extern int CertVerifyAuthenticodeLicense(ref CapiNative.CRYPTOAPI_BLOB pLicenseBlob, X509Native.AxlVerificationFlags dwFlags, [In, Out] ref X509Native.AXL_AUTHENTICODE_SIGNER_INFO pSignerInfo, [In, Out] ref X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO pTimestamperInfo);
 public static extern int CertFreeAuthenticodeTimestamperInfo(ref X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO pTimestamperInfo);
 public static extern int CertFreeAuthenticodeSignerInfo(ref X509Native.AXL_AUTHENTICODE_SIGNER_INFO pSignerInfo);