diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b72022 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +coverage.html +coverage.out \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 4da225f..b82f168 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,3 +8,8 @@ addons: go: - 1.5 + +script: + - golint *.go + - go vet ./... + - go test -v ./... diff --git a/decrypt.go b/decrypt.go index 2a3d8c3..ac1ebf0 100644 --- a/decrypt.go +++ b/decrypt.go @@ -19,7 +19,9 @@ import "C" // #include import "C" -func DecryptXML(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 Decrypt(privateKey []byte, doc []byte) ([]byte, error) { startProcessingXML() defer stopProcessingXML() diff --git a/decrypt_test.go b/decrypt_test.go index 6de5535..d71a0d3 100644 --- a/decrypt_test.go +++ b/decrypt_test.go @@ -69,7 +69,7 @@ j8Bbnl+ev0peYzxFyF5sQA==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`) - actualPlaintextString, err := DecryptXML(testSuite.Key, docStr) + actualPlaintextString, err := Decrypt(testSuite.Key, docStr) c.Assert(err, IsNil) c.Assert(strings.Contains(string(actualPlaintextString), ""), Equals, true) } @@ -135,20 +135,20 @@ func (testSuite *DecryptTest) TestInvalid(c *C) { var docStr []byte var err error - _, err = DecryptXML(testSuite.Key, testSuite.DocStr) + _, err = Decrypt(testSuite.Key, testSuite.DocStr) c.Assert(err, IsNil) - _, err = DecryptXML(testSuite.Key, []byte("")) + _, err = Decrypt(testSuite.Key, []byte("")) c.Assert(err, ErrorMatches, "xmlSecFindNode cannot find EncryptedData node") - _, err = DecryptXML([]byte("XXX"), testSuite.DocStr) + _, err = Decrypt([]byte("XXX"), testSuite.DocStr) c.Assert(err, ErrorMatches, "func=xmlSecOpenSSLAppKeyLoadBIO.*") docStr = []byte(`https://idp.testshib.org/idp/shibbolethinvalid<`) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, ErrorMatches, "malformed XML") docStr = []byte(` @@ -176,7 +176,7 @@ func (testSuite *DecryptTest) TestInvalid(c *C) { `) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, ErrorMatches, "func=xmlSecBase64CtxDecodeByte:file=base64.c:line=441:obj=:subj=:error=12:inByte=0x3f; func=xmlSecBase64CtxDecode:file=base64.c:line=612:obj=:subj=xmlSecBase64CtxDecodeByte:error=1:status=4; func=xmlSecBase64CtxUpdate:file=base64.c:line=268:obj=:subj=xmlSecBase64CtxDecode:error=1: ; func=xmlSecBase64Decode:file=base64.c:line=754:obj=:subj=xmlSecBase64CtxUpdate:error=1: ; func=xmlSecOpenSSLX509CertBase64DerRead:file=x509.c:line=1867:obj=:subj=xmlSecBase64Decode:error=1: ; func=xmlSecOpenSSLX509CertificateNodeRead:file=x509.c:line=981:obj=x509:subj=xmlSecOpenSSLX509CertBase64DerRead:error=1: ; func=xmlSecOpenSSLX509DataNodeRead:file=x509.c:line=942:obj=x509:subj=X509Certificate:error=1:read node failed; func=xmlSecOpenSSLKeyDataX509XmlRead:file=x509.c:line=674:obj=x509:subj=xmlSecOpenSSLX509DataNodeRead:error=1: ; func=xmlSecKeyInfoNodeRead:file=keyinfo.c:line=114:obj=x509:subj=xmlSecKeyDataXmlRead:error=1:node=X509Data; func=xmlSecKeysMngrGetKey:file=keys.c:line=1349:obj=:subj=xmlSecKeyInfoNodeRead:error=1:node=KeyInfo; func=xmlSecEncCtxEncDataNodeRead:file=xmlenc.c:line=957:obj=:subj=:error=45: ; func=xmlSecEncCtxDecryptToBuffer:file=xmlenc.c:line=715:obj=:subj=xmlSecEncCtxEncDataNodeRead:error=1: ; func=xmlSecKeysMngrGetKey:file=keys.c:line=1370:obj=:subj=xmlSecKeysMngrFindKey:error=1: ; func=xmlSecEncCtxEncDataNodeRead:file=xmlenc.c:line=957:obj=:subj=:error=45: ; func=xmlSecEncCtxDecryptToBuffer:file=xmlenc.c:line=715:obj=:subj=xmlSecEncCtxEncDataNodeRead:error=1: ; func=xmlSecEncCtxDecrypt:file=xmlenc.c:line=623:obj=:subj=xmlSecEncCtxDecryptToBuffer:error=1: ") docStr = []byte(` @@ -204,7 +204,7 @@ func (testSuite *DecryptTest) TestInvalid(c *C) { `) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, ErrorMatches, "func=xmlSecOpenSSLX509StoreVerify.*") docStr = []byte(` @@ -232,7 +232,7 @@ func (testSuite *DecryptTest) TestInvalid(c *C) { `) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, ErrorMatches, "func=xmlSecOpenSSLX509StoreVerify.*") docStr = []byte(` @@ -260,6 +260,6 @@ func (testSuite *DecryptTest) TestInvalid(c *C) { `) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, ErrorMatches, "func=xmlSecTransformNodeRead.*") } diff --git a/encrypt.go b/encrypt.go index 97c5962..9e5cfd6 100644 --- a/encrypt.go +++ b/encrypt.go @@ -21,44 +21,87 @@ package xmlsec import "C" import ( - "fmt" + "errors" "unsafe" ) +// SessionCipherType represents which session cipher to use to encrypt the document. +type SessionCipherType int + const ( - DefaultAlgorithm = iota + // 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 - DsaSha1 - Sha1 - Sha256 - Sha384 - Sha512 +) + +// CipherType represent which cipher to use to encrypt the document +type CipherType int + +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 Options struct { - SessionCipher int - Cipher int - DigestAlgorithm int +// DigestAlgorithmType represent which digest algorithm to use when encrypting the document. +type DigestAlgorithmType int + +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 +) + +// EncryptOptions specifies the ciphers to use to encrypt the document. +type EncryptOptions struct { + SessionCipher SessionCipherType + Cipher CipherType + DigestAlgorithm DigestAlgorithmType } -// XmlEncrypt encrypts the XML document to publicKey. -func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { +var errInvalidAlgorithm = errors.New("invalid algorithm") + +// Encrypt encrypts the XML document to publicKey and returns the encrypted +// document. +func Encrypt(publicKey, doc []byte, opts EncryptOptions) ([]byte, error) { startProcessingXML() defer stopProcessingXML() keysMngr := C.xmlSecKeysMngrCreate() if keysMngr == nil { - return nil, fmt.Errorf("xmlSecKeysMngrCreate failed") + return nil, mustPopError() } defer C.xmlSecKeysMngrDestroy(keysMngr) if rv := C.xmlSecCryptoAppDefaultKeysMngrInit(keysMngr); rv < 0 { - return nil, fmt.Errorf("xmlSecCryptoAppDefaultKeysMngrInit failed") + return nil, mustPopError() } key := C.xmlSecCryptoAppKeyLoadMemory( @@ -67,7 +110,7 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { C.xmlSecKeyDataFormatCertPem, nil, nil, nil) if key == nil { - return nil, fmt.Errorf("xmlSecCryptoAppKeyLoadMemory failed") + return nil, mustPopError() } if rv := C.xmlSecCryptoAppKeyCertLoadMemory(key, @@ -75,11 +118,11 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { C.xmlSecSize(len(publicKey)), C.xmlSecKeyDataFormatCertPem); rv < 0 { C.xmlSecKeyDestroy(key) - return nil, fmt.Errorf("xmlSecCryptoAppKeyCertLoad failed") + return nil, mustPopError() } if rv := C.xmlSecCryptoAppDefaultKeysMngrAdoptKey(keysMngr, key); rv < 0 { - return nil, fmt.Errorf("xmlSecCryptoAppDefaultKeysMngrAdoptKey failed") + return nil, mustPopError() } parsedDoc, err := newDoc(doc) @@ -90,7 +133,7 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { var sessionCipherTransform C.xmlSecTransformId switch opts.SessionCipher { - case DefaultAlgorithm: + case DefaultSessionCipher: sessionCipherTransform = C.MY_xmlSecTransformAes256CbcId() case Aes256Cbc: sessionCipherTransform = C.MY_xmlSecTransformAes256CbcId() @@ -101,7 +144,7 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { case Des3Cbc: sessionCipherTransform = C.MY_xmlSecTransformDes3CbcId() default: - return nil, fmt.Errorf("XXX") + return nil, errInvalidAlgorithm } // create encryption template to encrypt XML file and replace @@ -109,7 +152,7 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { encDataNode := C.xmlSecTmplEncDataCreate(parsedDoc, sessionCipherTransform, nil, (*C.xmlChar)(unsafe.Pointer(&C.xmlSecTypeEncElement)), nil, nil) if encDataNode == nil { - return nil, fmt.Errorf("xmlSecTmplEncDataCreate failed") + return nil, mustPopError() } defer func() { if encDataNode != nil { @@ -120,19 +163,19 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { // we want to put encrypted data in the node if C.xmlSecTmplEncDataEnsureCipherValue(encDataNode) == nil { - return nil, fmt.Errorf("xmlSecTmplEncDataEnsureCipherValue failed") + return nil, mustPopError() } // add keyInfoNode := C.xmlSecTmplEncDataEnsureKeyInfo(encDataNode, nil) if keyInfoNode == nil { - return nil, fmt.Errorf("xmlSecTmplEncDataEnsureKeyInfo failed") + return nil, mustPopError() } // add to store the encrypted session key var cipherTransform C.xmlSecTransformId switch opts.Cipher { - case DefaultAlgorithm: + case DefaultCipher: cipherTransform = C.MY_xmlSecTransformRsaOaepId() case RsaOaep: cipherTransform = C.MY_xmlSecTransformRsaOaepId() @@ -141,39 +184,39 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { } encKeyNode := C.xmlSecTmplKeyInfoAddEncryptedKey(keyInfoNode, cipherTransform, nil, nil, nil) if encKeyNode == nil { - return nil, fmt.Errorf("xmlSecTmplKeyInfoAddEncryptedKey failed") + return nil, mustPopError() } // we want to put encrypted key in the node if C.xmlSecTmplEncDataEnsureCipherValue(encKeyNode) == nil { - return nil, fmt.Errorf("xmlSecTmplEncDataEnsureCipherValue failed") + return nil, mustPopError() } // add and nodes to keyInfoNode2 := C.xmlSecTmplEncDataEnsureKeyInfo(encKeyNode, nil) if keyInfoNode2 == nil { - return nil, fmt.Errorf("xmlSecTmplEncDataEnsureKeyInfo failed") + return nil, mustPopError() } // Add a DigestMethod element to the encryption method node { encKeyMethod := C.xmlSecTmplEncDataGetEncMethodNode(encKeyNode) - var ns = constXmlChar("http://www.w3.org/2000/09/xmldsig#") - var strDigestMethod = constXmlChar("DigestMethod") - var strAlgorithm = constXmlChar("Algorithm") + var ns = constXMLChar("http://www.w3.org/2000/09/xmldsig#") + var strDigestMethod = constXMLChar("DigestMethod") + var strAlgorithm = constXMLChar("Algorithm") var algorithm *C.xmlChar switch opts.DigestAlgorithm { case Sha512: - algorithm = constXmlChar("http://www.w3.org/2001/04/xmlenc#sha512") + algorithm = constXMLChar("http://www.w3.org/2001/04/xmlenc#sha512") case Sha384: - algorithm = constXmlChar("http://www.w3.org/2001/04/xmldsig-more#sha384") + algorithm = constXMLChar("http://www.w3.org/2001/04/xmldsig-more#sha384") case Sha256: - algorithm = constXmlChar("http://www.w3.org/2001/04/xmlenc#sha256") + algorithm = constXMLChar("http://www.w3.org/2001/04/xmlenc#sha256") case Sha1: - algorithm = constXmlChar("http://www.w3.org/2000/09/xmldsig#sha1") - case DefaultAlgorithm: - algorithm = constXmlChar("http://www.w3.org/2000/09/xmldsig#sha1") + algorithm = constXMLChar("http://www.w3.org/2000/09/xmldsig#sha1") + case DefaultDigestAlgorithm: + algorithm = constXMLChar("http://www.w3.org/2000/09/xmldsig#sha1") default: - return nil, fmt.Errorf("unknown digest algorithm %d", opts.DigestAlgorithm) + return nil, errInvalidAlgorithm } node := C.xmlSecAddChild(encKeyMethod, strDigestMethod, ns) C.xmlSetProp(node, strAlgorithm, algorithm) @@ -182,22 +225,22 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { // add our certificate to KeyInfoNode x509dataNode := C.xmlSecTmplKeyInfoAddX509Data(keyInfoNode2) if x509dataNode == nil { - return nil, fmt.Errorf("xmlSecTmplKeyInfoAddX509Data failed") + return nil, mustPopError() } if dataNode := C.xmlSecTmplX509DataAddCertificate(x509dataNode); dataNode == nil { - return nil, fmt.Errorf("xmlSecTmplX509DataAddCertificate failed") + return nil, mustPopError() } // create encryption context var encCtx = C.xmlSecEncCtxCreate(keysMngr) if encCtx == nil { - return nil, fmt.Errorf("xmlSecEncCtxCreate failed") + return nil, mustPopError() } defer C.xmlSecEncCtxDestroy(encCtx) // generate a key of the appropriate type switch opts.SessionCipher { - case DefaultAlgorithm: + case DefaultSessionCipher: encCtx.encKey = C.xmlSecKeyGenerate(C.MY_xmlSecKeyDataAesId(), 256, C.xmlSecKeyDataTypeSession) case Aes128Cbc: @@ -213,15 +256,15 @@ func XmlEncrypt(publicKey, doc []byte, opts Options) ([]byte, error) { encCtx.encKey = C.xmlSecKeyGenerate(C.MY_xmlSecKeyDataDesId(), 192, C.xmlSecKeyDataTypeSession) default: - return nil, fmt.Errorf("unknown cipher type %d", opts.SessionCipher) + return nil, errInvalidAlgorithm } if encCtx.encKey == nil { - return nil, fmt.Errorf("xmlSecKeyGenerate failed") + return nil, mustPopError() } // encrypt the data if rv := C.xmlSecEncCtxXmlEncrypt(encCtx, encDataNode, C.xmlDocGetRootElement(parsedDoc)); rv < 0 { - return nil, fmt.Errorf("xmlSecEncCtxXmlEncrypt failed") + return nil, mustPopError() } encDataNode = nil // the template is inserted in the doc, so we don't own it diff --git a/encrypt_realworld_test.go b/encrypt_realworld_test.go index 69a7e8b..543873c 100644 --- a/encrypt_realworld_test.go +++ b/encrypt_realworld_test.go @@ -69,7 +69,7 @@ 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`) - actualPlaintextString, err := DecryptXML(testSuite.Key, docStr) + actualPlaintextString, err := Decrypt(testSuite.Key, docStr) c.Assert(err, IsNil) c.Assert(strings.HasSuffix(string(actualPlaintextString), "\n"), Equals, true) } func (testSuite *XmlencRealWorldTest) TestInvalid(c *C) { - _, err := DecryptXML(testSuite.Key, testSuite.DocStr) + _, err := Decrypt(testSuite.Key, testSuite.DocStr) c.Assert(err, IsNil) - _, err = DecryptXML(testSuite.Key, []byte("")) + _, err = Decrypt(testSuite.Key, []byte("")) c.Assert(err, ErrorMatches, "xmlSecFindNode cannot find EncryptedData node") - _, err = DecryptXML([]byte("XXX"), testSuite.DocStr) + _, err = Decrypt([]byte("XXX"), testSuite.DocStr) c.Assert(err, ErrorMatches, "func=xmlSecOpenSSLAppKeyLoadBIO:.*") docStr := []byte(`https://idp.testshib.org/idp/shibbolethinvalid<`) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, ErrorMatches, "malformed XML") docStr = []byte(` @@ -132,7 +132,7 @@ func (testSuite *XmlencRealWorldTest) TestInvalid(c *C) { `) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, IsNil) docStr = []byte(` @@ -160,7 +160,7 @@ func (testSuite *XmlencRealWorldTest) TestInvalid(c *C) { `) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, ErrorMatches, "func=xmlSecBase64CtxDecodeByte.*") docStr = []byte(` @@ -188,6 +188,6 @@ func (testSuite *XmlencRealWorldTest) TestInvalid(c *C) { `) - _, err = DecryptXML(testSuite.Key, docStr) + _, err = Decrypt(testSuite.Key, docStr) c.Assert(err, ErrorMatches, ".*name=EncryptionMethod.*") } diff --git a/encrypt_test.go b/encrypt_test.go index 65e60b9..f5502f8 100644 --- a/encrypt_test.go +++ b/encrypt_test.go @@ -82,10 +82,10 @@ cvCsEFiJZ4AbF+DgmO6TarJ8O05t8zvnOwJlNCASPZRH/JmF8tX0hoHuAQ==X509Data,omitempty"` } +// SignatureX509Data represents the element of type SignatureX509Data struct { X509Certificate string `xml:"X509Certificate,omitempty"` } -// DefaultSignature populates a default Signature that uses c14n and SHA1. +// DefaultSignature returns a Signature struct that uses the default c14n and SHA1 settings. func DefaultSignature(pemEncodedPublicKey []byte) Signature { // xmlsec wants the key to be base64-encoded but *not* wrapped with the // PEM flags diff --git a/thread_darwin.go b/thread_darwin.go index 0cf1a42..79f4c66 100644 --- a/thread_darwin.go +++ b/thread_darwin.go @@ -5,6 +5,6 @@ import "unsafe" // #include import "C" -func getThreadId() uintptr { +func getThreadID() uintptr { return uintptr(unsafe.Pointer(C.pthread_self())) } diff --git a/thread_linux.go b/thread_linux.go index dd6f99b..20f2d4c 100644 --- a/thread_linux.go +++ b/thread_linux.go @@ -2,6 +2,6 @@ package xmlsec import "syscall" -func getThreadId() uintptr { +func getThreadID() uintptr { return uintptr(syscall.Gettid()) } diff --git a/xmldsig.go b/xmldsig.go index fe30edf..e8dabd8 100644 --- a/xmldsig.go +++ b/xmldsig.go @@ -2,7 +2,6 @@ package xmlsec import ( "errors" - "fmt" "unsafe" ) @@ -15,9 +14,9 @@ import ( // #include import "C" -// DsigOptions represents additional, less commonly used, options for Sign and +// SignatureOptions represents additional, less commonly used, options for Sign and // Verify -type DsigOptions struct { +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. @@ -28,18 +27,19 @@ type DsigOptions struct { XMLID []XMLIDOption } +// XMLIDOption represents the definition of an XML reference element +// (See http://www.w3.org/TR/xml-id/) type XMLIDOption struct { ElementName string ElementNamespace string AttributeName string } -// Sign returns a version of docStr signed with key according to -// the XML-DSIG standard. docStr is a template document meaning -// that it contains a `Signature` element in the -// http://www.w3.org/2000/09/xmldsig# namespace. -func Sign(key []byte, doc []byte, opts DsigOptions) ([]byte, error) { - +// Sign returns a version of doc signed with key according to +// the XML-DSIG 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 Sign(key []byte, doc []byte, opts SignatureOptions) ([]byte, error) { startProcessingXML() defer stopProcessingXML() @@ -88,22 +88,22 @@ const ( xmlSecDSigStatusInvalid = 2 ) -// Verify checks that the signature in docStr is valid according +// Verify checks that the signature in doc is valid according // to the XML-DSIG specification. publicKey is the public part of -// the key used to sign docStr. If the signature is not correct, +// the key used to sign doc. If the signature is not correct, // this function returns ErrVerificationFailed. -func Verify(publicKey []byte, doc []byte, opts DsigOptions) error { +func Verify(publicKey []byte, doc []byte, opts SignatureOptions) error { startProcessingXML() defer stopProcessingXML() keysMngr := C.xmlSecKeysMngrCreate() if keysMngr == nil { - return fmt.Errorf("xmlSecKeysMngrCreate failed") + return mustPopError() } defer C.xmlSecKeysMngrDestroy(keysMngr) if rv := C.xmlSecCryptoAppDefaultKeysMngrInit(keysMngr); rv < 0 { - return fmt.Errorf("xmlSecCryptoAppDefaultKeysMngrInit failed") + return mustPopError() } key := C.xmlSecCryptoAppKeyLoadMemory( @@ -112,7 +112,7 @@ func Verify(publicKey []byte, doc []byte, opts DsigOptions) error { C.xmlSecKeyDataFormatCertPem, nil, nil, nil) if key == nil { - return fmt.Errorf("xmlSecCryptoAppKeyLoadMemory failed") + return mustPopError() } if rv := C.xmlSecCryptoAppKeyCertLoadMemory(key, @@ -120,16 +120,16 @@ func Verify(publicKey []byte, doc []byte, opts DsigOptions) error { C.xmlSecSize(len(publicKey)), C.xmlSecKeyDataFormatCertPem); rv < 0 { C.xmlSecKeyDestroy(key) - return fmt.Errorf("xmlSecCryptoAppKeyCertLoad failed") + return mustPopError() } if rv := C.xmlSecCryptoAppDefaultKeysMngrAdoptKey(keysMngr, key); rv < 0 { - return fmt.Errorf("xmlSecCryptoAppDefaultKeysMngrAdoptKey failed") + return mustPopError() } dsigCtx := C.xmlSecDSigCtxCreate(keysMngr) if dsigCtx == nil { - return fmt.Errorf("xmlSecDSigCtxCreate failed") + return mustPopError() } defer C.xmlSecDSigCtxDestroy(dsigCtx) diff --git a/xmldsig_test.go b/xmldsig_test.go index 76dd5f5..b699179 100644 --- a/xmldsig_test.go +++ b/xmldsig_test.go @@ -12,15 +12,15 @@ type Envelope struct { Signature Signature `xml:"http://www.w3.org/2000/09/xmldsig# Signature"` } -type XmlDSigTest struct { +type XMLDSigTest struct { Key []byte Cert []byte DocStr []byte } -var _ = Suite(&XmlDSigTest{}) +var _ = Suite(&XMLDSigTest{}) -func (testSuite *XmlDSigTest) SetUpTest(c *C) { +func (testSuite *XMLDSigTest) SetUpTest(c *C) { testSuite.Key = []byte(`-----BEGIN RSA PRIVATE KEY----- MIIBPAIBAAJBANPQbQ92nlbeg1Q5JNHSO1Yey46nZ7GJltLWw1ccSvp7pnvmfUm+ M521CpFpfr4EAE3UVBMoU9j/hqq3dFAc2H0CAwEAAQJBALFVCjmsAZyQ5jqZLO5N @@ -105,7 +105,7 @@ fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga } -func (testSuite *XmlDSigTest) TestSignAndVerify(c *C) { +func (testSuite *XMLDSigTest) TestSignAndVerify(c *C) { expectedSignedString := `