XML-LibXML-xmlsec

 view release on metacpan or  search on metacpan

xmlsec.xs  view on Meta::CPAN

#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" ) ) {

xmlsec.xs  view on Meta::CPAN

	   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 )