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:
@@ -1289,7 +1289,7 @@ int ccid_testpace()
|
||||
}
|
||||
|
||||
if (sc_card_valid(card_in_slot[i])) {
|
||||
return pace_test(ctx, card_in_slot[i]);
|
||||
return pace_test(card_in_slot[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
147
ccid/pace.c
147
ccid/pace.c
@@ -17,6 +17,7 @@
|
||||
* ccid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "pace.h"
|
||||
#include "sm.h"
|
||||
#include <opensc/log.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/asn1t.h>
|
||||
@@ -135,16 +136,16 @@ IMPLEMENT_ASN1_FUNCTIONS(PACE_GEN_AUTH_R)
|
||||
|
||||
|
||||
#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) {
|
||||
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,
|
||||
const __u8 *in, __u8 **out, size_t *outlen) {
|
||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
|
||||
inline int EstablishPACEChannel(sc_card_t *card, const __u8 *in,
|
||||
__u8 **out, size_t *outlen, struct sm_ctx *sm_ctx) {
|
||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
int pace_test(sc_context_t *ctx, sc_card_t *card) {
|
||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
|
||||
int pace_test(sc_card_t *card) {
|
||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -173,14 +174,14 @@ void bin_log(sc_context_t *ctx, const char *label, const u8 *data, size_t len)
|
||||
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) {
|
||||
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);
|
||||
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;
|
||||
*outlen = 2;
|
||||
|
||||
@@ -190,11 +191,11 @@ int GetReadersPACECapabilities(sc_context_t *ctx, sc_card_t *card,
|
||||
/* BitMap */
|
||||
*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 */
|
||||
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)
|
||||
{
|
||||
int r;
|
||||
@@ -203,13 +204,13 @@ int get_ef_card_access(sc_context_t *ctx, sc_card_t *card,
|
||||
__u8 *p;
|
||||
|
||||
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.");
|
||||
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.");
|
||||
|
||||
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.");
|
||||
ssc++;
|
||||
*length_ef_cardaccess = 0;
|
||||
@@ -217,7 +218,7 @@ int get_ef_card_access(sc_context_t *ctx, sc_card_t *card,
|
||||
while(1) {
|
||||
p = realloc(*ef_cardaccess, *length_ef_cardaccess + maxresp);
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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,
|
||||
* so we can't determine any file proberties */
|
||||
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)
|
||||
{
|
||||
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. */
|
||||
/* FIXME is there a OpenSSL way to get the value only or even a define for
|
||||
* 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;
|
||||
|
||||
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);
|
||||
ssc++;
|
||||
@@ -297,7 +298,7 @@ int pace_mse_set_at(sc_context_t *ctx, sc_card_t *card,
|
||||
goto err;
|
||||
|
||||
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;
|
||||
goto err;
|
||||
}
|
||||
@@ -340,10 +341,10 @@ err:
|
||||
if (apdu.resplen)
|
||||
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)
|
||||
{
|
||||
sc_apdu_t apdu;
|
||||
@@ -409,7 +410,7 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
|
||||
apdu.datalen = 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 */
|
||||
apdu.resplen = maxresp;
|
||||
@@ -423,11 +424,11 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
|
||||
if (r < 0)
|
||||
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,
|
||||
(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;
|
||||
goto err;
|
||||
}
|
||||
@@ -438,7 +439,7 @@ int pace_gen_auth(sc_context_t *ctx, sc_card_t *card,
|
||||
|| r_data->mapping_data
|
||||
|| r_data->eph_pub_key
|
||||
|| 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 "
|
||||
"encrypted nonce.", step);
|
||||
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->eph_pub_key
|
||||
|| 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 "
|
||||
"mapping data.", step);
|
||||
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->eph_pub_key
|
||||
|| 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 "
|
||||
"ephemeral public key.", step);
|
||||
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->eph_pub_key
|
||||
|| !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 "
|
||||
"authentication token.", step);
|
||||
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||
@@ -529,7 +530,7 @@ err:
|
||||
//if (apdu.resplen)
|
||||
//free(apdu.resp);
|
||||
|
||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, r);
|
||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
||||
}
|
||||
|
||||
PACE_SEC *
|
||||
@@ -585,12 +586,13 @@ void debug_ossl(sc_context_t *ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card,
|
||||
const __u8 *in, __u8 **out, size_t *outlen)
|
||||
int EstablishPACEChannel(sc_card_t *card, const __u8 *in,
|
||||
__u8 **out, size_t *outlen, struct sm_ctx *sm_ctx)
|
||||
{
|
||||
__u8 pin_id;
|
||||
size_t length_chat, length_pin, length_cert_desc, length_ef_cardaccess;
|
||||
const __u8 *chat, *pin, *certificate_description;
|
||||
u8 *buf;
|
||||
__u8 *ef_cardaccess = NULL;
|
||||
PACEInfo *info = NULL;
|
||||
PACEDomainParameterInfo *static_dp = NULL, *eph_dp = NULL;
|
||||
@@ -602,7 +604,7 @@ int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card,
|
||||
int r;
|
||||
|
||||
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;
|
||||
in++;
|
||||
@@ -624,42 +626,42 @@ int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card,
|
||||
enc_nonce = BUF_MEM_new();
|
||||
if (!enc_nonce) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
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) {
|
||||
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,
|
||||
&info, &static_dp)) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
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) {
|
||||
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);
|
||||
if (r < 0) {
|
||||
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;
|
||||
|
||||
sec = get_psec(card, (char *) pin, length_pin, pin_id);
|
||||
if (!sec) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
goto err;
|
||||
}
|
||||
pctx = PACE_CTX_new();
|
||||
if (!pctx || !PACE_CTX_init(pctx, info)) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
goto err;
|
||||
}
|
||||
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);
|
||||
if (!nonce || !mdata || !mdata_opp) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
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);
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
}
|
||||
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);
|
||||
pub = PACE_STEP3B_generate_ephemeral_key(eph_dp, pctx);
|
||||
pub_opp = BUF_MEM_new();
|
||||
if (!eph_dp || !pub || !pub_opp) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
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);
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
}
|
||||
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);
|
||||
if (!key ||
|
||||
!PACE_STEP3C_derive_keys(key, pctx, info, &k_mac, &k_enc)) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
goto err;
|
||||
}
|
||||
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();
|
||||
if (!token || !token_opp) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
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);
|
||||
if (r < 0) {
|
||||
goto err;
|
||||
}
|
||||
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,
|
||||
eph_dp, info, k_mac, token_opp)) {
|
||||
r = SC_ERROR_INTERNAL;
|
||||
debug_ossl(ctx);
|
||||
debug_ossl(card->ctx);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* 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:
|
||||
if (info)
|
||||
@@ -771,14 +797,16 @@ err:
|
||||
if (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 *out = NULL;
|
||||
size_t outlen;
|
||||
struct sm_ctx sm;
|
||||
memset(&sm, 0, sizeof(sm));
|
||||
|
||||
in[0] = PACE_CAN; // pin_id
|
||||
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[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
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifndef _PACE_H
|
||||
#define _PACE_H
|
||||
|
||||
#include "sm.h"
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <opensc/opensc.h>
|
||||
|
||||
@@ -39,11 +40,11 @@ extern "C" {
|
||||
|
||||
#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);
|
||||
int EstablishPACEChannel(sc_context_t *ctx, sc_card_t *card, const __u8 *in,
|
||||
__u8 **out, size_t *outlen);
|
||||
int pace_test(sc_context_t *ctx, sc_card_t *card);
|
||||
int EstablishPACEChannel(sc_card_t *card, const __u8 *in,
|
||||
__u8 **out, size_t *outlen, struct sm_ctx *sm_ctx);
|
||||
int pace_test(sc_card_t *card);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
35
ccid/sm.h
35
ccid/sm.h
@@ -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 <openssl/evp.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SM_ISO_PADDING 0x01
|
||||
#define SM_NO_PADDING 0x02
|
||||
|
||||
@@ -20,3 +45,13 @@ struct sm_ctx {
|
||||
EVP_MD_CTX * md_ctx;
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user