signedxml

package module
v0.0.0-...-4cf41fd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 28, 2021 License: MIT Imports: 18 Imported by: 0

README

signedxml

Build Status GoDoc

The signedxml package transforms and validates signed xml documents. The main use case is to support Single Sign On protocols like SAML and WS-Federation.

Other packages that provide similar functionality rely on C libraries, which makes them difficult to run across platforms without significant configuration. signedxml is written in pure go, and can be easily used on any platform.

Install

go get github.com/ma314smith/signedxml

Included Algorithms

Examples

Validating signed XML

If your signed xml contains the signature and certificate, then you can just pass in the xml and call Validate().

validator, err := signedxml.NewValidator(`<YourXMLString></YourXMLString>`)
xml, err = validator.ValidateReferences()

ValidateReferences() verifies the DigestValue and SignatureValue in the xml document, and returns the signed payload(s). If the error value is nil, then the signed xml is valid.

The x509.Certificate that was successfully used to validate the xml will be available by calling:

validator.SigningCert()

You can then verify that you trust the certificate. You can optionally supply your trusted certificates ahead of time by assigning them to the Certificates property of the Validator object, which is an x509.Certificate array.

Using an external Signature

If you need to specify an external Signature, you can use the SetSignature() function to assign it:

validator.SetSignature(<`Signature></Signature>`)
Generating signed XML

It is expected that your XML contains the Signature element with all the parameters set (except DigestValue and SignatureValue).

signer, err := signedxml.NewSigner(`<YourXMLString></YourXMLString`)
signedXML, err := signer.Sign(`*rsa.PrivateKey object`)

Sign() will generate the DigestValue and SignatureValue, populate it in the XML, and return the signed XML string.

Implementing custom transforms

Additional Transform algorithms can be included by adding to the CanonicalizationAlgorithms map. This interface will need to be implemented:

type CanonicalizationAlgorithm interface {
	Process(inputXML string, transformXML string) (outputXML string, err error)
}

Simple Example:

type NoChangeCanonicalization struct{}

func (n NoChangeCanonicalization) Process(inputXML string,
	transformXML string) (outputXML string, err error) {
	return inputXML, nil
}

signedxml.CanonicalizationAlgorithms["http://myTranform"] = NoChangeCanonicalization{}

See envelopedsignature.go and exclusivecanonicalization.go for examples of actual implementations.

Using a custom reference ID attribute

It is possible to set a custom reference ID attribute for both the signer and the validator. The default value is "ID"

Signer example:

signer.SetReferenceIDAttribute("customId")

Validator example:

validator.SetReferenceIDAttribute("customId")

Contributions

Contributions are welcome. Just fork the repo and send a pull request.

Documentation

Overview

Package signedxml transforms and validates signedxml documents

Index

Constants

This section is empty.

Variables

View Source
var CanonicalizationAlgorithms map[string]CanonicalizationAlgorithm

CanonicalizationAlgorithms maps the CanonicalizationMethod or Transform Algorithm URIs to a type that implements the CanonicalizationAlgorithm interface.

Implementations are provided for the following transforms:

http://www.w3.org/2001/10/xml-exc-c14n# (ExclusiveCanonicalization)
http://www.w3.org/2001/10/xml-exc-c14n#WithComments (ExclusiveCanonicalizationWithComments)
http://www.w3.org/2000/09/xmldsig#enveloped-signature (EnvelopedSignature)

Custom implementations can be added to the map

Functions

func CalculateHash

func CalculateHash(targetToBeHashed []byte, digestMethodURI string) (string, error)

calculates a hash of a targetToBeHashed ([]byte), detecting the hash algorithm by the URI string. The URI follows notation common for XML Signatures. If successfull, it outputs base64 encoded string of a target hash digest (fingerprint).

func CalculateHashFromRef

func CalculateHashFromRef(reference *etree.Element, targetToBeHashed interface{}) (string, error)

calculates a hash of a TargetToBeHashed (*etree.Document or []byte), detecting the hash algorithm in the reference element. If successful, hash digest value in base64 encoded string is written to the reference element/DigestValue tag.

func LoadCertFromPEMString

func LoadCertFromPEMString(pemString, pubKeyType string) (*x509.Certificate, error)

func PopulateElementWithNameSpaces

func PopulateElementWithNameSpaces(targetElem *etree.Element, rootDoc *etree.Document) (err error)

Copies all namespaces that related to the targetElement. It must have the following namespaces: - own namespaces (if it defines such): nothing todo here, typically, they're defined in attributes of that element; - if the element has a prefix, but no definition for it, then parent has this namespace defined; - if any of the sub-elementas have a prefix, which is different from targetElement, then some parent must define it. Needed before canonicalizing and calculating hash of the target Element. TargetElem is always a sub-tag (child) of RootDoc

func ValidateCertificate

func ValidateCertificate(cert *x509.Certificate, certDigest, digestMethodURI, notBefore, notAfter string) (err error)

Validates certificate: 1. checks if it hasn't expired, 2. calculates certificate hash digest and compares to supplied certificate digest value. Params 'notBefore', 'notAfter' are optional, just for setting validity dates separately, else X509.Certificate container equivalent values are used

Types

type C14N10Canonicalizer

type C14N10Canonicalizer struct {
	WithComments bool
}

func (C14N10Canonicalizer) Process

func (c C14N10Canonicalizer) Process(inputXML string,
	transformXML string) (outputXML string, err error)

type C14N10ExclusiveCanonicalizer

type C14N10ExclusiveCanonicalizer struct {
	WithComments bool
}

func (C14N10ExclusiveCanonicalizer) Process

func (c C14N10ExclusiveCanonicalizer) Process(inputXML string,
	transformXML string) (outputXML string, err error)

type C14N11Canonicalizer

type C14N11Canonicalizer struct {
	WithComments bool
}

func (C14N11Canonicalizer) Process

func (c C14N11Canonicalizer) Process(inputXML string,
	transformXML string) (outputXML string, err error)

type CanonicalizationAlgorithm

type CanonicalizationAlgorithm interface {
	Process(inputXML string, transformXML string) (outputXML string, err error)
}

CanonicalizationAlgorithm defines an interface for processing an XML document into a standard format.

If any child elements are in the Transform node, the entire transform node will be passed to the Process method through the transformXML parameter as an XML string. This is necessary for transforms that need additional processing data, like XPath (http://www.w3.org/TR/xmldsig-core/#sec-XPath). If there are no child elements in Transform (or CanonicalizationMethod), then an empty string will be passed through.

type EnvelopedSignature

type EnvelopedSignature struct{}

EnvelopedSignature implements the CanonicalizationAlgorithm interface and is used for processing the http://www.w3.org/2000/09/xmldsig#enveloped-signature transform algorithm

func (EnvelopedSignature) Process

func (e EnvelopedSignature) Process(inputXML string,
	transformXML string) (outputXML string, err error)

Process is called to transfrom the XML using the EnvelopedSignature algorithm

type ExclusiveCanonicalization

type ExclusiveCanonicalization struct {
	WithComments bool
	// contains filtered or unexported fields
}

ExclusiveCanonicalization implements the CanonicalizationAlgorithm interface and is used for processing the http://www.w3.org/2001/10/xml-exc-c14n# and http://www.w3.org/2001/10/xml-exc-c14n#WithComments transform algorithms

func (ExclusiveCanonicalization) Process

func (e ExclusiveCanonicalization) Process(inputXML string,
	transformXML string) (outputXML string, err error)

Process is called to transfrom the XML using the ExclusiveCanonicalization algorithm

type Signer

type Signer struct {
	// contains filtered or unexported fields
}

Signer provides options for signing an XML document

func NewSigner

func NewSigner(xml string) (*Signer, error)

NewSigner returns a *Signer for the XML provided

func (*Signer) SetReferenceIDAttribute

func (s *Signer) SetReferenceIDAttribute(refIDAttribute string)

SetReferenceIDAttribute set the referenceIDAttribute

func (*Signer) SetSignature

func (s *Signer) SetSignature(sig string) error

SetSignature can be used to assign an external signature for the XML doc that Validator will verify

func (*Signer) Sign

func (s *Signer) Sign(privateKey interface{}) (string, error)

Sign populates the XML digest and signature based on the parameters present and privateKey given

type Validator

type Validator struct {
	Certificates  []x509.Certificate
	RSAPublicKeys []*rsa.PublicKey
	// contains filtered or unexported fields
}

Validator provides options for verifying a signed XML document

func NewValidator

func NewValidator(xml string) (*Validator, error)

NewValidator returns a *Validator for the XML provided

func (*Validator) SetReferenceIDAttribute

func (v *Validator) SetReferenceIDAttribute(refIDAttribute string)

SetReferenceIDAttribute set the referenceIDAttribute

func (*Validator) SetSignature

func (s *Validator) SetSignature(sig string) error

SetSignature can be used to assign an external signature for the XML doc that Validator will verify

func (*Validator) SetValidationCert

func (v *Validator) SetValidationCert(cert *x509.Certificate)

func (*Validator) SetValidationCertFromPEMString

func (v *Validator) SetValidationCertFromPEMString(certPEM string) error

func (*Validator) SetXML

func (v *Validator) SetXML(xml string) error

SetXML is used to assign the XML document that the Validator will verify

func (*Validator) SigningCert

func (v *Validator) SigningCert() x509.Certificate

SigningCert returns the certificate, if any, that was used to successfully validate the signature of the XML document. This will be a zero value x509.Certificate before Validator.Validate is successfully called.

func (*Validator) Validate deprecated

func (v *Validator) Validate() error

Validate validates the Reference digest values, and the signature value over the SignedInfo.

Deprecated: Use ValidateReferences instead

func (*Validator) ValidateReferences

func (v *Validator) ValidateReferences() ([]string, error)

ValidateReferences validates the Reference digest values, and the signature value over the SignedInfo.

If the signature is enveloped in the XML, then it will be used. Otherwise, an external signature should be assigned using Validator.SetSignature.

The references returned by this method can be used to verify what was signed.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL