static int sc_pkcs15emu_oberthur_init(struct sc_pkcs15_card * p15card) { struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_auth_info auth_info; struct sc_pkcs15_object obj; struct sc_card *card = p15card->card; struct sc_path path; int rv, ii, tries_left; char serial[0x10]; unsigned char sopin_reference = 0x04; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); sc_bin_to_hex(card->serialnr.value, card->serialnr.len, serial, sizeof(serial), 0); p15card->tokeninfo->serial_number = strdup(serial); p15card->ops.parse_df = sc_awp_parse_df; p15card->ops.clear = sc_awp_clear; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Oberthur init: serial %s", p15card->tokeninfo->serial_number); sc_format_path(AWP_PIN_DF, &path); rv = sc_select_file(card, &path, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Oberthur init failed: cannot select PIN dir"); tries_left = -1; rv = sc_verify(card, SC_AC_CHV, sopin_reference, (unsigned char *)"", 0, &tries_left); if (rv && rv != SC_ERROR_PIN_CODE_INCORRECT) { sopin_reference = 0x84; rv = sc_verify(card, SC_AC_CHV, sopin_reference, (unsigned char *)"", 0, &tries_left); } if (rv && rv != SC_ERROR_PIN_CODE_INCORRECT) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Invalid state of SO-PIN"); /* add PIN */ memset(&auth_info, 0, sizeof(auth_info)); memset(&obj, 0, sizeof(obj)); auth_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; auth_info.auth_method = SC_AC_CHV; auth_info.auth_id.len = 1; auth_info.auth_id.value[0] = 0xFF; auth_info.attrs.pin.min_length = 4; auth_info.attrs.pin.max_length = 64; auth_info.attrs.pin.stored_length = 64; auth_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; auth_info.attrs.pin.reference = sopin_reference; auth_info.attrs.pin.pad_char = 0xFF; auth_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_SO_PIN; auth_info.tries_left = tries_left; strncpy(obj.label, "SO PIN", SC_PKCS15_MAX_LABEL_SIZE-1); obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Add PIN(%s,auth_id:%s,reference:%i)", obj.label, sc_pkcs15_print_id(&auth_info.auth_id), auth_info.attrs.pin.reference); rv = sc_pkcs15emu_add_pin_obj(p15card, &obj, &auth_info); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Oberthur init failed: cannot add PIN object"); tries_left = -1; rv = sc_verify(card, SC_AC_CHV, 0x81, (unsigned char *)"", 0, &tries_left); if (rv == SC_ERROR_PIN_CODE_INCORRECT) { /* add PIN */ memset(&auth_info, 0, sizeof(auth_info)); memset(&obj, 0, sizeof(obj)); auth_info.auth_id.len = sizeof(PinDomainID) > sizeof(auth_info.auth_id.value) ? sizeof(auth_info.auth_id.value) : sizeof(PinDomainID); memcpy(auth_info.auth_id.value, PinDomainID, auth_info.auth_id.len); auth_info.auth_method = SC_AC_CHV; auth_info.attrs.pin.min_length = 4; auth_info.attrs.pin.max_length = 64; auth_info.attrs.pin.stored_length = 64; auth_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; auth_info.attrs.pin.reference = 0x81; auth_info.attrs.pin.pad_char = 0xFF; auth_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_LOCAL; auth_info.tries_left = tries_left; strncpy(obj.label, PIN_DOMAIN_LABEL, SC_PKCS15_MAX_LABEL_SIZE-1); obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE; sc_format_path(AWP_PIN_DF, &auth_info.path); auth_info.path.type = SC_PATH_TYPE_PATH; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Add PIN(%s,auth_id:%s,reference:%i)", obj.label, sc_pkcs15_print_id(&auth_info.auth_id), auth_info.attrs.pin.reference); rv = sc_pkcs15emu_add_pin_obj(p15card, &obj, &auth_info); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Oberthur init failed: cannot add PIN object"); } else if (rv != SC_ERROR_DATA_OBJECT_NOT_FOUND) { SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Oberthur init failed: cannot verify PIN"); } for (ii=0; oberthur_infos[ii].name; ii++) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Oberthur init: read %s file", oberthur_infos[ii].name); rv = sc_oberthur_read_file(p15card, oberthur_infos[ii].path, &oberthur_infos[ii].content, &oberthur_infos[ii].len, 1); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Oberthur init failed: read oberthur file error"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Oberthur init: parse %s file, content length %i", oberthur_infos[ii].name, oberthur_infos[ii].len); rv = oberthur_infos[ii].parser(p15card, oberthur_infos[ii].content, oberthur_infos[ii].len, oberthur_infos[ii].postpone_allowed); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Oberthur init failed: parse error"); } SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS); }
/* * 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: if (!sc_valid_oid(&prkey->u.ec.params.id)) if (sc_pkcs15_fix_ec_parameters(ctx, &prkey->u.ec.params)) LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID); if (sc_card_find_ec_alg(p15card->card, keybits, &prkey->u.ec.params.id) == NULL) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported algorithm or 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, "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 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]; 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_GENERATE); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to generate MyEID private key"); /* Fill in data structure */ memset(&args, 0, sizeof(args)); args.mod_len = keybits; args.op_type = OP_TYPE_GENERATE; args.pubexp_len = MYEID_DEFAULT_PUBKEY_LEN; args.pubexp = MYEID_DEFAULT_PUBKEY; /* Generate 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"); /* Keypair generation -> collect public key info */ /* FIXME: was not preset in original Aventra version. Need to be tested. (VT) */ if (pubkey != NULL) { struct sc_cardctl_myeid_data_obj data_obj; 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); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, 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); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot get key modulus: 'MYEID_GETDATA' failed"); if ((data_obj.DataLen * 8) != key_info->modulus_length) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_PKCS15INIT, "Cannot get key modulus: invalid key-size"); memcpy (pubkey->u.rsa.modulus.data, raw_pubkey, pubkey->u.rsa.modulus.len); } if (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: if (sc_card_find_ec_alg(p15card->card, keybits) == 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) { 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"); 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); }
/* * Verify a PIN. * * If the code given to us has zero length, this means we * should ask the card reader to obtain the PIN from the * reader's PIN pad */ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pin_obj, const unsigned char *pincode, size_t pinlen) { struct sc_context *ctx = p15card->card->ctx; struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data; int r; sc_card_t *card; struct sc_pin_cmd_data data; LOG_FUNC_CALLED(ctx); sc_log(ctx, "PIN(type:%X;method:%X;len:)", auth_info->auth_type, auth_info->auth_method, pinlen); if (pinlen > SC_MAX_PIN_SIZE) LOG_TEST_RET(ctx, SC_ERROR_INVALID_PIN_LENGTH, "Invalid PIN size"); card = p15card->card; /* Initialize arguments */ memset(&data, 0, sizeof(data)); data.cmd = SC_PIN_CMD_VERIFY; data.pin_type = auth_info->auth_method; if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN) { data.pin_reference = auth_info->attrs.pin.reference; data.pin1.min_length = auth_info->attrs.pin.min_length; data.pin1.max_length = auth_info->attrs.pin.max_length; data.pin1.pad_length = auth_info->attrs.pin.stored_length; data.pin1.pad_char = auth_info->attrs.pin.pad_char; data.pin1.data = pincode; data.pin1.len = pinlen; if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_NEEDS_PADDING) data.flags |= SC_PIN_CMD_NEED_PADDING; switch (auth_info->attrs.pin.type) { case SC_PKCS15_PIN_TYPE_BCD: data.pin1.encoding = SC_PIN_ENCODING_BCD; break; case SC_PKCS15_PIN_TYPE_ASCII_NUMERIC: data.pin1.encoding = SC_PIN_ENCODING_ASCII; break; default: /* assume/hope the card driver knows how to encode the pin */ data.pin1.encoding = 0; } } else if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_AUTH_KEY) { struct sc_pkcs15_object *skey_obj = NULL; struct sc_pkcs15_id *skey_id = &auth_info->attrs.authkey.skey_id; struct sc_pkcs15_skey_info *skey_info = NULL; r = sc_pkcs15_find_skey_by_id(p15card, skey_id, &skey_obj); if (r) { sc_log(ctx, "cannot find secret key with id:%s", sc_pkcs15_print_id(skey_id)); LOG_FUNC_RETURN(ctx, r); } skey_info = (struct sc_pkcs15_skey_info *)skey_obj->data; sc_log(ctx, "found secret key '%s'", skey_obj->label); data.pin_reference = skey_info->key_reference; } if(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) { if (!pincode && !pinlen) data.flags |= SC_PIN_CMD_USE_PINPAD; if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) data.pin1.prompt = "Please enter SO PIN"; else data.pin1.prompt = "Please enter PIN"; } r = sc_lock(card); LOG_TEST_RET(ctx, r, "sc_lock() failed"); /* the path in the pin object is optional */ if ((auth_info->path.len > 0) || ((auth_info->path.aid.len > 0))) { r = sc_select_file(card, &auth_info->path, NULL); if (r) goto out; } r = sc_pin_cmd(card, &data, &auth_info->tries_left); sc_log(ctx, "PIN cmd result %i", r); if (r == SC_SUCCESS) sc_pkcs15_pincache_add(p15card, pin_obj, pincode, pinlen); out: sc_unlock(card); LOG_FUNC_RETURN(ctx, r); }
void OpenSCKeyRecord::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls) { sc_debug(mToken->mScCtx, "In OpenSCKeyRecord::getAcl, tag is: %s\n", tag); if (!mAclEntries) { mAclEntries.allocator(Allocator::standard()); // Anyone can read the DB record for this key (which is a reference CSSM_KEY) sc_debug(mToken->mScCtx, "DB read for a reference key object is always OK\n"); // Anyone can read the DB record for this key (which is a reference // CSSM_KEY) mAclEntries.add(CssmClient::AclFactory::AnySubject( mAclEntries.allocator()), AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0)); // The pinNum uniquely identifies the AuthID of the PIN needed to use this key, // so when OpenSCToken::verifyPIN() is called with this pinNum, we know which // PIN we have to verify int pinNum = mToken->getRefFromPinMap(&mPrKeyObj->auth_id); sc_debug(mToken->mScCtx, " auth_id for PIN: %s, pinNum = %d\n", sc_pkcs15_print_id(&mPrKeyObj->auth_id), pinNum); if (pinNum != -1) { char tmptag[20]; // This is hardcoded for now. // Apparently, more than one PIN slot is not supported. snprintf(tmptag, sizeof(tmptag), "PIN%d", 1); if(mObject->user_consent) { // PIN for this key must be entered every time // This will be used for user consent keys like the non repudiation keys // from national eID cards) CssmData prompt; mAclEntries.add(CssmClient::AclFactory::PromptPWSubject(mAclEntries.allocator(), prompt), AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_SIGN, 0), tmptag); } else if (pinNum == 1) { // PIN needs to be entered only once if this key is associated with PIN #1 // and doesn't have the user consent bit set mAclEntries.add(CssmClient::AclFactory::PinSubject(mAclEntries.allocator(), pinNum), AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_ENCRYPT, CSSM_ACL_AUTHORIZATION_DECRYPT, CSSM_ACL_AUTHORIZATION_SIGN, CSSM_ACL_AUTHORIZATION_MAC, CSSM_ACL_AUTHORIZATION_DERIVE, 0), tmptag); } else { // All other keys without the user consent bit set. // This is just a temporary workaround, until proper PIN slots are supported. CssmData prompt; mAclEntries.add(CssmClient::AclFactory::PromptPWSubject(mAclEntries.allocator(), prompt), AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_ENCRYPT, CSSM_ACL_AUTHORIZATION_DECRYPT, CSSM_ACL_AUTHORIZATION_SIGN, CSSM_ACL_AUTHORIZATION_MAC, CSSM_ACL_AUTHORIZATION_DERIVE, 0), tmptag); } } } count = mAclEntries.size(); acls = mAclEntries.entries(); // Notify the tokend object with the PIN it should verify mToken->setCurrentPIN(mToken->getRefFromPinMap(&mPrKeyObj->auth_id)); sc_debug(mToken->mScCtx, " retuning %d ACL entries\n", count); }
int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, const u8 ** buf, size_t *buflen) { sc_context_t *ctx = p15card->card->ctx; struct sc_pkcs15_prkey_info info; int r, i, gostr3410_params[3]; struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; size_t usage_len = sizeof(info.usage); size_t af_len = sizeof(info.access_flags); struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE]; struct sc_asn1_entry asn1_com_prkey_attr[C_ASN1_COM_PRKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_prk_rsa_attr[C_ASN1_PRK_RSA_ATTR_SIZE]; struct sc_asn1_entry asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE]; struct sc_asn1_entry asn1_prk_dsa_attr[C_ASN1_PRK_DSA_ATTR_SIZE]; struct sc_asn1_entry asn1_dsakey_i_p_attr[C_ASN1_DSAKEY_I_P_ATTR_SIZE]; struct sc_asn1_entry asn1_dsakey_value_attr[C_ASN1_DSAKEY_VALUE_ATTR_SIZE]; struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOSTR3410KEY_ATTR_SIZE]; struct sc_asn1_entry asn1_prk_gostr3410_attr[C_ASN1_PRK_GOSTR3410_ATTR_SIZE]; struct sc_asn1_entry asn1_ecckey_attr[C_ASN1_ECCKEY_ATTR]; struct sc_asn1_entry asn1_prk_ecc_attr[C_ASN1_PRK_ECC_ATTR]; struct sc_asn1_entry asn1_prkey[C_ASN1_PRKEY_SIZE]; struct sc_asn1_entry asn1_supported_algorithms[C_ASN1_SUPPORTED_ALGORITHMS_SIZE]; struct sc_asn1_pkcs15_object rsa_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_rsa_attr}; struct sc_asn1_pkcs15_object dsa_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_dsa_attr}; struct sc_asn1_pkcs15_object gostr3410_prkey_obj = {obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_gostr3410_attr}; struct sc_asn1_pkcs15_object ecc_prkey_obj = { obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_ecc_attr }; sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey); sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms); sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr); sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr); sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); sc_copy_asn1_entry(c_asn1_dsakey_value_attr, asn1_dsakey_value_attr); sc_copy_asn1_entry(c_asn1_dsakey_i_p_attr, asn1_dsakey_i_p_attr); sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr); sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); sc_copy_asn1_entry(c_asn1_prk_ecc_attr, asn1_prk_ecc_attr); sc_copy_asn1_entry(c_asn1_ecckey_attr, asn1_ecckey_attr); sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr); sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); sc_format_asn1_entry(asn1_prkey + 0, &rsa_prkey_obj, NULL, 0); sc_format_asn1_entry(asn1_prkey + 1, &ecc_prkey_obj, NULL, 0); sc_format_asn1_entry(asn1_prkey + 2, &dsa_prkey_obj, NULL, 0); sc_format_asn1_entry(asn1_prkey + 3, &gostr3410_prkey_obj, NULL, 0); sc_format_asn1_entry(asn1_prk_rsa_attr + 0, asn1_rsakey_attr, NULL, 0); sc_format_asn1_entry(asn1_prk_dsa_attr + 0, asn1_dsakey_attr, NULL, 0); sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 0); sc_format_asn1_entry(asn1_prk_ecc_attr + 0, asn1_ecckey_attr, NULL, 0); sc_format_asn1_entry(asn1_rsakey_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0); sc_format_asn1_entry(asn1_dsakey_attr + 0, asn1_dsakey_value_attr, NULL, 0); sc_format_asn1_entry(asn1_dsakey_value_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_dsakey_value_attr + 1, asn1_dsakey_i_p_attr, NULL, 0); sc_format_asn1_entry(asn1_dsakey_i_p_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0); sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0); sc_format_asn1_entry(asn1_ecckey_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_ecckey_attr + 1, &info.field_length, NULL, 0); sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0); sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0); sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0); sc_format_asn1_entry(asn1_com_key_attr + 3, &info.access_flags, &af_len, 0); sc_format_asn1_entry(asn1_com_key_attr + 4, &info.key_reference, NULL, 0); for (i=0; i<SC_MAX_SUPPORTED_ALGORITHMS && (asn1_supported_algorithms + i)->name; i++) sc_format_asn1_entry(asn1_supported_algorithms + i, &info.algo_refs[i], NULL, 0); sc_format_asn1_entry(asn1_com_key_attr + 5, asn1_supported_algorithms, NULL, 0); sc_format_asn1_entry(asn1_com_prkey_attr + 0, &info.subject.value, &info.subject.len, 0); /* Fill in defaults */ memset(&info, 0, sizeof(info)); info.key_reference = -1; info.native = 1; memset(gostr3410_params, 0, sizeof(gostr3410_params)); r = sc_asn1_decode_choice(ctx, asn1_prkey, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; LOG_TEST_RET(ctx, r, "PrKey DF ASN.1 decoding failed"); if (asn1_prkey[0].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PRKEY_RSA; } else if (asn1_prkey[1].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PRKEY_EC; } else if (asn1_prkey[2].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PRKEY_DSA; /* If the value was indirect-protected, mark the path */ if (asn1_dsakey_i_p_attr[0].flags & SC_ASN1_PRESENT) info.path.type = SC_PATH_TYPE_PATH_PROT; } else if (asn1_prkey[3].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PRKEY_GOSTR3410; assert(info.modulus_length == 0); info.modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; assert(info.params.len == 0); info.params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams); info.params.data = malloc(info.params.len); if (info.params.data == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); assert(sizeof(*keyinfo_gostparams) == info.params.len); keyinfo_gostparams = info.params.data; keyinfo_gostparams->gostr3410 = gostr3410_params[0]; keyinfo_gostparams->gostr3411 = gostr3410_params[1]; keyinfo_gostparams->gost28147 = gostr3410_params[2]; } else { sc_log(ctx, "Neither RSA or DSA or GOSTR3410 or ECC key in PrKDF entry."); LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT); } if (!p15card->app || !p15card->app->ddo.aid.len) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); if (r < 0) { sc_pkcs15_free_key_params(&info.params); return r; } } else { info.path.aid = p15card->app->ddo.aid; } sc_log(ctx, "PrivKey path '%s'", sc_print_path(&info.path)); /* OpenSC 0.11.4 and older encoded "keyReference" as a negative value. * Fixed in 0.11.5 we need to add a hack, so old cards continue to work. */ if (info.key_reference < -1) info.key_reference += 256; /* Check the auth_id - if not present, try and find it in access rules */ if ((obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) && (obj->auth_id.len == 0)) { sc_log(ctx, "Private key %s has no auth ID - checking AccessControlRules", sc_pkcs15_print_id(&info.id)); /* Search in the access_rules for an appropriate auth ID */ for (i = 0; i < SC_PKCS15_MAX_ACCESS_RULES; i++) { /* If access_mode is one of the private key usage modes */ if (obj->access_rules[i].access_mode & (SC_PKCS15_ACCESS_RULE_MODE_EXECUTE | SC_PKCS15_ACCESS_RULE_MODE_PSO_CDS | SC_PKCS15_ACCESS_RULE_MODE_PSO_DECRYPT | SC_PKCS15_ACCESS_RULE_MODE_INT_AUTH)) { if (obj->access_rules[i].auth_id.len != 0) { /* Found an auth ID to use for private key access */ obj->auth_id = obj->access_rules[i].auth_id; sc_log(ctx, "Auth ID found - %s", sc_pkcs15_print_id(&obj->auth_id)); break; } } } /* No auth ID found */ if (i == SC_PKCS15_MAX_ACCESS_RULES) sc_log(ctx, "Warning: No auth ID found"); } obj->data = malloc(sizeof(info)); if (obj->data == NULL) { sc_pkcs15_free_key_params(&info.params); LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); } memcpy(obj->data, &info, sizeof(info)); sc_log(ctx, "Key Subject %s", sc_dump_hex(info.subject.value, info.subject.len)); sc_log(ctx, "Key path %s", sc_print_path(&info.path)); return 0; }