Example #1
0
        // can be used with sha1 or sha2 
        // logic is copied from the "isolation library" in NDP\iso_whid\ds\security\cryptoapi\pkisign\msaxlapi\mansign.cpp
        private void VerifyLicenseNew(CmiManifestVerifyFlags verifyFlags, bool oldFormat)
        {
            XmlNamespaceManager nsm = new XmlNamespaceManager(_manifestDom.NameTable);
            nsm.AddNamespace("asm", AssemblyNamespaceUri);
            nsm.AddNamespace("asm2", AssemblyV2NamespaceUri);
            nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
            nsm.AddNamespace("msrel", MSRelNamespaceUri);
            nsm.AddNamespace("r", LicenseNamespaceUri);
            nsm.AddNamespace("as", AuthenticodeNamespaceUri);

            // We are done if no license.
            XmlElement licenseNode = _manifestDom.SelectSingleNode("asm:assembly/ds:Signature/ds:KeyInfo/msrel:RelData/r:license", nsm) as XmlElement;
            if (licenseNode == null)
            {
                return;
            }

            // Make sure this license is for this manifest.
            VerifyAssemblyIdentity(nsm);

            // Found a license, so instantiate signer info property.
            _authenticodeSignerInfo = new CmiAuthenticodeSignerInfo(Win32.TRUST_E_FAIL);

            // Find the license's signature
            XmlElement signatureNode = licenseNode.SelectSingleNode("//r:issuer/ds:Signature", nsm) as XmlElement;
            if (signatureNode == null)
            {
                throw new CryptographicException(Win32.TRUST_E_NOSIGNATURE);
            }

            // Make sure it is indeed an Authenticode signature, and it is an enveloped signature.
            // Then make sure the transforms are valid.
            VerifySignatureForm(signatureNode, "AuthenticodeSignature", nsm);

            // Now read the enveloped license signature.
            XmlDocument licenseDom = new XmlDocument();
            licenseDom.LoadXml(licenseNode.OuterXml);
            signatureNode = licenseDom.SelectSingleNode("//r:issuer/ds:Signature", nsm) as XmlElement;

            ManifestSignedXml2 signedXml = new ManifestSignedXml2(licenseDom);
            signedXml.LoadXml(signatureNode);
            if (_useSha256)
            {
                signedXml.SignedInfo.SignatureMethod = Sha256SignatureMethodUri;
            }

            // Check the signature
            if (!signedXml.CheckSignature())
            {
                _authenticodeSignerInfo = null;
                throw new CryptographicException(Win32.TRUST_E_CERT_SIGNATURE);
            }

            X509Certificate2 signingCertificate = GetSigningCertificate(signedXml, nsm);

            // First make sure certificate is not explicitly disallowed.
            X509Store store = new X509Store(StoreName.Disallowed, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            X509Certificate2Collection storedCertificates = null;
            try
            {
                storedCertificates = (X509Certificate2Collection)store.Certificates;
                if (storedCertificates == null)
                {
                    _authenticodeSignerInfo.ErrorCode = Win32.TRUST_E_FAIL;
                    throw new CryptographicException(Win32.TRUST_E_FAIL);
                }
                if (storedCertificates.Contains(signingCertificate))
                {
                    _authenticodeSignerInfo.ErrorCode = Win32.TRUST_E_EXPLICIT_DISTRUST;
                    throw new CryptographicException(Win32.TRUST_E_EXPLICIT_DISTRUST);
                }
            }
            finally
            {
                store.Close();
            }

            // prepare information for the TrustManager to display
            string hash;
            string description;
            string url;
            if (!GetManifestInformation(licenseNode, nsm, out hash, out description, out url))
            {
                _authenticodeSignerInfo.ErrorCode = Win32.TRUST_E_SUBJECT_FORM_UNKNOWN;
                throw new CryptographicException(Win32.TRUST_E_SUBJECT_FORM_UNKNOWN);
            }
            _authenticodeSignerInfo.Hash = hash;
            _authenticodeSignerInfo.Description = description;
            _authenticodeSignerInfo.DescriptionUrl = url;

            // read the timestamp from the manifest
            DateTime verificationTime;
            bool isTimestamped = VerifySignatureTimestamp(signatureNode, nsm, out verificationTime);
            bool isLifetimeSigning = false;
            if (isTimestamped)
            {
                isLifetimeSigning = ((verifyFlags & CmiManifestVerifyFlags.LifetimeSigning) == CmiManifestVerifyFlags.LifetimeSigning);
                if (!isLifetimeSigning)
                {
                    isLifetimeSigning = GetLifetimeSigning(signingCertificate);
                }
            }

            // Retrieve the Authenticode policy settings from registry.
            uint policies = GetAuthenticodePolicies();

            X509Chain chain = new X509Chain(); // use the current user profile
            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
            chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
            if ((CmiManifestVerifyFlags.RevocationCheckEndCertOnly & verifyFlags) == CmiManifestVerifyFlags.RevocationCheckEndCertOnly)
            {
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly;
            }
            else if ((CmiManifestVerifyFlags.RevocationCheckEntireChain & verifyFlags) == CmiManifestVerifyFlags.RevocationCheckEntireChain)
            {
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
            }
            else if (((CmiManifestVerifyFlags.RevocationNoCheck & verifyFlags) == CmiManifestVerifyFlags.RevocationNoCheck) ||
                ((Win32.WTPF_IGNOREREVOKATION & policies) == Win32.WTPF_IGNOREREVOKATION))
            {
                chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            }

            chain.ChainPolicy.VerificationTime = verificationTime; // local time
            if (isTimestamped && isLifetimeSigning)
            {
                chain.ChainPolicy.ApplicationPolicy.Add(new Oid(Win32.szOID_KP_LIFETIME_SIGNING));
            }

            chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);
            chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag; // don't ignore anything

            bool chainIsValid = chain.Build(signingCertificate);

            if (!chainIsValid)
            {
#if DEBUG
                X509ChainStatus[] statuses = chain.ChainStatus;
                foreach (X509ChainStatus status in statuses)
                {
                    System.Diagnostics.Debug.WriteLine("flag = " + status.Status + " " + status.StatusInformation);
                }
#endif
                AuthenticodeSignerInfo.ErrorCode = Win32.TRUST_E_SUBJECT_NOT_TRUSTED;
                throw new CryptographicException(Win32.TRUST_E_SUBJECT_NOT_TRUSTED);
            }

            // package information for the trust manager
            _authenticodeSignerInfo.SignerChain = chain;

            store = new X509Store(StoreName.TrustedPublisher, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            try
            {
                storedCertificates = (X509Certificate2Collection)store.Certificates;
                if (storedCertificates == null)
                {
                    _authenticodeSignerInfo.ErrorCode = Win32.TRUST_E_FAIL;
                    throw new CryptographicException(Win32.TRUST_E_FAIL);
                }
                if (!storedCertificates.Contains(signingCertificate))
                {
                    AuthenticodeSignerInfo.ErrorCode = Win32.TRUST_E_SUBJECT_NOT_TRUSTED;
                    throw new CryptographicException(Win32.TRUST_E_SUBJECT_NOT_TRUSTED);
                }
            }
            finally
            {
                store.Close();
            }

            // Verify Certificate publisher name
            XmlElement subjectNode = licenseNode.SelectSingleNode("r:grant/as:AuthenticodePublisher/as:X509SubjectName", nsm) as XmlElement;
            if (subjectNode == null || String.Compare(signingCertificate.Subject, subjectNode.InnerText, StringComparison.Ordinal) != 0)
            {
                AuthenticodeSignerInfo.ErrorCode = Win32.TRUST_E_CERT_SIGNATURE;
                throw new CryptographicException(Win32.TRUST_E_CERT_SIGNATURE);
            }

            if (!oldFormat)
                // Make sure we have the intended Authenticode signer.
                VerifyPublisherIdentity(nsm);
        }
Example #2
0
        private X509Certificate2 GetSigningCertificate(ManifestSignedXml2 signedXml, XmlNamespaceManager nsm)
        {
            X509Certificate2 signingCertificate = null;

            KeyInfo keyInfo = signedXml.KeyInfo;
            KeyInfoX509Data kiX509 = null;
            RSAKeyValue keyValue = null;
            foreach (KeyInfoClause kic in keyInfo)
            {
                if (keyValue == null)
                {
                    keyValue = kic as RSAKeyValue;
                    if (keyValue == null)
                    {
                        break;
                    }
                }

                if (kiX509 == null)
                {
                    kiX509 = kic as KeyInfoX509Data;
                }

                if (keyValue != null && kiX509 != null)
                {
                    break;
                }
            }

            if (keyValue == null || kiX509 == null)
            {
                // no X509Certificate KeyInfoClause
                _authenticodeSignerInfo.ErrorCode = Win32.TRUST_E_SUBJECT_FORM_UNKNOWN;
                throw new CryptographicException(Win32.TRUST_E_SUBJECT_FORM_UNKNOWN);
            }

            // get public key from signing keyInfo
            byte[] signingPublicKey = null;
            RSACryptoServiceProvider rsaProvider = keyValue.Key as RSACryptoServiceProvider;
            if (rsaProvider != null)
            {
                signingPublicKey = rsaProvider.ExportCspBlob(false);
            }
            if (signingPublicKey == null)
            {
                _authenticodeSignerInfo.ErrorCode = Win32.TRUST_E_CERT_SIGNATURE;
                throw new CryptographicException(Win32.TRUST_E_CERT_SIGNATURE);
            }

            // enumerate all certificates in x509Data searching for the one whose public key is used in <RSAKeyValue>
            foreach (X509Certificate2 certificate in kiX509.Certificates)
            {
                if (certificate == null)
                {
                    continue;
                }

                bool certificateAuthority = false;
                foreach (X509Extension extention in certificate.Extensions)
                {
                    X509BasicConstraintsExtension basicExtention = extention as X509BasicConstraintsExtension;
                    if (basicExtention != null)
                    {
                        certificateAuthority = basicExtention.CertificateAuthority;
                        if (certificateAuthority)
                        {
                            break;
                        }
                    }
                }

                if (certificateAuthority)
                {
                    // Ignore certs that have "Subject Type=CA" in basic contraints
                    continue;
                }

                RSACryptoServiceProvider p = (RSACryptoServiceProvider)certificate.PublicKey.Key;
                byte[] certificatePublicKey = p.ExportCspBlob(false);
                bool noMatch = false;
                if (signingPublicKey.Length == certificatePublicKey.Length)
                {
                    for (int i = 0; i < signingPublicKey.Length; i++)
                    {
                        if (signingPublicKey[i] != certificatePublicKey[i])
                        {
                            noMatch = true;
                            break;
                        }
                    }
                    if (!noMatch)
                    {
                        signingCertificate = certificate;
                        break;
                    }
                }
            }

            if (signingCertificate == null)
            {
                _authenticodeSignerInfo.ErrorCode = Win32.TRUST_E_CERT_SIGNATURE;
                throw new CryptographicException(Win32.TRUST_E_CERT_SIGNATURE);
            }
            return signingCertificate;
        }
Example #3
0
        // throw cryptographic exception for any verification errors.
        internal void Verify(CmiManifestVerifyFlags verifyFlags)
        {
            // Reset signer infos.
            _strongNameSignerInfo = null;
            _authenticodeSignerInfo = null;

            XmlNamespaceManager nsm = new XmlNamespaceManager(_manifestDom.NameTable);
            nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
            XmlElement signatureNode = _manifestDom.SelectSingleNode("//ds:Signature", nsm) as XmlElement;
            if (signatureNode == null)
            {
                throw new CryptographicException(Win32.TRUST_E_NOSIGNATURE);
            }

            // Make sure it is indeed SN signature, and it is an enveloped signature.
            bool oldFormat = VerifySignatureForm(signatureNode, "StrongNameSignature", nsm);

            // It is the DSig we want, now make sure the public key matches the token.
            string publicKeyToken = VerifyPublicKeyToken();

            // OK. We found the SN signature with matching public key token, so
            // instantiate the SN signer info property.
            _strongNameSignerInfo = new CmiStrongNameSignerInfo(Win32.TRUST_E_FAIL, publicKeyToken);

            // Now verify the SN signature, and Authenticode license if available.
            ManifestSignedXml2 signedXml = new ManifestSignedXml2(_manifestDom, true);
            signedXml.LoadXml(signatureNode);
            if (_useSha256)
            {
                signedXml.SignedInfo.SignatureMethod = Sha256SignatureMethodUri;
            }

            AsymmetricAlgorithm key = null;
            bool dsigValid = signedXml.CheckSignatureReturningKey(out key);
            _strongNameSignerInfo.PublicKey = key;
            if (!dsigValid)
            {
                _strongNameSignerInfo.ErrorCode = Win32.TRUST_E_BAD_DIGEST;
                throw new CryptographicException(Win32.TRUST_E_BAD_DIGEST);
            }

            // Verify license as well if requested.
            if ((verifyFlags & CmiManifestVerifyFlags.StrongNameOnly) != CmiManifestVerifyFlags.StrongNameOnly)
            {
                if (_useSha256)
                {
                    VerifyLicenseNew(verifyFlags, oldFormat);
                }
                else
                {
                    VerifyLicense(verifyFlags, oldFormat);
                }
            }
        }
Example #4
0
        private static void StrongNameSignManifestDom(XmlDocument manifestDom, XmlDocument licenseDom, CmiManifestSigner2 signer, bool useSha256)
        {
            RSA snKey = signer.StrongNameKey as RSA;

            // Make sure it is RSA, as this is the only one Fusion will support.
            if (snKey == null)
            {
                throw new NotSupportedException();
            }

            // Setup namespace manager.
            XmlNamespaceManager nsm = new XmlNamespaceManager(manifestDom.NameTable);
            nsm.AddNamespace("asm", AssemblyNamespaceUri);

            // Get to root element.
            XmlElement signatureParent = manifestDom.SelectSingleNode("asm:assembly", nsm) as XmlElement;
            if (signatureParent == null)
            {
                throw new CryptographicException(Win32.TRUST_E_SUBJECT_FORM_UNKNOWN);
            }

            if (signer.StrongNameKey.GetType() != typeof(RSACryptoServiceProvider))
            {
                throw new NotSupportedException();
            }

            // Setup up XMLDSIG engine.
            ManifestSignedXml2 signedXml = new ManifestSignedXml2(signatureParent);
            signedXml.SigningKey = GetFixedRSACryptoServiceProvider(signer.StrongNameKey as RSACryptoServiceProvider, useSha256);
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            if (signer.UseSha256)
                signedXml.SignedInfo.SignatureMethod = Sha256SignatureMethodUri;

            // Add the key information.
            signedXml.KeyInfo.AddClause(new RSAKeyValue(snKey));
            if (licenseDom != null)
            {
                signedXml.KeyInfo.AddClause(new KeyInfoNode(licenseDom.DocumentElement));
            }
            signedXml.KeyInfo.Id = "StrongNameKeyInfo";

            // Add the enveloped reference.
            Reference enveloped = new Reference();
            enveloped.Uri = "";
            if (signer.UseSha256)
                enveloped.DigestMethod = Sha256DigestMethod;

            // Add an enveloped then Exc-C14N transform.
            enveloped.AddTransform(new XmlDsigEnvelopedSignatureTransform());
            enveloped.AddTransform(new XmlDsigExcC14NTransform());
            signedXml.AddReference(enveloped);

#if (false) // DSIE: New format does not sign KeyInfo.
            // Add the key info reference.
            Reference strongNameKeyInfo = new Reference();
            strongNameKeyInfo.Uri = "#StrongNameKeyInfo";
            strongNameKeyInfo.AddTransform(new XmlDsigExcC14NTransform());
            signedXml.AddReference(strongNameKeyInfo);
#endif
            // Compute the signature.
            signedXml.ComputeSignature();

            // Get the XML representation
            XmlElement xmlDigitalSignature = signedXml.GetXml();
            xmlDigitalSignature.SetAttribute("Id", "StrongNameSignature");

            // Insert the signature now.
            signatureParent.AppendChild(xmlDigitalSignature);
        }
Example #5
0
        private static void AuthenticodeSignLicenseDom(XmlDocument licenseDom, CmiManifestSigner2 signer, string timeStampUrl, bool useSha256)
        {
            // Make sure it is RSA, as this is the only one Fusion will support.
            if (signer.Certificate.PublicKey.Key.GetType() != typeof(RSACryptoServiceProvider))
            {
                throw new NotSupportedException();
            }

            if (signer.Certificate.PrivateKey.GetType() != typeof(RSACryptoServiceProvider))
            {
                throw new NotSupportedException();
            }

            // Setup up XMLDSIG engine.
            ManifestSignedXml2 signedXml = new ManifestSignedXml2(licenseDom);
            signedXml.SigningKey = GetFixedRSACryptoServiceProvider(signer.Certificate.PrivateKey as RSACryptoServiceProvider, useSha256);
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            if (signer.UseSha256)
                signedXml.SignedInfo.SignatureMethod = Sha256SignatureMethodUri;

            // Add the key information.
            signedXml.KeyInfo.AddClause(new RSAKeyValue(GetFixedRSACryptoServiceProvider(signer.Certificate.PrivateKey as RSACryptoServiceProvider, useSha256) as RSA));
            signedXml.KeyInfo.AddClause(new KeyInfoX509Data(signer.Certificate, signer.IncludeOption));

            // Add the enveloped reference.
            Reference reference = new Reference();
            reference.Uri = "";
            if (signer.UseSha256)
                reference.DigestMethod = Sha256DigestMethod;

            // Add an enveloped and an Exc-C14N transform.
            reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
#if (false) // BUGBUG: LTA transform complaining about issuer node not found.
            reference.AddTransform(new XmlLicenseTransform()); 
#endif
            reference.AddTransform(new XmlDsigExcC14NTransform());

            // Add the reference.
            signedXml.AddReference(reference);

            // Compute the signature.
            signedXml.ComputeSignature();

            // Get the XML representation
            XmlElement xmlDigitalSignature = signedXml.GetXml();
            xmlDigitalSignature.SetAttribute("Id", "AuthenticodeSignature");

            // Insert the signature node under the issuer element.
            XmlNamespaceManager nsm = new XmlNamespaceManager(licenseDom.NameTable);
            nsm.AddNamespace("r", LicenseNamespaceUri);
            XmlElement issuerNode = licenseDom.SelectSingleNode("r:license/r:issuer", nsm) as XmlElement;
            issuerNode.AppendChild(licenseDom.ImportNode(xmlDigitalSignature, true));

            // Time stamp it if requested.
            if (timeStampUrl != null && timeStampUrl.Length != 0)
            {
                TimestampSignedLicenseDom(licenseDom, timeStampUrl);
            }

            // Wrap it inside a RelData element.
            licenseDom.DocumentElement.ParentNode.InnerXml = "<msrel:RelData xmlns:msrel=\"" +
                                                             MSRelNamespaceUri + "\">" +
                                                             licenseDom.OuterXml + "</msrel:RelData>";
        }
Example #6
0
        private static void StrongNameSignManifestDom(XmlDocument manifestDom, XmlDocument licenseDom, CmiManifestSigner2 signer, bool useSha256)
        {
            RSA snKey = signer.StrongNameKey as RSA;

            // Make sure it is RSA, as this is the only one Fusion will support.
            if (snKey == null)
            {
                throw new NotSupportedException();
            }

            // Setup namespace manager.
            XmlNamespaceManager nsm = new XmlNamespaceManager(manifestDom.NameTable);

            nsm.AddNamespace("asm", AssemblyNamespaceUri);

            // Get to root element.
            XmlElement signatureParent = manifestDom.SelectSingleNode("asm:assembly", nsm) as XmlElement;

            if (signatureParent == null)
            {
                throw new CryptographicException(Win32.TRUST_E_SUBJECT_FORM_UNKNOWN);
            }

            if (!(signer.StrongNameKey is RSA))
            {
                throw new NotSupportedException();
            }

            // Setup up XMLDSIG engine.
            ManifestSignedXml2 signedXml = new ManifestSignedXml2(signatureParent);

            if (signer.StrongNameKey is RSACryptoServiceProvider)
            {
                signedXml.SigningKey = GetFixedRSACryptoServiceProvider(signer.StrongNameKey as RSACryptoServiceProvider, useSha256);
            }
            else
            {
                signedXml.SigningKey = signer.StrongNameKey;
            }
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            if (signer.UseSha256)
            {
                signedXml.SignedInfo.SignatureMethod = Sha256SignatureMethodUri;
            }
            else
            {
                signedXml.SignedInfo.SignatureMethod = Sha1SignatureMethodUri;
            }

            // Add the key information.
            signedXml.KeyInfo.AddClause(new RSAKeyValue(snKey));
            if (licenseDom != null)
            {
                signedXml.KeyInfo.AddClause(new KeyInfoNode(licenseDom.DocumentElement));
            }
            signedXml.KeyInfo.Id = "StrongNameKeyInfo";

            // Add the enveloped reference.
            Reference enveloped = new Reference();

            enveloped.Uri = "";
            if (signer.UseSha256)
            {
                enveloped.DigestMethod = Sha256DigestMethod;
            }
            else
            {
                enveloped.DigestMethod = Sha1DigestMethod;
            }

            // Add an enveloped then Exc-C14N transform.
            enveloped.AddTransform(new XmlDsigEnvelopedSignatureTransform());
            enveloped.AddTransform(new XmlDsigExcC14NTransform());
            signedXml.AddReference(enveloped);

#if (false) // DSIE: New format does not sign KeyInfo.
            // Add the key info reference.
            Reference strongNameKeyInfo = new Reference();
            strongNameKeyInfo.Uri = "#StrongNameKeyInfo";
            strongNameKeyInfo.AddTransform(new XmlDsigExcC14NTransform());
            signedXml.AddReference(strongNameKeyInfo);
#endif
            // Compute the signature.
            signedXml.ComputeSignature();

            // Get the XML representation
            XmlElement xmlDigitalSignature = signedXml.GetXml();
            xmlDigitalSignature.SetAttribute("Id", "StrongNameSignature");

            // Insert the signature now.
            signatureParent.AppendChild(xmlDigitalSignature);
        }
Example #7
0
        private static void AuthenticodeSignLicenseDom(XmlDocument licenseDom, CmiManifestSigner2 signer, string timeStampUrl, bool useSha256)
        {
            // Make sure it is RSA, as this is the only one Fusion will support.
            RSA rsaPrivateKey = CngLightup.GetRSAPrivateKey(signer.Certificate);

            if (rsaPrivateKey == null)
            {
                throw new NotSupportedException();
            }

            // Setup up XMLDSIG engine.
            ManifestSignedXml2 signedXml = new ManifestSignedXml2(licenseDom);
            // only needs to change the provider type when RSACryptoServiceProvider is used
            var rsaCsp = rsaPrivateKey is RSACryptoServiceProvider?
                         GetFixedRSACryptoServiceProvider(rsaPrivateKey as RSACryptoServiceProvider, useSha256) : rsaPrivateKey;

            signedXml.SigningKey = rsaCsp;
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            if (signer.UseSha256)
            {
                signedXml.SignedInfo.SignatureMethod = Sha256SignatureMethodUri;
            }
            else
            {
                signedXml.SignedInfo.SignatureMethod = Sha1SignatureMethodUri;
            }

            // Add the key information.
            signedXml.KeyInfo.AddClause(new RSAKeyValue(rsaCsp));
            signedXml.KeyInfo.AddClause(new KeyInfoX509Data(signer.Certificate, signer.IncludeOption));

            // Add the enveloped reference.
            Reference reference = new Reference();

            reference.Uri = "";
            if (signer.UseSha256)
            {
                reference.DigestMethod = Sha256DigestMethod;
            }
            else
            {
                reference.DigestMethod = Sha1DigestMethod;
            }

            // Add an enveloped and an Exc-C14N transform.
            reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
#if (false) // BUGBUG: LTA transform complaining about issuer node not found.
            reference.AddTransform(new XmlLicenseTransform());
#endif
            reference.AddTransform(new XmlDsigExcC14NTransform());

            // Add the reference.
            signedXml.AddReference(reference);

            // Compute the signature.
            signedXml.ComputeSignature();

            // Get the XML representation
            XmlElement xmlDigitalSignature = signedXml.GetXml();
            xmlDigitalSignature.SetAttribute("Id", "AuthenticodeSignature");

            // Insert the signature node under the issuer element.
            XmlNamespaceManager nsm = new XmlNamespaceManager(licenseDom.NameTable);
            nsm.AddNamespace("r", LicenseNamespaceUri);
            XmlElement issuerNode = licenseDom.SelectSingleNode("r:license/r:issuer", nsm) as XmlElement;
            issuerNode.AppendChild(licenseDom.ImportNode(xmlDigitalSignature, true));

            // Time stamp it if requested.
            if (timeStampUrl != null && timeStampUrl.Length != 0)
            {
                TimestampSignedLicenseDom(licenseDom, timeStampUrl);
            }

            // Wrap it inside a RelData element.
            licenseDom.DocumentElement.ParentNode.InnerXml = "<msrel:RelData xmlns:msrel=\"" +
                                                             MSRelNamespaceUri + "\">" +
                                                             licenseDom.OuterXml + "</msrel:RelData>";
        }