• 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 <errno.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <gmssl/sm2.h>
16 #include <gmssl/mem.h>
17 
18 
19 static const char *options = "-key pem -pass str [-id str] [-in file] [-out file]";
20 
sm2sign_main(int argc,char ** argv)21 int sm2sign_main(int argc, char **argv)
22 {
23 	int ret = 1;
24 	char *prog = argv[0];
25 	char *keyfile = NULL;
26 	char *pass = NULL;
27 	char *id = SM2_DEFAULT_ID;
28 	char *infile = NULL;
29 	char *outfile = NULL;
30 	FILE *keyfp = NULL;
31 	FILE *infp = stdin;
32 	FILE *outfp = stdout;
33 	SM2_KEY key;
34 	SM2_SIGN_CTX sign_ctx;
35 	uint8_t buf[4096];
36 	ssize_t len;
37 	uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
38 	size_t siglen;
39 
40 	argc--;
41 	argv++;
42 
43 	if (argc < 1) {
44 		fprintf(stderr, "usage: %s %s\n", prog, options);
45 		return 1;
46 	}
47 
48 	while (argc > 0) {
49 		if (!strcmp(*argv, "-help")) {
50 			printf("usage: %s %s\n", prog, options);
51 			ret = 0;
52 			goto end;
53 		} else if (!strcmp(*argv, "-key")) {
54 			if (--argc < 1) goto bad;
55 			keyfile = *(++argv);
56 			if (!(keyfp = fopen(keyfile, "r"))) {
57 				fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno));
58 				goto end;
59 			}
60 		} else if (!strcmp(*argv, "-pass")) {
61 			if (--argc < 1) goto bad;
62 			pass = *(++argv);
63 		} else if (!strcmp(*argv, "-id")) {
64 			if (--argc < 1) goto bad;
65 			id = *(++argv);
66 		} else if (!strcmp(*argv, "-in")) {
67 			if (--argc < 1) goto bad;
68 			infile = *(++argv);
69 			if (!(infp = fopen(infile, "r"))) {
70 				fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
71 				goto end;
72 			}
73 		} else if (!strcmp(*argv, "-out")) {
74 			if (--argc < 1) goto bad;
75 			outfile = *(++argv);
76 			if (!(outfp = fopen(outfile, "w"))) {
77 				fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
78 				goto end;
79 			}
80 		} else {
81 			fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
82 			goto end;
83 bad:
84 			fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
85 			goto end;
86 		}
87 
88 		argc--;
89 		argv++;
90 	}
91 
92 	if (!keyfile) {
93 		fprintf(stderr, "%s: '-key' option required\n", prog);
94 		goto end;
95 	}
96 	if (!pass) {
97 		fprintf(stderr, "%s: '-pass' option required\n", prog);
98 		goto end;
99 	}
100 	if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) {
101 		fprintf(stderr, "%s: private key decryption failure\n", prog);
102 		goto end;
103 	}
104 
105 	if (sm2_sign_init(&sign_ctx, &key, id, strlen(id)) != 1) {
106 		fprintf(stderr, "%s: inner error\n", prog);
107 		goto end;
108 	}
109 	while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) {
110 		if (sm2_sign_update(&sign_ctx, buf, len) != 1) {
111 			fprintf(stderr, "%s: inner error\n", prog);
112 			goto end;
113 		}
114 	}
115 	if (sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) {
116 		fprintf(stderr, "%s: inner error\n", prog);
117 		goto end;
118 	}
119 	if (fwrite(sig, 1, siglen, outfp) != siglen) {
120 		fprintf(stderr, "%s: output signature failed : %s\n", prog, strerror(errno));
121 		goto end;
122 	}
123 	ret = 0;
124 end:
125 	gmssl_secure_clear(&key, sizeof(key));
126 	gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx));
127 	if (keyfp) fclose(keyfp);
128 	if (infile && infp) fclose(infp);
129 	if (outfile && outfp) fclose(outfp);
130 	return ret;
131 }
132