[xmlsec] X509, verification of signature

piotr at fraktal.com.pl piotr at fraktal.com.pl
Wed Mar 9 02:15:50 PST 2005


Hi

I successfully signed xml according to rules http://www.w3.org/TR/xmldsig-core/.
I did it using xmlsec. Signature is correct because I checked it using external tool.
But I've got an unsolved problem at verifing my signature myself.
I used code published in verify3.c file doing little changes matching to my task
and context (CryptoApi, X509, C++Builder6)

I read xml file to char* buffer and call my VerifyCert function. It successfully read
all certs from "CA" CryptoApi store and put them to xmlsec keys manager using
xmlSecMSCryptoAppKeysMngrCertLoadMemory (see LoadCerts() function).
But VerifyCert fails during call of xmlSecDSigCtxVerify(). This function returns
a few error context via error callback function. They look like:

1.
 file:        ..\src\keys.c
 func:        xmlSecKeysMngrGetKey
 errorObject:   
 errorSubject:    xmlSecKeysMngrFindKey
 reason:        1
 msg:        

2.
 file:        ..\src\xmldsig.c
 func:        xmlSecDSigCtxProcessKeyInfoNode
 errorObject:    
 errorSubject:    
 reason:        45
 msg:    
3.
 file:        ..\src\xmldsig.c
 func:        xmlSecDSigCtxProcessSignatureNode
 errorObject:   
 errorSubject:    xmlSecDSigCtxProcessKeyInfoNode
 reason:        1
 msg:
4.
 file:        ..\src\xmldsig.c
 func:        xmlSecDSigCtxVerify
 errorObject:    
 errorSubject:    xmlSecDSigCtxSigantureProcessNode
 reason:        1
 msg:      



What should I change to make this code to work?
Where did I mistakes?
Should I load all certs from CA store, or only proper one?


Thanx in advance
Peter



My code looks like:

//------------------------------------------------------------
// loads certs from MsStore
//

xmlSecKeysMngrPtr LoadCerts(AnsiString StoreName) {

   xmlSecKeysMngrPtr mngr = NULL;

   // przygotowanie menagera xmlsec

   mngr = xmlSecKeysMngrCreate();
   if(mngr == NULL) {
      return (NULL);
   }
   if(xmlSecCryptoAppDefaultKeysMngrInit(mngr) < 0) {
      xmlSecKeysMngrDestroy(mngr);
      return (NULL);
   }

   //xmlSecKeyDataFormat secKeyDataFormat = X509_ASN_ENCODING;

   // pobranie listy certyfikatow  - retrieving cert list

   wchar_t wcharStoreName[256];
   StoreName.WideChar(wcharStoreName, 256);

   HCERTSTORE hStoreHandle;


   PCCERT_CONTEXT pSignerCert = NULL;

   CRYPT_SIGN_MESSAGE_PARA  SigParams;
   DWORD cbSignedMessageBlob;
   BYTE  *pbSignedMessageBlob;
   DWORD cbDecodedMessageBlob;
   BYTE  *pbDecodedMessageBlob;
   CRYPT_VERIFY_MESSAGE_PARA VerifyParams;

   //--------------------------------------------------------------------
   // opening CryptoApi cert store

   if(!( hStoreHandle = CertOpenStore(
      CERT_STORE_PROV_SYSTEM,
      0,
      NULL,
      CERT_SYSTEM_STORE_CURRENT_USER,
      wcharStoreName))){
        return NULL;
   }


   PCCERT_CONTEXT  pCertContext = NULL;

   int loadResult = 0;

   // enumerating certs from CryptoApi store and loading to xmlsec keys menager
   while(loadResult == 0){
      pCertContext = CertEnumCertificatesInStore(hStoreHandle, pCertContext);
      if(!pCertContext)
         break;
      //char pszNameString[256];
      //CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL,
      //   pszNameString, 128);

      //if(strcmp(pszNameString, "Izba Celna w Krakowie") == 0)
      loadResult = xmlSecMSCryptoAppKeysMngrCertLoadMemory(mngr,
                               pCertContext->pbCertEncoded,
                               pCertContext->cbCertEncoded,
                               xmlSecKeyDataFormatDer,
                               xmlSecKeyDataTypeTrusted);

   }

   if(loadResult < 0){
      // cleaning
      xmlSecKeysMngrDestroy(mngr);
      return NULL;
   }
   return mngr;
}


// --------------------------------------------------------------
/* verifing certs
/*
some explanation: storeName = "CA"
inBuffer - contains previously loaded xml data
inSize   - size of inBuffer
txt - holds error messages
*/
bool VerifyCert(char *inBuffer, int inSize, char *storeName, int storeNameSize, AnsiString& 
txt){

   txt = "";
   bool result = true;
   xmlSecKeysMngrPtr mngr = NULL;

   if(!InitParser(storeName)){
      txt = "Nie mo¿na zainicjalizowaæ parsera";
      return false;
   }

   // setting up error callback
   xmlSecErrorsDefaultCallbackEnableOutput (1);
   xmlSecErrorsSetCallback(myXmlSecErrorsCallback);

   // loading certs from CryptoApi
   mngr = LoadCerts(storeName);

   if(!mngr){
      txt = "TXMLDocumentSign::VerifyCert() - b³¹d ³adowania certyfikatów";
      StopParser();
      return false;
   }

   xmlDocPtr doc = NULL;
   xmlSecDSigCtxPtr dsigCtx = NULL;
   xmlNodePtr node = NULL;

   int res = -1;


   // loading data from buffer and parsing
   doc = xmlParseMemory(inBuffer, inSize);
   xmlNodePtr rootNode = xmlDocGetRootElement(doc);
   if ((doc == NULL) || (rootNode == NULL)){
      result = false;
      txt = "TXMLDocumentSign::VerifyCert() - brak elemementu g³ównego w dokumencie 
XML.";
      goto done;
   }

   // test code
   {
      xmlChar *mem  = NULL;
      int size = 0;
      xmlDocDumpMemory(doc, &mem, &size);
      std::auto_ptr<TFileStream> fs (new TFileStream("dump.xml", fmCreate));
      fs->Write(mem, size);
      fs.release();
   }

   // find start node
   node = xmlSecFindNode(rootNode, BAD_CAST "Signature", BAD_CAST 
"http://www.w3.org/2000/09/xmldsig#"/*xmlSecDSigNs*/ );
   if(node == NULL) {
      result = false;
      txt = "TXMLDocumentSign::VerifyCert() - nie mo¿na odnale£æ elementu \"Signature\".";
      goto done;
   }

   // create signature context
   dsigCtx = xmlSecDSigCtxCreate(mngr);
   if(dsigCtx == NULL) {
      result = false;
      txt = "TXMLDocumentSign::VerifyCert() - b³¹d pozyskiwania kontekstu.";
      goto done;
   }

   // Verify signature
   if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
      txt = "TXMLDocumentSign::VerifyCert() - nieudana weryfikacja podpisu.";
      result = false;
      goto done;
   }

   if(!dsigCtx->status == xmlSecDSigStatusSucceeded){
      result = false;
   }

done:
   // cleanup
   if(dsigCtx != NULL) {
      xmlSecDSigCtxDestroy(dsigCtx);
   }

   if(doc != NULL) {
      xmlFreeDoc(doc);
   }

   StopParser();
   return result;
}


// --------------- initialization of xmlsec
int InitParser(char *storeName){

   xmlInitParser();
   LIBXML_TEST_VERSION xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | 
XML_COMPLETE_ATTRS;
   xmlSubstituteEntitiesDefault(1);
#ifndef XMLSEC_NO_XSLT
   xmlIndentTreeOutput = 1;
#endif // XMLSEC_NO_XSLT


   // Init xmlsec library
   if(xmlSecInit() < 0) {

      return(0);
   }

   // Check loaded library version
   if(xmlSecCheckVersion() != 1) {

      return(0);
   }

   // Load default crypto engine if we are supporting dynamic
   // * loading for xmlsec-crypto libraries. Use the crypto library
   // * name ("openssl", "nss", etc.) to load corresponding
   // * xmlsec-crypto library.
   //
#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
   if(xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
      return(0);
   }
#endif // XMLSEC_CRYPTO_DYNAMIC_LOADING

   // Init crypto library
   if(xmlSecCryptoAppInit(storeName) < 0) {
      return(0);
   }

   // Init xmlsec-crypto library
   if(xmlSecCryptoInit() < 0) {
      return(0);
   }
   return 1;
}

// shutting down xmlsec

int StopParser(){

   // Shutdown xmlsec-crypto library
   xmlSecCryptoShutdown();

   // Shutdown crypto library
   xmlSecCryptoAppShutdown();

   // Shutdown xmlsec library
   xmlSecShutdown();

   // Shutdown libxslt/libxml
//#ifndef XMLSEC_NO_XSLT
//   xsltCleanupGlobals();
//#endif // XMLSEC_NO_XSLT
   xmlCleanupParser();

   return(0);
}


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.aleksey.com/pipermail/xmlsec/attachments/20050309/43f09e2b/attachment-0002.htm


More information about the xmlsec mailing list