sm2verify.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. #include <stdio.h>
  10. #include <errno.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <gmssl/sm2.h>
  14. #include <gmssl/x509.h>
  15. static const char *options = "(-pubkey pem | -cert pem) [-id str] [-in file] -sig file";
  16. int sm2verify_main(int argc, char **argv)
  17. {
  18. int ret = 1;
  19. char *prog = argv[0];
  20. char *id = SM2_DEFAULT_ID;
  21. char *pubkeyfile = NULL;
  22. char *certfile = NULL;
  23. char *infile = NULL;
  24. char *sigfile = NULL;
  25. FILE *pubkeyfp = NULL;
  26. FILE *certfp = NULL;
  27. FILE *infp = stdin;
  28. FILE *sigfp = NULL;
  29. SM2_KEY key;
  30. SM2_SIGN_CTX verify_ctx;
  31. uint8_t cert[1024];
  32. size_t certlen;
  33. uint8_t buf[4096];
  34. size_t len;
  35. uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
  36. size_t siglen;
  37. int vr;
  38. argc--;
  39. argv++;
  40. if (argc < 1) {
  41. fprintf(stderr, "usage: %s %s\n", prog, options);
  42. return 1;
  43. }
  44. while (argc > 0) {
  45. if (!strcmp(*argv, "-help")) {
  46. printf("usage: %s %s\n", prog, options);
  47. ret = 0;
  48. goto end;
  49. } else if (!strcmp(*argv, "-pubkey")) {
  50. if (certfile) {
  51. fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog);
  52. goto end;
  53. }
  54. if (--argc < 1) goto bad;
  55. pubkeyfile = *(++argv);
  56. if (!(pubkeyfp = fopen(pubkeyfile, "rb"))) {
  57. fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno));
  58. goto end;
  59. }
  60. } else if (!strcmp(*argv, "-cert")) {
  61. if (pubkeyfile) {
  62. fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog);
  63. goto end;
  64. }
  65. if (--argc < 1) goto bad;
  66. certfile = *(++argv);
  67. if (!(certfp = fopen(certfile, "rb"))) {
  68. fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno));
  69. goto end;
  70. }
  71. } else if (!strcmp(*argv, "-id")) {
  72. if (--argc < 1) goto bad;
  73. id = *(++argv);
  74. } else if (!strcmp(*argv, "-in")) {
  75. if (--argc < 1) goto bad;
  76. infile = *(++argv);
  77. if (!(infp = fopen(infile, "rb"))) {
  78. fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
  79. goto end;
  80. }
  81. } else if (!strcmp(*argv, "-sig")) {
  82. if (--argc < 1) goto bad;
  83. sigfile = *(++argv);
  84. if (!(sigfp = fopen(sigfile, "rb"))) {
  85. fprintf(stderr, "%s: open '%s' failure : %s\n", prog, sigfile, strerror(errno));
  86. goto end;
  87. }
  88. } else {
  89. fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
  90. goto end;
  91. bad:
  92. fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
  93. goto end;
  94. }
  95. argc--;
  96. argv++;
  97. }
  98. if (!sigfile) {
  99. fprintf(stderr, "%s: '-sig' option required\n", prog);
  100. goto end;
  101. }
  102. if ((siglen = fread(sig, 1, sizeof(sig), sigfp)) <= 0) {
  103. fprintf(stderr, "%s: read signature error : %s\n", prog, strerror(errno));
  104. goto end;
  105. }
  106. if (pubkeyfile) {
  107. if (sm2_public_key_info_from_pem(&key, pubkeyfp) != 1) {
  108. fprintf(stderr, "%s: parse public key failed\n", prog);
  109. goto end;
  110. }
  111. } else if (certfile) {
  112. if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1
  113. || x509_cert_get_subject_public_key(cert, certlen, &key) != 1) {
  114. fprintf(stderr, "%s: parse certificate failed\n", prog);
  115. goto end;
  116. }
  117. } else {
  118. fprintf(stderr, "%s: '-pubkey' or '-cert' option required\n", prog);
  119. goto end;
  120. }
  121. if (sm2_verify_init(&verify_ctx, &key, id, strlen(id)) != 1) {
  122. fprintf(stderr, "%s: inner error\n", prog);
  123. goto end;
  124. }
  125. while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) {
  126. if (sm2_verify_update(&verify_ctx, buf, len) != 1) {
  127. fprintf(stderr, "%s: inner error\n", prog);
  128. goto end;
  129. }
  130. }
  131. if ((vr = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) {
  132. fprintf(stderr, "%s: inner error\n", prog);
  133. goto end;
  134. }
  135. fprintf(stdout, "verify : %s\n", vr == 1 ? "success" : "failure");
  136. if (vr == 1) {
  137. ret = 0;
  138. }
  139. end:
  140. if (infile && infp) fclose(infp);
  141. if (pubkeyfp) fclose(pubkeyfp);
  142. if (certfp) fclose(certfp);
  143. if (sigfp) fclose(sigfp);
  144. return ret;
  145. }