/* * Encode a card verifiable certificate as defined in TR-03110. */ int sc_pkcs15emu_sc_hsm_encode_cvc(sc_pkcs15_card_t * p15card, sc_cvc_t *cvc, u8 ** buf, size_t *buflen) { sc_card_t *card = p15card->card; struct sc_asn1_entry asn1_cvc[C_ASN1_CVC_SIZE]; struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE]; struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE]; struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE]; unsigned int cla,tag; size_t taglen; size_t lenchr; size_t lencar; int r; sc_copy_asn1_entry(c_asn1_cvc, asn1_cvc); sc_copy_asn1_entry(c_asn1_cvcert, asn1_cvcert); sc_copy_asn1_entry(c_asn1_cvc_body, asn1_cvc_body); sc_copy_asn1_entry(c_asn1_cvc_pubkey, asn1_cvc_pubkey); asn1_cvc_pubkey[1].flags = SC_ASN1_OPTIONAL; asn1_cvcert[1].flags = SC_ASN1_OPTIONAL; sc_format_asn1_entry(asn1_cvc_pubkey , &cvc->pukoid, NULL, 1); if (cvc->primeOrModulus && (cvc->primeOrModuluslen > 0)) { sc_format_asn1_entry(asn1_cvc_pubkey + 1, cvc->primeOrModulus, &cvc->primeOrModuluslen, 1); } sc_format_asn1_entry(asn1_cvc_pubkey + 2, cvc->coefficientAorExponent, &cvc->coefficientAorExponentlen, 1); if (cvc->coefficientB && (cvc->coefficientBlen > 0)) { sc_format_asn1_entry(asn1_cvc_pubkey + 3, cvc->coefficientB, &cvc->coefficientBlen, 1); sc_format_asn1_entry(asn1_cvc_pubkey + 4, cvc->basePointG, &cvc->basePointGlen, 1); sc_format_asn1_entry(asn1_cvc_pubkey + 5, cvc->order, &cvc->orderlen, 1); if (cvc->publicPoint && (cvc->publicPointlen > 0)) { sc_format_asn1_entry(asn1_cvc_pubkey + 6, cvc->publicPoint, &cvc->publicPointlen, 1); } sc_format_asn1_entry(asn1_cvc_pubkey + 7, cvc->cofactor, &cvc->cofactorlen, 1); } if (cvc->modulusSize > 0) { sc_format_asn1_entry(asn1_cvc_pubkey + 8, &cvc->modulusSize, NULL, 1); } sc_format_asn1_entry(asn1_cvc_body , &cvc->cpi, NULL, 1); lencar = strlen(cvc->car); sc_format_asn1_entry(asn1_cvc_body + 1, &cvc->car, &lencar, 1); sc_format_asn1_entry(asn1_cvc_body + 2, &asn1_cvc_pubkey, NULL, 1); lenchr = strlen(cvc->chr); sc_format_asn1_entry(asn1_cvc_body + 3, &cvc->chr, &lenchr, 1); sc_format_asn1_entry(asn1_cvcert , &asn1_cvc_body, NULL, 1); if (cvc->signature && (cvc->signatureLen > 0)) { sc_format_asn1_entry(asn1_cvcert + 1, cvc->signature, &cvc->signatureLen, 1); } sc_format_asn1_entry(asn1_cvc , &asn1_cvcert, NULL, 1); r = sc_asn1_encode(card->ctx, asn1_cvc, buf, buflen); LOG_TEST_RET(card->ctx, r, "Could not encode card verifiable certificate"); LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); }
int sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, u8 **buf, size_t *buflen) { int r; int version = ti->version; size_t serial_len, mnfid_len, label_len, flags_len, last_upd_len; struct sc_asn1_entry asn1_toki[14], asn1_tokeninfo[2]; sc_copy_asn1_entry(c_asn1_toki, asn1_toki); sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo); version--; sc_format_asn1_entry(asn1_toki + 0, &version, NULL, 1); if (ti->serial_number != NULL) { u8 serial[128]; serial_len = 0; if (strlen(ti->serial_number)/2 > sizeof(serial)) return SC_ERROR_BUFFER_TOO_SMALL; serial_len = sizeof(serial); if (sc_hex_to_bin(ti->serial_number, serial, &serial_len) < 0) return SC_ERROR_INVALID_ARGUMENTS; sc_format_asn1_entry(asn1_toki + 1, serial, &serial_len, 1); } else sc_format_asn1_entry(asn1_toki + 1, NULL, NULL, 0); if (ti->manufacturer_id != NULL) { mnfid_len = strlen(ti->manufacturer_id); sc_format_asn1_entry(asn1_toki + 2, ti->manufacturer_id, &mnfid_len, 1); } else sc_format_asn1_entry(asn1_toki + 2, NULL, NULL, 0); if (ti->label != NULL) { label_len = strlen(ti->label); sc_format_asn1_entry(asn1_toki + 3, ti->label, &label_len, 1); } else sc_format_asn1_entry(asn1_toki + 3, NULL, NULL, 0); if (ti->flags) { flags_len = sizeof(ti->flags); sc_format_asn1_entry(asn1_toki + 5, &ti->flags, &flags_len, 1); } else sc_format_asn1_entry(asn1_toki + 5, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 6, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 7, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 8, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 9, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 10, NULL, NULL, 0); if (ti->last_update != NULL) { last_upd_len = strlen(ti->last_update); sc_format_asn1_entry(asn1_toki + 11, ti->last_update, &last_upd_len, 1); } else sc_format_asn1_entry(asn1_toki + 11, NULL, NULL, 0); sc_format_asn1_entry(asn1_toki + 12, NULL, NULL, 0); sc_format_asn1_entry(asn1_tokeninfo, asn1_toki, NULL, 1); r = sc_asn1_encode(ctx, asn1_tokeninfo, buf, buflen); if (r) { sc_error(ctx, "sc_asn1_encode() failed: %s\n", sc_strerror(r)); return r; } return 0; }
int sc_pkcs15_encode_dodf_entry(sc_context_t *ctx, const struct sc_pkcs15_object *obj, u8 **buf, size_t *bufsize) { struct sc_asn1_entry asn1_com_data_attr[4], asn1_type_data_attr[2], asn1_data[2]; struct sc_pkcs15_data_info *info; struct sc_asn1_pkcs15_object data_obj = { (struct sc_pkcs15_object *) obj, asn1_com_data_attr, NULL, asn1_type_data_attr }; size_t label_len; info = (struct sc_pkcs15_data_info *) obj->data; label_len = strlen(info->app_label); sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr); sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr); sc_copy_asn1_entry(c_asn1_data, asn1_data); if (label_len) sc_format_asn1_entry(asn1_com_data_attr + 0, &info->app_label, &label_len, 1); if (sc_valid_oid(&info->app_oid)) sc_format_asn1_entry(asn1_com_data_attr + 1, &info->app_oid, NULL, 1); sc_format_asn1_entry(asn1_type_data_attr + 0, &info->path, NULL, 1); sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 1); return sc_asn1_encode(ctx, asn1_data, buf, bufsize); }
static int encode_dir_record(sc_context_t *ctx, const sc_app_info_t *app, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_dirrecord[5], asn1_dir[2]; sc_app_info_t tapp = *app; int r; size_t label_len; sc_copy_asn1_entry(c_asn1_dirrecord, asn1_dirrecord); sc_copy_asn1_entry(c_asn1_dir, asn1_dir); sc_format_asn1_entry(asn1_dir + 0, asn1_dirrecord, NULL, 1); sc_format_asn1_entry(asn1_dirrecord + 0, (void *) tapp.aid.value, (void *) &tapp.aid.len, 1); if (tapp.label != NULL) { label_len = strlen(tapp.label); sc_format_asn1_entry(asn1_dirrecord + 1, tapp.label, &label_len, 1); } if (tapp.path.len) sc_format_asn1_entry(asn1_dirrecord + 2, (void *) tapp.path.value, (void *) &tapp.path.len, 1); if (tapp.ddo.value != NULL && tapp.ddo.len) sc_format_asn1_entry(asn1_dirrecord + 3, (void *) tapp.ddo.value, (void *) &tapp.ddo.len, 1); r = sc_asn1_encode(ctx, asn1_dir, buf, buflen); LOG_TEST_RET(ctx, r, "Encode DIR record error"); return SC_SUCCESS; }
int sc_pkcs15_encode_pubkey_dsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_dsa *key, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_public_key[2]; struct sc_asn1_entry asn1_dsa_pub_coeff[5]; int r; sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); sc_copy_asn1_entry(c_asn1_dsa_pub_coefficients, asn1_dsa_pub_coeff); sc_format_asn1_entry(asn1_public_key + 0, asn1_dsa_pub_coeff, NULL, 1); sc_format_asn1_entry(asn1_dsa_pub_coeff + 0, key->pub.data, &key->pub.len, 1); sc_format_asn1_entry(asn1_dsa_pub_coeff + 1, key->g.data, &key->g.len, 1); sc_format_asn1_entry(asn1_dsa_pub_coeff + 2, key->p.data, &key->p.len, 1); sc_format_asn1_entry(asn1_dsa_pub_coeff + 3, key->q.data, &key->q.len, 1); r = sc_asn1_encode(ctx, asn1_public_key, buf, buflen); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 encoding failed"); return 0; }
int sc_pkcs15_decode_dodf_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_data_info info; struct sc_asn1_entry asn1_com_data_attr[3], asn1_type_data_attr[2], asn1_data[2]; struct sc_asn1_pkcs15_object data_obj = { obj, asn1_com_data_attr, NULL, asn1_type_data_attr }; size_t label_len = sizeof(info.app_label); int r; sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr); sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr); sc_copy_asn1_entry(c_asn1_data, asn1_data); sc_format_asn1_entry(asn1_com_data_attr + 0, &info.app_label, &label_len, 0); sc_format_asn1_entry(asn1_com_data_attr + 1, &info.app_oid, NULL, 0); sc_format_asn1_entry(asn1_type_data_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 0); /* Fill in defaults */ memset(&info, 0, sizeof(info)); sc_init_oid(&info.app_oid); r = sc_asn1_decode(ctx, asn1_data, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed"); if (!p15card->app || !p15card->app->ddo.aid.len) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); if (r < 0) return r; } else { info.path.aid = p15card->app->ddo.aid; } obj->type = SC_PKCS15_TYPE_DATA_OBJECT; obj->data = malloc(sizeof(info)); if (obj->data == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); memcpy(obj->data, &info, sizeof(info)); return SC_SUCCESS; }
static int asn1_decode_pbkdf2_params(sc_context_t *ctx, void **paramp, const u8 *buf, size_t buflen, int depth) { struct sc_pbkdf2_params info; struct sc_asn1_entry asn1_pbkdf2_params[5]; int r; sc_copy_asn1_entry(c_asn1_pbkdf2_params, asn1_pbkdf2_params); sc_format_asn1_entry(asn1_pbkdf2_params + 0, info.salt, &info.salt_len, 0); sc_format_asn1_entry(asn1_pbkdf2_params + 1, &info.iterations, NULL, 0); sc_format_asn1_entry(asn1_pbkdf2_params + 2, &info.key_length, NULL, 0); sc_format_asn1_entry(asn1_pbkdf2_params + 3, &info.hash_alg, NULL, 0); memset(&info, 0, sizeof(info)); info.salt_len = sizeof(info.salt); info.hash_alg.algorithm = SC_ALGORITHM_SHA1; r = _sc_asn1_decode(ctx, asn1_pbkdf2_params, buf, buflen, NULL, NULL, 0, depth + 1); if (r < 0) return r; *paramp = malloc(sizeof(info)); if (!*paramp) return SC_ERROR_OUT_OF_MEMORY; memcpy(*paramp, &info, sizeof(info)); return 0; }
/* * We are storing the ec_pointQ as u8 string. not as DER */ int sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, const u8 *buf, size_t buflen) { int r; u8 * ecpoint_data; size_t ecpoint_len; struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); r = sc_asn1_decode(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); if (r < 0) LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); sc_log(ctx, "decode-EC key=%p, buf=%p, buflen=%d", key, buf, buflen); key->ecpointQ.len = ecpoint_len; key->ecpointQ.value = ecpoint_data; /* An uncompressed ecpoint is of the form 04||x||y * The 04 indicates uncompressed * x and y are same size, and field_length = sizeof(x) in bits. */ /* TODO: -DEE support more then uncompressed */ key->params.field_length = (ecpoint_len - 1)/2 * 8; return r; }
static int parse_odf(const u8 * buf, size_t buflen, struct sc_pkcs15_card *card) { const u8 *p = buf; size_t left = buflen; int r, i, type; sc_path_t path; struct sc_asn1_entry asn1_obj_or_path[] = { { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; struct sc_asn1_entry asn1_odf[10]; sc_copy_asn1_entry(c_asn1_odf, asn1_odf); for (i = 0; asn1_odf[i].name != NULL; i++) sc_format_asn1_entry(asn1_odf + i, asn1_obj_or_path, NULL, 0); while (left > 0) { r = sc_asn1_decode_choice(card->card->ctx, asn1_odf, p, left, &p, &left); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) break; if (r < 0) return r; type = r; r = sc_pkcs15_make_absolute_path(&card->file_app->path, &path); if (r < 0) return r; r = sc_pkcs15_add_df(card, odf_indexes[type], &path, NULL); if (r) return r; } return 0; }
/* * We are storing the ec_pointQ as a octet string. * Thus we will just copy the string. * But to get the field length we decode it. */ int sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, const u8 *buf, size_t buflen) { int r; u8 * ecpoint_data; size_t ecpoint_len; struct sc_asn1_entry asn1_ec_pointQ[2]; sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1); r = sc_asn1_decode(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL); if (r < 0) SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 encoding failed"); sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"DEE-EC key=%p, buf=%p, buflen=%d", key, buf, buflen); key->ecpointQ.value = malloc(buflen); if (key->ecpointQ.value == NULL) return SC_ERROR_OUT_OF_MEMORY; key->ecpointQ.len = buflen; memcpy(key->ecpointQ.value, buf, buflen); /* An uncompressed ecpoint is of the form 04||x||y * The 04 indicates uncompressed * x and y are same size, and field_length = sizeof(x) in bits. */ /* TODO: -DEE support more then uncompressed */ key->params.field_length = (ecpoint_len - 1)/2 * 8; if (ecpoint_data) free (ecpoint_data); return r; }
int sc_pkcs15_encode_aodf_entry(sc_context_t *ctx, const struct sc_pkcs15_object *obj, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_com_ao_attr[2], asn1_pin_attr[10], asn1_type_pin_attr[2]; struct sc_asn1_entry asn1_auth_type[2]; struct sc_asn1_entry asn1_auth_type_choice[4]; struct sc_pkcs15_auth_info *info = (struct sc_pkcs15_auth_info *) obj->data; struct sc_asn1_pkcs15_object pin_obj = { (struct sc_pkcs15_object *) obj, asn1_com_ao_attr, NULL, asn1_type_pin_attr }; int r; size_t flags_len; size_t padchar_len = 1; if (info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN) return SC_ERROR_NOT_SUPPORTED; sc_copy_asn1_entry(c_asn1_auth_type, asn1_auth_type); sc_copy_asn1_entry(c_asn1_auth_type_choice, asn1_auth_type_choice); sc_copy_asn1_entry(c_asn1_type_pin_attr, asn1_type_pin_attr); sc_copy_asn1_entry(c_asn1_pin_attr, asn1_pin_attr); sc_copy_asn1_entry(c_asn1_com_ao_attr, asn1_com_ao_attr); sc_format_asn1_entry(asn1_auth_type + 0, asn1_auth_type_choice, NULL, 1); sc_format_asn1_entry(asn1_auth_type_choice + 0, &pin_obj, NULL, 1); sc_format_asn1_entry(asn1_type_pin_attr + 0, asn1_pin_attr, NULL, 1); flags_len = sizeof(info->attrs.pin.flags); sc_format_asn1_entry(asn1_pin_attr + 0, &info->attrs.pin.flags, &flags_len, 1); sc_format_asn1_entry(asn1_pin_attr + 1, &info->attrs.pin.type, NULL, 1); sc_format_asn1_entry(asn1_pin_attr + 2, &info->attrs.pin.min_length, NULL, 1); sc_format_asn1_entry(asn1_pin_attr + 3, &info->attrs.pin.stored_length, NULL, 1); if (info->attrs.pin.max_length > 0) sc_format_asn1_entry(asn1_pin_attr + 4, &info->attrs.pin.max_length, NULL, 1); if (info->attrs.pin.reference >= 0) sc_format_asn1_entry(asn1_pin_attr + 5, &info->attrs.pin.reference, NULL, 1); /* FIXME: check if pad_char present */ sc_format_asn1_entry(asn1_pin_attr + 6, &info->attrs.pin.pad_char, &padchar_len, 1); sc_format_asn1_entry(asn1_pin_attr + 8, &info->path, NULL, info->path.len ? 1 : 0); sc_format_asn1_entry(asn1_com_ao_attr + 0, &info->auth_id, NULL, 1); r = sc_asn1_encode(ctx, asn1_auth_type, buf, buflen); return r; }
int sc_pkcs15_encode_aodf_entry(sc_context_t *ctx, const struct sc_pkcs15_object *obj, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_com_ao_attr[2], asn1_pin_attr[10], asn1_type_pin_attr[2]; struct sc_asn1_entry asn1_pin[2]; struct sc_pkcs15_pin_info *pin = (struct sc_pkcs15_pin_info *) obj->data; struct sc_asn1_pkcs15_object pin_obj = { (struct sc_pkcs15_object *) obj, asn1_com_ao_attr, NULL, asn1_type_pin_attr }; int r; size_t flags_len; size_t padchar_len = 1; sc_copy_asn1_entry(c_asn1_pin, asn1_pin); sc_copy_asn1_entry(c_asn1_type_pin_attr, asn1_type_pin_attr); sc_copy_asn1_entry(c_asn1_pin_attr, asn1_pin_attr); sc_copy_asn1_entry(c_asn1_com_ao_attr, asn1_com_ao_attr); sc_format_asn1_entry(asn1_pin + 0, &pin_obj, NULL, 1); sc_format_asn1_entry(asn1_type_pin_attr + 0, asn1_pin_attr, NULL, 1); flags_len = sizeof(pin->flags); sc_format_asn1_entry(asn1_pin_attr + 0, &pin->flags, &flags_len, 1); sc_format_asn1_entry(asn1_pin_attr + 1, &pin->type, NULL, 1); sc_format_asn1_entry(asn1_pin_attr + 2, &pin->min_length, NULL, 1); sc_format_asn1_entry(asn1_pin_attr + 3, &pin->stored_length, NULL, 1); if (pin->max_length > 0) sc_format_asn1_entry(asn1_pin_attr + 4, &pin->max_length, NULL, 1); if (pin->reference >= 0) sc_format_asn1_entry(asn1_pin_attr + 5, &pin->reference, NULL, 1); /* FIXME: check if pad_char present */ sc_format_asn1_entry(asn1_pin_attr + 6, &pin->pad_char, &padchar_len, 1); sc_format_asn1_entry(asn1_pin_attr + 8, &pin->path, NULL, pin->path.len ? 1 : 0); sc_format_asn1_entry(asn1_com_ao_attr + 0, &pin->auth_id, NULL, 1); assert(pin->magic == SC_PKCS15_PIN_MAGIC); r = sc_asn1_encode(ctx, asn1_pin, buf, buflen); return r; }
static int asn1_encode_des_params(sc_context_t *ctx, void *params, u8 **buf, size_t *buflen, int depth) { struct sc_asn1_entry asn1_des_iv[2]; int ivlen = 8; sc_copy_asn1_entry(c_asn1_des_iv, asn1_des_iv); sc_format_asn1_entry(asn1_des_iv + 0, params, &ivlen, 1); return _sc_asn1_encode(ctx, asn1_des_iv, buf, buflen, depth + 1); }
int sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key, const u8 *buf, size_t buflen) { struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE]; struct sc_asn1_entry asn1_rsa_pub_coefficients[C_ASN1_RSA_PUB_COEFFICIENTS_SIZE]; int r; sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); sc_format_asn1_entry(asn1_public_key + 0, asn1_rsa_pub_coefficients, NULL, 0); sc_copy_asn1_entry(c_asn1_rsa_pub_coefficients, asn1_rsa_pub_coefficients); sc_format_asn1_entry(asn1_rsa_pub_coefficients + 0, &key->modulus.data, &key->modulus.len, 0); sc_format_asn1_entry(asn1_rsa_pub_coefficients + 1, &key->exponent.data, &key->exponent.len, 0); r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL); LOG_TEST_RET(ctx, r, "ASN.1 parsing of public key failed"); return SC_SUCCESS; }
int sc_pkcs15_encode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE]; struct sc_asn1_entry asn1_rsa_pub_coefficients[C_ASN1_RSA_PUB_COEFFICIENTS_SIZE]; int r; sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); sc_format_asn1_entry(asn1_public_key + 0, asn1_rsa_pub_coefficients, NULL, 1); sc_copy_asn1_entry(c_asn1_rsa_pub_coefficients, asn1_rsa_pub_coefficients); sc_format_asn1_entry(asn1_rsa_pub_coefficients + 0, key->modulus.data, &key->modulus.len, 1); sc_format_asn1_entry(asn1_rsa_pub_coefficients + 1, key->exponent.data, &key->exponent.len, 1); r = sc_asn1_encode(ctx, asn1_public_key, buf, buflen); LOG_TEST_RET(ctx, r, "ASN.1 encoding failed"); return 0; }
static int asn1_encode_gostr3410_params(sc_context_t *ctx, void *params, u8 **buf, size_t *buflen, int depth) { struct sc_asn1_entry asn1_gostr3410_params0[2], asn1_gostr3410_params[4]; struct sc_pkcs15_gost_parameters *gost_params = (struct sc_pkcs15_gost_parameters *)params; int r; sc_copy_asn1_entry(c_asn1_gostr3410_params0, asn1_gostr3410_params0); sc_copy_asn1_entry(c_asn1_gostr3410_params, asn1_gostr3410_params); sc_format_asn1_entry(asn1_gostr3410_params0 + 0, asn1_gostr3410_params, NULL, 1); sc_format_asn1_entry(asn1_gostr3410_params + 0, &gost_params->key, NULL, 1); sc_format_asn1_entry(asn1_gostr3410_params + 1, &gost_params->hash, NULL, 1); /* sc_format_asn1_entry(asn1_gostr3410_params + 2, &cipherp, NULL, 1); */ r = _sc_asn1_encode(ctx, asn1_gostr3410_params0, buf, buflen, depth + 1); sc_log(ctx, "encoded-params: %s", sc_dump_hex(*buf, *buflen)); return r; }
static int asn1_decode_gostr3410_params(sc_context_t *ctx, void **paramp, const u8 *buf, size_t buflen, int depth) { struct sc_asn1_entry asn1_gostr3410_params0[2], asn1_gostr3410_params[4]; struct sc_object_id keyp, hashp, cipherp; int r; sc_copy_asn1_entry(c_asn1_gostr3410_params0, asn1_gostr3410_params0); sc_copy_asn1_entry(c_asn1_gostr3410_params, asn1_gostr3410_params); sc_format_asn1_entry(asn1_gostr3410_params0 + 0, asn1_gostr3410_params, NULL, 0); sc_format_asn1_entry(asn1_gostr3410_params + 0, &keyp, NULL, 0); sc_format_asn1_entry(asn1_gostr3410_params + 1, &hashp, NULL, 0); sc_format_asn1_entry(asn1_gostr3410_params + 2, &cipherp, NULL, 0); r = _sc_asn1_decode(ctx, asn1_gostr3410_params0, buf, buflen, NULL, NULL, 0, depth + 1); /* TODO: store in paramp */ (void)paramp; /* no warning */ return r; }
static int asn1_decode_ec_params(sc_context_t *ctx, void **paramp, const u8 *buf, size_t buflen, int depth) { int r; struct sc_object_id curve; struct sc_asn1_entry asn1_ec_params[4]; struct sc_ec_parameters *ecp; sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DEE - asn1_decode_ec_params %p:%"SC_FORMAT_LEN_SIZE_T"u %d", buf, buflen, depth); memset(&curve, 0, sizeof(curve)); /* We only want to copy the parms if they are a namedCurve * or ecParameters nullParam aka implicityCA is not to be * used with PKCS#11 2.20 */ sc_copy_asn1_entry(c_asn1_ec_params, asn1_ec_params); sc_format_asn1_entry(asn1_ec_params + 1, &curve, 0, 0); /* Some signature algorithms will not have any data */ if (buflen == 0 || buf == NULL) return 0; r = sc_asn1_decode_choice(ctx, asn1_ec_params, buf, buflen, NULL, NULL); /* r = index in asn1_ec_params */ sc_debug(ctx, SC_LOG_DEBUG_ASN1, "asn1_decode_ec_params r=%d", r); if (r < 0) return r; ecp = calloc(sizeof(struct sc_ec_parameters), 1); if (ecp == NULL) return SC_ERROR_OUT_OF_MEMORY; if (r <= 1) { ecp->der.value = malloc(buflen); if (ecp->der.value == NULL) { free(ecp); return SC_ERROR_OUT_OF_MEMORY; } ecp->der.len = buflen; memcpy(ecp->der.value, buf, buflen); } else { r = 0; } ecp->type = r; /* but 0 = ecparams if any, 1=named curve */ *paramp = ecp; return SC_SUCCESS; };
int sc_pkcs15_decode_pubkey_dsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_dsa *key, const u8 *buf, size_t buflen) { struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE]; struct sc_asn1_entry asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE]; int r; sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); sc_copy_asn1_entry(c_asn1_dsa_pub_coefficients, asn1_dsa_pub_coefficients); sc_format_asn1_entry(asn1_public_key + 0, asn1_dsa_pub_coefficients, NULL, 1); sc_format_asn1_entry(asn1_dsa_pub_coefficients + 0, &key->pub.data, &key->pub.len, 0); sc_format_asn1_entry(asn1_dsa_pub_coefficients + 1, &key->g.data, &key->g.len, 0); sc_format_asn1_entry(asn1_dsa_pub_coefficients + 2, &key->p.data, &key->p.len, 0); sc_format_asn1_entry(asn1_dsa_pub_coefficients + 3, &key->q.data, &key->q.len, 0); r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL); LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); return 0; }
static int sc_pkcs15_decode_prkey_dsa(sc_context_t *ctx, struct sc_pkcs15_prkey_dsa *key, const u8 *buf, size_t buflen) { struct sc_asn1_entry asn1_dsa_prkey_obj[2]; sc_copy_asn1_entry(c_asn1_dsa_prkey_obj, asn1_dsa_prkey_obj); sc_format_asn1_entry(asn1_dsa_prkey_obj + 0, &key->priv.data, &key->priv.len, 0); return sc_asn1_decode(ctx, asn1_dsa_prkey_obj, buf, buflen, NULL, NULL); }
static int parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen) { struct sc_asn1_entry asn1_ddo[5]; sc_path_t odf_path, ti_path, us_path; int r; sc_copy_asn1_entry(c_asn1_ddo, asn1_ddo); sc_format_asn1_entry(asn1_ddo + 1, &odf_path, NULL, 0); sc_format_asn1_entry(asn1_ddo + 2, &ti_path, NULL, 0); sc_format_asn1_entry(asn1_ddo + 3, &us_path, NULL, 0); r = sc_asn1_decode(p15card->card->ctx, asn1_ddo, buf, buflen, NULL, NULL); if (r) { sc_error(p15card->card->ctx, "DDO parsing failed: %s\n", sc_strerror(r)); return r; } if (asn1_ddo[1].flags & SC_ASN1_PRESENT) { p15card->file_odf = sc_file_new(); if (p15card->file_odf == NULL) goto mem_err; p15card->file_odf->path = odf_path; } if (asn1_ddo[2].flags & SC_ASN1_PRESENT) { p15card->file_tokeninfo = sc_file_new(); if (p15card->file_tokeninfo == NULL) goto mem_err; p15card->file_tokeninfo->path = ti_path; } if (asn1_ddo[3].flags & SC_ASN1_PRESENT) { p15card->file_unusedspace = sc_file_new(); if (p15card->file_unusedspace == NULL) goto mem_err; p15card->file_unusedspace->path = us_path; } return 0; mem_err: if (p15card->file_odf != NULL) { sc_file_free(p15card->file_odf); p15card->file_odf = NULL; } if (p15card->file_tokeninfo != NULL) { sc_file_free(p15card->file_tokeninfo); p15card->file_tokeninfo = NULL; } if (p15card->file_unusedspace != NULL) { sc_file_free(p15card->file_unusedspace); p15card->file_unusedspace = NULL; } return SC_ERROR_OUT_OF_MEMORY; }
int sc_pkcs15_encode_pubkey_dsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_dsa *key, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE]; struct sc_asn1_entry asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE]; int r; LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); sc_copy_asn1_entry(c_asn1_dsa_pub_coefficients, asn1_dsa_pub_coefficients); sc_format_asn1_entry(asn1_public_key + 0, asn1_dsa_pub_coefficients, NULL, 1); sc_format_asn1_entry(asn1_dsa_pub_coefficients + 0, key->pub.data, &key->pub.len, 1); sc_format_asn1_entry(asn1_dsa_pub_coefficients + 1, key->g.data, &key->g.len, 1); sc_format_asn1_entry(asn1_dsa_pub_coefficients + 2, key->p.data, &key->p.len, 1); sc_format_asn1_entry(asn1_dsa_pub_coefficients + 3, key->q.data, &key->q.len, 1); r = sc_asn1_encode(ctx, asn1_public_key, buf, buflen); LOG_TEST_RET(ctx, r, "ASN.1 encoding failed"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); }
int sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key, const u8 *buf, size_t buflen) { struct sc_asn1_entry asn1_public_key[2]; struct sc_asn1_entry asn1_rsa_coeff[3]; int r; sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); sc_format_asn1_entry(asn1_public_key + 0, asn1_rsa_coeff, NULL, 0); sc_copy_asn1_entry(c_asn1_rsa_pub_coefficients, asn1_rsa_coeff); sc_format_asn1_entry(asn1_rsa_coeff + 0, &key->modulus.data, &key->modulus.len, 0); sc_format_asn1_entry(asn1_rsa_coeff + 1, &key->exponent.data, &key->exponent.len, 0); r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 parsing of public key failed"); return 0; }
int sc_pkcs15_decode_cdf_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_cert_info info; struct sc_asn1_entry asn1_cred_ident[3], asn1_com_cert_attr[4], asn1_x509_cert_attr[2], asn1_type_cert_attr[2], asn1_cert[2], asn1_x509_cert_value_choice[3]; struct sc_asn1_pkcs15_object cert_obj = { obj, asn1_com_cert_attr, NULL, asn1_type_cert_attr }; sc_pkcs15_der_t *der = &info.value; u8 id_value[128]; int id_type; size_t id_value_len = sizeof(id_value); int r; sc_copy_asn1_entry(c_asn1_cred_ident, asn1_cred_ident); sc_copy_asn1_entry(c_asn1_com_cert_attr, asn1_com_cert_attr); sc_copy_asn1_entry(c_asn1_x509_cert_attr, asn1_x509_cert_attr); sc_copy_asn1_entry(c_asn1_x509_cert_value_choice, asn1_x509_cert_value_choice); sc_copy_asn1_entry(c_asn1_type_cert_attr, asn1_type_cert_attr); sc_copy_asn1_entry(c_asn1_cert, asn1_cert); sc_format_asn1_entry(asn1_cred_ident + 0, &id_type, NULL, 0); sc_format_asn1_entry(asn1_cred_ident + 1, &id_value, &id_value_len, 0); sc_format_asn1_entry(asn1_com_cert_attr + 0, &info.id, NULL, 0); sc_format_asn1_entry(asn1_com_cert_attr + 1, &info.authority, NULL, 0); sc_format_asn1_entry(asn1_com_cert_attr + 2, asn1_cred_ident, NULL, 0); sc_format_asn1_entry(asn1_x509_cert_attr + 0, asn1_x509_cert_value_choice, NULL, 0); sc_format_asn1_entry(asn1_x509_cert_value_choice + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_x509_cert_value_choice + 1, &der->value, &der->len, 0); sc_format_asn1_entry(asn1_type_cert_attr + 0, asn1_x509_cert_attr, NULL, 0); sc_format_asn1_entry(asn1_cert + 0, &cert_obj, NULL, 0); /* Fill in defaults */ memset(&info, 0, sizeof(info)); info.authority = 0; r = sc_asn1_decode(ctx, asn1_cert, *buf, *buflen, buf, buflen); /* In case of error, trash the cert value (direct coding) */ if (r < 0 && der->value) free(der->value); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed"); r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); if (r < 0) return r; obj->type = SC_PKCS15_TYPE_CERT_X509; obj->data = malloc(sizeof(info)); if (obj->data == NULL) SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); memcpy(obj->data, &info, sizeof(info)); return 0; }
static int asn1_encode_pbes2_params(sc_context_t *ctx, void *params, u8 **buf, size_t *buflen, int depth) { struct sc_asn1_entry asn1_pbes2_params[3]; struct sc_pbes2_params *info; info = (struct sc_pbes2_params *) params; sc_copy_asn1_entry(c_asn1_pbes2_params, asn1_pbes2_params); sc_format_asn1_entry(asn1_pbes2_params + 0, &info->derivation_alg, NULL, 0); sc_format_asn1_entry(asn1_pbes2_params + 1, &info->key_encr_alg, NULL, 0); return _sc_asn1_encode(ctx, asn1_pbes2_params, buf, buflen, depth + 1); }
int sc_pkcs15_encode_pubkey_ec(sc_context_t *ctx, struct sc_pkcs15_pubkey_ec *key, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; int r; sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); sc_format_asn1_entry(asn1_ec_pointQ + 0, key->ecpointQ.value, &key->ecpointQ.len, 1); r = sc_asn1_encode(ctx, asn1_ec_pointQ, buf, buflen); LOG_TEST_RET(ctx, r, "ASN.1 encoding failed"); sc_log(ctx, "EC key->ecpointQ=%p:%d *buf=%p:%d", key->ecpointQ.value, key->ecpointQ.len, *buf, *buflen); return 0; }
int sc_pkcs15_encode_enveloped_data(sc_context_t *ctx, struct sc_pkcs15_enveloped_data *data, u8 **buf, size_t *buflen) { static struct sc_object_id oid_id_data = {{ 1, 2, 840, 113549, 1, 7, 1, -1 }}; struct sc_asn1_entry asn1_enveloped_data_attr[5], asn1_content_attr[4], asn1_encr_content[2], asn1_recipients_attr[2], asn1_kekri_attr[5], asn1_kek_attr[4]; int version2 = 2, version4 = 4, r; sc_copy_asn1_entry(c_asn1_enveloped_data_attr, asn1_enveloped_data_attr); sc_copy_asn1_entry(c_asn1_content_attr, asn1_content_attr); sc_copy_asn1_entry(c_asn1_encr_content, asn1_encr_content); sc_copy_asn1_entry(c_asn1_recipients_attr, asn1_recipients_attr); sc_copy_asn1_entry(c_asn1_kekri_attr, asn1_kekri_attr); sc_copy_asn1_entry(c_asn1_kek_attr, asn1_kek_attr); sc_format_asn1_entry(asn1_enveloped_data_attr + 0, &version2, NULL, 1); sc_format_asn1_entry(asn1_enveloped_data_attr + 2, asn1_recipients_attr, NULL, 1); sc_format_asn1_entry(asn1_enveloped_data_attr + 3, asn1_content_attr, NULL, 1); sc_format_asn1_entry(asn1_content_attr + 0, &oid_id_data, NULL, 1); sc_format_asn1_entry(asn1_content_attr + 1, &data->ce_alg, NULL, 1); sc_format_asn1_entry(asn1_content_attr + 2, asn1_encr_content, NULL, 1); sc_format_asn1_entry(asn1_encr_content + 0, data->content, &data->content_len, 1); sc_format_asn1_entry(asn1_recipients_attr + 0, asn1_kekri_attr, NULL, 1); sc_format_asn1_entry(asn1_kekri_attr + 0, &version4, NULL, 1); sc_format_asn1_entry(asn1_kekri_attr + 1, asn1_kek_attr, NULL, 1); sc_format_asn1_entry(asn1_kekri_attr + 2, &data->ke_alg, NULL, 1); sc_format_asn1_entry(asn1_kekri_attr + 3, data->key, &data->key_len, 1); sc_format_asn1_entry(asn1_kek_attr + 0, &data->id, &data->id.len, 1); memset(&data, 0, sizeof(data)); r = sc_asn1_encode(ctx, asn1_enveloped_data_attr, buf, buflen); return r; }
static int sc_hsm_decode_gakp_ec(struct sc_pkcs15_card *p15card, sc_cvc_t *cvc, struct sc_pkcs15_prkey_info *key_info, struct sc_pkcs15_pubkey *pubkey) { struct sc_asn1_entry asn1_ec_pointQ[C_ASN1_EC_POINTQ_SIZE]; struct sc_pkcs15_ec_parameters *ecparams = (struct sc_pkcs15_ec_parameters *)(key_info->params.data); struct sc_ec_params *ecp; u8 *buf; size_t buflen; int r; LOG_FUNC_CALLED(p15card->card->ctx); pubkey->algorithm = SC_ALGORITHM_EC; pubkey->u.ec.params.named_curve = strdup(ecparams->named_curve); sc_pkcs15_fix_ec_parameters(p15card->card->ctx, &pubkey->u.ec.params); ecp = calloc(1, sizeof(struct sc_ec_params)); if (!ecp) { LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY); } ecp->der = malloc(ecparams->der.len); if (!ecp->der) { LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY); } ecp->der_len = ecparams->der.len; memcpy(ecp->der, ecparams->der.value, ecp->der_len); pubkey->alg_id = (struct sc_algorithm_id *)calloc(1, sizeof(struct sc_algorithm_id)); if (!pubkey->alg_id) { LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY); } pubkey->alg_id->algorithm = SC_ALGORITHM_EC; pubkey->alg_id->params = ecp; sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ); sc_format_asn1_entry(asn1_ec_pointQ + 0, cvc->publicPoint, &cvc->publicPointlen, 1); r = sc_asn1_encode(p15card->card->ctx, asn1_ec_pointQ, &pubkey->u.ec.ecpointQ.value, &pubkey->u.ec.ecpointQ.len); LOG_TEST_RET(p15card->card->ctx, r, "ASN.1 encoding failed"); LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS); }
int sc_pkcs15_encode_pubkey_gostr3410(sc_context_t *ctx, struct sc_pkcs15_pubkey_gostr3410 *key, u8 **buf, size_t *buflen) { struct sc_asn1_entry asn1_gostr3410_pub_coeff[C_ASN1_GOSTR3410_PUB_COEFFICIENTS_SIZE]; int r; LOG_FUNC_CALLED(ctx); sc_copy_asn1_entry(c_asn1_gostr3410_pub_coefficients, asn1_gostr3410_pub_coeff); sc_format_asn1_entry(asn1_gostr3410_pub_coeff + 0, key->xy.data, &key->xy.len, 1); r = sc_asn1_encode(ctx, asn1_gostr3410_pub_coeff, buf, buflen); LOG_TEST_RET(ctx, r, "ASN.1 encoding failed"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); }
int sc_sm_parse_answer(struct sc_card *card, unsigned char *resp_data, size_t resp_len, struct sm_card_response *out) { struct sc_asn1_entry asn1_sm_response[4]; unsigned char data[SC_MAX_APDU_BUFFER_SIZE]; size_t data_len = sizeof(data); unsigned char status[2] = {0, 0}; size_t status_len = sizeof(status); unsigned char mac[8]; size_t mac_len = sizeof(mac); int rv; if (!resp_data || !resp_len || !out) return SC_ERROR_INVALID_ARGUMENTS; sc_copy_asn1_entry(c_asn1_sm_response, asn1_sm_response); sc_format_asn1_entry(asn1_sm_response + 0, data, &data_len, 0); sc_format_asn1_entry(asn1_sm_response + 1, status, &status_len, 0); sc_format_asn1_entry(asn1_sm_response + 2, mac, &mac_len, 0); rv = sc_asn1_decode(card->ctx, asn1_sm_response, resp_data, resp_len, NULL, NULL); if (rv) return rv; if (asn1_sm_response[0].flags & SC_ASN1_PRESENT) { if (data_len > sizeof(out->data)) return SC_ERROR_BUFFER_TOO_SMALL; memcpy(out->data, data, data_len); out->data_len = data_len; } if (asn1_sm_response[1].flags & SC_ASN1_PRESENT) { if (!status[0]) return SC_ERROR_INVALID_DATA; out->sw1 = status[0]; out->sw2 = status[1]; } if (asn1_sm_response[2].flags & SC_ASN1_PRESENT) { memcpy(out->mac, mac, mac_len); out->mac_len = mac_len; } return SC_SUCCESS; }