int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len) { int r; sc_cardctl_openpgp_keygen_info_t key_info; u8 fingerprints[60]; sc_path_t path; sc_file_t *file; if (key_id < 1 || key_id > 3) { printf("Unknown key ID %d.\n", key_id); return 1; } memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t)); key_info.keytype = key_id; key_info.modulus_len = key_len; key_info.modulus = malloc(key_len/8); r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info); free(key_info.modulus); if (r < 0) { printf("Failed to generate key. Error %s.\n", sc_strerror(r)); return 1; } sc_format_path("006E007300C5", &path); r = sc_select_file(card, &path, &file); r = sc_read_binary(card, 0, fingerprints, 60, 0); if (r < 0) { printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r)); return 1; } printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(key_id - 1), 20)); return 0; }
/* * Lock the pin file */ static int gpk_lock_pinfile(struct sc_profile *profile, sc_card_t *card, sc_file_t *pinfile) { struct sc_path path; struct sc_file *parent = NULL; int r; /* Select the parent DF */ path = pinfile->path; if (path.len >= 2) path.len -= 2; if (path.len == 0) sc_format_path("3F00", &path); if ((r = sc_select_file(card, &path, &parent)) < 0) return r; /* Present PINs etc as necessary */ r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_LOCK); if (r >= 0) r = gpk_lock(card, pinfile, SC_AC_OP_WRITE); sc_file_free(parent); return r; }
/* * Create the Application DF */ static int incrypto34_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) { int r; struct sc_file *file; struct sc_path path; memset(&file, 0, sizeof(file)); sc_format_path("3F00", &path); if ((r = sc_select_file(p15card->card, &path, &file)) < 0) return r; if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_CREATE)) < 0) return r; /* Create the application DF */ if ((r = sc_pkcs15init_create_file(profile, p15card, df)) < 0) return r; if ((r = sc_select_file(p15card->card, &df->path, NULL)) < 0) return r; /* Create a security environment for this DF. */ if ((r = incrypto34_create_sec_env(profile, p15card->card, 0x01, 0x00)) < 0) return r; return 0; }
static int do_fileid(struct state *cur, int argc, char **argv) { struct file_info *fi; struct sc_file *df, *file = cur->file->file; struct sc_path temp, *path = &file->path; /* sc_format_path doesn't return an error indication * when it's unable to parse the path */ sc_format_path(argv[0], &temp); if (temp.len != 2) { parse_error(cur, "Invalid file ID length\n"); return 1; } /* Get the DF, if any */ if ((fi = cur->file->parent) && (df = fi->file)) { if (df->path.len == 0) { parse_error(cur, "No path/fileid set for parent DF\n"); return 1; } if (df->path.len + 2 > sizeof(df->path)) { parse_error(cur, "File path too long\n"); return 1; } *path = df->path; } memcpy(path->value + path->len, temp.value, 2); path->len += 2; file->id = (temp.value[0] << 8) | temp.value[1]; return 0; }
static int dump_ef(sc_card_t * card, const char *path, u8 * buf, size_t * buf_len) { int rv; sc_file_t *file = NULL; sc_path_t scpath; sc_format_path(path, &scpath); rv = sc_select_file(card, &scpath, &file); if (rv < 0) { if (file) sc_file_free(file); return rv; } if (file->size > *buf_len) { sc_file_free(file); return SC_ERROR_BUFFER_TOO_SMALL; } rv = sc_read_binary(card, 0, buf, file->size, 0); sc_file_free(file); if (rv < 0) return rv; *buf_len = rv; return SC_SUCCESS; }
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, unsigned int type) { sc_pkcs15_df_t *df; sc_file_t *file; int created = 0; while (1) { for (df = p15card->df_list; df; df = df->next) { if (df->type == type) { if (created) df->enumerated = 1; return df; } } assert(created == 0); file = sc_file_new(); if (!file) return NULL; sc_format_path("11001101", &file->path); sc_pkcs15_add_df(p15card, type, &file->path); sc_file_free(file); created++; } }
static void handle_change( sc_card_t *card, int pin1, int pin2, int do_change, u8 *newpin, int newlen) { sc_path_t p; sc_file_t *f; struct sc_apdu a; u8 ref; int i; printf("\n%s %s with %s: ", do_change ? "Changing" : "Unblocking", pinlist[pin1].label, pinlist[pin2].label); sc_format_path(pinlist[pin1].path,&p); if((i=sc_select_file(card,&p,&f))<0){ printf("\nCannot select %s, %s\n", pinlist[pin1].label, sc_strerror(i)); return; } ref=f->prop_attr[2] | (strlen(pinlist[pin1].path)>8 ? 0x80 : 0x00); if(do_change){ sc_format_apdu(card, &a, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref); a.data=newpin, a.lc=a.datalen=newlen; } else { sc_format_apdu(card, &a, SC_APDU_CASE_1, 0x2C, 0x03, ref); } if((i=sc_transmit_apdu(card, &a))<0){ printf("\nsc_transmit_apdu() failed, %s\n", sc_strerror(i)); return; } if(a.sw1!=0x90 && a.sw2!=0x00){ printf("%02X%02X\n", a.sw1, a.sw2); return; } printf("OK\n"); }
static void show_card(sc_card_t *card) { sc_path_t path; sc_file_t *file; u8 buf[100]; int i, len; sc_format_path("3F002F02",&path); if((i=sc_select_file(card,&path,&file))<0){ printf("\nCannot select Serial-Number 2F02, is this a NetKey-Card ??\n"); return; } if(file->type!=SC_FILE_TYPE_WORKING_EF || file->ef_structure!=SC_FILE_EF_TRANSPARENT || file->size!=12 || (len=sc_read_binary(card,0,buf,12,0))!=12 || buf[0]!=0x5A || buf[1]!=0x0A ){ printf("\nInvald Serial-Number: Type=%d, EF-Structure=%d, Size=%lu\n", file->type, file->ef_structure, (unsigned long) file->size ); return; } printf("\nSerial-Number: "); for(i=2;i<11;++i) printf("%02X", buf[i]); printf("%X\n\n", buf[11]>>4); for(i=0;i<4;++i) show_pin(card, i); // printf("%s: %u tries left, %u tries max, %s\n", pinlist[i].label, pinlist[i].tries, max, status); if(pinlist[0].len) show_initial_puk(card); }
static int list_files(void) { sc_path_t path; int r; sc_format_path("3F00", &path); r = enum_dir(path, 0); return r; }
static int insert_cert( sc_pkcs15_card_t *p15card, const char *path, unsigned char id, int writable, const char *label ){ sc_card_t *card=p15card->card; sc_context_t *ctx=p15card->card->ctx; struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; unsigned char cert[20]; int r; memset(&cert_info, 0, sizeof(cert_info)); cert_info.id.len = 1; cert_info.id.value[0] = id; cert_info.authority = 0; sc_format_path(path, &cert_info.path); memset(&cert_obj, 0, sizeof(cert_obj)); strlcpy(cert_obj.label, label, sizeof(cert_obj.label)); cert_obj.flags = writable ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0; if(sc_select_file(card, &cert_info.path, NULL)!=SC_SUCCESS){ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Select(%s) failed\n", path); return 1; } if(sc_read_binary(card, 0, cert, sizeof(cert), 0)<0){ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "ReadBinary(%s) failed\n", path); return 2; } if(cert[0]!=0x30 || cert[1]!=0x82){ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]); return 3; } /* some certificates are prefixed by an OID */ if(cert[4]==0x06 && cert[5]<10 && cert[6+cert[5]]==0x30 && cert[7+cert[5]]==0x82){ cert_info.path.index=6+cert[5]; cert_info.path.count=(cert[8+cert[5]]<<8) + cert[9+cert[5]] + 4; } else { cert_info.path.index=0; cert_info.path.count=(cert[2]<<8) + cert[3] + 4; } r=sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if(r!=SC_SUCCESS){ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "sc_pkcs15emu_add_x509_cert(%s) failed\n", path); return 4; } sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "%s: OK, Index=%d, Count=%d\n", path, cert_info.path.index, cert_info.path.count); return 0; }
static int do_cd(int argc, char **argv) { sc_path_t path; sc_file_t *file; int r; if (argc != 1) goto usage; if (strcmp(argv[0], "..") == 0) { path = current_path; if (path.len < 4) { printf("unable to go up, already in MF.\n"); return -1; } if (path.type == SC_PATH_TYPE_DF_NAME) { sc_format_path("3F00", &path); } else { path.len -= 2; } r = sc_select_file(card, &path, &file); if (r) { printf("unable to go up: %s\n", sc_strerror(r)); return -1; } if (current_file) sc_file_free(current_file); current_file = file; current_path = path; return 0; } if (arg_to_path(argv[0], &path, 0) != 0) goto usage; r = sc_select_file(card, &path, &file); if (r) { check_ret(r, SC_AC_OP_SELECT, "unable to select DF", current_file); return -1; } if ((file->type != SC_FILE_TYPE_DF) && (card->type != SC_CARD_TYPE_BELPIC_EID)) { printf("Error: file is not a DF.\n"); sc_file_free(file); select_current_path_or_die(); return -1; } current_path = path; if (current_file) sc_file_free(current_file); current_file = file; return 0; usage: puts("Usage: cd <file_id>|aid:<DF name>"); return -1; }
int select_esteid_df (sc_card_t * card) { int r; sc_path_t tmppath; sc_format_path ("3F00EEEE", &tmppath); r = sc_select_file (card, &tmppath, NULL); LOG_TEST_RET(card->ctx, r, "esteid select DF failed"); return r; }
/* Loads certificates. * Certificates are stored in a ZLib compressed form with * a 4 byte header, so we extract, decompress and cache * them. */ static int loadCertificate(sc_pkcs15_card_t * p15card, int i, const char *certPath, const char *certLabel) { unsigned char *compCert = NULL, *cert = NULL, size[2]; unsigned long int compLen, len; sc_pkcs15_cert_info_t cert_info; sc_pkcs15_object_t cert_obj; sc_path_t cpath; sc_card_t *card = p15card->card; sc_pkcs15_id_t id; int r; memset(&cert_info, 0, sizeof(cert_info)); memset(&cert_obj, 0, sizeof(cert_obj)); sc_format_path(certPath, &cpath); if (sc_select_file(card, &cpath, NULL) != SC_SUCCESS) return SC_ERROR_WRONG_CARD; sc_read_binary(card, 2, size, 2, 0); compLen = (size[0] << 8) + size[1]; compCert = (unsigned char *) malloc(compLen * sizeof(unsigned char)); len = 4 * compLen; /*Approximation of the uncompressed size */ cert = (unsigned char *) malloc(len * sizeof(unsigned char)); sc_read_binary(card, 4, compCert, compLen, 0); if ((r = uncompress(cert, &len, compCert, compLen)) != Z_OK) { sc_error(p15card->card->ctx, "Zlib error: %d", r); return SC_ERROR_INTERNAL; } cpath.index = 0; cpath.count = len; sc_pkcs15_cache_file(p15card, &cpath, cert, len); id.len=1; id.value[0] = i + 1; cert_info.id = id; cert_info.path = cpath; cert_info.authority = (i == 2); strlcpy(cert_obj.label, certLabel, sizeof(cert_obj.label)); cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); return SC_SUCCESS; }
int sc_pkcs15_detect(sc_card_t *card) { int r; sc_path_t path; sc_format_path("NA0000063504B43532D3135", &path); r = sc_select_file(card, &path, NULL); if (r != 0) return 0; return 1; }
static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15_object *obj, struct sc_pkcs15_der *content, struct sc_path *path) { sc_card_t *card = p15card->card; sc_file_t *file; sc_pkcs15_cert_info_t *cinfo; sc_pkcs15_id_t *cid; int r; LOG_FUNC_CALLED(card->ctx); switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) { case SC_PKCS15_TYPE_PRKEY: case SC_PKCS15_TYPE_PUBKEY: /* For these two type, store_data just don't need to do anything. * All have been done already before this function is called */ r = SC_SUCCESS; break; case SC_PKCS15_TYPE_CERT: cinfo = (sc_pkcs15_cert_info_t *) obj->data; cid = &(cinfo->id); if (cid->len != 1) { sc_log(card->ctx, "ID=%s is not valid.", sc_dump_hex(cid->value, cid->len)); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); } /* OpenPGP card v.2 contains only 1 certificate */ if (cid->value[0] != 3) { sc_log(card->ctx, "This version does not support certificate ID = %d (only ID=3 is supported).", cid->value[0]); LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } /* Just update the certificate DO */ sc_format_path("7F21", path); r = sc_select_file(card, path, &file); LOG_TEST_RET(card->ctx, r, "Cannot select cert file"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); if (r >= 0 && content->len) r = sc_update_binary(p15card->card, 0, (const unsigned char *) content->value, content->len, 0); break; default: r = SC_ERROR_NOT_IMPLEMENTED; } LOG_FUNC_RETURN(card->ctx, r); }
static int westcos_pkcs15init_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) { int r; struct sc_path path; sc_format_path("3F00", &path); r = sc_select_file(p15card->card, &path, NULL); if(r) return (r); return r; }
int sc_pkcs15_parse_unusedspace(const u8 * buf, size_t buflen, struct sc_pkcs15_card *card) { const u8 *p = buf; size_t left = buflen; int r; sc_path_t path, dummy_path; sc_pkcs15_id_t auth_id; struct sc_asn1_entry asn1_unusedspace[] = { { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; struct sc_asn1_entry asn1_unusedspace_values[] = { { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; /* Clean the list if already present */ while (card->unusedspace_list) sc_pkcs15_remove_unusedspace(card, card->unusedspace_list); sc_format_path("3F00", &dummy_path); dummy_path.index = dummy_path.count = 0; sc_format_asn1_entry(asn1_unusedspace, asn1_unusedspace_values, NULL, 1); sc_format_asn1_entry(asn1_unusedspace_values, &path, NULL, 1); sc_format_asn1_entry(asn1_unusedspace_values+1, &auth_id, NULL, 0); while (left > 0) { memset(&auth_id, 0, sizeof(auth_id)); r = sc_asn1_decode(card->card->ctx, asn1_unusedspace, p, left, &p, &left); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) break; if (r < 0) return r; /* If the path length is 0, it's a dummy path then don't add it. * If the path length isn't included (-1) then it's against the standard * but we'll just ignore it instead of returning an error. */ if (path.count > 0) { r = sc_pkcs15_make_absolute_path(&card->file_app->path, &path); if (r < 0) return r; r = sc_pkcs15_add_unusedspace(card, &path, &auth_id); if (r) return r; } } card->unusedspace_read = 1; return 0; }
static int do_info(sc_card_t *card, const struct ef_name_map *map) { int i; u8 buf[2048]; for (i = 0; map[i].ef != NULL; i++) { sc_path_t path; sc_file_t *file; size_t count; int r; sc_format_path(map[i].ef, &path); r = sc_select_file(card, &path, &file); if (r) { util_error("failed to select EF %s: %s", map[i].ef, sc_strerror(r)); return EXIT_FAILURE; } count = file->size; if (!count) continue; if (count > sizeof(buf) - 1) { util_error("too small buffer to read the OpenPGP map"); return EXIT_FAILURE; } r = sc_read_binary(card, 0, buf, count, 0); if (r < 0) { util_error("failed to read %s: %s", map[i].ef, sc_strerror(r)); return EXIT_FAILURE; } if (r != (signed) count || (size_t) r < map[i].offset + map[i].length) { util_error("%s: expecting %"SC_FORMAT_LEN_SIZE_T"d bytes, got only %d", map[i].ef, count, r); return EXIT_FAILURE; } if (map[i].offset > 0) { memmove(buf, buf + map[i].offset, map[i].length); count -= map[i].offset; } if (map[i].length > 0 && count > map[i].length) count = map[i].length; if (map[i].type == TYPE_STRING) buf[count] = '\0'; display_data(&map[i], buf, count); } return EXIT_SUCCESS; }
static int myeid_init_card(sc_profile_t *profile, sc_card_t *card) { struct sc_path path; sc_file_t *file; int r; SC_FUNC_CALLED(card->ctx, 1); sc_format_path("3F00", &path); r = sc_select_file(card, &path, NULL); SC_FUNC_RETURN(card->ctx, 1, r); }
static int jpki_set_security_env(sc_card_t * card, const sc_security_env_t * env, int se_num) { int rc; sc_path_t path; LOG_FUNC_CALLED(card->ctx); sc_log(card->ctx, "flags=%08lx op=%d alg=%d algf=%08x algr=%08x kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u", env->flags, env->operation, env->algorithm, env->algorithm_flags, env->algorithm_ref, env->key_ref[0], env->key_ref_len); switch (env->operation) { case SC_SEC_OPERATION_SIGN: break; default: LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } switch (env->key_ref[0]) { case 1: sc_format_path(JPKI_AUTH_KEY, &path); break; case 2: sc_format_path(JPKI_SIGN_KEY, &path); break; default: LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); } path.type = SC_PATH_TYPE_FILE_ID; rc = sc_select_file(card, &path, NULL); LOG_TEST_RET(card->ctx, rc, "select key failed"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); }
/* * This function pretty much follows what find_tlv in the GNUpg * code does. */ static int read_file(sc_card_t *card, const char *path_name, void *buf, size_t len) { sc_path_t path; sc_file_t *file; int r; sc_format_path(path_name, &path); if ((r = sc_select_file(card, &path, &file)) < 0) return r; if (file->size < len) len = file->size; return sc_read_binary(card, 0, (u8 *) buf, len, 0); }
static int muscle_erase_card(sc_profile_t *profile, sc_card_t *card) { int r; struct sc_file *file; struct sc_path path; memset(&file, 0, sizeof(file)); sc_format_path("3F00", &path); if ((r = sc_select_file(card, &path, &file)) < 0) return r; if ((r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_ERASE)) < 0) return r; if ((r = sc_delete_file(card, &path)) < 0) return r; return 0; }
/* * Try to delete pkcs15 structure * This is not quite the same as erasing the whole token, but * it's close enough to be useful. */ static int incrypto34_erase(struct sc_profile *profile, sc_pkcs15_card_t *p15card) { int r; struct sc_file *file; struct sc_path path; memset(&file, 0, sizeof(file)); sc_format_path("3F00", &path); if ((r = sc_select_file(p15card->card, &path, &file)) < 0) return r; if (sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_DELETE) < 0) return sc_pkcs15init_erase_card_recursively(p15card, profile); else return sc_card_ctl(p15card->card, SC_CARDCTL_INCRYPTO34_ERASE_FILES, NULL); }
int jpki_select_ap(struct sc_card *card) { int rc; sc_path_t path; LOG_FUNC_CALLED(card->ctx); /* Select JPKI application */ sc_format_path(AID_JPKI, &path); path.type = SC_PATH_TYPE_DF_NAME; rc = sc_select_file(card, &path, NULL); LOG_TEST_RET(card->ctx, rc, "select JPKI AP failed"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); }
static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *p15card) { sc_context_t *ctx = p15card->card->ctx; int i, r; LOG_FUNC_CALLED(ctx); /* Optional private use DOs 0101 to 0104 */ for (i = 1; i <= PGP_NUM_PRIVDO; i++) { sc_pkcs15_data_info_t dat_info; sc_pkcs15_object_t dat_obj; char name[8]; char path[9]; u8 content[254]; memset(&dat_info, 0, sizeof(dat_info)); memset(&dat_obj, 0, sizeof(dat_obj)); snprintf(name, 8, "PrivDO%d", i); snprintf(path, 9, "3F00010%d", i); /* Check if the DO can be read and is not empty. Otherwise we * won't expose a PKCS#15 DATA object. */ r = read_file(p15card->card, path, content, sizeof(content)); if (r <= 0 ) { sc_log(ctx, "Cannot read DO 010%d or there is no data in it", i); /* Skip */ continue; } sc_format_path(path, &dat_info.path); strlcpy(dat_obj.label, name, sizeof(dat_obj.label)); strlcpy(dat_info.app_label, name, sizeof(dat_info.app_label)); /* Add DATA object to slot protected by PIN2 (PW1 with Ref 0x82) */ dat_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE | SC_PKCS15_CO_FLAG_MODIFIABLE; dat_obj.auth_id.len = 1; if (i == 1 || i == 3) dat_obj.auth_id.value[0] = 2; else dat_obj.auth_id.value[0] = 3; sc_log(ctx, "Add %s data object", name); r = sc_pkcs15emu_add_data_object(p15card, &dat_obj, &dat_info); LOG_TEST_RET(ctx, r, "Could not add data object to framework"); } LOG_FUNC_RETURN(ctx, SC_SUCCESS); }
static int do_file_path(struct state *cur, int argc, char **argv) { struct sc_file *file = cur->file->file; struct sc_path *path = &file->path; /* sc_format_path doesn't return an error indication * when it's unable to parse the path */ sc_format_path(argv[0], path); if (!path->len || (path->len & 1)) { parse_error(cur, "Invalid path length\n"); return 1; } file->id = (path->value[path->len-2] << 8) | path->value[path->len-1]; return 0; }
static int mcrd_set_decipher_key_ref(sc_card_t * card, int key_reference) { sc_apdu_t apdu; sc_path_t path; int r; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 keyref_data[SC_ESTEID_KEYREF_FILE_RECLEN]; assert(card != NULL); sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0xB8); /* track the active keypair */ sc_format_path("0033", &path); r = sc_select_file(card, &path, NULL); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Can't select keyref info file 0x0033"); r = sc_read_record(card, 1, keyref_data, SC_ESTEID_KEYREF_FILE_RECLEN, SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Can't read keyref info file!"); sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "authkey reference 0x%02x%02x\n", keyref_data[9], keyref_data[10]); sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "signkey reference 0x%02x%02x\n", keyref_data[19], keyref_data[20]); sbuf[0] = 0x83; sbuf[1] = 0x03; sbuf[2] = 0x80; switch (key_reference) { case 1: sbuf[3] = keyref_data[9]; sbuf[4] = keyref_data[10]; break; case 2: sbuf[3] = keyref_data[19]; sbuf[4] = keyref_data[20]; break; } apdu.data = sbuf; apdu.lc = 5; apdu.datalen = 5; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2)); }
static void show_certs(sc_card_t *card) { sc_path_t p; sc_file_t *f; X509 *c; u8 buf[2000]; const u8 *q; int j; size_t i; printf("\n"); for(i=0;i<sizeof(certlist)/sizeof(certlist[0]);++i){ printf("Certificate %lu: %s", (unsigned long) i, certlist[i].label); fflush(stdout); sc_format_path(certlist[i].path,&p); if((j=sc_select_file(card,&p,&f))<0){ printf(", Cannot select Cert-file %s, is this a NetKey-Card ??\n", certlist[i].path ); continue; } if(f->type!=SC_FILE_TYPE_WORKING_EF || f->ef_structure!=SC_FILE_EF_TRANSPARENT){ printf(", Invald Cert-file: Type=%d, EF-Structure=%d\n", f->type, f->ef_structure); continue; } if((j=sc_read_binary(card,0,buf,f->size,0))<0){ printf(", Cannot read Cert-file, %s\n", sc_strerror(j)); continue; } printf(", Maxlen=%lu", (unsigned long) f->size); q=buf; if(q[0]==0x30 && q[1]==0x82){ if(q[4]==6 && q[5]<10 && q[q[5]+6]==0x30 && q[q[5]+7]==0x82) q+=q[5]+6; printf(", Len=%d\n", (q[2]<<8)|q[3]); if((c=d2i_X509(NULL,&q,f->size))){ char buf2[2000]; X509_NAME_get_text_by_NID(c->cert_info->subject, NID_commonName, buf2,sizeof(buf2)); printf(" Subject-CN: %s\n", buf2); X509_NAME_get_text_by_NID(c->cert_info->issuer, NID_commonName, buf2,sizeof(buf2)); printf(" Issuer-CN: %s\n", buf2); X509_free(c); } else printf(" Invalid Certificate-Data\n"); } else printf(", empty\n"); } }
static int do_userinfo(sc_card_t *card) { int i; /* FIXME there are no length checks on buf. */ unsigned char buf[2048]; for (i = 0; openpgp_data[i].ef != NULL; i++) { sc_path_t path; sc_file_t *file; size_t count; int r; sc_format_path(openpgp_data[i].ef, &path); r = sc_select_file(card, &path, &file); if (r) { fprintf(stderr, "Failed to select EF %s: %s\n", openpgp_data[i].ef, sc_strerror(r)); return EXIT_FAILURE; } count = file->size; if (!count) continue; if (count > sizeof(buf) - 1) { fprintf(stderr, "Too small buffer to read the OpenPGP data\n"); return EXIT_FAILURE; } r = sc_read_binary(card, 0, buf, count, 0); if (r < 0) { fprintf(stderr, "%s: read failed - %s\n", openpgp_data[i].ef, sc_strerror(r)); return EXIT_FAILURE; } if (r != (signed)count) { fprintf(stderr, "%s: expecting %"SC_FORMAT_LEN_SIZE_T"d, got only %d bytes\n", openpgp_data[i].ef, count, r); return EXIT_FAILURE; } buf[count] = '\0'; display_data(openpgp_data + i, (char *) buf); } return EXIT_SUCCESS; }
/* Select and read a transparent EF */ static int read_transp(sc_card_t *card, const char *pathstring, unsigned char *buf, int buflen) { sc_path_t path; int r; sc_format_path(pathstring, &path); r = sc_select_file(card, &path, NULL); if (r < 0) fprintf(stderr, "\nFailed to select file %s: %s\n", pathstring, sc_strerror(r)); else { r = sc_read_binary(card, 0, buf, buflen, 0); if (r < 0) fprintf(stderr, "\nFailed to read %s: %s\n", pathstring, sc_strerror(r)); } return r; }