• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 15175033720

21 May 2025 10:22PM UTC coverage: 72.079% (+0.03%) from 72.047%
15175033720

push

github

web-flow
Several minor follow-ups for #33995 (#37558)

3 of 3 new or added lines in 1 file covered. (100.0%)

34302 existing lines in 652 files now uncovered.

299232 of 415142 relevant lines covered (72.08%)

700018.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/cryptsetup/cryptsetup-pkcs11.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include "sd-json.h"
4

5
#include "alloc-util.h"
6
#include "ask-password-api.h"
7
#include "cryptsetup-pkcs11.h"
8
#include "cryptsetup-util.h"
9
#include "fileio.h"
10
#include "iovec-util.h"
11
#include "log.h"
12
#include "pkcs11-util.h"
13
#include "random-util.h"
14

UNCOV
15
int decrypt_pkcs11_key(
×
16
                const char *volume_name,
17
                const char *friendly_name,
18
                const char *pkcs11_uri,
19
                const char *key_file,         /* We either expect key_file and associated parameters to be set (for file keys) … */
20
                size_t key_file_size,
21
                uint64_t key_file_offset,
22
                const struct iovec *key_data, /* … or literal keys via key_data */
23
                usec_t until,
24
                AskPasswordFlags askpw_flags,
25
                void **ret_decrypted_key,
26
                size_t *ret_decrypted_key_size) {
27
#if HAVE_P11KIT
28
        _cleanup_(pkcs11_crypt_device_callback_data_release) pkcs11_crypt_device_callback_data data = {
×
29
                .friendly_name = friendly_name,
30
                .askpw_flags = askpw_flags,
31
                .until = until,
32
        };
UNCOV
33
        int r;
×
34

UNCOV
35
        assert(friendly_name);
×
UNCOV
36
        assert(pkcs11_uri);
×
UNCOV
37
        assert(key_file || iovec_is_set(key_data));
×
UNCOV
38
        assert(ret_decrypted_key);
×
UNCOV
39
        assert(ret_decrypted_key_size);
×
40

41
        /* The functions called here log about all errors, except for EAGAIN which means "token not found right now" */
42

UNCOV
43
        if (iovec_is_set(key_data)) {
×
UNCOV
44
                data.encrypted_key = (void*) key_data->iov_base;
×
UNCOV
45
                data.encrypted_key_size = key_data->iov_len;
×
46

UNCOV
47
                data.free_encrypted_key = false;
×
48
        } else {
49
                _cleanup_free_ char *bindname = NULL;
×
50

51
                /* If we read the key via AF_UNIX, make this client recognizable */
52
                if (asprintf(&bindname, "@%" PRIx64"/cryptsetup-pkcs11/%s", random_u64(), volume_name) < 0)
×
UNCOV
53
                        return log_oom();
×
54

UNCOV
55
                r = read_full_file_full(
×
56
                                AT_FDCWD, key_file,
57
                                key_file_offset == 0 ? UINT64_MAX : key_file_offset,
58
                                key_file_size == 0 ? SIZE_MAX : key_file_size,
59
                                READ_FULL_FILE_CONNECT_SOCKET,
60
                                bindname,
61
                                (char**) &data.encrypted_key, &data.encrypted_key_size);
62
                if (r < 0)
×
63
                        return r;
64

65
                data.free_encrypted_key = true;
×
66
        }
67

68
        r = pkcs11_find_token(pkcs11_uri, pkcs11_crypt_device_callback, &data);
×
UNCOV
69
        if (r < 0)
×
70
                return r;
71

UNCOV
72
        *ret_decrypted_key = TAKE_PTR(data.decrypted_key);
×
UNCOV
73
        *ret_decrypted_key_size = data.decrypted_key_size;
×
74

75
        return 0;
×
76
#else
77
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "PKCS#11 Token support not available.");
78
#endif
79
}
80

81
int find_pkcs11_auto_data(
×
82
                struct crypt_device *cd,
83
                char **ret_uri,
84
                void **ret_encrypted_key,
85
                size_t *ret_encrypted_key_size,
86
                int *ret_keyslot) {
87

88
#if HAVE_P11KIT
UNCOV
89
        _cleanup_free_ char *uri = NULL;
×
UNCOV
90
        _cleanup_free_ void *key = NULL;
×
91
        int r, keyslot = -1;
×
UNCOV
92
        size_t key_size = 0;
×
93

UNCOV
94
        assert(cd);
×
UNCOV
95
        assert(ret_uri);
×
UNCOV
96
        assert(ret_encrypted_key);
×
UNCOV
97
        assert(ret_encrypted_key_size);
×
98
        assert(ret_keyslot);
×
99

100
        /* Loads PKCS#11 metadata from LUKS2 JSON token headers. */
101

UNCOV
102
        for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
×
103
                _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
×
104
                sd_json_variant *w;
×
105
                int ks;
×
106

107
                r = cryptsetup_get_token_as_json(cd, token, "systemd-pkcs11", &v);
×
UNCOV
108
                if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE))
×
UNCOV
109
                        continue;
×
UNCOV
110
                if (r < 0)
×
111
                        return log_error_errno(r, "Failed to read JSON token data off disk: %m");
×
112

113
                ks = cryptsetup_get_keyslot_from_token(v);
×
114
                if (ks < 0) {
×
115
                        /* Handle parsing errors of the keyslots field gracefully, since it's not 'owned' by
116
                         * us, but by the LUKS2 spec */
117
                        log_warning_errno(ks, "Failed to extract keyslot index from PKCS#11 JSON data token %i, skipping: %m", token);
×
118
                        continue;
×
119
                }
120

UNCOV
121
                if (uri)
×
122
                        return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
×
123
                                               "Multiple PKCS#11 tokens enrolled, cannot automatically determine token.");
124

UNCOV
125
                assert(keyslot < 0);
×
126
                keyslot = ks;
×
127

UNCOV
128
                w = sd_json_variant_by_key(v, "pkcs11-uri");
×
UNCOV
129
                if (!w || !sd_json_variant_is_string(w))
×
130
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
131
                                               "PKCS#11 token data lacks 'pkcs11-uri' field.");
132

UNCOV
133
                uri = strdup(sd_json_variant_string(w));
×
134
                if (!uri)
×
135
                        return log_oom();
×
136

137
                if (!pkcs11_uri_valid(uri))
×
138
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
139
                                               "PKCS#11 token data contains invalid PKCS#11 URI.");
140

UNCOV
141
                w = sd_json_variant_by_key(v, "pkcs11-key");
×
142
                if (!w)
×
143
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
144
                                               "PKCS#11 token data lacks 'pkcs11-key' field.");
145

146
                assert(!key);
×
147
                assert(key_size == 0);
×
UNCOV
148
                r = sd_json_variant_unbase64(w, &key, &key_size);
×
UNCOV
149
                if (r < 0)
×
150
                        return log_error_errno(r, "Failed to decode base64 encoded key: %m");
×
151
        }
152

UNCOV
153
        if (!uri)
×
UNCOV
154
                return log_error_errno(SYNTHETIC_ERRNO(ENXIO),
×
155
                                       "No valid PKCS#11 token data found.");
156

157
        log_info("Automatically discovered security PKCS#11 token '%s' unlocks volume.", uri);
×
158

159
        *ret_uri = TAKE_PTR(uri);
×
UNCOV
160
        *ret_encrypted_key = TAKE_PTR(key);
×
UNCOV
161
        *ret_encrypted_key_size = key_size;
×
162
        *ret_keyslot = keyslot;
×
163
        return 0;
×
164
#else
165
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "PKCS#11 Token support not available.");
166
#endif
167
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc