integrated SM into pace

git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@53 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2010-04-01 05:52:37 +00:00
parent ae3e7ae862
commit 9d573d0398
4 changed files with 129 additions and 64 deletions

View File

@@ -1289,7 +1289,7 @@ int ccid_testpace()
} }
if (sc_card_valid(card_in_slot[i])) { if (sc_card_valid(card_in_slot[i])) {
return pace_test(ctx, card_in_slot[i]); return pace_test(card_in_slot[i]);
} }
} }

View File

@@ -17,6 +17,7 @@
* ccid. If not, see <http://www.gnu.org/licenses/>. * ccid. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "pace.h" #include "pace.h"
#include "sm.h"
#include <opensc/log.h> #include <opensc/log.h>
#include <openssl/asn1.h> #include <openssl/asn1.h>
#include <openssl/asn1t.h> #include <openssl/asn1t.h>
@@ -135,16 +136,16 @@ IMPLEMENT_ASN1_FUNCTIONS(PACE_GEN_AUTH_R)
#ifdef NO_PACE #ifdef NO_PACE
inline int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card, inline int GetReadersPACECapabilities(sc_card_t *card,
const __u8 *in, __u8 **out, size_t *outlen) { const __u8 *in, __u8 **out, size_t *outlen) {
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
} }
inline int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card, inline int EstablishPACEChannel(sc_card_t *card, const __u8 *in,
const __u8 *in, __u8 **out, size_t *outlen) { __u8 **out, size_t *outlen, struct sm_ctx *sm_ctx) {
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
} }
int pace_test(sc_context_t *ctx, sc_card_t *card) { int pace_test(sc_card_t *card) {
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
} }
#else #else
@@ -173,14 +174,14 @@ void bin_log(sc_context_t *ctx, const char *label, const u8 *data, size_t len)
label, len, buf); label, len, buf);
} }
int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card, int GetReadersPACECapabilities(sc_card_t *card,
const __u8 *in, __u8 **out, size_t *outlen) { const __u8 *in, __u8 **out, size_t *outlen) {
if (!out || !outlen) if (!out || !outlen)
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS);
__u8 *result = realloc(*out, 2); __u8 *result = realloc(*out, 2);
if (!result) if (!result)
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY);
*out = result; *out = result;
*outlen = 2; *outlen = 2;
@@ -190,11 +191,11 @@ int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card,
/* BitMap */ /* BitMap */
*result = PACE_BITMAP_PACE|PACE_BITMAP_EID; *result = PACE_BITMAP_PACE|PACE_BITMAP_EID;
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
} }
/** select and read EF.CardAccess */ /** select and read EF.CardAccess */
int get_ef_card_access(sc_context_t *ctx, sc_card_t *card, int get_ef_card_access(sc_card_t *card,
__u8 **ef_cardaccess, size_t *length_ef_cardaccess) __u8 **ef_cardaccess, size_t *length_ef_cardaccess)
{ {
int r; int r;
@@ -203,13 +204,13 @@ int get_ef_card_access(sc_context_t *ctx, sc_card_t *card,
__u8 *p; __u8 *p;
memset(&path, 0, sizeof path); memset(&path, 0, sizeof path);
SC_TEST_RET(ctx, sc_append_file_id(&path, FID_EF_CARDACCESS), SC_TEST_RET(card->ctx, sc_append_file_id(&path, FID_EF_CARDACCESS),
"Could not create path object."); "Could not create path object.");
SC_TEST_RET(ctx, sc_concatenate_path(&path, sc_get_mf_path(), &path), SC_TEST_RET(card->ctx, sc_concatenate_path(&path, sc_get_mf_path(), &path),
"Could not create path object."); "Could not create path object.");
memset(&file, 0, sizeof file); memset(&file, 0, sizeof file);
SC_TEST_RET(ctx, sc_select_file(card, &path, &file), SC_TEST_RET(card->ctx, sc_select_file(card, &path, &file),
"Could not select EF.CardAccess."); "Could not select EF.CardAccess.");
ssc++; ssc++;
*length_ef_cardaccess = 0; *length_ef_cardaccess = 0;
@@ -217,7 +218,7 @@ int get_ef_card_access(sc_context_t *ctx, sc_card_t *card,
while(1) { while(1) {
p = realloc(*ef_cardaccess, *length_ef_cardaccess + maxresp); p = realloc(*ef_cardaccess, *length_ef_cardaccess + maxresp);
if (!p) if (!p)
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY);
*ef_cardaccess = p; *ef_cardaccess = p;
r = sc_read_binary(card, *length_ef_cardaccess, r = sc_read_binary(card, *length_ef_cardaccess,
@@ -229,7 +230,7 @@ int get_ef_card_access(sc_context_t *ctx, sc_card_t *card,
break; break;
} }
SC_TEST_RET(ctx, r, "Could not read EF.CardAccess."); SC_TEST_RET(card->ctx, r, "Could not read EF.CardAccess.");
*length_ef_cardaccess += r; *length_ef_cardaccess += r;
} }
@@ -237,12 +238,12 @@ int get_ef_card_access(sc_context_t *ctx, sc_card_t *card,
/* test cards only return an empty FCI template, /* test cards only return an empty FCI template,
* so we can't determine any file proberties */ * so we can't determine any file proberties */
if (*length_ef_cardaccess < file->size) if (*length_ef_cardaccess < file->size)
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_FILE_TOO_SMALL); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_FILE_TOO_SMALL);
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
} }
int pace_mse_set_at(sc_context_t *ctx, sc_card_t *card, int pace_mse_set_at(sc_card_t *card,
int protocol, int secret_key, int reference) int protocol, int secret_key, int reference)
{ {
sc_apdu_t apdu; sc_apdu_t apdu;
@@ -286,10 +287,10 @@ int pace_mse_set_at(sc_context_t *ctx, sc_card_t *card,
/* The tag/length for the sequence (0x30) is omitted in the command apdu. */ /* The tag/length for the sequence (0x30) is omitted in the command apdu. */
/* FIXME is there a OpenSSL way to get the value only or even a define for /* FIXME is there a OpenSSL way to get the value only or even a define for
* the tag? */ * the tag? */
apdu.data = sc_asn1_find_tag(ctx, d, r, 0x30, &apdu.datalen); apdu.data = sc_asn1_find_tag(card->ctx, d, r, 0x30, &apdu.datalen);
apdu.lc = apdu.datalen; apdu.lc = apdu.datalen;
bin_log(ctx, "MSE:Set AT command data", apdu.data, apdu.datalen); bin_log(card->ctx, "MSE:Set AT command data", apdu.data, apdu.datalen);
r = sc_transmit_apdu(card, &apdu); r = sc_transmit_apdu(card, &apdu);
ssc++; ssc++;
@@ -297,7 +298,7 @@ int pace_mse_set_at(sc_context_t *ctx, sc_card_t *card,
goto err; goto err;
if (apdu.resplen) { if (apdu.resplen) {
sc_error(ctx, "MSE:Set AT response data should be empty"); sc_error(card->ctx, "MSE:Set AT response data should be empty");
r = SC_ERROR_UNKNOWN_DATA_RECEIVED; r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
goto err; goto err;
} }
@@ -340,10 +341,10 @@ err:
if (apdu.resplen) if (apdu.resplen)
free(apdu.resp); free(apdu.resp);
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, r); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
} }
int pace_gen_auth(sc_context_t *ctx, sc_card_t *card, int pace_gen_auth(sc_card_t *card,
int step, const u8 *in, size_t in_len, u8 **out, size_t *out_len) int step, const u8 *in, size_t in_len, u8 **out, size_t *out_len)
{ {
sc_apdu_t apdu; sc_apdu_t apdu;
@@ -409,7 +410,7 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
apdu.datalen = r; apdu.datalen = r;
apdu.lc = r; apdu.lc = r;
bin_log(ctx, "General authenticate command data", apdu.data, apdu.datalen); bin_log(card->ctx, "General authenticate command data", apdu.data, apdu.datalen);
/* sanity checks in sc_transmit_apdu forbid case 4 apdus with le == 0 */ /* sanity checks in sc_transmit_apdu forbid case 4 apdus with le == 0 */
apdu.resplen = maxresp; apdu.resplen = maxresp;
@@ -423,11 +424,11 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
if (r < 0) if (r < 0)
goto err; goto err;
bin_log(ctx, "General authenticate response data", apdu.resp, apdu.resplen); bin_log(card->ctx, "General authenticate response data", apdu.resp, apdu.resplen);
if (!d2i_PACE_GEN_AUTH_R(&r_data, if (!d2i_PACE_GEN_AUTH_R(&r_data,
(const unsigned char **) &apdu.resp, apdu.resplen)) { (const unsigned char **) &apdu.resp, apdu.resplen)) {
sc_error(ctx, "Could not parse general authenticate response data."); sc_error(card->ctx, "Could not parse general authenticate response data.");
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
goto err; goto err;
} }
@@ -438,7 +439,7 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
|| r_data->mapping_data || r_data->mapping_data
|| r_data->eph_pub_key || r_data->eph_pub_key
|| r_data->auth_token) { || r_data->auth_token) {
sc_error(ctx, "Response data of general authenticate for " sc_error(card->ctx, "Response data of general authenticate for "
"step %d should (only) contain the " "step %d should (only) contain the "
"encrypted nonce.", step); "encrypted nonce.", step);
r = SC_ERROR_UNKNOWN_DATA_RECEIVED; r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
@@ -452,7 +453,7 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
|| !r_data->mapping_data || !r_data->mapping_data
|| r_data->eph_pub_key || r_data->eph_pub_key
|| r_data->auth_token) { || r_data->auth_token) {
sc_error(ctx, "Response data of general authenticate for " sc_error(card->ctx, "Response data of general authenticate for "
"step %d should (only) contain the " "step %d should (only) contain the "
"mapping data.", step); "mapping data.", step);
r = SC_ERROR_UNKNOWN_DATA_RECEIVED; r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
@@ -466,7 +467,7 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
|| r_data->mapping_data || r_data->mapping_data
|| !r_data->eph_pub_key || !r_data->eph_pub_key
|| r_data->auth_token) { || r_data->auth_token) {
sc_error(ctx, "Response data of general authenticate for " sc_error(card->ctx, "Response data of general authenticate for "
"step %d should (only) contain the " "step %d should (only) contain the "
"ephemeral public key.", step); "ephemeral public key.", step);
r = SC_ERROR_UNKNOWN_DATA_RECEIVED; r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
@@ -480,7 +481,7 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
|| r_data->mapping_data || r_data->mapping_data
|| r_data->eph_pub_key || r_data->eph_pub_key
|| !r_data->auth_token) { || !r_data->auth_token) {
sc_error(ctx, "Response data of general authenticate for " sc_error(card->ctx, "Response data of general authenticate for "
"step %d should (only) contain the " "step %d should (only) contain the "
"authentication token.", step); "authentication token.", step);
r = SC_ERROR_UNKNOWN_DATA_RECEIVED; r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
@@ -529,7 +530,7 @@ err:
//if (apdu.resplen) //if (apdu.resplen)
//free(apdu.resp); //free(apdu.resp);
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, r); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
} }
PACE_SEC * PACE_SEC *
@@ -585,12 +586,13 @@ void debug_ossl(sc_context_t *ctx) {
} }
} }
int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card, int EstablishPACEChannel(sc_card_t *card, const __u8 *in,
const __u8 *in, __u8 **out, size_t *outlen) __u8 **out, size_t *outlen, struct sm_ctx *sm_ctx)
{ {
__u8 pin_id; __u8 pin_id;
size_t length_chat, length_pin, length_cert_desc, length_ef_cardaccess; size_t length_chat, length_pin, length_cert_desc, length_ef_cardaccess;
const __u8 *chat, *pin, *certificate_description; const __u8 *chat, *pin, *certificate_description;
u8 *buf;
__u8 *ef_cardaccess = NULL; __u8 *ef_cardaccess = NULL;
PACEInfo *info = NULL; PACEInfo *info = NULL;
PACEDomainParameterInfo *static_dp = NULL, *eph_dp = NULL; PACEDomainParameterInfo *static_dp = NULL, *eph_dp = NULL;
@@ -602,7 +604,7 @@ int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card,
int r; int r;
if (!in || !out || !outlen) if (!in || !out || !outlen)
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS);
pin_id = *in; pin_id = *in;
in++; in++;
@@ -624,42 +626,42 @@ int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card,
enc_nonce = BUF_MEM_new(); enc_nonce = BUF_MEM_new();
if (!enc_nonce) { if (!enc_nonce) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
r = get_ef_card_access(ctx, card, &ef_cardaccess, &length_ef_cardaccess); r = get_ef_card_access(card, &ef_cardaccess, &length_ef_cardaccess);
if (r < 0) { if (r < 0) {
goto err; goto err;
} }
bin_log(ctx, "EF.CardAccess", ef_cardaccess, length_ef_cardaccess); bin_log(card->ctx, "EF.CardAccess", ef_cardaccess, length_ef_cardaccess);
if (!parse_ef_card_access(ef_cardaccess, length_ef_cardaccess, if (!parse_ef_card_access(ef_cardaccess, length_ef_cardaccess,
&info, &static_dp)) { &info, &static_dp)) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
r = pace_mse_set_at(ctx, card, info->protocol, pin_id, 1); r = pace_mse_set_at(card, info->protocol, pin_id, 1);
if (r < 0) { if (r < 0) {
goto err; goto err;
} }
r = pace_gen_auth(ctx, card, 1, NULL, 0, (u8 **) &enc_nonce->data, r = pace_gen_auth(card, 1, NULL, 0, (u8 **) &enc_nonce->data,
&enc_nonce->length); &enc_nonce->length);
if (r < 0) { if (r < 0) {
goto err; goto err;
} }
bin_log(ctx, "Encrypted nonce from MRTD", (u8 *)enc_nonce->data, enc_nonce->length); bin_log(card->ctx, "Encrypted nonce from MRTD", (u8 *)enc_nonce->data, enc_nonce->length);
enc_nonce->max = enc_nonce->length; enc_nonce->max = enc_nonce->length;
sec = get_psec(card, (char *) pin, length_pin, pin_id); sec = get_psec(card, (char *) pin, length_pin, pin_id);
if (!sec) { if (!sec) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
pctx = PACE_CTX_new(); pctx = PACE_CTX_new();
if (!pctx || !PACE_CTX_init(pctx, info)) { if (!pctx || !PACE_CTX_init(pctx, info)) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
pctx->tr_version = PACE_TR_VERSION_2_01; pctx->tr_version = PACE_TR_VERSION_2_01;
@@ -670,38 +672,38 @@ int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card,
mdata = PACE_STEP3A_generate_mapping_data(static_dp, pctx); mdata = PACE_STEP3A_generate_mapping_data(static_dp, pctx);
if (!nonce || !mdata || !mdata_opp) { if (!nonce || !mdata || !mdata_opp) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
r = pace_gen_auth(ctx, card, 2, (u8 *) mdata->data, mdata->length, r = pace_gen_auth(card, 2, (u8 *) mdata->data, mdata->length,
(u8 **) &mdata_opp->data, &mdata_opp->length); (u8 **) &mdata_opp->data, &mdata_opp->length);
if (r < 0) { if (r < 0) {
goto err; goto err;
} }
mdata_opp->max = mdata_opp->length; mdata_opp->max = mdata_opp->length;
bin_log(ctx, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length); bin_log(card->ctx, "Mapping data from MRTD", (u8 *) mdata_opp->data, mdata_opp->length);
eph_dp = PACE_STEP3A_map_dp(static_dp, pctx, nonce, mdata_opp); eph_dp = PACE_STEP3A_map_dp(static_dp, pctx, nonce, mdata_opp);
pub = PACE_STEP3B_generate_ephemeral_key(eph_dp, pctx); pub = PACE_STEP3B_generate_ephemeral_key(eph_dp, pctx);
pub_opp = BUF_MEM_new(); pub_opp = BUF_MEM_new();
if (!eph_dp || !pub || !pub_opp) { if (!eph_dp || !pub || !pub_opp) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
r = pace_gen_auth(ctx, card, 3, (u8 *) pub->data, pub->length, r = pace_gen_auth(card, 3, (u8 *) pub->data, pub->length,
(u8 **) &pub_opp->data, &pub_opp->length); (u8 **) &pub_opp->data, &pub_opp->length);
if (r < 0) { if (r < 0) {
goto err; goto err;
} }
pub_opp->max = pub_opp->length; pub_opp->max = pub_opp->length;
bin_log(ctx, "Public key from MRTD", (u8 *) pub_opp->data, pub_opp->length); bin_log(card->ctx, "Public key from MRTD", (u8 *) pub_opp->data, pub_opp->length);
key = PACE_STEP3B_compute_ephemeral_key(eph_dp, pctx, pub_opp); key = PACE_STEP3B_compute_ephemeral_key(eph_dp, pctx, pub_opp);
if (!key || if (!key ||
!PACE_STEP3C_derive_keys(key, pctx, info, &k_mac, &k_enc)) { !PACE_STEP3C_derive_keys(key, pctx, info, &k_mac, &k_enc)) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
token = PACE_STEP3D_compute_authentication_token(pctx, token = PACE_STEP3D_compute_authentication_token(pctx,
@@ -709,25 +711,49 @@ int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card,
token_opp = BUF_MEM_new(); token_opp = BUF_MEM_new();
if (!token || !token_opp) { if (!token || !token_opp) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
r = pace_gen_auth(ctx, card, 4, (u8 *) token->data, token->length, r = pace_gen_auth(card, 4, (u8 *) token->data, token->length,
(u8 **) &token_opp->data, &token_opp->length); (u8 **) &token_opp->data, &token_opp->length);
if (r < 0) { if (r < 0) {
goto err; goto err;
} }
token_opp->max = token_opp->length; token_opp->max = token_opp->length;
bin_log(ctx, "Authentication token from MRTD", (u8 *) token_opp->data, token_opp->length); bin_log(card->ctx, "Authentication token from MRTD", (u8 *) token_opp->data, token_opp->length);
if (!PACE_STEP3D_verify_authentication_token(pctx, if (!PACE_STEP3D_verify_authentication_token(pctx,
eph_dp, info, k_mac, token_opp)) { eph_dp, info, k_mac, token_opp)) {
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
debug_ossl(ctx); debug_ossl(card->ctx);
goto err; goto err;
} }
/* XXX parse CHAT to check role of terminal */ /* XXX parse CHAT to check role of terminal */
buf = realloc(sm_ctx->key_mac, k_mac->length);
if (!buf) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
sm_ctx->key_mac = buf;
memcpy(sm_ctx->key_mac, k_mac->data, k_mac->length);
sm_ctx->key_mac_len = k_mac->length;
buf = realloc(sm_ctx->key_enc, k_enc->length);
if (!buf) {
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
sm_ctx->key_enc = buf;
memcpy(sm_ctx->key_enc, k_enc->data, k_enc->length);
sm_ctx->key_enc_len = k_enc->length;
sm_ctx->cipher = pctx->cipher;
sm_ctx->cipher_ctx = pctx->cipher_ctx;
sm_ctx->cipher_engine = pctx->cipher_engine;
sm_ctx->md = pctx->md;
sm_ctx->md_ctx = pctx->md_ctx;
sm_ctx->md_engine = pctx->md_engine;
err: err:
if (info) if (info)
@@ -771,14 +797,16 @@ err:
if (pctx) if (pctx)
PACE_CTX_clear_free(pctx); PACE_CTX_clear_free(pctx);
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, r); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
} }
int pace_test(sc_context_t *ctx, sc_card_t *card) int pace_test(sc_card_t *card)
{ {
__u8 in[16]; __u8 in[16];
__u8 *out = NULL; __u8 *out = NULL;
size_t outlen; size_t outlen;
struct sm_ctx sm;
memset(&sm, 0, sizeof(sm));
in[0] = PACE_CAN; // pin_id in[0] = PACE_CAN; // pin_id
in[1] = 0; // length_chat in[1] = 0; // length_chat
@@ -792,7 +820,8 @@ int pace_test(sc_context_t *ctx, sc_card_t *card)
in[9] = 0; // length_cert_desc in[9] = 0; // length_cert_desc
in[10]= 0; // length_cert_desc in[10]= 0; // length_cert_desc
return EstablishPACEChannel(ctx, card, in, &out, &outlen); SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR,
EstablishPACEChannel(card, in, &out, &outlen, &sm));
} }
#endif #endif

View File

@@ -19,6 +19,7 @@
#ifndef _PACE_H #ifndef _PACE_H
#define _PACE_H #define _PACE_H
#include "sm.h"
#include <linux/usb/ch9.h> #include <linux/usb/ch9.h>
#include <opensc/opensc.h> #include <opensc/opensc.h>
@@ -39,11 +40,11 @@ extern "C" {
#define MAX_EF_CARDACCESS 2048 #define MAX_EF_CARDACCESS 2048
int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card, const __u8 int GetReadersPACECapabilities(sc_card_t *card, const __u8
*in, __u8 **out, size_t *outlen); *in, __u8 **out, size_t *outlen);
int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card, const __u8 *in, int EstablishPACEChannel(sc_card_t *card, const __u8 *in,
__u8 **out, size_t *outlen); __u8 **out, size_t *outlen, struct sm_ctx *sm_ctx);
int pace_test(sc_context_t *ctx, sc_card_t *card); int pace_test(sc_card_t *card);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -1,6 +1,31 @@
/*
* Copyright (C) 2010 Frank Morgner
*
* This file is part of ccid.
*
* ccid is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* ccid is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* ccid. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SM_H
#define _SM_H
#include <opensc/opensc.h> #include <opensc/opensc.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SM_ISO_PADDING 0x01 #define SM_ISO_PADDING 0x01
#define SM_NO_PADDING 0x02 #define SM_NO_PADDING 0x02
@@ -20,3 +45,13 @@ struct sm_ctx {
EVP_MD_CTX * md_ctx; EVP_MD_CTX * md_ctx;
ENGINE *md_engine; ENGINE *md_engine;
}; };
int sm_encrypt(const struct sm_ctx *ctx, sc_card_t *card,
const sc_apdu_t *apdu, sc_apdu_t *sm_apdu);
int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
const sc_apdu_t *sm_apdu, sc_apdu_t *apdu);
#ifdef __cplusplus
}
#endif
#endif