Peter Koch <pk <at> opensc-project.org> writes:

> Could you post the relevant parts of your code or send it to me.

I use pkcscsp.2:

getPublicKeyFromX509Cert and getX509Value - it is functions from 
pkcscsp.2, defined in cryptool.cpp. 
TESTCRK, TESTBL - test return value, if fail throw exception.  

...

RSA* HandleContainer::GetRSAKey(HCRYPTKEY hKey){
        RSA *rsa = NULL; 
        try{
               CK_OBJECT_HANDLE hPubKey;
                TESTCRK(getPublicKeyFromX509Cert(currentPContainer-
>GetpFunctionList(),currentPContainer->GethSession(), &hPubKey, 
currentPContainer->Gethandle()));

                std::vector<CK_BYTE>value; CK_ULONG lenValue = 0;

                TESTCRK(getX509Value(currentPContainer->GetpFunctionList(), 
currentPContainer->GethSession(), hPubKey, NULL, &lenValue));
                value.resize(lenValue); TESTBL(value.size());
                ZeroMemory(&value.front(),(lenValue*sizeof(CK_BYTE)));
                TESTCRK(getX509Value(currentPContainer->GetpFunctionList(), 
currentPContainer->GethSession(), hPubKey, &value.front(), &lenValue));

                const unsigned char *pPbKeyBuf  = (const unsigned char 
*)&value.front(); 
                rsa = d2i_RSAPublicKey(NULL,&pPbKeyBuf, (long)lenValue); 
 
        }catch (std::logic_error &) {}
        return rsa;
}
//////////////////////////////////////////////////////////////////////////

BOOL HandleContainer::Encrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, 
DWORD dwFlags, BYTE* pbData, DWORD*pdwDataLen, DWORD dwBufLen){
        TRACE(__LINE__,"HandleContainer::Encrypt ",NULL);
        BOOL bRet = FALSE; RSA *rsa = NULL;
        try{
                TESTBL(pdwDataLen != NULL);
                RSA *rsa = GetRSAKey(hKey); TESTBL(rsa);
                int ex_size = RSA_size(rsa); 
                int max_in_size = ex_size - RSA_PKCS1_PADDING_SIZE;
                if(ex_size > dwBufLen || !pbData){
                        *pdwDataLen = ex_size;
                        bRet = TRUE;
                        TESTBL(false);
                }
                if(*pdwDataLen > max_in_size) TESTBL(false);

                std::vector<byte>retVec; retVec.resize(ex_size);
                int outlen  = RSA_public_encrypt(*pdwDataLen, pbData, 
&retVec.front(), rsa, RSA_PKCS1_PADDING);
                TESTBL(outlen != -1);
                memcpy(pbData,&retVec.front(),outlen);
                *pdwDataLen = outlen;
                bRet = TRUE;
                TRACE(__LINE__,"HandleContainer::ExportKey TRUE",NULL);
        }catch (std::logic_error &) {
                TRACE(__LINE__,"HandleContainer::ExportKey FALSE",NULL);
        }
        if(rsa) RSA_free(rsa);
        return bRet;
}

...

Question: what is limitation on size of pbData for successful decryption. 
I know, what for successful encryption, size of pbData must be less of equal 
max_in_size. On decryption for NetKey card max_in_size == 117 (ex_size == 128,  
RSA_PKCS1_PADDING_SIZE == 11), but if in RSA_public_encrypt *pdwDataLen > 114, 
then tcos decrypt adpu return error 0x6988 ("key object used for sm has invalid 
format").


> Could you try this with your SignTrust card and/or NetKey card.

Thanks! Problem was in incorrect certificate usage on DP card. Now 
encrypt\decrypt work  fine with your script sample and my code on both tcos 
cards on certificates which support encryption. 

Remain one problem - definition of input buffer size. 

By the way, I have alike problem with cardos card :( which use non-padding 
decryption (It fail on RSA_public_encrypt with error "key size too small or 
large", if I use RSA_NO_PADDING). Maybe openssl has capability of definition 
correct input key size (sorry for off-topic). In that way I can crypt only 
session key with needed size, which will be symmetric crypt data.


_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to