func getReferencedXML(reference *etree.Element, inputDoc *etree.Document) (outputDoc *etree.Document, err error) { uri := reference.SelectAttrValue("URI", "") uri = strings.Replace(uri, "#", "", 1) // populate doc with the referenced xml from the Reference URI if uri == "" { outputDoc = inputDoc } else { path := fmt.Sprintf(".//[@ID='%s']", uri) e := inputDoc.FindElement(path) if e != nil { outputDoc = etree.NewDocument() outputDoc.SetRoot(e.Copy()) } else { // SAML v1.1 Assertions use AssertionID path := fmt.Sprintf(".//[@AssertionID='%s']", uri) e := inputDoc.FindElement(path) if e != nil { outputDoc = etree.NewDocument() outputDoc.SetRoot(e.Copy()) } } } if outputDoc == nil { return nil, errors.New("signedxml: unable to find refereced xml") } return outputDoc, nil }
func processTransform(transform *etree.Element, docIn *etree.Document) (docOut *etree.Document, err error) { transformAlgoURI := transform.SelectAttrValue("Algorithm", "") if transformAlgoURI == "" { return nil, errors.New("signedxml: unable to find Algorithm in Transform") } transformAlgo, ok := CanonicalizationAlgorithms[transformAlgoURI] if !ok { return nil, fmt.Errorf("signedxml: unable to find matching transform"+ "algorithm for %s in CanonicalizationAlgorithms", transformAlgoURI) } var transformContent string if transform.ChildElements() != nil { tDoc := etree.NewDocument() tDoc.SetRoot(transform.Copy()) transformContent, err = tDoc.WriteToString() if err != nil { return nil, err } } docString, err := docIn.WriteToString() if err != nil { return nil, err } docString, err = transformAlgo.Process(docString, transformContent) if err != nil { return nil, err } docOut = etree.NewDocument() docOut.ReadFromString(docString) return docOut, nil }
func (e ExclusiveCanonicalization) renderAttributes(node *etree.Element, prefixesInScope []string, defaultNS string) (newDefaultNS string, newPrefixesInScope []string) { currentNS := node.SelectAttrValue("xmlns", defaultNS) elementAttributes := []etree.Attr{} nsListToRender := make(map[string]string) attrListToRender := attributes{} // load map with for prefix -> uri lookup for _, attr := range node.Attr { if attr.Space == "xmlns" { e.namespaces[attr.Key] = attr.Value } } // handle the namespace of the node itself if node.Space != "" { if !contains(prefixesInScope, node.Space) { nsListToRender["xmlns:"+node.Space] = e.namespaces[node.Space] prefixesInScope = append(prefixesInScope, node.Space) } } else if defaultNS != currentNS { newDefaultNS = currentNS elementAttributes = append(elementAttributes, etree.Attr{Key: "xmlns", Value: currentNS}) } for _, attr := range node.Attr { // include the namespaces if they are in the inclusiveNamespacePrefixList if attr.Space == "xmlns" { if !contains(prefixesInScope, attr.Key) && contains(e.inclusiveNamespacePrefixList, attr.Key) { nsListToRender["xmlns:"+attr.Key] = attr.Value prefixesInScope = append(prefixesInScope, attr.Key) } } // include namespaces for qualfied attributes if attr.Space != "" && attr.Space != "xmlns" && !contains(prefixesInScope, attr.Space) { nsListToRender["xmlns:"+attr.Space] = e.namespaces[attr.Space] prefixesInScope = append(prefixesInScope, attr.Space) } // inclued all non-namespace attributes if attr.Space != "xmlns" && attr.Key != "xmlns" { attrListToRender = append(attrListToRender, attribute{ prefix: attr.Space, uri: e.namespaces[attr.Space], key: attr.Key, value: attr.Value, }) } } // sort and add the namespace attributes first sortedNSList := getSortedNamespaces(nsListToRender) elementAttributes = append(elementAttributes, sortedNSList...) // then sort and add the non-namespace attributes sortedAttributes := getSortedAttributes(attrListToRender) elementAttributes = append(elementAttributes, sortedAttributes...) // replace the nodes attributes with the sorted copy node.Attr = elementAttributes return currentNS, prefixesInScope }