diff --git a/src/libopensc/card-isoApplet.c b/src/libopensc/card-isoApplet.c index 131ac08f..d3364cb1 100644 --- a/src/libopensc/card-isoApplet.c +++ b/src/libopensc/card-isoApplet.c @@ -47,6 +47,7 @@ struct isoApplet_drv_data * If ECC is being used, the signatures generated by the card * have to be modified. */ unsigned int sec_env_alg_ref; + unsigned int sec_env_ec_field_length; }; #define DRVDATA(card) ((struct isoApplet_drv_data *) ((card)->drv_data)) @@ -191,16 +192,14 @@ isoApplet_init(sc_card_t *card) LOG_FUNC_CALLED(card->ctx); - drvdata=malloc(sizeof(*drvdata)); + drvdata=calloc(1, sizeof(*drvdata)); if (!drvdata) LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); - memset(drvdata, 0, sizeof(*drvdata)); - drvdata->sec_env_alg_ref = 0; card->drv_data = drvdata; card->cla = 0x00; - /* ECDSA + /* ECDSA * Curves supported by the pkcs15-init driver are indicated per curve. This * should be kept in sync with the explicit parameters in the pkcs15-init * driver. */ @@ -210,31 +209,31 @@ isoApplet_init(sc_card_t *card) ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE; ext_flags |= SC_ALGORITHM_EXT_EC_F_P; /* secp192r1, prime192r1, ansiX9p192r1*/ - r = sc_format_oid(&curve_oid, "1.2.840.10045.3.1.1"); + r = sc_format_oid(&curve_oid, "1.2.840.10045.3.1.1"); LOG_TEST_RET(card->ctx, r, "Error obtaining EC curve OID"); _sc_card_add_ec_alg(card, 192, flags, ext_flags, &curve_oid); /* prime256v1, secp256r1, ansiX9p256r1 */ - r = sc_format_oid(&curve_oid, "1.2.840.10045.3.1.7"); + r = sc_format_oid(&curve_oid, "1.2.840.10045.3.1.7"); LOG_TEST_RET(card->ctx, r, "Error obtaining EC curve OID"); _sc_card_add_ec_alg(card, 256, flags, ext_flags, &curve_oid); /* secp384r1, prime384v1, ansiX9p384r1 */ - r = sc_format_oid(&curve_oid, "1.3.132.0.34"); + r = sc_format_oid(&curve_oid, "1.3.132.0.34"); LOG_TEST_RET(card->ctx, r, "Error obtaining EC curve OID"); _sc_card_add_ec_alg(card, 384, flags, ext_flags, &curve_oid); /* brainpoolP192r1 */ - r = sc_format_oid(&curve_oid, "1.3.36.3.3.2.8.1.1.3"); + r = sc_format_oid(&curve_oid, "1.3.36.3.3.2.8.1.1.3"); LOG_TEST_RET(card->ctx, r, "Error obtaining EC curve OID"); _sc_card_add_ec_alg(card, 192, flags, ext_flags, &curve_oid); /* brainpoolP224r1 */ - r = sc_format_oid(&curve_oid, "1.3.36.3.3.2.8.1.1.5"); + r = sc_format_oid(&curve_oid, "1.3.36.3.3.2.8.1.1.5"); LOG_TEST_RET(card->ctx, r, "Error obtaining EC curve OID"); _sc_card_add_ec_alg(card, 224, flags, ext_flags, &curve_oid); /* brainpoolP256r1 */ - r = sc_format_oid(&curve_oid, "1.3.36.3.3.2.8.1.1.7"); + r = sc_format_oid(&curve_oid, "1.3.36.3.3.2.8.1.1.7"); LOG_TEST_RET(card->ctx, r, "Error obtaining EC curve OID"); _sc_card_add_ec_alg(card, 256, flags, ext_flags, &curve_oid); /* brainpoolP320r1 */ - r = sc_format_oid(&curve_oid, "1.3.36.3.3.2.8.1.1.9"); + r = sc_format_oid(&curve_oid, "1.3.36.3.3.2.8.1.1.9"); LOG_TEST_RET(card->ctx, r, "Error obtaining EC curve OID"); _sc_card_add_ec_alg(card, 320, flags, ext_flags, &curve_oid); @@ -1106,6 +1105,7 @@ isoApplet_set_security_env(sc_card_t *card, if( env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW ) { drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_ECDSA; + drvdata->sec_env_ec_field_length = env->algorithm_ref; } else { @@ -1190,38 +1190,41 @@ isoApplet_compute_signature(struct sc_card *card, const u8 *data, size_t datalen, u8 *out, size_t outlen) { + struct sc_context *ctx = card->ctx; struct isoApplet_drv_data *drvdata = DRVDATA(card); int r; - LOG_FUNC_CALLED(card->ctx); + LOG_FUNC_CALLED(ctx); r = iso_ops->compute_signature(card, data, datalen, out, outlen); if(r < 0) { - LOG_FUNC_RETURN(card->ctx, r); + LOG_FUNC_RETURN(ctx, r); } - /* If we used ECDSA for the signature op, OpenSC thinks it has to - * convert it to {sequence{integer,integer}} which is already done by the - * card actually. - * To fix this, I strip the {sequence, sequence} structual information, - * which will be added again later.*/ + /* If ECDSA was used, the ASN.1 sequence of integers R,S returned by the + * card needs to be converted to the raw concatenation of R,S for PKCS#11. */ if(drvdata->sec_env_alg_ref == ISOAPPLET_ALG_REF_ECDSA) { u8* p = NULL; - size_t len; + size_t len = drvdata->sec_env_ec_field_length / 4; - r = sc_asn1_sig_value_sequence_to_rs(card->ctx, out, r, &p, &len); - if(r < 0) { - if(p) - free(p); - LOG_FUNC_RETURN(card->ctx, r); + if (len > outlen) + LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL); + + p = calloc(1,len); + if (!p) + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + + r = sc_asn1_sig_value_sequence_to_rs(ctx, out, r, p, len); + if (!r) { + memcpy(out, p, len); + r = len; } - memcpy(out, p, len); - r = len; + free(p); } - LOG_FUNC_RETURN(card->ctx, r); + LOG_FUNC_RETURN(ctx, r); } static struct sc_card_driver *sc_get_driver(void)