static int rutoken_info(sc_card_t *card) { u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; sc_serial_number_t serial; int r; r = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_GET_INFO, rbuf); if (r) { fprintf(stderr, "Error: Get info failed: %s\n", sc_strerror(r)); return -1; } printf("Type: %d\n", rbuf[0]); printf("Version: %d.%d\n", rbuf[1]>>4, rbuf[1] & 0x0F); printf("Memory: %d Kb\n", rbuf[2]*8); printf("Protocol version: %d\n", rbuf[3]); printf("Software version: %d\n", rbuf[4]); printf("Order: %d\n", rbuf[5]); r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); if (r) { fprintf(stderr, "Error: Get serial failed: %s\n", sc_strerror(r)); return -1; } printf("Serial number: "); util_hex_dump(stdout, serial.value, serial.len, NULL); putchar('\n'); return 0; }
static int entersafe_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, sc_pkcs15_object_t *pin_obj, const unsigned char *pin, size_t pin_len, const unsigned char *puk, size_t puk_len) { struct sc_card *card = p15card->card; int r; sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; {/*pin*/ sc_entersafe_wkey_data data; if (!pin || !pin_len || pin_len > 16) return SC_ERROR_INVALID_ARGUMENTS; data.key_id = auth_info->attrs.pin.reference; data.usage=0x0B; data.key_data.symmetric.EC=0x33; data.key_data.symmetric.ver=0x00; /* pad pin with 0 */ memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val)); memcpy(data.key_data.symmetric.key_val, pin, pin_len); data.key_data.symmetric.key_len=16; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); /* Cache new PIN value. */ sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len); } {/*puk*/ sc_entersafe_wkey_data data; if (!puk || !puk_len || puk_len > 16) return SC_ERROR_INVALID_ARGUMENTS; data.key_id = auth_info->attrs.pin.reference+1; data.usage=0x0B; data.key_data.symmetric.EC=0x33; data.key_data.symmetric.ver=0x00; /* pad pin with 0 */ memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val)); memcpy(data.key_data.symmetric.key_val, puk, puk_len); data.key_data.symmetric.key_len=16; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); } SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r); }
/* * Create a new PIN */ static int setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df, sc_pkcs15_object_t *pin_obj, const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len) { struct sc_context *ctx = p15card->card->ctx; sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data; sc_file_t *pinfile = NULL; int r, ignore_ac = 0; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; /* Create the global pin file if it doesn't exist yet */ r = sc_profile_get_file(profile, "pinfile", &pinfile); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No 'pinfile' template in profile"); r = sc_select_file(p15card->card, &pinfile->path, &pinfile); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select 'pinfile'"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "pinfile->status:%X", pinfile->status); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create PIN with reference:%X, flags:%X, path:%s", auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, sc_print_path(&auth_info->path)); if (pinfile->status == SC_FILE_STATUS_CREATION) ignore_ac = 1; r = setcos_create_pin_internal(profile, p15card, ignore_ac, auth_info, pin, pin_len, puk, puk_len); /* If pinfile is in 'Creation' state and SOPIN has been created, * change status of MF and 'pinfile' to 'Operational:Activated' */ if (ignore_ac && (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)) { sc_file_t *mf = profile->mf_info->file; r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set 'pinfile' into the activated state"); r = sc_select_file(p15card->card, &mf->path, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF"); r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set MF into the activated state"); } sc_file_free(pinfile); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
static int list_sdos(char *sdo_tag) { struct iasecc_sdo sdo; struct iasecc_se_info se; unsigned sdo_class = 0; int rv, ii, jj; if (!sdo_tag) goto usage; if (*sdo_tag == 'x' || *sdo_tag == 'X') sdo_class = strtol(sdo_tag + 1, NULL, 16); else if ((strlen(sdo_tag) > 2) && (*(sdo_tag + 1) == 'x' || *(sdo_tag + 1) == 'X')) sdo_class = strtol(sdo_tag + 2, NULL, 16); else sdo_class = strtol(sdo_tag, NULL, 10); sdo_class &= 0x7F; if (sdo_class == IASECC_SDO_CLASS_SE) { for (ii=1; ii<0x20; ii++) { memset(&se, 0, sizeof(se)); se.reference = ii; rv = sc_card_ctl(card, SC_CARDCTL_GET_SE_INFO, &se); if (!rv) { printf("Found SE #%X\n", se.reference); _iasecc_print_docp(&se.docp); for(jj=0; jj<SC_MAX_CRTS_IN_SE && se.crts[jj].tag; jj++) _iasecc_print_crt(&se.crts[jj]); } } } else { for (ii=1; ii<0x20; ii++) { memset(&sdo, 0, sizeof(sdo)); sdo.sdo_class = sdo_class; sdo.sdo_ref = ii; rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_GET_DATA, &sdo); if (!rv) { printf("Found SDO class %X, reference %X\n", sdo.sdo_class, sdo.sdo_ref); _iasecc_print_docp(&sdo.docp); } } } return 0; usage: puts("Usage: list_sdos <SDO class>"); return -1; }
/* * Erase the card */ static int gpk_erase_card(struct sc_profile *pro, sc_pkcs15_card_t *p15card) { int locked; if (sc_card_ctl(p15card->card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0 && locked) { sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "This card is already personalized, unable to " "create PKCS#15 structure."); return SC_ERROR_NOT_SUPPORTED; } return sc_card_ctl(p15card->card, SC_CARDCTL_ERASE_CARD, NULL); }
int sc_pkcs15emu_tcos_init_ex( sc_pkcs15_card_t *p15card, sc_pkcs15emu_opt_t *opts ){ sc_card_t *card = p15card->card; sc_context_t *ctx = p15card->card->ctx; sc_serial_number_t serialnr; char serial[30]; int i, r; /* check if we have the correct card OS unless SC_PKCS15EMU_FLAGS_NO_CHECK */ i=(opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)); if (!i && card->type!=SC_CARD_TYPE_TCOS_V2 && card->type!=SC_CARD_TYPE_TCOS_V3) return SC_ERROR_WRONG_CARD; /* get the card serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr); if (r < 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unable to get ICCSN\n"); return SC_ERROR_WRONG_CARD; } sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0); serial[19] = '\0'; p15card->tokeninfo->serial_number = strdup(serial); if(!detect_netkey(p15card)) return SC_SUCCESS; if(!detect_idkey(p15card)) return SC_SUCCESS; if(!detect_unicard(p15card)) return SC_SUCCESS; if(!detect_signtrust(p15card)) return SC_SUCCESS; if(!detect_datev(p15card)) return SC_SUCCESS; return SC_ERROR_INTERNAL; }
static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key) { sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; sc_card_t *card = p15card->card; sc_entersafe_wkey_data data; sc_file_t *tfile; const sc_acl_entry_t *acl_entry; int r; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (key->algorithm != SC_ALGORITHM_RSA) /* ignore DSA keys */ SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS); r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile); if (r < 0) return r; acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE); if (acl_entry->method != SC_AC_NONE) { r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE); if(r<0) r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } sc_file_free(tfile); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin"); data.key_id = (u8) kinfo->key_reference; data.usage=0x22; data.key_data.rsa=&key->u.rsa; return sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data); }
/** * Stores an external (RSA) on the card. * @param profile profile information for this card * @param card sc_card_t object to use * @param obj sc_pkcs15_object_t object with pkcs15 information * @param key the private key * @return SC_SUCCESS on success and an error code otherwise **/ static int openpgp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key) { sc_card_t *card = p15card->card; sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; struct sc_pkcs15_prkey_rsa *rsa = &(key->u.rsa); sc_cardctl_openpgp_keystore_info_t key_info; int r; LOG_FUNC_CALLED(card->ctx); if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "only RSA is currently supported"); return SC_ERROR_NOT_SUPPORTED; } memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keystore_info_t)); key_info.keytype = kinfo->id.value[0]; key_info.e = rsa->exponent.data; key_info.e_len = rsa->exponent.len; key_info.p = rsa->p.data; key_info.p_len = rsa->p.len; key_info.q = rsa->q.data; key_info.q_len = rsa->q.len; key_info.n = rsa->modulus.data; key_info.n_len = rsa->modulus.len; r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_STORE_KEY, &key_info); LOG_FUNC_RETURN(card->ctx, r); }
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; }
static int rutoken_cipher(sc_card_t *card, u8 keyid, const u8 *in, size_t inlen, u8 *out, size_t outlen, int oper) { int r; struct sc_rutoken_decipherinfo inf = { in, inlen, out, outlen }; sc_security_env_t env; int cmd = (oper == OP_ENCRYPT) ? SC_CARDCTL_RUTOKEN_GOST_ENCIPHER : SC_CARDCTL_RUTOKEN_GOST_DECIPHER; memset(&env, 0, sizeof(env)); env.key_ref[0] = keyid; env.key_ref_len = 1; env.algorithm = SC_ALGORITHM_GOST; env.operation = SC_SEC_OPERATION_DECIPHER; /* set security env */ r = sc_set_security_env(card, &env, 0); if (r) { fprintf(stderr, "Error: Cipher failed (set security environment): %s\n", sc_strerror(r)); return -1; } /* cipher */ r = sc_card_ctl(card, cmd, &inf); if (r) { fprintf(stderr, "Error: Cipher failed: %s\n", sc_strerror(r)); return -1; } return 0; }
static int generate_gostkey(sc_card_t *card, u8 keyid, u8 keyoptions) { const sc_SecAttrV2_t gk_sec_attr = {0x44, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 2}; sc_DOHdrV2_t paramkey; int r; memset(¶mkey, 0, sizeof(paramkey)); paramkey.wDOBodyLen = SC_RUTOKEN_DEF_LEN_DO_GOST; paramkey.OTID.byObjectType = SC_RUTOKEN_TYPE_KEY; paramkey.OTID.byObjectID = keyid; paramkey.OP.byObjectOptions = keyoptions; /* assert(sizeof(*gk_sec_attr)); */ /* assert(sizeof(*paramkey.SA_V2)); */ /* assert(sizeof(paramkey.SA_V2) == sizeof(gk_sec_attr)); */ memcpy(paramkey.SA_V2, gk_sec_attr, sizeof(gk_sec_attr)); r = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_GENERATE_KEY_DO, ¶mkey); if (r) { fprintf(stderr, "Error: Generate GOST key failed: %s\n", sc_strerror(r)); return -1; } return 0; }
/* * Erase the card. */ static int myeid_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card) { struct sc_context *ctx = p15card->card->ctx; struct sc_cardctl_myeid_data_obj data_obj; struct sc_file *mf = NULL; unsigned char data[8]; int r; LOG_FUNC_CALLED(ctx); r = myeid_get_init_applet_data(profile, p15card, data, sizeof (data)); LOG_TEST_RET(ctx, r, "Get init applet date error"); /* Select parent DF and verify PINs/key as necessary */ r = sc_select_file(p15card->card, sc_get_mf_path(), &mf); LOG_TEST_RET(ctx, r, "Cannot select MF"); /* ACLs are not actives if file is not in the operational state */ if (mf->status == SC_FILE_STATUS_ACTIVATED) r = sc_pkcs15init_authenticate(profile, p15card, mf, SC_AC_OP_DELETE); LOG_TEST_RET(ctx, r, "'DELETE' authentication failed on MF"); data_obj.P1 = 0x01; data_obj.P2 = 0xE0; data_obj.Data = data; data_obj.DataLen = sizeof (data); r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); LOG_FUNC_RETURN(p15card->card->ctx, r); }
/* * On-board key generation. */ static int gpk_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) { struct sc_cardctl_gpk_genkey args; sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; unsigned int keybits; sc_file_t *keyfile; int r, n; sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "path=%s, %d bits\n", sc_print_path(&key_info->path), key_info->modulus_length); if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "GPK supports generating only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } /* The caller is supposed to have chosen a key file path for us */ if (key_info->path.len == 0 || key_info->modulus_length == 0) return SC_ERROR_INVALID_ARGUMENTS; keybits = key_info->modulus_length; if ((r = sc_select_file(p15card->card, &key_info->path, &keyfile)) < 0) return r; #ifndef PK_INIT_IMMEDIATELY r = gpk_pkfile_init_public(profile, p15card, keyfile, SC_ALGORITHM_RSA, keybits, key_info->usage); if (r < 0) { sc_file_free(keyfile); return r; } if ((r = gpk_pkfile_init_private(p15card->card, keyfile, 5 * ((3 + keybits / 16 + 7) & ~7UL))) < 0) { sc_file_free(keyfile); return r; } #endif sc_file_free(keyfile); memset(&args, 0, sizeof(args)); /*args.exponent = 0x10001;*/ n = key_info->path.len; args.fid = (key_info->path.value[n-2] << 8) | key_info->path.value[n-1]; args.privlen = keybits; r = sc_card_ctl(p15card->card, SC_CARDCTL_GPK_GENERATE_KEY, &args); if (r < 0) return r; /* This is fairly weird. The GENERATE RSA KEY command returns * immediately, but obviously it needs more time to complete. * This is why we sleep here. */ sleep(20); pubkey->algorithm = SC_ALGORITHM_RSA; return gpk_read_rsa_key(p15card->card, &pubkey->u.rsa); }
static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card) { int r; char buf[256]; sc_card_t *card = p15card->card; sc_serial_number_t serial; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); /* get serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; if (p15card->tokeninfo->serial_number) free(p15card->tokeninfo->serial_number); p15card->tokeninfo->serial_number = malloc(strlen(buf) + 1); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; strcpy(p15card->tokeninfo->serial_number, buf); /* the manufacturer ID, in this case Giesecke & Devrient GmbH */ if (p15card->tokeninfo->manufacturer_id) free(p15card->tokeninfo->manufacturer_id); p15card->tokeninfo->manufacturer_id = malloc(strlen(MANU_ID) + 1); if (!p15card->tokeninfo->manufacturer_id) return SC_ERROR_INTERNAL; strcpy(p15card->tokeninfo->manufacturer_id, MANU_ID); return SC_SUCCESS; }
/* * Create an empty security environment */ static int incrypto34_create_sec_env(struct sc_profile *profile, struct sc_card *card, unsigned int se_id, unsigned int key_id) { struct sc_cardctl_incrypto34_obj_info args; struct tlv tlv; unsigned char buffer[64]; tlv_init(&tlv, buffer, sizeof(buffer)); tlv_next(&tlv, 0x83); tlv_add(&tlv, se_id); tlv_next(&tlv, 0x86); tlv_add(&tlv, 0); tlv_add(&tlv, 0); tlv_next(&tlv, 0x8f); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); args.data = buffer; args.len = tlv_len(&tlv); return sc_card_ctl(card, SC_CARDCTL_INCRYPTO34_PUT_DATA_SECI, &args); }
/* * Create an empty security environment */ static int cardos_create_sec_env(struct sc_profile *profile, sc_card_t *card, unsigned int se_id, unsigned int key_id) { struct sc_cardctl_cardos_obj_info args; struct tlv tlv; unsigned char buffer[64]; int r; tlv_init(&tlv, buffer, sizeof(buffer)); tlv_next(&tlv, 0x83); tlv_add(&tlv, se_id); tlv_next(&tlv, 0x86); tlv_add(&tlv, 0); tlv_add(&tlv, 0); tlv_next(&tlv, 0x8f); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); tlv_add(&tlv, key_id); args.data = buffer; args.len = tlv_len(&tlv); /* ensure we are in the correct lifecycle */ r = sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_ADMIN); if (r < 0 && r != SC_ERROR_NOT_SUPPORTED) return r; return sc_card_ctl(card, SC_CARDCTL_CARDOS_PUT_DATA_SECI, &args); }
/* * Generate key */ static int cflex_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) { struct sc_cardctl_cryptoflex_genkey_info args; sc_card_t *card = p15card->card; sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; unsigned int keybits; unsigned char raw_pubkey[256]; sc_file_t *prkf = NULL, *pukf = NULL; int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Cryptoflex supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } /* Get the public and private key file */ r = cflex_get_keyfiles(profile, card, &key_info->path, &prkf, &pukf); if (r < 0) return r; if (! prkf) return SC_ERROR_NOT_SUPPORTED; /* Make sure we authenticate first */ r = sc_pkcs15init_authenticate(profile, p15card, prkf, SC_AC_OP_CRYPTO); if (r < 0) goto out; keybits = key_info->modulus_length; /* Perform key generation */ memset(&args, 0, sizeof(args)); args.exponent = 0x10001; args.key_bits = keybits; args.key_num = key_info->key_reference; r = sc_card_ctl(card, SC_CARDCTL_CRYPTOFLEX_GENERATE_KEY, &args); if (r < 0) goto out; /* extract public key */ pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = keybits / 8; pubkey->u.rsa.modulus.data = malloc(keybits / 8); pubkey->u.rsa.exponent.len = 3; pubkey->u.rsa.exponent.data = malloc(3); memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3); if ((r = sc_select_file(card, &pukf->path, NULL)) < 0 || (r = sc_read_binary(card, 3, raw_pubkey, keybits / 8, 0)) < 0) goto out; invert_buf(pubkey->u.rsa.modulus.data, raw_pubkey, pubkey->u.rsa.modulus.len); out: if (pukf) sc_file_free(pukf); if (prkf) sc_file_free(prkf); return r; }
/* * Store a private key */ static int myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, struct sc_pkcs15_prkey *prkey) { struct sc_context *ctx = p15card->card->ctx; struct sc_card *card = p15card->card; struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; struct sc_cardctl_myeid_gen_store_key_info args; struct sc_file *file = NULL; int r, keybits = key_info->modulus_length; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported"); /* Check that the card supports the requested modulus length */ if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store MyEID key with ID:%s and path:%s", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(card, &key_info->path, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store MyEID key: select key file failed"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store MyEID private key"); if (file) sc_file_free(file); /* Fill in data structure */ memset(&args, 0, sizeof(args)); args.mod_len = keybits; args.op_type = OP_TYPE_STORE; args.pubexp_len = prkey->u.rsa.exponent.len; args.pubexp = prkey->u.rsa.exponent.data; args.primep_len = prkey->u.rsa.p.len; args.primep = prkey->u.rsa.p.data; args.primeq_len = prkey->u.rsa.q.len; args.primeq = prkey->u.rsa.q.data; args.dp1_len = prkey->u.rsa.dmp1.len; args.dp1 = prkey->u.rsa.dmp1.data; args.dq1_len = prkey->u.rsa.dmq1.len; args.dq1 = prkey->u.rsa.dmq1.data; args.invq_len = prkey->u.rsa.iqmp.len; args.invq = prkey->u.rsa.iqmp.data; args.mod_len = prkey->u.rsa.modulus.len; args.mod = prkey->u.rsa.modulus.data; /* Store RSA key */ r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
/* * Create a new PIN */ static int myeid_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_file *df, struct sc_pkcs15_object *pin_obj, const unsigned char *pin, size_t pin_len, const unsigned char *puk, size_t puk_len) { struct sc_context *ctx = p15card->card->ctx; unsigned char data[20]; struct sc_cardctl_myeid_data_obj data_obj; struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; struct sc_pkcs15_auth_info puk_ainfo; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN('%s',ref:%i,flags:0x%X,pin_len:%d,puk_len:%d)\n", pin_obj->label, auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, pin_len, puk_len); if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_OBJECT_NOT_VALID; if (auth_info->attrs.pin.reference >= MYEID_MAX_PINS) return SC_ERROR_INVALID_ARGUMENTS; if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4) return SC_ERROR_INVALID_PIN_LENGTH; sc_profile_get_pin_info(profile, (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, &puk_ainfo); memset(data, 0, sizeof(data)); /* Make command to add a pin-record */ data_obj.P1 = 0x01; data_obj.P2 = auth_info->attrs.pin.reference; /* myeid pin number */ memset(data, auth_info->attrs.pin.pad_char, 8); memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin */ memset(&data[8], puk_ainfo.attrs.pin.pad_char, 8); memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */ if(auth_info->tries_left > 0 && auth_info->tries_left < 15) data[16] = auth_info->tries_left; else data[16] = 5; /* default value */ if(puk_ainfo.tries_left > 0 && puk_ainfo.tries_left < 15) data[17] = puk_ainfo.tries_left; else data[17] = 5; /* default value */ data[18] = 0x00; data_obj.Data = data; data_obj.DataLen = 19; r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Initialize PIN failed"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
static int entersafe_erase_card(struct sc_profile *profile, sc_pkcs15_card_t *p15card) { SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); if (sc_select_file(p15card->card, sc_get_mf_path(), NULL) < 0) return SC_SUCCESS; return sc_card_ctl(p15card->card,SC_CARDCTL_ERASE_CARD,0); }
/* * Lock a file operation */ static int gpk_lock(sc_card_t *card, sc_file_t *file, unsigned int op) { struct sc_cardctl_gpk_lock args; args.file = file; args.operation = op; return sc_card_ctl(card, SC_CARDCTL_GPK_LOCK, &args); }
/* * Create a new PIN */ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card, int ignore_ac, sc_pkcs15_pin_info_t *pin_info, const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len) { u8 data[20]; int so_pin_ref; int r,type, puk_tries; struct sc_cardctl_myeid_data_obj data_obj; sc_file_t *pinfile = NULL; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "pin (%d), pin_len (%d), puk_len(%d) \n", pin_info->reference, pin_len, puk_len); if (pin_info->reference >= MYEID_MAX_PINS) return SC_ERROR_INVALID_ARGUMENTS; if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4) return SC_ERROR_INVALID_PIN_LENGTH; if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) type = SC_PKCS15INIT_SO_PIN; else type = SC_PKCS15INIT_USER_PIN; sc_debug(card->ctx, "pin type (%s)\n", (type == SC_PKCS15INIT_SO_PIN) ? "SO_PIN": "USER_PIN"); memset(data, 0xFF, sizeof(data)); /* Make command to add a pin-record */ data_obj.P1 = 01; data_obj.P2 = pin_info->reference; /* myeid pin number */ memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin*/ memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */ data[16] = 0x00; data[17] = 0x00; data[18] = 0x00; data_obj.Data = data; data_obj.DataLen = 16; puk_tries = myeid_puk_retries(profile, pin_info); if(pin_info->tries_left > 0 && pin_info->tries_left < 15 && puk_tries > 0 && puk_tries < 15) { /* Optional PIN locking */ data[16] = (pin_info->tries_left & 0x0F); data[17] = (puk_tries & 0x0F); data_obj.DataLen = 19; } r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); SC_FUNC_RETURN(card->ctx, 1, r); }
/* * Store a private key object. */ static int muscle_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key) { struct sc_context *ctx = p15card->card->ctx; sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; sc_file_t* prkf; struct sc_pkcs15_prkey_rsa *rsa; sc_cardctl_muscle_key_info_t info; int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Muscle supports RSA keys only."); return SC_ERROR_NOT_SUPPORTED; } /* Verification stuff */ /* Used for verification AND for obtaining private key acls */ r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf); if(!prkf) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED); r = sc_pkcs15init_authenticate(profile, p15card, prkf, SC_AC_OP_CRYPTO); if (r < 0) { sc_file_free(prkf); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_NOT_SUPPORTED); } sc_file_free(prkf); r = muscle_select_key_reference(profile, p15card, key_info); if (r < 0) { SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,r); } rsa = &key->u.rsa; info.keySize = rsa->modulus.len << 3; info.keyType = 0x03; /* CRT type */ info.keyLocation = key_info->key_reference * 2; /* Mult by 2 to preserve even/odd keynumber structure */ info.pLength = rsa->p.len; info.pValue = rsa->p.data; info.qLength = rsa->q.len; info.qValue = rsa->q.data; info.pqLength = rsa->iqmp.len; info.pqValue = rsa->iqmp.data; info.dp1Length = rsa->dmp1.len; info.dp1Value = rsa->dmp1.data; info.dq1Length = rsa->dmq1.len; info.dq1Value = rsa->dmq1.data; r = sc_card_ctl(p15card->card, SC_CARDCTL_MUSCLE_IMPORT_KEY, &info); if (r < 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to import key"); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE,r); } return r; }
static int gpk_pkfile_init_private(sc_card_t *card, sc_file_t *file, unsigned int privlen) { struct sc_cardctl_gpk_pkinit args; args.file = file; args.privlen = privlen; return sc_card_ctl(card, SC_CARDCTL_GPK_PKINIT, &args); }
static int westcos_pkcs15init_finalize_card(sc_profile_t *profile, sc_card_t *card) { int r; /* be sure authentificate card */ r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL); if(r) return (r); return sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_USER); }
/* * Erase everything that's on the card */ static int rtecp_erase(sc_profile_t *profile, sc_pkcs15_card_t *p15card) { int r; if (!profile || !p15card || !p15card->card) return SC_ERROR_INVALID_ARGUMENTS; r = sc_card_ctl(p15card->card, SC_CARDCTL_RTECP_INIT, NULL); if (r == SC_SUCCESS) sc_free_apps(p15card->card); return r; }
/* pre secure channel creator initialization routine */ static int dnie_create_pre_ops(sc_card_t * card, cwa_provider_t * provider) { sc_serial_number_t serial; /* make sure that this cwa provider is used with a working DNIe card */ if (card->type != SC_CARD_TYPE_DNIE_USER) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD); /* ensure that Card Serial Number is properly cached */ return sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); }
static void print_serial(sc_card_t *in_card) { int r; sc_serial_number_t serial; r = sc_card_ctl(in_card, SC_CARDCTL_GET_SERIALNR, &serial); if (r) fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_GET_SERIALNR, *) failed\n"); else hex_dump_asc(stdout, serial.value, serial.len, -1); }
static int gpk_pkfile_load_private(sc_card_t *card, sc_file_t *file, u8 *data, unsigned int len, unsigned int datalen) { struct sc_cardctl_gpk_pkload args; args.file = file; args.data = data; args.len = len; args.datalen = datalen; return sc_card_ctl(card, SC_CARDCTL_GPK_PKLOAD, &args); }
static int entersafe_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) { int r; sc_entersafe_gen_key_data gendat; sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; sc_card_t *card = p15card->card; sc_file_t *tfile; const sc_acl_entry_t *acl_entry; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) return SC_ERROR_NOT_SUPPORTED; r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile); if (r < 0) return r; acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE); if (acl_entry->method != SC_AC_NONE) { r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE); if(r<0) r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } sc_file_free(tfile); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin"); /* generate key pair */ gendat.key_id = (u8) kinfo->key_reference; gendat.key_length = (size_t) kinfo->modulus_length; gendat.modulus = NULL; r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "EnterSafe generate RSA key pair failed"); /* get the modulus via READ PUBLIC KEY */ if (pubkey) { u8 *buf; struct sc_pkcs15_pubkey_rsa *rsa = &pubkey->u.rsa; /* set the modulus */ rsa->modulus.data = gendat.modulus; rsa->modulus.len = kinfo->modulus_length >> 3; /* set the exponent (always 0x10001) */ buf = malloc(3); if (!buf) return SC_ERROR_OUT_OF_MEMORY; buf[0] = 0x01; buf[1] = 0x00; buf[2] = 0x01; rsa->exponent.data = buf; rsa->exponent.len = 3; pubkey->algorithm = SC_ALGORITHM_RSA; } else