xmlsec

package module
v0.0.0-...-d2b1a58 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2020 License: BSD-2-Clause Imports: 11 Imported by: 13

README

go-xmlsec

Build Status

A partial wrapper for xmlsec.

As seems to be the case for many things in the XMLish world, the xmldsig and xmlenc standards are more complex that may be nessesary. This library is as general as I could reasonably make it with an eye towards supporting the parts of the standards that are needed to support a SAML implementation. If there are missing bits you feel you need, please raise an issue or submit a pull request.

Examples

Signing

key, _ := ioutil.ReadFile("saml.key")
doc, _ := ioutil.ReadAll(os.Stdin)
signedDoc, err := Sign(key, doc, SignatureOptions{})
os.Stdout.Write(signedDoc)

Verifying

key, _ := ioutil.ReadFile("saml.crt")
doc, _ := ioutil.ReadAll(os.Stdin)
err := xmldsig.Verify(key, doc, SignatureOptions{})
if err == xmldsig.ErrVerificationFailed {
  os.Exit(1)
}

Decrypting

key, _ := ioutil.ReadFile("saml.key")
doc, _ := ioutil.ReadAll(os.Stdin)
plaintextDoc, err := Decrypt(key, doc)
os.Stdout.Write(plaintextDoc)

Encrypting

key, _ := ioutil.ReadFile("saml.crt")
doc, _ := ioutil.ReadAll(os.Stdin)
encryptedDoc, err := Encrypt(key, doc, EncryptOptions{})
os.Stdout.Write(encryptedDoc)

Install

This package uses cgo to wrap libxmlsec. As such, you'll need libxmlsec headers and a C compiler to make it work. On linux, this might look like:

$ apt-get install libxml2-dev libxmlsec1-dev pkg-config
$ go get github.com/crewjam/go-xmlsec

On Mac with homebrew, this might look like:

$ brew install libxmlsec1 libxml2 pkg-config
$ go get github.com/crewjam/go-xmlsec

Static Linking

It may annoy you to grow a depenency on the shared libraries for libxmlsec, libxml2, etc. After some fighting, here is what I made work on Linux to get a static binary. See also Dockerfile.build-static which build the example program using this method.

Compile libxml

curl -sL ftp://xmlsoft.org/libxml2/libxml2-2.9.4.tar.gz | tar -xzf -
cd /libxml2-2.9.4
./configure --enable-static --disable-shared --without-gnu-ld --with-c14n --without-catalog --without-debug --without-docbook  --without-fexceptions  --without-ftp --without-history --without-html --without-http --without-iconv --without-icu --without-iso8859x --without-legacy --without-mem-debug --without-minimum --with-output --without-pattern --with-push --without-python --without-reader --without-readline --without-regexps --without-run-debug --with-sax1 --without-schemas --without-schematron --without-threads --without-thread-alloc --with-tree --without-valid --without-writer --without-xinclude --without-xpath --with-xptr --without-modules --without-zlib --without-lzma --without-coverage
make install

Compile openssl

curl -sL ftp://ftp.openssl.org/source/openssl-1.0.2h.tar.gz | tar -xzf -
cd openssl-1.0.2h
./config no-shared no-weak-ssl-ciphers no-ssl2 no-ssl3 no-comp no-idea no-dtls no-hw no-threads no-dso
make install

Compile libxmlsec

curl -sL http://www.aleksey.com/xmlsec/download/xmlsec1-1.2.22.tar.gz | tar -xzf -
./configure --enable-static --disable-shared --disable-crypto-dl --disable-apps-crypto-dl --enable-static-linking --without-gnu-ld       --with-default-crypto=openssl --with-openssl=/usr/local/ssl --with-libxml=/usr/local --without-nss --without-nspr --without-gcrypt --without-gnutls --without-libxslt
make -C src install
make -C include install
make install-pkgconfigDATA

Build with static tag

go build -tags static -ldflags '-s -extldflags "-static"' -o /bin/xmldsig-static.bin ./examples/xmldsig.go

Running ldd on the output should produce not a dynamic executable.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrVerificationFailed = errors.New("signature verification failed")

ErrVerificationFailed is returned from Verify when the signature is incorrect

Functions

func Decrypt

func Decrypt(privateKey []byte, doc []byte) ([]byte, error)

Decrypt finds the first encrypted part of doc, decrypts it using privateKey and returns the plaintext of the embedded document.

func Encrypt

func Encrypt(publicKey, doc []byte, opts EncryptOptions) ([]byte, error)

Encrypt encrypts the XML document to publicKey and returns the encrypted document.

func Sign

func Sign(key []byte, doc []byte, opts SignatureOptions) ([]byte, error)

Sign returns a version of doc signed with key according to the XMLDSIG standard. doc is a template document meaning that it contains an `http://www.w3.org/2000/09/xmldsig#Signature` element whose properties define how and what to sign.

func Verify

func Verify(publicKey []byte, doc []byte, opts SignatureOptions) error

Verify checks that the signature in doc is valid according to the XMLDSIG specification. publicKey is the public part of the key used to sign doc. If the signature is not correct, this function returns ErrVerificationFailed.

func VerifyTrusted

func VerifyTrusted(certs [][]byte, doc []byte, opts SignatureOptions) error

Verify checks that the signature in doc is valid according to the XMLDSIG specification. certs is an array of trusted certificates. If the signature is not correct, this function returns ErrVerificationFailed.

Types

type CipherType

type CipherType int

CipherType represent which cipher to use to encrypt the document

const (
	// DefaultCipher (the zero value) represents the default cipher, RSA-OAEP
	DefaultCipher CipherType = iota

	// RsaOaep means the cipher should be RSA-OAEP
	RsaOaep

	// RsaPkcs1 means the cipher should be RSA-PKCS1
	RsaPkcs1
)

type DigestAlgorithmType

type DigestAlgorithmType int

DigestAlgorithmType represent which digest algorithm to use when encrypting the document.

const (
	// DefaultDigestAlgorithm (the zero value) represents the default cipher, SHA1
	DefaultDigestAlgorithm DigestAlgorithmType = iota

	// Sha1 means the digest algorithm should be SHA-1
	Sha1

	// Sha256 means the digest algorithm should be SHA-256
	Sha256

	// Sha384 means the digest algorithm should be SHA-384
	Sha384

	// Sha512 means the digest algorithm should be SHA-512
	Sha512
)

type EncryptOptions

type EncryptOptions struct {
	SessionCipher   SessionCipherType
	Cipher          CipherType
	DigestAlgorithm DigestAlgorithmType
}

EncryptOptions specifies the ciphers to use to encrypt the document.

type Method

type Method struct {
	Algorithm string `xml:",attr"`
}

Method is part of Signature.

type SessionCipherType

type SessionCipherType int

SessionCipherType represents which session cipher to use to encrypt the document.

const (
	// DefaultSessionCipher (the zero value) represents the default session cipher, AES256-CBC
	DefaultSessionCipher SessionCipherType = iota

	// Aes128Cbc means the session cipher should be AES-128 in CBC mode.
	Aes128Cbc

	// Aes192Cbc means the session cipher should be AES-192 in CBC mode.
	Aes192Cbc

	// Aes256Cbc means the session cipher should be AES-256 in CBC mode.
	Aes256Cbc

	// Des3Cbc means the session cipher should be triple DES in CBC mode.
	Des3Cbc
)

type Signature

type Signature struct {
	XMLName xml.Name `xml:"http://www.w3.org/2000/09/xmldsig# Signature"`

	CanonicalizationMethod Method             `xml:"SignedInfo>CanonicalizationMethod"`
	SignatureMethod        Method             `xml:"SignedInfo>SignatureMethod"`
	ReferenceTransforms    []Method           `xml:"SignedInfo>Reference>Transforms>Transform"`
	DigestMethod           Method             `xml:"SignedInfo>Reference>DigestMethod"`
	DigestValue            string             `xml:"SignedInfo>Reference>DigestValue"`
	SignatureValue         string             `xml:"SignatureValue"`
	KeyName                string             `xml:"KeyInfo>KeyName,omitempty"`
	X509Certificate        *SignatureX509Data `xml:"KeyInfo>X509Data,omitempty"`
}

Signature is a model for the Signature object specified by XMLDSIG. This is convenience object when constructing XML that you'd like to sign. For example:

type Foo struct {
   Stuff string
   Signature Signature
}

f := Foo{Suff: "hello"}
f.Signature = DefaultSignature()
buf, _ := xml.Marshal(f)
buf, _ = Sign(key, buf)

func DefaultSignature

func DefaultSignature(pemEncodedPublicKey []byte) Signature

DefaultSignature returns a Signature struct that uses the default c14n and SHA1 settings.

type SignatureOptions

type SignatureOptions struct {
	// Specify the name of ID attributes for specific elements. This
	// may be required if the signed document contains Reference elements
	// that define which parts of the document are to be signed.
	//
	// https://www.aleksey.com/xmlsec/faq.html#section_3_2
	// http://www.w3.org/TR/xml-id/
	// http://xmlsoft.org/html/libxml-valid.html#xmlAddID
	XMLID []XMLIDOption
}

SignatureOptions represents additional, less commonly used, options for Sign and Verify

type SignatureX509Data

type SignatureX509Data struct {
	X509Certificate string `xml:"X509Certificate,omitempty"`
}

SignatureX509Data represents the <X509Data> element of <Signature>

type XMLIDOption

type XMLIDOption struct {
	ElementName      string
	ElementNamespace string
	AttributeName    string
}

XMLIDOption represents the definition of an XML reference element (See http://www.w3.org/TR/xml-id/)

Directories

Path Synopsis
Package xmlenc implements xml encrytion natively (https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html)
Package xmlenc implements xml encrytion natively (https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html)

Jump to

Keyboard shortcuts

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