run 'go get -u; make revendor'
Signed-off-by: Stephan Renatus <srenatus@chef.io>
This commit is contained in:
104
vendor/github.com/russellhaering/goxmldsig/validate.go
generated
vendored
104
vendor/github.com/russellhaering/goxmldsig/validate.go
generated
vendored
@@ -15,6 +15,7 @@ import (
|
||||
)
|
||||
|
||||
var uriRegexp = regexp.MustCompile("^#[a-zA-Z_][\\w.-]*$")
|
||||
var whiteSpace = regexp.MustCompile("\\s+")
|
||||
|
||||
var (
|
||||
// ErrMissingSignature indicates that no enveloped signature was found referencing
|
||||
@@ -58,31 +59,51 @@ func childPath(space, tag string) string {
|
||||
}
|
||||
}
|
||||
|
||||
// The RemoveElement method on etree.Element isn't recursive...
|
||||
func recursivelyRemoveElement(tree, el *etree.Element) bool {
|
||||
if tree.RemoveChild(el) != nil {
|
||||
return true
|
||||
func mapPathToElement(tree, el *etree.Element) []int {
|
||||
for i, child := range tree.Child {
|
||||
if child == el {
|
||||
return []int{i}
|
||||
}
|
||||
}
|
||||
|
||||
for _, child := range tree.Child {
|
||||
for i, child := range tree.Child {
|
||||
if childElement, ok := child.(*etree.Element); ok {
|
||||
if recursivelyRemoveElement(childElement, el) {
|
||||
return true
|
||||
childPath := mapPathToElement(childElement, el)
|
||||
if childElement != nil {
|
||||
return append([]int{i}, childPath...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return nil
|
||||
}
|
||||
|
||||
// transform applies the passed set of transforms to the specified root element.
|
||||
func removeElementAtPath(el *etree.Element, path []int) bool {
|
||||
if len(path) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(el.Child) <= path[0] {
|
||||
return false
|
||||
}
|
||||
|
||||
childElement, ok := el.Child[path[0]].(*etree.Element)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(path) == 1 {
|
||||
el.RemoveChild(childElement)
|
||||
return true
|
||||
}
|
||||
|
||||
return removeElementAtPath(childElement, path[1:])
|
||||
}
|
||||
|
||||
// Transform returns a new element equivalent to the passed root el, but with
|
||||
// the set of transformations described by the ref applied.
|
||||
//
|
||||
// The functionality of transform is currently very limited and purpose-specific.
|
||||
//
|
||||
// NOTE(russell_h): Ideally this wouldn't mutate the root passed to it, and would
|
||||
// instead return a copy. Unfortunately copying the tree makes it difficult to
|
||||
// correctly locate the signature. I'm opting, for now, to simply mutate the root
|
||||
// parameter.
|
||||
func (ctx *ValidationContext) transform(
|
||||
el *etree.Element,
|
||||
sig *types.Signature,
|
||||
@@ -93,6 +114,14 @@ func (ctx *ValidationContext) transform(
|
||||
return nil, nil, errors.New("Expected Enveloped and C14N transforms")
|
||||
}
|
||||
|
||||
// map the path to the passed signature relative to the passed root, in
|
||||
// order to enable removal of the signature by an enveloped signature
|
||||
// transform
|
||||
signaturePath := mapPathToElement(el, sig.UnderlyingElement())
|
||||
|
||||
// make a copy of the passed root
|
||||
el = el.Copy()
|
||||
|
||||
var canonicalizer Canonicalizer
|
||||
|
||||
for _, transform := range transforms {
|
||||
@@ -100,7 +129,7 @@ func (ctx *ValidationContext) transform(
|
||||
|
||||
switch AlgorithmID(algo) {
|
||||
case EnvelopedSignatureAltorithmId:
|
||||
if !recursivelyRemoveElement(el, sig.UnderlyingElement()) {
|
||||
if !removeElementAtPath(el, signaturePath) {
|
||||
return nil, nil, errors.New("Error applying canonicalization transform: Signature not found")
|
||||
}
|
||||
|
||||
@@ -115,6 +144,12 @@ func (ctx *ValidationContext) transform(
|
||||
case CanonicalXML11AlgorithmId:
|
||||
canonicalizer = MakeC14N11Canonicalizer()
|
||||
|
||||
case CanonicalXML10RecAlgorithmId:
|
||||
canonicalizer = MakeC14N10RecCanonicalizer()
|
||||
|
||||
case CanonicalXML10CommentAlgorithmId:
|
||||
canonicalizer = MakeC14N10CommentCanonicalizer()
|
||||
|
||||
default:
|
||||
return nil, nil, errors.New("Unknown Transform Algorithm: " + algo)
|
||||
}
|
||||
@@ -150,7 +185,16 @@ func (ctx *ValidationContext) digest(el *etree.Element, digestAlgorithmId string
|
||||
func (ctx *ValidationContext) verifySignedInfo(sig *types.Signature, canonicalizer Canonicalizer, signatureMethodId string, cert *x509.Certificate, decodedSignature []byte) error {
|
||||
signatureElement := sig.UnderlyingElement()
|
||||
|
||||
signedInfo := signatureElement.FindElement(childPath(signatureElement.Space, SignedInfoTag))
|
||||
nsCtx, err := etreeutils.NSBuildParentContext(signatureElement)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
signedInfo, err := etreeutils.NSFindOneChildCtx(nsCtx, signatureElement, Namespace, SignedInfoTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if signedInfo == nil {
|
||||
return errors.New("Missing SignedInfo")
|
||||
}
|
||||
@@ -189,7 +233,7 @@ func (ctx *ValidationContext) verifySignedInfo(sig *types.Signature, canonicaliz
|
||||
}
|
||||
|
||||
func (ctx *ValidationContext) validateSignature(el *etree.Element, sig *types.Signature, cert *x509.Certificate) (*etree.Element, error) {
|
||||
idAttr := el.SelectAttr(DefaultIdAttr)
|
||||
idAttr := el.SelectAttr(ctx.IdAttribute)
|
||||
if idAttr == nil || idAttr.Value == "" {
|
||||
return nil, errors.New("Missing ID attribute")
|
||||
}
|
||||
@@ -254,7 +298,7 @@ func contains(roots []*x509.Certificate, cert *x509.Certificate) bool {
|
||||
|
||||
// findSignature searches for a Signature element referencing the passed root element.
|
||||
func (ctx *ValidationContext) findSignature(el *etree.Element) (*types.Signature, error) {
|
||||
idAttr := el.SelectAttr(DefaultIdAttr)
|
||||
idAttr := el.SelectAttr(ctx.IdAttribute)
|
||||
if idAttr == nil || idAttr.Value == "" {
|
||||
return nil, errors.New("Missing ID attribute")
|
||||
}
|
||||
@@ -265,19 +309,18 @@ func (ctx *ValidationContext) findSignature(el *etree.Element) (*types.Signature
|
||||
err := etreeutils.NSFindIterate(el, Namespace, SignatureTag, func(ctx etreeutils.NSContext, el *etree.Element) error {
|
||||
|
||||
found := false
|
||||
err := etreeutils.NSFindIterateCtx(ctx, el, Namespace, SignedInfoTag,
|
||||
err := etreeutils.NSFindChildrenIterateCtx(ctx, el, Namespace, SignedInfoTag,
|
||||
func(ctx etreeutils.NSContext, signedInfo *etree.Element) error {
|
||||
// Ignore any SignedInfo that isn't an immediate descendent of Signature.
|
||||
if signedInfo.Parent() != el {
|
||||
return nil
|
||||
}
|
||||
|
||||
detachedSignedInfo, err := etreeutils.NSDetatch(ctx, signedInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c14NMethod := detachedSignedInfo.FindElement(childPath(detachedSignedInfo.Space, CanonicalizationMethodTag))
|
||||
c14NMethod, err := etreeutils.NSFindOneChildCtx(ctx, detachedSignedInfo, Namespace, CanonicalizationMethodTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c14NMethod == nil {
|
||||
return errors.New("missing CanonicalizationMethod on Signature")
|
||||
}
|
||||
@@ -302,6 +345,12 @@ func (ctx *ValidationContext) findSignature(el *etree.Element) (*types.Signature
|
||||
case CanonicalXML11AlgorithmId:
|
||||
canonicalSignedInfo = canonicalPrep(detachedSignedInfo, map[string]struct{}{})
|
||||
|
||||
case CanonicalXML10RecAlgorithmId:
|
||||
canonicalSignedInfo = canonicalPrep(detachedSignedInfo, map[string]struct{}{})
|
||||
|
||||
case CanonicalXML10CommentAlgorithmId:
|
||||
canonicalSignedInfo = canonicalPrep(detachedSignedInfo, map[string]struct{}{})
|
||||
|
||||
default:
|
||||
return fmt.Errorf("invalid CanonicalizationMethod on Signature: %s", c14NAlgorithm)
|
||||
}
|
||||
@@ -363,11 +412,12 @@ func (ctx *ValidationContext) verifyCertificate(sig *types.Signature) (*x509.Cer
|
||||
|
||||
if sig.KeyInfo != nil {
|
||||
// If the Signature includes KeyInfo, extract the certificate from there
|
||||
if sig.KeyInfo.X509Data.X509Certificate.Data == "" {
|
||||
if len(sig.KeyInfo.X509Data.X509Certificates) == 0 || sig.KeyInfo.X509Data.X509Certificates[0].Data == "" {
|
||||
return nil, errors.New("missing X509Certificate within KeyInfo")
|
||||
}
|
||||
|
||||
certData, err := base64.StdEncoding.DecodeString(sig.KeyInfo.X509Data.X509Certificate.Data)
|
||||
certData, err := base64.StdEncoding.DecodeString(
|
||||
whiteSpace.ReplaceAllString(sig.KeyInfo.X509Data.X509Certificates[0].Data, ""))
|
||||
if err != nil {
|
||||
return nil, errors.New("Failed to parse certificate")
|
||||
}
|
||||
|
Reference in New Issue
Block a user