static struct emv_pk *emv_pk_get_ca_pk_from_file(const char *fname, const unsigned char *rid, unsigned char idx) { if (!fname) return NULL; FILE *f = fopen(fname, "r"); if (!f) { perror("fopen"); return NULL; } while (!feof(f)) { char buf[BUFSIZ]; if (fgets(buf, sizeof(buf), f) == NULL) break; struct emv_pk *pk = emv_pk_parse_pk(buf); if (!pk) continue; if (memcmp(pk->rid, rid, 5) || pk->index != idx) { emv_pk_free(pk); continue; } fclose(f); return pk; } fclose(f); return NULL; }
static int cda_test_pk(void) { const struct emv_pk *pk = &mchip_05; struct tlvdb *db; db = tlvdb_external(0x90, sizeof(issuer_cert), issuer_cert); tlvdb_add(db, tlvdb_external(0x9f32, sizeof(issuer_exp), issuer_exp)); tlvdb_add(db, tlvdb_external(0x92, sizeof(issuer_rem), issuer_rem)); tlvdb_add(db, tlvdb_external(0x5a, sizeof(pan), pan)); struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db); if (!ipk) { fprintf(stderr, "Could not recover Issuer certificate!\n"); tlvdb_free(db); return 2; } tlvdb_add(db, tlvdb_external(0x9f46, sizeof(icc_cert), icc_cert)); tlvdb_add(db, tlvdb_external(0x9f47, sizeof(icc_exp), icc_exp)); /*tlvdb_add(db, tlvdb_external(0x9f48, sizeof(issuer_rem), issuer_rem));*/ struct emv_pk *iccpk = emv_pki_recover_icc_cert(ipk, db, &ssd1_tlv); if (!iccpk) { fprintf(stderr, "Could not recover ICC certificate!\n"); emv_pk_free(ipk); tlvdb_free(db); return 2; } tlvdb_add(db, tlvdb_fixed(0x9f37, sizeof(dd1), dd1)); struct tlvdb *cda_db; cda_db = tlvdb_fixed(0x9f27, 1, (unsigned char[]){ 0x40 });
static int sda_test_pk(void) { const struct emv_pk *pk = &vsdc_01; struct tlvdb *db; db = tlvdb_external(0x90, sizeof(issuer_cert), issuer_cert); tlvdb_add(db, tlvdb_external(0x9f32, sizeof(issuer_exp), issuer_exp)); tlvdb_add(db, tlvdb_external(0x92, sizeof(issuer_rem), issuer_rem)); struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db); if (!ipk) { fprintf(stderr, "Could not recover Issuer certificate!\n"); tlvdb_free(db); return 2; } tlvdb_add(db, tlvdb_external(0x93, sizeof(ssad_cr), ssad_cr)); struct tlvdb *dacdb = emv_pki_recover_dac(ipk, db, ssd1, sizeof(ssd1)); if (!dacdb) { fprintf(stderr, "Could not recover DAC!\n"); emv_pk_free(ipk); tlvdb_free(db); return 2; } const struct tlv *dac = tlvdb_get(dacdb, 0x9f45, NULL); if (!dac) { fprintf(stderr, "DAC not found!\n"); tlvdb_free(dacdb); emv_pk_free(ipk); tlvdb_free(db); return 2; } dump_buffer(dac->value, dac->len, stdout); tlvdb_free(dacdb); emv_pk_free(ipk); tlvdb_free(db); return 0; }
struct emv_pk *emv_pk_get_ca_pk(const unsigned char *rid, unsigned char idx) { struct emv_pk *pk = NULL; if (!pk) { char *fname = emv_pk_get_ca_pk_file(NULL, rid, idx); if (fname) { pk = emv_pk_get_ca_pk_from_file(fname, rid, idx); free(fname); } } if (!pk) { char *fname = emv_pk_get_ca_pk_rid_file(NULL, rid); if (fname) { pk = emv_pk_get_ca_pk_from_file(fname, rid, idx); free(fname); } } if (!pk) { const char *fname = openemv_config_get_str("capk.file", NULL); if (!fname) { fprintf(stderr, "No CA PK file specified!\n"); return NULL; } pk = emv_pk_get_ca_pk_from_file(fname, rid, idx); } if (!pk) return NULL; printf("Verifying CA PK for %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx %zd bits...", pk->rid[0], pk->rid[1], pk->rid[2], pk->rid[3], pk->rid[4], pk->index, pk->mlen * 8); if (emv_pk_verify(pk)) { printf("OK\n"); return pk; } printf("Failed!\n"); emv_pk_free(pk); return NULL; }
int main(int argc, char **argv) { FILE *f; const char *fname; int rc = 0; fname = openemv_config_get("capk"); f = fopen(fname, "r"); if (!f) { perror("fopen"); return 1; } while (!feof(f)) { char buf[BUFSIZ]; if (fgets(buf, sizeof(buf), f) == NULL) break; struct emv_pk *pk = emv_pk_parse_pk(buf); if (!pk) continue; fprintf(stderr, "Verifying CA PK for %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx %zd bits...", pk->rid[0], pk->rid[1], pk->rid[2], pk->rid[3], pk->rid[4], pk->index, pk->mlen * 8); if (emv_pk_verify(pk)) { fprintf(stderr, "OK\n"); if (argc > 2 && argv[2][0] == 'v') { unsigned char *c; c = emv_pk_dump_pk(pk); if (c) printf("%s\n", c); free(c); } } else { fprintf(stderr, "Failed!\n"); rc = 1; } emv_pk_free(pk); } fclose(f); return rc; }