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:[EMAIL PROTECTED] Sent: Friday, March 09, 2007 6:41 AM
To: '[email protected]'
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
[email protected]
http://www.aleksey.com/mailman/listinfo/xmlsec




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);
 
_______________________________________________
xmlsec mailing list
[email protected]
http://www.aleksey.com/mailman/listinfo/xmlsec

Reply via email to