Closed yebin-yu closed 6 months ago
void SM2_gmSig2OpensslSig(ECCSIGNATUREBLOB *sigBlob, unsigned char **sig, size_t *len) { BIGNUM *rB=NULL; BIGNUM *sB=NULL; BYTE *r = sigBlob->r+32; BYTE *s = sigBlob->s+32; rB = BN_bin2bn(r, 32, NULL); if(rB == NULL) {return NULL;} sB = BN_bin2bn(s, 32, NULL); if(sB == NULL) {return NULL;} ECDSA_SIG *ecdsaSig = ECDSA_SIG_new(); if (ecdsaSig == NULL) {return NULL;} if(ECDSA_SIG_set0(ecdsaSig, rB, sB) != 1) { return NULL; } unsigned char* sig_temp = NULL; int sigLen = i2d_ECDSA_SIG(ecdsaSig, sig); // *sig = sig_temp; printf("%s", *sig); *len = sigLen; } static int init_ukey_container(HCONTAINER *hcontainer) { HANDLE hdev = NULL; ULONG ulRslt = SAR_OK; // 枚举获取设备名,这里的逻辑应该是自动获取然后赋值 // ukey上获取到的值应该为:3DC2105010CFD4C62A42E5375DA38B9 char szDevName[256] = {0}; ULONG ulDevNameLen = 256; ulRslt = SKF_EnumDev(TRUE, szDevName, &ulDevNameLen); printf("szDevName: %s \n", szDevName); if (ulRslt != SAR_OK) { debug("SKF_EnumDev ERROR \n"); return 1; } // 连接设备 ulRslt = SKF_ConnectDev(szDevName, &hdev); if (ulRslt != SAR_OK) { debug("SKF_ConnectDev ERROR \n"); return 1; } // 获取application,这里的逻辑应该是自动获取然后赋值 // ukey上获取到的值应该为:GM3000RSA char appName[256] = {0}; ULONG appnameLen = 256; ulRslt = SKF_EnumApplication(hdev, appName, &appnameLen); printf("appName: %s\n", appName); if (ulRslt != SAR_OK) { debug("SKF_EnumApplication ERROR \n"); return 1; } // 打开应用 HANDLE happ; ulRslt = SKF_OpenApplication(hdev, appName, &happ); if (ulRslt != SAR_OK) { debug("SKF_OpenApplication ERROR \n"); return 1; } // 验证pin码 char pinStr[32]; ULONG retryCntMax = 3; ULONG currentRetryCnt = 0; printf("UKEY pin:"); scanf("%s", pinStr); ulRslt = SKF_VerifyPIN(happ, USER_TYPE, pinStr, &retryCntMax); while (ulRslt != SAR_OK && currentRetryCnt++ < retryCntMax) { sleep(2); // 防止暴力破解,等待两秒 printf("UKEY pin again:"); scanf("%s", pinStr); ulRslt = SKF_VerifyPIN(happ, USER_TYPE, pinStr, &retryCntMax); } if (ulRslt != SAR_OK) { debug("SKF_VerifyPIN ERROR \n"); return 1; } // 获取容器名 // ukey上获取到的值应该为:sm2 char containerName[256] = {0}; ULONG containerNameLen = 256; ulRslt = SKF_EnumContainer(happ, containerName, &containerNameLen); printf("containerName: %s\n", containerName); if (ulRslt != SAR_OK) { debug("SKF_EnumContainer ERROR \n"); return 1; } // 打开容器 ulRslt = SKF_OpenContainer(happ, containerName, hcontainer); if (ulRslt != SAR_OK) { debug("SKF_OpenContainer ERROR \n"); return 1; } return SAR_OK; } static int ukey_get_sig(const u_char *data, size_t datalen, u_char **sig, size_t *slen, struct sshkey *sign_key) { // get container handle ULONG ulRslt = SAR_OK; HCONTAINER container = NULL; if (init_ukey_container(&container) != 0) { debug("init_ukey_container ERROR \n"); return 1; } // hash unsigned char hashRslt[32] = {0}; int hashLen; if(1 != EVP_Digest(data, datalen, hashRslt, &hashLen, EVP_sm3(), NULL, sign_key)) { debug("EVP_Digest ERROR \n"); return 1; } // sign ECCSIGNATUREBLOB stSign = {0}; ulRslt = SKF_ECCSignData(container, hashRslt, hashLen, &stSign); if (ulRslt != SAR_OK) { debug("SKF_ECCSignData ERROR \n"); return 1; } SM2_gmSig2OpensslSig(&stSign, sig, slen); return 0; }
其中 EVP_Digest 为:
EVP_Digest
int EVP_Digest(const void *data, size_t count, unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl, struct sshkey *sign_key) { EVP_MD_CTX *ctx = EVP_MD_CTX_new(); int ret; EVP_PKEY *key_sm2 = NULL; if ((key_sm2 = EVP_PKEY_new()) == NULL) { return SSH_ERR_ALLOC_FAIL; } if ((EVP_PKEY_set1_EC_KEY(key_sm2, sign_key->ecdsa)) != 1) { ret = SSH_ERR_INTERNAL_ERROR; return 0; } if (ctx == NULL) return 0; EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT); ret = EVP_DigestInit_ex(ctx, type, impl) && EVP_DigestUpdate(ctx, data, count) && EVP_DigestFinal_ex(ctx, md, size); EVP_MD_CTX_free(ctx); return ret; }
其中
EVP_Digest
为: