Coverage Report

Created: 2026-10-16 07:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/pkcs12/p12_sbag.c
Line
Count
Source
1
/*
2
 * Copyright 1999-2026 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
#include <stdio.h>
11
#include "internal/cryptlib.h"
12
#include <openssl/pkcs12.h>
13
#include <openssl/core_names.h>
14
#include <openssl/objects.h>
15
#include <openssl/param_build.h>
16
#include "p12_local.h"
17
#include "crypto/x509.h"
18
19
#ifndef OPENSSL_NO_DEPRECATED_1_1_0
20
const ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)
21
0
{
22
0
    return PKCS12_get_attr_gen(bag->attrib, attr_nid);
23
0
}
24
#endif
25
26
const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag,
27
    int attr_nid)
28
0
{
29
0
    return PKCS12_get_attr_gen(bag->attrib, attr_nid);
30
0
}
31
32
const ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid)
33
0
{
34
0
    return PKCS12_get_attr_gen(PKCS8_pkey_get0_attrs(p8), attr_nid);
35
0
}
36
37
const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag)
38
0
{
39
0
    if (PKCS12_SAFEBAG_get_nid(bag) != NID_keyBag)
40
0
        return NULL;
41
0
    return bag->value.keybag;
42
0
}
43
44
const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag)
45
0
{
46
0
    if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag)
47
0
        return NULL;
48
0
    return bag->value.shkeybag;
49
0
}
50
51
const STACK_OF(PKCS12_SAFEBAG) *
52
PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag)
53
0
{
54
0
    if (OBJ_obj2nid(bag->type) != NID_safeContentsBag)
55
0
        return NULL;
56
0
    return bag->value.safes;
57
0
}
58
59
const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag)
60
0
{
61
0
    return bag->type;
62
0
}
63
64
int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag)
65
0
{
66
0
    return OBJ_obj2nid(bag->type);
67
0
}
68
69
int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag)
70
0
{
71
0
    int btype = PKCS12_SAFEBAG_get_nid(bag);
72
73
0
    if (btype != NID_certBag && btype != NID_crlBag && btype != NID_secretBag)
74
0
        return -1;
75
0
    return OBJ_obj2nid(bag->value.bag->type);
76
0
}
77
78
const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag)
79
0
{
80
0
    int btype = PKCS12_SAFEBAG_get_nid(bag);
81
82
0
    if (btype != NID_certBag && btype != NID_crlBag && btype != NID_secretBag)
83
0
        return NULL;
84
0
    return bag->value.bag->type;
85
0
}
86
87
const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag)
88
0
{
89
0
    int vtype = PKCS12_SAFEBAG_get_bag_nid(bag);
90
91
0
    if (vtype == -1 || vtype == NID_x509Certificate || vtype == NID_x509Crl
92
0
        || vtype == NID_sdsiCertificate)
93
0
        return NULL;
94
0
    return bag->value.bag->value.other;
95
0
}
96
97
X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag)
98
0
{
99
0
    if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
100
0
        return NULL;
101
0
    if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
102
0
        return NULL;
103
0
    return ASN1_item_unpack(bag->value.bag->value.octet,
104
0
        ASN1_ITEM_rptr(X509));
105
0
}
106
107
X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag)
108
0
{
109
0
    if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
110
0
        return NULL;
111
0
    if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
112
0
        return NULL;
113
0
    return ASN1_item_unpack(bag->value.bag->value.octet,
114
0
        ASN1_ITEM_rptr(X509_CRL));
115
0
}
116
117
X509 *PKCS12_SAFEBAG_get1_cert_ex(const PKCS12_SAFEBAG *bag,
118
    OSSL_LIB_CTX *libctx, const char *propq)
119
0
{
120
0
    X509 *ret = NULL;
121
122
0
    if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
123
0
        return NULL;
124
0
    if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
125
0
        return NULL;
126
0
    ret = ASN1_item_unpack_ex(bag->value.bag->value.octet,
127
0
        ASN1_ITEM_rptr(X509), libctx, propq);
128
0
    if (!ossl_x509_set0_libctx(ret, libctx, propq)) {
129
0
        X509_free(ret);
130
0
        return NULL;
131
0
    }
132
0
    return ret;
133
0
}
134
135
X509_CRL *PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG *bag,
136
    OSSL_LIB_CTX *libctx, const char *propq)
137
0
{
138
0
    X509_CRL *ret = NULL;
139
140
0
    if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
141
0
        return NULL;
142
0
    if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
143
0
        return NULL;
144
0
    ret = ASN1_item_unpack_ex(bag->value.bag->value.octet,
145
0
        ASN1_ITEM_rptr(X509_CRL), libctx, propq);
146
0
    if (!ossl_x509_crl_set0_libctx(ret, libctx, propq)) {
147
0
        X509_CRL_free(ret);
148
0
        return NULL;
149
0
    }
150
0
    return ret;
151
0
}
152
153
EVP_SKEY *PKCS8_PRIV_KEY_INFO_get1_skey(const PKCS8_PRIV_KEY_INFO *p8inf,
154
    OSSL_LIB_CTX *libctx, const char *propq,
155
    const OSSL_PARAM *extra_params, int strict)
156
0
{
157
0
    const ASN1_OBJECT *algoid = NULL;
158
0
    const X509_ALGOR *algor = NULL;
159
0
    const unsigned char *raw_key = NULL;
160
0
    int raw_key_len = 0;
161
0
    const char *skey_type = OSSL_SKEY_TYPE_GENERIC;
162
0
    unsigned char *oid_der = NULL;
163
0
    int oid_der_len = 0;
164
0
    unsigned char *params_der = NULL;
165
0
    int params_der_len = 0;
166
0
    OSSL_PARAM_BLD *bld = NULL;
167
0
    OSSL_PARAM *params = NULL;
168
0
    EVP_SKEY *skey = NULL;
169
170
0
    if (p8inf == NULL)
171
0
        return NULL;
172
173
0
    if (!PKCS8_pkey_get0(&algoid, &raw_key, &raw_key_len, &algor, p8inf)
174
0
        || raw_key == NULL || raw_key_len <= 0)
175
0
        return NULL;
176
177
0
    if (algoid != NULL) {
178
0
        int nid = OBJ_obj2nid(algoid);
179
180
0
        switch (nid) {
181
0
        case NID_id_aes:
182
0
            if (raw_key_len != 16 && raw_key_len != 24 && raw_key_len != 32)
183
0
                return NULL;
184
0
            skey_type = OSSL_SKEY_TYPE_AES;
185
0
            break;
186
0
        case NID_aes_128_cbc:
187
0
        case NID_aes_128_ccm:
188
0
        case NID_aes_128_ecb:
189
0
        case NID_aes_128_gcm:
190
0
            if (raw_key_len != 16)
191
0
                return NULL;
192
0
            skey_type = OSSL_SKEY_TYPE_AES;
193
0
            break;
194
0
        case NID_aes_192_cbc:
195
0
        case NID_aes_192_ccm:
196
0
        case NID_aes_192_ecb:
197
0
        case NID_aes_192_gcm:
198
0
            if (raw_key_len != 24)
199
0
                return NULL;
200
0
            skey_type = OSSL_SKEY_TYPE_AES;
201
0
            break;
202
0
        case NID_aes_256_cbc:
203
0
        case NID_aes_256_ccm:
204
0
        case NID_aes_256_ecb:
205
0
        case NID_aes_256_gcm:
206
0
            if (raw_key_len != 32)
207
0
                return NULL;
208
0
            skey_type = OSSL_SKEY_TYPE_AES;
209
0
            break;
210
0
        default:
211
0
            if (strict != 0)
212
0
                return NULL;
213
0
            break;
214
0
        }
215
0
    }
216
217
0
    bld = OSSL_PARAM_BLD_new();
218
0
    if (bld == NULL)
219
0
        return NULL;
220
221
0
    if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_SKEY_PARAM_RAW_BYTES,
222
0
            raw_key, (size_t)raw_key_len))
223
0
        goto err;
224
225
0
    if (algoid != NULL) {
226
0
        oid_der_len = i2d_ASN1_OBJECT(algoid, &oid_der);
227
0
        if (oid_der_len > 0
228
0
            && !OSSL_PARAM_BLD_push_octet_string(bld,
229
0
                OSSL_SKEY_PARAM_ALGORITHM_OID,
230
0
                oid_der, (size_t)oid_der_len))
231
0
            goto err;
232
0
    }
233
234
0
    if (algor != NULL && algor->parameter != NULL
235
0
        && algor->parameter->type != V_ASN1_UNDEF) {
236
0
        params_der_len = i2d_ASN1_TYPE(algor->parameter, &params_der);
237
0
        if (params_der_len > 0
238
0
            && !OSSL_PARAM_BLD_push_octet_string(bld,
239
0
                OSSL_SKEY_PARAM_ALGORITHM_PARAMS,
240
0
                params_der, (size_t)params_der_len))
241
0
            goto err;
242
0
    }
243
244
0
    if (extra_params != NULL) {
245
0
        const OSSL_PARAM *p;
246
247
0
        for (p = extra_params; p->key != NULL; p++) {
248
0
            switch (p->data_type) {
249
0
            case OSSL_PARAM_UTF8_STRING:
250
0
                if (!OSSL_PARAM_BLD_push_utf8_string(bld,
251
0
                        p->key, p->data, p->data_size))
252
0
                    goto err;
253
0
                break;
254
0
            case OSSL_PARAM_OCTET_STRING:
255
0
                if (!OSSL_PARAM_BLD_push_octet_string(bld,
256
0
                        p->key, p->data, p->data_size))
257
0
                    goto err;
258
0
                break;
259
0
            default:
260
0
                break;
261
0
            }
262
0
        }
263
0
    }
264
265
0
    params = OSSL_PARAM_BLD_to_param(bld);
266
0
    if (params == NULL)
267
0
        goto err;
268
269
0
    skey = EVP_SKEY_import(libctx, skey_type, propq,
270
0
        OSSL_SKEYMGMT_SELECT_ALL, params);
271
272
0
err:
273
0
    OSSL_PARAM_BLD_free(bld);
274
0
    OSSL_PARAM_clear_free(params);
275
0
    OPENSSL_free(oid_der);
276
0
    OPENSSL_free(params_der);
277
0
    return skey;
278
0
}
279
280
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509)
281
0
{
282
0
    return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
283
0
        NID_x509Certificate, NID_certBag);
284
0
}
285
286
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl)
287
0
{
288
0
    return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
289
0
        NID_x509Crl, NID_crlBag);
290
0
}
291
292
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len)
293
0
{
294
0
    PKCS12_BAGS *bag;
295
0
    PKCS12_SAFEBAG *safebag;
296
297
0
    if ((bag = PKCS12_BAGS_new()) == NULL) {
298
0
        ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
299
0
        return NULL;
300
0
    }
301
0
    bag->type = OBJ_nid2obj(type);
302
303
0
    switch (vtype) {
304
0
    case V_ASN1_OCTET_STRING: {
305
0
        ASN1_OCTET_STRING *strtmp = ASN1_OCTET_STRING_new();
306
307
0
        if (strtmp == NULL) {
308
0
            ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
309
0
            goto err;
310
0
        }
311
        /* Pack data into an octet string */
312
0
        if (!ASN1_OCTET_STRING_set(strtmp, value, len)) {
313
0
            ASN1_OCTET_STRING_free(strtmp);
314
0
            ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR);
315
0
            goto err;
316
0
        }
317
0
        bag->value.other = ASN1_TYPE_new();
318
0
        if (bag->value.other == NULL) {
319
0
            ASN1_OCTET_STRING_free(strtmp);
320
0
            ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
321
0
            goto err;
322
0
        }
323
0
        ASN1_TYPE_set(bag->value.other, vtype, strtmp);
324
0
    } break;
325
326
0
    default:
327
0
        ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_TYPE);
328
0
        goto err;
329
0
    }
330
331
0
    if ((safebag = PKCS12_SAFEBAG_new()) == NULL) {
332
0
        ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
333
0
        goto err;
334
0
    }
335
0
    safebag->value.bag = bag;
336
0
    safebag->type = OBJ_nid2obj(NID_secretBag);
337
0
    return safebag;
338
339
0
err:
340
0
    PKCS12_BAGS_free(bag);
341
0
    return NULL;
342
0
}
343
344
/* Turn PKCS8 object into a keybag */
345
346
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8)
347
0
{
348
0
    PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
349
350
0
    if (bag == NULL) {
351
0
        ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
352
0
        return NULL;
353
0
    }
354
0
    bag->type = OBJ_nid2obj(NID_keyBag);
355
0
    bag->value.keybag = p8;
356
0
    return bag;
357
0
}
358
359
/* Turn PKCS8 object into a shrouded keybag */
360
361
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8)
362
0
{
363
0
    PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
364
365
    /* Set up the safe bag */
366
0
    if (bag == NULL) {
367
0
        ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
368
0
        return NULL;
369
0
    }
370
0
    bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
371
0
    bag->value.shkeybag = p8;
372
0
    return bag;
373
0
}
374
375
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid,
376
    const char *pass,
377
    int passlen,
378
    unsigned char *salt,
379
    int saltlen, int iter,
380
    PKCS8_PRIV_KEY_INFO *p8inf,
381
    OSSL_LIB_CTX *ctx,
382
    const char *propq)
383
0
{
384
0
    PKCS12_SAFEBAG *bag = NULL;
385
0
    EVP_CIPHER *pbe_ciph = NULL;
386
0
    X509_SIG *p8;
387
388
0
    ERR_set_mark();
389
0
    pbe_ciph = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq);
390
0
    ERR_pop_to_mark();
391
392
0
    if (pbe_ciph != NULL)
393
0
        pbe_nid = -1;
394
395
0
    p8 = PKCS8_encrypt_ex(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
396
0
        p8inf, ctx, propq);
397
0
    if (p8 == NULL)
398
0
        goto err;
399
400
0
    bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
401
0
    if (bag == NULL)
402
0
        X509_SIG_free(p8);
403
404
0
err:
405
0
    EVP_CIPHER_free(pbe_ciph);
406
0
    return bag;
407
0
}
408
409
PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
410
    const char *pass,
411
    int passlen,
412
    unsigned char *salt,
413
    int saltlen, int iter,
414
    PKCS8_PRIV_KEY_INFO *p8inf)
415
0
{
416
0
    return PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(pbe_nid, pass, passlen,
417
0
        salt, saltlen, iter, p8inf,
418
0
        NULL, NULL);
419
0
}