sm2encrypt.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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) [-in file] [-out file]";
  16. int sm2encrypt_main(int argc, char **argv)
  17. {
  18. int ret = 1;
  19. char *prog = argv[0];
  20. char *pubkeyfile = NULL;
  21. char *certfile = NULL;
  22. char *infile = NULL;
  23. char *outfile = NULL;
  24. FILE *pubkeyfp = NULL;
  25. FILE *certfp = NULL;
  26. FILE *infp = stdin;
  27. FILE *outfp = stdout;
  28. uint8_t cert[1024];
  29. size_t certlen;
  30. SM2_KEY key;
  31. uint8_t inbuf[SM2_MAX_PLAINTEXT_SIZE + 1];
  32. uint8_t outbuf[SM2_MAX_CIPHERTEXT_SIZE];
  33. size_t inlen, outlen = sizeof(outbuf);
  34. argc--;
  35. argv++;
  36. if (argc < 1) {
  37. fprintf(stderr, "usage: %s %s\n", prog, options);
  38. return 1;
  39. }
  40. while (argc > 1) {
  41. if (!strcmp(*argv, "-help")) {
  42. printf("usage: %s %s\n", prog, options);
  43. ret = 0;
  44. goto end;
  45. } else if (!strcmp(*argv, "-pubkey")) {
  46. if (certfile) {
  47. fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog);
  48. goto end;
  49. }
  50. if (--argc < 1) goto bad;
  51. pubkeyfile = *(++argv);
  52. if (!(pubkeyfp = fopen(pubkeyfile, "rb"))) {
  53. fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno));
  54. goto end;
  55. }
  56. } else if (!strcmp(*argv, "-cert")) {
  57. if (pubkeyfile) {
  58. fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog);
  59. goto end;
  60. }
  61. if (--argc < 1) goto bad;
  62. certfile = *(++argv);
  63. if (!(certfp = fopen(certfile, "rb"))) {
  64. fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno));
  65. goto end;
  66. }
  67. } else if (!strcmp(*argv, "-in")) {
  68. if (--argc < 1) goto bad;
  69. infile = *(++argv);
  70. if (!(infp = fopen(infile, "rb"))) {
  71. fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno));
  72. goto end;
  73. }
  74. } else if (!strcmp(*argv, "-out")) {
  75. if (--argc < 1) goto bad;
  76. outfile = *(++argv);
  77. if (!(outfp = fopen(outfile, "wb"))) {
  78. fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
  79. goto end;
  80. }
  81. } else {
  82. fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv);
  83. goto end;
  84. bad:
  85. fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv);
  86. goto end;
  87. }
  88. argc--;
  89. argv++;
  90. }
  91. if (pubkeyfile) {
  92. if (sm2_public_key_info_from_pem(&key, pubkeyfp) != 1) {
  93. fprintf(stderr, "%s: parse public key failed\n", prog);
  94. goto end;
  95. }
  96. } else if (certfile) {
  97. if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1
  98. || x509_cert_get_subject_public_key(cert, certlen, &key) != 1) {
  99. fprintf(stderr, "%s: parse certificate failed\n", prog);
  100. goto end;
  101. }
  102. } else {
  103. fprintf(stderr, "%s: '-pubkey' or '-cert' option required\n", prog);
  104. goto end;
  105. }
  106. if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) {
  107. fprintf(stderr, "%s: read input error : %s\n", prog, strerror(errno));
  108. goto end;
  109. }
  110. if (inlen > SM2_MAX_PLAINTEXT_SIZE) {
  111. fprintf(stderr, "%s: input long than SM2_MAX_PLAINTEXT_SIZE (%d)\n", prog, SM2_MAX_PLAINTEXT_SIZE);
  112. goto end;
  113. }
  114. if (sm2_encrypt(&key, inbuf, inlen, outbuf, &outlen) != 1) {
  115. fprintf(stderr, "%s: inner error\n", prog);
  116. goto end;
  117. }
  118. if (outlen != fwrite(outbuf, 1, outlen, outfp)) {
  119. fprintf(stderr, "%s: output error : %s\n", prog, strerror(errno));
  120. goto end;
  121. }
  122. ret = 0;
  123. end:
  124. if (infile && infp) fclose(infp);
  125. if (outfile && outfp) fclose(outfp);
  126. if (pubkeyfp) fclose(pubkeyfp);
  127. if (certfp) fclose(certfp);
  128. return ret;
  129. }