1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include "homework-pkcs11.h"
5 #include "pkcs11-util.h"
10 CK_SESSION_HANDLE session
,
12 const CK_SLOT_INFO
*slot_info
,
13 const CK_TOKEN_INFO
*token_info
,
17 _cleanup_(erase_and_freep
) void *decrypted_key
= NULL
;
18 struct pkcs11_callback_data
*data
= userdata
;
19 _cleanup_free_
char *token_label
= NULL
;
20 CK_TOKEN_INFO updated_token_info
;
21 size_t decrypted_key_size
;
22 CK_OBJECT_HANDLE object
;
32 /* Special return values:
34 * -ENOANO → if we need a PIN but have none
35 * -ERFKILL → if a "protected authentication path" is needed but we have no OK to use it
36 * -EOWNERDEAD → if the PIN is locked
37 * -ENOLCK → if the supplied PIN is incorrect
38 * -ETOOMANYREFS → ditto, but only a few tries left
39 * -EUCLEAN → ditto, but only a single try left
42 token_label
= pkcs11_token_label(token_info
);
46 if (FLAGS_SET(token_info
->flags
, CKF_PROTECTED_AUTHENTICATION_PATH
)) {
48 if (data
->secret
->pkcs11_protected_authentication_path_permitted
<= 0)
49 return log_error_errno(SYNTHETIC_ERRNO(ERFKILL
), "Security token requires authentication through protected authentication path.");
51 rv
= m
->C_Login(session
, CKU_USER
, NULL
, 0);
53 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to log into security token '%s': %s", token_label
, p11_kit_strerror(rv
));
55 log_info("Successfully logged into security token '%s' via protected authentication path.", token_label
);
59 if (!FLAGS_SET(token_info
->flags
, CKF_LOGIN_REQUIRED
)) {
60 log_info("No login into security token '%s' required.", token_label
);
64 if (strv_isempty(data
->secret
->token_pin
))
65 return log_error_errno(SYNTHETIC_ERRNO(ENOANO
), "Security token requires PIN.");
67 STRV_FOREACH(i
, data
->secret
->token_pin
) {
68 rv
= m
->C_Login(session
, CKU_USER
, (CK_UTF8CHAR
*) *i
, strlen(*i
));
70 log_info("Successfully logged into security token '%s' with PIN.", token_label
);
73 if (rv
== CKR_PIN_LOCKED
)
74 return log_error_errno(SYNTHETIC_ERRNO(EOWNERDEAD
), "PIN of security token is blocked. Please unblock it first.");
75 if (!IN_SET(rv
, CKR_PIN_INCORRECT
, CKR_PIN_LEN_RANGE
))
76 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to log into security token '%s': %s", token_label
, p11_kit_strerror(rv
));
79 rv
= m
->C_GetTokenInfo(slot_id
, &updated_token_info
);
81 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to acquire updated security token information for slot %lu: %s", slot_id
, p11_kit_strerror(rv
));
83 if (FLAGS_SET(updated_token_info
.flags
, CKF_USER_PIN_FINAL_TRY
))
84 return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN
), "PIN of security token incorrect, only a single try left.");
85 if (FLAGS_SET(updated_token_info
.flags
, CKF_USER_PIN_COUNT_LOW
))
86 return log_error_errno(SYNTHETIC_ERRNO(ETOOMANYREFS
), "PIN of security token incorrect, only a few tries left.");
88 return log_error_errno(SYNTHETIC_ERRNO(ENOLCK
), "PIN of security token incorrect.");
91 r
= pkcs11_token_find_private_key(m
, session
, uri
, &object
);
95 r
= pkcs11_token_decrypt_data(m
, session
, object
, data
->encrypted_key
->data
, data
->encrypted_key
->size
, &decrypted_key
, &decrypted_key_size
);
99 if (base64mem(decrypted_key
, decrypted_key_size
, &data
->decrypted_password
) < 0)