locked
Problems with custom Cryptographic Service Provider RRS feed

  • Question

  • Hi all!
    I'm writting a custom cryptographic service provider and some problems are occurring.
    Firtly i wrote all the CSP calling the CryptoAPI. So, it's using the standard Windows csp (in this case, Microsoft Base Cryptographic Provider v1.0). It works.
    I type all the fields that is necessary and then i click to create the certificate.
    It works fine and then, it apears to Install the Certificate. I click it and then it install on "my store" location.
    Everything is ok. But i don't want to install in "my store" location.
    So I google it and found that i must implement the csp using my own contexts. I wrote that and then i found that in the function: "CPGetProvParam" with the flag: "PP_NAME" i must return my custom csp name. I did that and them it shows an error:

    "An error occurred while creating the certificate request. Please verify that you selected the correct CSP, or contact an administrator for assistance. 
      
     
    Suggested cause:
    No suggestion.
    Error: 0x80070715 - (unknown) "

    I've made a log and here is the order of the functions that are called:

    "DllMain
    CPAcquireContext(0, aa8b1a8e-d606-41f7-9fc8-09cdc8002cb9, CRYPT_NEWKEYSET, pVTable)
    A crypto context with the aa8b1a8e-d606-41f7-9fc8-09cdc8002cb9 key container has been acquired.

    CPGetProvParam(2212160, PP_NAME, 00000000, 0, 0)

    CPGetProvParam(2212160, PP_NAME, 0022ED48, 8, 0)

    CPGetProvParam(2212160, PP_UNIQUE_CONTAINER, 00000000, 0, 0)

    CPGetProvParam(2212160, PP_UNIQUE_CONTAINER, 0018ACA0, 70, 0)

    CPGetProvParam(2212160, PP_PROVTYPE, 0013B560, 4, 0)

    CPGetUserKey(2212160, AT_KEYEXCHANGE, phUserKey)

    CPDestroyKey(2212160, 2289672)

    CPGetUserKey(2212160, AT_KEYEXCHANGE, phUserKey)

    CPExportKey(2212160, 2289672, 0, PUBLICKEYBLOB, 0, 00000000, 0)

    CPExportKey(2212160, 2289672, 0, PUBLICKEYBLOB, 0, 001F4DE8, 148)

    CPDestroyKey(2212160, 2289672)

    CPGetUserKey(2212160, AT_KEYEXCHANGE, phUserKey)

    CPExportKey(2212160, 2289672, 0, PUBLICKEYBLOB, 0, 00000000, 0)

    CPExportKey(2212160, 2289672, 0, PUBLICKEYBLOB, 0, 001F4DE8, 148)

    CPDestroyKey(2212160, 2289672)

    CPGetProvParam(2212160, PP_ENUMALGS_EX, 0013B4A0, 88, CRYPT_FIRST)

    CPGetProvParam(2212160, PP_ENUMALGS, 0013B4F8, 32, CRYPT_FIRST)

    CPGetProvParam(2212160, PP_NAME, 00000000, 1293680, 0)
    CPGetProvParam(2212160, PP_NAME, 00208C20, 8, 0)

    Erro: 0.
    CPReleaseContext"

    I want to implement a csp that access a webservice, and then, the webservice access a HSM to do all the cryptographic services. Generate a Token, the key, gen hash and then sign hash.
    And i don't want to save the certificate in the my store, i want to send it to the webservice and store there!


    When i put the name of my custom csp in the function CPGetProvParam with the flag PP_NAME, it sends that error. But, if i put the name of another CSP, it works. I don't know what to do exactly. I don't know what's wrong. Please, any help will be welcome!!!
    • Moved by lucy-liu Monday, May 16, 2011 5:51 AM it is not related c++ (From:Visual C++ General)
    Tuesday, May 10, 2011 8:50 PM

All replies

  • Well, i don't know what part exactly you want to see, but i'll paste here my CPGetProvParam and CPAcquireContext.

    BOOL WINAPI
    CPAcquireContext(
        OUT HCRYPTPROV *phProv,
        IN  LPCSTR szContainer,
        IN  DWORD dwFlags,
        IN  PVTableProvStruc pVTable)
    {
        // LOG //
        char str_flags[1024];
        CPAcquireContext_flags2str(str_flags, dwFlags);   
        char chBuffer[1024];    
        sprintf(chBuffer, "CPAcquireContext(%lu, %s, %s, pVTable)\r\n", *phProv, szContainer, str_flags);
        escreverNoLog(chBuffer);
        // LOG //
       
        BOOL resp = false;
       
        LPCTSTR pszContainerName = (LPCTSTR)szContainer;

        if(CryptAcquireContext(phProv, (LPCTSTR)szContainer, NULL, PROV_RSA_FULL, 0))
        {
            resp = true;
            sprintf(chBuffer, "A crypto context with the %s key container has been acquired.\r\n", pszContainerName);
            escreverNoLog(chBuffer);
        }
        else
        {
            //-----------------------------------------------------------
            // Some sort of error occurred in acquiring the context.
            // This is most likely due to the specified container
            // not existing. Create a new key container.
            if(GetLastError() == NTE_BAD_KEYSET)
            {
                if(CryptAcquireContext(phProv, (LPCTSTR)szContainer, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
                {

                    resp = true;
                    sprintf(chBuffer, "A new key container called %s has been created.\r\n", pszContainerName);
                    escreverNoLog(chBuffer);
                }
                else
                {
                    sprintf(chBuffer, "%s", "Erro ao tentar criar o container.\r\n");
                    escreverNoLog(chBuffer);
                }
            }
            else
            {

               escreverNoLog("CryptAcquireContext Failed. \r\n");
            }
        }

        escreverNoLog("\r\n");

        return resp;

    }

    BOOL WINAPI
    CPGetProvParam(
        IN  HCRYPTPROV hProv,
        IN  DWORD dwParam,
        OUT LPBYTE pbData,
        IN OUT LPDWORD pcbDataLen,
        IN  DWORD dwFlags)
    {
        // LOG
        char str_flags[1024];
        char str_param[1024];
        CPGetProvParam_flags2str(str_flags, dwFlags);   
        CPGetProvParam_param2str(str_param, dwParam);   
        char chBuffer[1024];    

        sprintf(chBuffer, "CPGetProvParam(%lu, %s, %p, %lu, %s)\r\n",
            hProv, str_param, pbData, *pcbDataLen, str_flags);
        escreverNoLog(chBuffer);
        // LOG

        bool resp = false;

        if(dwParam == PP_NAME)
        {
            escreverNoLog("Entrou no pp_name \r\n");
            if(pbData == NULL)
                *pcbDataLen = strlen("Csp Bry") + 1;
            else
                sprintf((char *)pbData, "%s", "Csp Bry");
            resp = true;
        }
        else
        {
            if(CryptGetProvParam(hProv, dwParam, pbData, pcbDataLen, 0))
            {
                escreverNoLog("CryptGetProvParam succeeded \r\n");
                resp = true;
            }
            else
            {
                escreverNoLog("Erro get prov param\r\n");
            }
        }

        escreverNoLog("\r\n");
        return resp;
    }

     

    So, when i let this code, it doesn't work. If I change the "Csp Bry" to  "Microsoft Base Cryptographic Provider v1.0", "Gemplus GemSAFE Card CSP v1.0" or a safenet csp and it works!

    I'm using Windows XP SP3, i've patched the advapi32.dll and using Microsoft Active Directory Certificate Services to test.

    I don't know if i'm creating a wrong type of dll or something else. Actually, i'm stucked. hehe

    Wednesday, May 11, 2011 11:17 AM
  • First time i try to establish the connection with an existing container. If it's not created, i call again passing the flag "CRYPT_NEWKEYSET" to create.

    But this is not the final implementation. Firstly i'm doing some tests to know if some conditions can be met.

    Here they are:

    1 - Make a CSP using call to CryptoAPI

    2 - Try to open a form during CPAcquireContext to get some user data

    3 - Try to access a webservice during the CPSignHash, CPHashData, CPGenKey and some others functions

    4 - After the certificate generation, controll the location to install it. Don't need to install in My Store (Windows repository), but need to send it to the webservice.

     

    I made the 1, 2 and 3. But i'm stucked in 4.

    I know more or less what i have to do. But it's not working...  =(

    Wednesday, May 11, 2011 1:26 PM
  • Maybe i'm not clear enough.

    There are 2 proccess when you require a certificate in a Certificate Autority site. Firtly the generation and then the installation.

    When you're in the proccess of generation, you can select what CSP you want to use. So i select my custom CSP. I fill some data needed to the certificate and then click to generate it.

    Inside the proccess, it call many methods of CSP and one of them is CPGetProvParam. I don't have sure, but i imagine that when it call for the second time the CPGetProvParam with PP_NAME, it's getting the name of the csp and them using it to write on the requestInfo. Because the next proccess, the instalation, it should call again this csp.

    And then it makes the hash, sign and etc.

    After that, the certificate is generated. It apears a link button to install the certificate. When i click it, it should use the csp i passed in the CPGetProvParam, in this case, my custom CSP.

    But when i made the code, changing the name to my custom csp, it breaks the second time of the CPGetProvParam. So, it fails to create the certificate for some reason. If i pass another name, as i said, like microsoft standard csp or another csp (like GemPlus), it works.

    Another test i made was: change the Image Path of GemPlus CSP in the register to my custom csp path and it don't works too... So my doubt is: Am i doing the wrong type of dll?

    I need to register my csp in a different way?

    Because i think it's accessing the dll but some breaks and then stop the generation of the certificate.

     

    Wednesday, May 11, 2011 1:52 PM
  • But i need to use the CSP as a DLL.

    There problem is: in the first call to the provider, it breaks in the fourth call to CPGetProvParam with PP_NAME.

    So it doesn't generate the certificate and them i can't call the second time the provider.

    During the proccess of generation the certificate, it gives the error:


    "An error occurred while creating the certificate request. Please verify that you selected the correct CSP, or contact an administrator for assistance. 
      
     
    Suggested cause:
    No suggestion.
    Error: 0x80070715 - (unknown) "

     

    And i don't know what error is this. I google it and spent many hours, but i can't find anything.

    Wednesday, May 11, 2011 2:14 PM
  • Hi rickls,

    I am moving this thread from “Visual C++ General" forum to the “Security for Applications in Microsoft Windows” forum. Since the issue is related to Windows Security. There are more experts in the “Security for Applications in Microsoft Windows” forum.

    Thank you for your understanding!

     

    Best regards,

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, May 16, 2011 5:50 AM
  • Hi rickls,

    I have the same problem. 

    Present your problems solved? If resolved, can u tell me the answer? Thanks very much.


    Thursday, January 12, 2012 2:25 AM
  • Have you found any solution related to this? I am trying to solve a similar kind of problem but don't know how to proceed?
    Tuesday, February 14, 2017 2:00 PM