Merge branch 'tecnickcom-master'
Update Package with some fixes
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
coverage.html
|
||||
coverage.out
|
||||
target
|
||||
vendor
|
||||
/Dockerfile
|
||||
|
||||
40
.travis.yml
40
.travis.yml
@@ -1,5 +1,15 @@
|
||||
language: go
|
||||
sudo: false # silence warning
|
||||
|
||||
sudo: false
|
||||
|
||||
branches:
|
||||
except:
|
||||
- release
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
addons:
|
||||
apt:
|
||||
@@ -8,14 +18,26 @@ addons:
|
||||
- libxmlsec1-dev
|
||||
|
||||
go:
|
||||
- 1.6
|
||||
- 1.7
|
||||
- '1.11.1'
|
||||
- tip
|
||||
|
||||
install:
|
||||
- go get -t ./...
|
||||
- go get github.com/golang/lint/golint
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
before_install:
|
||||
- if [ -n "$GH_USER" ]; then git config --global github.user ${GH_USER}; fi;
|
||||
- if [ -n "$GH_TOKEN" ]; then git config --global github.token ${GH_TOKEN}; fi;
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
before_script:
|
||||
- make deps
|
||||
|
||||
script:
|
||||
- golint *.go
|
||||
- go vet ./...
|
||||
- go test -v ./...
|
||||
- make qa
|
||||
|
||||
after_failure:
|
||||
- cat ./target/test/report.xml
|
||||
|
||||
after_success:
|
||||
- if [ "$TRAVIS_GO_VERSION" = "1.11.1" ]; then $HOME/gopath/bin/goveralls -covermode=count -coverprofile=target/report/coverage.out -service=travis-ci; fi;
|
||||
|
||||
@@ -2,13 +2,13 @@ FROM ubuntu
|
||||
RUN apt-get update -yy && \
|
||||
apt-get install -yy git make curl libxml2-dev libxmlsec1-dev liblzma-dev pkg-config
|
||||
|
||||
RUN curl -s https://storage.googleapis.com/golang/go1.7.linux-amd64.tar.gz | tar -C /usr/local -xzf -
|
||||
RUN curl -s https://storage.googleapis.com/golang/go1.11.2.linux-amd64.tar.gz | tar -C /usr/local -xzf -
|
||||
ENV GOPATH=/go
|
||||
ENV PATH=$PATH:/usr/local/go/bin:/go/bin
|
||||
RUN mkdir -p /go/bin
|
||||
|
||||
ADD . /go/src/github.com/crewjam/go-xmlsec
|
||||
WORKDIR /go/src/github.com/crewjam/go-xmlsec
|
||||
ADD . /go/src/git.deineagentur.com/DeineAgenturUG/go-xmlsec
|
||||
WORKDIR /go/src/git.deineagentur.com/DeineAgenturUG/go-xmlsec
|
||||
RUN go get github.com/crewjam/errset
|
||||
RUN go build -o /bin/xmldsig ./examples/xmldsig.go
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
FROM ubuntu:16.04
|
||||
RUN apt-get update -yy && \
|
||||
apt-get install -yy git make curl pkg-config
|
||||
apt-get install -yy git make curl pkg-config
|
||||
|
||||
RUN curl -s https://storage.googleapis.com/golang/go1.7.linux-amd64.tar.gz | tar -C /usr/local -xzf -
|
||||
RUN curl -s https://storage.googleapis.com/golang/go1.7.3.linux-amd64.tar.gz | tar -C /usr/local -xzf -
|
||||
ENV GOPATH=/go
|
||||
ENV PATH=$PATH:/usr/local/go/bin:/go/bin
|
||||
RUN mkdir -p /go/bin
|
||||
@@ -22,7 +22,7 @@ RUN curl -sL ftp://xmlsoft.org/libxml2/libxml2-2.9.4.tar.gz | tar -xzf - && \
|
||||
--without-history \
|
||||
--without-html \
|
||||
--without-http \
|
||||
--without-iconv \
|
||||
--without-iconv \
|
||||
--without-icu \
|
||||
--without-iso8859x \
|
||||
--without-legacy \
|
||||
@@ -31,7 +31,7 @@ RUN curl -sL ftp://xmlsoft.org/libxml2/libxml2-2.9.4.tar.gz | tar -xzf - && \
|
||||
--with-output \
|
||||
--without-pattern \
|
||||
--with-push \
|
||||
--without-python \
|
||||
--without-python \
|
||||
--without-reader \
|
||||
--without-readline \
|
||||
--without-regexps \
|
||||
@@ -53,8 +53,7 @@ RUN curl -sL ftp://xmlsoft.org/libxml2/libxml2-2.9.4.tar.gz | tar -xzf - && \
|
||||
--without-coverage && \
|
||||
make install
|
||||
|
||||
RUN \
|
||||
curl -sL ftp://ftp.openssl.org/source/openssl-1.0.2j.tar.gz | tar -xzf - && \
|
||||
RUN curl -sL ftp://ftp.openssl.org/source/openssl-1.0.2j.tar.gz | tar -xzf - && \
|
||||
cd openssl-1.0.2j && \
|
||||
./config \
|
||||
no-shared \
|
||||
@@ -70,28 +69,28 @@ RUN \
|
||||
make depend install
|
||||
|
||||
RUN curl -sL http://www.aleksey.com/xmlsec/download/xmlsec1-1.2.22.tar.gz | tar -xzf - && \
|
||||
cd xmlsec1-1.2.22 && \
|
||||
./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
|
||||
cd xmlsec1-1.2.22 && \
|
||||
./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
|
||||
|
||||
ADD . /go/src/github.com/crewjam/go-xmlsec
|
||||
WORKDIR /go/src/github.com/crewjam/go-xmlsec
|
||||
ADD . /go/src/git.deineagentur.com/DeineAgenturUG/go-xmlsec
|
||||
WORKDIR /go/src/git.deineagentur.com/DeineAgenturUG/go-xmlsec
|
||||
RUN go get github.com/crewjam/errset
|
||||
RUN go build -tags static -ldflags '-s -extldflags "-static"' -o /bin/xmldsig ./examples/xmldsig.go
|
||||
RUN ldd /bin/xmldsig || true
|
||||
|
||||
177
Makefile
Normal file
177
Makefile
Normal file
@@ -0,0 +1,177 @@
|
||||
# MAKEFILE
|
||||
#
|
||||
# @author Nicola Asuni <info@tecnick.com>
|
||||
# @link https://git.deineagentur.com/DeineAgenturUG/go-xmlsec
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# List special make targets that are not associated with files
|
||||
.PHONY: help all test format fmtcheck vet lint coverage cyclo ineffassign misspell astscan qa deps clean nuke buildall dbuild
|
||||
|
||||
# Use bash as shell (Note: Ubuntu now uses dash which doesn't support PIPESTATUS).
|
||||
SHELL=/bin/bash
|
||||
|
||||
# CVS path (path to the parent dir containing the project)
|
||||
CVSPATH=git.deineagentur.com/DeineAgenturUG/go-xmlsec
|
||||
|
||||
# Project vendor
|
||||
VENDOR=miracl
|
||||
|
||||
# Project name
|
||||
PROJECT=go-xmlsec
|
||||
|
||||
# Project version
|
||||
VERSION=$(shell cat VERSION)
|
||||
|
||||
# Project release number (packaging build number)
|
||||
RELEASE=$(shell cat RELEASE)
|
||||
|
||||
# Current directory
|
||||
CURRENTDIR=$(shell pwd)
|
||||
|
||||
# GO lang path
|
||||
ifneq ($(GOPATH),)
|
||||
ifeq ($(findstring $(GOPATH),$(CURRENTDIR)),)
|
||||
# the defined GOPATH is not valid
|
||||
GOPATH=
|
||||
endif
|
||||
endif
|
||||
ifeq ($(GOPATH),)
|
||||
# extract the GOPATH
|
||||
GOPATH=$(firstword $(subst /src/, ,$(CURRENTDIR)))
|
||||
endif
|
||||
|
||||
# Add the GO binary dir in the PATH
|
||||
export PATH := $(GOPATH)/bin:$(PATH)
|
||||
|
||||
GOENV=GOPATH=$(GOPATH) CGO_CFLAGS_ALLOW='-w'
|
||||
|
||||
# --- MAKE TARGETS ---
|
||||
|
||||
# Display general help about this command
|
||||
help:
|
||||
@echo ""
|
||||
@echo "$(PROJECT) Makefile."
|
||||
@echo "GOPATH=$(GOPATH)"
|
||||
@echo "The following commands are available:"
|
||||
@echo ""
|
||||
@echo " make qa : Run all the tests and static analysis reports"
|
||||
@echo " make test : Run the unit tests"
|
||||
@echo ""
|
||||
@echo " make format : Format the source code"
|
||||
@echo " make fmtcheck : Check if the source code has been formatted"
|
||||
@echo " make vet : Check for suspicious constructs"
|
||||
@echo " make lint : Check for style errors"
|
||||
@echo " make coverage : Generate the coverage report"
|
||||
@echo " make cyclo : Generate the cyclomatic complexity report"
|
||||
@echo " make ineffassign : Detect ineffectual assignments"
|
||||
@echo " make misspell : Detect commonly misspelled words in source files"
|
||||
@echo " make astscan : GO AST scanner"
|
||||
@echo ""
|
||||
@echo " make docs : Generate source code documentation"
|
||||
@echo ""
|
||||
@echo " make deps : Get the dependencies"
|
||||
@echo " make clean : Remove any build artifact"
|
||||
@echo " make nuke : Deletes any intermediate file"
|
||||
@echo ""
|
||||
@echo " make buildall : Full build and test sequence"
|
||||
@echo " make dbuild : Build everything inside a Docker container"
|
||||
@echo ""
|
||||
|
||||
# Alias for help target
|
||||
all: help
|
||||
|
||||
# Run the unit tests
|
||||
test:
|
||||
@mkdir -p target/test
|
||||
$(GOENV) go test -covermode=atomic -bench=. -race -v . | \
|
||||
tee >($(GOENV) go-junit-report > target/test/report.xml); \
|
||||
test $${PIPESTATUS[0]} -eq 0
|
||||
|
||||
# Format the source code
|
||||
format:
|
||||
@find . -type f -name "*.go" -exec gofmt -s -w {} \;
|
||||
|
||||
# Check if the source code has been formatted
|
||||
fmtcheck:
|
||||
@mkdir -p target
|
||||
@find . -type f -name "*.go" -exec gofmt -s -d {} \; | tee target/format.diff
|
||||
@test ! -s target/format.diff || { echo "ERROR: the source code has not been formatted - please use 'make format' or 'gofmt'"; exit 1; }
|
||||
|
||||
# Check for syntax errors
|
||||
vet:
|
||||
$(GOENV) go vet .
|
||||
|
||||
# Check for style errors
|
||||
lint:
|
||||
$(GOENV) golint .
|
||||
|
||||
# Generate the coverage report
|
||||
coverage:
|
||||
@mkdir -p target/report
|
||||
$(GOENV) go test -covermode=count -coverprofile=target/report/coverage.out -v . && \
|
||||
$(GOENV) go tool cover -html=target/report/coverage.out -o target/report/coverage.html
|
||||
|
||||
# Report cyclomatic complexity
|
||||
cyclo:
|
||||
@mkdir -p target/report
|
||||
$(GOENV) gocyclo -avg . | tee target/report/cyclo.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||
|
||||
# Detect ineffectual assignments
|
||||
ineffassign:
|
||||
@mkdir -p target/report
|
||||
$(GOENV) ineffassign . | tee target/report/ineffassign.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||
|
||||
# Detect commonly misspelled words in source files
|
||||
misspell:
|
||||
@mkdir -p target/report
|
||||
$(GOENV) misspell -error . | tee target/report/misspell.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||
|
||||
# AST scanner
|
||||
astscan:
|
||||
@mkdir -p target/report
|
||||
$(GOENV) gas ./*.go | tee target/report/astscan.txt ; test $${PIPESTATUS[0]} -eq 0 || true
|
||||
|
||||
# Generate source docs
|
||||
docs:
|
||||
@mkdir -p target/docs
|
||||
nohup sh -c '$(GOENV) godoc -http=127.0.0.1:6060' > target/godoc_server.log 2>&1 &
|
||||
wget --directory-prefix=target/docs/ --execute robots=off --retry-connrefused --recursive --no-parent --adjust-extension --page-requisites --convert-links http://127.0.0.1:6060/pkg/github.com/${VENDOR}/${PROJECT}/ ; kill -9 `lsof -ti :6060`
|
||||
@echo '<html><head><meta http-equiv="refresh" content="0;./127.0.0.1:6060/pkg/'${CVSPATH}'/'${PROJECT}'/index.html"/></head><a href="./127.0.0.1:6060/pkg/'${CVSPATH}'/'${PROJECT}'/index.html">'${PKGNAME}' Documentation ...</a></html>' > target/docs/index.html
|
||||
|
||||
# Alias to run targets: fmtcheck test vet lint coverage
|
||||
qa: fmtcheck test vet lint coverage cyclo ineffassign misspell astscan
|
||||
|
||||
# --- INSTALL ---
|
||||
|
||||
# Get the dependencies
|
||||
deps:
|
||||
GOPATH=$(GOPATH) go get $(go list ./... | grep -v /vendor/)
|
||||
GOPATH=$(GOPATH) go get github.com/inconshreveable/mousetrap
|
||||
GOPATH=$(GOPATH) go get golang.org/x/lint/golint
|
||||
GOPATH=$(GOPATH) go get github.com/jstemmer/go-junit-report
|
||||
GOPATH=$(GOPATH) go get github.com/axw/gocov/gocov
|
||||
GOPATH=$(GOPATH) go get github.com/fzipp/gocyclo
|
||||
GOPATH=$(GOPATH) go get github.com/gordonklaus/ineffassign
|
||||
GOPATH=$(GOPATH) go get github.com/client9/misspell/cmd/misspell
|
||||
GOPATH=$(GOPATH) go get github.com/securego/gosec/cmd/gosec/...
|
||||
GOPATH=$(GOPATH) go get gopkg.in/check.v1
|
||||
|
||||
# Remove any build artifact
|
||||
clean:
|
||||
$(GOENV) go clean ./...
|
||||
|
||||
# Deletes any intermediate file
|
||||
nuke:
|
||||
rm -rf ./target
|
||||
$(GOENV) go clean -i ./...
|
||||
|
||||
# Full build and test sequence
|
||||
buildall: deps qa
|
||||
|
||||
# Build everything inside a Docker container
|
||||
dbuild:
|
||||
@mkdir -p target
|
||||
@rm -rf target/*
|
||||
@echo 0 > target/make.exit
|
||||
CVSPATH=$(CVSPATH) VENDOR=$(VENDOR) PROJECT=$(PROJECT) MAKETARGET='$(MAKETARGET)' ./dockerbuild.sh
|
||||
@exit `cat target/make.exit`
|
||||
47
README.md
47
README.md
@@ -1,21 +1,24 @@
|
||||
# go-xmlsec
|
||||
|
||||
[](http://godoc.org/github.com/crewjam/go-xmlsec) [](https://travis-ci.org/crewjam/go-xmlsec)
|
||||
[](http://godoc.org/git.deineagentur.com/DeineAgenturUG/go-xmlsec)
|
||||
[](https://travis-ci.org/tecnickcom/go-xmlsec?branch=master)
|
||||
[](https://coveralls.io/github/tecnickcom/go-xmlsec?branch=master)
|
||||
[](https://goreportcard.com/report/git.deineagentur.com/DeineAgenturUG/go-xmlsec)
|
||||
|
||||
A partial wrapper for [xmlsec](https://www.aleksey.com/xmlsec).
|
||||
A partial wrapper for [xmlsec](https://www.aleksey.com/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.
|
||||
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
|
||||
## Examples
|
||||
|
||||
## Signing
|
||||
### Signing
|
||||
|
||||
key, _ := ioutil.ReadFile("saml.key")
|
||||
doc, _ := ioutil.ReadAll(os.Stdin)
|
||||
signedDoc, err := Sign(key, doc, SignatureOptions{})
|
||||
os.Stdout.Write(signedDoc)
|
||||
|
||||
## Verifying
|
||||
### Verifying
|
||||
|
||||
key, _ := ioutil.ReadFile("saml.crt")
|
||||
doc, _ := ioutil.ReadAll(os.Stdin)
|
||||
@@ -24,59 +27,59 @@ As seems to be the case for many things in the XMLish world, the xmldsig and xml
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
## Decrypting
|
||||
### Decrypting
|
||||
|
||||
key, _ := ioutil.ReadFile("saml.key")
|
||||
doc, _ := ioutil.ReadAll(os.Stdin)
|
||||
plaintextDoc, err := Decrypt(key, doc)
|
||||
os.Stdout.Write(plaintextDoc)
|
||||
|
||||
## Encrypting
|
||||
### Encrypting
|
||||
|
||||
key, _ := ioutil.ReadFile("saml.crt")
|
||||
doc, _ := ioutil.ReadAll(os.Stdin)
|
||||
encryptedDoc, err := Encrypt(key, doc, EncryptOptions{})
|
||||
os.Stdout.Write(encryptedDoc)
|
||||
|
||||
# Install
|
||||
## 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
|
||||
$ go get git.deineagentur.com/DeineAgenturUG/go-xmlsec
|
||||
|
||||
On Mac with homebrew, this might look like:
|
||||
|
||||
$ brew install libxmlsec1 libxml2 pkg-config
|
||||
$ go get github.com/crewjam/go-xmlsec
|
||||
$ go get git.deineagentur.com/DeineAgenturUG/go-xmlsec
|
||||
|
||||
# Static Linking
|
||||
## 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
|
||||
### Compile libxml
|
||||
|
||||
```
|
||||
```shell
|
||||
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
|
||||
### Compile openssl
|
||||
|
||||
```
|
||||
```shell
|
||||
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
|
||||
### Compile libxmlsec
|
||||
|
||||
```
|
||||
```shell
|
||||
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
|
||||
@@ -84,12 +87,10 @@ make -C include install
|
||||
make install-pkgconfigDATA
|
||||
```
|
||||
|
||||
## Build with static tag
|
||||
### Build with static tag
|
||||
|
||||
```
|
||||
```shell
|
||||
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`.
|
||||
|
||||
|
||||
Running `ldd` on the output should produce `not a dynamic executable`.
|
||||
@@ -1,18 +1,13 @@
|
||||
// +build !static
|
||||
|
||||
package xmlsec
|
||||
|
||||
// #cgo pkg-config: xmlsec1 libxml-2.0
|
||||
// #cgo linux CFLAGS: -w
|
||||
// #cgo darwin CFLAGS: -Wno-invalid-pp-token -Wno-header-guard
|
||||
// #cgo pkg-config: xmlsec1
|
||||
// #cgo linux LDFLAGS: -lxml2 -lm
|
||||
// #include <xmlsec/xmlsec.h>
|
||||
// #include <xmlsec/xmltree.h>
|
||||
// #include <xmlsec/xmlenc.h>
|
||||
// #include <xmlsec/templates.h>
|
||||
// #include <xmlsec/crypto.h>
|
||||
import "C"
|
||||
|
||||
// #cgo pkg-config: libxml-2.0
|
||||
// #include <libxml/parser.h>
|
||||
// #include <libxml/parserInternals.h>
|
||||
// #include <libxml/xmlmemory.h>
|
||||
@@ -1,19 +0,0 @@
|
||||
// +build static
|
||||
|
||||
package xmlsec
|
||||
|
||||
// #cgo linux CFLAGS: -w
|
||||
// #cgo darwin CFLAGS: -Wno-invalid-pp-token -Wno-header-guard
|
||||
// #cgo pkg-config: --static xmlsec1
|
||||
// #include <xmlsec/xmlsec.h>
|
||||
// #include <xmlsec/xmltree.h>
|
||||
// #include <xmlsec/xmlenc.h>
|
||||
// #include <xmlsec/templates.h>
|
||||
// #include <xmlsec/crypto.h>
|
||||
import "C"
|
||||
|
||||
// #cgo pkg-config: --static libxml-2.0
|
||||
// #include <libxml/parser.h>
|
||||
// #include <libxml/parserInternals.h>
|
||||
// #include <libxml/xmlmemory.h>
|
||||
import "C"
|
||||
@@ -33,6 +33,7 @@ func Decrypt(privateKey []byte, doc []byte) ([]byte, error) {
|
||||
return nil, popError()
|
||||
}
|
||||
|
||||
// #nosec
|
||||
key := C.xmlSecCryptoAppKeyLoadMemory(
|
||||
(*C.xmlSecByte)(unsafe.Pointer(&privateKey[0])),
|
||||
C.xmlSecSize(len(privateKey)),
|
||||
@@ -59,6 +60,7 @@ func Decrypt(privateKey []byte, doc []byte) ([]byte, error) {
|
||||
}
|
||||
defer C.xmlSecEncCtxDestroy(encCtx)
|
||||
|
||||
// #nosec
|
||||
encDataNode := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeEncryptedData)),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecEncNs)))
|
||||
@@ -70,7 +72,6 @@ func Decrypt(privateKey []byte, doc []byte) ([]byte, error) {
|
||||
if rv := C.xmlSecEncCtxDecrypt(encCtx, encDataNode); rv < 0 {
|
||||
return nil, popError()
|
||||
}
|
||||
encDataNode = nil // the template is inserted in the doc, so we don't own it
|
||||
|
||||
return dumpDoc(parsedDoc), nil
|
||||
}
|
||||
|
||||
58
dockerbuild.sh
Executable file
58
dockerbuild.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# dockerbuild.sh
|
||||
#
|
||||
# Build the software inside a Docker container
|
||||
#
|
||||
# @author Nicola Asuni <info@tecnick.com>
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# NOTES:
|
||||
# This script requires Docker
|
||||
|
||||
# EXAMPLE USAGE:
|
||||
# VENDOR=vendorname PROJECT=projectname MAKETARGET=buildall ./dockerbuild.sh
|
||||
|
||||
# Get vendor and project name
|
||||
: ${CVSPATH:=project}
|
||||
: ${VENDOR:=vendor}
|
||||
: ${PROJECT:=project}
|
||||
|
||||
# make target to execute
|
||||
: ${MAKETARGET:=buildall}
|
||||
|
||||
# Name of the base development Docker image
|
||||
DOCKERDEV=${VENDOR}/dev_${PROJECT}
|
||||
|
||||
# Build the base environment and keep it cached locally
|
||||
docker build -t ${DOCKERDEV} ./resources/DockerDev/
|
||||
|
||||
# Define the project root path
|
||||
PRJPATH=/root/src/${CVSPATH}/${PROJECT}
|
||||
|
||||
# Generate a temporary Dockerfile to build and test the project
|
||||
# NOTE: The exit status of the RUN command is stored to be returned later,
|
||||
# so in case of error we can continue without interrupting this script.
|
||||
cat > Dockerfile <<- EOM
|
||||
FROM ${DOCKERDEV}
|
||||
RUN mkdir -p ${PRJPATH}
|
||||
ADD ./ ${PRJPATH}
|
||||
WORKDIR ${PRJPATH}
|
||||
RUN make ${MAKETARGET} || (echo \$? > target/make.exit)
|
||||
EOM
|
||||
|
||||
# Define the temporary Docker image name
|
||||
DOCKER_IMAGE_NAME=${VENDOR}/build_${PROJECT}
|
||||
|
||||
# Build the Docker image
|
||||
docker build --no-cache -t ${DOCKER_IMAGE_NAME} .
|
||||
|
||||
# Start a container using the newly created Docker image
|
||||
CONTAINER_ID=$(docker run -d ${DOCKER_IMAGE_NAME})
|
||||
|
||||
# Copy all build/test artifacts back to the host
|
||||
docker cp ${CONTAINER_ID}:"${PRJPATH}/target" ./
|
||||
|
||||
# Remove the temporary container and image
|
||||
docker rm -f ${CONTAINER_ID} || true
|
||||
docker rmi -f ${DOCKER_IMAGE_NAME} || true
|
||||
@@ -91,6 +91,7 @@ var errInvalidAlgorithm = errors.New("invalid algorithm")
|
||||
// Note: the invocations of C.CString() here return a pointer to a string
|
||||
// allocated from the C heap that would normally need to freed by calling
|
||||
// C.free, but because these are global, we can just leak them.
|
||||
// #nosec
|
||||
var (
|
||||
constDsigNamespace = (*C.xmlChar)(unsafe.Pointer(C.CString("http://www.w3.org/2000/09/xmldsig#")))
|
||||
constDigestMethod = (*C.xmlChar)(unsafe.Pointer(C.CString("DigestMethod")))
|
||||
@@ -117,6 +118,7 @@ func Encrypt(publicKey, doc []byte, opts EncryptOptions) ([]byte, error) {
|
||||
return nil, mustPopError()
|
||||
}
|
||||
|
||||
// #nosec
|
||||
key := C.xmlSecCryptoAppKeyLoadMemory(
|
||||
(*C.xmlSecByte)(unsafe.Pointer(&publicKey[0])),
|
||||
C.xmlSecSize(len(publicKey)),
|
||||
@@ -126,6 +128,7 @@ func Encrypt(publicKey, doc []byte, opts EncryptOptions) ([]byte, error) {
|
||||
return nil, mustPopError()
|
||||
}
|
||||
|
||||
// #nosec
|
||||
if rv := C.xmlSecCryptoAppKeyCertLoadMemory(key,
|
||||
(*C.xmlSecByte)(unsafe.Pointer(&publicKey[0])),
|
||||
C.xmlSecSize(len(publicKey)),
|
||||
@@ -162,6 +165,7 @@ func Encrypt(publicKey, doc []byte, opts EncryptOptions) ([]byte, error) {
|
||||
|
||||
// create encryption template to encrypt XML file and replace
|
||||
// its content with encryption result
|
||||
// #nosec
|
||||
encDataNode := C.xmlSecTmplEncDataCreate(parsedDoc, sessionCipherTransform,
|
||||
nil, (*C.xmlChar)(unsafe.Pointer(&C.xmlSecTypeEncElement)), nil, nil)
|
||||
if encDataNode == nil {
|
||||
@@ -279,5 +283,8 @@ func Encrypt(publicKey, doc []byte, opts EncryptOptions) ([]byte, error) {
|
||||
}
|
||||
encDataNode = nil // the template is inserted in the doc, so we don't own it
|
||||
|
||||
return dumpDoc(parsedDoc), nil
|
||||
rootNode := C.xmlDocGetRootElement(parsedDoc)
|
||||
buf := dumpNode(rootNode)
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
4
error.go
4
error.go
@@ -49,8 +49,8 @@ func onXmlsecError(file *C.char, line C.int, funcName *C.char, errorObject *C.ch
|
||||
globalErrors[threadID] = append(globalErrors[threadID], err)
|
||||
}
|
||||
|
||||
//export onXmlError
|
||||
func onXmlError(msg *C.char) {
|
||||
//export onXMLError
|
||||
func onXMLError(msg *C.char) {
|
||||
threadID := getThreadID()
|
||||
globalErrors[threadID] = append(globalErrors[threadID],
|
||||
fmt.Errorf("%s", strings.TrimSuffix(C.GoString(msg), "\n")))
|
||||
|
||||
@@ -8,7 +8,7 @@ package xmlsec
|
||||
// #include <xmlsec/xmlsec.h>
|
||||
// #include <xmlsec/errors.h>
|
||||
//
|
||||
// void onXmlError(const char *msg); // implemented in go
|
||||
// void onXMLError(const char *msg); // implemented in go
|
||||
// void onXmlsecError(const char *file, int line, const char *funcName, const char *errorObject, const char *errorSubject, int reason, const char *msg); // implemented in go
|
||||
//
|
||||
// static void onXmlGenericError_cgo(void *ctx, const char *format, ...) {
|
||||
@@ -17,7 +17,7 @@ package xmlsec
|
||||
// va_start(args, format);
|
||||
// vsnprintf(buffer, 256, format, args);
|
||||
// va_end (args);
|
||||
// onXmlError(buffer);
|
||||
// onXMLError(buffer);
|
||||
// }
|
||||
//
|
||||
// static void onXmlsecError_cgo(const char *file, int line, const char *funcName, const char *errorObject, const char *errorSubject, int reason, const char *msg) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/gofly/go-xmlsec"
|
||||
xmlsec "git.deineagentur.com/DeineAgenturUG/go-xmlsec"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -31,6 +31,10 @@ func main() {
|
||||
}
|
||||
|
||||
buf, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Printf("%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *doSign {
|
||||
signedBuf, err := xmlsec.Sign(key, buf, xmlsec.SignatureOptions{})
|
||||
@@ -38,7 +42,7 @@ func main() {
|
||||
fmt.Printf("%s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Stdout.Write(signedBuf)
|
||||
os.Stdout.Write(signedBuf) //#nosec
|
||||
}
|
||||
|
||||
if *doVerify {
|
||||
|
||||
10
resources/DockerDev/Dockerfile
Normal file
10
resources/DockerDev/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
# Dockerfile
|
||||
#
|
||||
# Linux development environment
|
||||
#
|
||||
# Extend the tecnickcom/alldev image defined in
|
||||
# https://github.com/tecnickcom/alldev
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
FROM tecnickcom/alldev
|
||||
MAINTAINER info@tecnick.com
|
||||
24
resources/certs/cert1
Normal file
24
resources/certs/cert1
Normal file
@@ -0,0 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDzzCCAzigAwIBAgIJAK+ii7kzrdqtMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEQMA4G
|
||||
A1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3
|
||||
DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMCAXDTE0MDUyMzE3NTIzOFoYDzIxMTQw
|
||||
NDI5MTc1MjM4WjCBnDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
|
||||
PTA7BgNVBAoTNFhNTCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtz
|
||||
ZXkuY29tL3htbHNlYykxFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAfBgkqhkiG
|
||||
9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgC
|
||||
QQCyuvKJ2CuUPD33ghPt4Q8MilesHxVbbpyKfmabrYVpDGVDmOKKp337qJUZZ95K
|
||||
fwlXbR2j0zyKWJmvRxUx+PsTAgMBAAGjggFFMIIBQTAMBgNVHRMEBTADAQH/MCwG
|
||||
CWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNV
|
||||
HQ4EFgQU/uTsUyTwlZXHELXhRLVdOWVa434wgeMGA1UdIwSB2zCB2IAUBrWkrKeq
|
||||
dUTqFZxP3wWDT2oe/guhgbSkgbEwga4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpD
|
||||
YWxpZm9ybmlhMT0wOwYDVQQKEzRYTUwgU2VjdXJpdHkgTGlicmFyeSAoaHR0cDov
|
||||
L3d3dy5hbGVrc2V5LmNvbS94bWxzZWMpMRAwDgYDVQQLEwdSb290IENBMRYwFAYD
|
||||
VQQDEw1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3Nl
|
||||
eS5jb22CCQCvoou5M63arDANBgkqhkiG9w0BAQUFAAOBgQBuTAW63AgWqqUDPGi8
|
||||
BiXbdKHhFP4J8qgkdv5WMa6SpSWVgNgOYXkK/BSg1aSmQtGv8/8UvBRPoJnO4y0N
|
||||
jWUFf1ubOgUNmedYNLq7YbTp8yTGWeogCyM2xdWELMP8BMgQL0sP+MDAFMKO3itY
|
||||
mEWnCEsP15HKSTms54RNj7oJ+A==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
25
resources/certs/cert2
Normal file
25
resources/certs/cert2
Normal file
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIID9zCCA2CgAwIBAgIJAK+ii7kzrdqsMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEQMA4G
|
||||
A1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3
|
||||
DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMCAXDTE0MDUyMzE3NTA1OVoYDzIxMTQw
|
||||
NDI5MTc1MDU5WjCBrjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWEx
|
||||
PTA7BgNVBAoTNFhNTCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtz
|
||||
ZXkuY29tL3htbHNlYykxEDAOBgNVBAsTB1Jvb3QgQ0ExFjAUBgNVBAMTDUFsZWtz
|
||||
ZXkgU2FuaW4xITAfBgkqhkiG9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbTCBnzAN
|
||||
BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtY4MCNj/qrOzVuex1BD/PuCYTDDOLLVj
|
||||
tpKXQteQPqy0kgMwuQgRwdNnICIHQbnFKL40XoyACJVWKM7b0LkvWJNeyVzXPqEE
|
||||
9ZPmNxWGUjVcr7powT7v8V7S2QflUnr8ZvR4XWwkZJ9EYKNhenijgJ5yYDrXCWdv
|
||||
C+fnjBjv2LcCAwEAAaOCARcwggETMB0GA1UdDgQWBBQGtaSsp6p1ROoVnE/fBYNP
|
||||
ah7+CzCB4wYDVR0jBIHbMIHYgBQGtaSsp6p1ROoVnE/fBYNPah7+C6GBtKSBsTCB
|
||||
rjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhN
|
||||
TCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNl
|
||||
YykxEDAOBgNVBAsTB1Jvb3QgQ0ExFjAUBgNVBAMTDUFsZWtzZXkgU2FuaW4xITAf
|
||||
BgkqhkiG9w0BCQEWEnhtbHNlY0BhbGVrc2V5LmNvbYIJAK+ii7kzrdqsMAwGA1Ud
|
||||
EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEARpb86RP/ck55X+NunXeIX81i763b
|
||||
j7Z1VJwFbA/QfupzxnqJ2IP/lxC8YxJ3Bp2IJMI7rC9r0poa41ZxI5rGHip97Dpg
|
||||
sxPF9lkRUmKBBQjkICOq1w/4d2DRInBoqXttD+0WsqDfNDVK+7kSE07ytn3RzHCj
|
||||
j0gv0PdxmuCsR/E=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
23
resources/certs/cert3
Normal file
23
resources/certs/cert3
Normal file
@@ -0,0 +1,23 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
29
signature.go
29
signature.go
@@ -11,6 +11,21 @@ type Method struct {
|
||||
Algorithm string `xml:",attr"`
|
||||
}
|
||||
|
||||
// Reference data struct
|
||||
type Reference struct {
|
||||
URI string `xml:"URI,attr"`
|
||||
ReferenceTransforms []Method `xml:"Transforms>Transform"`
|
||||
DigestMethod Method `xml:"DigestMethod"`
|
||||
DigestValue string `xml:"DigestValue"`
|
||||
}
|
||||
|
||||
// SignedInfo struct
|
||||
type SignedInfo struct {
|
||||
CanonicalizationMethod Method `xml:"CanonicalizationMethod"`
|
||||
SignatureMethod Method `xml:"SignatureMethod"`
|
||||
Reference Reference `xml:"Reference"`
|
||||
}
|
||||
|
||||
// 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:
|
||||
//
|
||||
@@ -24,17 +39,7 @@ type Method struct {
|
||||
// buf, _ := xml.Marshal(f)
|
||||
// buf, _ = Sign(key, buf)
|
||||
//
|
||||
type Reference struct {
|
||||
URI string `xml:",attr"`
|
||||
Transforms []Method `xml:"Transforms>Transform"`
|
||||
DigestMethod Method
|
||||
DigestValue string
|
||||
}
|
||||
type SignedInfo struct {
|
||||
CanonicalizationMethod Method `xml:"CanonicalizationMethod"`
|
||||
SignatureMethod Method `xml:"SignatureMethod"`
|
||||
Reference Reference
|
||||
}
|
||||
|
||||
type Signature struct {
|
||||
XMLName xml.Name `xml:"http://www.w3.org/2000/09/xmldsig# Signature"`
|
||||
SignedInfo SignedInfo
|
||||
@@ -65,7 +70,7 @@ func DefaultSignature(pemEncodedPublicKey []byte) Signature {
|
||||
},
|
||||
Reference: Reference{
|
||||
Transforms: []Method{
|
||||
Method{Algorithm: "http://www.w3.org/2000/09/xmldsig#enveloped-signature"},
|
||||
{Algorithm: "http://www.w3.org/2000/09/xmldsig#enveloped-signature"},
|
||||
},
|
||||
DigestMethod: Method{
|
||||
Algorithm: "http://www.w3.org/2000/09/xmldsig#sha1",
|
||||
|
||||
@@ -9,5 +9,6 @@ import "C"
|
||||
func getThreadID() uintptr {
|
||||
// Darwin lacks a meaningful version of gettid() so instead we use
|
||||
// ptread_self() as a proxy.
|
||||
// #nosec
|
||||
return uintptr(unsafe.Pointer(C.pthread_self()))
|
||||
}
|
||||
|
||||
141
xmldsig.go
141
xmldsig.go
@@ -5,12 +5,36 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #include <xmlsec/xmlsec.h>
|
||||
// #include <xmlsec/xmltree.h>
|
||||
// #include <xmlsec/xmlenc.h>
|
||||
// #include <xmlsec/xmldsig.h>
|
||||
// #include <xmlsec/errors.h>
|
||||
// #include <xmlsec/crypto.h>
|
||||
/*
|
||||
#include <xmlsec/xmlsec.h>
|
||||
#include <xmlsec/xmltree.h>
|
||||
#include <xmlsec/xmlenc.h>
|
||||
#include <xmlsec/xmldsig.h>
|
||||
#include <xmlsec/errors.h>
|
||||
#include <xmlsec/crypto.h>
|
||||
#include <xmlsec/nodeset.h>
|
||||
#include <libxml/list.h>
|
||||
|
||||
void
|
||||
xmlSecFindNodes(const xmlListPtr found, const xmlNodePtr parent, const xmlChar *name, const xmlChar *ns) {
|
||||
|
||||
xmlNodePtr cur;
|
||||
xmlNodePtr ret;
|
||||
|
||||
xmlSecAssert2(name != NULL, NULL);
|
||||
|
||||
cur = parent;
|
||||
while(cur != NULL) {
|
||||
if(cur->children != NULL) {
|
||||
xmlSecFindNodes(found, cur->children, name, ns);
|
||||
}
|
||||
if((cur->type == XML_ELEMENT_NODE) && xmlSecCheckNodeName(cur, name, ns)) {
|
||||
xmlListPushFront(found, cur);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// SignatureOptions represents additional, less commonly used, options for Sign and
|
||||
@@ -42,36 +66,58 @@ func Sign(key []byte, doc []byte, opts SignatureOptions) ([]byte, error) {
|
||||
startProcessingXML()
|
||||
defer stopProcessingXML()
|
||||
|
||||
ctx := C.xmlSecDSigCtxCreate(nil)
|
||||
if ctx == nil {
|
||||
return nil, errors.New("failed to create signature context")
|
||||
}
|
||||
defer C.xmlSecDSigCtxDestroy(ctx)
|
||||
|
||||
ctx.signKey = C.xmlSecCryptoAppKeyLoadMemory(
|
||||
(*C.xmlSecByte)(unsafe.Pointer(&key[0])),
|
||||
C.xmlSecSize(len(key)),
|
||||
C.xmlSecKeyDataFormatPem,
|
||||
nil, nil, nil)
|
||||
if ctx.signKey == nil {
|
||||
return nil, errors.New("failed to load pem key")
|
||||
}
|
||||
|
||||
parsedDoc, err := newDoc(doc, opts.XMLID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closeDoc(parsedDoc)
|
||||
|
||||
node := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||
// #nosec
|
||||
found := C.xmlListCreate(nil, nil)
|
||||
defer func() { C.xmlListDelete(found) }()
|
||||
|
||||
C.xmlSecFindNodes(
|
||||
found,
|
||||
C.xmlDocGetRootElement(parsedDoc),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
||||
if node == nil {
|
||||
|
||||
c := C.xmlListSize(found)
|
||||
if c == 0 {
|
||||
return nil, errors.New("cannot find start node")
|
||||
}
|
||||
|
||||
if rv := C.xmlSecDSigCtxSign(ctx, node); rv < 0 {
|
||||
return nil, errors.New("failed to sign")
|
||||
for C.xmlListEmpty(found) == 0 {
|
||||
link := C.xmlListFront(found)
|
||||
if link == nil {
|
||||
return nil, errors.New("Link is null")
|
||||
}
|
||||
|
||||
node := (C.xmlNodePtr)(C.xmlLinkGetData(link))
|
||||
if node != nil {
|
||||
|
||||
ctx := C.xmlSecDSigCtxCreate(nil)
|
||||
if ctx == nil {
|
||||
return nil, errors.New("failed to create signature context")
|
||||
}
|
||||
defer C.xmlSecDSigCtxDestroy(ctx)
|
||||
|
||||
// #nosec
|
||||
ctx.signKey = C.xmlSecCryptoAppKeyLoadMemory(
|
||||
(*C.xmlSecByte)(unsafe.Pointer(&key[0])),
|
||||
C.xmlSecSize(len(key)),
|
||||
C.xmlSecKeyDataFormatPem,
|
||||
nil, nil, nil)
|
||||
|
||||
if ctx.signKey == nil {
|
||||
return nil, errors.New("failed to load pem key")
|
||||
}
|
||||
|
||||
if rv := C.xmlSecDSigCtxSign(ctx, node); rv < 0 {
|
||||
return nil, errors.New("failed to sign")
|
||||
}
|
||||
}
|
||||
C.xmlListPopFront(found)
|
||||
}
|
||||
|
||||
return dumpDoc(parsedDoc), nil
|
||||
@@ -106,6 +152,7 @@ func Verify(publicKey []byte, doc []byte, opts SignatureOptions) error {
|
||||
return mustPopError()
|
||||
}
|
||||
|
||||
// #nosec
|
||||
key := C.xmlSecCryptoAppKeyLoadMemory(
|
||||
(*C.xmlSecByte)(unsafe.Pointer(&publicKey[0])),
|
||||
C.xmlSecSize(len(publicKey)),
|
||||
@@ -115,6 +162,7 @@ func Verify(publicKey []byte, doc []byte, opts SignatureOptions) error {
|
||||
return mustPopError()
|
||||
}
|
||||
|
||||
// #nosec
|
||||
if rv := C.xmlSecCryptoAppKeyCertLoadMemory(key,
|
||||
(*C.xmlSecByte)(unsafe.Pointer(&publicKey[0])),
|
||||
C.xmlSecSize(len(publicKey)),
|
||||
@@ -127,31 +175,48 @@ func Verify(publicKey []byte, doc []byte, opts SignatureOptions) error {
|
||||
return mustPopError()
|
||||
}
|
||||
|
||||
dsigCtx := C.xmlSecDSigCtxCreate(keysMngr)
|
||||
if dsigCtx == nil {
|
||||
return mustPopError()
|
||||
}
|
||||
defer C.xmlSecDSigCtxDestroy(dsigCtx)
|
||||
|
||||
parsedDoc, err := newDoc(doc, opts.XMLID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closeDoc(parsedDoc)
|
||||
|
||||
node := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||
// #nosec
|
||||
found := C.xmlListCreate(nil, nil)
|
||||
defer func() { C.xmlListDelete(found) }()
|
||||
|
||||
C.xmlSecFindNodes(
|
||||
found,
|
||||
C.xmlDocGetRootElement(parsedDoc),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
|
||||
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
|
||||
if node == nil {
|
||||
|
||||
c := C.xmlListSize(found)
|
||||
if c == 0 {
|
||||
return errors.New("cannot find start node")
|
||||
}
|
||||
|
||||
if rv := C.xmlSecDSigCtxVerify(dsigCtx, node); rv < 0 {
|
||||
return ErrVerificationFailed
|
||||
}
|
||||
for C.xmlListEmpty(found) == 0 {
|
||||
link := C.xmlListFront(found)
|
||||
if link == nil {
|
||||
break
|
||||
}
|
||||
node := (C.xmlNodePtr)(C.xmlLinkGetData(link))
|
||||
if node != nil {
|
||||
ctx := C.xmlSecDSigCtxCreate(keysMngr)
|
||||
if ctx == nil {
|
||||
return mustPopError()
|
||||
}
|
||||
defer C.xmlSecDSigCtxDestroy(ctx)
|
||||
|
||||
if dsigCtx.status != xmlSecDSigStatusSucceeded {
|
||||
return ErrVerificationFailed
|
||||
if rv := C.xmlSecDSigCtxVerify(ctx, node); rv < 0 {
|
||||
return ErrVerificationFailed
|
||||
}
|
||||
if ctx.status != xmlSecDSigStatusSucceeded {
|
||||
return ErrVerificationFailed
|
||||
}
|
||||
}
|
||||
C.xmlListPopFront(found)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
211
xmldsig_test.go
211
xmldsig_test.go
@@ -2,9 +2,8 @@ package xmlsec
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"strings"
|
||||
|
||||
. "gopkg.in/check.v1"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Envelope struct {
|
||||
@@ -163,6 +162,207 @@ fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
c.Assert(err, IsNil)
|
||||
}
|
||||
|
||||
func (testSuite *XMLDSigTest) TestSignAndVerifyMultiple(c *C) {
|
||||
expectedSignedString := `<?xml version="1.0"?>
|
||||
<Envelope xmlns="urn:envelope">
|
||||
<Data1 ID="id1">
|
||||
Hello, World!
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
||||
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
||||
<Reference URI="#id1">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<DigestValue>ixa7UpgiS2UJ37IG9HzhfK7z+Fo=</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>xaMgajZ9tBswZmIP5JoBwXMpD9W74fVbfWJ/HkfTHYkXNejOXT+UocvaGaVCqPNE
|
||||
+6rzavcVq18agibmYCkm6w==</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
<Data2 ID="id2">
|
||||
Hello, World!
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
||||
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
||||
<Reference URI="#id2">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<DigestValue>6hs7C+iZA45BBGAcaI0aNnMz+Ts=</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>F23IldNw0Gozri5ySU5Esopz7llkBrDJNHNgm+Ww93mrU5w1IrP0J7Cv0Xn19ro2
|
||||
QsO3oBVrpdMotMsFkbEVkA==</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
</Data2>
|
||||
</Data1>
|
||||
</Envelope>
|
||||
`
|
||||
actualUnsignedString := `
|
||||
<Envelope xmlns="urn:envelope">
|
||||
<Data1 ID="id1">
|
||||
Hello, World!
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
||||
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
||||
<Reference URI="#id1">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<DigestValue/>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue/>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
<Data2 ID="id2">
|
||||
Hello, World!
|
||||
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SignedInfo>
|
||||
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
||||
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
||||
<Reference URI="#id2">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||
<DigestValue/>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue/>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
|
||||
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
|
||||
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
|
||||
A1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtz
|
||||
ZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkG
|
||||
A1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1
|
||||
cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAn
|
||||
BgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQD
|
||||
Ew1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5j
|
||||
b20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7Ljqdn
|
||||
sYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQAB
|
||||
o4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
|
||||
ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTM
|
||||
QygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGu
|
||||
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1M
|
||||
IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
|
||||
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
|
||||
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
|
||||
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
|
||||
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
</X509Data>
|
||||
</KeyInfo>
|
||||
</Signature>
|
||||
</Data2>
|
||||
</Data1>
|
||||
</Envelope>
|
||||
`
|
||||
opts := SignatureOptions{XMLID: []XMLIDOption{
|
||||
{ElementName: "Data1", AttributeName: "ID"},
|
||||
{ElementName: "Data2", AttributeName: "ID"},
|
||||
}}
|
||||
|
||||
actualSignedString, err := Sign(testSuite.Key, []byte(actualUnsignedString), opts)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(string(actualSignedString), Equals, expectedSignedString)
|
||||
|
||||
err = Verify(testSuite.Cert, actualSignedString, opts)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
data1Sig := `<SignatureValue>xaMgajZ9tBswZmIP5JoBwXMpD9W74fVbfWJ/HkfTHYkXNejOXT+UocvaGaVCqPNE
|
||||
+6rzavcVq18agibmYCkm6w==</SignatureValue>`
|
||||
data2Sig := `<SignatureValue>F23IldNw0Gozri5ySU5Esopz7llkBrDJNHNgm+Ww93mrU5w1IrP0J7Cv0Xn19ro2
|
||||
QsO3oBVrpdMotMsFkbEVkA==</SignatureValue>`
|
||||
|
||||
breakData1 := strings.Replace(expectedSignedString, data1Sig, data2Sig, 1)
|
||||
err = Verify(testSuite.Cert, []byte(breakData1), opts)
|
||||
c.Assert(err, ErrorMatches, "signature verification failed")
|
||||
|
||||
breakData2 := strings.Replace(expectedSignedString, data2Sig, data1Sig, 1)
|
||||
err = Verify(testSuite.Cert, []byte(breakData2), opts)
|
||||
c.Assert(err, ErrorMatches, "signature verification failed")
|
||||
}
|
||||
|
||||
func (testSuite *XMLDSigTest) TestConstructFromSignature(c *C) {
|
||||
// Try again but this time construct the message from a struct having a Signature member
|
||||
doc := Envelope{Data: "Hello, World!"}
|
||||
@@ -179,7 +379,7 @@ func (testSuite *XMLDSigTest) TestConstructFromSignature(c *C) {
|
||||
<SignedInfo>
|
||||
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
|
||||
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
||||
<Reference>
|
||||
<Reference URI="">
|
||||
<Transforms>
|
||||
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
||||
</Transforms>
|
||||
@@ -187,8 +387,8 @@ func (testSuite *XMLDSigTest) TestConstructFromSignature(c *C) {
|
||||
<DigestValue>sEenIPkW9ssFSB9t4UU6VUrytqc=</DigestValue>
|
||||
</Reference>
|
||||
</SignedInfo>
|
||||
<SignatureValue>chSWfpQBIQraySsUHzs5N51+ruelu2HMHh5Mnd3EjcLqFBVD0f23kmXUp7zVhCVD
|
||||
vCfqu9yXDYKVOBI57F0Efg==</SignatureValue>
|
||||
<SignatureValue>xGbrj3FkyalDesH7R8xS41i5w69sM9WvuFmPeJ/LQ1zIjHoeHBq4SRzTOPg9xgjj
|
||||
YYGrWwpJY9khPQsfwjwWTQ==</SignatureValue>
|
||||
<KeyInfo>
|
||||
<X509Data>
|
||||
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tMCAXDTE0MDUyMzE3NTUzNFoYDzIxMTQwNDI5MTc1NTM0WjCBxzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExPTA7BgNVBAoTNFhNTCBTZWN1cml0eSBMaWJyYXJ5IChodHRwOi8vd3d3LmFsZWtzZXkuY29tL3htbHNlYykxKTAnBgNVBAsTIFRlc3QgVGhpcmQgTGV2ZWwgUlNBIENlcnRpZmljYXRlMRYwFAYDVQQDEw1BbGVrc2V5IFNhbmluMSEwHwYJKoZIhvcNAQkBFhJ4bWxzZWNAYWxla3NleS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEA09BtD3aeVt6DVDkk0dI7Vh7LjqdnsYmW0tbDVxxK+nume+Z9Sb4znbUKkWl+vgQATdRUEyhT2P+Gqrd0UBzYfQIDAQABo4IBRTCCAUEwDAYDVR0TBAUwAwEB/zAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFNf0xkZ3zjcEI60pVPuwDqTMQygZMIHjBgNVHSMEgdswgdiAFP7k7FMk8JWVxxC14US1XTllWuN+oYG0pIGxMIGuMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8GCSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZIhvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJfBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
|
||||
@@ -197,6 +397,7 @@ vCfqu9yXDYKVOBI57F0Efg==</SignatureValue>
|
||||
</Signature>
|
||||
</Envelope>
|
||||
`
|
||||
|
||||
c.Assert(string(actualSignedString), Equals, expectedSignedString)
|
||||
|
||||
err = Verify(testSuite.Cert, actualSignedString, SignatureOptions{})
|
||||
|
||||
16
xmlsec.go
16
xmlsec.go
@@ -42,6 +42,7 @@ func init() {
|
||||
}
|
||||
|
||||
func newDoc(buf []byte, idattrs []XMLIDOption) (*C.xmlDoc, error) {
|
||||
// #nosec
|
||||
ctx := C.xmlCreateMemoryParserCtxt((*C.char)(unsafe.Pointer(&buf[0])),
|
||||
C.int(len(buf)))
|
||||
if ctx == nil {
|
||||
@@ -78,15 +79,18 @@ func addIDAttr(node *C.xmlNode, attrName, nodeName, nsHref string) {
|
||||
cur = C.xmlSecGetNextElementNode(cur.next)
|
||||
}
|
||||
|
||||
// #nosec
|
||||
if C.GoString((*C.char)(unsafe.Pointer(node.name))) != nodeName {
|
||||
return
|
||||
}
|
||||
// #nosec
|
||||
if nsHref != "" && node.ns != nil && C.GoString((*C.char)(unsafe.Pointer(node.ns.href))) != nsHref {
|
||||
return
|
||||
}
|
||||
|
||||
// the attribute with name equal to attrName should exist
|
||||
for attr := node.properties; attr != nil; attr = attr.next {
|
||||
// #nosec
|
||||
if C.GoString((*C.char)(unsafe.Pointer(attr.name))) == attrName {
|
||||
id := C.xmlNodeListGetString(node.doc, attr.children, 1)
|
||||
if id == nil {
|
||||
@@ -106,7 +110,15 @@ func dumpDoc(doc *C.xmlDoc) []byte {
|
||||
var buffer *C.xmlChar
|
||||
var bufferSize C.int
|
||||
C.xmlDocDumpMemory(doc, &buffer, &bufferSize)
|
||||
defer C.MY_xmlFree(unsafe.Pointer(buffer))
|
||||
defer C.MY_xmlFree(unsafe.Pointer(buffer)) // #nosec
|
||||
|
||||
return C.GoBytes(unsafe.Pointer(buffer), bufferSize)
|
||||
return C.GoBytes(unsafe.Pointer(buffer), bufferSize) // #nosec
|
||||
}
|
||||
|
||||
func dumpNode(node *C.xmlNode) []byte {
|
||||
buffer := C.xmlBufferCreate()
|
||||
defer C.xmlBufferFree(buffer)
|
||||
bufferSize := C.xmlNodeDump(buffer, nil, node, 0, 0)
|
||||
|
||||
return C.GoBytes(unsafe.Pointer(buffer.content), bufferSize) // #nosec
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user