[xmlsec] FW: Fixes to mscrypto for non-MS CSPs

Wouter wsh333 at gmail.com
Tue Jun 5 23:30:12 PDT 2007


Ok :) This patch has been extended a little bit after that first post, I 
just saw the files Ed sent. Ed has tested this patch thoroughly, and I 
also have done some tests with these changes.

The changes will make mscrypto behave better with non micorsoft CSP's 
(Crypto Service Provider). For example also smartcards and in this 
particular case Entrust provider will now function better related to 
finding and using keys that are accessible via the MS certificate store.

I've created a patch from the current svn tree of xmlsec with the same 
changes (see attachment). However the patch is created on win32 
platform, and I hope you can apply it. If not, let me know, and I'll try 
to create one without the windows endofline chars. (I don't know how to 
create such a diff on a windows platform with svn, any ideas?).

Wouter

Aleksey Sanin wrote:
> Aha! I remember that one! You've asked Ed to try it
> and I was waiting for a confirmation that it works :)
>
> Aleksey
>
> Wouter wrote:
>> Is it the same patch as being posted in this mail?
>> http://www.aleksey.com/pipermail/xmlsec/2006/003560.html 
>> <http://www.aleksey.com/pipermail/xmlsec/2006/003560.html>
>>
>> Then there you can find a patch as well.
>>
>> Wouter
>>
>>
>> Aleksey Sanin wrote:
>>> To be honest, this is the first time I see it.... I might have
>>> missed it somehow, sorry. Is there any way you can create a diff?
>>> It is much easier to apply...
>>>
>>> Thanks!
>>> Aleksey
>>>
>>>
>>>
>>>
>>> Ed Shallow wrote:
>>>> Hi Aleksey,
>>>>
>>>>     Any developments here ?
>>>>
>>>> Cheers,
>>>> Ed
>>>>
>>>> -----Original Message-----
>>>> From: Ed Shallow [mailto:ed.shallow.pwgsc at rogers.com] Sent: Friday, 
>>>> March 09, 2007 6:41 AM
>>>> To: 'xmlsec at aleksey.com'
>>>> Subject: Fixes to mscrypto for non-MS CSPs
>>>>
>>>>       Hi Aleksey,
>>>>
>>>>    Please find attached changes to selected mscrypto routines to 
>>>> correct
>>>> problems found with non-Microsoft Cryptographic Service Providers 
>>>> (CSPs).
>>>> Most notably these patches fix handling of Entrust's CSP aka 
>>>> Entrust Service
>>>> Provider for Windows 7.x. These patches were written by Wouter and 
>>>> tested by
>>>> both Wouter and I last November and December. They were made to the 
>>>> 1.2.10
>>>> source baseline. They also introduce fallback search by "Friendly 
>>>> Name" if
>>>> cn and full dn searches fail.
>>>>
>>>>    I did not create diffs but rather included them exactly as I 
>>>> received
>>>> them from Wouter last November. These changes were applied and 
>>>> compiled to
>>>> the 1.2.10 distribution and not from the daily snapshot.
>>>>
>>>>    Can you apply and test ?
>>>>
>>>>    Wouter can answer any specific question you may have.
>>>>
>>>> Cheers,
>>>> Ed
>>>> ------------------------------------------------------------------------ 
>>>>
>>>>
>>>> _______________________________________________
>>>> xmlsec mailing list
>>>> xmlsec at aleksey.com
>>>> http://www.aleksey.com/mailman/listinfo/xmlsec
>>>
>>
>

-------------- next part --------------
Index: src/mscrypto/kt_rsa.c
===================================================================
--- src/mscrypto/kt_rsa.c	(revision 979)
+++ src/mscrypto/kt_rsa.c	(working copy)
@@ -364,7 +364,7 @@
 	    outBuf[i] = inBuf[inSize - (i + 1)];
 	}
 
-	if (0 == (hKey = xmlSecMSCryptoKeyDataGetKey(ctx->data, xmlSecKeyDataTypePrivate))) {
+	if (0 == (hKey = xmlSecMSCryptoKeyDataGetDecryptKey(ctx->data))) {
 	    xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "xmlSecMSCryptoKeyDataGetKey",
Index: src/mscrypto/keysstore.c
===================================================================
--- src/mscrypto/keysstore.c	(revision 979)
+++ src/mscrypto/keysstore.c	(working copy)
@@ -406,8 +406,69 @@
 				NULL);
 	    xmlFree(bdata);
 	}
-    }   
+    }
 
+    /*
+     * Try ro find certificate with name="Friendly Name"
+     */
+    if (NULL == pCertContext) {
+      DWORD dwPropSize;
+      PBYTE pbFriendlyName;
+      PCCERT_CONTEXT pCertCtxIter = NULL;
+      size_t len = xmlStrlen(name) + 1;     
+      wchar_t * lpFName;
+	
+      lpFName = (wchar_t *)xmlMalloc(sizeof(wchar_t) * len);
+      if(lpFName == NULL) {
+	    xmlSecError(XMLSEC_ERRORS_HERE,
+			xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+			NULL,
+			XMLSEC_ERRORS_R_MALLOC_FAILED,
+		    	XMLSEC_ERRORS_NO_MESSAGE);
+	    CertCloseStore(hStoreHandle, 0);
+	    return(NULL);
+      }
+      MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, lpFName, len);
+      
+      while (pCertCtxIter = CertEnumCertificatesInStore(hStoreHandle, pCertCtxIter)) {
+	if (TRUE != CertGetCertificateContextProperty(pCertCtxIter,
+						      CERT_FRIENDLY_NAME_PROP_ID,
+						      NULL,
+						      &dwPropSize)) {
+	  continue;
+	}
+
+	pbFriendlyName = xmlMalloc(dwPropSize);
+	if(pbFriendlyName == NULL) {
+	    xmlSecError(XMLSEC_ERRORS_HERE,
+			xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)),
+			NULL,
+			XMLSEC_ERRORS_R_MALLOC_FAILED,
+		    	XMLSEC_ERRORS_NO_MESSAGE);
+	    xmlFree(lpFName);
+	    CertCloseStore(hStoreHandle, 0);
+	    return(NULL);
+	}
+	if (TRUE != CertGetCertificateContextProperty(pCertCtxIter,
+						      CERT_FRIENDLY_NAME_PROP_ID,
+						      pbFriendlyName,
+						      &dwPropSize)) {
+	  xmlFree(pbFriendlyName);
+	  continue;
+	}
+
+	/* Compare FriendlyName to name */
+	if (!wcscmp(lpFName, (const wchar_t *)pbFriendlyName)) {
+	  pCertContext = pCertCtxIter;
+	  xmlFree(pbFriendlyName);
+	  break;
+	}
+	xmlFree(pbFriendlyName);
+      }
+
+      xmlFree(lpFName);
+    }
+
     /* We could do the following here: 
      * It would be nice if we could locate the cert with issuer name and
      * serial number, the given keyname can be something like this:
Index: src/mscrypto/certkeys.c
===================================================================
--- src/mscrypto/certkeys.c	(revision 979)
+++ src/mscrypto/certkeys.c	(working copy)
@@ -544,6 +544,28 @@
     return(xmlSecMSCryptoKeyDataCtxGetKey(ctx));
 }
 
+HCRYPTKEY
+xmlSecMSCryptoKeyDataGetDecryptKey(xmlSecKeyDataPtr data) {
+	xmlSecMSCryptoKeyDataCtxPtr ctx;
+	HCRYPTKEY hKey;
+
+	xmlSecAssert2(xmlSecKeyDataIsValid(data), 0);
+	xmlSecAssert2(xmlSecKeyDataCheckSize(data, xmlSecMSCryptoKeyDataSize), 0);
+
+	ctx = xmlSecMSCryptoKeyDataGetCtx(data);
+	xmlSecAssert2(ctx != NULL, 0);
+
+	if( !CryptGetUserKey(xmlSecMSCryptoKeyDataCtxGetProvider(ctx), AT_KEYEXCHANGE, &(hKey))) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+			NULL,
+			"CryptGetUserKey",
+			XMLSEC_ERRORS_R_CRYPTO_FAILED,
+			XMLSEC_ERRORS_NO_MESSAGE);
+		return(0);
+	}
+	return (hKey);
+}
+
 /**
  * xmlSecMSCryptoKeyDataGetCert:
  * @data:		the key data to retrieve certificate from.
Index: src/mscrypto/ciphers.c
===================================================================
--- src/mscrypto/ciphers.c	(revision 979)
+++ src/mscrypto/ciphers.c	(working copy)
@@ -552,6 +552,22 @@
 
 		return(-1);
 	    }
+	} else if (dwError == NTE_BAD_KEYSET) {
+	  /* This error can indicate that a newly installed provider 
+	   * does not have a usable key container yet. It needs to be
+	   * created, and then we have to try again CryptAcquireContext.
+	   * This is also referenced in 
+	   * http://www.microsoft.com/mind/0697/crypto.asp (inituser)
+	   */
+	    if(!CryptAcquireContext(&ctx->cryptProvider, NULL, ctx->providerName,
+				    ctx->providerType, CRYPT_NEWKEYSET)) {
+	        xmlSecError(XMLSEC_ERRORS_HERE, 
+		    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
+		    "CryptAcquireContext",
+		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
+		    XMLSEC_ERRORS_NO_MESSAGE);
+		return(-1);
+	    }
 	} else {
 	    xmlSecError(XMLSEC_ERRORS_HERE, 
 			xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
Index: include/xmlsec/mscrypto/certkeys.h
===================================================================
--- include/xmlsec/mscrypto/certkeys.h	(revision 979)
+++ include/xmlsec/mscrypto/certkeys.h	(working copy)
@@ -23,6 +23,7 @@
 XMLSEC_CRYPTO_EXPORT PCCERT_CONTEXT 	xmlSecMSCryptoKeyDataGetCert	(xmlSecKeyDataPtr data);
 XMLSEC_CRYPTO_EXPORT HCRYPTKEY 		xmlSecMSCryptoKeyDataGetKey	(xmlSecKeyDataPtr data, 
 									 xmlSecKeyDataType type);
+XMLSEC_CRYPTO_EXPORT HCRYPTKEY	xmlSecMSCryptoKeyDataGetDecryptKey(xmlSecKeyDataPtr data);
 XMLSEC_CRYPTO_EXPORT PCCERT_CONTEXT 	xmlSecMSCryptoCertDup		(PCCERT_CONTEXT pCert);
 XMLSEC_CRYPTO_EXPORT xmlSecKeyDataPtr 	xmlSecMSCryptoCertAdopt		(PCCERT_CONTEXT pCert, xmlSecKeyDataType type);
 


More information about the xmlsec mailing list