santuario-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Cullum, Steve" <steven.cul...@eds.com>
Subject XML Security-C:: HCRYPTPROV DSS/RSA providers not set via WinCAPI CryptoX509 using just the PCCERT_CONTEXT cosntructor
Date Fri, 20 May 2005 18:07:13 GMT
Environment :-

XML-Security-C - CVS version 17/05/05
XALAN-1.7.0 and XERCES-2.5.0
Compiler VC7 (2003)
	#define HAVE_OPENSSL  0
	#define HAVE_WINCAPI  1
	#define USING_XALAN

I am trying to validate a SOAP response signed using the Verisign TSIK toolkit.  
The XML-SOAP response has a detached public key which I have installed into the "current user"
store.
There is no "KeyInfo" or "Object" in my XML document but this seems to be acceptable to DSIGSignature::load();

I don't seem to be able to verify the public key via an WinCAPICryptoX509 using the WinCAPICryptoX509(PCCERT_CONTEXT)
constructor - It loads the key correctly but does not set up the DSA/RSA provider handles
which are needed later on during processing.

Using the mscrypto API - I find the certificate context and create a X509 certificate with
it.

	 WinCAPICryptoX509 * x509 = new WinCAPICryptoX509(certContext);
  	 sig->setSigningKey(x509->clonePublicKey());        // FAILS HERE....
  
However WinCAPICryptoX509::clonePublicKey() fails due to the fact that WinCAPICryptoX509::m_pDSS
has not been set.  The only way I seem able to set WinCAPICryptoX509::m_pDSS is via the constructor
WinCAPICryptoX509::WinCAPICryptoX509(HCRYPTPROV provRSA, HCRYPTPROV provDSS) but if I do this
I am then unable to set 
WinCAPICryptoX509::mp_certContext certificate context handle.

(*) Is there a call similar to WinCAPICryptoX509::SetDSAProvider() ?
(*) As an aside the MSDN documentation for CryptImportPublicKeyInfo() states that it "is always
acceptable" to use X509_ASN_ENCODING | PKCS_7_ASN_ENCODING for the DWORD dwCertEncodingType
parameter - [is this relevant?]

To generate a DSS crypto provider handle I am using 

	WinCAPICryptoProvider * cp = new WinCAPICryptoProvider(NULL, NULL, CRYPT_MACHINE_KEYSET);
    	XSECPlatformUtils::SetCryptoProvider(cp);

(*) Would this handle be the correct one to send to WinCAPICryptoX509::SetDSAProvider() if
it existed ie
	WinCAPICryptoX509::SetDSAProvider(cp->getProviderDSS());

I have also tried 
 
   WinCAPICryptoProvider *cp = new WinCAPICryptoProvider(NULL, NULL, CRYPT_MACHINE_KEYSET);
   WinCAPICryptoX509 *x509 = (WinCAPICryptoX509 *)cp->X509();

At this stage there is no way I seem able to set the X509 certificate context eg
   x509->mp_certContext = certContext;  // no class member fn() exists to allow me to do
this.


(*) If I manually set the value of m_pDSS (via the debugger) inside WinCAPICryptoX509::clonePublicKey()
with a handle derived from calling new WinCAPICryptoProvider(NULL, NULL, CRYPT_MACHINE_KEYSET).
 WinCAPICryptoX509::clonePublicKey() does not fail and "seems" to generate a valid Key.  Calling
sig->Verify() however gives me the error message...

	WinCAPI:DSA::VerifyBase64Signature - Expect 40 bytes in a DSA signature

-- Does this mean my document is fundementally rubbish ?? Looking at the public key details
I can see.
[Signature Algorithm] sha1DSA
[Public Key] DSA (1024 Bits)
[Thumbprint Algorithm] sha1


Eg...
  WinCAPICryptoProvider *cp = new WinCAPICryptoProvider(NULL, NULL, CRYPT_MACHINE_KEYSET);
  // get value of cp->m_provDSS 

  WinCAPICryptoX509::clonePublicKey()
  {
    HCRYPTKEY key;
    BOOL fResult;
  
    &m_pDSS = 1415288 /* set to valid handle gained by WinCAPICryptoProvider(NULL, NULL,
CRYPT_MACHINE_KEYSET); (using debugger)
    if(getPublicKeyType() == XSECCryptoKey::KEY_DSA_PUBLIC) 
    {
      fResult= CryptImportPublicKeyInfo(m_pDSS, X509_ASN_ENCODING, &(mp_certContext->pCertInfo->SubjectPublicKeyInfo),
&key); 
  }
}
	


Can someone verify my steps are correct..

  Load the document into DSIGSignature()
  CertOpenStore()
  certCtxt = CertFindCertificateInStore()
  Create X509 from certCtxt
  Load the signature inside DSIGSignature()
  Set the DSIGSignature signing key to a cloned copy of the public key stored in X509  (do
I have to clone)
  verify the DSIGSignature

  

    

  

//
// my source code....based heavily on SimpleValidate.cpp
//
#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"TESTSIGNER"
#define CERT_STORE_NAME  L"MY"

int main (int argc, char **argv) 
{
	//.. 
	//.. Reading and validation code ommitted
	//..

  // create a signature object to validate the document
  XSECProvider prov;

  DSIGSignature * sig = prov.newSignatureFromDOM(doc);

  sig->registerIdAttributeName(MAKE_UNICODE_STRING("ID"));

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

  // using MSCryptoAPI
  try 
  {
    HCERTSTORE     certStore = NULL;
    PCCERT_CONTEXT certContext = NULL; 

    // open the microsoft certiticate store
    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
    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);
    }

    // build an x509 certificate from my cert context
    WinCAPICryptoX509 * x509 = new WinCAPICryptoX509(certContext);

    sig->load();
    
    // no keyinfo in my XML
    
    sig->setSigningKey(x509->clonePublicKey());        // FAILS HERE....
    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);
  }

  return 0;
}

Mime
View raw message