Compare commits
15 Commits
v4.4
...
nightly-ma
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b7beeec8c | ||
|
|
1f037da326 | ||
|
|
ffbdef14b6 | ||
|
|
ad59aa8c1a | ||
|
|
fcca95715e | ||
|
|
704df76499 | ||
|
|
e6cc190c4f | ||
|
|
615737807a | ||
|
|
e563bb3379 | ||
|
|
374cff588c | ||
|
|
ca8d81fd20 | ||
|
|
5d71e69c1d | ||
|
|
75691b6a42 | ||
|
|
811f33e282 | ||
|
|
90b62f067d |
@@ -76,7 +76,7 @@ set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/openpgp/defs.c
|
||||
)
|
||||
|
||||
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/openpgp/version.h" 3)
|
||||
SET_VERSION(ver_major ver_minor "${CMAKE_CURRENT_LIST_DIR}/src/openpgp/version.h")
|
||||
|
||||
if(ESP_PLATFORM)
|
||||
project(pico_openpgp)
|
||||
|
||||
Submodule pico-keys-sdk updated: 6f996c67c2...6b483029a5
@@ -29,10 +29,20 @@ int cmd_get_data() {
|
||||
if (!(ef = search_by_fid(fid, NULL, SPECIFY_EF))) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
}
|
||||
if (!authenticate_action(ef, ACL_OP_READ_SEARCH)) {
|
||||
if (fid == EF_PRIV_DO_3) {
|
||||
if (!has_pw2 && !has_pw3) {
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
}
|
||||
}
|
||||
else if (fid == EF_PRIV_DO_4) {
|
||||
if (!has_pw3) {
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
}
|
||||
}
|
||||
else if (!authenticate_action(ef, ACL_OP_READ_SEARCH)) {
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
}
|
||||
if (currentEF && (currentEF->fid & 0x1FF0) == (fid & 0x1FF0)) { //previously selected
|
||||
if (currentEF && currentEF->fid == fid) { // previously selected same EF
|
||||
ef = currentEF;
|
||||
}
|
||||
else {
|
||||
@@ -44,23 +54,25 @@ int cmd_get_data() {
|
||||
}
|
||||
uint16_t fids[] = { 1, fid };
|
||||
uint16_t data_len = parse_do(fids, 1);
|
||||
uint8_t *p = NULL;
|
||||
uint16_t tg = 0;
|
||||
uint16_t tg_len = 0;
|
||||
asn1_ctx_t ctxi;
|
||||
asn1_ctx_init(res_APDU, data_len, &ctxi);
|
||||
if (walk_tlv(&ctxi, &p, &tg, &tg_len, NULL)) {
|
||||
uint8_t dec = 2;
|
||||
if ((tg & 0x1f) == 0x1f) {
|
||||
dec++;
|
||||
}
|
||||
if ((res_APDU[dec - 1] & 0xF0) == 0x80) {
|
||||
dec += (res_APDU[dec - 1] & 0x0F);
|
||||
}
|
||||
if (tg_len + dec == data_len) {
|
||||
memmove(res_APDU, res_APDU + dec, data_len - dec);
|
||||
data_len -= dec;
|
||||
res_APDU_size -= dec;
|
||||
if (!(ef->type & FILE_DATA_FLASH)) {
|
||||
uint8_t *p = NULL;
|
||||
uint16_t tg = 0;
|
||||
uint16_t tg_len = 0;
|
||||
asn1_ctx_t ctxi;
|
||||
asn1_ctx_init(res_APDU, data_len, &ctxi);
|
||||
if (walk_tlv(&ctxi, &p, &tg, &tg_len, NULL)) {
|
||||
uint8_t dec = 2;
|
||||
if ((tg & 0x1f) == 0x1f) {
|
||||
dec++;
|
||||
}
|
||||
if ((res_APDU[dec - 1] & 0xF0) == 0x80) {
|
||||
dec += (res_APDU[dec - 1] & 0x0F);
|
||||
}
|
||||
if (tg_len + dec == data_len) {
|
||||
memmove(res_APDU, res_APDU + dec, data_len - dec);
|
||||
data_len -= dec;
|
||||
res_APDU_size -= dec;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_gpg == false) {
|
||||
@@ -128,3 +140,10 @@ int cmd_get_next_data() {
|
||||
select_file(ef);
|
||||
return cmd_get_data();
|
||||
}
|
||||
|
||||
int cmd_get_bulk_data() {
|
||||
if (apdu.nc < 3) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
return bulk_cmd(cmd_get_data);
|
||||
}
|
||||
|
||||
@@ -32,43 +32,54 @@ int cmd_put_data() {
|
||||
if (!authenticate_action(ef, ACL_OP_UPDATE_ERASE)) {
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
}
|
||||
if ((fid == EF_PRIV_DO_1 || fid == EF_PRIV_DO_3) && (!has_pw2 && !has_pw3)) {
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
}
|
||||
if (!(fid == EF_PRIV_DO_1 || fid == EF_PRIV_DO_3) && !has_pw3) {
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
}
|
||||
if (fid == EF_PW_STATUS) {
|
||||
fid = EF_PW_PRIV;
|
||||
apdu.nc = 4; //we silently ommit the reset parameters
|
||||
}
|
||||
if (currentEF && (currentEF->fid & 0x1FF0) == (fid & 0x1FF0)) { //previously selected
|
||||
if (currentEF && currentEF->fid == fid) { // previously selected same EF
|
||||
ef = currentEF;
|
||||
}
|
||||
if (apdu.nc > 0 && (ef->type & FILE_DATA_FLASH)) {
|
||||
if (ef->type & FILE_DATA_FLASH) {
|
||||
int r = 0;
|
||||
if (fid == EF_RC) {
|
||||
has_rc = false;
|
||||
if ((r = load_dek()) != PICOKEY_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
uint8_t dhash[33];
|
||||
dhash[0] = apdu.nc;
|
||||
double_hash_pin(apdu.data, apdu.nc, dhash + 1);
|
||||
r = file_put_data(ef, dhash, sizeof(dhash));
|
||||
if (apdu.nc > 0) {
|
||||
if (fid == EF_RC) {
|
||||
has_rc = false;
|
||||
if ((r = load_dek()) != PICOKEY_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
uint8_t dhash[33];
|
||||
dhash[0] = apdu.nc;
|
||||
double_hash_pin(apdu.data, apdu.nc, dhash + 1);
|
||||
r = file_put_data(ef, dhash, sizeof(dhash));
|
||||
|
||||
file_t *tf = search_by_fid(EF_DEK, NULL, SPECIFY_EF);
|
||||
if (!tf) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
file_t *tf = search_by_fid(EF_DEK, NULL, SPECIFY_EF);
|
||||
if (!tf) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
}
|
||||
uint8_t def[IV_SIZE + 32 + 32 + 32 + 32];
|
||||
memcpy(def, file_get_data(tf), file_get_size(tf));
|
||||
hash_multi(apdu.data, apdu.nc, session_rc);
|
||||
memcpy(def + IV_SIZE + 32, dek + IV_SIZE, 32);
|
||||
aes_encrypt_cfb_256(session_rc, def, def + IV_SIZE + 32, 32);
|
||||
r = file_put_data(tf, def, sizeof(def));
|
||||
}
|
||||
uint8_t def[IV_SIZE + 32 + 32 + 32 + 32];
|
||||
memcpy(def, file_get_data(tf), file_get_size(tf));
|
||||
hash_multi(apdu.data, apdu.nc, session_rc);
|
||||
memcpy(def + IV_SIZE + 32, dek + IV_SIZE, 32);
|
||||
aes_encrypt_cfb_256(session_rc, def, def + IV_SIZE + 32, 32);
|
||||
r = file_put_data(tf, def, sizeof(def));
|
||||
else {
|
||||
r = file_put_data(ef, apdu.data, apdu.nc);
|
||||
}
|
||||
if (r != PICOKEY_OK) {
|
||||
return SW_MEMORY_FAILURE();
|
||||
}
|
||||
low_flash_available();
|
||||
}
|
||||
else {
|
||||
r = file_put_data(ef, apdu.data, apdu.nc);
|
||||
delete_file(ef);
|
||||
}
|
||||
if (r != PICOKEY_OK) {
|
||||
return SW_MEMORY_FAILURE();
|
||||
}
|
||||
low_flash_available();
|
||||
}
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
@@ -55,12 +55,12 @@ uint8_t historical_bytes[] = {
|
||||
|
||||
uint8_t extended_capabilities[] = {
|
||||
10, 0,
|
||||
0x77, /*
|
||||
0x7f, /*
|
||||
* No Secure Messaging supported
|
||||
* GET CHALLENGE supported
|
||||
* Key import supported
|
||||
* PW status byte can be put
|
||||
* No private_use_DO
|
||||
* private_use_DO
|
||||
* Algorithm attrs are changable
|
||||
* ENC/DEC with AES
|
||||
* KDF-DO available
|
||||
@@ -68,7 +68,7 @@ uint8_t extended_capabilities[] = {
|
||||
0, /* Secure Messaging Algorithm: N/A (TDES=0, AES=1) */
|
||||
0x00, 128, /* Max size of GET CHALLENGE */
|
||||
0x08, 0x00, /* max. length of cardholder certificate (2KiB) */
|
||||
0x00, 0xff,
|
||||
0x08, 0x00, /* max. length of private DO (2KiB) */
|
||||
0x00, 0x1
|
||||
};
|
||||
|
||||
@@ -114,7 +114,7 @@ file_t file_entries[] = {
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
|
||||
/* 10 */ { .fid = EF_CH_CERT, .parent = 0, .name = NULL,
|
||||
.type = FILE_TYPE_WORKING_EF | FILE_DATA_FUNC, .data = (uint8_t *) parse_ch_cert,
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
|
||||
/* 11 */ { .fid = EF_EXLEN_INFO, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF,
|
||||
.data = exlen_info, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
|
||||
/* 12 */ { .fid = EF_GFM, .parent = 0, .name = NULL, .type = FILE_TYPE_WORKING_EF,
|
||||
@@ -476,10 +476,28 @@ file_t file_entries[] = {
|
||||
/* 131 */ { .fid = EF_PW_RETRIES, .parent = 0, .name = NULL,
|
||||
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
|
||||
/* 131 */ { .fid = EF_PRIV_DO_1, .parent = 0, .name = NULL,
|
||||
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
|
||||
/* 132 */ { .fid = EF_PRIV_DO_2, .parent = 0, .name = NULL,
|
||||
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
|
||||
/* 133 */ { .fid = EF_PRIV_DO_3, .parent = 0, .name = NULL,
|
||||
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP },
|
||||
/* 134 */ { .fid = EF_PRIV_DO_4, .parent = 0, .name = NULL,
|
||||
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_WP },
|
||||
/* 135 */ { .fid = EF_PW_RETRIES, .parent = 0, .name = NULL,
|
||||
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
|
||||
/* 136 */ { .fid = EF_PW_STATUS, .parent = 0, .name = NULL,
|
||||
.type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL,
|
||||
.ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_R_WP },
|
||||
|
||||
/* 132 */ { .fid = 0x0000, .parent = 0, .name = openpgp_aid, .type = FILE_TYPE_WORKING_EF,
|
||||
/* 137 */ { .fid = 0x0000, .parent = 0, .name = openpgp_aid, .type = FILE_TYPE_WORKING_EF,
|
||||
.data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = ACL_RO },
|
||||
/* 133 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_NOT_KNOWN, .data = NULL,
|
||||
/* 138 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_NOT_KNOWN, .data = NULL,
|
||||
.ef_structure = 0, .acl = ACL_NONE } //end
|
||||
};
|
||||
|
||||
|
||||
@@ -163,4 +163,9 @@
|
||||
|
||||
#define EF_DEV_CONF 0x1122
|
||||
|
||||
#define EF_PRIV_DO_1 0x0101
|
||||
#define EF_PRIV_DO_2 0x0102
|
||||
#define EF_PRIV_DO_3 0x0103
|
||||
#define EF_PRIV_DO_4 0x0104
|
||||
|
||||
#endif
|
||||
|
||||
@@ -282,7 +282,7 @@ int dek_decrypt(uint8_t *data, size_t len) {
|
||||
|
||||
void init_openpgp() {
|
||||
isUserAuthenticated = false;
|
||||
has_pw1 = has_pw3 = false;
|
||||
has_pw1 = has_pw2 = has_pw3 = false;
|
||||
algo_dec = EF_ALGO_PRIV2;
|
||||
algo_aut = EF_ALGO_PRIV3;
|
||||
pk_dec = EF_PK_DEC;
|
||||
@@ -293,7 +293,7 @@ void init_openpgp() {
|
||||
|
||||
int openpgp_unload() {
|
||||
isUserAuthenticated = false;
|
||||
has_pw1 = has_pw3 = false;
|
||||
has_pw1 = has_pw2 = has_pw3 = false;
|
||||
algo_dec = EF_ALGO_PRIV2;
|
||||
algo_aut = EF_ALGO_PRIV3;
|
||||
pk_dec = EF_PK_DEC;
|
||||
@@ -793,6 +793,7 @@ extern int cmd_terminate_df();
|
||||
extern int cmd_pso();
|
||||
extern int cmd_keypair_gen();
|
||||
extern int cmd_reset_retry();
|
||||
extern int cmd_get_bulk_data();
|
||||
|
||||
#define INS_VERIFY 0x20
|
||||
#define INS_MSE 0x22
|
||||
@@ -807,6 +808,7 @@ extern int cmd_reset_retry();
|
||||
#define INS_SELECT_DATA 0xA5
|
||||
#define INS_GET_DATA 0xCA
|
||||
#define INS_GET_NEXT_DATA 0xCC
|
||||
#define INS_GET_BULK_DATA 0xCE
|
||||
#define INS_PUT_DATA 0xDA
|
||||
#define INS_IMPORT_DATA 0xDB
|
||||
#define INS_TERMINATE_DF 0xE6
|
||||
@@ -830,7 +832,8 @@ static const cmd_t cmds[] = {
|
||||
{ INS_VERSION, cmd_version_openpgp },
|
||||
{ INS_SELECT_DATA, cmd_select_data },
|
||||
{ INS_GET_NEXT_DATA, cmd_get_next_data },
|
||||
{ 0x00, 0x0 }
|
||||
{ INS_GET_BULK_DATA, cmd_get_bulk_data },
|
||||
{ 0x00, NULL }
|
||||
};
|
||||
|
||||
int openpgp_process_apdu() {
|
||||
|
||||
@@ -124,7 +124,7 @@ static int x509_create_cert(void *pk_ctx, uint8_t algo, uint8_t slot, bool attes
|
||||
mbedtls_x509write_crt_set_extension(&ctx, "\x2B\x06\x01\x04\x01\x82\xC4\x0A\x03\x08", 10, 0, &meta[1], 2);
|
||||
}
|
||||
uint8_t v = 1;
|
||||
mbedtls_x509write_crt_set_extension(&ctx, "\x2B\x06\x01\x04\x01\x82\xC4\x0A\x03\x09", 10, 0, &v, sizeof(serial));
|
||||
mbedtls_x509write_crt_set_extension(&ctx, "\x2B\x06\x01\x04\x01\x82\xC4\x0A\x03\x09", 10, 0, &v, sizeof(v));
|
||||
}
|
||||
else {
|
||||
uint8_t wslot = slot;
|
||||
@@ -153,9 +153,7 @@ static int x509_create_cert(void *pk_ctx, uint8_t algo, uint8_t slot, bool attes
|
||||
}
|
||||
mbedtls_x509write_crt_set_subject_key_identifier(&ctx);
|
||||
mbedtls_x509write_crt_set_authority_key_identifier(&ctx);
|
||||
mbedtls_x509write_crt_set_key_usage(&ctx,
|
||||
MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
|
||||
MBEDTLS_X509_KU_KEY_CERT_SIGN);
|
||||
mbedtls_x509write_crt_set_key_usage(&ctx, MBEDTLS_X509_KU_DIGITAL_SIGNATURE | MBEDTLS_X509_KU_KEY_CERT_SIGN);
|
||||
int ret = mbedtls_x509write_crt_der(&ctx, buffer, buffer_size, random_gen, NULL);
|
||||
/* skey cannot be freed, as it is freed later */
|
||||
if (attestation) {
|
||||
@@ -1020,6 +1018,9 @@ static int cmd_move_key() {
|
||||
if ((!IS_KEY(to) && to != 0xFF) || !IS_KEY(from)) {
|
||||
return SW_INCORRECT_P1P2();
|
||||
}
|
||||
if (IS_RETIRED(from) && IS_ACTIVE(to)) {
|
||||
return SW_INCORRECT_P1P2();
|
||||
}
|
||||
if (from == 0x93) {
|
||||
from = EF_PIV_KEY_RETIRED18;
|
||||
}
|
||||
@@ -1030,9 +1031,85 @@ static int cmd_move_key() {
|
||||
if (!(efs = search_by_fid(from, NULL, SPECIFY_EF)) || (!(efd = search_by_fid(to, NULL, SPECIFY_EF)) && to != 0xFF)) {
|
||||
return SW_FILE_NOT_FOUND();
|
||||
}
|
||||
uint16_t cert_from_fid = 0;
|
||||
uint16_t cert_to_fid = 0;
|
||||
if (from == EF_PIV_KEY_AUTHENTICATION) {
|
||||
cert_from_fid = EF_PIV_AUTHENTICATION;
|
||||
}
|
||||
else if (from == EF_PIV_KEY_SIGNATURE) {
|
||||
cert_from_fid = EF_PIV_SIGNATURE;
|
||||
}
|
||||
else if (from == EF_PIV_KEY_KEYMGM) {
|
||||
cert_from_fid = EF_PIV_KEY_MANAGEMENT;
|
||||
}
|
||||
else if (from == EF_PIV_KEY_CARDAUTH) {
|
||||
cert_from_fid = EF_PIV_CARD_AUTH;
|
||||
}
|
||||
else if (from == EF_PIV_KEY_RETIRED18) {
|
||||
cert_from_fid = EF_PIV_RETIRED18;
|
||||
}
|
||||
else {
|
||||
cert_from_fid = from + 0xC08B;
|
||||
}
|
||||
if (to != 0xFF) {
|
||||
if (to == EF_PIV_KEY_AUTHENTICATION) {
|
||||
cert_to_fid = EF_PIV_AUTHENTICATION;
|
||||
}
|
||||
else if (to == EF_PIV_KEY_SIGNATURE) {
|
||||
cert_to_fid = EF_PIV_SIGNATURE;
|
||||
}
|
||||
else if (to == EF_PIV_KEY_KEYMGM) {
|
||||
cert_to_fid = EF_PIV_KEY_MANAGEMENT;
|
||||
}
|
||||
else if (to == EF_PIV_KEY_CARDAUTH) {
|
||||
cert_to_fid = EF_PIV_CARD_AUTH;
|
||||
}
|
||||
else if (to == EF_PIV_KEY_RETIRED18) {
|
||||
cert_to_fid = EF_PIV_RETIRED18;
|
||||
}
|
||||
else {
|
||||
cert_to_fid = to + 0xC08B;
|
||||
}
|
||||
}
|
||||
|
||||
if (to != 0xFF) {
|
||||
file_put_data(efd, file_get_data(efs), file_get_size(efs));
|
||||
}
|
||||
|
||||
file_t *ef_cert_from = search_by_fid(cert_from_fid, NULL, SPECIFY_EF);
|
||||
if (to != 0xFF) {
|
||||
file_t *ef_cert_to = search_by_fid(cert_to_fid, NULL, SPECIFY_EF);
|
||||
if (!ef_cert_to) {
|
||||
return SW_FILE_NOT_FOUND();
|
||||
}
|
||||
if (file_has_data(ef_cert_from)) {
|
||||
file_put_data(ef_cert_to, file_get_data(ef_cert_from), file_get_size(ef_cert_from));
|
||||
}
|
||||
else {
|
||||
flash_clear_file(ef_cert_to);
|
||||
}
|
||||
}
|
||||
if (ef_cert_from) {
|
||||
flash_clear_file(ef_cert_from);
|
||||
}
|
||||
|
||||
uint8_t *meta_src = NULL;
|
||||
int meta_len = meta_find(from, &meta_src);
|
||||
if (to != 0xFF) {
|
||||
if (meta_len > 0 && meta_src != NULL) {
|
||||
uint8_t *meta_copy = (uint8_t *)calloc(1, (size_t)meta_len);
|
||||
if (!meta_copy) {
|
||||
return SW_MEMORY_FAILURE();
|
||||
}
|
||||
memcpy(meta_copy, meta_src, (size_t)meta_len);
|
||||
meta_add(to, meta_copy, (uint16_t)meta_len);
|
||||
free(meta_copy);
|
||||
}
|
||||
else {
|
||||
meta_delete(to);
|
||||
}
|
||||
}
|
||||
meta_delete(from);
|
||||
flash_clear_file(efs);
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
@@ -1154,6 +1231,7 @@ static int cmd_attestation() {
|
||||
return SW_INCORRECT_PARAMS();
|
||||
}
|
||||
int r = 0;
|
||||
uint8_t abuf[2048];
|
||||
if (meta[0] == PIV_ALGO_RSA1024 || meta[0] == PIV_ALGO_RSA2048) {
|
||||
mbedtls_rsa_context ctx;
|
||||
mbedtls_rsa_init(&ctx);
|
||||
@@ -1162,7 +1240,7 @@ static int cmd_attestation() {
|
||||
mbedtls_rsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
r = x509_create_cert(&ctx, meta[0], key_ref, true, res_APDU, 2048);
|
||||
r = x509_create_cert(&ctx, meta[0], key_ref, true, abuf, sizeof(abuf));
|
||||
mbedtls_rsa_free(&ctx);
|
||||
}
|
||||
else if (meta[0] == PIV_ALGO_ECCP256 || meta[0] == PIV_ALGO_ECCP384) {
|
||||
@@ -1173,7 +1251,7 @@ static int cmd_attestation() {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
r = x509_create_cert(&ctx, meta[0], key_ref, true, res_APDU, 2048);
|
||||
r = x509_create_cert(&ctx, meta[0], key_ref, true, abuf, sizeof(abuf));
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
}
|
||||
else {
|
||||
@@ -1182,7 +1260,7 @@ static int cmd_attestation() {
|
||||
if (r <= 0) {
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
memmove(res_APDU, res_APDU + 2048 - r, r);
|
||||
memcpy(res_APDU, abuf + sizeof(abuf) - r, r);
|
||||
res_APDU_size = r;
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ def test_extended_capabilities(card):
|
||||
pytest.skip("Yubikey returns 6B00 when no key")
|
||||
else:
|
||||
a = get_data_object(card, 0xc0)
|
||||
assert a == None or match(b'[\x70\x74\x75\x77]\x00\x00.[\x00\x08]\x00\x00\xff[\x00\x01][\x00\x01]', a)
|
||||
assert a == None or match(b'[\x70\x7F\x75\x77]\x00\x00.[\x00\x08]\x00\x08\x00[\x00\x01][\x00\x01]', a)
|
||||
|
||||
def test_key_attributes_1(card):
|
||||
if card.is_yubikey:
|
||||
|
||||
@@ -28,6 +28,26 @@ from card_const import *
|
||||
from constants_for_test import *
|
||||
import pytest
|
||||
|
||||
PRIVATE_DO_0101 = (0x01, 0x01)
|
||||
PRIVATE_DO_0102 = (0x01, 0x02)
|
||||
PRIVATE_DO_0103 = (0x01, 0x03)
|
||||
PRIVATE_DO_0104 = (0x01, 0x04)
|
||||
|
||||
|
||||
def _assert_sw(e, sw_list):
|
||||
sw = e.args[0]
|
||||
assert sw in sw_list
|
||||
|
||||
|
||||
def _expect_security_error(callable_):
|
||||
try:
|
||||
callable_()
|
||||
except ValueError as e:
|
||||
_assert_sw(e, ["6982", "6985"])
|
||||
return
|
||||
assert False
|
||||
|
||||
|
||||
class Test_Card_Personalize_Card_2(object):
|
||||
def test_verify_pw3_0(self, card):
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
@@ -202,3 +222,112 @@ class Test_Card_Personalize_Card_2(object):
|
||||
def test_verify_pw3_2(self, card):
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
|
||||
def test_private_do_0101_write_ok_with_pw3(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
r = card.cmd_put_data(PRIVATE_DO_0101[0], PRIVATE_DO_0101[1], b"priv0101_pw3_ok")
|
||||
assert r
|
||||
|
||||
def test_private_do_0101_write_fail_with_pw1_81(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(1, PW1_TEST4)
|
||||
assert v
|
||||
_expect_security_error(
|
||||
lambda: card.cmd_put_data(PRIVATE_DO_0101[0], PRIVATE_DO_0101[1], b"priv0101_pw1_81")
|
||||
)
|
||||
|
||||
def test_private_do_0101_write_ok_with_pw1_82(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(2, PW1_TEST4)
|
||||
assert v
|
||||
r = card.cmd_put_data(PRIVATE_DO_0101[0], PRIVATE_DO_0101[1], b"priv0101_ok")
|
||||
assert r
|
||||
|
||||
def test_private_do_0101_read_always(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
data = get_data_object(card, 0x0101)
|
||||
assert data == b"priv0101_ok" or data == b"priv0101_pw3_ok"
|
||||
|
||||
def test_private_do_0102_write_fail_with_pw1(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(2, PW1_TEST4)
|
||||
assert v
|
||||
_expect_security_error(
|
||||
lambda: card.cmd_put_data(PRIVATE_DO_0102[0], PRIVATE_DO_0102[1], b"priv0102_pw1")
|
||||
)
|
||||
|
||||
def test_private_do_0102_write_ok_with_pw3(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
r = card.cmd_put_data(PRIVATE_DO_0102[0], PRIVATE_DO_0102[1], b"priv0102_ok")
|
||||
assert r
|
||||
|
||||
def test_private_do_0102_read_always(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
data = get_data_object(card, 0x0102)
|
||||
assert data == b"priv0102_ok"
|
||||
|
||||
def test_private_do_0103_read_fail_without_auth(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
_expect_security_error(lambda: get_data_object(card, 0x0103))
|
||||
|
||||
def test_private_do_0103_read_fail_with_pw1_81(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(1, PW1_TEST4)
|
||||
assert v
|
||||
_expect_security_error(lambda: get_data_object(card, 0x0103))
|
||||
|
||||
def test_private_do_0103_write_ok_with_pw3(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
r = card.cmd_put_data(PRIVATE_DO_0103[0], PRIVATE_DO_0103[1], b"priv0103_pw3_ok")
|
||||
assert r
|
||||
|
||||
def test_private_do_0103_read_ok_with_pw3(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
data = get_data_object(card, 0x0103)
|
||||
assert data == b"priv0103_pw3_ok"
|
||||
|
||||
def test_private_do_0103_write_ok_with_pw1_82(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(2, PW1_TEST4)
|
||||
assert v
|
||||
r = card.cmd_put_data(PRIVATE_DO_0103[0], PRIVATE_DO_0103[1], b"priv0103_ok")
|
||||
assert r
|
||||
|
||||
def test_private_do_0103_read_ok_with_pw1_82(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(2, PW1_TEST4)
|
||||
assert v
|
||||
data = get_data_object(card, 0x0103)
|
||||
assert data == b"priv0103_ok"
|
||||
|
||||
def test_private_do_0104_read_fail_without_auth(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
_expect_security_error(lambda: get_data_object(card, 0x0104))
|
||||
|
||||
def test_private_do_0104_read_fail_with_pw1(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(2, PW1_TEST4)
|
||||
assert v
|
||||
_expect_security_error(lambda: get_data_object(card, 0x0104))
|
||||
|
||||
def test_private_do_0104_write_ok_with_pw3(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
r = card.cmd_put_data(PRIVATE_DO_0104[0], PRIVATE_DO_0104[1], b"priv0104_ok")
|
||||
assert r
|
||||
|
||||
def test_private_do_0104_read_ok_with_pw3(self, card):
|
||||
card.cmd_select_openpgp()
|
||||
v = card.verify(3, PW3_TEST0)
|
||||
assert v
|
||||
data = get_data_object(card, 0x0104)
|
||||
assert data == b"priv0104_ok"
|
||||
|
||||
Reference in New Issue
Block a user