Example #1
0
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
}
Example #2
0
func (aut Person) CreateXml(e *etree.Element) *etree.Element {
	a := e.CreateElement("author")
	a_ln := a.CreateElement("last-name")
	a_mn := a.CreateElement("middle-name")
	a_fn := a.CreateElement("first-name")
	a_ln.SetText(aut.Lname)
	a_mn.SetText(aut.Mname)
	a_fn.SetText(aut.Fname)
	return a
}
// getSortedNamespaces sorts the namespace attributes by their prefix
func getSortedNamespaces(list map[string]string) []etree.Attr {
	var keys []string
	for k := range list {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	elem := etree.Element{}
	for _, k := range keys {
		elem.CreateAttr(k, list[k])
	}

	return elem.Attr
}
func removeTokenFromElement(token etree.Token, e *etree.Element) *etree.Token {
	for i, t := range e.Child {
		if t == token {
			e.Child = append(e.Child[0:i], e.Child[i+1:]...)
			return &t
		}
	}
	return nil
}
func TestJustSetLocElement(t *testing.T) {
	smu, err := NewSitemapURL(URL{"loc": "path", "host": "http://example.com"})

	if err != nil {
		t.Fatalf(`Fatal to validate! This is a critical error: %s`, err)
	}

	doc := etree.NewDocument()
	doc.ReadFromBytes(smu.XML())

	var elm *etree.Element
	url := doc.SelectElement("url")

	elm = url.SelectElement("loc")
	if elm == nil {
		t.Errorf(`Failed to generate xml that loc element is blank: %s`, elm)
	}
	if elm != nil && elm.Text() != "http://example.com/path" {
		t.Errorf(`Failed to generate xml thats deferrent value in loc element: %s`, elm.Text())
	}
}
Example #6
0
func calculateHash(reference *etree.Element, doc *etree.Document) (string, error) {
	digestMethodElement := reference.SelectElement("DigestMethod")
	if digestMethodElement == nil {
		return "", errors.New("signedxml: unable to find DigestMethod")
	}

	digestMethodURI := digestMethodElement.SelectAttrValue("Algorithm", "")
	if digestMethodURI == "" {
		return "", errors.New("signedxml: unable to find Algorithm in DigestMethod")
	}

	digestAlgo, ok := hashAlgorithms[digestMethodURI]
	if !ok {
		return "", fmt.Errorf("signedxml: unable to find matching hash"+
			"algorithm for %s in hashAlgorithms", digestMethodURI)
	}

	doc.WriteSettings.CanonicalEndTags = true
	doc.WriteSettings.CanonicalText = true
	doc.WriteSettings.CanonicalAttrVal = true

	h := digestAlgo.New()
	docBytes, err := doc.WriteToBytes()
	if err != nil {
		return "", err
	}

	//ioutil.WriteFile("C:/Temp/SignedXML/Suspect.xml", docBytes, 0644)
	//s, _ := doc.WriteToString()
	//logger.Println(s)

	h.Write(docBytes)
	d := h.Sum(nil)
	calculatedValue := base64.StdEncoding.EncodeToString(d)

	return calculatedValue, nil
}
func TestSetNilValue(t *testing.T) {
	smu, err := NewSitemapURL(&Options{}, URL{"loc": "path", "priority": nil, "changefreq": nil, "lastmod": nil, "host": "http://example.com"})

	if err != nil {
		t.Fatalf(`Fatal to validate! This is a critical error: %s`, err)
	}

	doc := etree.NewDocument()
	doc.ReadFromBytes(smu.XML())

	var elm *etree.Element
	url := doc.SelectElement("url")

	elm = url.SelectElement("loc")
	if elm == nil {
		t.Errorf(`Failed to generate xml that loc element is blank: %s`, elm)
	}
	if elm != nil && elm.Text() != "http://example.com/path" {
		t.Errorf(`Failed to generate xml thats deferrent value in loc element: %s`, elm.Text())
	}

	elm = url.SelectElement("priority")
	if elm != nil {
		t.Errorf(`Failed to generate xml that priority element must be nil: %s`, elm)
	}

	elm = url.SelectElement("changefreq")
	if elm != nil {
		t.Errorf(`Failed to generate xml that changefreq element must be nil: %s`, elm)
	}

	elm = url.SelectElement("lastmod")
	if elm != nil {
		t.Errorf(`Failed to generate xml that lastmod element must be nil: %s`, elm)
	}
}
Example #8
0
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 TestJustSetLocElementAndThenItNeedsCompleteValues(t *testing.T) {
	smu, err := NewSitemapURL(URL{"loc": "path", "host": "http://example.com"})

	if err != nil {
		t.Fatalf(`Fatal to validate! This is a critical error: %s`, err)
	}

	doc := etree.NewDocument()
	doc.ReadFromBytes(smu.XML())

	var elm *etree.Element
	url := doc.SelectElement("url")

	elm = url.SelectElement("loc")
	if elm == nil {
		t.Errorf(`Failed to generate xml that loc element is blank: %s`, elm)
	}
	if elm != nil && elm.Text() != "http://example.com/path" {
		t.Errorf(`Failed to generate xml thats deferrent value in loc element: %s`, elm.Text())
	}

	elm = url.SelectElement("priority")
	if elm == nil {
		t.Errorf(`Failed to generate xml that priority element is nil: %s`, elm)
	}
	if elm != nil && elm.Text() != "0.5" {
		t.Errorf(`Failed to generate xml thats deferrent value in priority element: %s`, elm.Text())
	}

	elm = url.SelectElement("changefreq")
	if elm == nil {
		t.Errorf(`Failed to generate xml that changefreq element is nil: %s`, elm)
	}
	if elm != nil && elm.Text() != "weekly" {
		t.Errorf(`Failed to generate xml thats deferrent value in changefreq element: %s`, elm.Text())
	}

	elm = url.SelectElement("lastmod")
	if elm == nil {
		t.Errorf(`Failed to generate xml that lastmod element is nil: %s`, elm)
	}
	if elm != nil {
		if _, err := time.Parse(time.RFC3339, elm.Text()); err != nil {
			t.Errorf(`Failed to generate xml thats failed to parse datetime in lastmod element: %s`, err)
		}
	}
}
// SetBuilderElementValue if it will change to struct from map if the future's
// author is feeling a bothersome in this function.
func SetBuilderElementValue(elm *etree.Element, data map[string]interface{}, basekey string) (*etree.Element, bool) {
	var child *etree.Element

	key := basekey
	ts, tk := spaceDecompose(elm.Tag)
	_, sk := spaceDecompose(elm.Space)

	if elm.Tag != "" && ts != "" && tk != "" {
		key = fmt.Sprintf("%s:%s", elm.Space, basekey)
	} else if sk != "" {
		key = fmt.Sprintf("%s:%s", sk, basekey)
	}

	if values, ok := data[basekey]; ok {
		switch value := values.(type) {
		case nil:
		default:
			child = elm.CreateElement(key)
			child.SetText(fmt.Sprint(value))
		case int:
			child = elm.CreateElement(key)
			child.SetText(fmt.Sprint(value))
		case string:
			child = elm.CreateElement(key)
			child.SetText(value)
		case float64, float32:
			child = elm.CreateElement(key)
			child.SetText(fmt.Sprint(value))
		case time.Time:
			child = elm.CreateElement(key)
			child.SetText(value.Format(time.RFC3339))
		case bool:
			_ = elm.CreateElement(fmt.Sprintf("%s:%s", key, key))
		case []int:
			for _, v := range value {
				child = elm.CreateElement(key)
				child.SetText(fmt.Sprint(v))
			}
		case []string:
			for _, v := range value {
				child = elm.CreateElement(key)
				child.SetText(v)
			}
		case Attrs:
			val, attrs := value[0], value[1]

			child, _ = SetBuilderElementValue(elm, URL{basekey: val}, basekey)
			switch attr := attrs.(type) {
			case map[string]string:
				for k, v := range attr {
					child.CreateAttr(k, v)
				}
			// TODO: gotta remove below
			case Attr:
				for k, v := range attr {
					child.CreateAttr(k, v)
				}
			}

		case interface{}:
			var childkey string
			if sk == "" {
				childkey = fmt.Sprintf("%s:%s", key, key)
			} else {
				childkey = fmt.Sprint(key)
			}

			switch value := values.(type) {
			case []URL:
				for _, v := range value {
					child := elm.CreateElement(childkey)
					for ck := range v {
						SetBuilderElementValue(child, v, ck)
					}
				}
			case URL:
				child := elm.CreateElement(childkey)
				for ck := range value {
					SetBuilderElementValue(child, value, ck)
				}
			}
		}

		return child, true
	}

	return child, false
}
Example #11
0
// SetBuilderElementValue if it will change to struct from map if the future's
// author is feeling a bothersome in this function.
func SetBuilderElementValue(elm *etree.Element, data map[string]interface{}, basekey string) bool {
	key := basekey
	ts, tk := spaceDecompose(elm.Tag)
	_, sk := spaceDecompose(elm.Space)

	if elm.Tag != "" && ts != "" && tk != "" {
		key = fmt.Sprintf("%s:%s", elm.Space, basekey)
	} else if sk != "" {
		key = fmt.Sprintf("%s:%s", sk, basekey)
	}

	if values, ok := data[basekey]; ok {
		switch value := values.(type) {
		case nil:
		default:
			child := elm.CreateElement(key)
			child.SetText(fmt.Sprint(value))
		case int:
			child := elm.CreateElement(key)
			child.SetText(fmt.Sprint(value))
		case string:
			child := elm.CreateElement(key)
			child.SetText(value)
		case float64, float32:
			child := elm.CreateElement(key)
			child.SetText(fmt.Sprint(value))
		case time.Time:
			child := elm.CreateElement(key)
			child.SetText(value.Format(time.RFC3339))
		case bool:
			_ = elm.CreateElement(fmt.Sprintf("%s:%s", key, key))
		case []int:
			for _, v := range value {
				child := elm.CreateElement(key)
				child.SetText(fmt.Sprint(v))
			}
		case []string:
			for _, v := range value {
				child := elm.CreateElement(key)
				child.SetText(v)
			}
		case interface{}:
			var childkey string
			if sk == "" {
				childkey = fmt.Sprintf("%s:%s", key, key)
			} else {
				childkey = fmt.Sprint(key)
			}

			switch value := values.(type) {
			case []URL:
				for _, v := range value {
					child := elm.CreateElement(childkey)
					for ck := range v {
						SetBuilderElementValue(child, v, ck)
					}
				}
			case URL:
				child := elm.CreateElement(childkey)
				for ck := range value {
					SetBuilderElementValue(child, value, ck)
				}
			}
		}

		return true
	}
	return false
}
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
}