decode_spki2typespki.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright 2020-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. #include <string.h>
  10. #include <openssl/asn1t.h>
  11. #include <openssl/core_names.h>
  12. #include <openssl/core_object.h>
  13. #include <openssl/params.h>
  14. #include <openssl/x509.h>
  15. #include "internal/sizes.h"
  16. #include "crypto/x509.h"
  17. #include "crypto/ec.h"
  18. #include "prov/bio.h"
  19. #include "prov/implementations.h"
  20. #include "endecoder_local.h"
  21. static OSSL_FUNC_decoder_newctx_fn spki2typespki_newctx;
  22. static OSSL_FUNC_decoder_freectx_fn spki2typespki_freectx;
  23. static OSSL_FUNC_decoder_decode_fn spki2typespki_decode;
  24. /*
  25. * Context used for SubjectPublicKeyInfo to Type specific SubjectPublicKeyInfo
  26. * decoding.
  27. */
  28. struct spki2typespki_ctx_st {
  29. PROV_CTX *provctx;
  30. };
  31. static void *spki2typespki_newctx(void *provctx)
  32. {
  33. struct spki2typespki_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
  34. if (ctx != NULL)
  35. ctx->provctx = provctx;
  36. return ctx;
  37. }
  38. static void spki2typespki_freectx(void *vctx)
  39. {
  40. struct spki2typespki_ctx_st *ctx = vctx;
  41. OPENSSL_free(ctx);
  42. }
  43. static int spki2typespki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
  44. OSSL_CALLBACK *data_cb, void *data_cbarg,
  45. OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
  46. {
  47. struct spki2typespki_ctx_st *ctx = vctx;
  48. unsigned char *der, *derp;
  49. long len;
  50. int ok = 0;
  51. int objtype = OSSL_OBJECT_PKEY;
  52. X509_PUBKEY *xpub = NULL;
  53. X509_ALGOR *algor = NULL;
  54. const ASN1_OBJECT *oid = NULL;
  55. char dataname[OSSL_MAX_NAME_SIZE];
  56. OSSL_PARAM params[5], *p = params;
  57. if (!ossl_read_der(ctx->provctx, cin, &der, &len))
  58. return 1;
  59. derp = der;
  60. xpub = ossl_d2i_X509_PUBKEY_INTERNAL((const unsigned char **)&derp, len,
  61. PROV_LIBCTX_OF(ctx->provctx));
  62. if (xpub == NULL) {
  63. /* We return "empty handed". This is not an error. */
  64. ok = 1;
  65. goto end;
  66. }
  67. if (!X509_PUBKEY_get0_param(NULL, NULL, NULL, &algor, xpub))
  68. goto end;
  69. X509_ALGOR_get0(&oid, NULL, NULL, algor);
  70. #ifndef OPENSSL_NO_EC
  71. /* SM2 abuses the EC oid, so this could actually be SM2 */
  72. if (OBJ_obj2nid(oid) == NID_X9_62_id_ecPublicKey
  73. && ossl_x509_algor_is_sm2(algor))
  74. strcpy(dataname, "SM2");
  75. else
  76. #endif
  77. if (OBJ_obj2txt(dataname, sizeof(dataname), oid, 0) <= 0)
  78. goto end;
  79. ossl_X509_PUBKEY_INTERNAL_free(xpub);
  80. xpub = NULL;
  81. *p++ =
  82. OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
  83. dataname, 0);
  84. *p++ =
  85. OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE,
  86. "SubjectPublicKeyInfo",
  87. 0);
  88. *p++ =
  89. OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, der, len);
  90. *p++ =
  91. OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &objtype);
  92. *p = OSSL_PARAM_construct_end();
  93. ok = data_cb(params, data_cbarg);
  94. end:
  95. ossl_X509_PUBKEY_INTERNAL_free(xpub);
  96. OPENSSL_free(der);
  97. return ok;
  98. }
  99. const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_der_decoder_functions[] = {
  100. { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))spki2typespki_newctx },
  101. { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))spki2typespki_freectx },
  102. { OSSL_FUNC_DECODER_DECODE, (void (*)(void))spki2typespki_decode },
  103. { 0, NULL }
  104. };