robotk <robotk_at_163.com> writes:
> suggest a new feature: adding smart card support to windows svn client in
> version 1.5
Search for "smartcard" in http://svn.collab.net/repos/svn/trunk/CHANGES,
you will see it's in upcoming 1.5.0.
-Karl
> Hi:
>   Maybe someone have posted this suggestion before, and the Linux build now can
> support smart card thanks to Joe Orton's greate work(http://svn.haxx.se/users/
> archive-2008-04/0377.shtml).
>   I think it is not difficult to implement this feature on windows. Last month,
> we made an effort to implement smart card authentication by using Microsoft's
> CSP and openSSL library. We found that it is simple to manipulate the smart
> card by CSP API. Microsoft's CSP is a software interface standard. Almost all
> the smart card manufacturers support this standard and provide the software
> realization(dll).  The CSP standard allows us to use the public-private key
> pair to encrypt,decrypt data and sign message digest while know nothing about
> the hardware details. All the CSPs are registered in HKEY_LOCAL_MACHINE\
> SOFTWARE\Microsoft\Cryptography\Defaults\Provider. This page(http://
> msdn.microsoft.com/en-us/library/aa380245%28VS.85%29.aspx) describes the CSP in
> detail.
>   Most smart card manufacturers also provide a standards-based PKCS#11 library.
> PKCS#11(http://www.rsa.com/rsalabs/node.asp?id=2133) is a cryptographic token
> interface standard developed by RSA laboratories. It is the counterpart of
> Microsoft's CSP. PuTTY, openVPN and some other software on windows platform use
> PKCS#11 instead of CSP. The specifications of the PKCS#11 standard are
> described in ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20.pdf.
>  
> The following are several typical examples of using CSP API. (without error
> handling)
> All the CSP APIs are declared in header file wincrypt.h.
> 1. Enumerate all the certificates stored in USB KEY:
>     #include <wincrypt.h>
>     #pragma comment(lib, "crypt32.lib")
>     HCRYPTPROV hCryptProv = NULL;
>     CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
> CRYPT_VERIFYCONTEXT);
>     HCERTSTORE hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0,
> hCryptProv, CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
>     // just access to the publicly available information, the CSP would not ask
> for a PIN
>     PCCERT_CONTEXT pCertContext = NULL;
>     while (1)
>    {
>      pCertContext = CertEnumCertificatesInStore (hCertStore, pCertContext);
>      if (!pCertContext) break;
>      //suppose the maximum length of all the fileds doesn't exceed 512
>      const int iMaxFldLen = 512;
>      char szSubjectName[iMaxFldLen]={0}, szIssuerName[iMaxFldLen]={0};
>      // get common name,
>      CertGetNameString (pCertContext, CERT_NAME_ATTR_TYPE, NULL,
> szOID_COMMON_NAME, szSubjectName, iMaxFldLen);
>      // get issuer name
>      CertGetNameString (pCertContext, CERT_NAME_ATTR_TYPE,
> CERT_NAME_ISSUER_FLAG,
>               szOID_COMMON_NAME, szIssuerName, iMaxFldLen);
>      printf ("%s %s\n", szSubjectName, szIssuerName);
>      // get the CSP name and key container name
>      char szContName[iMaxFldLen]={0}, szProvName[iMaxFldLen]={0}, pvData
> [iMaxFldLen]={0};
>      DWORD cbData = iMaxFldLen;
>      CertGetCertificateContextProperty (pCertContext,
> CERT_KEY_PROV_INFO_PROP_ID, pvData, &cbData);
>      CRYPT_KEY_PROV_INFO* pProvInfo = (CRYPT_KEY_PROV_INFO *)pvData;
>      sprintf (szContName, "%S", pProvInfo->pwszContainerName);
>      sprintf (szProvName, "%S", pProvInfo->pwszProvName);
>    
>      printf ("%s %s\n", szContName, szProvName);
>      // get other fields of the X509 certificate
>      // ...
>     }
>     CryptReleaseContext (hCryptProv, 0); // release the handle
>
> 2. Using private key stored in the USB KEY to sign the digest of message
>     #include <wincrypt.h>
>     #pragma comment(lib, "crypt32.lib")
>     // the container name and CSP name can be retrieved in example 1
>     // char szContName[] = {"61aecdd2-65b4-4919-a56c-0b2f5f7833d1"};
>     // char szProvName[] = {"SafeSign CSP Version 1.0"};
>     char szMsg[] = {"something"};
>     DWORD dwMsgLen = strlen(szMsg);
>     HCRYPTPROV hCryptProv = NULL;
>     CryptAcquireContext (&hCryptProv, szContName, szProvName, PROV_RSA_FULL,
> 0);
>     HCRYPTHASH hHash = NULL;
>     CryptCreateHash (hCryptProv, CALG_MD5, 0, 0, &hHash);
>     CryptHashData (hHash, (BYTE*)szMsg, dwMsgLen, 0);
>     DWORD dwSignLen = 0;
>     CryptSignHash (hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSignLen);
>     char* szSignBuf = (char*) malloc(dwSignLen*sizeof(char));
>     if (!CryptSignHash (hHash, AT_SIGNATURE, NULL, 0, (BYTE*)szSignBuf, &
> dwSignLen))
>     {
>       printf ("CryptSignHash failed\n");
>     }
>     else
>     {
>       printf ("CryptSignHash done\n");
>     }
>   
>     free (szSignBuf);
>     CryptReleaseContext (hCryptProv, 0); // release the handle
>
> 3. Using private key to decrypt the ciphertext encrypted by the public key
>     #include <wincrypt.h>
>     #pragma comment(lib, "crypt32.lib")
>     // the container name and CSP name can be retrieved in example 1
>     // char szContName[] = {"61aecdd2-65b4-4919-a56c-0b2f5f7833d1"};
>     // char szProvName[] = {"SafeSign CSP Version 1.0"};
>     char pEncryptedData[] = {"top secret encrypted by public key"};
>     DWORD dwEncryptDataLen = strlen(pEncryptedData);
>     HCRYPTPROV hCryptProv = NULL;
>     CryptAcquireContext (&hCryptProv, szContName, szProvName, PROV_RSA_FULL,
> 0);
>     HCRYPTKEY hUserKey = NULL;
>     BOOL bRet= CryptGetUserKey (hCryptProv, AT_KEYEXCHANGE, &hUserKey);
>     // pEncryptedData point to the ciphertext encrypted by the public key and
>     // dwEncryptDataLen is the length of the ciphertext
>     if (!CryptDecrypt(hUserKey, 0, true, 0, (BYTE*)pEncryptedData, &
> dwEncryptDataLen))
>     {
>       // CryptDecrypt() will failed if the pEncryptedData was NOT
>       // encrypted by the corresponding public key
>       printf ("CryptDecrypt failed\n");
>     }
>     else
>     {
>       printf ("CryptDecrypt done\n");
>     }
>     // now pEncryptedData point to plaintext and
>     // dwEncryptDataLen is the length of the plaintext
>     CryptReleaseContext (hCryptProv, 0);
>  
>  
>  
> Thanks
>  
> Setven Zhang
>
>
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
> 上房老大买二手房,看实景照片,挑专业经纪人
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-06-12 09:54:34 CEST