public override bool Execute() { using (Package package = Package.Open(PackageFile, FileMode.Open)) { try { PackageDigitalSignatureManager signatureManager = new PackageDigitalSignatureManager(package); signatureManager.CertificateOption = CertificateEmbeddingOption.InSignaturePart; List<Uri> toSign = package.GetParts().Select(part => part.Uri).ToList(); toSign.Add(PackUriHelper.GetRelationshipPartUri(signatureManager.SignatureOrigin)); toSign.Add(signatureManager.SignatureOrigin); toSign.Add(PackUriHelper.GetRelationshipPartUri(new Uri("/", UriKind.RelativeOrAbsolute))); signatureManager.Sign(toSign, new X509Certificate2(Certificate, CertificatePassword)); return true; } catch (Exception ex) { Log.LogError("Error signing package: ", ex); return false; } } }
private static bool SignVsix(string vsixPackagePath, X509Certificate2 certificate) { // many thanks to Jeff Wilcox for the idea and code // check for details: http://www.jeff.wilcox.name/2010/03/vsixcodesigning/ using (var package = Package.Open(vsixPackagePath)) { var signatureManager = new PackageDigitalSignatureManager(package); signatureManager.CertificateOption = CertificateEmbeddingOption.InSignaturePart; var partsToSign = new List<Uri>(); foreach (var packagePart in package.GetParts()) { partsToSign.Add(packagePart.Uri); } partsToSign.Add(PackUriHelper.GetRelationshipPartUri(signatureManager.SignatureOrigin)); partsToSign.Add(signatureManager.SignatureOrigin); partsToSign.Add(PackUriHelper.GetRelationshipPartUri(new Uri("/", UriKind.RelativeOrAbsolute))); try { signatureManager.Sign(partsToSign, certificate); } catch (CryptographicException) { return false; } return true; } }
/// <summary> /// Verify. /// </summary> /// <param name="input">The input.</param> /// <param name="serial">The serial.</param> /// <returns></returns> public override bool Verify(Stream input, string serial = null) { if (input == null) { throw new ArgumentNullException("input"); } using (var package = Package.Open(input, FileMode.Open, FileAccess.Read)) { var mgr = new PackageDigitalSignatureManager(package) { CertificateOption = CertificateEmbeddingOption.InSignaturePart }; var result = false; foreach (var sig in mgr.Signatures) { var verifyResult = mgr.VerifySignatures(true); result = verifyResult == VerifyResult.Success; if (result && !String.IsNullOrWhiteSpace(serial)) { var actualSerial = new BigInteger(sig.Signer.GetSerialNumber()); var expectedSerial = CertUtil.HexadecimalStringToBigInt(serial); result = actualSerial == expectedSerial; } } package.Close(); return result; } }
public static OpenXmlPowerToolsDocument Insert(OpenXmlPowerToolsDocument doc, IEnumerable<string> certificateList) { using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc)) { using (Package package = streamDoc.GetPackage()) { foreach (string digitalCertificate in certificateList) { X509Certificate x509Certificate = X509Certificate2.CreateFromCertFile(digitalCertificate); PackageDigitalSignatureManager digitalSigntaureManager = new PackageDigitalSignatureManager(package); digitalSigntaureManager.CertificateOption = CertificateEmbeddingOption.InSignaturePart; System.Collections.Generic.List<Uri> partsToSign = new System.Collections.Generic.List<Uri>(); //Adds each part to the list, except relationships parts. foreach (PackagePart openPackagePart in package.GetParts()) { if (!PackUriHelper.IsRelationshipPartUri(openPackagePart.Uri)) partsToSign.Add(openPackagePart.Uri); } List<PackageRelationshipSelector> relationshipSelectors = new List<PackageRelationshipSelector>(); //Creates one selector for each package-level relationship, based on id foreach (PackageRelationship relationship in package.GetRelationships()) { PackageRelationshipSelector relationshipSelector = new PackageRelationshipSelector(relationship.SourceUri, PackageRelationshipSelectorType.Id, relationship.Id); relationshipSelectors.Add(relationshipSelector); } digitalSigntaureManager.Sign(partsToSign, x509Certificate, relationshipSelectors); } } return streamDoc.GetModifiedDocument(); } }
/// <summary> /// Tests a Digital Signature from a package /// </summary> /// <returns>Digital signatures list</returns> public static Collection<string> GetList(OpenXmlPowerToolsDocument doc) { using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc)) { // Creates the PackageDigitalSignatureManager PackageDigitalSignatureManager digitalSignatureManager = new PackageDigitalSignatureManager(streamDoc.GetPackage()); // Verifies the collection of certificates in the package Collection<string> digitalSignatureDescriptions = new Collection<string>(); ReadOnlyCollection<PackageDigitalSignature> digitalSignatures = digitalSignatureManager.Signatures; if (digitalSignatures.Count > 0) { foreach (PackageDigitalSignature signature in digitalSignatures) { if (PackageDigitalSignatureManager.VerifyCertificate(signature.Signer) != X509ChainStatusFlags.NoError) { digitalSignatureDescriptions.Add(string.Format(System.Globalization.CultureInfo.InvariantCulture, "Signature: {0} ({1})", signature.Signer.Subject, PackageDigitalSignatureManager.VerifyCertificate(signature.Signer))); } else digitalSignatureDescriptions.Add("Signature: " + signature.Signer.Subject); } } else { digitalSignatureDescriptions.Add("No digital signatures found"); } return digitalSignatureDescriptions; } }
/// <summary> /// Constructor for use when opening an existing signature /// </summary> /// <param name="manager">digital signature manager - to consult for hash, embedding and other options</param> /// <param name="signaturePart">part that houses the signature</param> internal PackageDigitalSignature( PackageDigitalSignatureManager manager, PackagePart signaturePart) { _manager = manager; _processor = new XmlDigitalSignatureProcessor(manager, signaturePart, this); }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ /// <summary> /// Constructor for creating a new signature /// </summary> /// <param name="manager">digital signature manager - to consult for hash, embedding and other options</param> /// <param name="processor">digital signature manager - to consult for hash, embedding and other options</param> internal PackageDigitalSignature( PackageDigitalSignatureManager manager, XmlDigitalSignatureProcessor processor) { Debug.Assert(processor.PackageSignature == null, "Logic Error: one processor per-signature"); _manager = manager; _processor = processor; // _processor.PackageSignature = this; }
/// <summary> /// Main signing process /// </summary> /// <param name="package"></param> /// <returns></returns> private bool SignAllParts(Package package) { if (package == null) throw new ArgumentNullException("SignAllParts(package)"); // Create the DigitalSignature Manager PackageDigitalSignatureManager dsm = new PackageDigitalSignatureManager(package); dsm.CertificateOption = CertificateEmbeddingOption.InSignaturePart; // Create a list of all the part URIs in the package to sign // (GetParts() also includes PackageRelationship parts). System.Collections.Generic.List<Uri> toSign = new System.Collections.Generic.List<Uri>(); foreach (PackagePart packagePart in package.GetParts()) { // Add all package parts to the list for signing. toSign.Add(packagePart.Uri); } // Add the URI for SignatureOrigin PackageRelationship part. // The SignatureOrigin relationship is created when Sign() is called. // Signing the SignatureOrigin relationship disables counter-signatures. toSign.Add(PackUriHelper.GetRelationshipPartUri(dsm.SignatureOrigin)); // Also sign the SignatureOrigin part. toSign.Add(dsm.SignatureOrigin); // Add the package relationship to the signature origin to be signed. toSign.Add(PackUriHelper.GetRelationshipPartUri(new Uri("/", UriKind.RelativeOrAbsolute))); // Sign() will prompt the user to select a Certificate to sign with. try { var cert = new X509Certificate2(this.CertificatePath, (String.IsNullOrEmpty(this.CertificatePassword) ? null : this.CertificatePassword)); dsm.Sign(toSign, cert); } // If there are no certificates or the SmartCard manager is // not running, catch the exception and show an error message. catch (CryptographicException ex) { Console.WriteLine( "Cannot Sign: {0}", ex.Message); } return dsm.IsSigned && dsm.VerifySignatures(true) == VerifyResult.Success; }
private static void SignAllParts(Package package) { if (package == null) throw new ArgumentNullException("SignAllParts(package)"); // Create the DigitalSignature Manager PackageDigitalSignatureManager dsm = new PackageDigitalSignatureManager(package); dsm.CertificateOption = CertificateEmbeddingOption.InSignaturePart; // Create a list of all the part URIs in the package to sign // (GetParts() also includes PackageRelationship parts). System.Collections.Generic.List<Uri> toSign = new System.Collections.Generic.List<Uri>(); foreach (PackagePart packagePart in package.GetParts()) { // Add all package parts to the list for signing. toSign.Add(packagePart.Uri); } // Add the URI for SignatureOrigin PackageRelationship part. // The SignatureOrigin relationship is created when Sign() is called. // Signing the SignatureOrigin relationship disables counter-signatures. toSign.Add(PackUriHelper.GetRelationshipPartUri(dsm.SignatureOrigin)); // Also sign the SignatureOrigin part. toSign.Add(dsm.SignatureOrigin); // Add the package relationship to the signature origin to be signed. toSign.Add(PackUriHelper.GetRelationshipPartUri(new Uri("/", UriKind.RelativeOrAbsolute))); // Sign() will prompt the user to select a Certificate to sign with. try { dsm.Sign(toSign); } // If there are no certificates or the SmartCard manager is // not running, catch the exception and show an error message. catch (CryptographicException ex) { MessageBox.Show( "Cannot Sign\n" + ex.Message, "No Digital Certificates Available", MessageBoxButton.OK, MessageBoxImage.Exclamation); } }
/// <summary> /// Factory method that creates a new PackageDigitalSignature /// </summary> internal static PackageDigitalSignature Sign( PackageDigitalSignatureManager manager, PackagePart signaturePart, IEnumerable<Uri> parts, IEnumerable<PackageRelationshipSelector> relationshipSelectors, X509Certificate2 signer, String signatureId, bool embedCertificate, IEnumerable<System.Security.Cryptography.Xml.DataObject> signatureObjects, IEnumerable<System.Security.Cryptography.Xml.Reference> objectReferences) { // create XmlDigitalSignatureProcessor p = new XmlDigitalSignatureProcessor(manager, signaturePart); // and sign return p.Sign(parts, relationshipSelectors, signer, signatureId, embedCertificate, signatureObjects, objectReferences); }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <param name="overrideCurrentSignature"></param> /// <from>http://msdn.microsoft.com/en-us/library/system.io.packaging.packagedigitalsignaturemanager.sign(v=vs.100).aspx</from> public void Sign(string path, bool overrideCurrentSignature) { { _log.Debug("We're going to try signing {0}, override current signature {1}".format(path, overrideCurrentSignature)); var package = Package.Open(path); _log.Debug("Opened {0}".format(path)); var signatureManager = new PackageDigitalSignatureManager(package) { CertificateOption = CertificateEmbeddingOption.InSignaturePart }; if (signatureManager.IsSigned) { if (overrideCurrentSignature) { _log.Debug("{0} is signed we'll try to remove signatures".format(path)); //TODO: make smarter so we only remove signatures for the relevant parts signatureManager.RemoveAllSignatures(); package.Flush(); } else { _log.Debug("{0} is signed, we're going to throw".format(path)); throw new AlreadySignedException(); } } var toSign = package.GetParts().Select(packagePart => packagePart.Uri).ToList(); toSign.Add(PackUriHelper.GetRelationshipPartUri(signatureManager.SignatureOrigin)); toSign.Add(signatureManager.SignatureOrigin); toSign.Add(PackUriHelper.GetRelationshipPartUri(new Uri("/", UriKind.RelativeOrAbsolute))); _log.Debug("About to start signing {0}".format(path)); signatureManager.Sign(toSign, Certificate); _log.Debug("signed {0}, going to close".format(path)); package.Close(); _log.Debug("closed {0}".format(path)); } GC.Collect(); }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <from>http://msdn.microsoft.com/en-us/library/system.io.packaging.packagedigitalsignaturemanager.sign(v=vs.100).aspx</from> public void Sign(string path) { var package = Package.Open(path); var signatureManager = new PackageDigitalSignatureManager(package); signatureManager.CertificateOption = CertificateEmbeddingOption.InSignaturePart; var toSign = new List<Uri>(); foreach (PackagePart packagePart in package.GetParts()) { toSign.Add(packagePart.Uri); } toSign.Add(PackUriHelper.GetRelationshipPartUri(signatureManager.SignatureOrigin)); toSign.Add(signatureManager.SignatureOrigin); toSign.Add(PackUriHelper.GetRelationshipPartUri(new Uri("/", UriKind.RelativeOrAbsolute))); signatureManager.Sign(toSign, Certificate); package.Close(); }
/// <summary> /// RemoveAll /// </summary> public static OpenXmlPowerToolsDocument RemoveAll(OpenXmlPowerToolsDocument doc) { using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc)) { using (Package package = streamDoc.GetPackage()) { // Creates the PackageDigitalSignatureManager PackageDigitalSignatureManager digitalSignatureManager = new PackageDigitalSignatureManager(package); digitalSignatureManager.RemoveAllSignatures(); } return streamDoc.GetModifiedDocument(); } }
private void SignAllParts(Package package, X509Certificate2 certificate) { var partsToSign = new List<Uri>(); var relationshipsToSign = new List<PackageRelationshipSelector>(); foreach (var relationship in package.GetRelationshipsByType(RtOfficeDocument)) { AddSignableItems(relationship, partsToSign, relationshipsToSign); } var mgr = new PackageDigitalSignatureManager(package) { CertificateOption = CertificateEmbeddingOption.InSignaturePart }; var officeObject = CreateOfficeObject(SignatureID, ManifestHashAlgorithm); var officeObjectReference = new Reference("#" + OfficeObjectID); mgr.Sign(partsToSign, certificate, relationshipsToSign, SignatureID, new[] { officeObject }, new[] { officeObjectReference }); package.Close(); }
//Returns the sorted PackageRelationship collection from a given collection of PackageRelationshipSelectors //Note: All the selectors in the given selector collection are assumed to be for the same Part/PackageRoot //This method should be called for a part/packageroot private static IEnumerable<PackageRelationship> GetRelationships( PackageDigitalSignatureManager manager, IEnumerable<PackageRelationshipSelector> relationshipSelectorsWithSameSource) { SortedDictionary<String, PackageRelationship> relationshipsDictionarySortedById = new SortedDictionary<String, PackageRelationship>(StringComparer.Ordinal); foreach (PackageRelationshipSelector relationshipSelector in relationshipSelectorsWithSameSource) { // loop and accumulate and group them by owning Part foreach (PackageRelationship r in relationshipSelector.Select(manager.Package)) { // add relationship if(!relationshipsDictionarySortedById.ContainsKey(r.Id)) relationshipsDictionarySortedById.Add(r.Id, r); } } return relationshipsDictionarySortedById.Values; }
private static XmlNode GenerateDigestMethod( PackageDigitalSignatureManager manager, XmlDocument xDoc) { // <DigestMethod> XmlElement digestMethod = xDoc.CreateElement(XTable.Get(XTable.ID.DigestMethodTagName), SignedXml.XmlDsigNamespaceUrl); XmlAttribute digestAlgorithmAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.AlgorithmAttrName)); digestAlgorithmAttr.Value = manager.HashAlgorithm; digestMethod.Attributes.Append(digestAlgorithmAttr); return digestMethod; }
private static XmlNode GeneratePartSigningReference( PackageDigitalSignatureManager manager, XmlDocument xDoc, HashAlgorithm hashAlgorithm, Uri partName) { PackagePart part = manager.Package.GetPart(partName); // <Reference> XmlElement reference = xDoc.CreateElement(XTable.Get(XTable.ID.ReferenceTagName), SignedXml.XmlDsigNamespaceUrl); // add Uri with content type as Query XmlAttribute uriAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.UriAttrName)); uriAttr.Value = PackUriHelper.GetStringForPartUri(partName) + _contentTypeQueryStringPrefix + part.ContentType; reference.Attributes.Append(uriAttr); // add transforms tag if necessary String transformName = String.Empty; if (manager.TransformMapping.ContainsKey(part.ContentType)) { transformName = manager.TransformMapping[part.ContentType]; // <Transforms> XmlElement transforms = xDoc.CreateElement(XTable.Get(XTable.ID.TransformsTagName), SignedXml.XmlDsigNamespaceUrl); // <Transform> XmlElement transform = xDoc.CreateElement(XTable.Get(XTable.ID.TransformTagName), SignedXml.XmlDsigNamespaceUrl); XmlAttribute algorithmAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.AlgorithmAttrName)); algorithmAttr.Value = transformName; transform.Attributes.Append(algorithmAttr); transforms.AppendChild(transform); reference.AppendChild(transforms); } // <DigestMethod> reference.AppendChild(GenerateDigestMethod(manager, xDoc)); // <DigestValue> using (Stream s = part.GetStream(FileMode.Open, FileAccess.Read)) { reference.AppendChild(GenerateDigestValueNode(xDoc, hashAlgorithm, s, transformName)); } return reference; }
/// <summary> /// Generates a Reference tag that contains a Relationship transform /// </summary> /// <param name="manager">manager</param> /// <param name="relationshipPartName">name of the relationship part</param> /// <param name="xDoc">current xml document</param> /// <param name="hashAlgorithm">hash algorithm = digest method</param> /// <param name="relationshipSelectors">relationshipSelectors that represent the relationships to sign </param> /// <remarks>ContentType is known and part name can be derived from the relationship collection</remarks> private static XmlNode GenerateRelationshipSigningReference( PackageDigitalSignatureManager manager, XmlDocument xDoc, HashAlgorithm hashAlgorithm, Uri relationshipPartName, IEnumerable<PackageRelationshipSelector> relationshipSelectors) { string relPartContentType = PackagingUtilities.RelationshipPartContentType.ToString(); // <Reference> XmlElement reference = xDoc.CreateElement(XTable.Get(XTable.ID.ReferenceTagName), SignedXml.XmlDsigNamespaceUrl); // add Uri // persist the Uri of the associated Relationship part String relationshipPartString; if (PackUriHelper.ComparePartUri(relationshipPartName, PackageRelationship.ContainerRelationshipPartName) == 0) relationshipPartString = PackageRelationship.ContainerRelationshipPartName.ToString(); else relationshipPartString = PackUriHelper.GetStringForPartUri(relationshipPartName); XmlAttribute uriAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.UriAttrName)); uriAttr.Value = relationshipPartString + _contentTypeQueryStringPrefix + relPartContentType; reference.Attributes.Append(uriAttr); // add transforms tag (always necessary) // <Transforms> XmlElement transforms = xDoc.CreateElement(XTable.Get(XTable.ID.TransformsTagName), SignedXml.XmlDsigNamespaceUrl); // add Relationship transform String opcNamespace = XTable.Get(XTable.ID.OpcSignatureNamespace); String opcNamespacePrefix = XTable.Get(XTable.ID.OpcSignatureNamespacePrefix); XmlElement transform = xDoc.CreateElement(XTable.Get(XTable.ID.TransformTagName), SignedXml.XmlDsigNamespaceUrl); XmlAttribute algorithmAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.AlgorithmAttrName)); algorithmAttr.Value = XTable.Get(XTable.ID.RelationshipsTransformName); transform.Attributes.Append(algorithmAttr); // <RelationshipReference SourceId="abc" /> or // <RelationshipGroupReference SourceType="xyz" /> foreach (PackageRelationshipSelector relationshipSelector in relationshipSelectors) { switch (relationshipSelector.SelectorType) { case PackageRelationshipSelectorType.Id: { XmlNode relationshipNode = xDoc.CreateElement(opcNamespacePrefix, XTable.Get(XTable.ID.RelationshipReferenceTagName), opcNamespace); XmlAttribute idAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.SourceIdAttrName)); idAttr.Value = relationshipSelector.SelectionCriteria; relationshipNode.Attributes.Append(idAttr); transform.AppendChild(relationshipNode); } break; case PackageRelationshipSelectorType.Type: { XmlNode relationshipNode = xDoc.CreateElement(opcNamespacePrefix, XTable.Get(XTable.ID.RelationshipsGroupReferenceTagName), opcNamespace); XmlAttribute typeAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.SourceTypeAttrName)); typeAttr.Value = relationshipSelector.SelectionCriteria; relationshipNode.Attributes.Append(typeAttr); transform.AppendChild(relationshipNode); } break; default: Invariant.Assert(false, "This option should never be executed"); break; } } transforms.AppendChild(transform); // add non-Relationship transform (if any) String transformName = null; if (manager.TransformMapping.ContainsKey(relPartContentType)) { transformName = manager.TransformMapping[relPartContentType]; // let them override //Currently we only support two transforms and so we validate whether its //one of those if (transformName == null || transformName.Length == 0 || !XmlDigitalSignatureProcessor.IsValidXmlCanonicalizationTransform(transformName)) throw new InvalidOperationException(SR.Get(SRID.UnsupportedTransformAlgorithm)); // <Transform> transform = xDoc.CreateElement(XTable.Get(XTable.ID.TransformTagName), SignedXml.XmlDsigNamespaceUrl); algorithmAttr = xDoc.CreateAttribute(XTable.Get(XTable.ID.AlgorithmAttrName)); algorithmAttr.Value = transformName; transform.Attributes.Append(algorithmAttr); transforms.AppendChild(transform); } reference.AppendChild(transforms); // <DigestMethod> reference.AppendChild(GenerateDigestMethod(manager, xDoc)); // <DigestValue> - digest the virtual node list made from these Relationship tags using (Stream s = XmlDigitalSignatureProcessor.GenerateRelationshipNodeStream(GetRelationships(manager, relationshipSelectors))) // serialized node list { reference.AppendChild(GenerateDigestValueNode(xDoc, hashAlgorithm, s, transformName)); } return reference; }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ /// <summary> /// GenerateRelationshipSigningReferences /// </summary> /// <param name="manager"></param> /// <param name="xDoc"></param> /// <param name="hashAlgorithm"></param> /// <param name="relationshipSelectors"></param> /// <param name="manifest"></param> /// <returns>number of references to be signed</returns> private static int GenerateRelationshipSigningReferences( PackageDigitalSignatureManager manager, XmlDocument xDoc, HashAlgorithm hashAlgorithm, IEnumerable<PackageRelationshipSelector> relationshipSelectors, XmlNode manifest) { // PartUri - and its list of PackageRelationshipSelectors Dictionary<Uri, List<PackageRelationshipSelector>> partAndSelectorDictionary = new Dictionary<Uri, List<PackageRelationshipSelector>>(); foreach (PackageRelationshipSelector relationshipSelector in relationshipSelectors) { //update the partAndSelectorDictionary for each relationshipSelector Uri relationshipPartUri = PackUriHelper.GetRelationshipPartUri(relationshipSelector.SourceUri); List<PackageRelationshipSelector> selectors; if (partAndSelectorDictionary.ContainsKey(relationshipPartUri)) selectors = partAndSelectorDictionary[relationshipPartUri]; else { selectors = new List<PackageRelationshipSelector>(); partAndSelectorDictionary.Add(relationshipPartUri, selectors); } selectors.Add(relationshipSelector); } // now that we have them grouped by Part name, emit the XML // Here is an optimization for saving space by declaring the OPC namespace and prefix // in the <Manifest> tag. It will become: // <Manifest xmlns:opc="http://schemas.openxmlformats.org/package/2006/digital-signature"> // Later when we generate the RelationshipSigningReference we can use the namespace prefix "opc" // instead of the long namespace itself, thus saving some space if the manifest has more than one // RelationshipSigningReference. // XmlElement xmlE = (XmlElement)manifest; xmlE.SetAttribute(XTable.Get(XTable.ID.OpcSignatureNamespaceAttribute), XTable.Get(XTable.ID.OpcSignatureNamespace)); int count = 0; foreach (Uri partName in partAndSelectorDictionary.Keys) { // emit xml and append manifest.AppendChild( GenerateRelationshipSigningReference(manager, xDoc, hashAlgorithm, partName, /* we are guaranteed that this is a valid part Uri, so we do not use PackUriHelper.CreatePartUri */ partAndSelectorDictionary[partName])); count++; } return count; }
/// <summary> /// Generate Manifest tag /// </summary> /// <param name="manager">manager</param> /// <param name="xDoc">current Xml doc</param> /// <param name="hashAlgorithm">hash algorithm to hash with</param> /// <param name="parts">parts to sign - possibly null</param> /// <param name="relationshipSelectors">relationshipSelectors that represent the /// relationships that have to be signed - possibly null</param> /// <returns></returns> internal static XmlNode GenerateManifest( PackageDigitalSignatureManager manager, XmlDocument xDoc, HashAlgorithm hashAlgorithm, IEnumerable<Uri> parts, IEnumerable<PackageRelationshipSelector> relationshipSelectors) { Debug.Assert(manager != null); Debug.Assert(xDoc != null); Debug.Assert(hashAlgorithm != null); // check args if (!hashAlgorithm.CanReuseTransform) throw new ArgumentException(SR.Get(SRID.HashAlgorithmMustBeReusable)); // <Manifest> XmlNode manifest = xDoc.CreateNode(XmlNodeType.Element, XTable.Get(XTable.ID.ManifestTagName), SignedXml.XmlDsigNamespaceUrl); // add part references if (parts != null) { // loop and write - may still be empty foreach (Uri partUri in parts) { // generate a reference tag manifest.AppendChild(GeneratePartSigningReference(manager, xDoc, hashAlgorithm, partUri)); } } // any relationship references? int relationshipCount = 0; if (relationshipSelectors != null) { relationshipCount = GenerateRelationshipSigningReferences(manager, xDoc, hashAlgorithm, relationshipSelectors, manifest); } // did we sign anything? Manifest can NOT be empty if (parts == null && relationshipCount == 0) throw new ArgumentException(SR.Get(SRID.NothingToSign)); return manifest; }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ /// <summary> /// Constructor - called from PackageDigitalSignatureManager when opening an existing signature /// </summary> /// <param name="manager">current DigitalSignatureManager</param> /// <param name="packageSignature">public signature object</param> /// <param name="signaturePart">the part that will/does house the associated XML signature</param> internal XmlDigitalSignatureProcessor(PackageDigitalSignatureManager manager, PackagePart signaturePart, PackageDigitalSignature packageSignature) : this(manager, signaturePart) { _signature = packageSignature; }
/// <summary> /// Constructor for use when opening an existing signature /// </summary> /// <param name="manager">digital signature manager - to consult for hash, embedding and other options</param> /// <param name="signaturePart">part that houses the signature</param> internal PackageDigitalSignature( PackageDigitalSignatureManager manager, PackagePart signaturePart) { _manager = manager; _processor = new XmlDigitalSignatureProcessor(manager, signaturePart, this); }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ /// <summary> /// Constructor for creating a new signature /// </summary> /// <param name="manager">digital signature manager - to consult for hash, embedding and other options</param> /// <param name="processor">digital signature manager - to consult for hash, embedding and other options</param> internal PackageDigitalSignature( PackageDigitalSignatureManager manager, XmlDigitalSignatureProcessor processor) { Debug.Assert(processor.PackageSignature == null, "Logic Error: one processor per-signature"); _manager = manager; _processor = processor; // _processor.PackageSignature = this; }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ /// <summary> /// Constructor - called from public constructor as well as static Sign() method /// </summary> /// <param name="manager">current DigitalSignatureManager</param> /// <param name="signaturePart">the part that will/does house the associated XML signature</param> private XmlDigitalSignatureProcessor(PackageDigitalSignatureManager manager, PackagePart signaturePart) { Invariant.Assert(manager != null); Invariant.Assert(signaturePart != null); _signaturePart = signaturePart; _manager = manager; _lookForEmbeddedCert = true; }
// ------------------------ ValidateSignatures ------------------------ /// <summary> /// Validates all the digital signatures of a given package.</summary> /// <param name="package"> /// The package for validating digital signatures.</param> /// <returns> /// true if all digital signatures are valid; otherwise false if the /// package is unsigned or any of the signatures are invalid.</returns> private static bool ValidateSignatures(Package package) { if (package == null) throw new ArgumentNullException("ValidateSignatures(package)"); // Create a PackageDigitalSignatureManager for the given Package. PackageDigitalSignatureManager dsm = new PackageDigitalSignatureManager(package); // Check to see if the package contains any signatures. if (!dsm.IsSigned) { MessageBox.Show("The package is not signed"); return false; } // Verify that all signatures are valid. VerifyResult result = dsm.VerifySignatures(false); if (result != VerifyResult.Success) { MessageBox.Show("One or more digital signatures are invalid."); return false; } // else if (result == VerifyResult.Success) return true; // All signatures are valid. }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ /// <summary> /// Parse the Manifest tag /// </summary> /// <param name="manager"></param> /// <param name="reader">XmlReader positioned to the Manifest tag</param> /// <param name="partManifest"></param> /// <param name="partEntryManifest"></param> /// <param name="relationshipManifest"></param> internal static void ParseManifest( PackageDigitalSignatureManager manager, XmlReader reader, out List<Uri> partManifest, out List<PartManifestEntry> partEntryManifest, out List<PackageRelationshipSelector> relationshipManifest) { Invariant.Assert(manager != null); Invariant.Assert(reader != null); // these are empty (non-null) when nothing is found partManifest = new List<Uri>(); partEntryManifest = new List<PartManifestEntry>(); relationshipManifest = new List<PackageRelationshipSelector>(); // manually parse the Relationship tags because they are custom formed and the Reference class will not handle // them correctly string referenceTagName = XTable.Get(XTable.ID.ReferenceTagName); int referenceCount = 0; while (reader.Read() && (reader.MoveToContent() == XmlNodeType.Element)) { // should be on a <Reference> tag if (String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) == 0 && (String.CompareOrdinal(reader.LocalName, referenceTagName) == 0) && reader.Depth == 2) { // Parse each reference - distinguish between Relationships and Parts // because we don't store the Relationship-part itself - just it's Relationships. PartManifestEntry partManifestEntry = ParseReference(reader); if (partManifestEntry.IsRelationshipEntry) { foreach (PackageRelationshipSelector relationshipSelector in partManifestEntry.RelationshipSelectors) relationshipManifest.Add(relationshipSelector); } else partManifest.Add(partManifestEntry.Uri); // return the manifest entry to be used for hashing partEntryManifest.Add(partManifestEntry); referenceCount++; } else throw new XmlException(SR.Get(SRID.UnexpectedXmlTag, reader.Name)); } // XmlDSig xsd requires at least one <Reference> tag if (referenceCount == 0) throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); }