diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 6e7c5953..e14d5409 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -869,6 +869,10 @@ static int myeid_set_security_env(struct sc_card *card, { tmp.algorithm_ref = 0x00; } + + if ((tmp.algorithm_flags & SC_ALGORITHM_AES_CBC_PAD) == SC_ALGORITHM_AES_CBC_PAD) + tmp.algorithm_ref |= 0x80; /* set PKCS#7 padding */ + /* from this point, there's no difference to RSA SE */ return myeid_set_security_env_rsa(card, &tmp, se_num); } @@ -1267,7 +1271,7 @@ static int myeid_wrap_key(struct sc_card *card, u8 *out, size_t outlen) sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x84, 0x00); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.le = outlen; + apdu.le = 0; apdu.lc = 0; r = sc_transmit_apdu(card, &apdu); @@ -1325,7 +1329,7 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra apdu.resplen = sizeof(rbuf); apdu.le = crgram_len; - if (crgram_len == 256) + if (crgram_len == 256 && p2 == 0x86) { apdu.le = 0; /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ @@ -1352,10 +1356,10 @@ static int myeid_unwrap_key(struct sc_card *card, const u8 *crgram, size_t crgra LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { - if (crgram_len == 256) + if (crgram_len == 256 && p2 == 0x86) /* with symmetric crypto, we support only single apdu unwrap for now */ { sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, - 0x2A, 0x00, 0x86); + 0x2A, 0x00, p2); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = crgram_len; diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 0ed164e0..35b5b5d4 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -426,7 +426,7 @@ int sc_pkcs15_unwrap(struct sc_pkcs15_card *p15card, LOG_TEST_RET(ctx, r, "cannot encode security operation flags"); senv.algorithm_flags = sec_flags; - if ((sec_flags & SC_ALGORITHM_AES_CBC & SC_ALGORITHM_AES_CBC_PAD) > 0) { + if ((sec_flags & (SC_ALGORITHM_AES_CBC | SC_ALGORITHM_AES_CBC_PAD)) > 0) { senv_param = (sc_sec_env_param_t) { SC_SEC_ENV_PARAM_IV, (u8*) param, paramlen }; LOG_TEST_RET(ctx, sec_env_add_param(&senv, &senv_param), "failed to add IV to security environment"); } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index fb1f4a63..2ec9f80a 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2198,12 +2198,21 @@ out: return rv; } -/* TODO Only Session secret key objects are supported for now +/* + * Secret key objects can be stored on card, if the card supports them + * * Session objects have CKA_TOKEN=false + * + * CKA_TOKEN = FALSE can mean two things: + * 1. If the card supports on card session objects, the object is stored on card for duration of the PKCS#11 session. + * Depending on card implementation, it can be automatically deleted during the card's reset. + * This kind of objects are not written to the PKCS#15 directory file. + * 2. If the card doesn't support on card session objects, a CKA_TOKEN = FALSE object is stored only in OpenSC's memory. + + * This is used by the C_DeriveKey with ECDH to hold the * key, and the calling application can then retrieve tha attributes as needed. - * TODO If a card can support secret key objects on the card, this - * code will need to be expanded. + * . */ static CK_RV pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile, @@ -2348,10 +2357,11 @@ pkcs15_create_secret_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile skey_info->data.len = args.key.data_len; skey_info->value_len = args.value_len; /* callers preferred length */ args.key.data = NULL; + key_obj->session_object = 1; } else { if(_token == FALSE) - args.session_object = 1; /* store the object on card for duration of the session. */ + args.session_object = 1; /* store the object on card for duration of the session. */ rc = sc_pkcs15init_store_secret_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) { @@ -4752,9 +4762,8 @@ pkcs15_skey_get_attribute(struct sc_pkcs11_session *session, *(CK_OBJECT_CLASS*)attr->pValue = CKO_SECRET_KEY; break; case CKA_TOKEN: - /*TODO DEE change if on card skeys are supported */ check_attribute_buffer(attr, sizeof(CK_BBOOL)); - *(CK_BBOOL*)attr->pValue = FALSE; + *(CK_BBOOL*)attr->pValue = skey->base.p15_object->session_object == 0; break; case CKA_PRIVATE: check_attribute_buffer(attr, sizeof(CK_BBOOL));