mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
Update Tools
This commit is contained in:
125
tools/certgen.c
125
tools/certgen.c
@@ -47,14 +47,22 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/mem.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/x509_ext.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
static const char *options =
|
||||
"[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num "
|
||||
"-key file [-pass pass] "
|
||||
"[-key_usage str]* [-out file]";
|
||||
|
||||
|
||||
static int ext_key_usage_set(int *usages, const char *usage_name)
|
||||
{
|
||||
@@ -67,18 +75,6 @@ static int ext_key_usage_set(int *usages, const char *usage_name)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static const char *options =
|
||||
"[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num "
|
||||
"-key file [-pass pass] "
|
||||
"[-key_usage str]*";
|
||||
|
||||
|
||||
int certgen_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
@@ -91,12 +87,10 @@ int certgen_main(int argc, char **argv)
|
||||
char *common_name = NULL;
|
||||
int days = 0;
|
||||
int key_usage = 0;
|
||||
char *file = NULL;
|
||||
FILE *outfp = stdout;
|
||||
FILE *keyfp = NULL;
|
||||
char *keyfile = NULL;
|
||||
char *pass = NULL;
|
||||
char *outfile = NULL;
|
||||
|
||||
SM2_KEY sm2_key;
|
||||
uint8_t serial[12];
|
||||
uint8_t name[256];
|
||||
size_t namelen;
|
||||
@@ -105,17 +99,25 @@ int certgen_main(int argc, char **argv)
|
||||
uint8_t uniq_id[32];
|
||||
uint8_t exts[512];
|
||||
size_t extslen = 0;
|
||||
FILE *keyfp = NULL;
|
||||
SM2_KEY sm2_key;
|
||||
uint8_t cert[1024];
|
||||
size_t certlen;
|
||||
FILE *outfp = stdout;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (argc > 0) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
help:
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
return 0;
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-CN")) {
|
||||
if (--argc < 1) goto bad;
|
||||
common_name = *(++argv);
|
||||
@@ -137,64 +139,66 @@ help:
|
||||
} else if (!strcmp(*argv, "-days")) {
|
||||
if (--argc < 1) goto bad;
|
||||
days = atoi(*(++argv));
|
||||
if (days <= 0) {
|
||||
fprintf(stderr, "%s: invalid '-days' value\n", prog);
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-key_usage")) {
|
||||
if (--argc < 1) goto bad;
|
||||
if (ext_key_usage_set(&key_usage, *(++argv)) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
fprintf(stderr, "%s: invalid -key_usage value\n", prog);
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-key")) {
|
||||
if (--argc < 1) goto bad;
|
||||
file = *(++argv);
|
||||
if (!(keyfp = fopen(file, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
keyfile = *(++argv);
|
||||
if (!(keyfp = fopen(keyfile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-pass")) {
|
||||
if (--argc < 1) goto bad;
|
||||
pass = *(++argv);
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
file = *(++argv);
|
||||
if (!(outfp = fopen(file, "w"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
bad:
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!common_name || days <= 0) {
|
||||
fprintf(stderr, "%s: missing options\n", prog);
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
if (!common_name) {
|
||||
fprintf(stderr, "%s: '-CN' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!days) {
|
||||
fprintf(stderr, "%s: '-days' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!keyfile) {
|
||||
fprintf(stderr, "%s: '-key' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!pass) {
|
||||
pass = getpass("Encryption Password : ");
|
||||
}
|
||||
if (!pass || strlen(pass) == 0) {
|
||||
fprintf(stderr, "%s: '-pass' option required\n", prog);
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (keyfp == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) {
|
||||
error_print();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) {
|
||||
fprintf(stderr, "%s: load private key failed\n", prog);
|
||||
goto end;
|
||||
}
|
||||
time(¬_before);
|
||||
if (rand_bytes(serial, sizeof(serial)) != 1
|
||||
|| x509_name_set(name, &namelen, sizeof(name),
|
||||
@@ -213,14 +217,19 @@ bad:
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
exts, extslen,
|
||||
&sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1
|
||||
|| x509_cert_to_pem(cert, certlen, outfp) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
&sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) {
|
||||
fprintf(stderr, "%s: inner error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (x509_cert_to_pem(cert, certlen, outfp) != 1) {
|
||||
fprintf(stderr, "%s: output certificate failed\n", prog);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
memset(&sm2_key, 0, sizeof(SM2_KEY));
|
||||
gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY));
|
||||
if (keyfp) fclose(keyfp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -47,20 +47,23 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
static const char *options = "[-in file]";
|
||||
|
||||
static const char *options = "[-in file] [-out file]";
|
||||
|
||||
int certparse_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL;
|
||||
FILE *infp = stdin;
|
||||
|
||||
FILE *outfp = stdout;
|
||||
uint8_t cert[18192];
|
||||
size_t certlen;
|
||||
|
||||
@@ -70,38 +73,49 @@ int certparse_main(int argc, char **argv)
|
||||
while (argc > 0) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
return 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: llegal option '%s'\n", prog, *argv);
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (infile) {
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
for (;;) {
|
||||
int rv;
|
||||
if ((rv = x509_cert_from_pem(cert, &certlen, sizeof(cert), infp)) != 1) {
|
||||
if (rv < 0) fprintf(stderr, "%s: read certificate failure\n", prog);
|
||||
else ret = 0;
|
||||
goto end;
|
||||
}
|
||||
x509_cert_print(outfp, 0, 0, "Certificate", cert, certlen);
|
||||
if (x509_cert_to_pem(cert, certlen, outfp) != 1) {
|
||||
fprintf(stderr, "%s: output certficate failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
if ((ret = x509_cert_from_pem(cert, &certlen, sizeof(cert), infp)) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
} else if (!ret) {
|
||||
break;
|
||||
}
|
||||
x509_cert_print(stdout, 0, 0, "Certificate", cert, certlen);
|
||||
x509_cert_to_pem(cert, certlen, stdout);
|
||||
}
|
||||
return 0;
|
||||
end:
|
||||
if (infile && infp) fclose(infp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -47,94 +47,98 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
// 验证证书链是一个重量级的功能,应准备相应的文档,列举所有验证项目
|
||||
// 比如最基本的是证书中的签名、有效期、各个扩展等
|
||||
// 外部相关的:证书链、CRL等
|
||||
|
||||
static const char *options = "[-in pem] -cacert pem (-id str)\n";
|
||||
|
||||
int certverify_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *certfile = NULL;
|
||||
FILE *certfp = NULL;
|
||||
|
||||
char *infile = NULL;
|
||||
char *cacertfile = NULL;
|
||||
FILE *infp = stdin;
|
||||
FILE *cacertfp = NULL;
|
||||
|
||||
uint8_t cert[1024];
|
||||
size_t certlen;
|
||||
const uint8_t *issuer;
|
||||
size_t issuer_len;
|
||||
uint8_t cacert[1024];
|
||||
size_t cacertlen;
|
||||
char *signer_id = SM2_DEFAULT_ID;
|
||||
|
||||
SM2_KEY ca_pubkey;
|
||||
int rv;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
while (argc >= 1) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("Usage: %s [-cert pem] -cacert pem\n", prog);
|
||||
return 0;
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (argc > 0) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-cert")) {
|
||||
if (--argc < 1) goto bad;
|
||||
certfile = *(++argv);
|
||||
if (!(certfp = fopen(certfile, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-cacert")) {
|
||||
if (--argc < 1) goto bad;
|
||||
cacertfile = *(++argv);
|
||||
if (!(cacertfp = fopen(cacertfile, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, cacertfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-id")) {
|
||||
if (--argc < 1) goto bad;
|
||||
signer_id = *(++argv);
|
||||
} else {
|
||||
printf("Usage: %s [-cert pem] -cacert pem\n", prog);
|
||||
return 0;
|
||||
break;
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!certfp || !cacertfp) {
|
||||
error_print();
|
||||
return -1;
|
||||
if (!cacertfile) {
|
||||
fprintf(stderr, "%s: '-cacert' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
if (x509_cert_from_pem(cert, &certlen, sizeof(cert), infp) != 1) {
|
||||
fprintf(stderr, "%s: read certificate failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (x509_cert_from_pem(cacert, &cacertlen, sizeof(cacert), cacertfp) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
if (x509_cert_get_subject(cert, certlen, &issuer, &issuer_len) != 1) {
|
||||
fprintf(stderr, "%s: parse certificate error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, signer_id, strlen(signer_id)) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
if (x509_cert_from_pem_by_subject(cacert, &cacertlen, sizeof(cacert), issuer, issuer_len, cacertfp) != 1) {
|
||||
fprintf(stderr, "%s: load CA certificate failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
ret = 1;
|
||||
printf("Verification %s\n", ret ? "success" : "failure");
|
||||
|
||||
if ((rv = x509_cert_verify_by_ca_cert(cert, certlen, cacert, cacertlen, signer_id, strlen(signer_id))) < 0) {
|
||||
fprintf(stderr, "%s: inner error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
printf("Verification %s\n", rv ? "success" : "failure");
|
||||
ret = 0;
|
||||
goto end;
|
||||
|
||||
bad:
|
||||
fprintf(stderr, "%s: commands should not be used together\n", prog);
|
||||
|
||||
end:
|
||||
if (infile && infp) fclose(infp);
|
||||
if (cacertfp) fclose(cacertfp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
215
tools/cmsdecrypt.c
Normal file
215
tools/cmsdecrypt.c
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/cms.h>
|
||||
|
||||
|
||||
|
||||
static const char *options = "-key file -pass str -cert file -in file [-out file]";
|
||||
|
||||
int cmsdecrypt_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *keyfile = NULL;
|
||||
char *pass = NULL;
|
||||
char *certfile = NULL;
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL;
|
||||
FILE *keyfp = NULL;
|
||||
FILE *certfp = NULL;
|
||||
FILE *infp = NULL;
|
||||
FILE *outfp = stdout;
|
||||
uint8_t cert[1024];
|
||||
size_t certlen;
|
||||
struct stat st;
|
||||
uint8_t *cms = NULL;
|
||||
size_t cmslen, cms_maxlen;
|
||||
SM2_KEY key;
|
||||
int content_type;
|
||||
uint8_t *content = NULL;
|
||||
size_t content_len;
|
||||
const uint8_t *rcpt_infos;
|
||||
size_t rcpt_infos_len;
|
||||
const uint8_t *shared_info1;
|
||||
const uint8_t *shared_info2;
|
||||
size_t shared_info1_len, shared_info2_len;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (argc > 1) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-key")) {
|
||||
if (--argc < 1) goto bad;
|
||||
keyfile = *(++argv);
|
||||
if (!(keyfp = fopen(keyfile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-pass")) {
|
||||
if (--argc < 1) goto bad;
|
||||
pass = *(++argv);
|
||||
} else if (!strcmp(*argv, "-cert")) {
|
||||
if (--argc < 1) goto bad;
|
||||
certfile = *(++argv);
|
||||
if (!(certfp = fopen(certfile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!keyfile) {
|
||||
fprintf(stderr, "%s: '-key' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!pass) {
|
||||
fprintf(stderr, "%s: '-pass' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!certfile) {
|
||||
fprintf(stderr, "%s: '-cert' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!infile) {
|
||||
fprintf(stderr, "%s: '-in' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) {
|
||||
fprintf(stderr, "%s: private key decryption failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) {
|
||||
fprintf(stderr, "%s: load certificate failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
fstat(fileno(infp), &st);
|
||||
cms_maxlen = (st.st_size * 3)/4 + 1;
|
||||
if (!(cms = malloc(cms_maxlen))) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) {
|
||||
fprintf(stderr, "%s: read CMS failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(content = malloc(cmslen))) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cms_deenvelop(cms, cmslen,
|
||||
&key, cert, certlen,
|
||||
&content_type, content, &content_len,
|
||||
&rcpt_infos, &rcpt_infos_len,
|
||||
&shared_info1, &shared_info1_len,
|
||||
&shared_info2, &shared_info2_len) != 1) {
|
||||
fprintf(stderr, "%s: decryption failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (content_type != OID_cms_data) {
|
||||
fprintf(stderr, "%s: invalid CMS content type: %s\n", prog, cms_content_type_name(content_type));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (fwrite(content, 1, content_len, outfp) != content_len) {
|
||||
fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
if (infile && infp) fclose(infp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
if (keyfile && keyfp) fclose(keyfp);
|
||||
if (cms) free(cms);
|
||||
if (content) free(content);
|
||||
return ret;
|
||||
}
|
||||
270
tools/cmsencrypt.c
Normal file
270
tools/cmsencrypt.c
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <gmssl/cms.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
|
||||
|
||||
/*
|
||||
|
||||
签名的时候要提供签名者的证书,并且提供签名私钥
|
||||
但是验证的时候假定CMS中已经包含签名者的证书了,但是我们要提供CA证书库
|
||||
|
||||
加密的时候要指定接收者的证书,并且可以有多个接收者
|
||||
解密的时候只提供一个解密私钥,但是最好配合解密者的证书,从这个证书中找到解密者的名字
|
||||
|
||||
如果即加密又签名,那么输出的是SignedAndEnveloped
|
||||
|
||||
CMS有PEM吗?
|
||||
|
||||
cms -encrypt -rcpt a.pem -rcpt b.pem -rcpt c.pem -in file -sign -signcert a.pem -signcert b.pem
|
||||
-rcptcert -rcpt_cert -sign_cert b.pem -signkey
|
||||
|
||||
首先接收者可以有多个证书
|
||||
|
||||
这里面有个问题,因为我们要输出一个加密的对象,因此我们必须把输入的内容读取进来。
|
||||
|
||||
|
||||
EnvelopedData 是一个封装的SEQUENCE中,因此必须读取所有的内容。
|
||||
如果是一个文件,就需要读取所有的文件内容,如果是一个stream ,也需要读取完整的内容到一个足够大的buffer中,如何设置这个buffer的大小呢
|
||||
|
||||
|
||||
|
||||
对于输入文件,如果输入有文件名的话,可以直接通过stat获取文件长度
|
||||
但是如果对于stream的话,实际上我们是没有办法获得输入长度的,那么就直接准备一个buffer好了。
|
||||
不要给自己找麻烦了,直接只支持文件输入吧
|
||||
encrypt
|
||||
|
||||
*/
|
||||
|
||||
static const char *options = "-encrypt (-rcptcert pem)* -in file -out file";
|
||||
|
||||
|
||||
static int get_files_size(int argc, char **argv, const char *option, size_t *len)
|
||||
{
|
||||
char *prog = argv[0];
|
||||
char *file = NULL;
|
||||
FILE *fp = NULL;
|
||||
struct stat st;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
*len = 0;
|
||||
while (argc > 1) {
|
||||
if (!strcmp(*argv, option)) {
|
||||
if (--argc < 1) {
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
return -1;
|
||||
}
|
||||
file = *(++argv);
|
||||
if (!(fp = fopen(file, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failed : %s\n", prog, file, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (fstat(fileno(fp), &st) < 0) {
|
||||
fprintf(stderr, "%s: access '%s' failed : %s\n", prog, file, strerror(errno));
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
*len += st.st_size;
|
||||
fclose(fp);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cmsencrypt_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
int op = 0;
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL;
|
||||
FILE *infp = stdin;
|
||||
FILE *outfp = stdout;
|
||||
uint8_t *rcpt_certs = NULL;
|
||||
size_t rcpt_certs_len;
|
||||
uint8_t key[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t *inbuf = NULL;
|
||||
size_t inlen;
|
||||
uint8_t *cms = NULL;
|
||||
size_t cmslen;
|
||||
uint8_t *cert;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 预先统计证书缓冲大小和输入大小
|
||||
if (get_files_size(argc, argv, "-rcptcert", &rcpt_certs_len) != 1) {
|
||||
goto end;
|
||||
}
|
||||
if (rcpt_certs_len <= 0) {
|
||||
fprintf(stderr, "%s: invalid cert length\n", prog);
|
||||
goto end;
|
||||
}
|
||||
rcpt_certs_len = (rcpt_certs_len * 3)/4;
|
||||
if (!(rcpt_certs = malloc(rcpt_certs_len))) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
cert = rcpt_certs;
|
||||
|
||||
if (get_files_size(argc, argv, "-in", &inlen) != 1) {
|
||||
goto end;
|
||||
}
|
||||
if (inlen <= 0) {
|
||||
fprintf(stderr, "%s: invalid input length\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!(inbuf = malloc(inlen))) {
|
||||
fprintf(stderr, "%s: %s\n", prog, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
while (argc > 1) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-rcptcert")) {
|
||||
char *certfile;
|
||||
FILE *certfp;
|
||||
size_t certlen;
|
||||
if (--argc < 1) goto bad;
|
||||
certfile = *(++argv);
|
||||
if (!(certfp = fopen(certfile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
if (x509_cert_from_pem(cert, &certlen, rcpt_certs_len, certfp) != 1) {
|
||||
fprintf(stderr, "%s: error\n", prog);
|
||||
fclose(certfp);
|
||||
goto end;
|
||||
}
|
||||
cert += certlen;
|
||||
fclose(certfp);
|
||||
} else if (!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
if ((inlen = fread(inbuf, 1, inlen, infp)) <= 0) {
|
||||
fprintf(stderr, "%s: read data error: %s\n", prog, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
rcpt_certs_len = cert - rcpt_certs;
|
||||
|
||||
if (rand_bytes(key, sizeof(key)) != 1
|
||||
|| rand_bytes(iv, sizeof(iv)) != 1
|
||||
|| cms_envelop(NULL, &cmslen, rcpt_certs, rcpt_certs_len,
|
||||
OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv),
|
||||
OID_cms_data, inbuf, inlen, NULL, 0, NULL, 0) != 1) {
|
||||
fprintf(stderr, "%s: inner error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!(cms = malloc(cmslen))) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (cms_envelop(cms, &cmslen, rcpt_certs, rcpt_certs_len,
|
||||
OID_sm4_cbc, key, sizeof(key), iv, sizeof(iv),
|
||||
OID_cms_data, inbuf, inlen, NULL, 0, NULL, 0) != 1) {
|
||||
fprintf(stderr, "%s: inner error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (cms_to_pem(cms, cmslen, outfp) != 1) {
|
||||
fprintf(stderr, "%s: output CMS failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
if (infile && infp) fclose(infp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
if (rcpt_certs) free(rcpt_certs);
|
||||
if (cms) free(cms);
|
||||
return ret;
|
||||
}
|
||||
126
tools/cmsparse.c
Normal file
126
tools/cmsparse.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <gmssl/cms.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
|
||||
|
||||
static const char *options = "-in file";
|
||||
|
||||
int cmsparse_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *infile = NULL;
|
||||
FILE *infp = stdin;
|
||||
struct stat st;
|
||||
uint8_t *cms = NULL;
|
||||
size_t cms_maxlen, cmslen;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
while (argc > 1) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!infile) {
|
||||
fprintf(stderr, "%s: option '-in' required'\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (fstat(fileno(infp), &st) < 0) {
|
||||
fprintf(stderr, "%s: access '%s' failed : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
cms_maxlen = (st.st_size * 3)/4 + 1;
|
||||
if (!(cms = malloc(cms_maxlen))) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) {
|
||||
fprintf(stderr, "%s: parse CMS error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
cms_print(stdout, 0, 0, "CMS", cms, cmslen);
|
||||
ret = 0;
|
||||
end:
|
||||
if (infp) fclose(infp);
|
||||
if (cms) free(cms);
|
||||
return ret;
|
||||
}
|
||||
246
tools/cmssign.c
Normal file
246
tools/cmssign.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/cms.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
/*
|
||||
302 typedef struct {
|
||||
303 uint8_t *certs;
|
||||
304 size_t certs_len;
|
||||
305 SM2_KEY *sign_key;
|
||||
306 } CMS_CERTS_AND_KEY;
|
||||
|
||||
|
||||
|
||||
输出长度主要由输入长度和
|
||||
|
||||
*/
|
||||
|
||||
static const char *options = "-key file -pass str -cert file -in file [-out file]";
|
||||
|
||||
int cmssign_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *keyfile = NULL;
|
||||
char *pass = NULL;
|
||||
char *certfile = NULL;
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL;
|
||||
FILE *keyfp = NULL;
|
||||
FILE *certfp = NULL;
|
||||
FILE *infp = NULL;
|
||||
FILE *outfp = stdout;
|
||||
SM2_KEY key;
|
||||
uint8_t cert[1024];
|
||||
size_t certlen;
|
||||
struct stat st;
|
||||
uint8_t *in = NULL;
|
||||
size_t inlen;
|
||||
uint8_t *cms = NULL;
|
||||
size_t cmslen, cms_maxlen;
|
||||
CMS_CERTS_AND_KEY cert_and_key;
|
||||
|
||||
int content_type;
|
||||
uint8_t *content = NULL;
|
||||
size_t content_len;
|
||||
|
||||
const uint8_t *rcpt_infos;
|
||||
size_t rcpt_infos_len;
|
||||
const uint8_t *shared_info1;
|
||||
const uint8_t *shared_info2;
|
||||
size_t shared_info1_len, shared_info2_len;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (argc > 1) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-key")) {
|
||||
if (--argc < 1) goto bad;
|
||||
keyfile = *(++argv);
|
||||
if (!(keyfp = fopen(keyfile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-pass")) {
|
||||
if (--argc < 1) goto bad;
|
||||
pass = *(++argv);
|
||||
} else if (!strcmp(*argv, "-cert")) {
|
||||
if (--argc < 1) goto bad;
|
||||
certfile = *(++argv);
|
||||
if (!(certfp = fopen(certfile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!keyfile) {
|
||||
fprintf(stderr, "%s: '-key' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!pass) {
|
||||
fprintf(stderr, "%s: '-pass' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!certfile) {
|
||||
fprintf(stderr, "%s: '-cert' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!infile) {
|
||||
fprintf(stderr, "%s: '-in' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) {
|
||||
fprintf(stderr, "%s: private key decryption failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) {
|
||||
fprintf(stderr, "%s: load certificate failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
{
|
||||
SM2_KEY public_key;
|
||||
if (x509_cert_get_subject_public_key(cert, certlen, &public_key) != 1) {
|
||||
fprintf(stderr, "%s: parse certficate failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (sm2_public_key_equ(&key, &public_key) != 1) {
|
||||
fprintf(stderr, "%s: key and cert are not match!\n", prog);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
cert_and_key.certs = cert;
|
||||
cert_and_key.certs_len = certlen;
|
||||
cert_and_key.sign_key = &key;
|
||||
|
||||
if (fstat(fileno(infp), &st) < 0) {
|
||||
fprintf(stderr, "%s: access file error : %s\n", prog, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
if ((inlen = st.st_size) <= 0) {
|
||||
fprintf(stderr, "%s: invalid input length\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!(in = malloc(inlen))) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (fread(in, 1, inlen, infp) != inlen) {
|
||||
fprintf(stderr, "%s: read file error : %s\n", prog, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
cms_maxlen = (inlen * 4)/3 + 4096; // 主要由SignerInfos,其中的DN长度决定
|
||||
if (!(cms = malloc(cms_maxlen))) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cms_sign(cms, &cmslen, &cert_and_key, 1, OID_cms_data, in, inlen, NULL, 0) != 1) {
|
||||
fprintf(stderr, "%s: sign failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cms_to_pem(cms, cmslen, outfp) != 1) {
|
||||
fprintf(stderr, "%s: output failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
if (infile && infp) fclose(infp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
if (keyfile && keyfp) fclose(keyfp);
|
||||
if (cms) free(cms);
|
||||
if (in) free(in);
|
||||
return ret;
|
||||
}
|
||||
177
tools/cmsverify.c
Normal file
177
tools/cmsverify.c
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <gmssl/cms.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/rand.h>
|
||||
|
||||
|
||||
|
||||
static const char *options = "-in file [-out file]";
|
||||
|
||||
int cmsverify_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL;
|
||||
FILE *infp = NULL;
|
||||
FILE *outfp = NULL;
|
||||
struct stat st;
|
||||
uint8_t *cms = NULL;
|
||||
size_t cmslen, cms_maxlen;
|
||||
|
||||
int content_type;
|
||||
const uint8_t *content;
|
||||
size_t content_len;
|
||||
const uint8_t *certs;
|
||||
size_t certslen;
|
||||
const uint8_t *crls;
|
||||
size_t crlslen;
|
||||
const uint8_t *signer_infos;
|
||||
size_t signer_infos_len;
|
||||
int rv;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (argc > 1) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!infile) {
|
||||
fprintf(stderr, "%s: '-in' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
fstat(fileno(infp), &st);
|
||||
cms_maxlen = (st.st_size * 3)/4 + 1;
|
||||
if (!(cms = malloc(cms_maxlen))) {
|
||||
fprintf(stderr, "%s: malloc failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (cms_from_pem(cms, &cmslen, cms_maxlen, infp) != 1) {
|
||||
fprintf(stderr, "%s: read CMS failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((rv = cms_verify(cms, cmslen, NULL, 0, NULL, 0,
|
||||
&content_type, &content, &content_len,
|
||||
&certs, &certslen, &crls, &crlslen,
|
||||
&signer_infos, &signer_infos_len)) < 0) {
|
||||
fprintf(stderr, "%s: verify error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
printf("verify %s\n", rv ? "success" : "failure");
|
||||
ret = rv ? 0 : 1;
|
||||
|
||||
if (outfile) {
|
||||
const uint8_t *p;
|
||||
size_t len;
|
||||
|
||||
if (content_type == OID_cms_data) {
|
||||
if (asn1_octet_string_from_der(&p, &len, &content, &content_len) != 1
|
||||
|| asn1_length_is_zero(content_len) != 1) {
|
||||
fprintf(stderr, "%s: invalid CMS\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (len != fwrite(p, 1, len, outfp)) {
|
||||
fprintf(stderr, "%s: output error : %s\n", prog, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
end:
|
||||
if (infile && infp) fclose(infp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
if (cms) free(cms);
|
||||
return ret;
|
||||
}
|
||||
@@ -47,22 +47,24 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/x509_crl.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
static const char *options = "[-in file]";
|
||||
|
||||
static const char *options = "[-in file] [-out file]";
|
||||
|
||||
int crlparse_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL;
|
||||
FILE *infp = stdin;
|
||||
|
||||
uint8_t crl[18192];
|
||||
FILE *outfp = stdout;
|
||||
uint8_t crl[64 * 1024];
|
||||
size_t crllen;
|
||||
|
||||
argc--;
|
||||
@@ -71,38 +73,50 @@ int crlparse_main(int argc, char **argv)
|
||||
while (argc > 0) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
return 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: llegal option '%s'\n", prog, *argv);
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (infile) {
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
for (;;) {
|
||||
int rv;
|
||||
|
||||
if ((rv = x509_crl_from_fp(crl, &crllen, sizeof(crl), infp)) != 1) {
|
||||
if (rv < 0) fprintf(stderr, "%s: read CRL failure\n", prog);
|
||||
else ret = 0;
|
||||
goto end;
|
||||
}
|
||||
x509_crl_print(outfp, 0, 0, "CRL", crl, crllen);
|
||||
if (x509_crl_to_pem(crl, crllen, outfp) != 1) {
|
||||
fprintf(stderr, "%s: output CRL failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int ret;
|
||||
if ((ret = x509_crl_from_pem(crl, &crllen, sizeof(crl), infp)) < 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
} else if (!ret) {
|
||||
break;
|
||||
}
|
||||
x509_crl_print(stdout, 0, 0, "CRL", crl, crllen);
|
||||
// x509_crl_to_pem(crl, crllen, stdout);
|
||||
}
|
||||
return 0;
|
||||
end:
|
||||
if (infile && infp) fclose(infp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,11 @@ extern int sm9sign_main(int argc, char **argv);
|
||||
extern int sm9verify_main(int argc, char **argv);
|
||||
extern int sm9encrypt_main(int argc, char **argv);
|
||||
extern int sm9decrypt_main(int argc, char **argv);
|
||||
extern int cmsparse_main(int argc, char **argv);
|
||||
extern int cmsencrypt_main(int argc, char **argv);
|
||||
extern int cmsdecrypt_main(int argc, char **argv);
|
||||
extern int cmssign_main(int argc, char **argv);
|
||||
extern int cmsverify_main(int argc, char **argv);
|
||||
extern int tlcp_client_main(int argc, char **argv);
|
||||
extern int tlcp_server_main(int argc, char **argv);
|
||||
extern int tls12_client_main(int argc, char **argv);
|
||||
@@ -90,18 +95,18 @@ static const char *options =
|
||||
"command [options]\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" help Print commands list or help for one command\n"
|
||||
" help Print this help message\n"
|
||||
" version Print version\n"
|
||||
" rand Generate random bytes\n"
|
||||
" sm2keygen Generate SM2 keypair\n"
|
||||
" sm2sign Generate SM2 signature\n"
|
||||
" sm2verify Verify SM2 signature\n"
|
||||
" sm2encrypt SM2 public key encryption\n"
|
||||
" sm2decrypt SM2 decryption\n"
|
||||
" sm2encrypt Encrypt with SM2 public key\n"
|
||||
" sm2decrypt Decrypt with SM2 private key\n"
|
||||
" sm3 Generate SM3 hash\n"
|
||||
" sm3hmac Generate HMAC-SM3 MAC tag\n"
|
||||
" sm4 Encrypt or decrypt data with SM4\n"
|
||||
" zuc Encrypt or decrypt data with ZUC\n"
|
||||
" sm3hmac Generate SM3 HMAC tag\n"
|
||||
" sm4 Encrypt or decrypt with SM4\n"
|
||||
" zuc Encrypt or decrypt with ZUC\n"
|
||||
" sm9setup Generate SM9 master secret\n"
|
||||
" sm9keygen Generate SM9 private key\n"
|
||||
" sm9sign Generate SM9 signature\n"
|
||||
@@ -109,21 +114,26 @@ static const char *options =
|
||||
" sm9encrypt SM9 public key encryption\n"
|
||||
" sm9decrypt SM9 decryption\n"
|
||||
" pbkdf2 Generate key from password\n"
|
||||
" reqgen Generate PKCS #10 certificate signing request (CSR)\n"
|
||||
" reqsign Generate a certificate from PKCS #10 CSR\n"
|
||||
" reqparse Parse and print a PKCS #10 CSR\n"
|
||||
" reqgen Generate certificate signing request (CSR)\n"
|
||||
" reqsign Generate certificate from CSR\n"
|
||||
" reqparse Parse and print a CSR\n"
|
||||
" crlparse Parse and print CRL\n"
|
||||
" certgen Generate a self-signed X.509 certificate in PEM format\n"
|
||||
" certparse Parse and print certificates in a PEM file\n"
|
||||
" certverify Verify certificate chain in a PEM file\n"
|
||||
" certgen Generate a self-signed certificate\n"
|
||||
" certparse Parse and print certificates\n"
|
||||
" certverify Verify certificate chain\n"
|
||||
" cmsparse Parse cryptographic message syntax (CMS)\n"
|
||||
" cmsencrypt Generate CMS EnvelopedData\n"
|
||||
" cmsdecrypt Decrypt CMS EnvelopedData\n"
|
||||
" cmssign Generate CMS SignedData\n"
|
||||
" cmsverify Verify CMS SignedData\n"
|
||||
" sdfutil SDF crypto device utility\n"
|
||||
" skfutil SKF crypto device utility\n"
|
||||
" tlcp_client TLCP client\n"
|
||||
" tlcp_server TLCP server\n"
|
||||
" tls12_client TLS 1.2 client\n"
|
||||
" tls12_server TLS 1.2 server\n"
|
||||
" tls13_client TLS 1.3 client\n"
|
||||
" tls13_server TLS 1.3 server\n"
|
||||
" sdfutil SDF crypto device utility\n"
|
||||
" skfutil SKF crypto device utility\n";
|
||||
" tls13_server TLS 1.3 server\n";
|
||||
|
||||
|
||||
|
||||
@@ -154,6 +164,8 @@ int main(int argc, char **argv)
|
||||
return certparse_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "certverify")) {
|
||||
return certverify_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "crlparse")) {
|
||||
return crlparse_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "reqgen")) {
|
||||
return reqgen_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "reqparse")) {
|
||||
@@ -192,6 +204,16 @@ int main(int argc, char **argv)
|
||||
return sm9encrypt_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "sm9decrypt")) {
|
||||
return sm9decrypt_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "cmsparse")) {
|
||||
return cmsparse_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "cmsencrypt")) {
|
||||
return cmsencrypt_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "cmsdecrypt")) {
|
||||
return cmsdecrypt_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "cmssign")) {
|
||||
return cmssign_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "cmsverify")) {
|
||||
return cmsverify_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "tlcp_client")) {
|
||||
return tlcp_client_main(argc, argv);
|
||||
} else if (!strcmp(*argv, "tlcp_server")) {
|
||||
|
||||
128
tools/reqgen.c
128
tools/reqgen.c
@@ -47,28 +47,23 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/mem.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/x509_req.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static const char *options =
|
||||
"[-C str] [-ST str] [-L str] [-O str] [-OU str] -CN str -days num"
|
||||
" -key file [-pass pass] [-out file]";
|
||||
|
||||
int reqgen_main(int argc, char **argv)
|
||||
{
|
||||
int ret = -1;
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *country = NULL;
|
||||
char *state = NULL;
|
||||
@@ -76,34 +71,31 @@ int reqgen_main(int argc, char **argv)
|
||||
char *org = NULL;
|
||||
char *org_unit = NULL;
|
||||
char *common_name = NULL;
|
||||
|
||||
char *file = NULL;
|
||||
char *pass = NULL;
|
||||
int days = 0;
|
||||
|
||||
FILE *keyfp = NULL;
|
||||
FILE *outfp = stdout;
|
||||
|
||||
uint8_t req[1024];
|
||||
size_t reqlen = 0;
|
||||
|
||||
char *keyfile = NULL;
|
||||
char *pass = NULL;
|
||||
char *outfile = NULL;
|
||||
uint8_t name[256];
|
||||
size_t namelen = 0;
|
||||
|
||||
SM2_KEY sm2_key; // 这个应该是从文件中读取的!
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
FILE *keyfp = NULL;
|
||||
FILE *outfp = stdout;
|
||||
uint8_t req[1024];
|
||||
size_t reqlen = 0;
|
||||
SM2_KEY sm2_key;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
while (argc >= 1) {
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (argc > 0) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
return 0;
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-C")) {
|
||||
if (--argc < 1) goto bad;
|
||||
country = *(++argv);
|
||||
@@ -122,51 +114,62 @@ int reqgen_main(int argc, char **argv)
|
||||
} else if (!strcmp(*argv, "-CN")) {
|
||||
if (--argc < 1) goto bad;
|
||||
common_name = *(++argv);
|
||||
} else if (!strcmp(*argv, "-days")) {
|
||||
if (--argc < 1) goto bad;
|
||||
days = atoi(*(++argv));
|
||||
if (days <= 0) {
|
||||
fprintf(stderr, "%s: invalid '-days' value\n", prog);
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-key")) {
|
||||
if (--argc < 1) goto bad;
|
||||
file = *(++argv);
|
||||
if (!(keyfp = fopen(file, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
keyfile = *(++argv);
|
||||
if (!(keyfp = fopen(keyfile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-pass")) {
|
||||
if (--argc < 1) goto bad;
|
||||
pass = *(++argv);
|
||||
} else if (!strcmp(*argv, "-days")) {
|
||||
if (--argc < 1) goto bad;
|
||||
days = atoi(*(++argv));
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
file = *(++argv);
|
||||
if (!(outfp = fopen(file, "w"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (!common_name || days <= 0 || !keyfp) {
|
||||
fprintf(stderr, "%s: missing options\n", prog);
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
if (!common_name) {
|
||||
fprintf(stderr, "%s: '-CN' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!days) {
|
||||
fprintf(stderr, "%s: '-days' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!keyfile) {
|
||||
fprintf(stderr, "%s: '-key' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!pass) {
|
||||
pass = getpass("Encryption Password : ");
|
||||
}
|
||||
if (!pass || strlen(pass) == 0) {
|
||||
fprintf(stderr, "%s: '-pass' option required\n", prog);
|
||||
error_print();
|
||||
return -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
fprintf(stderr, "%s: load private key failed\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (x509_name_set(name, &namelen, sizeof(name),
|
||||
@@ -177,13 +180,18 @@ bad:
|
||||
&sm2_key,
|
||||
NULL, 0,
|
||||
OID_sm2sign_with_sm3,
|
||||
&sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1
|
||||
|| x509_req_to_pem(req, reqlen, outfp) != 1) {
|
||||
memset(&sm2_key, 0, sizeof(SM2_KEY));
|
||||
error_print();
|
||||
return -1;
|
||||
&sm2_key, SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1) {
|
||||
fprintf(stderr, "%s: inner error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
memset(&sm2_key, 0, sizeof(SM2_KEY));
|
||||
return 0;
|
||||
if (x509_req_to_pem(req, reqlen, outfp) != 1) {
|
||||
fprintf(stderr, "%s: output CSR failed\n", prog);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY));
|
||||
if (keyfp) fclose(keyfp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -47,19 +47,23 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/x509_req.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
static const char *options = "[-in file] [-out file]";
|
||||
|
||||
int reqparse_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL;
|
||||
FILE *infp = stdin;
|
||||
FILE *outfp = stdout;
|
||||
uint8_t req[1024];
|
||||
size_t reqlen;
|
||||
|
||||
@@ -68,39 +72,46 @@ int reqparse_main(int argc, char **argv)
|
||||
|
||||
while (argc > 0) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
help:
|
||||
fprintf(stderr, "usage: %s [-in file]\n", prog);
|
||||
return -1;
|
||||
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
goto end;
|
||||
} else if(!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
infile = *(++argv);
|
||||
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto help;
|
||||
goto end;
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
if (infile) {
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (x509_req_from_pem(req, &reqlen, sizeof(req), infp) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
fprintf(stderr, "%s: read CSR failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
x509_req_print(stdout, 0, 0, "CertificationRequest", req, reqlen);
|
||||
x509_req_to_pem(req, reqlen, stdout);
|
||||
return 0;
|
||||
|
||||
bad:
|
||||
fprintf(stderr, "%s: '%s' option value required\n", prog, *argv);
|
||||
return -1;
|
||||
x509_req_print(outfp, 0, 0, "CertificationRequest", req, reqlen);
|
||||
if (x509_req_to_pem(req, reqlen, outfp) != 1) {
|
||||
fprintf(stderr, "%s: output CSR failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
if (infile && infp) fclose(infp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
173
tools/reqsign.c
173
tools/reqsign.c
@@ -47,43 +47,42 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <gmssl/pem.h>
|
||||
#include <gmssl/mem.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/x509.h>
|
||||
#include <gmssl/x509_ext.h>
|
||||
#include <gmssl/x509_req.h>
|
||||
#include <gmssl/pkcs8.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
static const char *options = "[-in pem] -days num -cacert pem -key pem [-pass str] [-out pem]\n";
|
||||
|
||||
static int ext_key_usage_set(int *usages, const char *usage_name)
|
||||
{
|
||||
int flag = 0;
|
||||
if (x509_key_usage_from_name(&flag, usage_name) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*usages |= flag;
|
||||
|
||||
printf("flag = %08x", flag);
|
||||
printf("usage = %08x", *usages);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const char *usage = "usage: %s [-in file] -days num -cacert file -key file [-pass str] [-out file]\n";
|
||||
|
||||
int reqsign_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
char *prog = argv[0];
|
||||
char *file;
|
||||
char *pass = NULL;
|
||||
char *infile = NULL;
|
||||
int days = 0;
|
||||
|
||||
char *cacertfile = NULL;
|
||||
char *keyfile = NULL;
|
||||
char *pass = NULL;
|
||||
char *outfile = NULL;
|
||||
FILE *infp = stdin;
|
||||
|
||||
FILE *cacertfp = NULL;
|
||||
FILE *keyfp = NULL;
|
||||
FILE *outfp = stdout;
|
||||
|
||||
uint8_t req[512];
|
||||
size_t reqlen;
|
||||
@@ -91,16 +90,12 @@ int reqsign_main(int argc, char **argv)
|
||||
size_t subject_len;
|
||||
SM2_KEY subject_public_key;
|
||||
|
||||
FILE *outfp = stdout;
|
||||
|
||||
FILE *cacertfp = NULL;
|
||||
uint8_t cacert[1024];
|
||||
size_t cacertlen;
|
||||
const uint8_t *issuer;
|
||||
size_t issuer_len;
|
||||
SM2_KEY issuer_public_key;
|
||||
|
||||
FILE *keyfp = NULL;
|
||||
SM2_KEY sm2_key;
|
||||
|
||||
uint8_t cert[1024];
|
||||
@@ -111,107 +106,121 @@ int reqsign_main(int argc, char **argv)
|
||||
size_t extslen = 0;
|
||||
int key_usage = 0;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, usage, prog);
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: %s %s\n", prog, options);
|
||||
return 1;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
while (argc >= 1) {
|
||||
if (!strcmp(*argv, "-help")) {
|
||||
help:
|
||||
printf(usage, prog);
|
||||
return 0;
|
||||
printf("usage: %s %s\n", prog, options);
|
||||
ret = 0;
|
||||
goto end;
|
||||
} else if (!strcmp(*argv, "-in")) {
|
||||
if (--argc < 1) goto bad;
|
||||
file = *(++argv);
|
||||
if (!(infp = fopen(file, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
infile = *(++argv);
|
||||
if (!(infp = fopen(infile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-days")) {
|
||||
if (--argc < 1) goto bad;
|
||||
days = atoi(*(++argv));
|
||||
if (days <= 0) {
|
||||
fprintf(stderr, "%s: invalid '-days' value\n", prog);
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-key_usage")) {
|
||||
if (--argc < 1) goto bad;
|
||||
if (ext_key_usage_set(&key_usage, *(++argv)) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
fprintf(stderr, "%s: set KeyUsage extenstion failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-cacert")) {
|
||||
if (--argc < 1) goto bad;
|
||||
file = *(++argv);
|
||||
if (!(cacertfp = fopen(file, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
cacertfile = *(++argv);
|
||||
if (!(cacertfp = fopen(cacertfile, "r"))) {
|
||||
fprintf(stderr, "%s: invalid -key_usage value\n", prog);
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-key")) {
|
||||
if (--argc < 1) goto bad;
|
||||
file = *(++argv);
|
||||
if (!(keyfp = fopen(file, "r"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
keyfile = *(++argv);
|
||||
if (!(keyfp = fopen(keyfile, "r"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else if (!strcmp(*argv, "-pass")) {
|
||||
if (--argc < 1) goto bad;
|
||||
pass = *(++argv);
|
||||
|
||||
} else if (!strcmp(*argv, "-out")) {
|
||||
if (--argc < 1) goto bad;
|
||||
file = *(++argv);
|
||||
if (!(outfp = fopen(file, "w"))) {
|
||||
error_print();
|
||||
return -1;
|
||||
outfile = *(++argv);
|
||||
if (!(outfp = fopen(outfile, "w"))) {
|
||||
fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
|
||||
goto end;
|
||||
bad:
|
||||
error_print();
|
||||
break;
|
||||
fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
|
||||
goto end;
|
||||
}
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
if (days <= 0
|
||||
|| !infp
|
||||
|| !cacertfp
|
||||
|| !keyfp) {
|
||||
error_print();
|
||||
return -1;
|
||||
|
||||
if (!days) {
|
||||
fprintf(stderr, "%s: '-days' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!cacertfile) {
|
||||
fprintf(stderr, "%s: '-cacert' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!keyfile) {
|
||||
fprintf(stderr, "%s: '-key' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!pass) {
|
||||
fprintf(stderr, "%s: '-pass' option required\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
if (x509_req_from_pem(req, &reqlen, sizeof(req), infp) != 1
|
||||
|| x509_req_get_details(req, reqlen,
|
||||
NULL, &subject, &subject_len, &subject_public_key,
|
||||
NULL, NULL, NULL, NULL, NULL) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
fprintf(stderr, "%s: parse CSR failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (x509_cert_from_pem(cacert, &cacertlen, sizeof(cacert), cacertfp) != 1
|
||||
|| x509_cert_get_subject(cacert, cacertlen, &issuer, &issuer_len) != 1
|
||||
|| x509_cert_get_subject_public_key(cacert, cacertlen, &issuer_public_key) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
fprintf(stderr, "%s: parse CA certificate failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!pass) {
|
||||
pass = getpass("Password : ");
|
||||
if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1) {
|
||||
fprintf(stderr, "%s: load private key failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
if (!pass || strlen(pass) == 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_private_key_info_decrypt_from_pem(&sm2_key, pass, keyfp) != 1
|
||||
|| sm2_public_key_equ(&sm2_key, &issuer_public_key) != 1) {
|
||||
error_print();
|
||||
memset(&sm2_key, 0, sizeof(SM2_KEY));
|
||||
return -1;
|
||||
if (sm2_public_key_equ(&sm2_key, &issuer_public_key) != 1) {
|
||||
fprintf(stderr, "%s: private key and CA certificate not match\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
rand_bytes(serial, sizeof(serial));
|
||||
if (rand_bytes(serial, sizeof(serial)) != 1) {
|
||||
fprintf(stderr, "%s: inner error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
time(¬_before);
|
||||
|
||||
if (x509_validity_add_days(¬_after, not_before, days) != 1
|
||||
@@ -228,14 +237,20 @@ bad:
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
exts, extslen,
|
||||
&sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1
|
||||
|| x509_cert_to_pem(cert, certlen, outfp) != 1) {
|
||||
memset(&sm2_key, 0, sizeof(SM2_KEY));
|
||||
error_print();
|
||||
return -1;
|
||||
&sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
|
||||
fprintf(stderr, "%s: inner error\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
// FIXME: fclose() ....
|
||||
memset(&sm2_key, 0, sizeof(SM2_KEY));
|
||||
return 0;
|
||||
if (x509_cert_to_pem(cert, certlen, outfp) != 1) {
|
||||
fprintf(stderr, "%s: output certificate failed\n", prog);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
gmssl_secure_clear(&sm2_key, sizeof(SM2_KEY));
|
||||
if (keyfp) fclose(keyfp);
|
||||
if (cacertfp) fclose(cacertfp);
|
||||
if (infile && infp) fclose(infp);
|
||||
if (outfile && outfp) fclose(outfp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -131,7 +131,7 @@ bad:
|
||||
}
|
||||
|
||||
if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) {
|
||||
fprintf(stderr, "%s: private key decryption failure", prog);
|
||||
fprintf(stderr, "%s: private key decryption failure\n", prog);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user