• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the License); you may
5  *  not use this file except in compliance with the License.
6  *
7  *  http://www.apache.org/licenses/LICENSE-2.0
8  */
9 
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <gmssl/skf.h>
15 #include <gmssl/error.h>
16 #include "../sgd.h"
17 #include "skf.h"
18 #include "skf_ext.h"
19 #include "skf_int.h"
20 
21 
skf_load_library(const char * so_path,const char * vendor)22 int skf_load_library(const char *so_path, const char *vendor)
23 {
24 	if (SKF_LoadLibrary((LPSTR)so_path, (LPSTR)vendor) != SAR_OK) {
25 		error_print();
26 		return -1;
27 	}
28 	return 1;
29 }
30 
skf_unload_library(void)31 void skf_unload_library(void)
32 {
33 	SKF_UnloadLibrary();
34 }
35 
36 
skf_open_app(SKF_DEVICE * dev,const char * appname,const char * pin,HAPPLICATION * phApp)37 static int skf_open_app(SKF_DEVICE *dev, const char *appname, const char *pin, HAPPLICATION *phApp)
38 {
39 	int ret = 0;
40 	HAPPLICATION hApp = NULL;
41 	ULONG ulPINType = USER_TYPE;
42 	ULONG numRetry;
43 
44 	if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK) {
45 		error_print();
46 		return -1;
47 	}
48 	if (SKF_VerifyPIN(hApp, ulPINType, (CHAR *)pin, &numRetry) != SAR_OK) {
49 		fprintf(stderr, "Invalid user PIN, retry count = %u\n", numRetry);
50 		error_print();
51 		goto end;
52 	}
53 	*phApp = hApp;
54 	hApp = NULL;
55 	ret = 1;
56 end:
57 	if (hApp) SKF_CloseApplication(hApp);
58 	return ret;
59 }
60 
61 static const uint8_t zeros[ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32] = {0};
62 
SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(const ECCPUBLICKEYBLOB * blob,SM2_KEY * sm2_key)63 static int SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(const ECCPUBLICKEYBLOB *blob, SM2_KEY *sm2_key)
64 {
65 	SM2_POINT point;
66 
67 	if (blob->BitLen != 256) {
68 		error_print();
69 		return -1;
70 	}
71 	if (memcmp(blob->XCoordinate, zeros, sizeof(zeros)) != 0
72 		|| memcmp(blob->YCoordinate, zeros, sizeof(zeros)) != 0) {
73 		error_print();
74 		return -1;
75 	}
76 	if (sm2_point_from_xy(&point,
77 			blob->XCoordinate + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32,
78 			blob->YCoordinate + ECC_MAX_YCOORDINATE_BITS_LEN/8 - 32) != 1
79 		|| sm2_key_set_public_key(sm2_key, &point) != 1) {
80 		error_print();
81 		return -1;
82 	}
83 	return SAR_OK;
84 }
85 
SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(const ECCSIGNATUREBLOB * blob,SM2_SIGNATURE * sig)86 static int SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(const ECCSIGNATUREBLOB *blob, SM2_SIGNATURE *sig)
87 {
88 	if (memcmp(blob->r, zeros, sizeof(zeros)) != 0
89 		|| memcmp(blob->s, zeros, sizeof(zeros)) != 0) {
90 		error_print();
91 		return -1;
92 	}
93 	memset(sig, 0, sizeof(SM2_SIGNATURE));
94 	memcpy(sig->r, blob->r + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32);
95 	memcpy(sig->s, blob->s + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32);
96 	return SAR_OK;
97 }
98 
skf_rand_bytes(SKF_DEVICE * dev,uint8_t * buf,size_t len)99 int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len)
100 {
101 	if (SKF_GenRandom(dev->handle, buf, (ULONG)len) != SAR_OK) {
102 		error_print();
103 		return -1;
104 	}
105 	return 1;
106 }
107 
skf_load_sign_key(SKF_DEVICE * dev,const char * appname,const char * pin,const char * container_name,SKF_KEY * key)108 int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key)
109 {
110 	int ret = -1;
111 	HAPPLICATION hApp = NULL;
112 	HCONTAINER hContainer = NULL;
113 	ULONG containerType = 0;
114 	BOOL bSign = SGD_TRUE;
115 	ECCPUBLICKEYBLOB publicKeyBlob;
116 	ULONG ulBlobLen = sizeof(ECCPUBLICKEYBLOB);
117 	SM2_KEY public_key;
118 
119 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
120 		error_print();
121 		return -1;
122 	}
123 	if (SKF_OpenContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK
124 		|| SKF_GetContainerType(hContainer, &containerType) != SAR_OK) {
125 		error_print();
126 		goto end;
127 	}
128 	if (containerType != SKF_CONTAINER_TYPE_ECC) {
129 		error_print();
130 		goto end;
131 	}
132 	if (SKF_ExportPublicKey(hContainer, bSign, (BYTE *)&publicKeyBlob, &ulBlobLen) != SAR_OK) {
133 		error_print();
134 		goto end;
135 	}
136 	if (ulBlobLen != sizeof(ECCPUBLICKEYBLOB)) {
137 		error_print();
138 		goto end;
139 	}
140 	if (SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(&publicKeyBlob, &public_key) != SAR_OK) {
141 		error_print();
142 		goto end;
143 	}
144 	memset(key, 0, sizeof(SKF_KEY));
145 	key->public_key = public_key;
146 	key->app_handle = hApp;
147 	hApp = NULL;
148 	strncpy(key->app_name, appname, 64);
149 	key->container_handle = hContainer;
150 	hContainer = NULL;
151 	strncpy(key->container_name, container_name, 64);
152 	ret = 1;
153 end:
154 	if (hApp) SKF_CloseApplication(hApp);
155 	if (hContainer) SKF_CloseContainer(hContainer);
156 	return ret;
157 }
158 
skf_sign(SKF_KEY * key,const uint8_t dgst[32],uint8_t * sig,size_t * siglen)159 int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen)
160 {
161 	ECCSIGNATUREBLOB sigBlob;
162 	SM2_SIGNATURE sm2_sig;
163 
164 	if (SKF_ECCSignData(key->container_handle, (BYTE *)dgst, 32, &sigBlob) != SAR_OK) {
165 		error_print();
166 		return -1;
167 	}
168 	if (SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(&sigBlob, &sm2_sig) != SAR_OK) {
169 		error_print();
170 		return -1;
171 	}
172 	*siglen = 0;
173 	if (sm2_signature_to_der(&sm2_sig, &sig, siglen) != 1) {
174 		error_print();
175 		return -1;
176 	}
177 	return 1;
178 }
179 
skf_release_key(SKF_KEY * key)180 int skf_release_key(SKF_KEY *key)
181 {
182 	if (key->app_handle) {
183 		if (SKF_ClearSecureState(key->app_handle) != SAR_OK
184 			|| SKF_CloseApplication(key->app_handle) != SAR_OK) {
185 			error_print();
186 			return -1;
187 		}
188 		key->app_handle = NULL;
189 	}
190 	if (key->container_handle) {
191 		if (SKF_CloseContainer(key->container_handle) != SAR_OK) {
192 			error_print();
193 			return -1;
194 		}
195 	}
196 	memset(key, 0, sizeof(SKF_KEY));
197 	return 1;
198 }
199 
skf_close_device(SKF_DEVICE * dev)200 int skf_close_device(SKF_DEVICE *dev)
201 {
202 	if (SKF_UnlockDev(dev->handle) != SAR_OK
203 		|| SKF_DisConnectDev(dev->handle) != SAR_OK) {
204 		error_print();
205 		return -1;
206 	}
207 	memset(dev, 0, sizeof(SKF_DEVICE));
208 	return 1;
209 }
210 
211 
212 
213 
214 
215 
216 
skf_list_devices(FILE * fp,int fmt,int ind,const char * label)217 int skf_list_devices(FILE *fp, int fmt, int ind, const char *label)
218 {
219 	int ret = -1;
220 	BOOL bPresent = TRUE;
221 	char *nameList = NULL;
222 	ULONG nameListLen = 0;
223 	const char *name;
224 	int i;
225 
226 	format_print(fp, fmt, ind, "%s\n", label);
227 	ind += 4;
228 
229 	if (SKF_EnumDev(bPresent, NULL, &nameListLen) != SAR_OK) {
230 		error_print();
231 		return -1;
232 	}
233 	if (nameListLen == 0) {
234 		return 0;
235 	}
236 	if (!(nameList = malloc(nameListLen))) {
237 		error_print();
238 		return -1;
239 	}
240 	if (SKF_EnumDev(bPresent, (LPSTR)nameList, &nameListLen) != SAR_OK) {
241 		error_print();
242 		goto end;
243 	}
244 	for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) {
245 		(void)format_print(fp, fmt, ind, "%s\n", name);
246 	}
247 	ret = 1;
248 end:
249 	free(nameList);
250 	return ret;
251 }
252 
skf_print_device_info(FILE * fp,int fmt,int ind,const char * devname)253 int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname)
254 {
255 	int ret = 0;
256 	DEVHANDLE hDev = NULL;
257 	ULONG devState = 0;
258 	LPSTR devStateName = NULL;
259 	DEVINFO devInfo = {{0,0}};
260 
261 	format_print(fp, fmt, ind, "%s\n", devname);
262 	ind += 4;
263 
264 	if (SKF_GetDevState((LPSTR)devname, &devState) != SAR_OK
265 		|| SKF_GetDevStateName(devState, &devStateName) != SAR_OK
266 		|| SKF_ConnectDev((LPSTR)devname, &hDev) != SAR_OK
267 		|| SKF_GetDevInfo(hDev, &devInfo) != SAR_OK) {
268 		error_print();
269 		goto end;
270 	}
271 
272 	(void)format_print(fp, fmt, ind, "DeviceState: %s\n", (char *)devStateName);
273 	//(void)SKF_PrintDevInfo(fp, fmt, ind, "DeviceInfo", &devInfo);
274 	ret = 1;
275 end:
276 	if (hDev) SKF_DisConnectDev(hDev);
277 	return ret;
278 }
279 
skf_set_label(SKF_DEVICE * dev,const char * label)280 int skf_set_label(SKF_DEVICE *dev, const char *label)
281 {
282 	if (SKF_SetLabel(dev->handle, (LPSTR)label) != SAR_OK) {
283 		error_print();
284 		return -1;
285 	}
286 	return 1;
287 }
288 
skf_open_device(SKF_DEVICE * dev,const char * devname,const uint8_t authkey[16])289 int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16])
290 {
291 	DEVHANDLE hDev = NULL;
292 	DEVINFO devInfo = {{0,0}};
293 	ULONG ulTimeOut = 0xffffffff;
294 	BYTE authRand[16] = {0};
295 	BYTE authData[16] = {0};
296 	ULONG authRandLen = SKF_AUTHRAND_LENGTH;
297 	ULONG authDataLen = sizeof(authData);
298 	BLOCKCIPHERPARAM encParam = {{0}, 0, 0, 0};
299 
300 	if (SKF_OpenDevice((LPSTR)devname, (BYTE *)authkey, &devInfo, &hDev) != SAR_OK
301 		|| SKF_LockDev(hDev, ulTimeOut) != SAR_OK) {
302 		error_print();
303 		return -1;
304 	}
305 	memset(dev, 0, sizeof(SKF_DEVICE));
306 	dev->handle = hDev;
307 	hDev = NULL;
308 
309 	return 1;
310 }
311 
skf_change_authkey(SKF_DEVICE * dev,const uint8_t authkey[16])312 int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16])
313 {
314 	if (SKF_ChangeDevAuthKey(dev->handle, (BYTE *)authkey, 16) != SAR_OK) {
315 		error_print();
316 		return -1;
317 	}
318 	return 1;
319 }
320 
skf_list_apps(SKF_DEVICE * dev,int fmt,int ind,const char * label,FILE * fp)321 int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp)
322 {
323 	int ret = 0;
324 	HAPPLICATION hApp = NULL;
325 	char *nameList = NULL;
326 	ULONG nameListLen = 0;
327 	const char *name;
328 	int i;
329 
330 	format_print(fp, fmt, ind, "%s\n", label);
331 	ind += 4;
332 
333 	if (SKF_EnumApplication(dev->handle, NULL, &nameListLen) != SAR_OK) {
334 		error_print();
335 		return -1;
336 	}
337 	if (nameListLen <= 1) {
338 		return 0;
339 	}
340 	if (!(nameList = malloc(nameListLen))) {
341 		error_print();
342 		return -1;
343 	}
344 	if (SKF_EnumApplication(dev->handle, (LPSTR)nameList, &nameListLen) != SAR_OK) {
345 		error_print();
346 		goto end;
347 	}
348 	for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) {
349 		ULONG adminMaxRetry;
350 		ULONG adminMinRetry;
351 		ULONG userMaxRetry;
352 		ULONG userMinRetry;
353 		BOOL adminDefaultPin;
354 		BOOL userDefaultPin;
355 
356 		if (SKF_OpenApplication(dev->handle, (LPSTR)name, &hApp) != SAR_OK
357 			|| SKF_GetPINInfo(hApp, ADMIN_TYPE, &adminMaxRetry, &adminMinRetry, &adminDefaultPin) != SAR_OK
358 			|| SKF_GetPINInfo(hApp, USER_TYPE, &userMaxRetry, &userMinRetry, &userDefaultPin) != SAR_OK
359 			|| SKF_CloseApplication(hApp) != SAR_OK) {
360 			error_print();
361 			goto end;
362 		}
363 		hApp = NULL;
364 
365 		(void)format_print(fp, fmt, ind, "Application %d:\n", i);
366 		(void)format_print(fp, fmt, ind + 4, "ApplicationName", name);
367 		(void)format_print(fp, fmt, ind + 4, "AdminPinMaxRetry: %s\n", adminMaxRetry);
368 		(void)format_print(fp, fmt, ind + 4, "AdminPinMinRetry: %u\n", adminMinRetry);
369 		(void)format_print(fp, fmt, ind + 4, "AdminDefaultPin: %s\n", adminDefaultPin ? "True" : "False");
370 		(void)format_print(fp, fmt, ind + 4, "UserPinMaxRetry: %u\n", userMaxRetry);
371 		(void)format_print(fp, fmt, ind + 4, "UserPinMinRetry: %u\n", userMinRetry);
372 		(void)format_print(fp, fmt, ind + 4, "UserDefaultPin: %s\n", userDefaultPin ? "True" : "False");
373 	}
374 	ret = 1;
375 end:
376 	if (hApp) SKF_CloseApplication(hApp);
377 	return ret;
378 }
379 
skf_create_app(SKF_DEVICE * dev,const char * appname,const char * admin_pin,const char * user_pin)380 int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin)
381 {
382 	int ret = 0;
383 	HAPPLICATION hApp = NULL;
384 	ULONG appRights = SECURE_ANYONE_ACCOUNT;
385 
386 	if (SKF_CreateApplication(dev->handle, (LPSTR)appname,
387 		(CHAR *)admin_pin, SKF_DEFAULT_ADMIN_PIN_RETRY_COUNT,
388 		(CHAR *)user_pin, SKF_DEFAULT_USER_PIN_RETRY_COUNT,
389 		appRights, &hApp) != SAR_OK) {
390 		error_print();
391 		return -1;
392 	}
393 	if (SKF_CloseApplication(hApp) != SAR_OK) {
394 		error_print();
395 		return -1;
396 	}
397 	return 1;
398 }
399 
skf_delete_app(SKF_DEVICE * dev,const char * appname)400 int skf_delete_app(SKF_DEVICE *dev, const char *appname)
401 {
402 	if (SKF_DeleteApplication(dev->handle, (LPSTR)appname) != SAR_OK) {
403 		error_print();
404 		return -1;
405 	}
406 	return 1;
407 }
408 
skf_change_app_admin_pin(SKF_DEVICE * dev,const char * appname,const char * oid_pin,const char * new_pin)409 int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin)
410 {
411 	int ret = -1;
412 	HAPPLICATION hApp = NULL;
413 	ULONG ulPINType = ADMIN_TYPE;
414 	ULONG ulRetryCount = 0;
415 
416 	if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK
417 		|| SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) {
418 		fprintf(stderr, "Retry Count = %u\n", ulRetryCount);
419 		error_print();
420 		goto end;
421 	}
422 	ret = 1;
423 end:
424 	if (hApp) SKF_CloseApplication(hApp);
425 	return ret;
426 }
427 
skf_change_app_user_pin(SKF_DEVICE * dev,const char * appname,const char * oid_pin,const char * new_pin)428 int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin)
429 {
430 	int ret = -1;
431 	HAPPLICATION hApp = NULL;
432 	ULONG ulPINType = USER_TYPE;
433 	ULONG ulRetryCount = 0;
434 
435 	if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK
436 		|| SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) {
437 		fprintf(stderr, "Retry Count = %u\n", ulRetryCount);
438 		goto end;
439 	}
440 	ret = 1;
441 end:
442 	if (hApp) SKF_CloseApplication(hApp);
443 	return ret;
444 }
445 
skf_unblock_user_pin(SKF_DEVICE * dev,const char * appname,const char * admin_pin,const char * new_user_pin)446 int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin)
447 {
448 	int ret = -1;
449 	HAPPLICATION hApp = NULL;
450 	ULONG ulRetryCount = 0;
451 
452 	if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK
453 		|| SKF_UnblockPIN(hApp, (CHAR *)admin_pin, (CHAR *)new_user_pin, &ulRetryCount) != SAR_OK) {
454 		fprintf(stderr, "Invalid admin PIN, retry count = %u\n", ulRetryCount);
455 		error_print();
456 		goto end;
457 	}
458 	ret = 1;
459 end:
460 	if (hApp) SKF_CloseApplication(hApp);
461 	return ret;
462 }
463 
skf_list_objects(FILE * fp,int fmt,int ind,const char * label,SKF_DEVICE * dev,const char * appname,const char * pin)464 int skf_list_objects(FILE *fp, int fmt, int ind, const char *label,
465 	SKF_DEVICE *dev, const char *appname, const char *pin)
466 {
467 	int ret = -1;
468 	HAPPLICATION hApp = NULL;
469 	char *nameList = NULL;
470 	ULONG nameListLen = 0;
471 	const char *name;
472 	int i;
473 
474 	format_print(fp, fmt, ind, "%s\n", label);
475 	ind += 4;
476 
477 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
478 		error_print();
479 		return -1;
480 	}
481 	if (SKF_EnumFiles(hApp, NULL, &nameListLen) != SAR_OK) {
482 		error_print();
483 		goto end;
484 	}
485 	if (nameListLen <= 1) {
486 		ret = 0;
487 		goto end;
488 	}
489 	if (!(nameList = malloc(nameListLen))) {
490 		error_print();
491 		goto end;
492 	}
493 	if (SKF_EnumFiles(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) {
494 		error_print();
495 		goto end;
496 	}
497 	for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) {
498 		FILEATTRIBUTE fileInfo;
499 
500 		if (SKF_GetFileInfo(hApp, (LPSTR)name, &fileInfo) != SAR_OK) {
501 			error_print();
502 			goto end;
503 		}
504 		format_print(fp, fmt, ind, "Object:\n");
505 		format_print(fp, fmt, ind + 4, "Name: %s\n", (char *)&(fileInfo.FileName));
506 		format_print(fp, fmt, ind + 4, "Size: %u\n", fileInfo.FileSize);
507 		format_print(fp, fmt, ind + 4, "ReadRights: %08X\n", fileInfo.ReadRights);
508 		format_print(fp, fmt, ind + 4, "WriteRights: %08X\n", fileInfo.WriteRights);
509 	}
510 
511 	ret = 1;
512 
513 end:
514 	if (hApp) SKF_CloseApplication(hApp);
515 	if (nameList) free(nameList);
516 	return ret;
517 }
518 
skf_import_object(SKF_DEVICE * dev,const char * appname,const char * pin,const char * objname,const uint8_t * data,size_t datalen)519 int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin,
520 	const char *objname, const uint8_t *data, size_t datalen)
521 {
522 	int ret = -1;
523 	HAPPLICATION hApp = NULL;
524 	ULONG ulReadRights = SECURE_ANYONE_ACCOUNT;
525 	ULONG ulWriteRights = SECURE_USER_ACCOUNT;
526 
527 	if (!dev || !appname || !pin || !objname || !data || !datalen) {
528 		error_print();
529 		return -1;
530 	}
531 	if (datalen > SKF_MAX_FILE_SIZE) {
532 		error_print();
533 		return -1;
534 	}
535 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
536 		error_print();
537 		return -1;
538 	}
539 	if (SKF_CreateFile(hApp, (LPSTR)objname, datalen, ulReadRights, ulWriteRights) != SAR_OK
540 		|| SKF_WriteFile(hApp, (LPSTR)objname, 0, (BYTE *)data, datalen) != SAR_OK) {
541 		error_print();
542 		goto end;
543 	}
544 	ret = 1;
545 end:
546 	if (hApp) SKF_CloseApplication(hApp);
547 	return ret;
548 }
549 
skf_export_object(SKF_DEVICE * dev,const char * appname,const char * pin,const char * objname,uint8_t * out,size_t * outlen)550 int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin,
551 	const char *objname, uint8_t *out, size_t *outlen)
552 {
553 	int ret = -1;
554 	HAPPLICATION hApp = NULL;
555 	FILEATTRIBUTE fileInfo;
556 	ULONG ulen;
557 	int len;
558 
559 	if (!dev || !appname || !pin || !objname || !outlen) {
560 		error_print();
561 		return -1;
562 	}
563 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
564 		error_print();
565 		return -1;
566 	}
567 	if (SKF_GetFileInfo(hApp, (LPSTR)objname, &fileInfo) != SAR_OK) {
568 		error_print();
569 		goto end;
570 	}
571 	if (fileInfo.FileSize > SKF_MAX_FILE_SIZE) {
572 		error_print();
573 		goto end;
574 	}
575 	if (!out) {
576 		*outlen = (size_t)fileInfo.FileSize;
577 		ret = 1;
578 		goto end;
579 	}
580 	ulen = fileInfo.FileSize;
581 	if (SKF_ReadFile(hApp, (LPSTR)objname, 0, fileInfo.FileSize, out, &ulen) != SAR_OK) {
582 		goto end;
583 	}
584 	if (ulen != fileInfo.FileSize) {
585 		error_print();
586 		goto end;
587 	}
588 	*outlen = ulen;
589 	ret = 1;
590 end:
591 	if (hApp) SKF_CloseApplication(hApp);
592 	return ret;
593 }
594 
skf_delete_object(SKF_DEVICE * dev,const char * appname,const char * pin,const char * objname)595 int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname)
596 {
597 	int ret = -1;
598 	HAPPLICATION hApp = NULL;
599 
600 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
601 		error_print();
602 		return -1;
603 	}
604 	if (SKF_DeleteFile(hApp, (LPSTR)objname) != SAR_OK) {
605 		error_print();
606 		goto end;
607 	}
608 	ret = 1;
609 end:
610 	if (hApp) SKF_CloseApplication(hApp);
611 	return ret;
612 }
613 
skf_list_containers(FILE * fp,int fmt,int ind,const char * label,SKF_DEVICE * dev,const char * appname,const char * pin)614 int skf_list_containers(FILE *fp, int fmt, int ind, const char *label,
615 	SKF_DEVICE *dev, const char *appname, const char *pin)
616 {
617 	int ret = -1;
618 	HAPPLICATION hApp = NULL;
619 	HCONTAINER hContainer = NULL;
620 	char *nameList = NULL;
621 	ULONG nameListLen = 0;
622 	const char *name;
623 	int i;
624 
625 	format_print(fp, fmt, ind, "%s\n", label);
626 	ind += 4;
627 
628 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
629 		error_print();
630 		return -1;
631 	}
632 	if (SKF_EnumContainer(hApp, NULL, &nameListLen) != SAR_OK) {
633 		error_print();
634 		goto end;
635 	}
636 	if (nameListLen <= 1) {
637 		ret = 0;
638 		goto end;
639 	}
640 	if (!(nameList = malloc(nameListLen))) {
641 		error_print();
642 		goto end;
643 	}
644 	if (SKF_EnumContainer(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) {
645 		error_print();
646 		goto end;
647 	}
648 	for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) {
649 		ULONG containerType;
650 		LPSTR containerTypeName;
651 
652 		if (SKF_OpenContainer(hApp, (LPSTR)name, &hContainer) != SAR_OK
653 			|| SKF_GetContainerType(hContainer, &containerType) != SAR_OK
654 			|| SKF_GetContainerTypeName(containerType, &containerTypeName) != SAR_OK
655 			|| SKF_CloseContainer(hContainer) != SAR_OK) {
656 			error_print();
657 			goto end;
658 		}
659 		hContainer = NULL;
660 		(void)format_print(fp, fmt, ind, "Container:\n");
661 		(void)format_print(fp, fmt, ind + 4, "Name: %s\n", name);
662 		(void)format_print(fp, fmt, ind + 4, "Type: %s\n", (char *)containerTypeName);
663 	}
664 	ret = 1;
665 
666 end:
667 	if (hContainer) SKF_CloseContainer(hContainer);
668 	if (hApp) SKF_CloseApplication(hApp);
669 	return ret;
670 }
671 
skf_create_container(SKF_DEVICE * dev,const char * appname,const char * pin,const char * container_name)672 int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name)
673 {
674 	int ret = -1;
675 	HAPPLICATION hApp = NULL;
676 	HCONTAINER hContainer = NULL;
677 	ECCPUBLICKEYBLOB publicKey = {0, {0}, {0}};
678 
679 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
680 		error_print();
681 		return -1;
682 	}
683 	if (SKF_CreateContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK
684 		|| SKF_GenECCKeyPair(hContainer, SGD_SM2_1, &publicKey) != SAR_OK) {
685 		error_print();
686 		goto end;
687 	}
688 	ret = 1;
689 end:
690 	if (hContainer) SKF_CloseContainer(hContainer);
691 	if (hApp) SKF_CloseApplication(hApp);
692 	return ret;
693 }
694 
skf_delete_container(SKF_DEVICE * dev,const char * appname,const char * pin,const char * container_name)695 int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name)
696 {
697 	int ret = -1;
698 	HAPPLICATION hApp = NULL;
699 
700 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
701 		error_print();
702 		return -1;
703 	}
704 	if (SKF_DeleteContainer(hApp, (LPSTR)container_name) != SAR_OK) {
705 		error_print();
706 		goto end;
707 	}
708 	ret = 1;
709 end:
710 	if (hApp) SKF_CloseApplication(hApp);
711 	return 1;
712 }
713 
skf_import_sign_cert(SKF_DEVICE * dev,const char * appname,const char * pin,const char * container_name,const uint8_t * cert,size_t certlen)714 int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin,
715 	const char *container_name, const uint8_t *cert, size_t certlen)
716 {
717 	int ret = 0;
718 	HAPPLICATION hApp = NULL;
719 	HCONTAINER hContainer = NULL;
720 	ULONG containerType;
721 	BOOL bSign = SGD_TRUE;
722 
723 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
724 		error_print();
725 		return -1;
726 	}
727 	if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) {
728 		error_print();
729 		goto end;
730 	}
731 	if (containerType == SKF_CONTAINER_TYPE_UNDEF) {
732 		error_print();
733 		goto end;
734 	}
735 	if (containerType != SKF_CONTAINER_TYPE_ECC) {
736 		error_print();
737 		goto end;
738 	}
739 	// FIXME: 判断导入证书的类型是否为签名证书
740 	if (SKF_ImportCertificate(hContainer, bSign, (BYTE *)cert, (ULONG)certlen) != SAR_OK) {
741 		error_print();
742 		goto end;
743 	}
744 	ret = 1;
745 end:
746 	if (hContainer) SKF_CloseContainer(hContainer);
747 	if (hApp) SKF_CloseApplication(hApp);
748 	return ret;
749 }
750 
skf_export_sign_cert(SKF_DEVICE * dev,const char * appname,const char * pin,const char * container_name,uint8_t * cert,size_t * certlen)751 int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin,
752 	const char *container_name, uint8_t *cert, size_t *certlen)
753 {
754 	int ret = -1;
755 	HAPPLICATION hApp = NULL;
756 	HCONTAINER hContainer = NULL;
757 	ULONG containerType;
758 	BOOL bSign = SGD_TRUE;
759 	ULONG ulCertLen = 0;
760 
761 	if (skf_open_app(dev, appname, pin, &hApp) != 1) {
762 		error_print();
763 		return -1;
764 	}
765 	if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) {
766 		error_print();
767 		goto end;
768 	}
769 	if (containerType != SKF_CONTAINER_TYPE_ECC) {
770 		error_print();
771 		goto end;
772 	}
773 	if (SKF_ExportCertificate(hContainer, bSign, (BYTE *)cert, &ulCertLen) != SAR_OK) {
774 		error_print();
775 		goto end;
776 	}
777 	ret = 1;
778 end:
779 	if (hContainer) SKF_CloseContainer(hContainer);
780 	if (hApp) SKF_CloseApplication(hApp);
781 	return ret;
782 }
783