mirror of
https://github.com/polhenarejos/pico-openpgp.git
synced 2026-01-23 01:43:46 +08:00
Add meta data when generatin keypair and returning public key on get metadata.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -395,20 +395,103 @@ static int cmd_get_metadata() {
|
||||
return SW_INCORRECT_P1P2();
|
||||
}
|
||||
uint8_t *meta = NULL;
|
||||
int meta_len = 0;
|
||||
if ((meta_len = meta_find(P2(apdu), &meta)) <= 0) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
uint16_t key_ref = P2(apdu);
|
||||
if (key_ref == 0x80) {
|
||||
key_ref = EF_PIV_PIN;
|
||||
}
|
||||
else if (key_ref == 0x81) {
|
||||
key_ref = EF_PIV_PUK;
|
||||
}
|
||||
file_t *ef_key = search_by_fid(key_ref, NULL, SPECIFY_EF);
|
||||
if (!file_has_data(ef_key)) {
|
||||
return SW_MEMORY_FAILURE();
|
||||
}
|
||||
if (key_ref != EF_PIV_PIN && key_ref != EF_PIV_PUK) {
|
||||
int meta_len = 0;
|
||||
if ((meta_len = meta_find(key_ref, &meta)) <= 0) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
}
|
||||
res_APDU[res_APDU_size++] = 0x1;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = meta[0];
|
||||
res_APDU[res_APDU_size++] = 0x2;
|
||||
res_APDU[res_APDU_size++] = 2;
|
||||
res_APDU[res_APDU_size++] = meta[1];
|
||||
res_APDU[res_APDU_size++] = meta[2];
|
||||
res_APDU[res_APDU_size++] = 0x3;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = meta[3];
|
||||
if (meta[0] == PIV_ALGO_RSA1024 || meta[0] == PIV_ALGO_RSA2048 || meta[0] == PIV_ALGO_ECCP256 || meta[0] == PIV_ALGO_ECCP384) {
|
||||
res_APDU[res_APDU_size++] = 0x4;
|
||||
if (meta[0] == PIV_ALGO_RSA1024 || meta[0] == PIV_ALGO_RSA2048) {
|
||||
mbedtls_rsa_context ctx;
|
||||
mbedtls_rsa_init(&ctx);
|
||||
int r = load_private_key_rsa(&ctx, ef_key, false);
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_rsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
res_APDU[res_APDU_size++] = 0x81;
|
||||
res_APDU[res_APDU_size++] = 0x82;
|
||||
put_uint16_t(mbedtls_mpi_size(&ctx.N), res_APDU + res_APDU_size); res_APDU_size += 2;
|
||||
mbedtls_mpi_write_binary(&ctx.N, res_APDU + res_APDU_size, mbedtls_mpi_size(&ctx.N));
|
||||
res_APDU_size += mbedtls_mpi_size(&ctx.N);
|
||||
res_APDU[res_APDU_size++] = 0x82;
|
||||
res_APDU[res_APDU_size++] = mbedtls_mpi_size(&ctx.E) & 0xff;
|
||||
mbedtls_mpi_write_binary(&ctx.E, res_APDU + res_APDU_size, mbedtls_mpi_size(&ctx.E));
|
||||
res_APDU_size += mbedtls_mpi_size(&ctx.E);
|
||||
mbedtls_rsa_free(&ctx);
|
||||
}
|
||||
else {
|
||||
mbedtls_ecdsa_context ctx;
|
||||
mbedtls_ecdsa_init(&ctx);
|
||||
int r = load_private_key_ecdsa(&ctx, ef_key, false);
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
uint8_t pt[MBEDTLS_ECP_MAX_PT_LEN];
|
||||
size_t plen = 0;
|
||||
mbedtls_ecp_point_write_binary(&ctx.grp, &ctx.Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &plen, pt, sizeof(pt));
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
res_APDU[res_APDU_size++] = 0x86;
|
||||
if (plen >= 128) {
|
||||
res_APDU[res_APDU_size++] = 0x81;
|
||||
}
|
||||
res_APDU[res_APDU_size++] = plen;
|
||||
memcpy(res_APDU + res_APDU_size, pt, plen);
|
||||
res_APDU_size += plen;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (key_ref == EF_PIV_PIN || key_ref == EF_PIV_PUK || key_ref == EF_PIV_KEY_MANAGEMENT) {
|
||||
uint8_t dhash[32];
|
||||
int32_t eq = false;
|
||||
if (key_ref == EF_PIV_PIN) {
|
||||
double_hash_pin((const uint8_t *)"\x31\x32\x33\x34\x35\x36\xFF\xFF", 8, dhash);
|
||||
eq = memcmp(dhash, file_get_data(ef_key) + 1, file_get_size(ef_key) - 1);
|
||||
}
|
||||
else if (key_ref == EF_PIV_PUK) {
|
||||
double_hash_pin((const uint8_t *)"\x31\x32\x33\x34\x35\x36\x37\x38", 8, dhash);
|
||||
eq = memcmp(dhash, file_get_data(ef_key) + 1, file_get_size(ef_key) - 1);
|
||||
}
|
||||
else if (key_ref == EF_PIV_KEY_MANAGEMENT) {
|
||||
eq = memcmp("\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08", file_get_data(ef_key), file_get_size(ef_key));
|
||||
}
|
||||
res_APDU[res_APDU_size++] = 0x5;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = eq;
|
||||
if (key_ref == EF_PIV_PIN || key_ref == EF_PIV_PUK) {
|
||||
file_t *pw_status;
|
||||
if (!(pw_status = search_by_fid(EF_PW_PRIV, NULL, SPECIFY_EF))) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
}
|
||||
uint8_t retries = *(file_get_data(pw_status) + 3 + (key_ref & 0xf));
|
||||
res_APDU[res_APDU_size++] = 0x6;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = retries;
|
||||
}
|
||||
}
|
||||
res_APDU[res_APDU_size++] = 0x1;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = meta[0];
|
||||
res_APDU[res_APDU_size++] = 0x2;
|
||||
res_APDU[res_APDU_size++] = 2;
|
||||
res_APDU[res_APDU_size++] = meta[1];
|
||||
res_APDU[res_APDU_size++] = meta[2];
|
||||
res_APDU[res_APDU_size++] = 0x3;
|
||||
res_APDU[res_APDU_size++] = 1;
|
||||
res_APDU[res_APDU_size++] = meta[3];
|
||||
return SW_OK();
|
||||
}
|
||||
uint8_t challenge[16];
|
||||
@@ -649,14 +732,17 @@ static int cmd_asym_keygen() {
|
||||
if (!asn1_find_tag(&ctxi, 0xAC, &aac) || asn1_len(&aac) == 0) {
|
||||
return SW_WRONG_DATA();
|
||||
}
|
||||
asn1_ctx_t a80 = {0}, a81 = {0};
|
||||
asn1_ctx_t a80 = {0}, aaa = {0}, aab = {0};
|
||||
asn1_find_tag(&aac, 0x80, &a80);
|
||||
asn1_find_tag(&aac, 0x81, &a81);
|
||||
asn1_find_tag(&aac, 0xAA, &aaa);
|
||||
asn1_find_tag(&aac, 0xAB, &aab);
|
||||
if (asn1_len(&a80) == 0) {
|
||||
return SW_WRONG_DATA();
|
||||
}
|
||||
if (a80.data[0] == PIV_ALGO_RSA1024 || a80.data[0] == PIV_ALGO_RSA2048) {
|
||||
printf("KEYPAIR RSA\r\n");
|
||||
asn1_ctx_t a81 = {0};
|
||||
asn1_find_tag(&aac, 0x81, &a81);
|
||||
mbedtls_rsa_context rsa;
|
||||
mbedtls_rsa_init(&rsa);
|
||||
uint8_t index = 0;
|
||||
@@ -696,6 +782,9 @@ static int cmd_asym_keygen() {
|
||||
}
|
||||
else if (a80.data[0] == PIV_ALGO_X25519) {
|
||||
}
|
||||
uint8_t meta[] = {a80.data[0], asn1_len(&aaa) ? aaa.data[0] : PINPOLICY_ALWAYS, asn1_len(&aab) ? aab.data[0] : TOUCHPOLICY_ALWAYS, ORIGIN_GENERATED};
|
||||
meta_add(key_ref, meta, sizeof(meta));
|
||||
low_flash_available();
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user