xades

package module
v0.2.2-0...-924c397 Latest Latest
Warning

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

Go to latest
Published: Nov 23, 2020 License: Apache-2.0 Imports: 8 Imported by: 0

README

goxades

Implementation of XAdES signature in golang

Installation

Install goxades using go get:

$ go get github.com/artemkunich/goxades

Usage

Creating signature
package main

import (
	"crypto"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"strings"

	xades "github.com/artemkunich/goxades"
	"github.com/beevik/etree"
	dsig "github.com/russellhaering/goxmldsig"
)

var sampleXml = `<element id="signedData" xmlns="namespace">text</element>`

func main() {

	doc := etree.NewDocument()
	err := doc.ReadFromString(strings.ReplaceAll(sampleXml, "\n", ""))
	if err != nil {
		fmt.Printf("%v\n", err.Error())
	}

	keyStore, err := loadCert("key.pem", "cert.crt")
	if err != nil {
		fmt.Printf("%v\n", err.Error())
	}

	root := removeComments(doc.Root())
	canonicalizer := dsig.MakeC14N10ExclusiveCanonicalizerWithPrefixList("")
	signContext := xades.SigningContext{
		DataContext: xades.SignedDataContext{
			Canonicalizer: canonicalizer,
			Hash:          crypto.SHA256,
			ReferenceURI:  "#signedData",
			IsEnveloped:   true,
		},
		PropertiesContext: xades.SignedPropertiesContext{
			Canonicalizer: canonicalizer,
			Hash:          crypto.SHA256,
		},
		Canonicalizer: canonicalizer,
		Hash:          crypto.SHA256,
		KeyStore:      *keyStore,
	}
	signature, err := xades.CreateSignature(root, &signContext)
	if err != nil {
		fmt.Printf("%v\n", err.Error())
	}

	b, err := canonicalSerialize(signature)
	if err != nil {
		fmt.Printf("%v\n", err.Error())
	}
	fmt.Println(string(b))
}

func removeComments(elem *etree.Element) *etree.Element {
	copy := elem.Copy()
	for _, token := range copy.Child {
		_, ok := token.(*etree.Comment)
		if ok {
			copy.RemoveChild(token)
		}
	}
	for i, child := range elem.ChildElements() {
		copy.ChildElements()[i] = removeComments(child)
	}
	return copy
}

func canonicalSerialize(el *etree.Element) ([]byte, error) {
	doc := etree.NewDocument()
	doc.SetRoot(el.Copy())

	doc.WriteSettings = etree.WriteSettings{
		CanonicalAttrVal: true,
		CanonicalEndTags: false,
		CanonicalText:    true,
	}

	return doc.WriteToBytes()
}

func loadCert(keyPath string, certPath string) (*xades.MemoryX509KeyStore, error) {
	buffer, err := ioutil.ReadFile(certPath)
	if err != nil {
		return nil, err
	}

	blockc, _ := pem.Decode(buffer)
	cert, err := x509.ParseCertificate(blockc.Bytes)

	buffer, err = ioutil.ReadFile(keyPath)
	if err != nil {
		return nil, err
	}
	blockp, _ := pem.Decode(buffer)
	key, err := x509.ParsePKCS1PrivateKey(blockp.Bytes)

	return &xades.MemoryX509KeyStore{
		PrivateKey: key,
		Cert:       cert,
		CertBinary: blockc.Bytes,
	}, nil
}



Documentation

Index

Constants

View Source
const (
	Prefix    string = "xades"
	Namespace string = "http://uri.etsi.org/01903/v1.3.2#"
)
View Source
const (
	SignedPropertiesTag          string = "SignedProperties"
	SignedSignaturePropertiesTag string = "SignedSignatureProperties"
	SigningTimeTag               string = "SigningTime"
	SigningCertificateTag        string = "SigningCertificate"
	CertTag                      string = "Cert"
	IssuerSerialTag              string = "IssuerSerial"
	CertDigestTag                string = "CertDigest"
	QualifyingPropertiesTag      string = "QualifyingProperties"
)

Variables

This section is empty.

Functions

func CreateSignature

func CreateSignature(signedData *etree.Element, ctx *SigningContext) (*etree.Element, error)

CreateSignature create filled signature element

func DigestValue

func DigestValue(element *etree.Element, canonicalizer *dsig.Canonicalizer, hash crypto.Hash) (base64encoded string, err error)

DigestValue calculate hash for digest

func SignatureValue

func SignatureValue(element *etree.Element, canonicalizer *dsig.Canonicalizer, hash crypto.Hash, keyStore *MemoryX509KeyStore) (base64encoded string, err error)

SignatureValue calculate signature

Types

type MemoryX509KeyStore

type MemoryX509KeyStore struct {
	PrivateKey *rsa.PrivateKey
	Cert       *x509.Certificate
	CertBinary []byte
}

MemoryX509KeyStore struct

func (*MemoryX509KeyStore) GetKeyPair

func (ks *MemoryX509KeyStore) GetKeyPair() (*rsa.PrivateKey, []byte, error)

GetKeyPair func

type SignedDataContext

type SignedDataContext struct {
	Canonicalizer dsig.Canonicalizer
	Hash          crypto.Hash
	ReferenceURI  string
	IsEnveloped   bool
}

type SignedPropertiesContext

type SignedPropertiesContext struct {
	Canonicalizer dsig.Canonicalizer
	Hash          crypto.Hash
	SigninigTime  time.Time
}

type SigningContext

type SigningContext struct {
	DataContext       SignedDataContext
	PropertiesContext SignedPropertiesContext
	Canonicalizer     dsig.Canonicalizer
	Hash              crypto.Hash
	KeyStore          MemoryX509KeyStore
}

Jump to

Keyboard shortcuts

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