- fixed corruption of certificate description

- adjusted output parsing from certificate_description_print
- fixed check for certificate description in terminal certificate


git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@536 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
frankmorgner
2011-09-22 13:48:59 +00:00
parent 62d8b637ab
commit 2a59a1806a

View File

@@ -944,9 +944,9 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
if (pace_input.certificate_description_length && if (pace_input.certificate_description_length &&
pace_input.certificate_description) { pace_input.certificate_description) {
const unsigned char *pp = pace_input.certificate_description;
if (!d2i_CVC_CERTIFICATE_DESCRIPTION(&desc, if (!d2i_CVC_CERTIFICATE_DESCRIPTION(&desc,
&pace_input.certificate_description, &pp, pace_input.certificate_description_length)) {
pace_input.certificate_description_length)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse certificate description."); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not parse certificate description.");
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
goto err; goto err;
@@ -963,28 +963,33 @@ int EstablishPACEChannel(struct sm_ctx *oldnpactx, sc_card_t *card,
printf("Certificate Description\n"); printf("Certificate Description\n");
switch(certificate_description_print(bio_stdout, desc, 8)) { switch(certificate_description_print(bio_stdout, desc, 8)) {
case -1: case 0:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not print certificate description."); sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not print certificate description.");
ssl_error(card->ctx); ssl_error(card->ctx);
r = SC_ERROR_INTERNAL; r = SC_ERROR_INTERNAL;
goto err; goto err;
case 0:
break; break;
case 1: case 1:
/* text format */
break;
case 2:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in " sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in "
"HTML format can not (yet) be handled."); "HTML format can not (yet) be handled.");
r = SC_ERROR_NOT_SUPPORTED; r = SC_ERROR_NOT_SUPPORTED;
goto err; goto err;
case 2: break;
case 3:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in " sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in "
"PDF format can not (yet) be handled."); "PDF format can not (yet) be handled.");
r = SC_ERROR_NOT_SUPPORTED; r = SC_ERROR_NOT_SUPPORTED;
goto err; goto err;
break;
default: default:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in " sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate description in "
"unknown format can not (yet) be handled."); "unknown format can not be handled.");
r = SC_ERROR_NOT_SUPPORTED; r = SC_ERROR_NOT_SUPPORTED;
goto err; goto err;
break;
} }
hash_cert_desc = EAC_hash_certificate_description( hash_cert_desc = EAC_hash_certificate_description(
@@ -1260,6 +1265,8 @@ err:
PACE_SEC_clear_free(sec); PACE_SEC_clear_free(sec);
if (bio_stdout) if (bio_stdout)
BIO_free_all(bio_stdout); BIO_free_all(bio_stdout);
if (desc)
CVC_CERTIFICATE_DESCRIPTION_free(desc);
if (r < 0) { if (r < 0) {
if (eac_ctx) if (eac_ctx)
@@ -1502,8 +1509,8 @@ static CVC_CERT *
cert_from_apdudata(const unsigned char *data, size_t len) cert_from_apdudata(const unsigned char *data, size_t len)
{ {
/* there MUST be a more elegant way to do this... */ /* there MUST be a more elegant way to do this... */
CVC_CERT *cert; CVC_CERT *cert = NULL;
long int asn1datalen; long int asn1datalen = len;
int tag, xclass; int tag, xclass;
const unsigned char *p = data; const unsigned char *p = data;
@@ -1512,11 +1519,11 @@ cert_from_apdudata(const unsigned char *data, size_t len)
goto err; goto err;
if (0x80 & ASN1_get_object(&p, &asn1datalen, &tag, &xclass, len) if (0x80 & ASN1_get_object(&p, &asn1datalen, &tag, &xclass, len)
|| !d2i_CVC_CERT_BODY(&cert->body, &data, (data-p)+asn1datalen)) || !d2i_CVC_CERT_BODY(&cert->body, &data, (p-data)+asn1datalen))
goto err; goto err;
p += len; p += asn1datalen;
if (0x80 & ASN1_get_object(&p, &asn1datalen, &tag, &xclass, len-(data-p)) if (0x80 & ASN1_get_object(&p, &asn1datalen, &tag, &xclass, len-(p-data))
|| tag != 0x37) || tag != 0x37)
goto err; goto err;
cert->signature = ASN1_OCTET_STRING_new(); cert->signature = ASN1_OCTET_STRING_new();
@@ -1529,32 +1536,76 @@ cert_from_apdudata(const unsigned char *data, size_t len)
err: err:
if (cert) if (cert)
CVC_CERT_free(cert); CVC_CERT_free(cert);
return NULL;
} }
static int static int
npa_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx, npa_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
sc_apdu_t *apdu) sc_apdu_t *apdu)
{ {
int r;
CVC_CERT *cvc_cert = NULL;
if (apdu && apdu->ins == 0x2a && apdu->p1 == 0x00 && apdu->p2 == 0xbe) { if (apdu && apdu->ins == 0x2a && apdu->p1 == 0x00 && apdu->p2 == 0xbe) {
/* PSO:Verify Certificate /* PSO:Verify Certificate
* check certificate description to match given certificate */ * check certificate description to match given certificate */
struct npa_sm_ctx *eacsmctx = ctx->priv_data; struct npa_sm_ctx *eacsmctx = ctx->priv_data;
CVC_CERT *cvc_cert = cert_from_apdudata(apdu->data, apdu->datalen); cvc_cert = cert_from_apdudata(apdu->data, apdu->datalen);
if (!eacsmctx || !cvc_cert if (!eacsmctx || !cvc_cert || !cvc_cert->body) {
|| !CVC_check_cert(cvc_cert, eacsmctx->certificate_description, r = SC_ERROR_INVALID_DATA;
eacsmctx->certificate_description_length)) { goto err;
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Certificate Description doesn't match Certificate"); }
if (cvc_cert)
CVC_CERT_free(cvc_cert); switch (CVC_get_terminal_type(cvc_cert->body->chat)) {
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA); case CVC_CVCA:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Processing CVCA certificate");
break;
case CVC_DV:
case CVC_DocVer:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Processing DV certificate");
break;
case CVC_Terminal:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Processing Terminal certificate");
switch (CVC_check_cert(cvc_cert,
eacsmctx->certificate_description,
eacsmctx->certificate_description_length)) {
case 1:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
"Certificate Description matches Certificate");
break;
case 0:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
"Certificate Description doesn't match Certificate");
r = SC_ERROR_INVALID_DATA;
goto err;
break;
default:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
"Error verifying Certificate Description");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
break;
}
break;
default:
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Unknown type of certificate");
r = SC_ERROR_INVALID_DATA;
goto err;
break;
} }
CVC_CERT_free(cvc_cert);
} }
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r = increment_ssc(ctx->priv_data);
increment_ssc(ctx->priv_data));
err:
if (cvc_cert)
CVC_CERT_free(cvc_cert);
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
} }
static int static int