santuario-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Cullum, Steve" <steven.cul...@eds.com>
Subject RE: XML Security-C:: HCRYPTPROV DSS/RSA providers not set via Win CAPI CryptoX509 using just the PCCERT_CONTEXT cosntructor
Date Mon, 23 May 2005 17:54:29 GMT
Ooops..

My last post didn't actually make a point...

Q) Is it a limitation in xml-security to only allow keys of length 40.

The following thread - discusses this topic in more detail...

http://groups-beta.google.com/group/microsoft.public.platformsdk.security/br
owse_frm/thread/b24b3cfdeac53dd1/ea4a951d04202694?q=DSA+signature+length+46&
rnum=15&hl=en#ea4a951d04202694 

-----Original Message-----
From: Cullum, Steve 
Sent: 23 May 2005 16:52
To: 'security-dev@xml.apache.org'
Subject: RE: XML Security-C:: HCRYPTPROV DSS/RSA providers not set via Win
CAPI CryptoX509 using just the PCCERT_CONTEXT cosntructor


Berin,

Using the latest version of xml-security from CVS - I can clone the X509
cert using WINCAPI but I get errors during sig->validate() regarding and
invalid signature.  I tried the same sequence of code using the OpenSSL
providers and got something very similar.

Using WINCAPI - the message 
	An error occured in the XML-Security-C Crypto routines
	Message: WinCAPI:DSA::VerifyBase64Signature - Expect 40 bytes in a
DSA signature

Using OPENSSL - the message
	An error occured in the XML-Security-C Crypto routines
   	Message: OpenSSL:DSA - Signature Length incorrect

(*) Do these errors relate to the certificte or the signature in the XML
document?

(*) For the OpenSSL test, I exported the key as a BASE64 DER encoded
certificate and manually removed the ----BEGIN CERTIFICATE---- and ----END
CERTIFICATE---- headers.  Was this the correct thing to do?



bool WinCAPICryptoKeyDSA::verifyBase64Signature(unsigned char * hashBuf,
unsigned int hashLen, char * base64Signature, unsigned int sigLen) {
  .. hashBuf= [data]
  .. hashLen= 20
  .. base64Signature
"MCwCFFiTYY7/B+tYizrqccMZJKVQC6RyAhQUoVXtXfNUVEFZlaE3USajTEqUzQ=="
  .. sigLen= 64  

  b64.decodeInit();
  rawSigLen = b64.decode((unsigned char *) base64Signature, sigLen, rawSig,
sigLen);
  rawSigLen += b64.decodeFinish(&rawSig[rawSigLen], sigLen - rawSigLen);

  .. rawSigLen = 46

  if (rawSigLen != 40)
  {
	throw XSECCryptoException(XSECCryptoException::DSAError,
      "WinCAPI:DSA::VerifyBase64Signature - Expect 40 bytes in a DSA
signature");
  }
}




//
// validate.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"

#include "IOStreamOutputter.hpp"

#define USE_WINCAPI

// XML-Security-C (XSEC)
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "xerces-c_2D.lib")
#pragma comment (lib, "xsec_1D.lib")


#include <xsec/framework/XSECProvider.hpp>
#include <xsec/dsig/DSIGReference.hpp>

#ifdef USE_WINCAPI
  #include <xsec/enc/WinCAPI/WinCAPICryptoKeyHMAC.hpp>
  #include <xsec/enc/WinCAPI/WinCAPICryptoProvider.hpp>
  #include <xsec/enc/WinCAPI/WinCAPICryptoX509.hpp>
#endif

#ifdef USE_OPENSSL
  #include <xsec/enc/OpenSSL/OpenSSLCryptoKeyHMAC.hpp>
  #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
  #include <xsec/enc/XSECCryptoException.hpp>
#endif // USE_OPENSSL

#include <xsec/framework/XSECException.hpp>
#include <xsec/enc/XSECCryptoException.hpp>

// Xerces
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>


#if defined(_WIN32)
#	include <xsec/utils/winutils/XSECURIResolverGenericWin32.hpp>
#else
#	include <xsec/utils/unixutils/XSECURIResolverGenericUnix.hpp>
#endif


XERCES_CPP_NAMESPACE_USE

TCHAR *docToValidate = 0x00;
#define IDATTRIBUTENS    "http://schemas.xmlsoap.org/ws/2002/07/utility" 
#define IDATTRIBUTENAME  "Id"
#define MY_TYPE          (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#define SIGNER_NAME      L"MYSIGNER"
#define CERT_STORE_NAME  L"MY"

void ReadFile(TCHAR *fileName, TCHAR **chars, DWORD *len /* in TCHARS */)
{
  DWORD bytesRead = 0;
  HANDLE hfp = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  *len = GetFileSize(hfp, NULL);

  *len /= sizeof(TCHAR); // convert length from bytes to TCHAR's
  *chars = (TCHAR *)malloc(*len * sizeof(TCHAR)); // dont mul by
sizeof(TCHAR)
  ReadFile(hfp, (LPVOID)*chars, *len * sizeof(TCHAR), &bytesRead, NULL);
  CloseHandle(hfp);
}


int main (int argc, char **argv) {

  try 
  {
    XMLPlatformUtils::Initialize();
    XSECPlatformUtils::Initialise();
  }
  catch (const XMLException &e)
  {
    cerr << "Error during initialisation of Xerces" << endl;
    cerr << "Error Message = : " << e.getMessage() << endl;
  }

  // Use xerces to parse the document
  XercesDOMParser * parser = new XercesDOMParser;
  parser->setDoNamespaces(true);
  parser->setCreateEntityReferenceNodes(true);
  parser->setDoSchema(true);

  // Create an input source
  DWORD len = 0;
  ReadFile(_T("c:\\apache\\signedxml\\nocert.xml"), &docToValidate, &len);
  MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*)
docToValidate, (unsigned int) len, "XSECMem");

  parser->parse(*memIS);
  int errorCount = parser->getErrorCount();
  if (errorCount > 0) {
    cerr << "Error parsing input document\n";
    exit (1);
  }

  DOMDocument *doc = parser->getDocument();
  docSetup(doc);

  // Now create a signature object to validate the document
  XSECProvider prov;
 
  DSIGSignature * sig = prov.newSignatureFromDOM(doc);

  // Register defined attribute name
  sig->registerIdAttributeName(MAKE_UNICODE_STRING("ID"));
  sig->registerIdAttributeNameNS(MAKE_UNICODE_STRING(IDATTRIBUTENS),
MAKE_UNICODE_STRING(IDATTRIBUTENAME));

  try 
  {
#ifdef USE_WINCAPI
    HCERTSTORE     certStore = NULL;
    PCCERT_CONTEXT certContext = NULL; 

    certStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL,
CERT_SYSTEM_STORE_CURRENT_USER, CERT_STORE_NAME);
    if(certStore == NULL)
    {
      cout << "Certificate store cannot be opened\n";
      exit (1);
    }

    // find signer's certificate. -- this certificate must have access to
the signer's private key.
    certContext = CertFindCertificateInStore(certStore, MY_TYPE, 0,
CERT_FIND_SUBJECT_STR, SIGNER_NAME, NULL);
    if(certContext == NULL)
    {
      cout << "unable to find signers certificate\n";
      exit (1);
    }

    WinCAPICryptoProvider * cp = new WinCAPICryptoProvider(NULL, NULL,
CRYPT_MACHINE_KEYSET);
    XSECPlatformUtils::SetCryptoProvider(cp);
    WinCAPICryptoX509 * x509 = new WinCAPICryptoX509(certContext,
cp->getProviderRSA(), cp->getProviderDSS());
#endif // USE_WINCAPI

#ifdef USE_OPENSSL    
    OpenSSLCryptoX509 * x509 = new OpenSSLCryptoX509();
    TCHAR *b64;
    DWORD b64Len;
    ReadFile(_T("c:\\apache\\signedxml\\nocert.cer"), &b64, &b64Len);
    x509->loadX509Base64Bin(b64, (unsigned int) b64Len);
#endif // USE_OPENSSL

    // in my XML file i have no keyinfo
    sig->load();
    sig->setSigningKey(x509->clonePublicKey());

    if (sig->verify()) 
    {
      cout << "Signature Valid\n";
    }
    else 
    {
      char * err = XMLString::transcode(sig->getErrMsgs());
      cout << "Incorrect Signature\n";
      cout << err << endl;
      XSEC_RELEASE_XMLCH(err);
    }
  }
  catch (XSECException &e)
  {
    cerr << "An error occured during a signature load\n   Message: " <<
e.getMsg() << endl;
    exit(1);
  }
  catch (XSECCryptoException &e) {
    cerr << "An error occured in the XML-Security-C Crypto routines\n
Message: " << e.getMsg() << endl;
    exit(1);
  }

  // Clean up

  delete memIS;
  delete parser;

  return 0;
}





 

Mime
View raw message