1 /* SPDX-License-Identifier: LGPL-2.1+ */
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
;
33 /* Special return values:
35 * -ENOANO → if we need a PIN but have none
36 * -ERFKILL → if a "protected authentication path" is needed but we have no OK to use it
37 * -EOWNERDEAD → if the PIN is locked
38 * -ENOLCK → if the supplied PIN is incorrect
39 * -ETOOMANYREFS → ditto, but only a few tries left
40 * -EUCLEAN → ditto, but only a single try left
43 token_label
= pkcs11_token_label(token_info
);
47 if (FLAGS_SET(token_info
->flags
, CKF_PROTECTED_AUTHENTICATION_PATH
)) {
49 if (data
->secret
->pkcs11_protected_authentication_path_permitted
<= 0)
50 return log_error_errno(SYNTHETIC_ERRNO(ERFKILL
), "Security token requires authentication through protected authentication path.");
52 rv
= m
->C_Login(session
, CKU_USER
, NULL
, 0);
54 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to log into security token '%s': %s", token_label
, p11_kit_strerror(rv
));
56 log_info("Successfully logged into security token '%s' via protected authentication path.", token_label
);
60 if (!FLAGS_SET(token_info
->flags
, CKF_LOGIN_REQUIRED
)) {
61 log_info("No login into security token '%s' required.", token_label
);
65 if (strv_isempty(data
->secret
->pkcs11_pin
))
66 return log_error_errno(SYNTHETIC_ERRNO(ENOANO
), "Security Token requires PIN.");
68 STRV_FOREACH(i
, data
->secret
->pkcs11_pin
) {
69 rv
= m
->C_Login(session
, CKU_USER
, (CK_UTF8CHAR
*) *i
, strlen(*i
));
71 log_info("Successfully logged into security token '%s' with PIN.", token_label
);
74 if (rv
== CKR_PIN_LOCKED
)
75 return log_error_errno(SYNTHETIC_ERRNO(EOWNERDEAD
), "PIN of security token is blocked. Please unblock it first.");
76 if (!IN_SET(rv
, CKR_PIN_INCORRECT
, CKR_PIN_LEN_RANGE
))
77 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to log into security token '%s': %s", token_label
, p11_kit_strerror(rv
));
80 rv
= m
->C_GetTokenInfo(slot_id
, &updated_token_info
);
82 return log_error_errno(SYNTHETIC_ERRNO(EIO
), "Failed to acquire updated security token information for slot %lu: %s", slot_id
, p11_kit_strerror(rv
));
84 if (FLAGS_SET(updated_token_info
.flags
, CKF_USER_PIN_FINAL_TRY
))
85 return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN
), "PIN of security token incorrect, only a single try left.");
86 if (FLAGS_SET(updated_token_info
.flags
, CKF_USER_PIN_COUNT_LOW
))
87 return log_error_errno(SYNTHETIC_ERRNO(ETOOMANYREFS
), "PIN of security token incorrect, only a few tries left.");
89 return log_error_errno(SYNTHETIC_ERRNO(ENOLCK
), "PIN of security token incorrect.");
92 r
= pkcs11_token_find_private_key(m
, session
, uri
, &object
);
96 r
= pkcs11_token_decrypt_data(m
, session
, object
, data
->encrypted_key
->data
, data
->encrypted_key
->size
, &decrypted_key
, &decrypted_key_size
);
100 if (base64mem(decrypted_key
, decrypted_key_size
, &data
->decrypted_password
) < 0)