OpenCSP开源程序解析之OPENCSP_Main.cpp

#include "OPENCSP_define.h"
#include "OPENCSP_Keyset.h"
#include "OPENCSP_Provider.h"
#include ".\opencsp_cardaccess.h"

#pragma data_seg("_OPENCSP_SHARED")
/*
    Two variables are used to OPENCSP_UserMutext
*/
DWORD g_sharedProcessID = 0;                                
LONG  g_lock = 0;
/*
    Used to share info between multi-process
*/
SHARED_KEYSET_INFO_LIST g_sharedKeysetInfo; 
#pragma data_seg()
#pragma comment(linker,"/section:_OPENCSP_SHARED,RWS")

HINSTANCE g_hModule = NULL;

BOOL WINAPI
DllMain(// handle to the DLL module  DLL句柄,表示DLL被映射到进程地址空间内的虚拟地址
  HINSTANCE hinstDLL,  
  DWORD fdwReason,     // reason for calling function   系统为什么调用该函数
  LPVOID lpvReserved)  // reserved
{

    /*当新建一个进程时,系统为该进程分配了地址空间,之后将EXE文件和
    所需要的DLL文件都映射到进程的地址空间。
    之后系统创建了进程的主线程,并使用这个主线程来调用每一个DLL中的DLLMain函数,
    传递给DLLMain函数的参数fdwReason的值是DLL_PROCESS_ATTACH*/

    switch(fdwReason)
    {
    case DLL_PROCESS_ATTACH:         //当这个DLL被映射到了进程的地址空间时
        {
//禁用指定的DLL的DLL_THREAD_ATTACH和DLL_THREAD_DETACH通知,这样可以减小某些程序的工作集大小。
            DisableThreadLibraryCalls(hinstDLL);
            g_hModule = hinstDLL;
        }
        break;
    case DLL_PROCESS_DETACH:         //这个DLL从进程的地址空间中解除映射
        {
            /* clear key set instances, if they are not referred */
            SHARED_KEYSET_INFO_LIST::iterator itr = g_sharedKeysetInfo.begin();
            for (; itr != g_sharedKeysetInfo.end(); itr++)
            {
                if (itr->_refCount == 0)
                {
                    OPENCSP_Keyset::clearKeysetInstance(itr->_keysetName);
                    g_sharedKeysetInfo.erase(itr);
                }
            }
        }
        break;
    default:
        break;
    }

    return TRUE;
}


/*
-  CPAcquireContext
-
*  Purpose:
*               The CPAcquireContext function is used to acquire a context
*               handle to a cryptographic service provider (CSP).
*
*
*  Parameters:
*               OUT phProv         -  Handle to a CSP
*               IN  szContainer    -  Pointer to a string which is the
*                                     identity of the logged on user
*               IN  dwFlags        -  Flags values
*               IN  pVTable        -  Pointer to table of function pointers
*
*  Returns:
*/

BOOL WINAPI
CPAcquireContext(                                  //获取指定CSP的密钥容器的句柄
                 OUT HCRYPTPROV *phProv,   //CSP模块句柄指针
                 IN  LPCSTR szContainer,   //指定容器的名称
                 IN  DWORD dwFlags,
                 IN  PVTableProvStruc pVTable)
{
    DWORD fOK = S_OK;
    KEYSET_NAME kn, readerName, keysetName, knTmp;

    if (dwFlags & ~(CRYPT_SILENT|CRYPT_VERIFYCONTEXT|CRYPT_NEWKEYSET|
        CRYPT_MACHINE_KEYSET|CRYPT_DELETEKEYSET))//dwFlags是其中一种或多种
    {
        fOK = NTE_BAD_FLAGS;
        goto END;
    }

    // newkeyset and deletekeyset cannot co-exist!
    if ((dwFlags & CRYPT_NEWKEYSET) && (dwFlags & CRYPT_DELETEKEYSET) ||
        (dwFlags & CRYPT_NEWKEYSET) && (dwFlags & CRYPT_VERIFYCONTEXT))
    {
        fOK = NTE_BAD_FLAGS;
        goto END;
    }

    // Four cases:
    // 1) NULL
    // 2) MyLogin
    // 3) "\\.\My USB Reader 0 or \\.\My USB Reader 0\"
    // 4) "\\.\My USB Reader 0\MyLogin"

    if (szContainer == NULL)
        kn = TEXT("");
    else
        kn = szContainer;

    size_t p = kn.find(TEXT("\\\\.\\"));
    if (p == 0)
    {
        // reader exists
        knTmp = kn.substr(4); //strip off "\\\\.\\" string here
        p = knTmp.find(TEXT("\\"));
        if (p != KEYSET_NAME::npos)
        {
            keysetName = knTmp.substr( p + 1);
            readerName = kn.substr(4, p);
        }
        else
        {
            readerName = knTmp.substr(0);
            keysetName[0] = TEXT('\0');
        }
    }
    else
    {
        if (kn.find(TEXT("\\")) != KEYSET_NAME::npos)
        {
            fOK = NTE_BAD_KEYSET_PARAM;
            goto END;
        }
        readerName[0] = TEXT('\0');
        keysetName = kn.substr(0);
    }

    if (dwFlags & CRYPT_MACHINE_KEYSET) 
        dwFlags ^= CRYPT_MACHINE_KEYSET; // strip the flag off

    if (dwFlags & CRYPT_DELETEKEYSET)
    {
        // delete the key set
        BOOL bSilent = FALSE;
        if (dwFlags & CRYPT_SILENT) bSilent = TRUE;
        fOK = OPENCSP_Keyset::deleteKeyset(readerName, keysetName, bSilent);
    }
    else
    {
        // open or create key set now!
        fOK = OPENCSP_Keyset::getKeyset(readerName, keysetName, dwFlags, *phProv);
    }

END:
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-      CPReleaseContext
-
*      Purpose:
*               The CPReleaseContext function is used to release a
*               context created by CryptAcquireContext.
*
*     Parameters:
*               IN  phProv        -  Handle to a CSP
*               IN  dwFlags       -  Flags values
*
*  Returns:
*/

BOOL WINAPI
CPReleaseContext(                        //释放由CPAcquireContext获得的句柄
                 IN  HCRYPTPROV hProv,
                 IN  DWORD dwFlags)
{
    UNREFERENCED_PARAMETER(dwFlags);

    DWORD fOK = OPENCSP_Keyset::release(hProv);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPGenKey
-
*  Purpose:
*                Generate cryptographic keys
*
*
*  Parameters:
*               IN      hProv   -  Handle to a CSP
*               IN      Algid   -  Algorithm identifier
*               IN      dwFlags -  Flags values
*               OUT     phKey   -  Handle to a generated key
*
*  Returns:
*/

BOOL WINAPI
CPGenKey(                              //生成一个密钥,根据算法和属性
         IN  HCRYPTPROV hProv,
         IN  ALG_ID Algid,     //要产生密钥的算法,可以是对称密钥,也可以是非对称密钥对
         IN  DWORD dwFlags,    //指定密钥的属性
         OUT HCRYPTKEY *phKey)   //产生的密钥句柄
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->genKey(Algid, dwFlags, phKey);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPDeriveKey
-
*  Purpose:
*                Derive cryptographic keys from base data
*
*
*  Parameters:
*               IN      hProv      -  Handle to a CSP
*               IN      Algid      -  Algorithm identifier
*               IN      hBaseData -   Handle to base data
*               IN      dwFlags    -  Flags values
*               OUT     phKey      -  Handle to a generated key
*
*  Returns:
*/

BOOL WINAPI
CPDeriveKey(                                   //从一基本数据值中派生会话密钥
            IN  HCRYPTPROV hProv,  //CSP 句柄
            IN  ALG_ID Algid,  //要产生密钥的对称加密算法
            IN  HCRYPTHASH hHash,  //哈希对象的句柄
            IN  DWORD dwFlags,   //指定密钥的类型
            OUT HCRYPTKEY *phKey)  //指定密钥的类型
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    SetLastError(E_NOTIMPL);
    return TRUE;
}


/*
-  CPDestroyKey
-
*  Purpose:
*                Destroys the cryptographic key that is being referenced
*                with the hKey parameter
*
*
*  Parameters:
*               IN      hProv  -  Handle to a CSP
*               IN      hKey   -  Handle to a key
*
*  Returns:
*/

BOOL WINAPI
CPDestroyKey(                           //释放密钥句柄
             IN  HCRYPTPROV hProv,
             IN  HCRYPTKEY hKey)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->destroyKey(hKey);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPSetKeyParam
-
*  Purpose:
*                Allows applications to customize various aspects of the
*                operations of a key
*
*  Parameters:
*               IN      hProv   -  Handle to a CSP
*               IN      hKey    -  Handle to a key
*               IN      dwParam -  Parameter number
*               IN      pbData  -  Pointer to data
*               IN      dwFlags -  Flags values
*
*  Returns:
*/

BOOL WINAPI 
CPSetKeyParam(                               //设置密钥的各种参数
              IN  HCRYPTPROV hProv,
              IN  HCRYPTKEY hKey,
              IN  DWORD dwParam,     //指定查询的参数
              IN  CONST BYTE *pbData,  //指向接收数据的缓冲区指针
              IN  DWORD dwFlags)    //根据dwParam不同设定不同值
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->setKeyParam(hKey, dwParam, pbData, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPGetKeyParam
-
*  Purpose:
*                Allows applications to get various aspects of the
*                operations of a key
*
*  Parameters:
*               IN      hProv      -  Handle to a CSP
*               IN      hKey       -  Handle to a key
*               IN      dwParam    -  Parameter number
*               OUT     pbData     -  Pointer to data
*               IN      pdwDataLen -  Length of parameter data
*               IN      dwFlags    -  Flags values
*
*  Returns:
*/

BOOL WINAPI
CPGetKeyParam(                      //获得密钥的各种参数
              IN  HCRYPTPROV hProv,
              IN  HCRYPTKEY hKey,
              IN  DWORD dwParam,
              OUT LPBYTE pbData,        //指向接收数据的缓冲区指针
              IN OUT LPDWORD pcbDataLen,   //指出pbData 数据长度
              IN  DWORD dwFlags)  //根据dwParam不同设定不同值
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->getKeyParam(hKey, dwParam, pbData, pcbDataLen, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPSetProvParam
-
*  Purpose:
*                Allows applications to customize various aspects of the
*                operations of a provider
*
*  Parameters:
*               IN      hProv   -  Handle to a CSP
*               IN      dwParam -  Parameter number
*               IN      pbData  -  Pointer to data
*               IN      dwFlags -  Flags values
*
*  Returns:
*/

BOOL WINAPI
CPSetProvParam(                          //设置CSP 的各种参数
               IN  HCRYPTPROV hProv,
               IN  DWORD dwParam,          //指定查询的参数
               IN  CONST BYTE *pbData,    //指向接收数据的缓冲区指针
               IN  DWORD dwFlags)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->setProvParam(dwParam, pbData, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPGetProvParam
-
*  Purpose:
*                Allows applications to get various aspects of the
*                operations of a provider
*
*  Parameters:
*               IN      hProv      -  Handle to a CSP
*               IN      dwParam    -  Parameter number
*               OUT     pbData     -  Pointer to data
*               IN OUT  pdwDataLen -  Length of parameter data
*               IN      dwFlags    -  Flags values
*
*  Returns:
*/

BOOL WINAPI
CPGetProvParam(                          //获得CSP 的各种参数
               IN  HCRYPTPROV hProv,
               IN  DWORD dwParam,              //指定查询的参数
               OUT LPBYTE pbData,            //指向接收数据的缓冲区指针
               IN OUT LPDWORD pcbDataLen,    //指出pbData 数据长度
               IN  DWORD dwFlags)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->getProvParam(dwParam, pbData, pcbDataLen, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPSetHashParam
-
*  Purpose:
*                Allows applications to customize various aspects of the
*                operations of a hash
*
*  Parameters:
*               IN      hProv   -  Handle to a CSP
*               IN      hHash   -  Handle to a hash
*               IN      dwParam -  Parameter number
*               IN      pbData  -  Pointer to data
*               IN      dwFlags -  Flags values
*
*  Returns:
*/

BOOL WINAPI
CPSetHashParam(                   //设置哈希句柄的各种参数
               IN  HCRYPTPROV hProv,
               IN  HCRYPTHASH hHash,
               IN  DWORD dwParam,           //指定设置的参数
               IN  CONST BYTE *pbData,     //指向接收数据的缓冲区指针
               IN  DWORD dwFlags)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->setHashParam(hHash, dwParam, pbData, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPGetHashParam
-
*  Purpose:
*                Allows applications to get various aspects of the
*                operations of a hash
*
*  Parameters:
*               IN      hProv      -  Handle to a CSP
*               IN      hHash      -  Handle to a hash
*               IN      dwParam    -  Parameter number
*               OUT     pbData     -  Pointer to data
*               IN      pdwDataLen -  Length of parameter data
*               IN      dwFlags    -  Flags values
*
*  Returns:
*/

BOOL WINAPI
CPGetHashParam(                             //获得哈希句柄的各种参数
               IN  HCRYPTPROV hProv,
               IN  HCRYPTHASH hHash,
               IN  DWORD dwParam,
               OUT LPBYTE pbData,
               IN OUT LPDWORD pcbDataLen,
               IN  DWORD dwFlags)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->getHashParam(hHash, dwParam, pbData, pcbDataLen, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPExportKey
-
*  Purpose:
*                Export cryptographic keys out of a CSP in a secure manner
*
*
*  Parameters:
*               IN  hProv         - Handle to the CSP user
*               IN  hKey          - Handle to the key to export
*               IN  hPubKey       - Handle to exchange public key value of
*                                   the destination user
*               IN  dwBlobType    - Type of key blob to be exported
*               IN  dwFlags       - Flags values
*               OUT pbData        -     Key blob data
*               IN OUT pdwDataLen - Length of key blob in bytes
*
*  Returns:
*/

BOOL WINAPI
CPExportKey(                               //把密钥以KEY BLOB形式导出 
            IN  HCRYPTPROV hProv,
            IN  HCRYPTKEY hKey,     //被导出的密钥
            IN  HCRYPTKEY hPubKey,  //用来加密的公钥句柄
            IN  DWORD dwBlobType,    //导出KEY BLOB的类型
            IN  DWORD dwFlags,  
            OUT LPBYTE pbData,      //导出KEY BLOB的地址
            IN OUT LPDWORD pcbDataLen)   //导出KEY BLOB的长度
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->exportKey(hKey, hPubKey, dwBlobType, dwFlags, pbData, pcbDataLen);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPImportKey
-
*  Purpose:
*                Import cryptographic keys
*
*
*  Parameters:
*               IN  hProv     -  Handle to the CSP user
*               IN  pbData    -  Key blob data
*               IN  dwDataLen -  Length of the key blob data
*               IN  hPubKey   -  Handle to the exchange public key value of
*                                the destination user
*               IN  dwFlags   -  Flags values
*               OUT phKey     -  Pointer to the handle to the key which was
*                                Imported
*
*  Returns:
*/

BOOL WINAPI
CPImportKey(                //把KEY BLOB导入CSP中
            IN  HCRYPTPROV hProv,
            IN  CONST BYTE *pbData,
            IN  DWORD cbDataLen,    //导入KEY BLOB的长度
            IN  HCRYPTKEY hPubKey,  //用来加密的公钥句柄
            IN  DWORD dwFlags,
            OUT HCRYPTKEY *phKey)   //导入的密钥句柄
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->importKey(pbData, cbDataLen, hPubKey, dwFlags, phKey);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPEncrypt
-
*  Purpose:
*                Encrypt data
*
*
*  Parameters:
*               IN  hProv         -  Handle to the CSP user
*               IN  hKey          -  Handle to the key
*               IN  hHash         -  Optional handle to a hash
*               IN  Final         -  Boolean indicating if this is the final
*                                    block of plaintext
*               IN  dwFlags       -  Flags values
*               IN OUT pbData     -  Data to be encrypted
*               IN OUT pdwDataLen -  Pointer to the length of the data to be
*                                    encrypted
*               IN dwBufLen       -  Size of Data buffer
*
*  Returns:
*/

BOOL WINAPI
CPEncrypt(                 //使用指定加密密钥来加密一段明文
          IN  HCRYPTPROV hProv,
          IN  HCRYPTKEY hKey,
          IN  HCRYPTHASH hHash, 
          IN  BOOL fFinal,    //是否是最后一次加密操作
          IN  DWORD dwFlags,
          IN OUT LPBYTE pbData,  //需要加密数据的地址
          IN OUT LPDWORD pcbDataLen,
          IN  DWORD cbBufLen)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->encrypt(hKey, hHash, fFinal, dwFlags, pbData, pcbDataLen, cbBufLen);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPDecrypt
-
*  Purpose:
*                Decrypt data
*
*
*  Parameters:
*               IN  hProv         -  Handle to the CSP user
*               IN  hKey          -  Handle to the key
*               IN  hHash         -  Optional handle to a hash
*               IN  Final         -  Boolean indicating if this is the final
*                                    block of ciphertext
*               IN  dwFlags       -  Flags values
*               IN OUT pbData     -  Data to be decrypted
*               IN OUT pdwDataLen -  Pointer to the length of the data to be
*                                    decrypted
*
*  Returns:
*/

BOOL WINAPI
CPDecrypt(                         //使用指定加密密钥来解密一段密文
          IN  HCRYPTPROV hProv,
          IN  HCRYPTKEY hKey,
          IN  HCRYPTHASH hHash,
          IN  BOOL fFinal,
          IN  DWORD dwFlags,
          IN OUT LPBYTE pbData,
          IN OUT LPDWORD pcbDataLen)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->decrypt(hKey, hHash, fFinal, dwFlags, pbData, pcbDataLen);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPCreateHash
-
*  Purpose:
*                initate the hashing of a stream of data
*
*
*  Parameters:
*               IN  hUID    -  Handle to the user identifcation
*               IN  Algid   -  Algorithm identifier of the hash algorithm
*                              to be used
*               IN  hKey   -   Optional handle to a key
*               IN  dwFlags -  Flags values
*               OUT pHash   -  Handle to hash object
*
*  Returns:
*/

BOOL WINAPI
CPCreateHash(                       //根据算法创建哈希句柄
             IN  HCRYPTPROV hProv,
             IN  ALG_ID Algid,  //要产生密钥的算法,可以是对称密钥,也可以是非对称密钥对
             IN  HCRYPTKEY hKey,
             IN  DWORD dwFlags,
             OUT HCRYPTHASH *phHash)  //产生的哈希句柄
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->createHash(Algid, hKey, dwFlags, phHash);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPHashData
-
*  Purpose:
*                Compute the cryptograghic hash on a stream of data
*
*
*  Parameters:
*               IN  hProv     -  Handle to the user identifcation
*               IN  hHash     -  Handle to hash object
*               IN  pbData    -  Pointer to data to be hashed
*               IN  dwDataLen -  Length of the data to be hashed
*               IN  dwFlags   -  Flags values
*
*  Returns:
*/

BOOL WINAPI
CPHashData(                  //往哈希句柄填充数据
           IN  HCRYPTPROV hProv,
           IN  HCRYPTHASH hHash,
           IN  CONST BYTE *pbData,
           IN  DWORD cbDataLen,
           IN  DWORD dwFlags)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->hashData(hHash, pbData, cbDataLen, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPHashSessionKey
-
*  Purpose:
*                Compute the cryptograghic hash on a key object.
*
*
*  Parameters:
*               IN  hProv     -  Handle to the user identifcation
*               IN  hHash     -  Handle to hash object
*               IN  hKey      -  Handle to a key object
*               IN  dwFlags   -  Flags values
*
*  Returns:
*               CRYPT_FAILED
*               CRYPT_SUCCEED
*/

BOOL WINAPI
CPHashSessionKey(             //往哈希句柄填充密钥句柄
                 IN  HCRYPTPROV hProv,
                 IN  HCRYPTHASH hHash,
                 IN  HCRYPTKEY hKey,   //填充到哈希对象中的密钥句柄
                 IN  DWORD dwFlags)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->hashSessionKey(hHash, hKey, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPSignHash
-
*  Purpose:
*                Create a digital signature from a hash
*
*
*  Parameters:
*               IN  hProv        -  Handle to the user identifcation
*               IN  hHash        -  Handle to hash object
*               IN  dwKeySpec    -  Key pair to that is used to sign with
*               IN  sDescription -  Description of data to be signed
*               IN  dwFlags      -  Flags values
*               OUT pbSignature  -  Pointer to signature data
*               IN OUT dwHashLen -  Pointer to the len of the signature data
*
*  Returns:
*/

BOOL WINAPI
CPSignHash(                  //用指定私钥对哈希值进行数字签名
           IN  HCRYPTPROV hProv,
           IN  HCRYPTHASH hHash,
           IN  DWORD dwKeySpec,   //指定密钥对属性
           IN  LPCTSTR szDescription,  //哈希对象描述
           IN  DWORD dwFlags,
           OUT LPBYTE pbSignature,  //指向签名结果的缓冲区指针
           IN OUT LPDWORD pcbSigLen)  //签名结果的长度
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->signHash(hHash, dwKeySpec, szDescription, dwFlags, pbSignature, pcbSigLen);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPDestroyHash
-
*  Purpose:
*                Destroy the hash object
*
*
*  Parameters:
*               IN  hProv     -  Handle to the user identifcation
*               IN  hHash     -  Handle to hash object
*
*  Returns:
*/

BOOL WINAPI
CPDestroyHash(                      //销毁哈希句柄
              IN  HCRYPTPROV hProv,
              IN  HCRYPTHASH hHash)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->destroyHash(hHash);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPVerifySignature
-
*  Purpose:
*                Used to verify a signature against a hash object
*
*
*  Parameters:
*               IN  hProv        -  Handle to the user identifcation
*               IN  hHash        -  Handle to hash object
*               IN  pbSignture   -  Pointer to signature data
*               IN  dwSigLen     -  Length of the signature data
*               IN  hPubKey      -  Handle to the public key for verifying
*                                   the signature
*               IN  sDescription -  String describing the signed data
*               IN  dwFlags      -  Flags values
*
*  Returns:
*/

BOOL WINAPI
CPVerifySignature(                  //用指定私钥对签名值进行签名验证
                  IN  HCRYPTPROV hProv,
                  IN  HCRYPTHASH hHash,
                  IN  CONST BYTE *pbSignature,  //签名结果的缓冲区指针
                  IN  DWORD cbSigLen,   //签名结果的长度
                  IN  HCRYPTKEY hPubKey,  //用于签名验证的公钥句柄
                  IN  LPCTSTR szDescription,  //哈希对象描述
                  IN  DWORD dwFlags)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->verifySignature(hHash, pbSignature, cbSigLen, hPubKey, 
        szDescription, dwFlags);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPGenRandom
-
*  Purpose:
*                Used to fill a buffer with random bytes
*
*
*  Parameters:
*               IN  hProv         -  Handle to the user identifcation
*               IN  dwLen         -  Number of bytes of random data requested
*               IN OUT pbBuffer   -  Pointer to the buffer where the random
*                                    bytes are to be placed
*
*  Returns:
*/

BOOL WINAPI
CPGenRandom(              // 根据指定长度产生随机数
            IN  HCRYPTPROV hProv,
            IN  DWORD cbLen,  //需要产生的随机数长度
            OUT LPBYTE pbBuffer)
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->genRandom(cbLen, pbBuffer);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPGetUserKey
-
*  Purpose:
*                Gets a handle to a permanent user key
*
*
*  Parameters:
*               IN  hProv      -  Handle to the user identifcation
*               IN  dwKeySpec  -  Specification of the key to retrieve
*               OUT phUserKey  -  Pointer to key handle of retrieved key
*
*  Returns:
*/

BOOL WINAPI
CPGetUserKey(                    //获得密钥对句柄
             IN  HCRYPTPROV hProv,
             IN  DWORD dwKeySpec,  //密钥对属性
             OUT HCRYPTKEY *phUserKey)   //密钥的句柄
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->getUserKey(dwKeySpec, phUserKey);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPDuplicateHash
-
*  Purpose:
*                Duplicates the state of a hash and returns a handle to it.
*                This is an optional entry.  Typically it only occurs in
*                SChannel related CSPs.
*
*  Parameters:
*               IN      hUID           -  Handle to a CSP
*               IN      hHash          -  Handle to a hash
*               IN      pdwReserved    -  Reserved
*               IN      dwFlags        -  Flags
*               IN      phHash         -  Handle to the new hash
*
*  Returns:
*/

BOOL WINAPI
CPDuplicateHash(            //复制哈希
                IN  HCRYPTPROV hProv,
                IN  HCRYPTHASH hHash,
                IN  LPDWORD pdwReserved,
                IN  DWORD dwFlags,
                OUT HCRYPTHASH *phHash)   //目标哈希句柄
{   
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    DWORD fOK = provider->duplicateHash(hHash, pdwReserved, dwFlags, phHash);
    if (fOK != S_OK)
    {
        SetLastError(fOK);
        return FALSE;
    }

    return TRUE;
}


/*
-  CPDuplicateKey
-
*  Purpose:
*                Duplicates the state of a key and returns a handle to it.
*                This is an optional entry.  Typically it only occurs in
*                SChannel related CSPs.
*
*  Parameters:
*               IN      hUID           -  Handle to a CSP
*               IN      hKey           -  Handle to a key
*               IN      pdwReserved    -  Reserved
*               IN      dwFlags        -  Flags
*               IN      phKey          -  Handle to the new key
*
*  Returns:
*/

BOOL WINAPI
CPDuplicateKey(              //密钥和密钥状态的复制
               IN  HCRYPTPROV hProv,
               IN  HCRYPTKEY hKey,  //源密钥句柄
               IN  LPDWORD pdwReserved,
               IN  DWORD dwFlags,
               OUT HCRYPTKEY *phKey) //目标密钥句柄
{
    OPENCSP_Provider* provider = OPENCSP_Keyset::findProvider(hProv);
    if (!provider)
    {
        SetLastError(NTE_BAD_UID);
        return FALSE;
    }

    SetLastError(E_NOTIMPL);

    return TRUE;
}

//-----------------------------------------------------------------------------------
static HMODULE GetInstanceHandle( void );

STDAPI DllUnregisterServer(void)
{
    LONG nStatus;
    HKEY hProviders = NULL;
    DWORD dwDisp;

    nStatus = RegCreateKeyEx(            //创建指定的注册键。如果这个键已经存在,打开它
        HKEY_LOCAL_MACHINE,
        TEXT("SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider"),
        0,
        TEXT(""),
        REG_OPTION_NON_VOLATILE,
        KEY_ALL_ACCESS,
        NULL,
        &hProviders,
        &dwDisp);
    if (ERROR_SUCCESS == nStatus)
    {
        RegDeleteKey(hProviders, s_szProviderName);
        RegCloseKey(hProviders);
        hProviders = NULL;
    }
    return S_OK;
}

STDAPI DllRegisterServer(void)
{
    LONG nStatus;
    TCHAR szModulePath[MAX_PATH];
    HRESULT hReturnStatus = NO_ERROR;
    HKEY hProviders = NULL;
    HKEY hMyCsp = NULL;
    DWORD dwDisp;
    DWORD dwStatus = 0;

    nStatus = RegCreateKeyEx(
        HKEY_LOCAL_MACHINE,
        TEXT("SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider"),
        0,
        TEXT(""),
        REG_OPTION_NON_VOLATILE,
        KEY_ALL_ACCESS,
        NULL,
        &hProviders,
        &dwDisp);
    if (ERROR_SUCCESS != nStatus)
    {
        hReturnStatus = HRESULT_FROM_WIN32(nStatus);
        goto ErrorExit;
    }

    nStatus = RegCreateKeyEx(
        hProviders,
        s_szProviderName,
        0,
        TEXT(""),
        REG_OPTION_NON_VOLATILE,
        KEY_ALL_ACCESS,
        NULL,
        &hMyCsp,
        &dwDisp);
    if (ERROR_SUCCESS != nStatus)
    {
        hReturnStatus = HRESULT_FROM_WIN32(nStatus);
        goto ErrorExit;
    }
    nStatus = RegCloseKey(hProviders);
    hProviders = NULL;
    if (ERROR_SUCCESS != nStatus)
    {
        hReturnStatus = HRESULT_FROM_WIN32(nStatus);
        goto ErrorExit;
    }

    /* Image Path */
    dwStatus = GetModuleFileName(GetInstanceHandle(), szModulePath, 
        sizeof(szModulePath) / sizeof(TCHAR));//获取一个已加载模块的文件路径
    if (0 == dwStatus)
    {
        hReturnStatus = HRESULT_FROM_WIN32(GetLastError());
        goto ErrorExit;
    }

    nStatus = RegSetValueEx(
        hMyCsp,
        TEXT("Image Path"),
        0,
        REG_SZ,
        (LPBYTE)szModulePath,
        (lstrlen(szModulePath) + 1) * sizeof(TCHAR));
    if (ERROR_SUCCESS != nStatus)
    {
        hReturnStatus = HRESULT_FROM_WIN32(nStatus);
        goto ErrorExit;
    }

    /* Type */
    nStatus = RegSetValueEx(    //在注册表项下设置指定值的数据和类型
        hMyCsp,
        TEXT("Type"),
        0,
        REG_DWORD,
        (LPBYTE)&s_dwCspType,
        sizeof(DWORD));
    if (ERROR_SUCCESS != nStatus)
    {
        hReturnStatus = HRESULT_FROM_WIN32(nStatus);
        goto ErrorExit;
    }

    /* SigInFile */
    dwStatus = 0;
    nStatus = RegSetValueEx(
        hMyCsp,
        TEXT("SigInFile"),
        0,
        REG_DWORD,
        (LPBYTE)&dwStatus,
        sizeof(DWORD));
    if (ERROR_SUCCESS != nStatus)
    {
        hReturnStatus = HRESULT_FROM_WIN32(nStatus);
        goto ErrorExit;
    }

ErrorExit:
    if (hProviders)
    {
        RegCloseKey(hProviders);
    }

    if (hMyCsp)
        RegCloseKey(hMyCsp);

    return hReturnStatus;
}


static HINSTANCE GetInstanceHandle(void)
{
    return g_hModule;
}

你可能感兴趣的:(opencsp)