]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-pkcs11.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <libcryptsetup.h>
6 #include "cryptsetup-token.h"
7 #include "cryptsetup-token-util.h"
10 #include "luks2-pkcs11.h"
11 #include "memory-util.h"
12 #include "pkcs11-util.h"
15 #define TOKEN_NAME "systemd-pkcs11"
16 #define TOKEN_VERSION_MAJOR "1"
17 #define TOKEN_VERSION_MINOR "0"
19 /* for libcryptsetup debug purpose */
20 _public_
const char *cryptsetup_token_version(void) {
21 return TOKEN_VERSION_MAJOR
"." TOKEN_VERSION_MINOR
" systemd-v" STRINGIFY(PROJECT_VERSION
) " (" GIT_VERSION
")";
24 _public_
int cryptsetup_token_open_pin(
25 struct crypt_device
*cd
, /* is always LUKS2 context */
26 int token
/* is always >= 0 */,
29 char **password
, /* freed by cryptsetup_token_buffer_free */
31 void *usrptr
/* plugin defined parameter passed to crypt_activate_by_token*() API */) {
36 assert(!pin
|| pin_size
);
39 /* This must not fail at this moment (internal error) */
40 r
= crypt_token_json_get(cd
, token
, &json
);
41 /* Use assert_se() here to avoid emitting warning with -DNDEBUG */
42 assert_se(token
== r
);
45 return acquire_luks2_key(cd
, json
, usrptr
, pin
, pin_size
, password
, password_len
);
49 * This function is called from within following libcryptsetup calls
50 * provided conditions further below are met:
52 * crypt_activate_by_token(), crypt_activate_by_token_type(type == 'systemd-pkcs11'):
54 * - token is assigned to at least one luks2 keyslot eligible to activate LUKS2 device
55 * (alternatively: name is set to null, flags contains CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY
56 * and token is assigned to at least single keyslot).
58 * - if plugin defines validate function (see cryptsetup_token_validate below) it must have
59 * passed the check (aka return 0)
61 _public_
int cryptsetup_token_open(
62 struct crypt_device
*cd
, /* is always LUKS2 context */
63 int token
/* is always >= 0 */,
64 char **password
, /* freed by cryptsetup_token_buffer_free */
66 void *usrptr
/* plugin defined parameter passed to crypt_activate_by_token*() API */) {
68 return cryptsetup_token_open_pin(cd
, token
, NULL
, 0, password
, password_len
, usrptr
);
72 * libcryptsetup callback for memory deallocation of 'password' parameter passed in
73 * any crypt_token_open_* plugin function
75 _public_
void cryptsetup_token_buffer_free(void *buffer
, size_t buffer_len
) {
76 erase_and_free(buffer
);
80 * prints systemd-pkcs11 token content in crypt_dump().
81 * 'type' and 'keyslots' fields are printed by libcryptsetup
83 _public_
void cryptsetup_token_dump(
84 struct crypt_device
*cd
/* is always LUKS2 context */,
85 const char *json
/* validated 'systemd-pkcs11' token if cryptsetup_token_validate is defined */) {
88 size_t pkcs11_key_size
;
89 _cleanup_free_
char *pkcs11_uri
= NULL
, *key_str
= NULL
;
90 _cleanup_free_
void *pkcs11_key
= NULL
;
92 r
= parse_luks2_pkcs11_data(cd
, json
, &pkcs11_uri
, &pkcs11_key
, &pkcs11_key_size
);
94 return (void) crypt_log_debug_errno(cd
, r
, "Failed to parse " TOKEN_NAME
" metadata: %m.");
96 r
= crypt_dump_buffer_to_hex_string(pkcs11_key
, pkcs11_key_size
, &key_str
);
98 return (void) crypt_log_debug_errno(cd
, r
, "Cannot dump " TOKEN_NAME
" content: %m");
100 crypt_log(cd
, "\tpkcs11-uri: %s\n", pkcs11_uri
);
101 crypt_log(cd
, "\tpkcs11-key: %s\n", key_str
);
106 * If plugin is available in library path, it's called in before following libcryptsetup calls:
108 * crypt_token_json_set, crypt_dump, any crypt_activate_by_token_* flavour
110 _public_
int cryptsetup_token_validate(
111 struct crypt_device
*cd
, /* is always LUKS2 context */
112 const char *json
/* contains valid 'type' and 'keyslots' fields. 'type' is 'systemd-pkcs11' */) {
116 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
118 r
= json_parse(json
, 0, &v
, NULL
, NULL
);
120 return crypt_log_debug_errno(cd
, r
, "Could not parse " TOKEN_NAME
" json object: %m.");
122 w
= json_variant_by_key(v
, "pkcs11-uri");
123 if (!w
|| !json_variant_is_string(w
)) {
124 crypt_log_debug(cd
, "PKCS#11 token data lacks 'pkcs11-uri' field.");
128 if (!pkcs11_uri_valid(json_variant_string(w
))) {
129 crypt_log_debug(cd
, "PKCS#11 token data contains invalid PKCS#11 URI.");
133 w
= json_variant_by_key(v
, "pkcs11-key");
134 if (!w
|| !json_variant_is_string(w
)) {
135 crypt_log_debug(cd
, "PKCS#11 token data lacks 'pkcs11-key' field.");
139 r
= unbase64mem(json_variant_string(w
), NULL
, NULL
);
141 return crypt_log_debug_errno(cd
, r
, "Failed to decode base64 encoded key: %m.");