diff --git a/src/openpgp/cmd_put_data.c b/src/openpgp/cmd_put_data.c index 81918cc..3592a6b 100644 --- a/src/openpgp/cmd_put_data.c +++ b/src/openpgp/cmd_put_data.c @@ -61,13 +61,10 @@ int cmd_put_data(void) { return SW_WRONG_P1P2(); } if (fid == EF_PW_STATUS) { - if (apdu.nc > 4) { + if (apdu.nc != 1 || apdu.data[0] > 1) { return SW_WRONG_DATA(); } fid = EF_PW_PRIV; - if (apdu.nc == 0) { - return SW_WRONG_LENGTH(); - } if (!(ef = file_search_by_fid(fid, NULL, SPECIFY_EF))) { return SW_REFERENCE_NOT_FOUND(); } @@ -94,7 +91,7 @@ int cmd_put_data(void) { uint16_t status_len = MIN(file_get_size(ef), sizeof(pw_status)); memcpy(pw_status, file_get_data(ef), status_len); } - memcpy(pw_status, apdu.data, MIN(apdu.nc, 4u)); + pw_status[0] = apdu.data[0]; r = file_put_data(ef, CONST_BYTE_ARRAY(pw_status, sizeof(pw_status))); } else if (fid == EF_RC) { diff --git a/src/openpgp/openpgp.c b/src/openpgp/openpgp.c index a4936b1..b57a674 100644 --- a/src/openpgp/openpgp.c +++ b/src/openpgp/openpgp.c @@ -219,6 +219,27 @@ static bool reset_code_is_public_default(const file_t *rc) { return pin_record_matches_value(rc, default_reset_code, sizeof(default_reset_code) - 1); } +static void restore_pw_status_limits(void) { + file_t *pw_status = file_search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF); + if (!pw_status || !file_has_data(pw_status) || file_get_size(pw_status) > 64) { + return; + } + + uint16_t status_len = file_get_size(pw_status); + uint8_t status[64]; + bool changed = false; + memcpy(status, file_get_data(pw_status), status_len); + for (uint8_t i = 1; i < 4 && i < status_len; i++) { + if (status[i] != 127) { + status[i] = 127; + changed = true; + } + } + if (changed) { + file_put_data(pw_status, CONST_BYTE_ARRAY(status, status_len)); + } +} + static int set_reset_code_retries(uint8_t retries) { file_t *pw_status = file_search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF); if (!pw_status || !file_has_data(pw_status)) { @@ -437,6 +458,7 @@ void scan_files_openpgp(void) { } #endif } + restore_pw_status_limits(); file_t *rc = file_search_by_fid(EF_RC, NULL, SPECIFY_EF); if (!rc || !file_has_data(rc) || reset_dek || reset_code_is_public_default(rc)) { openpgp_reset_code_deactivate();