检查指针句柄是否有效

时间:2015-03-04 16:01:46

标签: c++ c multithreading thread-safety cryptoapi

我想实现一个Microsoft CryptographicServiceProvider库,目前我正在考虑如何处理我创建的上下文句柄的最佳方法。

我的问题是针对这种情况的,但设计方法可以用于其他情况。

我来自托管代码背景,而且我对C / C ++中的多线程指针处理不是百分之百。

一般来说,有两个函数负责句柄的创建和销毁(CryptAcquireContext,CryptReleaseContext),所有后续的CSP函数都使用由创建者函数返回的句柄。

我没有找到微软的任何具体信息或规范,它提供了一种设计方法或规则。但我与微软创建的其他CSP提供商进行了研究,以找出设计规则,即:

  • 功能必须是线程安全的
  • 线程之间不会共享上下文句柄
  • 如果上下文句柄无效,则返回错误

其他MS CSP Provider会将有效指针作为句柄返回,否则返回NULL。

我不认为调用应用程序会传递完整的垃圾,但是它可能会传递一个已经释放的句柄,我的库应该返回错误。

这让我有三个想法如何实现:

  1. 只需使用malloc或new分配我的上下文结构的内存,并将原始指针作为句柄返回。

    我可以预期调用我的库的应用程序将传递一个有效的句柄。但如果不是我的库将遇到一个未定义的行为。所以我需要一个更好的解决方案。

  2. 将我创建的指针添加到列表中(std :: list,std :: map)。所以我可以迭代列表来检查指针是否存在。对列表的访问受到互斥锁的保护。

    这应该是安全的,并且常规的API使用不应该是性能问题。但在终端服务器方案中它可能是。在这种情况下,Windows进程lsass.exe为每个想要在单独线程中登录CSP上下文的用户创建,并为每个上下文进行大约10次API调用。

    设计目标是我的库应该能够并行处理300个客户端。在这种情况下,我不知道Windows创建了多少个线程。

    因此,如果可能的话,我更喜欢无锁实现。

  3. 我分配一个基本结构,它包含一个检查值和实际数据的指针。使用此结构的指针作为上下文句柄。

    typedef struct CSPHandle  
    {  
        int Type; // (eg. magic number CSPContext=0xA1B2C3D4)  
        CSPContextPtr pCSPContext;  
    };
    

    所以我可以读取传递指针的第一个字节,并检查数据是否等于我定义的类型。我对实际数据指针有完全的控制权,如果上下文被释放则设置为NULL。这是好主意还是坏主意?

  4. 您对此案有何看法?我应该采用其中一种方法还是有其他解决方案?

    由于

1 个答案:

答案 0 :(得分:0)

我找到了解决方案,并将回答我的问题。

我忽略了一点但很重要的细节

在CSP中,没有对dll的直接API调用(加载库,获取函数指针,调用函数),因为函数调用由Microsoft CSP转发,后者按名称加载CSP库。

因此Microsoft CSP需要知道并检查传递的上下文以获得到特定库的正确映射。

例:
1. client-> cryptacquirecontext( in cspname, out ctx)
2. MS CSP->从cspname中加载libray 3. MS CSP->调用已加载库的函数指针 4. CSP LIB-> cryptacquirecontext创建新的上下文
5. MS CSP->接收返回的csp句柄并将其保存到dll映射
6. MS CSP->将结果返回给调用应用程序
7. client-> cryptsetprovparam(ctx)//在之前创建的 8. MS CSP->检查上下文是否存在以及哪个库负责 9. MS CSP->如果给定的上下文无法映射到csp dll,则会返回错误,因为MS CSP不知道应该调用哪个函数指针。

所以在这种情况下,分配内存就足够了。如果客户端应用程序传递了无效的上下文句柄,它将永远不会访问csp库。

我认为MS CSP使用带有互斥锁的列表来存储上下文映射。因为上下文可以是从随机数到有效指针的任何内容。

相关问题