/* * Object deletion. */ static int cardos_delete_object(sc_profile_t *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, const struct sc_path *path) { int r = SC_SUCCESS, stored_in_ef = 0, algorithm = 0; size_t keybits; sc_file_t *file = NULL; struct sc_pkcs15_prkey_info *key_info; struct sc_pkcs15_prkey_rsa key_obj; struct sc_context *ctx = p15card->card->ctx; uint8_t abignum[256]; LOG_FUNC_CALLED(ctx); /* * If we are deleting a private key, overwrite it so it can't be used. */ if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) { key_info = obj->data; keybits = key_info->modulus_length & ~7UL; init_key_object(&key_obj, abignum, keybits >> 3); r = cardos_key_algorithm(key_info->usage, keybits, &algorithm); LOG_TEST_RET(ctx, r, "cardos_key_algorithm failed"); r = sc_select_file(p15card->card, &key_info->path, &file); LOG_TEST_RET(ctx, r, "Failed to store key: cannot select parent DF"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); sc_file_free(file); LOG_TEST_RET(ctx, r, "Failed to store key: UPDATE authentication failed"); r = cardos_put_key(profile, p15card, algorithm, key_info, &key_obj); LOG_TEST_RET(ctx, r, "cardos_put_key failed"); }
static int cflex_delete_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) { sc_path_t path; sc_file_t *parent; int r = 0; /* Select the parent DF */ path = df->path; path.len -= 2; r = sc_select_file(p15card->card, &path, &parent); if (r < 0) return r; r = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_DELETE); sc_file_free(parent); if (r < 0) return r; /* cryptoflex has no ERASE AC */ memset(&path, 0, sizeof(path)); path.type = SC_PATH_TYPE_FILE_ID; path.value[0] = df->id >> 8; path.value[1] = df->id & 0xFF; path.len = 2; r = sc_delete_file(p15card->card, &path); return r; }
/* * Lock the pin file */ static int gpk_lock_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card, sc_file_t *pinfile) { struct sc_path path; struct sc_file *parent = NULL; int r; SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); /* 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(p15card->card, &path, &parent)) < 0) return r; /* Present PINs etc as necessary */ r = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_LOCK); if (r >= 0) r = gpk_lock(p15card->card, pinfile, SC_AC_OP_WRITE); sc_file_free(parent); SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r); }
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); }
/* * Store a private key */ static int miocos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, struct sc_pkcs15_prkey *key) { struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; struct sc_pkcs15_prkey_rsa *rsa; struct sc_file *file = NULL; int r; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); rsa = &key->u.rsa; if (rsa->modulus.len != 128) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys."); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(p15card->card, &key_info->path, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store 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 private key"); r = miocos_update_private_key(profile, p15card->card, rsa); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
/* * Create the PK file * XXX: Handle the UPDATE ACL = NEVER case just like for EFsc files */ static int gpk_pkfile_create(sc_profile_t *profile, sc_card_t *card, sc_file_t *file) { struct sc_file *found = NULL; int r; sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &file->path, &found); sc_ctx_suppress_errors_off(card->ctx); if (r == SC_ERROR_FILE_NOT_FOUND) { r = sc_pkcs15init_create_file(profile, card, file); if (r >= 0) r = sc_select_file(card, &file->path, &found); } else { /* XXX: make sure the file has correct type and size? */ } if (r >= 0) r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_UPDATE); if (found) sc_file_free(found); return r; }
static int muscle_create_pin(sc_profile_t *profile, sc_card_t *card, 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) { sc_file_t *file; sc_pkcs15_pin_info_t *pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data; int r; int type; if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { type = SC_PKCS15INIT_SO_PIN; } else { type = SC_PKCS15INIT_USER_PIN; } if ((r = sc_select_file(card, &df->path, &file)) < 0) return r; if ((r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_WRITE)) < 0) return r; sc_keycache_set_pin_name(&df->path, pin_info->reference, type); pin_info->flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; return 0; }
/* * 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; }
/* * 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); }
/* * 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; }
/* * 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); }
/* * 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 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
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 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; struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)obj->data; size_t keybits = key_info->modulus_length; 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); } /* Disable RSA:512bits */ if ( ( keybits < 1024 ) || ( keybits > 2048 ) || ( keybits % 0x20 ) ) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n", keybits); return 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); }
/* * Erase the card. */ static int myeid_erase_card(sc_profile_t *profile, sc_card_t *card) { struct sc_cardctl_myeid_data_obj data_obj; sc_pkcs15_pin_info_t sopin_info, pin_info; u8 data[8]; int r; SC_FUNC_CALLED(card->ctx, 1); /* The SO pin has pin reference 1 -- not that it matters much * because pkcs15-init will ask to enter all pins, even if we * did a --so-pin on the command line. */ sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin_info); /* Select parent DF and verify PINs/key as necessary */ r = sc_pkcs15init_authenticate(profile, card, profile->mf_info->file, SC_AC_OP_DELETE); if (r < 0) return r == SC_ERROR_FILE_NOT_FOUND ? 0 : r; data[0]= 0xFF; data[1]= 0xFF; data[2]= 0x11; data[3]= 0x3F; data[4]= 0xFF; data[5]= 0x11; data[6]= 0xFF; data[7]= 0xFF; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &pin_info); if(pin_info.reference > 0 && pin_info.reference <= MYEID_MAX_PINS && sopin_info.reference > 0 && sopin_info.reference <= MYEID_MAX_PINS) { data[2] = (pin_info.reference << 4)| pin_info.reference; data[3] = (sopin_info.reference << 4) | 0x0F; data[5] = data[2]; } data_obj.P1 = 0x01; data_obj.P2 = 0xE0; data_obj.Data = data; data_obj.DataLen = 0x08; sc_debug(card->ctx, "so_pin(%d), user pin (%d)\n", sopin_info.reference, pin_info.reference); r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); SC_FUNC_RETURN(card->ctx, 1, r); }
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); }
/* * Store a private key */ static int setcos_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_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data; struct sc_cardctl_setcos_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"); /* Parameter check */ if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7)) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path)); r = sc_select_file(p15card->card, &key_info->path, &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store 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 private key"); /* 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 * 8; args.pubexp = prkey->u.rsa.exponent.data; args.primep_len = prkey->u.rsa.p.len * 8; args.primep = prkey->u.rsa.p.data; args.primeq_len = prkey->u.rsa.q.len * 8; args.primeq = prkey->u.rsa.q.data; /* Generate/store rsa key */ r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GENERATE_STORE_KEY, &args); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'GENERATE_STORE_KEY' failed"); if (file) sc_file_free(file); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
static int muscle_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) { sc_file_t *file; sc_pkcs15_pin_info_t *pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data; int r; if ((r = sc_select_file(p15card->card, &df->path, &file)) < 0) return r; if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_WRITE)) < 0) return r; pin_info->flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; return 0; }
/* * Erase the card. */ static int setcos_erase_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) { sc_path_t path; int r; /* Just delete the entire MF */ /* Select parent DF and verify PINs/key as necessary */ r = sc_pkcs15init_authenticate(profile, p15card, profile->mf_info->file, SC_AC_OP_DELETE); if (r < 0) return r == SC_ERROR_FILE_NOT_FOUND ? 0 : r; /* Empty path -> we have to to delete the current DF (= the MF) */ memset(&path, 0, sizeof(sc_path_t)); r = sc_delete_file(p15card->card, &path) ; if (r) return r; sc_free_apps(p15card->card); return 0; }
static int muscle_create_dir(sc_profile_t *profile, sc_card_t *card, 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(card, &path, &file)) < 0) return r; if ((r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_CREATE)) < 0) return r; /* Create the application DF */ if ((r = sc_pkcs15init_create_file(profile, card, df)) < 0) return r; if ((r = sc_select_file(card, &df->path, NULL)) < 0) return r; return 0; }
/* * Store a private key object. */ static int cardos_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; struct sc_file *file = NULL; int algorithm = 0, r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "CardOS supports RSA keys only."); return SC_ERROR_NOT_SUPPORTED; } if (cardos_key_algorithm(key_info->usage, key_info->modulus_length, &algorithm) < 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "CardOS does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } r = sc_select_file(p15card->card, &key_info->path, &file); if (r) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to store key: cannot select parent DF"); return r; } r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); sc_file_free(file); if (r) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to store key: 'UPDATE' authentication failed"); return r; } r = cardos_put_key(profile, p15card, algorithm, key_info, &key->u.rsa); return r; }
static int myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, struct sc_pkcs15_pubkey *pubkey) { 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; size_t keybits = key_info->modulus_length; unsigned char raw_pubkey[256]; LOG_FUNC_CALLED(ctx); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA && object->type != SC_PKCS15_TYPE_PRKEY_EC) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: only RSA and EC supported"); /* Check that the card supports the requested modulus length */ switch (object->type) { case SC_PKCS15_TYPE_PRKEY_RSA: if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported RSA key size"); break; case SC_PKCS15_TYPE_PRKEY_EC: /* EC is supported in MyEID v > 3.5. TODO: set correct return value if older MyEID version. */ /* Here the information about curve is not available, that's why supported algorithm is checked without curve OID. */ if (sc_card_find_ec_alg(p15card->card, keybits, NULL) == NULL) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported EC key size"); if(key_info->field_length != 0) keybits = key_info->field_length; else key_info->field_length = keybits; break; default: LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key type"); break; } sc_log(ctx, "Generate 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); LOG_TEST_RET(ctx, r, "Cannot generate key: failed to select key file"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_GENERATE); LOG_TEST_RET(ctx, r, "No authorisation to generate private key"); /* Fill in data structure */ memset(&args, 0, sizeof (args)); args.key_len_bits = keybits; args.op_type = OP_TYPE_GENERATE; if (object->type == SC_PKCS15_TYPE_PRKEY_RSA) { args.key_type = SC_CARDCTL_MYEID_KEY_RSA; args.pubexp_len = MYEID_DEFAULT_PUBKEY_LEN; args.pubexp = MYEID_DEFAULT_PUBKEY; } else if (object->type == SC_PKCS15_TYPE_PRKEY_EC) { args.key_type = SC_CARDCTL_MYEID_KEY_EC; } /* Generate RSA key */ r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args); LOG_TEST_RET(ctx, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed"); /* Keypair generation -> collect public key info */ if (pubkey != NULL) { struct sc_cardctl_myeid_data_obj data_obj; if (object->type == SC_PKCS15_TYPE_PRKEY_RSA) { pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = (keybits + 7) / 8; pubkey->u.rsa.modulus.data = malloc(pubkey->u.rsa.modulus.len); pubkey->u.rsa.exponent.len = MYEID_DEFAULT_PUBKEY_LEN; pubkey->u.rsa.exponent.data = malloc(MYEID_DEFAULT_PUBKEY_LEN); memcpy(pubkey->u.rsa.exponent.data, MYEID_DEFAULT_PUBKEY, MYEID_DEFAULT_PUBKEY_LEN); /* Get public key modulus */ r = sc_select_file(card, &file->path, NULL); LOG_TEST_RET(ctx, r, "Cannot get key modulus: select key file failed"); data_obj.P1 = 0x01; data_obj.P2 = 0x01; data_obj.Data = raw_pubkey; data_obj.DataLen = sizeof (raw_pubkey); r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj); LOG_TEST_RET(ctx, r, "Cannot get RSA key modulus: 'MYEID_GETDATA' failed"); if ((data_obj.DataLen * 8) != key_info->modulus_length) LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Cannot get RSA key modulus: invalid key-size"); memcpy(pubkey->u.rsa.modulus.data, raw_pubkey, pubkey->u.rsa.modulus.len); } else if (object->type == SC_PKCS15_TYPE_PRKEY_EC) { struct sc_ec_parameters *ecparams = (struct sc_ec_parameters *)key_info->params.data; sc_log(ctx, "curve '%s', len %i, oid '%s'", ecparams->named_curve, ecparams->field_length, sc_dump_oid(&(ecparams->id))); pubkey->algorithm = SC_ALGORITHM_EC; r = sc_select_file(card, &file->path, NULL); LOG_TEST_RET(ctx, r, "Cannot get public key: select key file failed"); data_obj.P1 = 0x01; data_obj.P2 = 0x86; /* Get public EC key (Q) */ data_obj.Data = raw_pubkey; data_obj.DataLen = sizeof (raw_pubkey); r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj); LOG_TEST_RET(ctx, r, "Cannot get EC public key: 'MYEID_GETDATA' failed"); if (pubkey->u.ec.ecpointQ.value) free(pubkey->u.ec.ecpointQ.value); pubkey->u.ec.ecpointQ.value = malloc(data_obj.DataLen - 2); if (pubkey->u.ec.ecpointQ.value == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(pubkey->u.ec.ecpointQ.value, data_obj.Data + 2, data_obj.DataLen - 2); pubkey->u.ec.ecpointQ.len = data_obj.DataLen - 2; if (pubkey->u.ec.params.named_curve) free(pubkey->u.ec.params.named_curve); pubkey->u.ec.params.named_curve = NULL; if (pubkey->u.ec.params.der.value) free(pubkey->u.ec.params.der.value); pubkey->u.ec.params.der.value = NULL; pubkey->u.ec.params.der.len = 0; pubkey->u.ec.params.named_curve = strdup(ecparams->named_curve); if (!pubkey->u.ec.params.named_curve) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params); LOG_TEST_RET(ctx, r, "Cannot fix EC parameters"); } } if (file) sc_file_free(file); LOG_FUNC_RETURN(ctx, r); }
/* * Create an empty key object */ static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_pkcs15_object_t *obj) { sc_context_t *ctx; /* RSA_PRkey/ Adds Miller- * RSA_PUBkey Rabin tests Attempts Reserve */ const unsigned char prkey_prop[] = { 0x23, 0, 0, 0xAA, 0, 0 }; const unsigned char pbkey_prop[] = { 0x33, 0, 0, 0xAA, 0, 0 }; /* GOSTR3410_PRkey/ * GOSTR3410_PUBkey paramset Attempts Reserve */ unsigned char prgkey_prop[] = { 0x03, '?', 0, 0xAA, 0, 0 }; unsigned char pbgkey_prop[] = { 0x13, '?', 0, 0xAA, 0, 0 }; /* AccessMode - Update Use - - - Delete */ unsigned char prkey_sec[15] = { 0x46, 0, '?', '?', 0, 0, 0, '?' }; unsigned char pbkey_sec[15] = { 0x46, 0, '?', 0, 0, 0, 0, '?' }; unsigned char auth_id, paramset; sc_pkcs15_prkey_info_t *key_info; sc_file_t *file; int r; if (!profile || !p15card || !p15card->card || !p15card->card->ctx || !obj || !obj->data) return SC_ERROR_INVALID_ARGUMENTS; ctx = p15card->card->ctx; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA && obj->type != SC_PKCS15_TYPE_PRKEY_GOSTR3410) return SC_ERROR_NOT_SUPPORTED; if (obj->auth_id.len != 1) return SC_ERROR_INVALID_ARGUMENTS; auth_id = obj->auth_id.value[0]; key_info = (sc_pkcs15_prkey_info_t *)obj->data; assert(key_info); if ((obj->type == SC_PKCS15_TYPE_PRKEY_RSA && key_info->modulus_length % 128 != 0) || (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410 && key_info->modulus_length != SC_PKCS15_GOSTR3410_KEYSIZE)) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key size %u\n", key_info->modulus_length); return SC_ERROR_INVALID_ARGUMENTS; } if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) { if (key_info->params.len < sizeof(int)) return SC_ERROR_INVALID_ARGUMENTS; if (((int*)key_info->params.data)[0] < 1 || ((int*)key_info->params.data)[0] > 3) return SC_ERROR_INVALID_ARGUMENTS; paramset = ((unsigned int*)key_info->params.data)[0] & 0x03; assert(sizeof(prgkey_prop)/sizeof(prgkey_prop[0]) > 1); assert(sizeof(pbgkey_prop)/sizeof(pbgkey_prop[0]) > 1); prgkey_prop[1] = 0x10 + (paramset << 4); pbgkey_prop[1] = prgkey_prop[1]; } r = sc_profile_get_file(profile, "PKCS15-AppDF", &file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Get PKCS15-AppDF info failed"); r = sc_file_add_acl_entry(file, SC_AC_OP_CREATE, SC_AC_CHV, auth_id); if (r == SC_SUCCESS) r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_CREATE); assert(file); sc_file_free(file); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Authenticate failed"); file = sc_file_new(); if (!file) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); file->id = key_info->key_reference; r = sc_file_set_type_attr(file, (const u8*)"\x10\x00", 2); /* private key file */ if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) file->size = key_info->modulus_length / 8 / 2 * 5 + 8; else file->size = key_info->modulus_length / 8; if (r == SC_SUCCESS) { assert(sizeof(prkey_sec)/sizeof(prkey_sec[0]) > 7); prkey_sec[2] = auth_id; prkey_sec[3] = auth_id; prkey_sec[7] = auth_id; r = sc_file_set_sec_attr(file, prkey_sec, sizeof(prkey_sec)); } if (r == SC_SUCCESS) { if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) r = sc_file_set_prop_attr(file, prkey_prop, sizeof(prkey_prop)); else r = sc_file_set_prop_attr(file, prgkey_prop,sizeof(prgkey_prop)); } if (r == SC_SUCCESS) { sc_log(ctx, "create private key file id:%04i", file->id); r = sc_create_file(p15card->card, file); } /* public key file */ if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) file->size = key_info->modulus_length / 8 / 2 * 3; else file->size = key_info->modulus_length / 8 * 2; if (r == SC_SUCCESS) { assert(sizeof(pbkey_sec)/sizeof(pbkey_sec[0]) > 7); pbkey_sec[2] = auth_id; pbkey_sec[7] = auth_id; r = sc_file_set_sec_attr(file, pbkey_sec, sizeof(pbkey_sec)); } if (r == SC_SUCCESS) { if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) r = sc_file_set_prop_attr(file, pbkey_prop, sizeof(pbkey_prop)); else r = sc_file_set_prop_attr(file, pbgkey_prop,sizeof(pbgkey_prop)); } if (r == SC_SUCCESS) { sc_log(ctx, "create public key file id:%04i", file->id); r = sc_create_file(p15card->card, file); } assert(file); sc_file_free(file); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r); }
static int myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, struct sc_pkcs15_pubkey *pubkey) { 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; size_t keybits = key_info->modulus_length; unsigned char raw_pubkey[256]; LOG_FUNC_CALLED(ctx); if (object->type != SC_PKCS15_TYPE_PRKEY_RSA && object->type != SC_PKCS15_TYPE_PRKEY_EC) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: only RSA and EC supported"); /* Check that the card supports the requested modulus length */ switch (object->type) { case SC_PKCS15_TYPE_PRKEY_RSA: if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported RSA key size"); break; case SC_PKCS15_TYPE_PRKEY_EC: LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "20140202: waiting for cards and specification from Aventra. VTA"); break; default: LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key type"); break; } sc_log(ctx, "Generate 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); LOG_TEST_RET(ctx, r, "Cannot generate key: failed to select key file"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_GENERATE); LOG_TEST_RET(ctx, r, "No authorisation to generate private key"); /* Fill in data structure */ memset(&args, 0, sizeof (args)); args.key_len_bits = keybits; args.op_type = OP_TYPE_GENERATE; if (object->type == SC_PKCS15_TYPE_PRKEY_RSA) { args.key_type = SC_CARDCTL_MYEID_KEY_RSA; args.pubexp_len = MYEID_DEFAULT_PUBKEY_LEN; args.pubexp = MYEID_DEFAULT_PUBKEY; } else if (object->type == SC_PKCS15_TYPE_PRKEY_EC) { args.key_type = SC_CARDCTL_MYEID_KEY_EC; } /* Generate RSA key */ r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args); LOG_TEST_RET(ctx, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed"); /* Keypair generation -> collect public key info */ if (pubkey != NULL) { struct sc_cardctl_myeid_data_obj data_obj; if (object->type == SC_PKCS15_TYPE_PRKEY_RSA) { pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = (keybits + 7) / 8; pubkey->u.rsa.modulus.data = malloc(pubkey->u.rsa.modulus.len); pubkey->u.rsa.exponent.len = MYEID_DEFAULT_PUBKEY_LEN; pubkey->u.rsa.exponent.data = malloc(MYEID_DEFAULT_PUBKEY_LEN); memcpy(pubkey->u.rsa.exponent.data, MYEID_DEFAULT_PUBKEY, MYEID_DEFAULT_PUBKEY_LEN); /* Get public key modulus */ r = sc_select_file(card, &file->path, NULL); LOG_TEST_RET(ctx, r, "Cannot get key modulus: select key file failed"); data_obj.P1 = 0x01; data_obj.P2 = 0x01; data_obj.Data = raw_pubkey; data_obj.DataLen = sizeof (raw_pubkey); r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj); LOG_TEST_RET(ctx, r, "Cannot get RSA key modulus: 'MYEID_GETDATA' failed"); if ((data_obj.DataLen * 8) != key_info->modulus_length) LOG_TEST_RET(ctx, SC_ERROR_PKCS15INIT, "Cannot get RSA key modulus: invalid key-size"); memcpy(pubkey->u.rsa.modulus.data, raw_pubkey, pubkey->u.rsa.modulus.len); } else if (object->type == SC_PKCS15_TYPE_PRKEY_EC) { pubkey->algorithm = SC_ALGORITHM_EC; r = sc_select_file(card, &file->path, NULL); LOG_TEST_RET(ctx, r, "Cannot get public key: select key file failed"); data_obj.P1 = 0x01; data_obj.P2 = 0x86; /* Get public EC key (Q) */ data_obj.Data = raw_pubkey; data_obj.DataLen = sizeof (raw_pubkey); r = sc_card_ctl(card, SC_CARDCTL_MYEID_GETDATA, &data_obj); LOG_TEST_RET(ctx, r, "Cannot get EC public key: 'MYEID_GETDATA' failed"); /* * TODO DEE - this looks like a bug... * pubkey->u.ec.ecpointQ.value is just value. "04||X||Y" * pubkey->data.value should be DER OCTET STRING * but * pubkey->data.value looks like TLV with TAG if 0x86 * and single byte length. * Could call sc_pkcs15_encode_pubkey * to set pubkey->data.value */ pubkey->u.ec.ecpointQ.value = malloc(data_obj.DataLen - 2); pubkey->u.ec.ecpointQ.len = data_obj.DataLen - 2; //pubkey->data.value = malloc(data_obj.DataLen); //pubkey->data.len = data_obj.DataLen; pubkey->u.ec.params.field_length = keybits; /* Omit the first 2 bytes (0x86??) */ memcpy(pubkey->u.ec.ecpointQ.value, data_obj.Data + 2, data_obj.DataLen - 2); //memcpy(pubkey->data.value, data_obj.Data, data_obj.DataLen); } } if (file) sc_file_free(file); LOG_FUNC_RETURN(ctx, 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; LOG_FUNC_CALLED(ctx); switch (object->type) { case SC_PKCS15_TYPE_PRKEY_RSA: if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported RSA key size"); break; case SC_PKCS15_TYPE_PRKEY_EC: LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "20140202: waiting for cards and specification from Aventra. VTA"); break; default: LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Store key failed: Unsupported key type"); break; } sc_log(ctx, "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); LOG_TEST_RET(ctx, r, "Cannot store MyEID key: select key file failed"); r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE); LOG_TEST_RET(ctx, r, "No authorisation to store MyEID private key"); if (file) sc_file_free(file); /* Fill in data structure */ memset(&args, 0, sizeof (args)); args.op_type = OP_TYPE_STORE; if(object->type == SC_PKCS15_TYPE_PRKEY_RSA) { //args.key_len_bits = keybits; args.key_type = SC_CARDCTL_MYEID_KEY_RSA; 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.key_len_bits = prkey->u.rsa.modulus.len; args.mod = prkey->u.rsa.modulus.data; } else { args.key_type = SC_CARDCTL_MYEID_KEY_EC; args.d = prkey->u.ec.privateD.data; args.d_len = prkey->u.ec.privateD.len; args.ecpublic_point = prkey->u.ec.ecpointQ.value; args.ecpublic_point_len = prkey->u.ec.ecpointQ.len; args.key_len_bits = prkey->u.ec.params.field_length; } /* Store RSA key */ r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args); LOG_TEST_RET(ctx, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed"); LOG_FUNC_RETURN(ctx, r); }
static int muscle_generate_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) { sc_cardctl_muscle_gen_key_info_t args; sc_cardctl_muscle_key_info_t extArgs; sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; sc_file_t* prkf; unsigned int keybits; int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_error(card->ctx, "Muscle supports only RSA keys (for now)."); SC_FUNC_RETURN(card->ctx, 2,SC_ERROR_NOT_SUPPORTED); } keybits = key_info->modulus_length & ~7UL; if (keybits > 2048) { sc_error(card->ctx, "Unable to generate key, max size is %d", 2048); SC_FUNC_RETURN(card->ctx, 2,SC_ERROR_INVALID_ARGUMENTS); } /* 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(card->ctx, 2,SC_ERROR_NOT_SUPPORTED); r = sc_pkcs15init_authenticate(profile, card, prkf, SC_AC_OP_CRYPTO); if (r < 0) { sc_file_free(prkf); SC_FUNC_RETURN(card->ctx, 2,SC_ERROR_NOT_SUPPORTED); } sc_file_free(prkf); /* END VERIFICATION STUFF */ /* Public key acls... get_file_by_path as well? */ memset(&args, 0, sizeof(args)); args.keyType = 0x01; // RSA forced args.privateKeyLocation = key_info->key_reference * 2; args.publicKeyLocation = key_info->key_reference * 2 + 1; args.keySize = keybits; r = sc_card_ctl(card, SC_CARDCTL_MUSCLE_GENERATE_KEY, &args); if (r < 0) { sc_error(card->ctx, "Unable to generate key"); SC_FUNC_RETURN(card->ctx, 2,r); } memset(&extArgs, 0, sizeof(extArgs)); memset(pubkey, 0, sizeof(*pubkey)); extArgs.keyType = 0x01; extArgs.keyLocation = args.publicKeyLocation; r = sc_card_ctl(card, SC_CARDCTL_MUSCLE_EXTRACT_KEY, &extArgs); if (r < 0) { sc_error(card->ctx, "Unable to extract the public key"); SC_FUNC_RETURN(card->ctx, 2,r); } pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = extArgs.modLength; pubkey->u.rsa.modulus.data = extArgs.modValue; pubkey->u.rsa.exponent.len = extArgs.expLength; pubkey->u.rsa.exponent.data = extArgs.expValue; if (r < 0) { if (pubkey->u.rsa.modulus.data) free (pubkey->u.rsa.modulus.data); if (pubkey->u.rsa.exponent.data) free (pubkey->u.rsa.exponent.data); } return r; }
/* * Common code for generating or storing a private key. * If pubkey == NULL and prkey != NULL, we have to store a private key * In the oposite case, we have to generate a private key */ static int myeid_generate_store_key(sc_profile_t *profile, sc_card_t *card, unsigned int index, /* keynumber: 0 for 1st priv key, ... */ unsigned int keybits, sc_pkcs15_pubkey_t *pubkey, sc_pkcs15_prkey_t *prkey, sc_pkcs15_prkey_info_t *info) { struct sc_cardctl_myeid_gen_store_key_info args; struct sc_cardctl_myeid_data_obj data_obj; unsigned char raw_pubkey[256]; int r; unsigned int mod_len; sc_file_t *prkf = NULL; SC_FUNC_CALLED(card->ctx, 1); /* Parameter check */ if ( (keybits < 1024) || (keybits > 2048) || (keybits & 0X7)) { sc_error(card->ctx, "Unsupported key size [%u]: 1024-2048 bit + 8-multiple\n", keybits); return SC_ERROR_INVALID_ARGUMENTS; } /* Get the private key file */ r = myeid_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, index, &prkf); if (r < 0) goto done; /* Take enough room for a 1024 bit key */ if (prkf->size < 1024) prkf->size = 1024; /* Now create the key file */ r = sc_pkcs15init_create_file(profile, card, prkf); if (r < 0) goto done; /* Fill in data structure */ memset(&args, 0, sizeof(args)); args.mod_len = keybits; if (prkey == NULL) { args.op_type = OP_TYPE_GENERATE; args.pubexp_len = MYEID_DEFAULT_PUBKEY_LEN; args.pubexp = MYEID_DEFAULT_PUBKEY; } else { 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; } /* Authenticate */ r = sc_pkcs15init_authenticate(profile, card, prkf, SC_AC_OP_UPDATE); if (r < 0) goto done; /* Generate/store rsa key */ r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_KEY, &args); if (r < 0) goto done; info->key_reference = 0; info->path = prkf->path; done: if (prkf) sc_file_free(prkf); SC_FUNC_RETURN(card->ctx, 1, r); }