i2d_evp.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright 1995-2021 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. OSSL_ENCODER_CTX *ctx = NULL;
  34. int ret;
  35. for (ret = -1;
  36. ret == -1 && output_info->output_type != NULL;
  37. output_info++) {
  38. /*
  39. * The i2d_ calls don't take a boundary length for *pp. However,
  40. * OSSL_ENCODER_to_data() needs one, so we make one up. Because
  41. * OSSL_ENCODER_to_data() decrements this number by the amount of
  42. * bytes written, we need to calculate the length written further
  43. * down, when pp != NULL.
  44. */
  45. size_t len = INT_MAX;
  46. int pp_was_NULL = (pp == NULL || *pp == NULL);
  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. ctx = NULL;
  61. }
  62. if (ret == -1)
  63. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE);
  64. return ret;
  65. }
  66. int i2d_KeyParams(const EVP_PKEY *a, unsigned char **pp)
  67. {
  68. if (evp_pkey_is_provided(a)) {
  69. static const struct type_and_structure_st output_info[] = {
  70. { "DER", "type-specific" },
  71. { NULL, }
  72. };
  73. return i2d_provided(a, EVP_PKEY_KEY_PARAMETERS, output_info, pp);
  74. }
  75. if (a->ameth != NULL && a->ameth->param_encode != NULL)
  76. return a->ameth->param_encode(a, pp);
  77. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE);
  78. return -1;
  79. }
  80. int i2d_KeyParams_bio(BIO *bp, const EVP_PKEY *pkey)
  81. {
  82. return ASN1_i2d_bio_of(EVP_PKEY, i2d_KeyParams, bp, pkey);
  83. }
  84. int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
  85. {
  86. if (evp_pkey_is_provided(a)) {
  87. static const struct type_and_structure_st output_info[] = {
  88. { "DER", "type-specific" },
  89. { "DER", "pkcs8" },
  90. { NULL, }
  91. };
  92. return i2d_provided(a, EVP_PKEY_KEYPAIR, output_info, pp);
  93. }
  94. if (a->ameth != NULL && a->ameth->old_priv_encode != NULL) {
  95. return a->ameth->old_priv_encode(a, pp);
  96. }
  97. if (a->ameth != NULL && a->ameth->priv_encode != NULL) {
  98. PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
  99. int ret = 0;
  100. if (p8 != NULL) {
  101. ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
  102. PKCS8_PRIV_KEY_INFO_free(p8);
  103. }
  104. return ret;
  105. }
  106. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  107. return -1;
  108. }
  109. int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp)
  110. {
  111. if (evp_pkey_is_provided(a)) {
  112. static const struct type_and_structure_st output_info[] = {
  113. { "DER", "type-specific" },
  114. { "blob", NULL }, /* for EC */
  115. { NULL, }
  116. };
  117. return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_info, pp);
  118. }
  119. switch (EVP_PKEY_get_id(a)) {
  120. case EVP_PKEY_RSA:
  121. return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp);
  122. #ifndef OPENSSL_NO_DSA
  123. case EVP_PKEY_DSA:
  124. return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp);
  125. #endif
  126. #ifndef OPENSSL_NO_EC
  127. case EVP_PKEY_EC:
  128. return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp);
  129. #endif
  130. default:
  131. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  132. return -1;
  133. }
  134. }