initial (broken) implementation of xmlenc
This commit is contained in:
45
README.md
45
README.md
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
A (partial) wrapper for [xmlsec](https://www.aleksey.com/xmlsec).
|
A (partial) wrapper for [xmlsec](https://www.aleksey.com/xmlsec).
|
||||||
|
|
||||||
|
# Signing (xmldsig)
|
||||||
|
|
||||||
## Signing Example
|
## Signing Example
|
||||||
|
|
||||||
key, _ := ioutil.ReadFile("saml.key")
|
key, _ := ioutil.ReadFile("saml.key")
|
||||||
@@ -21,3 +23,46 @@ A (partial) wrapper for [xmlsec](https://www.aleksey.com/xmlsec).
|
|||||||
if err == xmldsig.ErrVerificationFailed {
|
if err == xmldsig.ErrVerificationFailed {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Encryption (xmlenc)
|
||||||
|
|
||||||
|
## Encryption Example
|
||||||
|
|
||||||
|
ctx := xmlenc.Context{}
|
||||||
|
cert, _ := ioutil.ReadFile("saml.cert.pem")
|
||||||
|
err := ctx.AddCert(cert)
|
||||||
|
tmplDoc := []byte(``<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
XML Security Library example: Original XML doc file before encryption (encrypt3 example).
|
||||||
|
-->
|
||||||
|
<Envelope xmlns="urn:envelope">
|
||||||
|
<Data>
|
||||||
|
Hello, World!
|
||||||
|
</Data>
|
||||||
|
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element">
|
||||||
|
<xenc:EncryptionMethod xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
|
||||||
|
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||||
|
<!--<ds:KeyName>aes</ds:KeyName>-->
|
||||||
|
<xenc:EncryptedKey Id="aes" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
|
||||||
|
<xenc:EncryptionMethod xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
|
||||||
|
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
|
||||||
|
<ds:DigestMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||||
|
</xenc:EncryptionMethod>
|
||||||
|
<xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
|
||||||
|
<xenc:CipherValue></xenc:CipherValue>
|
||||||
|
</xenc:CipherData>
|
||||||
|
</xenc:EncryptedKey>
|
||||||
|
</ds:KeyInfo>
|
||||||
|
<xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
|
||||||
|
<xenc:CipherValue></xenc:CipherValue>
|
||||||
|
</xenc:CipherData>
|
||||||
|
</xenc:EncryptedData>
|
||||||
|
</Envelope>`)
|
||||||
|
ciphertext, err := ctx.Encrypt(docStr, []byte("Hello, World!"))
|
||||||
|
|
||||||
|
## Decryption Example
|
||||||
|
|
||||||
|
ctx := xmlenc.Context{}
|
||||||
|
key, _ := ioutil.ReadFile("saml.key.pem")
|
||||||
|
err := ctx.AddKey(key)
|
||||||
|
plaintext, err := ctx.Decrypt(ciphertext)
|
||||||
|
|||||||
@@ -23,13 +23,18 @@ type Method struct {
|
|||||||
type Signature struct {
|
type Signature struct {
|
||||||
XMLName xml.Name `xml:"http://www.w3.org/2000/09/xmldsig# Signature"`
|
XMLName xml.Name `xml:"http://www.w3.org/2000/09/xmldsig# Signature"`
|
||||||
|
|
||||||
CanonicalizationMethod Method `xml:"SignedInfo>CanonicalizationMethod"`
|
CanonicalizationMethod Method `xml:"SignedInfo>CanonicalizationMethod"`
|
||||||
SignatureMethod Method `xml:"SignedInfo>SignatureMethod"`
|
SignatureMethod Method `xml:"SignedInfo>SignatureMethod"`
|
||||||
ReferenceTransforms []Method `xml:"SignedInfo>Reference>Transforms>Transform"`
|
ReferenceTransforms []Method `xml:"SignedInfo>Reference>Transforms>Transform"`
|
||||||
DigestMethod Method `xml:"SignedInfo>Reference>DigestMethod"`
|
DigestMethod Method `xml:"SignedInfo>Reference>DigestMethod"`
|
||||||
DigestValue string `xml:"SignedInfo>Reference>DigestValue"`
|
DigestValue string `xml:"SignedInfo>Reference>DigestValue"`
|
||||||
SignatureValue string `xml:"SignatureValue"`
|
SignatureValue string `xml:"SignatureValue"`
|
||||||
KeyName string `xml:"KeyInfo>KeyName"`
|
KeyName string `xml:"KeyInfo>KeyName"`
|
||||||
|
X509Certificate *SignatureX509Data `xml:"KeyInfo>X509Data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SignatureX509Data struct {
|
||||||
|
X509Certificate string `xml:"X509Certificate,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultSignature populates a default Signature that uses c14n and SHA1.
|
// DefaultSignature populates a default Signature that uses c14n and SHA1.
|
||||||
|
|||||||
26
xmlenc/model.go
Normal file
26
xmlenc/model.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package xmlenc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EncryptedData struct {
|
||||||
|
XMLName xml.Name `xml:"http://www.w3.org/2001/04/xmlenc#"`
|
||||||
|
EncryptionMethod EncryptionMethod
|
||||||
|
KeyInfo KeyInfo
|
||||||
|
CipherDataValue string `xml:"CipherData>CipherValue"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EncryptionMethod struct {
|
||||||
|
Algorithm string `xml:",attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type KeyInfo struct {
|
||||||
|
XMLName xml.Name `xml:"http://www.w3.org/2000/09/xmldsig# KeyInfo"`
|
||||||
|
KeyName string `xml:"KeyName"`
|
||||||
|
X509Data *X509Data `xml:"X509Data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type X509Data struct {
|
||||||
|
X509Certificate string `xml:"X509Certificate,omitempty"`
|
||||||
|
}
|
||||||
351
xmlenc/xmlenc.go
Normal file
351
xmlenc/xmlenc.go
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
package xmlenc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Note: on mac you need: brew install libxmlsec1 libxml2
|
||||||
|
|
||||||
|
// #cgo pkg-config: xmlsec1
|
||||||
|
// #include <xmlsec/xmlsec.h>
|
||||||
|
// #include <xmlsec/xmltree.h>
|
||||||
|
// #include <xmlsec/xmlenc.h>
|
||||||
|
// #include <xmlsec/crypto.h>
|
||||||
|
// #include <xmlsec/app.h>
|
||||||
|
//
|
||||||
|
// static inline xmlSecKeyDataId MY_xmlSecKeyDataDesId() {
|
||||||
|
// return xmlSecOpenSSLKeyDataDesGetKlass();
|
||||||
|
// }
|
||||||
|
// static inline xmlSecKeyDataId MY_xmlSecKeyDataDsaId() {
|
||||||
|
// return xmlSecOpenSSLKeyDataDsaGetKlass();
|
||||||
|
// }
|
||||||
|
// static inline xmlSecKeyDataId MY_xmlSecKeyDataEcdsaId() {
|
||||||
|
// return xmlSecOpenSSLKeyDataEcdsaGetKlass();
|
||||||
|
// }
|
||||||
|
// static inline xmlSecKeyDataId MY_xmlSecKeyDataRsaId() {
|
||||||
|
// return xmlSecOpenSSLKeyDataRsaGetKlass();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// #cgo pkg-config: libxml-2.0
|
||||||
|
// #include <libxml/parser.h>
|
||||||
|
// #include <libxml/parserInternals.h>
|
||||||
|
// #include <libxml/xmlmemory.h>
|
||||||
|
// // Macro wrapper function
|
||||||
|
// static inline void MY_xmlFree(void *p) {
|
||||||
|
// xmlFree(p);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
C.xmlInitParser()
|
||||||
|
|
||||||
|
if rv := C.xmlSecInit(); rv < 0 {
|
||||||
|
panic("xmlsec failed to initialize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if rv := C.xmlSecCryptoAppInit(nil); rv < 0 {
|
||||||
|
panic("xmlsec crypto initialization failed.")
|
||||||
|
}
|
||||||
|
if rv := C.xmlSecCryptoInit(); rv < 0 {
|
||||||
|
panic("xmlsec crypto initialization failed.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDoc(buf []byte) (*C.xmlDoc, error) {
|
||||||
|
ctx := C.xmlCreateMemoryParserCtxt((*C.char)(unsafe.Pointer(&buf[0])),
|
||||||
|
C.int(len(buf)))
|
||||||
|
if ctx == nil {
|
||||||
|
return nil, errors.New("error creating parser")
|
||||||
|
}
|
||||||
|
defer C.xmlFreeParserCtxt(ctx)
|
||||||
|
|
||||||
|
//C.xmlCtxtUseOptions(ctx, C.int(p.Options))
|
||||||
|
C.xmlParseDocument(ctx)
|
||||||
|
|
||||||
|
if ctx.wellFormed == C.int(0) {
|
||||||
|
return nil, errors.New("malformed XML")
|
||||||
|
}
|
||||||
|
|
||||||
|
doc := ctx.myDoc
|
||||||
|
if doc == nil {
|
||||||
|
return nil, errors.New("parse failed")
|
||||||
|
}
|
||||||
|
return doc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dumpDoc(doc *C.xmlDoc) []byte {
|
||||||
|
var buffer *C.xmlChar
|
||||||
|
var bufferSize C.int
|
||||||
|
C.xmlDocDumpMemory(doc, &buffer, &bufferSize)
|
||||||
|
rv := C.GoStringN((*C.char)(unsafe.Pointer(buffer)), bufferSize)
|
||||||
|
C.MY_xmlFree(unsafe.Pointer(buffer))
|
||||||
|
|
||||||
|
// TODO(ross): this is totally nasty un-idiomatic, but I'm
|
||||||
|
// tired of googling how to copy a []byte from a char*
|
||||||
|
return []byte(rv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func closeDoc(doc *C.xmlDoc) {
|
||||||
|
C.xmlFreeDoc(doc)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
ctx *C.xmlSecEncCtx
|
||||||
|
keysMngr *C.xmlSecKeysMngr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Close() {
|
||||||
|
if c.ctx != nil {
|
||||||
|
C.xmlSecEncCtxDestroy(c.ctx)
|
||||||
|
c.ctx = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.keysMngr != nil {
|
||||||
|
C.xmlSecKeysMngrDestroy(c.keysMngr)
|
||||||
|
c.keysMngr = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) init() error {
|
||||||
|
if c.ctx != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c.keysMngr = C.xmlSecKeysMngrCreate()
|
||||||
|
if c.keysMngr == nil {
|
||||||
|
return errors.New("xmlSecKeysMngrCreate failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
if rv := C.xmlSecCryptoAppDefaultKeysMngrInit(c.keysMngr); rv < 0 {
|
||||||
|
return fmt.Errorf("xmlSecCryptoAppDefaultKeysMngrInit failed: %d", rv)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ctx = C.xmlSecEncCtxCreate(c.keysMngr)
|
||||||
|
if c.ctx == nil {
|
||||||
|
return errors.New("xmlSecEncCtxCreate failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
DES = iota
|
||||||
|
DSA
|
||||||
|
ECDSA
|
||||||
|
RSA
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Context) AddKey(data []byte) error {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
key := C.xmlSecCryptoAppKeyLoadMemory(
|
||||||
|
(*C.xmlSecByte)(unsafe.Pointer(&data[0])),
|
||||||
|
C.uint(len(data)),
|
||||||
|
C.xmlSecKeyDataFormatPem,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil)
|
||||||
|
if key == nil {
|
||||||
|
return errors.New("xmlSecCryptoAppKeyLoadMemory failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "k"
|
||||||
|
C.xmlSecKeySetName(key, (*C.xmlChar)(unsafe.Pointer(C.CString(name))))
|
||||||
|
|
||||||
|
if rv := C.xmlSecCryptoAppDefaultKeysMngrAdoptKey(c.keysMngr, key); rv < 0 {
|
||||||
|
return errors.New("xmlSecCryptoAppDefaultKeysMngrAdoptKey failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) AddCert(data []byte) error {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
var xmlSecKeyType C.xmlSecKeyDataId
|
||||||
|
switch keyType {
|
||||||
|
case DES:
|
||||||
|
xmlSecKeyType = C.MY_xmlSecKeyDataDesId()
|
||||||
|
case DSA:
|
||||||
|
xmlSecKeyType = C.MY_xmlSecKeyDataDsaId()
|
||||||
|
case ECDSA:
|
||||||
|
xmlSecKeyType = C.MY_xmlSecKeyDataEcdsaId()
|
||||||
|
case RSA:
|
||||||
|
xmlSecKeyType = C.MY_xmlSecKeyDataRsaId()
|
||||||
|
default:
|
||||||
|
return errors.New("unknown key type")
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if rv := C.xmlSecCryptoAppKeysMngrCertLoadMemory(c.keysMngr,
|
||||||
|
(*C.xmlSecByte)(unsafe.Pointer(&data[0])),
|
||||||
|
C.uint(len(data)),
|
||||||
|
C.xmlSecKeyDataFormatCertPem, // https://www.aleksey.com/xmlsec/api/xmlsec-keysdata.html#XMLSECKEYDATAFORMAT
|
||||||
|
C.xmlSecKeyDataTypePublic); rv < 0 {
|
||||||
|
return errors.New("xmlSecCryptoAppKeysMngrCertLoadMemory failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypt encrypts `plaintext` according to the template `tmplDoc`.
|
||||||
|
func (c *Context) Encrypt(tmplDoc []byte, plaintext []byte) ([]byte, error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedDoc, err := newDoc(tmplDoc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer closeDoc(parsedDoc)
|
||||||
|
|
||||||
|
tmplNode := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||||
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeEncryptedData)),
|
||||||
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecEncNs)))
|
||||||
|
if tmplNode == nil {
|
||||||
|
return nil, errors.New("cannot find start node")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(ross): actually use the requested cipher
|
||||||
|
c.ctx.encKey = C.xmlSecKeyGenerateByName(
|
||||||
|
(*C.xmlChar)(unsafe.Pointer(C.CString("aes"))),
|
||||||
|
128, C.xmlSecKeyDataTypeSession)
|
||||||
|
if c.ctx.encKey == nil {
|
||||||
|
return nil, errors.New("failed to generate session key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if rv := C.xmlSecEncCtxXmlEncrypt(c.ctx, tmplNode,
|
||||||
|
C.xmlDocGetRootElement(parsedDoc)); rv < 0 {
|
||||||
|
return nil, errors.New("cannot encrypt")
|
||||||
|
}
|
||||||
|
|
||||||
|
return dumpDoc(parsedDoc), nil
|
||||||
|
}
|
||||||
|
func (c *Context) Decrypt(doc []byte) ([]byte, error) {
|
||||||
|
if err := c.init(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func Decrypt(key []byte, doc []byte) ([]byte, error) {
|
||||||
|
|
||||||
|
parsedDoc, err := newDoc(doc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer closeDoc(parsedDoc)
|
||||||
|
|
||||||
|
node := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||||
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeEncryptedKey)),
|
||||||
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecEncNs)))
|
||||||
|
if node == nil {
|
||||||
|
return nil, errors.New("cannot find start node")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, err := newContext(key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer closeContext(ctx)
|
||||||
|
|
||||||
|
ctx.mode = C.xmlEncCtxModeEncryptedKey
|
||||||
|
|
||||||
|
if rv := C.xmlSecEncCtxDecrypt(ctx, node); rv < 0 {
|
||||||
|
return nil, errors.New("cannot decrypt")
|
||||||
|
}
|
||||||
|
if ctx.result == nil {
|
||||||
|
return nil, errors.New("cannot decrypt")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx2 := C.xmlSecEncCtxCreate(nil)
|
||||||
|
if ctx2 == nil {
|
||||||
|
return nil, errors.New("failed to create signature context")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx2.encKey = C.xmlSecKeyReadMemory(C.MY_xmlSecKeyDataDesId(),
|
||||||
|
C.xmlSecBufferGetData(ctx.result),
|
||||||
|
C.xmlSecBufferGetSize(ctx.result))
|
||||||
|
if ctx2.encKey == nil {
|
||||||
|
return nil, errors.New("cannot load session key")
|
||||||
|
}
|
||||||
|
ctx2.mode = C.xmlEncCtxModeEncryptedData
|
||||||
|
|
||||||
|
node2 := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
|
||||||
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeEncryptedData)),
|
||||||
|
(*C.xmlChar)(unsafe.Pointer(&C.xmlSecEncNs)))
|
||||||
|
if node2 == nil {
|
||||||
|
return nil, errors.New("cannot find start node")
|
||||||
|
}
|
||||||
|
|
||||||
|
if rv := C.xmlSecEncCtxDecrypt(ctx2, node2); rv < 0 {
|
||||||
|
return nil, errors.New("cannot decrypt")
|
||||||
|
}
|
||||||
|
if ctx2.result == nil {
|
||||||
|
return nil, errors.New("cannot decrypt")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Panic("%s", string(dumpDoc(parsedDoc)))
|
||||||
|
|
||||||
|
// Apparently we can either have replaced the document or not, so if we
|
||||||
|
// have return it with dump.
|
||||||
|
if ctx2.resultReplaced != 0 {
|
||||||
|
return dumpDoc(parsedDoc), nil
|
||||||
|
} else {
|
||||||
|
sz := C.xmlSecBufferGetSize(ctx2.result)
|
||||||
|
buf := C.xmlSecBufferGetData(ctx2.result)
|
||||||
|
rv := C.GoStringN((*C.char)(unsafe.Pointer(buf)), C.int(sz)) // TODO(ross): eliminate double copy
|
||||||
|
return []byte(rv), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
// x
|
||||||
|
*/
|
||||||
98
xmlenc/xmlenc_test.go
Normal file
98
xmlenc/xmlenc_test.go
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package xmlenc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "gopkg.in/check.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hook up gocheck into the "go test" runner.
|
||||||
|
func Test(t *testing.T) { TestingT(t) }
|
||||||
|
|
||||||
|
type EncryptTest struct{}
|
||||||
|
|
||||||
|
var _ = Suite(&EncryptTest{})
|
||||||
|
|
||||||
|
func (s *EncryptTest) TestEncrypt(c *C) {
|
||||||
|
key := []byte(`-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICXgIBAAKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9
|
||||||
|
IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+
|
||||||
|
PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQAB
|
||||||
|
AoGAD4/Z4LWVWV6D1qMIp1Gzr0ZmdWTE1SPdZ7Ej8glGnCzPdguCPuzbhGXmIg0V
|
||||||
|
J5D+02wsqws1zd48JSMXXM8zkYZVwQYIPUsNn5FetQpwxDIMPmhHg+QNBgwOnk8J
|
||||||
|
K2sIjjLPL7qY7Itv7LT7Gvm5qSOkZ33RCgXcgz+okEIQMYkCQQDzbTOyDL0c5WQV
|
||||||
|
6A2k06T/azdhUdGXF9C0+WkWSfNaovmTgRXh1G+jMlr82Snz4p4/STt7P/XtyWzF
|
||||||
|
3pkVgZr3AkEA7nPjXwHlttNEMo6AtxHd47nizK2NUN803ElIUT8P9KSCoERmSXq6
|
||||||
|
6PDekGNic4ldpsSvOeYCk8MAYoDBy9kvVwJBAMLgX4xg6lzhv7hR5+pWjTb1rIY6
|
||||||
|
rCHbrPfU264+UZXz9v2BT/VUznLF81WMvStD9xAPHpFS6R0OLghSZhdzhI0CQQDL
|
||||||
|
8Duvfxzrn4b9QlmduV8wLERoT6rEVxKLsPVz316TGrxJvBZLk/cV0SRZE1cZf4uk
|
||||||
|
XSWMfEcJ/0Zt+LdG1CqjAkEAqwLSglJ9Dy3HpgMz4vAAyZWzAxvyA1zW0no9GOLc
|
||||||
|
PQnYaNUN/Fy2SYtETXTb0CQ9X1rt8ffkFP7ya+5TC83aMg==
|
||||||
|
-----END RSA PRIVATE KEY-----`)
|
||||||
|
log.Printf("%s", string(key))
|
||||||
|
cert := []byte(`-----BEGIN CERTIFICATE-----
|
||||||
|
MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMC
|
||||||
|
Tk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYD
|
||||||
|
VQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG
|
||||||
|
9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4
|
||||||
|
MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xi
|
||||||
|
ZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2Zl
|
||||||
|
aWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5v
|
||||||
|
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LO
|
||||||
|
NoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHIS
|
||||||
|
KOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d
|
||||||
|
1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8
|
||||||
|
BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7n
|
||||||
|
bK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2Qar
|
||||||
|
Q4/67OZfHd7R+POBXhophSMv1ZOo
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
log.Printf("%s", string(cert))
|
||||||
|
|
||||||
|
docStr := []byte(`<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
XML Security Library example: Original XML doc file before encryption (encrypt3 example).
|
||||||
|
-->
|
||||||
|
<Envelope xmlns="urn:envelope">
|
||||||
|
<Data>
|
||||||
|
Hello, World!
|
||||||
|
</Data>
|
||||||
|
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element">
|
||||||
|
<xenc:EncryptionMethod xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
|
||||||
|
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||||
|
<!--<ds:KeyName>aes</ds:KeyName>-->
|
||||||
|
<xenc:EncryptedKey Id="aes" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
|
||||||
|
<xenc:EncryptionMethod xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
|
||||||
|
Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
|
||||||
|
<ds:DigestMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
||||||
|
</xenc:EncryptionMethod>
|
||||||
|
<xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
|
||||||
|
<xenc:CipherValue></xenc:CipherValue>
|
||||||
|
</xenc:CipherData>
|
||||||
|
</xenc:EncryptedKey>
|
||||||
|
</ds:KeyInfo>
|
||||||
|
<xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
|
||||||
|
<xenc:CipherValue></xenc:CipherValue>
|
||||||
|
</xenc:CipherData>
|
||||||
|
</xenc:EncryptedData>
|
||||||
|
</Envelope>`)
|
||||||
|
|
||||||
|
ctx := Context{}
|
||||||
|
err := ctx.AddCert(cert)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
err = ctx.AddKey(key)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
actualEncryptedString, err := ctx.Encrypt(docStr, []byte("Hello, World!"))
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
log.Printf("%s", actualEncryptedString)
|
||||||
|
|
||||||
|
// expectedEncryptedString := "XXX"
|
||||||
|
//c.Assert(string(actualEncryptedString), Equals, expectedEncryptedString)
|
||||||
|
|
||||||
|
plaintext, err := ctx.Decrypt(actualEncryptedString)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
log.Printf("plaintext=%s", plaintext)
|
||||||
|
//c.Assert(string(plaintext), Equals, "Hello, World!")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user