app_x509.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <string.h>
  10. #include "apps.h"
  11. /*
  12. * X509_ctrl_str() is sorely lacking in libcrypto, but is still needed to
  13. * allow the application to process verification options in a manner similar
  14. * to signature or other options that pass through EVP_PKEY_CTX_ctrl_str(),
  15. * for uniformity.
  16. *
  17. * As soon as more stuff is added, the code will need serious rework. For
  18. * the moment, it only handles the FIPS 196 / SM2 distinguishing ID.
  19. */
  20. #ifdef EVP_PKEY_CTRL_SET1_ID
  21. static ASN1_OCTET_STRING *mk_octet_string(void *value, size_t value_n)
  22. {
  23. ASN1_OCTET_STRING *v = ASN1_OCTET_STRING_new();
  24. if (v == NULL) {
  25. BIO_printf(bio_err, "error: allocation failed\n");
  26. } else if (!ASN1_OCTET_STRING_set(v, value, value_n)) {
  27. ASN1_OCTET_STRING_free(v);
  28. v = NULL;
  29. }
  30. return v;
  31. }
  32. #endif
  33. static int x509_ctrl(void *object, int cmd, void *value, size_t value_n)
  34. {
  35. switch (cmd) {
  36. #ifdef EVP_PKEY_CTRL_SET1_ID
  37. case EVP_PKEY_CTRL_SET1_ID:
  38. {
  39. ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
  40. if (v == NULL) {
  41. BIO_printf(bio_err,
  42. "error: setting distinguishing ID in certificate failed\n");
  43. return 0;
  44. }
  45. X509_set0_distinguishing_id(object, v);
  46. return 1;
  47. }
  48. #endif
  49. default:
  50. break;
  51. }
  52. return -2; /* typical EVP_PKEY return for "unsupported" */
  53. }
  54. static int x509_req_ctrl(void *object, int cmd, void *value, size_t value_n)
  55. {
  56. switch (cmd) {
  57. #ifdef EVP_PKEY_CTRL_SET1_ID
  58. case EVP_PKEY_CTRL_SET1_ID:
  59. {
  60. ASN1_OCTET_STRING *v = mk_octet_string(value, value_n);
  61. if (v == NULL) {
  62. BIO_printf(bio_err,
  63. "error: setting distinguishing ID in certificate signing request failed\n");
  64. return 0;
  65. }
  66. X509_REQ_set0_distinguishing_id(object, v);
  67. return 1;
  68. }
  69. #endif
  70. default:
  71. break;
  72. }
  73. return -2; /* typical EVP_PKEY return for "unsupported" */
  74. }
  75. static int do_x509_ctrl_string(int (*ctrl)(void *object, int cmd,
  76. void *value, size_t value_n),
  77. void *object, const char *value)
  78. {
  79. int rv = 0;
  80. char *stmp, *vtmp = NULL;
  81. size_t vtmp_len = 0;
  82. int cmd = 0; /* Will get command values that make sense somehow */
  83. stmp = OPENSSL_strdup(value);
  84. if (stmp == NULL)
  85. return -1;
  86. vtmp = strchr(stmp, ':');
  87. if (vtmp != NULL) {
  88. *vtmp = 0;
  89. vtmp++;
  90. vtmp_len = strlen(vtmp);
  91. }
  92. if (strcmp(stmp, "distid") == 0) {
  93. #ifdef EVP_PKEY_CTRL_SET1_ID
  94. cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
  95. #endif
  96. } else if (strcmp(stmp, "hexdistid") == 0) {
  97. if (vtmp != NULL) {
  98. void *hexid;
  99. long hexid_len = 0;
  100. hexid = OPENSSL_hexstr2buf((const char *)vtmp, &hexid_len);
  101. OPENSSL_free(stmp);
  102. stmp = vtmp = hexid;
  103. vtmp_len = (size_t)hexid_len;
  104. }
  105. #ifdef EVP_PKEY_CTRL_SET1_ID
  106. cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */
  107. #endif
  108. }
  109. rv = ctrl(object, cmd, vtmp, vtmp_len);
  110. OPENSSL_free(stmp);
  111. return rv;
  112. }
  113. int x509_ctrl_string(X509 *x, const char *value)
  114. {
  115. return do_x509_ctrl_string(x509_ctrl, x, value);
  116. }
  117. int x509_req_ctrl_string(X509_REQ *x, const char *value)
  118. {
  119. return do_x509_ctrl_string(x509_req_ctrl, x, value);
  120. }