Beispiel #1
0
func XMLSecDSigCtxSignDocument(ctx PtrSource, doc types.Document) error {
	ctxptr, err := validDSigCtxPtr(ctx)
	if err != nil {
		return err
	}

	root, err := doc.DocumentElement()
	if err != nil {
		return err
	}

	rootptr, err := validNodePtr(root)
	if err != nil {
		return err
	}

	cname := stringToXMLChar(SignatureNode)
	cns := stringToXMLChar(DSigNs)
	defer C.free(unsafe.Pointer(cname))
	defer C.free(unsafe.Pointer(cns))

	nodeptr := C.xmlSecFindNode(rootptr, cname, cns)
	if nodeptr == nil {
		return errors.New("failed to find start node")
	}

	return xmlSecDSigCtxSignRaw(ctxptr, nodeptr)
}
Beispiel #2
0
func findSignatureNode(n *C.xmlNode) *C.xmlNode {
	/* move this out to C so we can just static/const it? */
	cname := stringToXMLChar(SignatureNode)
	cns := stringToXMLChar(DSigNs)
	defer C.free(unsafe.Pointer(cname))
	defer C.free(unsafe.Pointer(cns))

	return C.xmlSecFindNode(n, cname, cns)
}
Beispiel #3
0
// 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()

	keysMngr := C.xmlSecKeysMngrCreate()
	if keysMngr == nil {
		return nil, popError()
	}
	defer C.xmlSecKeysMngrDestroy(keysMngr)

	if rv := C.xmlSecCryptoAppDefaultKeysMngrInit(keysMngr); rv < 0 {
		return nil, popError()
	}

	key := C.xmlSecCryptoAppKeyLoadMemory(
		(*C.xmlSecByte)(unsafe.Pointer(&privateKey[0])),
		C.xmlSecSize(len(privateKey)),
		C.xmlSecKeyDataFormatPem,
		nil, nil, nil)
	if key == nil {
		return nil, popError()
	}

	if rv := C.xmlSecCryptoAppDefaultKeysMngrAdoptKey(keysMngr, key); rv < 0 {
		return nil, popError()
	}

	parsedDoc, err := newDoc(doc, nil)
	if err != nil {
		return nil, err
	}
	defer closeDoc(parsedDoc)

	// create encryption context
	encCtx := C.xmlSecEncCtxCreate(keysMngr)
	if encCtx == nil {
		return nil, popError()
	}
	defer C.xmlSecEncCtxDestroy(encCtx)

	encDataNode := C.xmlSecFindNode(C.xmlDocGetRootElement(parsedDoc),
		(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeEncryptedData)),
		(*C.xmlChar)(unsafe.Pointer(&C.xmlSecEncNs)))
	if encDataNode == nil {
		return nil, fmt.Errorf("xmlSecFindNode cannot find EncryptedData node")
	}

	// decrypt the data
	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
}
Beispiel #4
0
// Sign returns a version of doc signed with key according to
// the XMLDSIG standard. doc is a template document meaning
// that it contains an `http://www.w3.org/2000/09/xmldsig#Signature`
// element whose properties define how and what to sign.
func 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),
		(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
		(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
	if node == nil {
		return nil, errors.New("cannot find start node")
	}

	if rv := C.xmlSecDSigCtxSign(ctx, node); rv < 0 {
		return nil, errors.New("failed to sign")
	}

	return dumpDoc(parsedDoc), nil

}
Beispiel #5
0
// Verify checks that the signature in doc is valid according
// to the XMLDSIG specification. publicKey is the public part of
// the key used to sign doc. If the signature is not correct,
// this function returns ErrVerificationFailed.
func Verify(publicKey []byte, doc []byte, opts SignatureOptions) error {
	startProcessingXML()
	defer stopProcessingXML()

	keysMngr := C.xmlSecKeysMngrCreate()
	if keysMngr == nil {
		return mustPopError()
	}
	defer C.xmlSecKeysMngrDestroy(keysMngr)

	if rv := C.xmlSecCryptoAppDefaultKeysMngrInit(keysMngr); rv < 0 {
		return mustPopError()
	}

	key := C.xmlSecCryptoAppKeyLoadMemory(
		(*C.xmlSecByte)(unsafe.Pointer(&publicKey[0])),
		C.xmlSecSize(len(publicKey)),
		C.xmlSecKeyDataFormatCertPem,
		nil, nil, nil)
	if key == nil {
		return mustPopError()
	}

	if rv := C.xmlSecCryptoAppKeyCertLoadMemory(key,
		(*C.xmlSecByte)(unsafe.Pointer(&publicKey[0])),
		C.xmlSecSize(len(publicKey)),
		C.xmlSecKeyDataFormatCertPem); rv < 0 {
		C.xmlSecKeyDestroy(key)
		return mustPopError()
	}

	if rv := C.xmlSecCryptoAppDefaultKeysMngrAdoptKey(keysMngr, key); rv < 0 {
		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),
		(*C.xmlChar)(unsafe.Pointer(&C.xmlSecNodeSignature)),
		(*C.xmlChar)(unsafe.Pointer(&C.xmlSecDSigNs)))
	if node == nil {
		return errors.New("cannot find start node")
	}

	if rv := C.xmlSecDSigCtxVerify(dsigCtx, node); rv < 0 {
		return ErrVerificationFailed
	}

	if dsigCtx.status != xmlSecDSigStatusSucceeded {
		return ErrVerificationFailed
	}
	return nil
}