mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-15 12:56:28 +08:00
782 lines
19 KiB
C
Executable File
782 lines
19 KiB
C
Executable File
/*
|
|
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
|
* not use this file except in compliance with the License.
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <gmssl/skf.h>
|
|
#include <gmssl/error.h>
|
|
#include "../sgd.h"
|
|
#include "skf.h"
|
|
#include "skf_ext.h"
|
|
#include "skf_int.h"
|
|
|
|
|
|
int skf_load_library(const char *so_path, const char *vendor)
|
|
{
|
|
if (SKF_LoadLibrary((LPSTR)so_path, (LPSTR)vendor) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void skf_unload_library(void)
|
|
{
|
|
SKF_UnloadLibrary();
|
|
}
|
|
|
|
|
|
static int skf_open_app(SKF_DEVICE *dev, const char *appname, const char *pin, HAPPLICATION *phApp)
|
|
{
|
|
int ret = 0;
|
|
HAPPLICATION hApp = NULL;
|
|
ULONG ulPINType = USER_TYPE;
|
|
ULONG numRetry;
|
|
|
|
if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_VerifyPIN(hApp, ulPINType, (CHAR *)pin, &numRetry) != SAR_OK) {
|
|
fprintf(stderr, "Invalid user PIN, retry count = %u\n", numRetry);
|
|
error_print();
|
|
goto end;
|
|
}
|
|
*phApp = hApp;
|
|
hApp = NULL;
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
static const uint8_t zeros[ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32] = {0};
|
|
|
|
static int SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(const ECCPUBLICKEYBLOB *blob, SM2_KEY *sm2_key)
|
|
{
|
|
SM2_POINT point;
|
|
|
|
if (blob->BitLen != 256) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (memcmp(blob->XCoordinate, zeros, sizeof(zeros)) != 0
|
|
|| memcmp(blob->YCoordinate, zeros, sizeof(zeros)) != 0) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (sm2_point_from_xy(&point,
|
|
blob->XCoordinate + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32,
|
|
blob->YCoordinate + ECC_MAX_YCOORDINATE_BITS_LEN/8 - 32) != 1
|
|
|| sm2_key_set_public_key(sm2_key, &point) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
return SAR_OK;
|
|
}
|
|
|
|
static int SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(const ECCSIGNATUREBLOB *blob, SM2_SIGNATURE *sig)
|
|
{
|
|
if (memcmp(blob->r, zeros, sizeof(zeros)) != 0
|
|
|| memcmp(blob->s, zeros, sizeof(zeros)) != 0) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
memset(sig, 0, sizeof(SM2_SIGNATURE));
|
|
memcpy(sig->r, blob->r + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32);
|
|
memcpy(sig->s, blob->s + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32);
|
|
return SAR_OK;
|
|
}
|
|
|
|
int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len)
|
|
{
|
|
if (SKF_GenRandom(dev->handle, buf, (ULONG)len) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
HCONTAINER hContainer = NULL;
|
|
ULONG containerType = 0;
|
|
BOOL bSign = SGD_TRUE;
|
|
ECCPUBLICKEYBLOB publicKeyBlob;
|
|
ULONG ulBlobLen = sizeof(ECCPUBLICKEYBLOB);
|
|
SM2_KEY public_key;
|
|
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_OpenContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK
|
|
|| SKF_GetContainerType(hContainer, &containerType) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (containerType != SKF_CONTAINER_TYPE_ECC) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (SKF_ExportPublicKey(hContainer, bSign, (BYTE *)&publicKeyBlob, &ulBlobLen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (ulBlobLen != sizeof(ECCPUBLICKEYBLOB)) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(&publicKeyBlob, &public_key) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
memset(key, 0, sizeof(SKF_KEY));
|
|
key->public_key = public_key;
|
|
key->app_handle = hApp;
|
|
hApp = NULL;
|
|
strncpy(key->app_name, appname, 64);
|
|
key->container_handle = hContainer;
|
|
hContainer = NULL;
|
|
strncpy(key->container_name, container_name, 64);
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
if (hContainer) SKF_CloseContainer(hContainer);
|
|
return ret;
|
|
}
|
|
|
|
int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen)
|
|
{
|
|
ECCSIGNATUREBLOB sigBlob;
|
|
SM2_SIGNATURE sm2_sig;
|
|
|
|
if (SKF_ECCSignData(key->container_handle, (BYTE *)dgst, 32, &sigBlob) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(&sigBlob, &sm2_sig) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
*siglen = 0;
|
|
if (sm2_signature_to_der(&sm2_sig, &sig, siglen) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int skf_release_key(SKF_KEY *key)
|
|
{
|
|
if (key->app_handle) {
|
|
if (SKF_ClearSecureState(key->app_handle) != SAR_OK
|
|
|| SKF_CloseApplication(key->app_handle) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
key->app_handle = NULL;
|
|
}
|
|
if (key->container_handle) {
|
|
if (SKF_CloseContainer(key->container_handle) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
}
|
|
memset(key, 0, sizeof(SKF_KEY));
|
|
return 1;
|
|
}
|
|
|
|
int skf_close_device(SKF_DEVICE *dev)
|
|
{
|
|
if (SKF_UnlockDev(dev->handle) != SAR_OK
|
|
|| SKF_DisConnectDev(dev->handle) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
memset(dev, 0, sizeof(SKF_DEVICE));
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int skf_list_devices(FILE *fp, int fmt, int ind, const char *label)
|
|
{
|
|
int ret = -1;
|
|
BOOL bPresent = TRUE;
|
|
char *nameList = NULL;
|
|
ULONG nameListLen = 0;
|
|
const char *name;
|
|
int i;
|
|
|
|
format_print(fp, fmt, ind, "%s\n", label);
|
|
ind += 4;
|
|
|
|
if (SKF_EnumDev(bPresent, NULL, &nameListLen) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (nameListLen == 0) {
|
|
return 0;
|
|
}
|
|
if (!(nameList = malloc(nameListLen))) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_EnumDev(bPresent, (LPSTR)nameList, &nameListLen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) {
|
|
(void)format_print(fp, fmt, ind, "%s\n", name);
|
|
}
|
|
ret = 1;
|
|
end:
|
|
free(nameList);
|
|
return ret;
|
|
}
|
|
|
|
int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname)
|
|
{
|
|
int ret = 0;
|
|
DEVHANDLE hDev = NULL;
|
|
ULONG devState = 0;
|
|
LPSTR devStateName = NULL;
|
|
DEVINFO devInfo = {{0,0}};
|
|
|
|
format_print(fp, fmt, ind, "%s\n", devname);
|
|
ind += 4;
|
|
|
|
if (SKF_GetDevState((LPSTR)devname, &devState) != SAR_OK
|
|
|| SKF_GetDevStateName(devState, &devStateName) != SAR_OK
|
|
|| SKF_ConnectDev((LPSTR)devname, &hDev) != SAR_OK
|
|
|| SKF_GetDevInfo(hDev, &devInfo) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
|
|
(void)format_print(fp, fmt, ind, "DeviceState: %s\n", (char *)devStateName);
|
|
//(void)SKF_PrintDevInfo(fp, fmt, ind, "DeviceInfo", &devInfo);
|
|
ret = 1;
|
|
end:
|
|
if (hDev) SKF_DisConnectDev(hDev);
|
|
return ret;
|
|
}
|
|
|
|
int skf_set_label(SKF_DEVICE *dev, const char *label)
|
|
{
|
|
if (SKF_SetLabel(dev->handle, (LPSTR)label) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16])
|
|
{
|
|
DEVHANDLE hDev = NULL;
|
|
DEVINFO devInfo = {{0,0}};
|
|
ULONG ulTimeOut = 0xffffffff;
|
|
BYTE authRand[16] = {0};
|
|
BYTE authData[16] = {0};
|
|
ULONG authRandLen = SKF_AUTHRAND_LENGTH;
|
|
ULONG authDataLen = sizeof(authData);
|
|
BLOCKCIPHERPARAM encParam = {{0}, 0, 0, 0};
|
|
|
|
if (SKF_OpenDevice((LPSTR)devname, (BYTE *)authkey, &devInfo, &hDev) != SAR_OK
|
|
|| SKF_LockDev(hDev, ulTimeOut) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
memset(dev, 0, sizeof(SKF_DEVICE));
|
|
dev->handle = hDev;
|
|
hDev = NULL;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16])
|
|
{
|
|
if (SKF_ChangeDevAuthKey(dev->handle, (BYTE *)authkey, 16) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp)
|
|
{
|
|
int ret = 0;
|
|
HAPPLICATION hApp = NULL;
|
|
char *nameList = NULL;
|
|
ULONG nameListLen = 0;
|
|
const char *name;
|
|
int i;
|
|
|
|
format_print(fp, fmt, ind, "%s\n", label);
|
|
ind += 4;
|
|
|
|
if (SKF_EnumApplication(dev->handle, NULL, &nameListLen) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (nameListLen <= 1) {
|
|
return 0;
|
|
}
|
|
if (!(nameList = malloc(nameListLen))) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_EnumApplication(dev->handle, (LPSTR)nameList, &nameListLen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) {
|
|
ULONG adminMaxRetry;
|
|
ULONG adminMinRetry;
|
|
ULONG userMaxRetry;
|
|
ULONG userMinRetry;
|
|
BOOL adminDefaultPin;
|
|
BOOL userDefaultPin;
|
|
|
|
if (SKF_OpenApplication(dev->handle, (LPSTR)name, &hApp) != SAR_OK
|
|
|| SKF_GetPINInfo(hApp, ADMIN_TYPE, &adminMaxRetry, &adminMinRetry, &adminDefaultPin) != SAR_OK
|
|
|| SKF_GetPINInfo(hApp, USER_TYPE, &userMaxRetry, &userMinRetry, &userDefaultPin) != SAR_OK
|
|
|| SKF_CloseApplication(hApp) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
hApp = NULL;
|
|
|
|
(void)format_print(fp, fmt, ind, "Application %d:\n", i);
|
|
(void)format_print(fp, fmt, ind + 4, "ApplicationName", name);
|
|
(void)format_print(fp, fmt, ind + 4, "AdminPinMaxRetry: %s\n", adminMaxRetry);
|
|
(void)format_print(fp, fmt, ind + 4, "AdminPinMinRetry: %u\n", adminMinRetry);
|
|
(void)format_print(fp, fmt, ind + 4, "AdminDefaultPin: %s\n", adminDefaultPin ? "True" : "False");
|
|
(void)format_print(fp, fmt, ind + 4, "UserPinMaxRetry: %u\n", userMaxRetry);
|
|
(void)format_print(fp, fmt, ind + 4, "UserPinMinRetry: %u\n", userMinRetry);
|
|
(void)format_print(fp, fmt, ind + 4, "UserDefaultPin: %s\n", userDefaultPin ? "True" : "False");
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin)
|
|
{
|
|
int ret = 0;
|
|
HAPPLICATION hApp = NULL;
|
|
ULONG appRights = SECURE_ANYONE_ACCOUNT;
|
|
|
|
if (SKF_CreateApplication(dev->handle, (LPSTR)appname,
|
|
(CHAR *)admin_pin, SKF_DEFAULT_ADMIN_PIN_RETRY_COUNT,
|
|
(CHAR *)user_pin, SKF_DEFAULT_USER_PIN_RETRY_COUNT,
|
|
appRights, &hApp) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_CloseApplication(hApp) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int skf_delete_app(SKF_DEVICE *dev, const char *appname)
|
|
{
|
|
if (SKF_DeleteApplication(dev->handle, (LPSTR)appname) != SAR_OK) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
ULONG ulPINType = ADMIN_TYPE;
|
|
ULONG ulRetryCount = 0;
|
|
|
|
if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK
|
|
|| SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) {
|
|
fprintf(stderr, "Retry Count = %u\n", ulRetryCount);
|
|
error_print();
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
ULONG ulPINType = USER_TYPE;
|
|
ULONG ulRetryCount = 0;
|
|
|
|
if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK
|
|
|| SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) {
|
|
fprintf(stderr, "Retry Count = %u\n", ulRetryCount);
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
ULONG ulRetryCount = 0;
|
|
|
|
if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK
|
|
|| SKF_UnblockPIN(hApp, (CHAR *)admin_pin, (CHAR *)new_user_pin, &ulRetryCount) != SAR_OK) {
|
|
fprintf(stderr, "Invalid admin PIN, retry count = %u\n", ulRetryCount);
|
|
error_print();
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_list_objects(FILE *fp, int fmt, int ind, const char *label,
|
|
SKF_DEVICE *dev, const char *appname, const char *pin)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
char *nameList = NULL;
|
|
ULONG nameListLen = 0;
|
|
const char *name;
|
|
int i;
|
|
|
|
format_print(fp, fmt, ind, "%s\n", label);
|
|
ind += 4;
|
|
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_EnumFiles(hApp, NULL, &nameListLen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (nameListLen <= 1) {
|
|
ret = 0;
|
|
goto end;
|
|
}
|
|
if (!(nameList = malloc(nameListLen))) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (SKF_EnumFiles(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) {
|
|
FILEATTRIBUTE fileInfo;
|
|
|
|
if (SKF_GetFileInfo(hApp, (LPSTR)name, &fileInfo) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
format_print(fp, fmt, ind, "Object:\n");
|
|
format_print(fp, fmt, ind + 4, "Name: %s\n", (char *)&(fileInfo.FileName));
|
|
format_print(fp, fmt, ind + 4, "Size: %u\n", fileInfo.FileSize);
|
|
format_print(fp, fmt, ind + 4, "ReadRights: %08X\n", fileInfo.ReadRights);
|
|
format_print(fp, fmt, ind + 4, "WriteRights: %08X\n", fileInfo.WriteRights);
|
|
}
|
|
|
|
ret = 1;
|
|
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
if (nameList) free(nameList);
|
|
return ret;
|
|
}
|
|
|
|
int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin,
|
|
const char *objname, const uint8_t *data, size_t datalen)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
ULONG ulReadRights = SECURE_ANYONE_ACCOUNT;
|
|
ULONG ulWriteRights = SECURE_USER_ACCOUNT;
|
|
|
|
if (!dev || !appname || !pin || !objname || !data || !datalen) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (datalen > SKF_MAX_FILE_SIZE) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_CreateFile(hApp, (LPSTR)objname, (ULONG)datalen, ulReadRights, ulWriteRights) != SAR_OK
|
|
|| SKF_WriteFile(hApp, (LPSTR)objname, 0, (BYTE *)data, (ULONG)datalen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin,
|
|
const char *objname, uint8_t *out, size_t *outlen)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
FILEATTRIBUTE fileInfo;
|
|
ULONG ulen;
|
|
|
|
if (!dev || !appname || !pin || !objname || !outlen) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_GetFileInfo(hApp, (LPSTR)objname, &fileInfo) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (fileInfo.FileSize > SKF_MAX_FILE_SIZE) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (!out) {
|
|
*outlen = (size_t)fileInfo.FileSize;
|
|
ret = 1;
|
|
goto end;
|
|
}
|
|
ulen = fileInfo.FileSize;
|
|
if (SKF_ReadFile(hApp, (LPSTR)objname, 0, fileInfo.FileSize, out, &ulen) != SAR_OK) {
|
|
goto end;
|
|
}
|
|
if (ulen != fileInfo.FileSize) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
*outlen = ulen;
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_DeleteFile(hApp, (LPSTR)objname) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_list_containers(FILE *fp, int fmt, int ind, const char *label,
|
|
SKF_DEVICE *dev, const char *appname, const char *pin)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
HCONTAINER hContainer = NULL;
|
|
char *nameList = NULL;
|
|
ULONG nameListLen = 0;
|
|
const char *name;
|
|
int i;
|
|
|
|
format_print(fp, fmt, ind, "%s\n", label);
|
|
ind += 4;
|
|
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_EnumContainer(hApp, NULL, &nameListLen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (nameListLen <= 1) {
|
|
ret = 0;
|
|
goto end;
|
|
}
|
|
if (!(nameList = malloc(nameListLen))) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (SKF_EnumContainer(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) {
|
|
ULONG containerType;
|
|
LPSTR containerTypeName;
|
|
|
|
if (SKF_OpenContainer(hApp, (LPSTR)name, &hContainer) != SAR_OK
|
|
|| SKF_GetContainerType(hContainer, &containerType) != SAR_OK
|
|
|| SKF_GetContainerTypeName(containerType, &containerTypeName) != SAR_OK
|
|
|| SKF_CloseContainer(hContainer) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
hContainer = NULL;
|
|
(void)format_print(fp, fmt, ind, "Container:\n");
|
|
(void)format_print(fp, fmt, ind + 4, "Name: %s\n", name);
|
|
(void)format_print(fp, fmt, ind + 4, "Type: %s\n", (char *)containerTypeName);
|
|
}
|
|
ret = 1;
|
|
|
|
end:
|
|
if (hContainer) SKF_CloseContainer(hContainer);
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
HCONTAINER hContainer = NULL;
|
|
ECCPUBLICKEYBLOB publicKey = {0, {0}, {0}};
|
|
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_CreateContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK
|
|
|| SKF_GenECCKeyPair(hContainer, SGD_SM2_1, &publicKey) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hContainer) SKF_CloseContainer(hContainer);
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_DeleteContainer(hApp, (LPSTR)container_name) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return 1;
|
|
}
|
|
|
|
int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin,
|
|
const char *container_name, const uint8_t *cert, size_t certlen)
|
|
{
|
|
int ret = 0;
|
|
HAPPLICATION hApp = NULL;
|
|
HCONTAINER hContainer = NULL;
|
|
ULONG containerType;
|
|
BOOL bSign = SGD_TRUE;
|
|
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (containerType == SKF_CONTAINER_TYPE_UNDEF) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (containerType != SKF_CONTAINER_TYPE_ECC) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
// FIXME: 判断导入证书的类型是否为签名证书
|
|
if (SKF_ImportCertificate(hContainer, bSign, (BYTE *)cert, (ULONG)certlen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hContainer) SKF_CloseContainer(hContainer);
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|
|
|
|
int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin,
|
|
const char *container_name, uint8_t *cert, size_t *certlen)
|
|
{
|
|
int ret = -1;
|
|
HAPPLICATION hApp = NULL;
|
|
HCONTAINER hContainer = NULL;
|
|
ULONG containerType;
|
|
BOOL bSign = SGD_TRUE;
|
|
ULONG ulCertLen = 0;
|
|
|
|
if (skf_open_app(dev, appname, pin, &hApp) != 1) {
|
|
error_print();
|
|
return -1;
|
|
}
|
|
if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (containerType != SKF_CONTAINER_TYPE_ECC) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
if (SKF_ExportCertificate(hContainer, bSign, (BYTE *)cert, &ulCertLen) != SAR_OK) {
|
|
error_print();
|
|
goto end;
|
|
}
|
|
ret = 1;
|
|
end:
|
|
if (hContainer) SKF_CloseContainer(hContainer);
|
|
if (hApp) SKF_CloseApplication(hApp);
|
|
return ret;
|
|
}
|