2 * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
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
10 #include <openssl/core.h>
11 #include <openssl/core_dispatch.h>
12 #include <openssl/core_names.h>
13 #include <openssl/core_object.h>
14 #include <openssl/asn1.h>
15 #include <openssl/err.h>
16 #include <openssl/objects.h>
17 #include <openssl/pkcs12.h>
18 #include <openssl/x509.h>
19 #include <openssl/proverr.h>
20 #include "internal/asn1.h"
21 #include "internal/sizes.h"
23 #include "prov/implementations.h"
24 #include "endecoder_local.h"
26 static OSSL_FUNC_decoder_newctx_fn epki2pki_newctx
;
27 static OSSL_FUNC_decoder_freectx_fn epki2pki_freectx
;
28 static OSSL_FUNC_decoder_decode_fn epki2pki_decode
;
31 * Context used for EncryptedPrivateKeyInfo to PrivateKeyInfo decoding.
33 struct epki2pki_ctx_st
{
37 static void *epki2pki_newctx(void *provctx
)
39 struct epki2pki_ctx_st
*ctx
= OPENSSL_zalloc(sizeof(*ctx
));
42 ctx
->provctx
= provctx
;
46 static void epki2pki_freectx(void *vctx
)
48 struct epki2pki_ctx_st
*ctx
= vctx
;
54 * The selection parameter in epki2pki_decode() is not used by this function
55 * because it's not relevant just to decode EncryptedPrivateKeyInfo to
58 static int epki2pki_decode(void *vctx
, OSSL_CORE_BIO
*cin
, int selection
,
59 OSSL_CALLBACK
*data_cb
, void *data_cbarg
,
60 OSSL_PASSPHRASE_CALLBACK
*pw_cb
, void *pw_cbarg
)
62 struct epki2pki_ctx_st
*ctx
= vctx
;
64 unsigned char *der
= NULL
;
65 const unsigned char *pder
= NULL
;
68 PKCS8_PRIV_KEY_INFO
*p8inf
= NULL
;
69 const X509_ALGOR
*alg
= NULL
;
70 BIO
*in
= ossl_bio_new_from_core_bio(ctx
->provctx
, cin
);
76 ok
= (asn1_d2i_read_bio(in
, &mem
) >= 0);
79 /* We return "empty handed". This is not an error. */
83 pder
= der
= (unsigned char *)mem
->data
;
84 der_len
= (long)mem
->length
;
87 ok
= 1; /* Assume good */
89 if ((p8
= d2i_X509_SIG(NULL
, &pder
, der_len
)) != NULL
) {
93 ERR_clear_last_mark();
95 if (!pw_cb(pbuf
, sizeof(pbuf
), &plen
, NULL
, pw_cbarg
)) {
96 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_GET_PASSPHRASE
);
99 const ASN1_OCTET_STRING
*oct
;
100 unsigned char *new_der
= NULL
;
103 X509_SIG_get0(p8
, &alg
, &oct
);
104 if (!PKCS12_pbe_crypt_ex(alg
, pbuf
, plen
,
105 oct
->data
, oct
->length
,
106 &new_der
, &new_der_len
, 0,
107 PROV_LIBCTX_OF(ctx
->provctx
), NULL
)) {
112 der_len
= new_der_len
;
123 p8inf
= d2i_PKCS8_PRIV_KEY_INFO(NULL
, &pder
, der_len
);
126 if (p8inf
!= NULL
&& PKCS8_pkey_get0(NULL
, NULL
, NULL
, &alg
, p8inf
)) {
128 * We have something and recognised it as PrivateKeyInfo, so let's
129 * pass all the applicable data to the callback.
131 char keytype
[OSSL_MAX_NAME_SIZE
];
132 OSSL_PARAM params
[5], *p
= params
;
133 int objtype
= OSSL_OBJECT_PKEY
;
135 OBJ_obj2txt(keytype
, sizeof(keytype
), alg
->algorithm
, 0);
137 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE
,
139 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE
,
140 "PrivateKeyInfo", 0);
141 *p
++ = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA
,
143 *p
++ = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE
, &objtype
);
144 *p
= OSSL_PARAM_construct_end();
146 ok
= data_cb(params
, data_cbarg
);
148 PKCS8_PRIV_KEY_INFO_free(p8inf
);
153 const OSSL_DISPATCH ossl_EncryptedPrivateKeyInfo_der_to_der_decoder_functions
[] = {
154 { OSSL_FUNC_DECODER_NEWCTX
, (void (*)(void))epki2pki_newctx
},
155 { OSSL_FUNC_DECODER_FREECTX
, (void (*)(void))epki2pki_freectx
},
156 { OSSL_FUNC_DECODER_DECODE
, (void (*)(void))epki2pki_decode
},