i2d_evp.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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. static int i2d_provided(const EVP_PKEY *a, int selection,
  26. const char *output_structures[],
  27. unsigned char **pp)
  28. {
  29. OSSL_ENCODER_CTX *ctx = NULL;
  30. int ret;
  31. for (ret = -1;
  32. ret == -1 && *output_structures != NULL;
  33. output_structures++) {
  34. /*
  35. * The i2d_ calls don't take a boundary length for *pp. However,
  36. * OSSL_ENCODER_CTX_get_num_encoders() needs one, so we make one
  37. * up.
  38. */
  39. size_t len = INT_MAX;
  40. ctx = OSSL_ENCODER_CTX_new_for_pkey(a, selection, "DER",
  41. *output_structures, NULL);
  42. if (ctx == NULL)
  43. return -1;
  44. if (OSSL_ENCODER_to_data(ctx, pp, &len))
  45. ret = (int)len;
  46. OSSL_ENCODER_CTX_free(ctx);
  47. ctx = NULL;
  48. }
  49. if (ret == -1)
  50. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE);
  51. return ret;
  52. }
  53. int i2d_KeyParams(const EVP_PKEY *a, unsigned char **pp)
  54. {
  55. if (evp_pkey_is_provided(a)) {
  56. const char *output_structures[] = { "type-specific", NULL };
  57. return i2d_provided(a, EVP_PKEY_KEY_PARAMETERS, output_structures, pp);
  58. }
  59. if (a->ameth != NULL && a->ameth->param_encode != NULL)
  60. return a->ameth->param_encode(a, pp);
  61. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE);
  62. return -1;
  63. }
  64. int i2d_KeyParams_bio(BIO *bp, const EVP_PKEY *pkey)
  65. {
  66. return ASN1_i2d_bio_of(EVP_PKEY, i2d_KeyParams, bp, pkey);
  67. }
  68. int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
  69. {
  70. if (evp_pkey_is_provided(a)) {
  71. const char *output_structures[] = { "type-specific", "pkcs8", NULL };
  72. return i2d_provided(a, EVP_PKEY_KEYPAIR, output_structures, pp);
  73. }
  74. if (a->ameth != NULL && a->ameth->old_priv_encode != NULL) {
  75. return a->ameth->old_priv_encode(a, pp);
  76. }
  77. if (a->ameth != NULL && a->ameth->priv_encode != NULL) {
  78. PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
  79. int ret = 0;
  80. if (p8 != NULL) {
  81. ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
  82. PKCS8_PRIV_KEY_INFO_free(p8);
  83. }
  84. return ret;
  85. }
  86. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  87. return -1;
  88. }
  89. int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp)
  90. {
  91. if (evp_pkey_is_provided(a)) {
  92. const char *output_structures[] = { "type-specific", NULL };
  93. return i2d_provided(a, EVP_PKEY_PUBLIC_KEY, output_structures, pp);
  94. }
  95. switch (EVP_PKEY_id(a)) {
  96. case EVP_PKEY_RSA:
  97. return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp);
  98. #ifndef OPENSSL_NO_DSA
  99. case EVP_PKEY_DSA:
  100. return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp);
  101. #endif
  102. #ifndef OPENSSL_NO_EC
  103. case EVP_PKEY_EC:
  104. return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp);
  105. #endif
  106. default:
  107. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  108. return -1;
  109. }
  110. }