RC7
Fix Signatrure counter: now incremented Fix PIN status init: was not correctly initialized Fix "only once" CDS management: PIN was not invalidated after signing Change all return 0 by corresponding THROW error code PIN API refacto
This commit is contained in:
parent
2e0d755fb6
commit
9dec68f892
2
Makefile
2
Makefile
@ -23,7 +23,7 @@ APP_LOAD_PARAMS=--appFlags 0x40 --path "2152157255" --curve secp256k1 $(COMMON_
|
||||
|
||||
APPVERSION_M=1
|
||||
APPVERSION_N=0
|
||||
APPVERSION_P=RC6
|
||||
APPVERSION_P=RC7
|
||||
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
|
||||
|
||||
ICONNAME=icon_pgp.gif
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef GPG_API_H
|
||||
#define GPG_API_H
|
||||
|
||||
int gpg_oid2curve(unsigned char* oid, unsigned int len);
|
||||
|
||||
void gpg_init(void);
|
||||
void gpg_init_ux(void);
|
||||
@ -34,17 +35,17 @@ int gpg_apdu_get_challenge(void) ;
|
||||
|
||||
int gpg_apdu_select(void) ;
|
||||
|
||||
int gpg_apdu_verify(int id) ;
|
||||
int gpg_apdu_change_ref_data(int id) ;
|
||||
int gpg_apdu_verify(void) ;
|
||||
int gpg_apdu_change_ref_data(void) ;
|
||||
int gpg_apdu_reset_retry_counter(void) ;
|
||||
|
||||
|
||||
int gpg_oid2curve(unsigned char* oid, unsigned int len);
|
||||
int gpg_is_pin_verified(int id);
|
||||
int gpg_is_pin_blocked(int id);
|
||||
int gpg_set_pin_verified(int id, int verified);
|
||||
int gpg_check_pin(int id, unsigned char *pin_val, unsigned int pin_len);
|
||||
void gpg_change_pin(int id, unsigned char *pin_val, unsigned int pin_len);
|
||||
gpg_pin_t *gpg_pin_get_pin(int id);
|
||||
int gpg_pin_is_verified(gpg_pin_t *pin);
|
||||
int gpg_pin_is_blocked(gpg_pin_t *pin);
|
||||
int gpg_pin_set_verified(gpg_pin_t *pin, int verified);
|
||||
int gpg_pin_check(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len);
|
||||
void gpg_pin_set(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len);
|
||||
void gpg_pin_sync12(void) ;
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
/* --- IO ---- */
|
||||
|
@ -29,7 +29,7 @@ int gpg_apdu_get_challenge() {
|
||||
}
|
||||
if (olen > GPG_EXT_CHALLENGE_LENTH) {
|
||||
THROW(SW_WRONG_LENGTH);
|
||||
return 0;
|
||||
return SW_WRONG_LENGTH;
|
||||
}
|
||||
|
||||
if ((G_gpg_vstate.io_p1&0x82) == 0x82) {
|
||||
|
@ -654,7 +654,7 @@ int gpg_apdu_put_data(unsigned int ref) {
|
||||
|
||||
/* ----------------- RC ----------------- */
|
||||
case 0xD3:
|
||||
sw = gpg_apdu_change_ref_data(PIN_ID_RC);
|
||||
sw = gpg_apdu_change_ref_data();
|
||||
break;
|
||||
|
||||
/* ----------------- UIF ----------------- */
|
||||
|
@ -20,12 +20,15 @@
|
||||
#include "gpg_vars.h"
|
||||
|
||||
|
||||
int gpg_is_verified(id) {
|
||||
return G_gpg_vstate.verified_pin[id] ;
|
||||
}
|
||||
|
||||
void gpg_check_access_ins() {
|
||||
unsigned int ref;
|
||||
gpg_pin_t *pin_pw1, *pin_pw2, *pin_pw3, *pin_rc;
|
||||
|
||||
pin_pw1 = gpg_pin_get_pin(PIN_ID_PW1);
|
||||
pin_pw2 = gpg_pin_get_pin(PIN_ID_PW2);
|
||||
pin_pw3 = gpg_pin_get_pin(PIN_ID_PW3);
|
||||
pin_rc = gpg_pin_get_pin(PIN_ID_RC);
|
||||
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
|
||||
|
||||
switch (G_gpg_vstate.io_ins) {
|
||||
@ -42,7 +45,7 @@ void gpg_check_access_ins() {
|
||||
return;
|
||||
|
||||
case INS_RESET_RETRY_COUNTER:
|
||||
if (gpg_is_verified(PIN_ID_PW3) || gpg_is_verified(PIN_ID_RC)) {
|
||||
if (gpg_pin_is_verified(pin_pw3) || gpg_pin_is_verified(pin_rc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -54,27 +57,27 @@ void gpg_check_access_ins() {
|
||||
if (G_gpg_vstate.io_p1 == 0x81) {
|
||||
return;
|
||||
}
|
||||
if (gpg_is_verified(PIN_ID_PW3)) {
|
||||
if (gpg_pin_is_verified(pin_pw3)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case INS_PSO:
|
||||
if ((ref == 0x9e9a) && gpg_is_verified(PIN_ID_PW1)) {
|
||||
if ((ref == 0x9e9a) && gpg_pin_is_verified(pin_pw1)) {
|
||||
//pso:sign
|
||||
if (N_gpg_pstate->PW_status[0] == 0) {
|
||||
gpg_set_pin_verified(PIN_ID_PW1,0);
|
||||
gpg_pin_set_verified(pin_pw1, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ((ref == 0x8086 ) && gpg_is_verified(PIN_ID_PW2)) {
|
||||
if ((ref == 0x8086 ) && gpg_pin_is_verified(pin_pw2)) {
|
||||
//pso:dec
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case INS_INTERNAL_AUTHENTICATE:
|
||||
if (gpg_is_verified(PIN_ID_PW2)) {
|
||||
if (gpg_pin_is_verified(pin_pw2)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -83,7 +86,7 @@ void gpg_check_access_ins() {
|
||||
return;
|
||||
|
||||
case INS_TERMINATE_DF:
|
||||
if (gpg_is_pin_verified(PIN_ID_PW3) || gpg_is_pin_blocked(PIN_ID_PW3)) {
|
||||
if (gpg_pin_is_verified(pin_pw3)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -96,6 +99,11 @@ void gpg_check_access_ins() {
|
||||
|
||||
void gpg_check_access_read_DO() {
|
||||
unsigned int ref;
|
||||
gpg_pin_t *pin_pw2, *pin_pw3;
|
||||
|
||||
pin_pw2 = gpg_pin_get_pin(PIN_ID_PW2);
|
||||
pin_pw3 = gpg_pin_get_pin(PIN_ID_PW3);
|
||||
|
||||
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
|
||||
|
||||
switch(ref) {
|
||||
@ -144,14 +152,14 @@ void gpg_check_access_read_DO() {
|
||||
|
||||
//PW1
|
||||
case 0x0103:
|
||||
if (gpg_is_verified(PIN_ID_PW2)) {
|
||||
if (gpg_pin_is_verified(pin_pw2)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
//PW3
|
||||
case 0x0104:
|
||||
if (gpg_is_verified(PIN_ID_PW3)) {
|
||||
if (gpg_pin_is_verified(pin_pw3)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -164,15 +172,18 @@ char debugbuff[5];
|
||||
|
||||
void gpg_check_access_write_DO() {
|
||||
unsigned int ref;
|
||||
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
|
||||
gpg_pin_t *pin_pw2, *pin_pw3;
|
||||
|
||||
pin_pw2 = gpg_pin_get_pin(PIN_ID_PW2);
|
||||
pin_pw3 = gpg_pin_get_pin(PIN_ID_PW3);
|
||||
ref = (G_gpg_vstate.io_p1 << 8) | G_gpg_vstate.io_p2 ;
|
||||
|
||||
switch(ref) {
|
||||
//PW1
|
||||
case 0x0101:
|
||||
case 0x0103:
|
||||
case 0x01F2:
|
||||
if (gpg_is_verified(PIN_ID_PW2)) {
|
||||
if (gpg_pin_is_verified(pin_pw2)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -214,7 +225,7 @@ void gpg_check_access_write_DO() {
|
||||
case 0x00D6:
|
||||
case 0x00D7:
|
||||
case 0x00D8:
|
||||
if (gpg_is_verified(PIN_ID_PW3)) {
|
||||
if (gpg_pin_is_verified(pin_pw3)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -254,7 +265,7 @@ int gpg_dispatch() {
|
||||
|
||||
case INS_TERMINATE_DF:
|
||||
gpg_io_discard(0);
|
||||
if (G_gpg_vstate.verified_pin[PIN_ID_PW3] || (N_gpg_pstate->PW3.counter == 0)) {
|
||||
if (gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW3)) || (N_gpg_pstate->PW3.counter == 0)) {
|
||||
gpg_install(STATE_TERMINATE);
|
||||
return(SW_OK);
|
||||
break;
|
||||
@ -335,17 +346,16 @@ int gpg_dispatch() {
|
||||
(G_gpg_vstate.io_p2 == 0x82) ||
|
||||
(G_gpg_vstate.io_p2 == 0x83)
|
||||
) {
|
||||
sw = gpg_apdu_verify(G_gpg_vstate.io_p2&0x0F);
|
||||
sw = gpg_apdu_verify();
|
||||
break;
|
||||
}
|
||||
THROW(0x9BF0);
|
||||
//THROW(SW_INCORRECT_P1P2);
|
||||
THROW(SW_INCORRECT_P1P2);
|
||||
|
||||
case INS_CHANGE_REFERENCE_DATA:
|
||||
if ((G_gpg_vstate.io_p2 == 0x81) ||
|
||||
(G_gpg_vstate.io_p2 == 0x83)
|
||||
) {
|
||||
sw = gpg_apdu_change_ref_data(G_gpg_vstate.io_p2&0x0F);
|
||||
sw = gpg_apdu_change_ref_data();
|
||||
break;
|
||||
}
|
||||
THROW(SW_INCORRECT_P1P2);
|
||||
|
@ -69,12 +69,12 @@ int gpg_apdu_gen() {
|
||||
break;
|
||||
default:
|
||||
THROW(SW_INCORRECT_P1P2);
|
||||
return 0;
|
||||
return SW_INCORRECT_P1P2;
|
||||
}
|
||||
|
||||
if (G_gpg_vstate.io_lc != 2){
|
||||
THROW(SW_WRONG_LENGTH);
|
||||
return 0;
|
||||
return SW_WRONG_LENGTH;
|
||||
}
|
||||
|
||||
gpg_io_fetch_tl(&t,&l);
|
||||
@ -96,7 +96,7 @@ int gpg_apdu_gen() {
|
||||
break;
|
||||
default:
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
|
||||
switch ((G_gpg_vstate.io_p1<<8)|G_gpg_vstate.io_p2) {
|
||||
@ -210,28 +210,28 @@ int gpg_apdu_gen() {
|
||||
case 1024/8:
|
||||
if (keygpg->key.rsa1024.size == 0) {
|
||||
THROW (SW_REFERENCED_DATA_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_REFERENCED_DATA_NOT_FOUND;
|
||||
}
|
||||
gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa1024.n);
|
||||
break;
|
||||
case 2048/8:
|
||||
if (keygpg->key.rsa2048.size == 0) {
|
||||
THROW (SW_REFERENCED_DATA_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_REFERENCED_DATA_NOT_FOUND;
|
||||
}
|
||||
gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa2048.n);
|
||||
break;
|
||||
case 3072/8:
|
||||
if (keygpg->key.rsa3072.size == 0) {
|
||||
THROW (SW_REFERENCED_DATA_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_REFERENCED_DATA_NOT_FOUND;
|
||||
}
|
||||
gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa3072.n);
|
||||
break;
|
||||
case 4096/8:
|
||||
if (keygpg->key.rsa4096.size == 0) {
|
||||
THROW (SW_REFERENCED_DATA_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_REFERENCED_DATA_NOT_FOUND;
|
||||
}
|
||||
gpg_io_insert_tlv(0x81,ksz,(unsigned char*)&keygpg->key.rsa4096.n);
|
||||
break;
|
||||
@ -285,5 +285,5 @@ int gpg_apdu_gen() {
|
||||
}
|
||||
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
|
@ -211,6 +211,8 @@ void gpg_init() {
|
||||
gpg_nvm_write(N_gpg_pstate->magic, (void*)C_MAGIC, sizeof(C_MAGIC));
|
||||
os_memset(&G_gpg_vstate, 0, sizeof(gpg_v_state_t));
|
||||
}
|
||||
//ensure pin1 and pin2 are sync in case of powerloss
|
||||
gpg_pin_sync12();
|
||||
//key conf
|
||||
G_gpg_vstate.slot = N_gpg_pstate->config_slot[1];
|
||||
G_gpg_vstate.kslot = &N_gpg_pstate->keys[G_gpg_vstate.slot];
|
||||
@ -252,16 +254,20 @@ int gpg_install(unsigned char app_state) {
|
||||
G_gpg_vstate.work.io_buffer[0] = 0x39;
|
||||
gpg_nvm_write(&N_gpg_pstate->sex, G_gpg_vstate.work.io_buffer, 1);
|
||||
|
||||
//default PW1: 1 2 3 4 5 6
|
||||
//default PW1/PW2: 1 2 3 4 5 6
|
||||
os_memmove(pin.value, C_sha256_PW1, sizeof(C_sha256_PW1));
|
||||
pin.length = 6;
|
||||
pin.counter = 3;
|
||||
pin.ref = PIN_ID_PW1;
|
||||
gpg_nvm_write(&N_gpg_pstate->PW1, &pin, sizeof(gpg_pin_t));
|
||||
pin.ref = PIN_ID_PW2;
|
||||
gpg_nvm_write(&N_gpg_pstate->PW2, &pin, sizeof(gpg_pin_t));
|
||||
|
||||
//default PW3: 1 2 3 4 5 6 7 8
|
||||
os_memmove(pin.value, C_sha256_PW2, sizeof(C_sha256_PW2));
|
||||
pin.length = 8;
|
||||
pin.counter = 3;
|
||||
pin.ref = PIN_ID_PW3;
|
||||
gpg_nvm_write(&N_gpg_pstate->PW3, &pin, sizeof(gpg_pin_t));
|
||||
|
||||
//PWs status
|
||||
@ -269,7 +275,7 @@ int gpg_install(unsigned char app_state) {
|
||||
G_gpg_vstate.work.io_buffer[1] = GPG_MAX_PW_LENGTH;
|
||||
G_gpg_vstate.work.io_buffer[2] = GPG_MAX_PW_LENGTH;
|
||||
G_gpg_vstate.work.io_buffer[3] = GPG_MAX_PW_LENGTH;
|
||||
gpg_nvm_write(&N_gpg_pstate->config_slot, G_gpg_vstate.work.io_buffer, 4);
|
||||
gpg_nvm_write(&N_gpg_pstate->PW_status, G_gpg_vstate.work.io_buffer, 4);
|
||||
|
||||
//config slot
|
||||
G_gpg_vstate.work.io_buffer[0] = GPG_KEYS_SLOTS;
|
||||
|
@ -42,6 +42,7 @@ void gpg_io_set_offset(unsigned int offset) {
|
||||
}
|
||||
else {
|
||||
THROW(ERROR_IO_OFFSET);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,6 +77,7 @@ void gpg_io_clear() {
|
||||
void gpg_io_hole(unsigned int sz) {
|
||||
if ((G_gpg_vstate.io_length + sz) > GPG_IO_BUFFER_LENGTH) {
|
||||
THROW(ERROR_IO_FULL);
|
||||
return ;
|
||||
}
|
||||
os_memmove(G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+sz,
|
||||
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
|
||||
@ -340,7 +342,7 @@ int gpg_io_do(unsigned int io_flags) {
|
||||
(G_io_apdu_buffer[2] != G_gpg_vstate.io_p1) ||
|
||||
(G_io_apdu_buffer[3] != G_gpg_vstate.io_p2) ) {
|
||||
THROW(SW_COMMAND_NOT_ALLOWED);
|
||||
return 0;
|
||||
return SW_COMMAND_NOT_ALLOWED;
|
||||
}
|
||||
G_gpg_vstate.io_cla = G_io_apdu_buffer[0];
|
||||
G_gpg_vstate.io_lc = G_io_apdu_buffer[4];
|
||||
|
201
src/gpg_pin.c
201
src/gpg_pin.c
@ -21,11 +21,12 @@
|
||||
|
||||
#include "gpg_ux_nanos.h"
|
||||
|
||||
static gpg_pin_t *gpg_get_pin(int id) {
|
||||
gpg_pin_t *gpg_pin_get_pin(int id) {
|
||||
switch (id) {
|
||||
case PIN_ID_PW1 :
|
||||
case PIN_ID_PW2 :
|
||||
return &N_gpg_pstate->PW1;
|
||||
case PIN_ID_PW2 :
|
||||
return &N_gpg_pstate->PW2;
|
||||
case PIN_ID_PW3:
|
||||
return &N_gpg_pstate->PW3;
|
||||
case PIN_ID_RC:
|
||||
@ -36,38 +37,89 @@ static gpg_pin_t *gpg_get_pin(int id) {
|
||||
|
||||
|
||||
|
||||
static int gpg_pin_get_index(unsigned int id) {
|
||||
switch (id) {
|
||||
case PIN_ID_PW1 :
|
||||
return 1;
|
||||
case PIN_ID_PW2 :
|
||||
return 2;
|
||||
case PIN_ID_PW3 :
|
||||
return 3;
|
||||
case PIN_ID_RC :
|
||||
return 4;
|
||||
|
||||
static int gpg_check_pin_internal(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void gpg_pin_sync12() {
|
||||
gpg_pin_t *pin1, *pin2;
|
||||
pin1 = gpg_pin_get_pin(PIN_ID_PW1);
|
||||
pin2 = gpg_pin_get_pin(PIN_ID_PW2);
|
||||
if (os_memcmp(pin1, pin2, sizeof(gpg_pin_t))) {
|
||||
pin1 = gpg_pin_get_pin(PIN_ID_PW1);
|
||||
pin2 = gpg_pin_get_pin(PIN_ID_PW2);
|
||||
gpg_nvm_write(pin2, pin1, sizeof(gpg_pin_t));
|
||||
}
|
||||
|
||||
}
|
||||
static int gpg_pin_check_internal(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
|
||||
cx_sha256_t sha256;
|
||||
unsigned int counter;
|
||||
gpg_pin_t *brother;
|
||||
|
||||
brother = NULL;
|
||||
if (pin->ref == PIN_ID_PW1) {
|
||||
brother = gpg_pin_get_pin(PIN_ID_PW2);
|
||||
} else if (pin->ref == PIN_ID_PW2) {
|
||||
brother = gpg_pin_get_pin(PIN_ID_PW1);
|
||||
}
|
||||
|
||||
if (pin->counter == 0) {
|
||||
THROW(SW_PIN_BLOCKED);
|
||||
return SW_PIN_BLOCKED;
|
||||
}
|
||||
|
||||
counter = pin->counter-1;
|
||||
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
|
||||
|
||||
if (brother) {
|
||||
gpg_nvm_write(&(brother->counter), &counter, sizeof(int));
|
||||
}
|
||||
cx_sha256_init(&sha256);
|
||||
cx_hash((cx_hash_t*)&sha256, CX_LAST, pin_val, pin_len, NULL);
|
||||
if (os_memcmp(sha256.acc, pin->value, 32)) {
|
||||
return 0;
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED;
|
||||
}
|
||||
|
||||
counter = 3;
|
||||
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
|
||||
return 1;
|
||||
if (brother) {
|
||||
gpg_nvm_write(&(brother->counter), &counter, sizeof(int));
|
||||
}
|
||||
return SW_OK;
|
||||
}
|
||||
|
||||
static void gpg_checkthrow_pin(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
|
||||
|
||||
if (gpg_check_pin_internal(pin,pin_val,pin_len)) {
|
||||
static void gpg_pin_check_throw(gpg_pin_t *pin, unsigned char *pin_val, int pin_len) {
|
||||
int sw;
|
||||
gpg_pin_set_verified(pin,0);
|
||||
sw = gpg_pin_check_internal(pin,pin_val,pin_len);
|
||||
if (sw == SW_OK) {
|
||||
gpg_pin_set_verified(pin,1);
|
||||
return;
|
||||
}
|
||||
THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
THROW(sw);
|
||||
}
|
||||
|
||||
static void gpg_set_pin(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
|
||||
int gpg_pin_check(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
|
||||
int sw;
|
||||
sw = gpg_pin_check_internal(pin,pin_val,pin_len);
|
||||
gpg_pin_set_verified(pin,0);
|
||||
if (sw == SW_OK) {
|
||||
gpg_pin_set_verified(pin,1);
|
||||
}
|
||||
return sw;
|
||||
}
|
||||
|
||||
void gpg_pin_set(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin_len) {
|
||||
cx_sha256_t sha256;
|
||||
|
||||
gpg_pin_t newpin;
|
||||
@ -78,74 +130,47 @@ static void gpg_set_pin(gpg_pin_t *pin, unsigned char *pin_val, unsigned int pin
|
||||
newpin.counter = 3;
|
||||
|
||||
gpg_nvm_write(pin, &newpin, sizeof(gpg_pin_t));
|
||||
gpg_pin_sync12();
|
||||
}
|
||||
|
||||
/*
|
||||
static void gpg_unblock_pin(int id) {
|
||||
gpg_pin_t *pin;
|
||||
int counter;
|
||||
pin = gpg_get_pin(id);
|
||||
counter = 3;
|
||||
gpg_nvm_write(&(pin->counter), &counter, sizeof(int));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
int gpg_set_pin_verified(int id, int verified) {
|
||||
G_gpg_vstate.verified_pin[id] = verified;
|
||||
int gpg_pin_set_verified(gpg_pin_t *pin, int verified) {
|
||||
int idx;
|
||||
idx = gpg_pin_get_index(pin->ref);
|
||||
if (idx >= 0) {
|
||||
G_gpg_vstate.verified_pin[idx]=verified;
|
||||
return verified;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gpg_pin_is_verified(gpg_pin_t *pin) {
|
||||
int idx;
|
||||
idx = gpg_pin_get_index(pin->ref);
|
||||
if (idx >= 0) {
|
||||
return G_gpg_vstate.verified_pin[idx];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int gpg_check_pin(int id, unsigned char *pin_val, unsigned int pin_len) {
|
||||
gpg_pin_t *pin;
|
||||
pin = gpg_get_pin(id);
|
||||
return gpg_set_pin_verified(id, gpg_check_pin_internal(pin,pin_val,pin_len)?1:0);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void gpg_change_pin(int id, unsigned char *pin_val, unsigned int pin_len) {
|
||||
gpg_pin_t *pin;
|
||||
pin = gpg_get_pin(id);
|
||||
gpg_set_pin(pin, pin_val, pin_len);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int gpg_is_pin_verified(int id) {
|
||||
return G_gpg_vstate.verified_pin[id] != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int gpg_is_pin_blocked(int id) {
|
||||
gpg_pin_t *pin;
|
||||
pin = gpg_get_pin(id);
|
||||
int gpg_pin_is_blocked(gpg_pin_t *pin) {
|
||||
return pin->counter == 0;
|
||||
}
|
||||
|
||||
|
||||
/* @return: 1 verified
|
||||
* 0 not verified
|
||||
* -1 blocked
|
||||
*/
|
||||
int gpg_apdu_verify(int id) {
|
||||
int gpg_apdu_verify() {
|
||||
gpg_pin_t *pin;
|
||||
|
||||
pin = gpg_get_pin(id);
|
||||
pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
|
||||
if (pin == NULL) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
|
||||
gpg_set_pin_verified(id,0);
|
||||
if (gpg_is_pin_blocked(id)) {
|
||||
gpg_pin_set_verified(pin,0);
|
||||
if (gpg_pin_is_blocked(pin)) {
|
||||
THROW(SW_PIN_BLOCKED);
|
||||
return 0;
|
||||
return SW_PIN_BLOCKED;
|
||||
}
|
||||
if (G_gpg_vstate.io_length == 0) {
|
||||
if (G_gpg_vstate.pinmode == PIN_MODE_SCREEN) {
|
||||
@ -161,34 +186,33 @@ int gpg_apdu_verify(int id) {
|
||||
return 0;
|
||||
}
|
||||
if (G_gpg_vstate.pinmode == PIN_MODE_TRUST) {
|
||||
gpg_set_pin_verified(id,1);
|
||||
gpg_pin_set_verified(pin,1);
|
||||
gpg_io_discard(1);
|
||||
return SW_OK;
|
||||
}
|
||||
}
|
||||
gpg_checkthrow_pin(pin,
|
||||
gpg_pin_check_throw(pin,
|
||||
G_gpg_vstate.work.io_buffer+ G_gpg_vstate.io_offset,
|
||||
G_gpg_vstate.io_length);
|
||||
gpg_set_pin_verified(id,1);
|
||||
gpg_io_discard(1);
|
||||
return SW_OK;
|
||||
}
|
||||
|
||||
int gpg_apdu_change_ref_data(int id) {
|
||||
int gpg_apdu_change_ref_data() {
|
||||
gpg_pin_t *pin;
|
||||
int len, newlen;
|
||||
|
||||
pin = gpg_get_pin(id);
|
||||
pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
|
||||
if (pin == NULL) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
|
||||
gpg_set_pin_verified(id,0);
|
||||
gpg_pin_set_verified(pin,0);
|
||||
|
||||
|
||||
// --- RC pin ---
|
||||
if (id == PIN_ID_RC) {
|
||||
if (pin->ref == PIN_ID_RC) {
|
||||
newlen = G_gpg_vstate.io_length;
|
||||
if (newlen == 0) {
|
||||
gpg_nvm_write(pin, NULL, sizeof(gpg_pin_t));
|
||||
@ -197,9 +221,9 @@ int gpg_apdu_change_ref_data(int id) {
|
||||
else if ((newlen > GPG_MAX_PW_LENGTH) ||
|
||||
(newlen < 8)) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
} else {
|
||||
gpg_set_pin(pin,
|
||||
gpg_pin_set(pin,
|
||||
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
|
||||
newlen);
|
||||
}
|
||||
@ -208,9 +232,9 @@ int gpg_apdu_change_ref_data(int id) {
|
||||
}
|
||||
|
||||
// --- PW1/PW3 pin ---
|
||||
if (gpg_is_pin_blocked(id)) {
|
||||
if (gpg_pin_is_blocked(pin)) {
|
||||
THROW(SW_PIN_BLOCKED);
|
||||
return 0;
|
||||
return SW_PIN_BLOCKED;
|
||||
}
|
||||
//avoid any-overflow whitout giving info
|
||||
if (G_gpg_vstate.io_length == 0) {
|
||||
@ -228,18 +252,18 @@ int gpg_apdu_change_ref_data(int id) {
|
||||
len = pin->length;
|
||||
}
|
||||
|
||||
gpg_checkthrow_pin(pin,
|
||||
gpg_pin_check_throw(pin,
|
||||
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
|
||||
len);
|
||||
|
||||
newlen = G_gpg_vstate.io_length-len;
|
||||
if ( (newlen > GPG_MAX_PW_LENGTH) ||
|
||||
((id == PIN_ID_PW1) && (newlen < 6)) ||
|
||||
((id == PIN_ID_PW3) && (newlen < 8)) ) {
|
||||
((pin->ref == PIN_ID_PW1) && (newlen < 6)) ||
|
||||
((pin->ref == PIN_ID_PW3) && (newlen < 8)) ) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
gpg_set_pin(pin,
|
||||
gpg_pin_set(pin,
|
||||
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+len,
|
||||
newlen);
|
||||
gpg_io_discard(1);
|
||||
@ -248,20 +272,23 @@ int gpg_apdu_change_ref_data(int id) {
|
||||
|
||||
int gpg_apdu_reset_retry_counter() {
|
||||
gpg_pin_t *pin_pw1;
|
||||
gpg_pin_t *pin_pw3;
|
||||
gpg_pin_t *pin_rc;
|
||||
int rc_len, pw1_len;
|
||||
|
||||
pin_pw1 = gpg_get_pin(PIN_ID_PW1);
|
||||
pin_pw1 = gpg_pin_get_pin(PIN_ID_PW1);
|
||||
pin_pw3 = gpg_pin_get_pin(PIN_ID_PW3);
|
||||
pin_rc = gpg_pin_get_pin(PIN_ID_RC);
|
||||
|
||||
if (G_gpg_vstate.io_p1 == 2) {
|
||||
if (!G_gpg_vstate.verified_pin[PIN_ID_PW3]) {
|
||||
if (!gpg_pin_is_verified(pin_pw3)) {
|
||||
THROW(SW_SECURITY_STATUS_NOT_SATISFIED);
|
||||
return 0;
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED;
|
||||
}
|
||||
rc_len = 0;
|
||||
pw1_len = G_gpg_vstate.io_length;
|
||||
} else {
|
||||
pin_rc = gpg_get_pin(PIN_ID_RC);
|
||||
|
||||
//avoid any-overflow whitout giving info
|
||||
if (pin_rc->length > G_gpg_vstate.io_length) {
|
||||
rc_len = G_gpg_vstate.io_length;
|
||||
@ -269,16 +296,16 @@ int gpg_apdu_reset_retry_counter() {
|
||||
rc_len = pin_rc->length;
|
||||
}
|
||||
pw1_len = G_gpg_vstate.io_length-rc_len;
|
||||
gpg_checkthrow_pin(pin_rc,
|
||||
gpg_pin_check_throw(pin_rc,
|
||||
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset,
|
||||
rc_len);
|
||||
}
|
||||
|
||||
if ((pw1_len > GPG_MAX_PW_LENGTH) ||(pw1_len < 6)) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
gpg_set_pin(pin_pw1,
|
||||
gpg_pin_set(pin_pw1,
|
||||
G_gpg_vstate.work.io_buffer+G_gpg_vstate.io_offset+rc_len,
|
||||
pw1_len);
|
||||
gpg_io_discard(1);
|
||||
|
@ -26,6 +26,11 @@ const unsigned char gpg_oid_sha512[] = {
|
||||
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
|
||||
};
|
||||
|
||||
static void gpg_pso_reset_PW1() {
|
||||
if (N_gpg_pstate->PW_status[0] ==0) {
|
||||
gpg_pin_set_verified(gpg_pin_get_pin(PIN_ID_PW1),0);
|
||||
}
|
||||
}
|
||||
|
||||
static int gpg_sign(gpg_key_t *sigkey) {
|
||||
// --- RSA
|
||||
@ -50,7 +55,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
|
||||
}
|
||||
if (key->size != ksz) {
|
||||
THROW(SW_CONDITIONS_NOT_SATISFIED);
|
||||
return 0;
|
||||
return SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
|
||||
//sign
|
||||
@ -71,6 +76,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
|
||||
//send
|
||||
gpg_io_discard(0);
|
||||
gpg_io_inserted(ksz);
|
||||
gpg_pso_reset_PW1();
|
||||
return SW_OK;
|
||||
}
|
||||
// --- ECDSA/EdDSA
|
||||
@ -83,7 +89,7 @@ static int gpg_sign(gpg_key_t *sigkey) {
|
||||
key = &sigkey->key.ecfp256;
|
||||
if (key->d_len != 32) {
|
||||
THROW(SW_CONDITIONS_NOT_SATISFIED);
|
||||
return 0;
|
||||
return SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
//sign
|
||||
if (sigkey->attributes.value[0] == 19) {
|
||||
@ -120,11 +126,12 @@ static int gpg_sign(gpg_key_t *sigkey) {
|
||||
}
|
||||
|
||||
//send
|
||||
gpg_pso_reset_PW1();
|
||||
return SW_OK;
|
||||
}
|
||||
// --- PSO:CDS NOT SUPPORTED
|
||||
THROW(SW_REFERENCED_DATA_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_REFERENCED_DATA_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
@ -133,7 +140,12 @@ int gpg_apdu_pso(unsigned int pso) {
|
||||
switch(pso) {
|
||||
// --- PSO:CDS ---
|
||||
case 0x9e9a: {
|
||||
return gpg_sign(&G_gpg_vstate.kslot->sig);
|
||||
unsigned int cnt;
|
||||
int sw;
|
||||
sw = gpg_sign(&G_gpg_vstate.kslot->sig);
|
||||
cnt = G_gpg_vstate.kslot->sig_count+1;
|
||||
nvm_write(&G_gpg_vstate.kslot->sig_count,&cnt,sizeof(unsigned int));
|
||||
return sw;
|
||||
}
|
||||
|
||||
// --- PSO:DEC ---
|
||||
@ -149,7 +161,7 @@ int gpg_apdu_pso(unsigned int pso) {
|
||||
cx_rsa_private_key_t *key;
|
||||
if (G_gpg_vstate.kslot->dec.attributes.value[0] != 0x01) {
|
||||
THROW(SW_CONDITIONS_NOT_SATISFIED);
|
||||
return 0;
|
||||
return SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
ksz = (G_gpg_vstate.kslot->dec.attributes.value[1]<<8) | G_gpg_vstate.kslot->dec.attributes.value[2];
|
||||
ksz = ksz>>3;
|
||||
@ -192,7 +204,7 @@ int gpg_apdu_pso(unsigned int pso) {
|
||||
key = &G_gpg_vstate.kslot->AES_dec;
|
||||
if (!(key->size != 16)) {
|
||||
THROW(SW_CONDITIONS_NOT_SATISFIED+5);
|
||||
return 0;
|
||||
return SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
msg_len = G_gpg_vstate.io_length - G_gpg_vstate.io_offset;
|
||||
sz = cx_aes(key,
|
||||
@ -212,23 +224,23 @@ int gpg_apdu_pso(unsigned int pso) {
|
||||
unsigned int curve;
|
||||
if (G_gpg_vstate.kslot->dec.attributes.value[0] != 18) {
|
||||
THROW(SW_CONDITIONS_NOT_SATISFIED);
|
||||
return 0;
|
||||
return SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
key = &G_gpg_vstate.kslot->dec.key.ecfp256;
|
||||
if (key->d_len != 32) {
|
||||
THROW(SW_CONDITIONS_NOT_SATISFIED);
|
||||
return 0;
|
||||
return SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
gpg_io_fetch_l(&l);
|
||||
gpg_io_fetch_tl(&t, &l);
|
||||
if (t != 0x7f49) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
gpg_io_fetch_tl(&t, &l);
|
||||
if (t != 0x86) {
|
||||
THROW(SW_WRONG_DATA);
|
||||
return 0;
|
||||
return SW_WRONG_DATA;
|
||||
}
|
||||
|
||||
curve = gpg_oid2curve(G_gpg_vstate.kslot->dec.attributes.value+1, G_gpg_vstate.kslot->dec.attributes.length-1);
|
||||
@ -262,7 +274,7 @@ int gpg_apdu_pso(unsigned int pso) {
|
||||
// --- PSO:DEC:xx NOT SUPPORTDED
|
||||
default:
|
||||
THROW(SW_REFERENCED_DATA_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_REFERENCED_DATA_NOT_FOUND;
|
||||
}
|
||||
|
||||
}
|
||||
@ -270,10 +282,10 @@ int gpg_apdu_pso(unsigned int pso) {
|
||||
//--- PSO:yy NOT SUPPPORTED ---
|
||||
default:
|
||||
THROW(SW_REFERENCED_DATA_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_REFERENCED_DATA_NOT_FOUND;
|
||||
}
|
||||
THROW(SW_REFERENCED_DATA_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_REFERENCED_DATA_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
@ -284,7 +296,7 @@ int gpg_apdu_internal_authenticate() {
|
||||
if (G_gpg_vstate.kslot->aut.attributes.value[0] == 1) {
|
||||
if ( G_gpg_vstate.io_length > ((G_gpg_vstate.kslot->aut.attributes.value[1]<<8)|G_gpg_vstate.kslot->aut.attributes.value[2])*40/100) {
|
||||
THROW(SW_WRONG_LENGTH);
|
||||
return 0;
|
||||
return SW_WRONG_LENGTH;
|
||||
}
|
||||
}
|
||||
return gpg_sign(&G_gpg_vstate.kslot->aut);
|
||||
|
@ -22,22 +22,24 @@
|
||||
|
||||
int gpg_apdu_select() {
|
||||
int sw;
|
||||
if ( (G_gpg_vstate.io_length = 6) &&
|
||||
if ( (G_gpg_vstate.io_length == 6) &&
|
||||
(os_memcmp(G_gpg_vstate.work.io_buffer, N_gpg_pstate->AID, G_gpg_vstate.io_length) == 0) ) {
|
||||
G_gpg_vstate.DO_current = 0;
|
||||
G_gpg_vstate.DO_reccord = 0;
|
||||
G_gpg_vstate.DO_offset = 0;
|
||||
if ( G_gpg_vstate.selected == 0) {
|
||||
G_gpg_vstate.verified_pin[PIN_ID_PW1] = 0;
|
||||
G_gpg_vstate.verified_pin[PIN_ID_PW2] = 0;
|
||||
G_gpg_vstate.verified_pin[PIN_ID_PW3] = 0;
|
||||
G_gpg_vstate.verified_pin[PIN_ID_RC] = 0;
|
||||
G_gpg_vstate.verified_pin[0] = 0;
|
||||
G_gpg_vstate.verified_pin[1] = 0;
|
||||
G_gpg_vstate.verified_pin[2] = 0;
|
||||
G_gpg_vstate.verified_pin[3] = 0;
|
||||
G_gpg_vstate.verified_pin[4] = 0;
|
||||
}
|
||||
|
||||
gpg_io_discard(0);
|
||||
sw = SW_OK;
|
||||
} else {
|
||||
THROW(SW_FILE_NOT_FOUND);
|
||||
return 0;
|
||||
return SW_FILE_NOT_FOUND;
|
||||
}
|
||||
return sw;
|
||||
}
|
||||
|
@ -39,6 +39,7 @@
|
||||
#define GPG_RSA_DEFAULT_PUB 0x010001U
|
||||
|
||||
struct gpg_pin_s {
|
||||
unsigned int ref;
|
||||
//initial pin length, 0 means not set
|
||||
unsigned int length;
|
||||
unsigned int counter;
|
||||
@ -151,6 +152,7 @@ struct gpg_nv_state_s {
|
||||
|
||||
/* PINs */
|
||||
gpg_pin_t PW1;
|
||||
gpg_pin_t PW2;
|
||||
gpg_pin_t PW3;
|
||||
gpg_pin_t RC;
|
||||
|
||||
@ -259,10 +261,10 @@ typedef struct gpg_v_state_s gpg_v_state_t;
|
||||
#define IO_OFFSET_END (unsigned int)-1
|
||||
#define IO_OFFSET_MARK (unsigned int)-2
|
||||
|
||||
#define PIN_ID_PW1 1
|
||||
#define PIN_ID_PW2 2
|
||||
#define PIN_ID_PW3 3
|
||||
#define PIN_ID_RC 4
|
||||
#define PIN_ID_PW1 0x81
|
||||
#define PIN_ID_PW2 0x82
|
||||
#define PIN_ID_PW3 0x83
|
||||
#define PIN_ID_RC 0x84
|
||||
|
||||
#define PIN_MODE_HOST 1
|
||||
#define PIN_MODE_SCREEN 2
|
||||
|
@ -32,26 +32,6 @@
|
||||
/* --- NanoS UI layout --- */
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
#define PICSTR(x) ((char*)PIC(x))
|
||||
|
||||
#define TEMPLATE_TYPE PICSTR(C_TEMPLATE_TYPE)
|
||||
#define TEMPLATE_KEY PICSTR(C_TEMPLATE_KEY)
|
||||
#define INVALID_SELECTION PICSTR(C_INVALID_SELECTION)
|
||||
#define OK PICSTR(C_OK)
|
||||
#define NOK PICSTR(C_NOK)
|
||||
#define WRONG_PIN PICSTR(C_WRONG_PIN)
|
||||
#define RIGHT_PIN PICSTR(C_RIGHT_PIN)
|
||||
#define PIN_CHANGED PICSTR(C_PIN_CHANGED)
|
||||
#define PIN_DIFFERS PICSTR(C_PIN_DIFFERS)
|
||||
#define PIN_USER PICSTR(C_PIN_USER)
|
||||
#define PIN_ADMIN PICSTR(C_PIN_ADMIN)
|
||||
#define VERIFIED PICSTR(C_VERIFIED)
|
||||
#define NOT_VERIFIED PICSTR(C_NOT_VERIFIED)
|
||||
#define ALLOWED PICSTR(C_ALLOWED)
|
||||
#define NOT_ALLOWED PICSTR(C_NOT_ALLOWED)
|
||||
#define DEFAULT_MODE PICSTR(C_DEFAULT_MODE)
|
||||
|
||||
|
||||
|
||||
const ux_menu_entry_t ui_menu_template[];
|
||||
void ui_menu_template_display(unsigned int value);
|
||||
@ -172,12 +152,12 @@ unsigned int ui_pinconfirm_nanos_button(unsigned int button_mask, unsigned int b
|
||||
sw = 0x6985;
|
||||
switch(button_mask) {
|
||||
case BUTTON_EVT_RELEASED|BUTTON_LEFT: // CANCEL
|
||||
gpg_set_pin_verified(G_gpg_vstate.io_p2&0x0F,0);
|
||||
gpg_pin_set_verified(gpg_pin_get_pin(G_gpg_vstate.io_p2),0);
|
||||
sw = 0x6985;
|
||||
break;
|
||||
|
||||
case BUTTON_EVT_RELEASED|BUTTON_RIGHT: // OK
|
||||
gpg_set_pin_verified(G_gpg_vstate.io_p2&0x0F,1);
|
||||
gpg_pin_set_verified(gpg_pin_get_pin(G_gpg_vstate.io_p2),1);
|
||||
sw = 0x9000;
|
||||
break;
|
||||
default:
|
||||
@ -336,24 +316,22 @@ unsigned int ui_pinentry_nanos_button(unsigned int button_mask, unsigned int but
|
||||
// >= 0
|
||||
static unsigned int validate_pin() {
|
||||
unsigned int offset, len, sw;
|
||||
gpg_pin_t *pin;
|
||||
|
||||
|
||||
for (offset = 1; offset< G_gpg_vstate.ux_pinentry[0];offset++) {
|
||||
G_gpg_vstate.menu[offset] = C_pin_digit[G_gpg_vstate.ux_pinentry[offset]];
|
||||
}
|
||||
|
||||
if (G_gpg_vstate.io_ins == 0x20) {
|
||||
if (gpg_check_pin(G_gpg_vstate.io_p2&0x0F, (unsigned char*)(G_gpg_vstate.menu+1), G_gpg_vstate.ux_pinentry[0])) {
|
||||
sw = SW_OK;
|
||||
} else {
|
||||
sw = SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
|
||||
sw = gpg_pin_check(pin, (unsigned char*)(G_gpg_vstate.menu+1), G_gpg_vstate.ux_pinentry[0]);
|
||||
gpg_io_discard(1);
|
||||
gpg_io_insert_u16(sw);
|
||||
gpg_io_do(IO_RETURN_AFTER_TX);
|
||||
if (sw == SW_CONDITIONS_NOT_SATISFIED) {
|
||||
ui_info(WRONG_PIN, NULL, ui_menu_main_display, 0);
|
||||
} else {
|
||||
ui_info(RIGHT_PIN, NULL, ui_menu_main_display, 0);
|
||||
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), " %d tries remaining", pin->counter );
|
||||
ui_info(WRONG_PIN, G_gpg_vstate.menu, ui_menu_main_display, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -365,10 +343,12 @@ static unsigned int validate_pin() {
|
||||
G_gpg_vstate.io_p1++;
|
||||
}
|
||||
if (G_gpg_vstate.io_p1 == 3) {
|
||||
if (!gpg_check_pin(G_gpg_vstate.io_p2&0x0F, G_gpg_vstate.work.io_buffer+1, G_gpg_vstate.work.io_buffer[0])) {
|
||||
pin = gpg_pin_get_pin(G_gpg_vstate.io_p2);
|
||||
if (gpg_pin_check(pin, G_gpg_vstate.work.io_buffer+1, G_gpg_vstate.work.io_buffer[0])!=SW_OK) {
|
||||
gpg_io_discard(1);
|
||||
gpg_io_insert_u16(SW_CONDITIONS_NOT_SATISFIED);
|
||||
gpg_io_do(IO_RETURN_AFTER_TX);
|
||||
snprintf(G_gpg_vstate.menu, sizeof(G_gpg_vstate.menu), " %d tries remaining", pin->counter );
|
||||
ui_info(WRONG_PIN, NULL, ui_menu_main_display, 0);
|
||||
return 0;
|
||||
}
|
||||
@ -381,11 +361,12 @@ static unsigned int validate_pin() {
|
||||
gpg_io_do(IO_RETURN_AFTER_TX);
|
||||
ui_info(PIN_DIFFERS, NULL, ui_menu_main_display, 0);
|
||||
} else {
|
||||
gpg_change_pin(G_gpg_vstate.io_p2&0x0F, G_gpg_vstate.work.io_buffer+offset+ 1, len);
|
||||
gpg_pin_set(gpg_pin_get_pin(G_gpg_vstate.io_p2), G_gpg_vstate.work.io_buffer+offset+ 1, len);
|
||||
gpg_io_discard(1);
|
||||
gpg_io_insert_u16(SW_OK);
|
||||
gpg_io_do(IO_RETURN_AFTER_TX);
|
||||
ui_info(PIN_CHANGED, NULL, ui_menu_main_display, 0);
|
||||
//ui_info(PIN_CHANGED, NULL, ui_menu_main_display, 0);
|
||||
ui_menu_main_display(0);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
@ -680,7 +661,7 @@ void ui_menu_pinmode_action(unsigned int value) {
|
||||
switch (value) {
|
||||
case PIN_MODE_HOST:
|
||||
case PIN_MODE_SCREEN:
|
||||
if (!gpg_is_pin_verified(PIN_ID_PW1)) {
|
||||
if (!gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW2))) {
|
||||
ui_info(PIN_USER, NOT_VERIFIED, ui_menu_pinmode_display,0);
|
||||
return;
|
||||
}
|
||||
@ -688,7 +669,7 @@ void ui_menu_pinmode_action(unsigned int value) {
|
||||
|
||||
case PIN_MODE_CONFIRM:
|
||||
case PIN_MODE_TRUST:
|
||||
if (!gpg_is_pin_verified(PIN_ID_PW3)) {
|
||||
if (!gpg_pin_is_verified(gpg_pin_get_pin(PIN_ID_PW3))) {
|
||||
ui_info(PIN_ADMIN, NOT_VERIFIED, ui_menu_pinmode_display,0);
|
||||
return;
|
||||
}
|
||||
@ -709,8 +690,8 @@ const ux_menu_entry_t ui_menu_reset[] = {
|
||||
#error menu definition not correct for current value of GPG_KEYS_SLOTS
|
||||
#endif
|
||||
{NULL, NULL, 0, NULL, "Really Reset ?", NULL, 0, 0},
|
||||
{NULL, ui_menu_main_display, 0, &C_badge_back, "Oh No!", NULL, 61, 40},
|
||||
{NULL, ui_menu_reset_action, 0, NULL, "Yes!", NULL, 0, 0},
|
||||
{NULL, ui_menu_main_display, 0, &C_badge_back, "No", NULL, 61, 40},
|
||||
{NULL, ui_menu_reset_action, 0, NULL, "Yes", NULL, 0, 0},
|
||||
UX_MENU_END
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user