My own cng signature provider don't work.

Unanswered My own cng signature provider don't work.

  • Thursday, November 17, 2011 2:15 PM
     
     

    Hello!

    I wrote my own CNG provider. Register my provider as described in CNG SDK. Then, if I want view my custom certificate in Windows certificate view window by double clicking on mycert.cer I see that sequence of function calls

    GetSignatureInterface with right my provider name and right pszAlgId.

    OpenSignatureProvider with right pszAlgId

    GetProperty with pszProperty="ObjectLength". Then i return ObjectLength size.

    GetProperty with pszProperty="HashDigestLength". BUT WHY "HashDigestLength"? This is signature only provider?

    If I return my hash digest length (i have registered my own hash provider) or any data - then I can't see any calls of my cng provider.

    If I return STATUS_NOT_SUPPORTED, then i see CloseSignatureProvider.

    After that I see another sequence of calls:

    GetSignatureInterface with right my provider name and right pszAlgId.

    OpenSignatureProvider with right pszAlgId

    GetProperty with pszProperty="ObjectLength". Then I return ObjectLength size.

    GetProperty with pszProperty="HashDigestLength". I return STATUS_NOT_SUPPORTED

    CloseSignatureProvider.

    What I’m doing wrong? Help please!

    • Edited by hbchome Friday, November 18, 2011 5:23 AM
    • Edited by hbchome Friday, November 18, 2011 5:24 AM
    • Edited by hbchome Friday, November 18, 2011 5:24 AM
    •  

All Replies

  • Tuesday, November 29, 2011 7:01 AM
     
     

    Here is some details.

    I'm trying to register:

    id-GostR3411-94-with-GostR3410-2001 OBJECT IDENTIFIER ::=
             { iso(1) member-body(2) ru(643) rans(2) cryptopro(2)
               gostR3411-94-with-gostR3410-2001(3) } signature algorithm. This algorithm described in RFC 4491 section 2.2.3.

    Also i trying to register:

    id-GostR3410-2001 OBJECT IDENTIFIER ::=
           { iso(1) member-body(2) ru(643) rans(2) cryptopro(2)
               gostR3410-2001(19) } for public keys.

    There GostR3410-2001-PublicKeyParameters ::=
            SEQUENCE {
                publicKeyParamSet
                    OBJECT IDENTIFIER,
                digestParamSet
                    OBJECT IDENTIFIER,
                encryptionParamSet
                    OBJECT IDENTIFIER DEFAULT
                        id-Gost28147-89-CryptoPro-A-ParamSet
            }

    As described in sec. 2.3.2.

     

    This is my registration sequence:


    FOR HASH.

    pInterfaceReg = &InterfaceReg;

    FunctionsArray[0] = FUNCTION_NAME_HASH;

     

    InterfaceReg.dwInterface = BCRYPT_HASH_INTERFACE;

    InterfaceReg.dwFlags = 0;

    InterfaceReg.cFunctions = 1;

    InterfaceReg.rgpszFunctions = FunctionsArray;

    ImageReg.pszImage = L

    "MyHashProv.dll"; //provider dll

     

    ImageReg.cInterfaces = 1;

    //only one interface - hash
     

    ImageReg.rgpInterfaces = &pInterfaceReg;

     

    CPR.pUM = &ImageReg;

    if

     

    (!NT_SUCCESS(status=BCryptRegisterProvider(MY_HASH_PROVIDER_NAME,

    CRYPT_OVERWRITE,&CPR)))

    {

    wprintf(L

    "**** Error 0x%x returned by BCryptAddContextFunctionProvider\n"

    , status);

     

    return

    0;

    }

     

     

     

    if

    (!NT_SUCCESS(status = BCryptAddContextFunctionProvider(

    CRYPT_LOCAL,

    NULL,

    BCRYPT_HASH_INTERFACE,

    FUNCTION_NAME_HASH,

    MY_HASH_PROVIDER_NAME,

    CRYPT_PRIORITY_TOP)))

    {

    wprintf(L

    "**** Error 0x%x returned by BCryptAddContextFunctionProvider\n"

    , status);

     

    return

    0;

    }

     

     

    CRYPT_OID_INFO oidInfo;

     

    int

    rc = 0;

    memset(&oidInfo, 0,

    sizeof

    (CRYPT_OID_INFO));

    oidInfo.cbSize =

    sizeof

    (CRYPT_OID_INFO);

    oidInfo.pszOID=

    "1.2.643.2.2.9"

    ;

    oidInfo.pwszName= L

    "GOST-3411-94 HASH"

    ;

    oidInfo.dwGroupId = CRYPT_HASH_ALG_OID_GROUP_ID;

    oidInfo.Algid = CALG_OID_INFO_CNG_ONLY ;

    oidInfo.pwszCNGAlgid = FUNCTION_NAME_HASH;

    rc = CryptRegisterOIDInfo( &oidInfo, CRYPT_INSTALL_OID_INFO_BEFORE_FLAG );

     

    if

    (!rc)

    {

    wprintf(L

    "**** Error returned by CryptRegisterOIDInfo\n"

    , status);

     

    return

    0;

    }

     


    FOR SIGN AND PUBKEY:

    pInterfaceReg = &InterfaceReg;

    FunctionsArray[0] = FUNCTION_NAME_SIGN;

    FunctionsArray[1] = FUNCTION_NAME_PUBKEY;

    InterfaceReg.dwInterface = BCRYPT_SIGNATURE_INTERFACE;

    InterfaceReg.dwFlags = 0;

    InterfaceReg.cFunctions = 2;

    InterfaceReg.rgpszFunctions = FunctionsArray;

    ImageReg.pszImage = L

    "MySignProv.dll";

    //provider dll

    ImageReg.cInterfaces = 1;

     

    ImageReg.rgpInterfaces = &pInterfaceReg;

     

    CPR.pUM = &ImageReg;

     

     

    if

    (!NT_SUCCESS(status=BCryptRegisterProvider(MY_SIGNATURE_PROVIDER_NAME,

    CRYPT_OVERWRITE,&CPR)))

    {

    wprintf(L

    "**** Error 0x%x returned by BCryptAddContextFunctionProvider\n"

    , status);

     

    return

    0;

    }

     

    if

    (!NT_SUCCESS(status = BCryptAddContextFunctionProvider(

    CRYPT_LOCAL,

    NULL,

    BCRYPT_SIGNATURE_INTERFACE,

    FUNCTION_NAME_SIGN,

    MY_SIGNATURE_PROVIDER_NAME,

    CRYPT_PRIORITY_TOP)))

    {

    wprintf(L

    "**** Error 0x%x returned by BCryptAddContextFunctionProvider\n"

    , status);

     

    return

    0;

    }

     

     

    if

    (!NT_SUCCESS(status = BCryptAddContextFunctionProvider(

    CRYPT_LOCAL,

    NULL,

    BCRYPT_SIGNATURE_INTERFACE,

    FUNCTION_NAME_PUBKEY,

    MY_SIGNATURE_PROVIDER_NAME,

    CRYPT_PRIORITY_TOP)))

    {

    wprintf(L

    "**** Error 0x%x returned by BCryptAddContextFunctionProvider\n"

    , status);

     

    return

    0;

    }

     

     

     

    CRYPT_OID_INFO oidInfo;

     

    intrc = 0;

    memset(&oidInfo, 0, sizeof(CRYPT_OID_INFO));

    oidInfo.cbSize =

    sizeof(CRYPT_OID_INFO);

    oidInfo.pszOID=

    "1.2.643.2.2.19";

    oidInfo.pwszName= L

    "GOST-3410-2001 PUBKEY";

    oidInfo.dwGroupId = CRYPT_PUBKEY_ALG_OID_GROUP_ID;

    oidInfo.Algid = CALG_OID_INFO_CNG_ONLY;

    oidInfo.pwszCNGAlgid = FUNCTION_NAME_PUBKEY;

     

     

     

    rc = CryptRegisterOIDInfo( &oidInfo, CRYPT_INSTALL_OID_INFO_BEFORE_FLAG);

     

    if

    (!rc)

    {

    wprintf(L

    "**** Error returned by CryptRegisterOIDInfo\n"

    , status);

     

    return

    0;

    }

     

    const

    DWORD aiECCPubKey = CALG_OID_INFO_PARAMETERS;

     

    memset(&oidInfo, 0,

    sizeof

    (CRYPT_OID_INFO));

    oidInfo.cbSize =

    sizeof

    (CRYPT_OID_INFO);

    oidInfo.pszOID=

    "1.2.643.2.2.3"

    ;

    oidInfo.pwszName= L

    "GOST-3410-2001 SIGN"

    ;

    oidInfo.dwGroupId = CRYPT_SIGN_ALG_OID_GROUP_ID;

    oidInfo.Algid = CALG_OID_INFO_CNG_ONLY ;

    oidInfo.pwszCNGAlgid =FUNCTION_NAME_HASH;

    oidInfo.pwszCNGExtraAlgid= FUNCTION_NAME_PUBKEY;

     

    rc = CryptRegisterOIDInfo( &oidInfo, CRYPT_INSTALL_OID_INFO_BEFORE_FLAG);

     

    if

    (!rc)

    {

    wprintf(L

    "**** Error returned by CryptRegisterOIDInfo\n"

    , status);

     

    return

    0;

    }

    At this time I see my pwszNames in CertView dialog in right places, including Hash algorithm name, but can't see any calls of my providers :(

  • Friday, May 25, 2012 1:25 PM
     
     

    1) No need to register hash OID and "pubkey" OID. Registering with group=CRYPT_SIGN_ALG_OID_GROUP_ID is enough for signing and verification.

    2) Maybe you have another entry registered for your OID? Try to enum them with "CryptEnumOIDInfo" function or see "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\<Your OID>\".

    For 32-bit mode applications it is located in "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\OID\EncodingType 0\CryptDllFindOIDInfo\<Your OID>\".

    In that case, if another entry have inverted CNG ids of hash algorithm and signature algorithm, the result will be the same as you described.