i2d_evp.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright 1995-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. /* We need to use some deprecated APIs to support the legacy bits */
  10. #define OPENSSL_SUPPRESS_DEPRECATED
  11. #include <stdio.h>
  12. #include "internal/cryptlib.h"
  13. #include <openssl/evp.h>
  14. #include <openssl/encoder.h>
  15. #include <openssl/buffer.h>
  16. #include <openssl/x509.h>
  17. #ifndef OPENSSL_NO_DEPRECATED_3_0
  18. # include <openssl/rsa.h> /* For i2d_RSAPublicKey */
  19. #endif
  20. #include <openssl/dsa.h> /* For i2d_DSAPublicKey */
  21. #include <openssl/ec.h> /* For i2o_ECPublicKey */
  22. #include "crypto/asn1.h"
  23. #include "crypto/evp.h"
  24. static int i2d_provided(const EVP_PKEY *a, int selection,
  25. const char *output_structures[],
  26. unsigned char **pp)
  27. {
  28. OSSL_ENCODER_CTX *ctx = NULL;
  29. int ret;
  30. for (ret = -1;
  31. ret == -1 && *output_structures != NULL;
  32. output_structures++) {
  33. /*
  34. * The i2d_ calls don't take a boundary length for *pp. However,
  35. * OSSL_ENCODER_CTX_get_num_encoders() needs one, so we make one
  36. * up.
  37. */
  38. size_t len = INT_MAX;
  39. ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, selection, "DER",
  40. *output_structures, NULL);
  41. if (ctx == NULL)
  42. return -1;
  43. if (OSSL_ENCODER_to_data(ctx, pp, &len))
  44. ret = (int)len;
  45. OSSL_ENCODER_CTX_free(ctx);
  46. ctx = NULL;
  47. }
  48. if (ret == -1)
  49. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE);
  50. return ret;
  51. }
  52. int i2d_KeyParams(const EVP_PKEY *a, unsigned char **pp)
  53. {
  54. if (evp_pkey_is_provided(a)) {
  55. const char *output_structures[] = { "type-specific", NULL };
  56. return i2d_provided(a, EVP_PKEY_KEY_PARAMETERS, output_structures, pp);
  57. }
  58. if (a->ameth != NULL && a->ameth->param_encode != NULL)
  59. return a->ameth->param_encode(a, pp);
  60. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE);
  61. return -1;
  62. }
  63. int i2d_KeyParams_bio(BIO *bp, const EVP_PKEY *pkey)
  64. {
  65. return ASN1_i2d_bio_of(EVP_PKEY, i2d_KeyParams, bp, pkey);
  66. }
  67. int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
  68. {
  69. if (evp_pkey_is_provided(a)) {
  70. const char *output_structures[] = { "type-specific", "pkcs8", NULL };
  71. return i2d_provided(a, EVP_PKEY_KEYPAIR, output_structures, pp);
  72. }
  73. if (a->ameth != NULL && a->ameth->old_priv_encode != NULL) {
  74. return a->ameth->old_priv_encode(a, pp);
  75. }
  76. if (a->ameth != NULL && a->ameth->priv_encode != NULL) {
  77. PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
  78. int ret = 0;
  79. if (p8 != NULL) {
  80. ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
  81. PKCS8_PRIV_KEY_INFO_free(p8);
  82. }
  83. return ret;
  84. }
  85. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  86. return -1;
  87. }
  88. int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp)
  89. {
  90. if (evp_pkey_is_provided(a)) {
  91. const char *output_structures[] = { "type-specific", NULL };
  92. return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_structures, pp);
  93. }
  94. switch (EVP_PKEY_id(a)) {
  95. #ifndef OPENSSL_NO_DEPRECATED_3_0
  96. # ifndef OPENSSL_NO_RSA
  97. case EVP_PKEY_RSA:
  98. return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp);
  99. # endif
  100. #endif
  101. #ifndef OPENSSL_NO_DSA
  102. case EVP_PKEY_DSA:
  103. return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp);
  104. #endif
  105. #ifndef OPENSSL_NO_EC
  106. case EVP_PKEY_EC:
  107. return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp);
  108. #endif
  109. default:
  110. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  111. return -1;
  112. }
  113. }