Skip to content

Commit

Permalink
Merge pull request #34 from Nitrokey/check-pin-or-set-it
Browse files Browse the repository at this point in the history
Check secrets app PIN before setting the new reverse hotp credential
  • Loading branch information
sosthene-nitrokey authored Apr 25, 2024
2 parents 70c04f5 + 8e63fa4 commit 537957e
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
4 changes: 3 additions & 1 deletion src/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "min.h"
#include "operations_ccid.h"
#include "random_data.h"
#include "return_codes.h"
#include "settings.h"
#include "structs.h"
#include "utils.h"
Expand Down Expand Up @@ -71,7 +72,8 @@ int set_secret_on_device(struct Device *dev, const char *OTP_secret_base32, cons
check_ret(authenticate_ccid(dev, admin_PIN), RET_WRONG_PIN);
}
#endif
return set_secret_on_device_ccid(dev, OTP_secret_base32, hotp_counter);

return set_secret_on_device_ccid(dev, admin_PIN, OTP_secret_base32, hotp_counter);
}


Expand Down
25 changes: 24 additions & 1 deletion src/operations_ccid.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ int authenticate_ccid(struct Device *dev, const char *admin_PIN) {
// Invalid PIN or PIN attempt counter is used up
return RET_WRONG_PIN;
}
if (iccResult.data_status_code == 0x6982) {
return RET_SECURITY_STATUS_NOT_SATISFIED;
}
if (iccResult.data_status_code != 0x9000) {
// TODO print the error code
return 1;
Expand All @@ -99,6 +102,19 @@ int authenticate_ccid(struct Device *dev, const char *admin_PIN) {
return RET_NO_ERROR;
}

// Attempt to authenticate with admin_PIN. If the PIN is not set (status code 0x6982), create the PIN
// with the given value
int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN) {
int r = authenticate_ccid(dev, admin_PIN);
if (r == RET_SECURITY_STATUS_NOT_SATISFIED) {
check_ret(set_pin_ccid(dev, admin_PIN), RET_SECURITY_STATUS_NOT_SATISFIED);
return authenticate_ccid(dev, admin_PIN);
}

return RET_NO_ERROR;
}


int delete_secret_on_device_ccid(struct Device *dev) {
TLV tlvs[] = {
{
Expand Down Expand Up @@ -130,7 +146,7 @@ int delete_secret_on_device_ccid(struct Device *dev) {
return r;
}

int set_secret_on_device_ccid(struct Device *dev, const char *OTP_secret_base32, const uint64_t hotp_counter) {
int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter) {
// Decode base32 secret
uint8_t binary_secret_buf[HOTP_SECRET_SIZE_BYTES + 2] = {0};
const size_t decoded_length = base32_decode((const unsigned char *) OTP_secret_base32, binary_secret_buf + 2) + 2;
Expand All @@ -150,6 +166,13 @@ int set_secret_on_device_ccid(struct Device *dev, const char *OTP_secret_base32,
return r;
}

#ifdef CCID_SECRETS_AUTHENTICATE_OR_CREATE_PIN
if (strnlen(admin_PIN, 30) > 0) {
if (authenticate_or_set_ccid(dev, admin_PIN) != RET_NO_ERROR) {
return RET_SECURITY_STATUS_NOT_SATISFIED;
}
}
#endif
TLV tlvs[] = {
{
.tag = Tag_CredentialId,
Expand Down
3 changes: 2 additions & 1 deletion src/operations_ccid.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

int set_pin_ccid(struct Device *dev, const char *admin_PIN);
int authenticate_ccid(struct Device *dev, const char *admin_PIN);
int set_secret_on_device_ccid(struct Device *dev, const char *OTP_secret_base32, const uint64_t hotp_counter);
int authenticate_or_set_ccid(struct Device *dev, const char *admin_PIN);
int set_secret_on_device_ccid(struct Device *dev, const char *admin_PIN, const char *OTP_secret_base32, const uint64_t hotp_counter);
int verify_code_ccid(struct Device *dev, const uint32_t code_to_verify);
int status_ccid(libusb_device_handle *handle, int *attempt_counter, uint16_t *firmware_version, uint32_t *serial_number);

Expand Down
5 changes: 4 additions & 1 deletion src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@
// #define FEATURE_CCID_ASK_FOR_PIN_ON_ERROR

// Use the provided PIN for authentication over CCID
// #define CCID_AUTHENTICATE
// #define CCID_AUTHENTICATE

// Attempt to authenticate before setting the PIN, if no pin is present, create the PIN
#define CCID_SECRETS_AUTHENTICATE_OR_CREATE_PIN

// Allow CCID use
#define FEATURE_USE_CCID
Expand Down

0 comments on commit 537957e

Please sign in to comment.