Coverage Report

Created: 2025-06-13 06:56

/src/openssl/crypto/pkcs12/p12_key.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1999-2024 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/bn.h>
14
#include <openssl/trace.h>
15
#include <openssl/kdf.h>
16
#include <openssl/core_names.h>
17
#include "internal/provider.h"
18
19
int PKCS12_key_gen_asc_ex(const char *pass, int passlen, unsigned char *salt,
20
                          int saltlen, int id, int iter, int n,
21
                          unsigned char *out, const EVP_MD *md_type,
22
                          OSSL_LIB_CTX *ctx, const char *propq)
23
0
{
24
0
    int ret;
25
0
    unsigned char *unipass;
26
0
    int uniplen;
27
28
0
    if (pass == NULL) {
29
0
        unipass = NULL;
30
0
        uniplen = 0;
31
0
    } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
32
0
        ERR_raise(ERR_LIB_PKCS12, ERR_R_PKCS12_LIB);
33
0
        return 0;
34
0
    }
35
0
    ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter,
36
0
                                n, out, md_type, ctx, propq);
37
0
    OPENSSL_clear_free(unipass, uniplen);
38
0
    return ret > 0;
39
0
}
40
41
int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
42
                       int saltlen, int id, int iter, int n,
43
                       unsigned char *out, const EVP_MD *md_type)
44
0
{
45
0
    return PKCS12_key_gen_asc_ex(pass, passlen, salt, saltlen, id, iter, n,
46
0
                                  out, md_type, NULL, NULL);
47
0
}
48
49
int PKCS12_key_gen_utf8_ex(const char *pass, int passlen, unsigned char *salt,
50
                           int saltlen, int id, int iter, int n,
51
                           unsigned char *out, const EVP_MD *md_type,
52
                           OSSL_LIB_CTX *ctx, const char *propq)
53
0
{
54
0
    int ret;
55
0
    unsigned char *unipass;
56
0
    int uniplen;
57
58
0
    if (pass == NULL) {
59
0
        unipass = NULL;
60
0
        uniplen = 0;
61
0
    } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) {
62
0
        ERR_raise(ERR_LIB_PKCS12, ERR_R_PKCS12_LIB);
63
0
        return 0;
64
0
    }
65
0
    ret = PKCS12_key_gen_uni_ex(unipass, uniplen, salt, saltlen, id, iter,
66
0
                                n, out, md_type, ctx, propq);
67
0
    OPENSSL_clear_free(unipass, uniplen);
68
0
    return ret > 0;
69
0
}
70
71
int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
72
                        int saltlen, int id, int iter, int n,
73
                        unsigned char *out, const EVP_MD *md_type)
74
0
{
75
0
    return PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, id, iter, n,
76
0
                                  out, md_type, NULL, NULL);
77
0
}
78
79
int PKCS12_key_gen_uni_ex(unsigned char *pass, int passlen, unsigned char *salt,
80
                          int saltlen, int id, int iter, int n,
81
                          unsigned char *out, const EVP_MD *md_type,
82
                          OSSL_LIB_CTX *libctx, const char *propq)
83
0
{
84
0
    int res = 0;
85
0
    EVP_KDF *kdf;
86
0
    EVP_KDF_CTX *ctx;
87
0
    OSSL_PARAM params[6], *p = params;
88
89
0
    if (n <= 0)
90
0
        return 0;
91
92
0
    kdf = EVP_KDF_fetch(libctx, "PKCS12KDF", propq);
93
0
    if (kdf == NULL)
94
0
        return 0;
95
0
    ctx = EVP_KDF_CTX_new(kdf);
96
0
    EVP_KDF_free(kdf);
97
0
    if (ctx == NULL)
98
0
        return 0;
99
100
0
    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
101
0
                                            (char *)EVP_MD_get0_name(md_type),
102
0
                                            0);
103
0
    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
104
0
                                             pass, passlen);
105
0
    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
106
0
                                             salt, saltlen);
107
0
    *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS12_ID, &id);
108
0
    *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter);
109
0
    *p = OSSL_PARAM_construct_end();
110
111
0
    OSSL_TRACE_BEGIN(PKCS12_KEYGEN) {
112
0
        BIO_printf(trc_out, "PKCS12_key_gen_uni_ex(): ID %d, ITER %d\n", id, iter);
113
0
        BIO_printf(trc_out, "Password (length %d):\n", passlen);
114
0
        BIO_hex_string(trc_out, 0, passlen, pass, passlen);
115
0
        BIO_printf(trc_out, "\n");
116
0
        BIO_printf(trc_out, "Salt (length %d):\n", saltlen);
117
0
        BIO_hex_string(trc_out, 0, saltlen, salt, saltlen);
118
0
        BIO_printf(trc_out, "\n");
119
0
    } OSSL_TRACE_END(PKCS12_KEYGEN);
120
121
0
    if (EVP_KDF_derive(ctx, out, (size_t)n, params)) {
122
0
        res = 1;
123
0
        OSSL_TRACE_BEGIN(PKCS12_KEYGEN) {
124
0
            BIO_printf(trc_out, "Output KEY (length %d)\n", n);
125
0
            BIO_hex_string(trc_out, 0, n, out, n);
126
0
            BIO_printf(trc_out, "\n");
127
0
        } OSSL_TRACE_END(PKCS12_KEYGEN);
128
0
    }
129
0
    EVP_KDF_CTX_free(ctx);
130
0
    return res;
131
0
}
132
133
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
134
                       int saltlen, int id, int iter, int n,
135
                       unsigned char *out, const EVP_MD *md_type)
136
0
{
137
0
    return PKCS12_key_gen_uni_ex(pass, passlen, salt, saltlen, id, iter, n, out, md_type, NULL, NULL);
138
0
}