From d6df76600e8352aaa43f0a6c0d069956edea93ef Mon Sep 17 00:00:00 2001 From: guoshengxu Date: Tue, 14 Mar 2023 22:05:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86sm2keyparse=E9=83=A8?= =?UTF-8?q?=E5=88=86=20(#1423)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update gmssl.c 添加sm2keyparse功能,以十六进制明文查看SM2的公钥和私钥。 * Create sm2keyparse.c 增加sm2keyparse部分。 * Update CMakeLists.txt 增加tools/sm2keyparse.c * Update sm2keyparse.c --- CMakeLists.txt | 1 + tools/gmssl.c | 4 ++ tools/sm2keyparse.c | 135 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 tools/sm2keyparse.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b67506c8..056e83cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ set(tools tools/sm3.c tools/sm3hmac.c tools/sm2keygen.c + tools/sm2keyparse.c tools/sm2sign.c tools/sm2verify.c tools/sm2encrypt.c diff --git a/tools/gmssl.c b/tools/gmssl.c index ef2bd6d2..5d96dde4 100644 --- a/tools/gmssl.c +++ b/tools/gmssl.c @@ -28,6 +28,7 @@ extern int reqgen_main(int argc, char **argv); extern int reqparse_main(int argc, char **argv); extern int reqsign_main(int argc, char **argv); extern int sm2keygen_main(int argc, char **argv); +extern int sm2keyparse_main(int argc,char **argv); extern int sm2sign_main(int argc, char **argv); extern int sm2verify_main(int argc, char **argv); extern int sm2encrypt_main(int argc, char **argv); @@ -66,6 +67,7 @@ static const char *options = " version Print version\n" " rand Generate random bytes\n" " sm2keygen Generate SM2 keypair\n" + " sm2keyparse Parse SM2 key to hex plaintext\n" " sm2sign Generate SM2 signature\n" " sm2verify Verify SM2 signature\n" " sm2encrypt Encrypt with SM2 public key\n" @@ -157,6 +159,8 @@ int main(int argc, char **argv) return pbkdf2_main(argc, argv); } else if (!strcmp(*argv, "sm2keygen")) { return sm2keygen_main(argc, argv); + } else if (!strcmp(*argv, "sm2keyparse")) { + return sm2keyparse_main(argc, argv); } else if (!strcmp(*argv, "sm2sign")) { return sm2sign_main(argc, argv); } else if (!strcmp(*argv, "sm2verify")) { diff --git a/tools/sm2keyparse.c b/tools/sm2keyparse.c new file mode 100644 index 00000000..55afb98e --- /dev/null +++ b/tools/sm2keyparse.c @@ -0,0 +1,135 @@ +/* + * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + +#include +#include +#include +#include +#include +#include + + +static const char *usage = "-in private.pem -pass pass / -pubin public.pem"; + +static const char *options = +"Options\n" +" -pass pass Password to encrypt the private key\n" +" -in pem Input private key in PEM format\n" +" -pubin pem Input public key in PEM format\n" +"\n"; + + +int sm2keyparse_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *pass = NULL; + char *pubinfile = NULL; + char *infile = NULL; + FILE *pubinfp = NULL; + FILE *infp = NULL; + SM2_KEY key; + + argc--; + argv++; + + 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, usage); + printf("%s\n", options); + ret = 0; + goto end; + } else if(!strcmp(*argv,"-pubin")){ + if (--argc<1) goto bad; + pubinfile=(*++argv); + if (!(pubinfp = fopen(pubinfile, "rb"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubinfile, strerror(errno)); + goto end; + } + goto pubkey; + } else if(!strcmp(*argv, "-in")){ + if (--argc<1) goto bad; + infile = *(++argv); + if (!(infp = fopen(infile, "rb"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } 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 (!pass) { + fprintf(stderr, "%s: `-pass` option required\n", prog); + goto end; + } + + if (sm2_private_key_info_decrypt_from_pem(&key, pass, infp) != 1) { + fprintf(stderr, "%s: private key decryption failure\n", prog); + goto end; + } else { + printf("\n"); + for(int i=0;i<4;i++){ + for(int j=0;j<8;j++){ + printf("%02x ",key.private_key[i*8+j]); + } + printf("\n"); + } + printf("\n"); + } + + if(pubinfile){ +pubkey: + if (sm2_public_key_info_from_pem(&key, pubinfp) != 1) { + fprintf(stderr, "%s: parse public key failed\n", prog); + goto end; + } else { + printf("\nx:\n"); + for(int i=0;i<4;i++){ + for(int j=0;j<8;j++){ + printf("%02x ",key.public_key.x[i*8+j]); + } + printf("\n"); + } + printf("\n"); + + printf("y:\n"); + for(int i=0;i<4;i++){ + for(int j=0;j<8;j++){ + printf("%02x ",key.public_key.y[i*8+j]); + } + printf("\n"); + } + printf("\n"); + } + } + +end: + gmssl_secure_clear(&key, sizeof(key)); + if (infile && infp) fclose(infp); + if (pubinfile && pubinfp) fclose(pubinfp); + return ret; +} +