2
0

d2i_pr.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (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 <stdio.h>
  10. #include "internal/cryptlib.h"
  11. #include <openssl/bn.h>
  12. #include <openssl/evp.h>
  13. #include <openssl/objects.h>
  14. #include <openssl/engine.h>
  15. #include <openssl/x509.h>
  16. #include <openssl/asn1.h>
  17. #include "crypto/asn1.h"
  18. #include "crypto/evp.h"
  19. EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
  20. long length)
  21. {
  22. EVP_PKEY *ret;
  23. const unsigned char *p = *pp;
  24. if ((a == NULL) || (*a == NULL)) {
  25. if ((ret = EVP_PKEY_new()) == NULL) {
  26. ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
  27. return NULL;
  28. }
  29. } else {
  30. ret = *a;
  31. #ifndef OPENSSL_NO_ENGINE
  32. ENGINE_finish(ret->engine);
  33. ret->engine = NULL;
  34. #endif
  35. }
  36. if (!EVP_PKEY_set_type(ret, type)) {
  37. ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
  38. goto err;
  39. }
  40. if (!ret->ameth->old_priv_decode ||
  41. !ret->ameth->old_priv_decode(ret, &p, length)) {
  42. if (ret->ameth->priv_decode) {
  43. EVP_PKEY *tmp;
  44. PKCS8_PRIV_KEY_INFO *p8 = NULL;
  45. p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
  46. if (!p8)
  47. goto err;
  48. tmp = EVP_PKCS82PKEY(p8);
  49. PKCS8_PRIV_KEY_INFO_free(p8);
  50. if (tmp == NULL)
  51. goto err;
  52. EVP_PKEY_free(ret);
  53. ret = tmp;
  54. if (EVP_PKEY_type(type) != EVP_PKEY_base_id(ret))
  55. goto err;
  56. } else {
  57. ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
  58. goto err;
  59. }
  60. }
  61. *pp = p;
  62. if (a != NULL)
  63. (*a) = ret;
  64. return ret;
  65. err:
  66. if (a == NULL || *a != ret)
  67. EVP_PKEY_free(ret);
  68. return NULL;
  69. }
  70. /*
  71. * This works like d2i_PrivateKey() except it automatically works out the
  72. * type
  73. */
  74. static EVP_PKEY *key_as_pkcs8(const unsigned char **pp, long length, int *carry_on)
  75. {
  76. const unsigned char *p = *pp;
  77. PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
  78. EVP_PKEY *ret;
  79. if (p8 == NULL)
  80. return NULL;
  81. ret = EVP_PKCS82PKEY(p8);
  82. if (ret == NULL)
  83. *carry_on = 0;
  84. PKCS8_PRIV_KEY_INFO_free(p8);
  85. if (ret != NULL)
  86. *pp = p;
  87. return ret;
  88. }
  89. EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
  90. long length)
  91. {
  92. STACK_OF(ASN1_TYPE) *inkey;
  93. const unsigned char *p;
  94. int keytype;
  95. EVP_PKEY *ret = NULL;
  96. int carry_on = 1;
  97. ERR_set_mark();
  98. ret = key_as_pkcs8(pp, length, &carry_on);
  99. if (ret != NULL) {
  100. ERR_clear_last_mark();
  101. if (a != NULL)
  102. *a = ret;
  103. return ret;
  104. }
  105. if (carry_on == 0) {
  106. ERR_clear_last_mark();
  107. ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
  108. ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
  109. return NULL;
  110. }
  111. p = *pp;
  112. /*
  113. * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
  114. * analyzing it we can determine the passed structure: this assumes the
  115. * input is surrounded by an ASN1 SEQUENCE.
  116. */
  117. inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
  118. p = *pp;
  119. /*
  120. * Since we only need to discern "traditional format" RSA and DSA keys we
  121. * can just count the elements.
  122. */
  123. if (sk_ASN1_TYPE_num(inkey) == 6)
  124. keytype = EVP_PKEY_DSA;
  125. else if (sk_ASN1_TYPE_num(inkey) == 4)
  126. keytype = EVP_PKEY_EC;
  127. else
  128. keytype = EVP_PKEY_RSA;
  129. sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
  130. ret = d2i_PrivateKey(keytype, a, pp, length);
  131. if (ret != NULL)
  132. ERR_pop_to_mark();
  133. else
  134. ERR_clear_last_mark();
  135. return ret;
  136. }