Exemplo n.º 1
0
 /// <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);
 }
        private static XmlNode GenerateDigestValueNode(XmlDocument xDoc, HashAlgorithm hashAlgorithm, Stream s, String transformName)
        {
            // <DigestValue>
            XmlElement digestValue     = xDoc.CreateElement(XTable.Get(XTable.ID.DigestValueTagName), SignedXml.XmlDsigNamespaceUrl);
            XmlText    digestValueText = xDoc.CreateTextNode(XmlDigitalSignatureProcessor.GenerateDigestValue(s, transformName, hashAlgorithm));

            digestValue.AppendChild(digestValueText);
            return(digestValue);
        }
Exemplo n.º 3
0
        //------------------------------------------------------
        //
        //  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>
        /// 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);
        }
        /// <summary>
        /// Parses Transforms tag
        /// </summary>
        /// <param name="reader">node to parse</param>
        /// <param name="partUri">Part Uri for the part owning the relationships</param>
        /// <param name="relationshipSelectors">allocates and returns a list of
        /// PackageRelationshipSelectors if Relationship transform</param>
        /// <returns>ordered list of Transform names</returns>
        private static List <String> ParseTransformsTag(XmlReader reader, Uri partUri, ref List <PackageRelationshipSelector> relationshipSelectors)
        {
            // # reference that signs multiple PackageRelationships
            // <Reference URI="/shared/_rels/image.jpg.rels?ContentType=image/jpg">
            //      <Transforms>
            //          <Transform Algorithm="http://schemas.openxmlformats.org/package/2006/RelationshipTransform">
            //              <RelationshipReference SourceId="1" />
            //              <RelationshipReference SourceId="2" />
            //              <RelationshipReference SourceId="8" />
            //          </Transform>
            //          <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
            //      </Transforms>
            //      <DigestMethod Algorithm="sha1" />
            //      <DigestValue>... </DigestValue>
            // </Reference>

            // verify lack of attributes
            if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) != 0)
            {
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            List <String> transforms = null;
            bool          relationshipTransformFound = false;
            int           transformsCountWhenRelationshipTransformFound = 0;

            // Look for transforms.
            // There are currently only 3 legal transforms which can be arranged in any
            // combination.
            while (reader.Read() && (reader.MoveToContent() == XmlNodeType.Element))
            {
                String transformName = null;

                // at this level, all tags must be Transform tags
                if (reader.Depth != 4 ||
                    String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0 ||
                    String.CompareOrdinal(reader.LocalName, XTable.Get(XTable.ID.TransformTagName)) != 0)
                {
                    throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
                }

                // inspect the Algorithm attribute to determine the type of transform
                if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) == 1)
                {
                    transformName = reader.GetAttribute(XTable.Get(XTable.ID.AlgorithmAttrName));
                }

                // legal transform name?
                if ((transformName != null) && (transformName.Length > 0))
                {
                    // what type of transform?
                    if (String.CompareOrdinal(transformName, XTable.Get(XTable.ID.RelationshipsTransformName)) == 0)
                    {
                        if (!relationshipTransformFound)
                        {
                            // relationship transform
                            ParseRelationshipsTransform(reader, partUri, ref relationshipSelectors);

                            if (transforms == null)
                            {
                                transforms = new List <String>();
                            }

                            transforms.Add(transformName);

                            relationshipTransformFound = true;
                            transformsCountWhenRelationshipTransformFound = transforms.Count;
                            continue;   // success
                        }
                        else
                        {
                            throw new XmlException(SR.Get(SRID.MultipleRelationshipTransformsFound));
                        }
                    }
                    else
                    {
                        // non-Relationship transform should have no children
                        if (reader.IsEmptyElement)
                        {
                            if (transforms == null)
                            {
                                transforms = new List <String>();
                            }

                            if (XmlDigitalSignatureProcessor.IsValidXmlCanonicalizationTransform(transformName))
                            {
                                transforms.Add(transformName); // return it
                                continue;                      // success
                            }
                            else
                            {
                                throw new InvalidOperationException(SR.Get(SRID.UnsupportedTransformAlgorithm));
                            }
                        }
                    }
                }
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            if (transforms.Count == 0)
            {
                throw new XmlException(SR.Get(SRID.XmlSignatureParseError));
            }

            //If we found another transform after the Relationship transform, it will be validated earlier
            //in this method to make sure that its a supported xml canonicalization algorithm and so we can
            //simplify this test condition - As per the OPC spec - Relationship transform must be followed
            //by a canonicalization algorithm.
            if (relationshipTransformFound && (transforms.Count == transformsCountWhenRelationshipTransformFound))
            {
                throw new XmlException(SR.Get(SRID.RelationshipTransformNotFollowedByCanonicalizationTransform));
            }

            return(transforms);
        }