2
0

i2d_evp.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright 1995-2023 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. /*
  10. * Low level APIs are deprecated for public use, but still ok for
  11. * internal use.
  12. */
  13. #include "internal/deprecated.h"
  14. #include <stdio.h>
  15. #include "internal/cryptlib.h"
  16. #include <openssl/evp.h>
  17. #include <openssl/encoder.h>
  18. #include <openssl/buffer.h>
  19. #include <openssl/x509.h>
  20. #include <openssl/rsa.h> /* For i2d_RSAPublicKey */
  21. #include <openssl/dsa.h> /* For i2d_DSAPublicKey */
  22. #include <openssl/ec.h> /* For i2o_ECPublicKey */
  23. #include "crypto/asn1.h"
  24. #include "crypto/evp.h"
  25. struct type_and_structure_st {
  26. const char *output_type;
  27. const char *output_structure;
  28. };
  29. static int i2d_provided(const EVP_PKEY *a, int selection,
  30. const struct type_and_structure_st *output_info,
  31. unsigned char **pp)
  32. {
  33. int ret;
  34. for (ret = -1;
  35. ret == -1 && output_info->output_type != NULL;
  36. output_info++) {
  37. /*
  38. * The i2d_ calls don't take a boundary length for *pp. However,
  39. * OSSL_ENCODER_to_data() needs one, so we make one up. Because
  40. * OSSL_ENCODER_to_data() decrements this number by the amount of
  41. * bytes written, we need to calculate the length written further
  42. * down, when pp != NULL.
  43. */
  44. size_t len = INT_MAX;
  45. int pp_was_NULL = (pp == NULL || *pp == NULL);
  46. OSSL_ENCODER_CTX *ctx;
  47. ctx = OSSL_ENCODER_CTX_new_for_pkey(a, selection,
  48. output_info->output_type,
  49. output_info->output_structure,
  50. NULL);
  51. if (ctx == NULL)
  52. return -1;
  53. if (OSSL_ENCODER_to_data(ctx, pp, &len)) {
  54. if (pp_was_NULL)
  55. ret = (int)len;
  56. else
  57. ret = INT_MAX - (int)len;
  58. }
  59. OSSL_ENCODER_CTX_free(ctx);
  60. }
  61. if (ret == -1)
  62. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE);
  63. return ret;
  64. }
  65. int i2d_KeyParams(const EVP_PKEY *a, unsigned char **pp)
  66. {
  67. if (evp_pkey_is_provided(a)) {
  68. static const struct type_and_structure_st output_info[] = {
  69. { "DER", "type-specific" },
  70. { NULL, }
  71. };
  72. return i2d_provided(a, EVP_PKEY_KEY_PARAMETERS, output_info, pp);
  73. }
  74. if (a->ameth != NULL && a->ameth->param_encode != NULL)
  75. return a->ameth->param_encode(a, pp);
  76. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE);
  77. return -1;
  78. }
  79. int i2d_KeyParams_bio(BIO *bp, const EVP_PKEY *pkey)
  80. {
  81. return ASN1_i2d_bio_of(EVP_PKEY, i2d_KeyParams, bp, pkey);
  82. }
  83. int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
  84. {
  85. if (evp_pkey_is_provided(a)) {
  86. static const struct type_and_structure_st output_info[] = {
  87. { "DER", "type-specific" },
  88. { "DER", "PrivateKeyInfo" },
  89. { NULL, }
  90. };
  91. return i2d_provided(a, EVP_PKEY_KEYPAIR, output_info, pp);
  92. }
  93. if (a->ameth != NULL && a->ameth->old_priv_encode != NULL) {
  94. return a->ameth->old_priv_encode(a, pp);
  95. }
  96. if (a->ameth != NULL && a->ameth->priv_encode != NULL) {
  97. PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
  98. int ret = 0;
  99. if (p8 != NULL) {
  100. ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
  101. PKCS8_PRIV_KEY_INFO_free(p8);
  102. }
  103. return ret;
  104. }
  105. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  106. return -1;
  107. }
  108. int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp)
  109. {
  110. if (evp_pkey_is_provided(a)) {
  111. static const struct type_and_structure_st output_info[] = {
  112. { "DER", "type-specific" },
  113. { "blob", NULL }, /* for EC */
  114. { NULL, }
  115. };
  116. return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_info, pp);
  117. }
  118. switch (EVP_PKEY_get_base_id(a)) {
  119. case EVP_PKEY_RSA:
  120. return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp);
  121. #ifndef OPENSSL_NO_DSA
  122. case EVP_PKEY_DSA:
  123. return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp);
  124. #endif
  125. #ifndef OPENSSL_NO_EC
  126. case EVP_PKEY_EC:
  127. return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp);
  128. #endif
  129. default:
  130. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  131. return -1;
  132. }
  133. }