XML-LibXML-xmlsec
view release on metacpan or search on metacpan
#include <xmlsec/xmlsec.h>
#include <xmlsec/xmldsig.h>
#include <xmlsec/openssl/app.h>
#include <xmlsec/xmltree.h>
#include <xmlsec/errors.h>
#include <xmlsec/templates.h>
#include "perl-libxml-mm.h"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <xmlsec/app.h>
#include "crypto.h"
#define XMLSEC_ERRORS_BUFFER_SIZE 1024
xmlSecKeyPtr FindKey(xmlSecKeysMngrPtr mngr, xmlChar* name) {
xmlSecKeyPtr r;
xmlSecKeyInfoCtxPtr ctx=xmlSecKeyInfoCtxCreate(mngr);
xmlSecKeyInfoCtxInitialize(ctx,mngr);
r= xmlSecKeysMngrFindKey(mngr, name, ctx);
xmlSecKeyInfoCtxDestroy(ctx);
return r;
}
/* extracts the libxml2 node from a perl reference
*/
xmlNodePtr
PmmSvNodeExt( SV* perlnode, int copy )
{
xmlNodePtr retval = NULL;
ProxyNodePtr proxy = NULL;
dTHX;
if ( perlnode != NULL && perlnode != &PL_sv_undef ) {
/* if ( sv_derived_from(perlnode, "XML::LibXML::Node") */
/* && SvPROXYNODE(perlnode) != NULL ) { */
/* retval = PmmNODE( SvPROXYNODE(perlnode) ) ; */
/* } */
xs_warn("PmmSvNodeExt: perlnode found\n" );
if ( sv_derived_from(perlnode, "XML::LibXML::Node") ) {
proxy = SvPROXYNODE(perlnode);
if ( proxy != NULL ) {
xs_warn( "PmmSvNodeExt: is a xmlNodePtr structure\n" );
retval = PmmNODE( proxy ) ;
}
if ( retval != NULL
&& ((ProxyNodePtr)retval->_private) != proxy ) {
xs_warn( "PmmSvNodeExt: no node in proxy node\n" );
PmmNODE( proxy ) = NULL;
retval = NULL;
}
}
#ifdef XML_LIBXML_GDOME_SUPPORT
else if ( sv_derived_from( perlnode, "XML::GDOME::Node" ) ) {
croak( "id-attr must be specified");
}
real_doc=(xmlDocPtr) PmmSvNode(doc);
if (real_doc == NULL) {
croak("Error: failed to get libxml doc");
}
/* set id atribute */
buf = xmlStrdup(id_name);
nodeName = (xmlChar*)strrchr((char*)buf, ':');
if(nodeName != NULL) {
(*(nodeName++)) = '\0';
nsHref = buf;
} else {
nodeName = buf;
nsHref = NULL;
}
cur = xmlSecGetNextElementNode(real_doc->children);
while(cur != NULL) {
if(xmlSecAppAddIDAttr(cur, id_attr, nodeName, nsHref) < 0) {
xmlFree(buf);
croak ("Error: xmlSecAppAddIDAttr failed");
}
cur = xmlSecGetNextElementNode(cur->next);
}
xmlFree(buf);
RETVAL=0;
OUTPUT:
RETVAL
int
XmlSecSignDoc(self,doc,mgr, id)
HV * self
SV * doc
IV mgr
xmlChar * id
CODE:
/********************************************************************
XmlSecSignDoc()
Entry point for signing process with a given id
Args:
doc: the libxml doc to sign
mgr: the previously setup key mgr
id: the id value of the node subject to signature
*********************************************************************/
int ret=0;
xmlDocPtr real_doc;
xmlAttrPtr attr;
xmlNodePtr startNode;
if (id == NULL) {
croak( "id must be specified");
}
xmlSecKeysMngrPtr pkm=INT2PTR(xmlSecKeysMngrPtr, mgr);
xmlSecDSigCtx dsigCtx;
ret=xmlSecDSigCtxInitialize(&dsigCtx, pkm);
if (ret < 0) {
croak("Error xmlSecDSigCtxInitialize fail");
}
real_doc=(xmlDocPtr) PmmSvNode(doc);
if (real_doc == NULL) {
croak("Error: failed to get libxml doc");
}
/* find starting node by id */
attr = xmlGetID(real_doc, id);
if (attr == NULL) {
croak("Error: xmlsec fail to find starting node");
}
startNode = xmlSecFindNode(attr->parent, "Signature", "http://www.w3.org/2000/09/xmldsig#");
if (startNode == NULL)
{
croak( "Error: xmlsec fail to find Signature node");
}
ret=xmlSecDSigCtxSign(&dsigCtx, startNode);
if (ret < 0)
{
croak("Error xmlsec signature failed");
}
xmlSecDSigCtxFinalize(&dsigCtx);
RETVAL=ret;
OUTPUT:
RETVAL
int
XmlSecSign(self,doc,mgr,node)
HV * self
SV * doc
IV mgr
SV * node
CODE:
/********************************************************************
xmlSecSign()
Document signing with a given starting node
Args:
doc: the libxml doc to sign
mgr: the previously setup key mgr
node: the signature node
*********************************************************************/
int ret=0;
xmlNodePtr startNode= PmmSvNodeExt(node,0);
if (node == NULL) {
croak("Starting node missing");
}
xmlDocPtr real_doc=(xmlDocPtr) PmmSvNode(doc);
if (real_doc == NULL) {
croak("Error: failed to get libxml doc");
}
xmlSecKeysMngrPtr pkm=INT2PTR(xmlSecKeysMngrPtr, mgr);
xmlSecDSigCtx dsigCtx;
ret=xmlSecDSigCtxInitialize(&dsigCtx, pkm);
if (ret < 0) {
croak("Error xmlSecDSigCtxInitialize fail");
}
ret=xmlSecDSigCtxSign(&dsigCtx, startNode);
if (ret < 0)
{
croak("Error xmlsec signature failed");
}
xmlSecDSigCtxFinalize(&dsigCtx);
RETVAL=ret;
OUTPUT:
RETVAL
int
XmlSecVerify(self,doc,mgr, id)
HV * self
SV * doc
IV mgr
xmlChar * id
PREINIT:
dMY_CXT;
CODE:
/********************************************************************
XmlSecVerify()
This is the main signature verifying function
Args:
doc: the already signed XML document handle
mgr: the previously setup key manager
id: the id of the node we are to verify
********************************************************************/
int ret=0;
xmlDocPtr real_doc;
xmlAttrPtr attr;
xmlNodePtr startNode;
if (id == NULL) {
croak( "id must be specified");
}
xmlSecKeysMngrPtr pkm=INT2PTR(xmlSecKeysMngrPtr, mgr);
xmlSecDSigCtx dsigCtx;
ret=xmlSecDSigCtxInitialize(&dsigCtx, pkm);
if (ret < 0) {
croak("Error xmlSecDSigCtxInitialize fail");
}
real_doc=(xmlDocPtr) PmmSvNode(doc);
if (real_doc == NULL) {
croak("Error: failed to get libxml doc");
}
attr = xmlGetID(real_doc, id);
if (attr == NULL) {
croak("Error: xmlsec fail to find starting node");
}
startNode = xmlSecFindNode(attr->parent, "Signature", "http://www.w3.org/2000/09/xmldsig#");
if (startNode == NULL)
{
croak( "Error: xmlsec fail to find Signature node");
}
//I reset the error msg
MY_CXT.sLastMsg[0]=(char)0;
xmlSecErrorsSetCallback (&MyErrorsCallback);
ret=xmlSecDSigCtxVerify(&dsigCtx, startNode);
xmlSecErrorsSetCallback(&xmlSecErrorsDefaultCallback);
if (ret < 0)
{ croak("Error: xmlSecDSigCtxVerify fail");
RETVAL=ret;
} else {
ret=dsigCtx.status;
}
RETVAL=ret;
OUTPUT:
RETVAL
char *
lastmsg(self)
SV * self
PREINIT:
dMY_CXT;
CODE:
RETVAL=MY_CXT.sLastMsg;
OUTPUT:
RETVAL
int
KeyCertLoad(self,mgr,name,secret,file,format)
SV * self
IV mgr
xmlChar * name
xmlChar * secret
xmlChar * file
xmlSecKeyDataFormat format
CODE:
/********************************************************************
KeyCertLoad()
Entry point for x509 certificate loading
Args:
mgr: The key manager ptr, IV packed
secret: The password for decrypting the certificate
file: Certificate filename
format: The format of the certificate file
*********************************************************************/
int ret=0;
xmlSecKeysMngrPtr pkm=INT2PTR(xmlSecKeysMngrPtr, mgr);
xmlSecKeyPtr key=FindKey(pkm,name);
if (key==NULL) { /* There's no key yet */
key=xmlSecCryptoAppKeyLoad (file,format,secret,xmlSecCryptoAppGetDefaultPwdCallback(),file);
//printf ("Loaded cert as new key\n");
if (key == NULL) {
croak ("Can't load certificate file");
}
ret = xmlSecKeySetName(key, name);
ret = xmlSecCryptoAppDefaultKeysMngrAdoptKey(pkm, key);
} else { /* we attach the certificate to the previously loaded key */
ret=xmlSecCryptoAppKeyCertLoad (key,file,xmlSecKeyDataFormatPem);
//printf ("Loaded cert as attribute\n");
if (ret<0) {
croak("Can't load certificate file");
}
}
RETVAL=ret;
OUTPUT:
( run in 0.498 second using v1.01-cache-2.11-cpan-71847e10f99 )