locked
Must CSP submitted to be signed have all 00 bytes in the 144 byte resource entry with tag 666 ? RRS feed

  • Question

  • RE: http://msdn.microsoft.com/en-us/library/aa388145(v=VS.85).aspx

    I submitted a CSP DLL which had non-zero bytes in the resource entry with 666. 

    Microsoft signed it, but it does not verify with cspsign d

    >cspsign d \windows\syswow64\thecsp.dll
    The Resource Signature does *NOT* verify.

    I'm wondering if the non-zero bytes was the cause of the problem, and exactly how this might have occuured.

    If the exact mechanism of the signature proces was described I might figure out what happened.  

    The verify of the signature hash cannot be be over all the bytes in the file, since that would include the signature itself.   So presumably the verify of the signature either omits the contents of the 666 resource, or replaces it with all 00 bytes.  If the signature verify process does operate like that, and the generation of the hash does operate over all bytes, not having 00 bytes would cause a signature problem.  Is my reasoning correct ?

     

     

    Thursday, June 30, 2011 7:16 PM

All replies

  • Hi,

    The tool cspsign can not verify the official Microsoft CSP signature. This tool is used only under Windows 2000 for producing test signature recognized by the test advapi32 dlls distributed by the CSPDK.

    So, it is normal to have this error reported by cspsign. You have to install your csp dll on a machine and call CryptAcquireContext to check if it is working. As for the signature itself, all what matters is the size of the resource entry (144 bytes), not the value of the original bytes.

    Cheers,
    --
    Mounir IDRASSI
    IDRIX
    http://www.idrix.fr


    Mounir IDRASSI - IDRIX - http://www.idrix.fr
    Sunday, July 3, 2011 9:27 PM
  • Thank you for the correction on cspsign.   I'm still having trouble getting CryptAcquireContext  to not return a NTE_BAD_SIGNATURE.

    Here is more information:

     

    The csp_http.dll as sent to Microsoft has this:

    Directory of C:\Users\Andrew\src2011\c++\math\csp_http\signing\as_sent (To Microsoft)
    06/30/2011 04:32 PM 753,664 csp_http.dll

    rb.getResource( RT_RCDATA, MAKEINTRESOURCE( 666 ) )

    00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 00 00

    _________________________________________________________________________________

    Microsoft returned the csp_http.dll with the same time-date stamp,

    Directory of C:\Users\Andrew\src2011\c++\math\csp_http\signing\microsoft_signed
    06/30/2011 04:32 PM 753,664 csp_http.dll

    Apparently Microsoft preserves the time-date stamp when adding the signature to resource 666.

    ( Beware that  Win7 unzip will trample the time-date stamp of zipped files from the internet unless you unblock the zip per http://support.microsoft.com/kb/942532/en-us )

    The new value in the signature resource of csp_http.dll is:


    rb.getResource( RT_RCDATA, MAKEINTRESOURCE( 666 ) )

    00 01 00 00 40 01 00 00

    fe 64 08 99 fa cb 10 17 0b d3 79 d7 c0 38 49 bd 4a 7d ff e8 a6 a6 12 21 96 c6 55 60 e0 fa e8 1e
    79 96 6e da 97 1a 8a c4 d1 35 52 90 e2 05 c2 e3 11 ea 9a be 8d 4e f1 d9 b7 0e 14 46 3a f3 83 e4
    e2 81 82 57 4b 61 5c d9 d0 69 c7 eb d1 9f 39 51 36 16 70 1f 5e 2f a1 5c bd e6 2b 93 39 e4 66 b7
    a4 2d 7f 27 ec c5 4d 9d 02 86 f5 51 e3 9c 48 4d b5 70 db d7 70 de bb 1c b7 de b8 e2 cb 4a be 6a

    00 00 00 00 00 00 00 00

    _________________________________________________________________________________

    And I copy that DLL to this

    Directory of C:\windows\syswow64
    06/30/2011 04:32 PM 753,664 csp_http.dll

     _____________________________

    I intend to use the signature in the DLL, so I don't do anything with the .sig file.


    csp_http.sig: signature sent by Microsoft

    aa 09 eb 50 af e5 66 2a c8 8b 11 c7 5c 15 a8 3e 1d 0d 40 af 9f bd 72 fe 3e a2 ac 59 a0 17 c6 68
    37 50 40 6b 29 9d aa 89 0d e3 68 14 c6 1e 04 a6 4a 26 6f a3 8f ec de f1 bd 32 ce ea 66 4d e4 f0
    ad d6 9e 35 df e1 ab ff 21 e3 87 7b e3 ec e4 fd 8b c6 d4 f6 95 20 cf ca 1b ae 5d 0f 4f a9 6f cc
    b6 d8 b9 89 e5 30 9b e3 f1 84 ef 94 ef ec 12 87 ac 25 67 bd a1 b6 87 99 d6 4c ac 50 47 6e c2 74
    00 00 00 00 00 00 00 00

    _____________________________

    My registry entry is:


    HKEY_LOCAL_MACHINE
       SOFTWARE

    Wow6432Node
          Microsoft
             Cryptography
                Defaults
                   Provider
                      CSP name = csp_http
                         Type       = 0x00000001                                                  #define PROV_RSA_FULL 1
                         SigInFile  = 0x00000001
                         Image Path = C:\Windows\SysWow64\csp_http.dll

     

    From http://msdn.microsoft.com/en-us/library/aa387481(v=VS.85).aspx

    The CSP name key is the name of the CSP.

    The Type value is a REG_DWORD that contains the numeric type identifier of the CSP. This value is one of the PROV_* values defined in Wincrypt.h.

    The SigInFile value is a REG_DWORD value that contains a Boolean value that indicates whether the digital signature for the CSP is contained in a file or in the registry. If this value contains zero, the signature is contained in the registry in the Signature value. If the SigInFile value is not zero, then the signature is contained in the provider module specified by the Image Path value.

    The Signature value is a binary BLOB that contains the digital signature for the CSP. This value is only used if the SigInFile value is zero.

    The Image Path value is a REG_SZ value that contains the name of the CSP module. For security reasons, the name must be specified using a fully qualified path, such as "C:\Myx\Rsabase.dll". If a relative path is specified, Windows may fail to load the CSP in some situations.

    If SigInFile is not zero, this file contains the digital signature as a Windows resource. For more information about containing the signature in a Windows resource, see Test Signing the CSP.

     

     

     

    And then I run this code to check the signature:


     // Generate a list of all CSP providers on the system.
     //
     void listProviders( std::ostream & out )
     {
      out << "List of CSP providers: " << std::endl;

      TCHAR      pszName[999];
      DWORD      dwType, cbName= 999;

      DWORD i= 0;
      
      while ( ::CryptEnumProviders( i++, NULL, 0, &dwType, pszName, &cbName) ) {
       out << "\t" << pszName << std::endl;
       cbName= 999;
      }
     }

     void check( std::ostream & out )
     {
      listProviders( out );

      HCRYPTPROV csp;
      TCHAR * keyContainer= (TCHAR *)NULL;


      if ( ! ::CryptAcquireContext( &csp, keyContainer, "csp_http", PROV_RSA_FULL, 0 ) ) {

             LineWinError::showError( out, ::GetLastError() );                // ::GetLastError() returns NTE_BAD_SIGNATURE
       
             return;
      }


      out << "::CryptAcquireContext() worked" << std::endl;  

      ::CryptReleaseContext( csp, 0 );
     }

     

    The output is:

    "List of CSP providers:
     csp_http
     Microsoft Base Cryptographic Provider v1.0
     Microsoft Base DSS and Diffie-Hellman Cryptographic Provider
     Microsoft Base DSS Cryptographic Provider
     Microsoft Base Smart Card Crypto Provider
     Microsoft DH SChannel Cryptographic Provider
     Microsoft Enhanced Cryptographic Provider v1.0
     Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider
     Microsoft Enhanced RSA and AES Cryptographic Provider
     Microsoft RSA SChannel Cryptographic Provider
     Microsoft Strong Cryptographic Provider
    NTE_BAD_SIGNATURE (Bad Signature?) " 

     

    I observe that the CSP was detected, but not able to be acquired.

    So I'm still perplexed.

    Some possibilities that occur to me:

    1) The NTE_BAD_SIGNATURE error is misleading, perhaps something else is wrong which leads to a signature error being reported. 

    2) Something about the 64 bit registry entry in SysWow64 causes a problem.

    3) Something is wrong with the program that calls CryptAcquireContext

     

    Is there a way to check the signature without using CryptAcquireContext ?

     

    Any hints or experience welcome !

     


    • Edited by Andrew7Webb Wednesday, July 6, 2011 6:18 PM
    Wednesday, July 6, 2011 6:07 PM
  • Hi,

    There is something strange in the value of the signature in the resources: in all signed CSP dlls I have seen in my life along with signed Microsoft CSP distributed with Windows XP (rsaenh.dll), the value of the signature in the resources starts with "00 01 00 00 50 01 00 00" whereas yours starts with "00 01 00 00 40 01 00 00". The fifth byte in your embedded signature seems wrong compared with usual value 0x50.

    The safest solution in your situation is to put the signature in the registry: remove the registry value SignInFile and put the content of the .sig file in the registry value Signature.
    You can also try to change the signature in the resources in order to set its fifth byte to 0x50 and see if this solves the signature verification failure.

    If neither of these suggestions solves your issue, then probably your binaries have been corrupted in a way or another.

    I hope this will help.
    Cheers,
    --
    Mounir IDRASSI
    IDRIX
    http://www.idrix.fr


    Mounir IDRASSI - IDRIX - http://www.idrix.fr
    Wednesday, July 6, 2011 10:47 PM
  • -- Odd about that "00 01 00 00 40 01 00 00" header. I wonder if it is documented anywhere?

    But the good news is that I went past the signature error.

    When I created the registry entries, the characters that were actually present were:   Image path = "C:\Windows\SysWow64\csp_http.dll"

    Notice the lower case "p" in Path, and the "Quotes" around the string.

    And many apologies, when I wrote the previous post, my brain copied them back to be shown as the correct values !

    Perhaps that mistake should have resulted in a FILE NOT found, or WRONG_PARAMETER error rather than a signature error, but such is life.

    Thursday, July 7, 2011 1:02 AM
  • Happy to see that you've finally got it working! And thanks to this mistake, I know now of another possible value for the CSP signature header...


    Mounir IDRASSI - IDRIX - http://www.idrix.fr
    Thursday, July 7, 2011 10:33 AM
  • There is a structure in cspdk.h which seems to define the CSP signature header:


    typedef struct {
        DWORD dwVersion;
        DWORD dwCrcOffset;
        BYTE rgbSignature[88];  // 1024-bit key, plus 2 DWORDs of padding.
    } InFileSignatureResource;

    So now we can decode the header as:

    rb.getResource( RT_RCDATA, MAKEINTRESOURCE( 666 ) )

    00 01 00 00       // DWORD dwVersion;    Little endian 0x100  ==   version  1.00

    40 01 00 00       // DWORD dwCrcOffset;  LIttle endian 0x140 ==   offset of a CRC in ?? 

    fe 64 08 99 fa cb 10 17 0b d3 79 d7 c0 38 49 bd 4a 7d ff e8 a6 a6 12 21 96 c6 55 60 e0 fa e8 1e             // BYTE rgbSignature[88]; // 1024-bit key,
    79 96 6e da 97 1a 8a c4 d1 35 52 90 e2 05 c2 e3 11 ea 9a be 8d 4e f1 d9 b7 0e 14 46 3a f3 83 e4
    e2 81 82 57 4b 61 5c d9 d0 69 c7 eb d1 9f 39 51 36 16 70 1f 5e 2f a1 5c bd e6 2b 93 39 e4 66 b7
    a4 2d 7f 27 ec c5 4d 9d 02 86 f5 51 e3 9c 48 4d b5 70 db d7 70 de bb 1c b7 de b8 e2 cb 4a be 6a

    00 00 00 00   // plus 2 DWORDs of padding.

    00 00 00 00

     

    There seems to be a mistake in the size of BYTE rgbSignature[88]  for a 1024-bit key.

    After removing the 8 bytes of padding, they allocate 80 bytes for a 1024 bit signature.

    But 80 bytes is only 640 bits, not 1024.

    Most likely Microsoft actually meant to allocate 0x80 == 128 which would be 1024 bits.

    So it should be  BYTE rgbSignature[ (1024/8) + 2*sizeof(DWORD) ]; // 1024-bit key, 


    Saturday, July 9, 2011 2:56 PM
  • I'm devloping my own CSP. Can anyone provide Microsoft's e-mail address for signing CSP. What information (besides CSP dll) do I need to send?

    And second question: does CSP signature work on Win7? Because 1) CSPDK is meant for Win2k and earlier, 2) all default CSPs (like rsaenh.dll) don't have signature neither in dll resource (it containts zeroed 144 bytes), nor in Registry. And still MS CSPs work well... is there some other way of verification in Win7?

    Wednesday, January 16, 2013 8:26 AM
  • Hi,

    You dll must be sent to cspsign@microsoft.com. If you want your email to be correctly processed, you have to include contact information about your company (address, telephone...) and the detailed capabilities of your CSP (algorithms, key size, storage..). The first time you send your complete request, you must expect some delay because they do some checks about the company information you supplied.

    Concerning your second question, yes the CSP signature is still mandatory for Windows 7 and Windows 8, and it is still working (a CSP dll signed for XP, will work for 7 and 8). Unfortunately, Microsoft never updated their CSPDK beyong Windows 2000, so in order to test you CSP under Windows XP and above, you have to either rely on a Kernel Debugger in order to deactivate signature checking or using a patched Advapi32 dll (or cryptsp.dll for Windwos 7 and Windows 8). I have been publishing these patches for years now, you can find them using Google or by going to my blog http://blog.idrassi.com and looking for the post with the tag CSP.

    For the default CSPs (rsaenh.dll), they indeed don't contain the usual signature resource but their binaries are digitally signed with a Microsoft Authenticode certificate dedicated to critical Windows components and the OS is checking this signature using the WinTrust API. Unfortunately, Microsoft didn't extend this mechanism to non Microsoft components.

    Cheers,
    --
    Mounir IDRASSI
    IDRIX
    http://www.idrix.fr


    Mounir IDRASSI - IDRIX - http://www.idrix.fr

    Thursday, January 31, 2013 10:17 PM
  • Mounir, thank you a lot for your detailed answer and you blog! Can you please describe in short the process of finding out which bytes and how to patch (and what dlls) in order to disable CSP signature checking? Did you use some tools like IDA (Interactive DisAssembler) for reverse engineering?
    Monday, March 4, 2013 8:32 AM
  • I am developing csp.dll

    I have a same problem under windows 7.

    if you have a good solution, please, let me know~~

    Tuesday, July 16, 2013 7:10 AM