static int compare_obj_id(struct sc_pkcs15_object *obj, const sc_pkcs15_id_t *id) { void *data = obj->data; switch (obj->type) { case SC_PKCS15_TYPE_CERT_X509: return sc_pkcs15_compare_id(&((struct sc_pkcs15_cert_info *) data)->id, id); case SC_PKCS15_TYPE_PRKEY_RSA: case SC_PKCS15_TYPE_PRKEY_DSA: return sc_pkcs15_compare_id(&((struct sc_pkcs15_prkey_info *) data)->id, id); case SC_PKCS15_TYPE_PUBKEY_RSA: case SC_PKCS15_TYPE_PUBKEY_DSA: return sc_pkcs15_compare_id(&((struct sc_pkcs15_pubkey_info *) data)->id, id); case SC_PKCS15_TYPE_AUTH_PIN: return sc_pkcs15_compare_id(&((struct sc_pkcs15_pin_info *) data)->auth_id, id); case SC_PKCS15_TYPE_DATA_OBJECT: return sc_pkcs15_compare_id(&((struct sc_pkcs15_data_info *) data)->id, id); } return 0; }
/* Add a PIN to the PIN cache related to the card. Some operations can trigger re-authentication later. */ void sc_pkcs15_pincache_add(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pin_obj, const u8 *pin, 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; struct sc_pkcs15_object *obj = NULL; int r; LOG_FUNC_CALLED(ctx); if (!p15card->opts.use_pin_cache) { sc_log(ctx, "PIN caching not enabled"); return; } else if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) { sc_log(ctx, "only 'PIN' auth. object can be cached"); return; } /* If the PIN protects an object with user consent, don't cache it */ obj = p15card->obj_list; while (obj != NULL) { /* Compare 'sc_pkcs15_object.auth_id' with 'sc_pkcs15_pin_info.auth_id'. * In accordance with PKCS#15 "6.1.8 CommonObjectAttributes" and * "6.1.16 CommonAuthenticationObjectAttributes" with the exception that * "CommonObjectAttributes.accessControlRules" are not taken into account. */ if (sc_pkcs15_compare_id(&obj->auth_id, &auth_info->auth_id)) { /* Caching is refused, if the protected object requires user consent */ if (!p15card->opts.pin_cache_ignore_user_consent) { if (obj->user_consent > 0) { sc_log(ctx, "caching refused (user consent)"); return; } } } obj = obj->next; } r = sc_pkcs15_allocate_object_content(ctx, pin_obj, pin, pinlen); if (r != SC_SUCCESS) { sc_log(ctx, "Failed to allocate object content"); return; } pin_obj->usage_counter = 0; sc_log(ctx, "PIN(%s) cached", pin_obj->label); }
static int read_certificate(void) { int r, i, count; struct sc_pkcs15_id id; struct sc_pkcs15_object *objs[32]; id.len = SC_PKCS15_MAX_ID_SIZE; sc_pkcs15_hex_string_to_id(opt_cert, &id); r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32); if (r < 0) { fprintf(stderr, "Certificate enumeration failed: %s\n", sc_strerror(r)); return 1; } count = r; for (i = 0; i < count; i++) { struct sc_pkcs15_cert_info *cinfo = (struct sc_pkcs15_cert_info *) objs[i]->data; struct sc_pkcs15_cert *cert; if (sc_pkcs15_compare_id(&id, &cinfo->id) != 1) continue; if (verbose) printf("Reading certificate with ID '%s'\n", opt_cert); r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); if (r) { fprintf(stderr, "Certificate read failed: %s\n", sc_strerror(r)); return 1; } r = print_pem_object("CERTIFICATE", cert->data, cert->data_len); sc_pkcs15_free_certificate(cert); return r; } fprintf(stderr, "Certificate with ID '%s' not found.\n", opt_cert); return 2; }