int EAC_CTX_init_ta(const EAC_CTX *ctx, const unsigned char *privkey, size_t privkey_len, const unsigned char *cvca, size_t cvca_len) { CVC_CERT *ta_cvca = NULL; int r = 0; check(ctx && ctx->ta_ctx, "Invalid arguments"); if (privkey && privkey_len) { if (ctx->ta_ctx->priv_key) EVP_PKEY_free(ctx->ta_ctx->priv_key); ctx->ta_ctx->priv_key = d2i_AutoPrivateKey(&ctx->ta_ctx->priv_key, &privkey, privkey_len); if (!ctx->ta_ctx->priv_key) goto err; } if (cvca && cvca_len) { ta_cvca = CVC_d2i_CVC_CERT(&ta_cvca, &cvca, cvca_len); } r = TA_CTX_set_trust_anchor(ctx->ta_ctx, ta_cvca, ctx->bn_ctx); err: if (ta_cvca) CVC_CERT_free(ta_cvca); return r; }
int TA_CTX_import_certificate(TA_CTX *ctx, const CVC_CERT *next_cert, BN_CTX *bn_ctx) { int ok = 0, i; const CVC_CERT *trust_anchor = NULL; check(ctx && next_cert && next_cert->body && next_cert->body->chat && next_cert->body->certificate_authority_reference, "Invalid arguments"); /* Check date to see if the certificate is still valid * (not for link certificates). */ if ((ctx->flags & TA_FLAG_SKIP_TIMECHECK) != TA_FLAG_SKIP_TIMECHECK && CVC_get_role(next_cert->body->chat) != CVC_CVCA && cvc_check_time(next_cert) != 1) goto err; /* get the current trust anchor */ if (ctx->current_cert) { trust_anchor = ctx->current_cert; } else if (ctx->trust_anchor) { trust_anchor = ctx->trust_anchor; } else if (ctx->lookup_cvca_cert) { trust_anchor = ctx->lookup_cvca_cert( next_cert->body->certificate_authority_reference->data, next_cert->body->certificate_authority_reference->length); check(trust_anchor && TA_CTX_set_trust_anchor(ctx, trust_anchor, bn_ctx), "Could not look up trust anchor"); } check(trust_anchor && trust_anchor->body && trust_anchor->body->certificate_holder_reference, "No trust anchor, can't verify certificate"); /* Check chain integrity: The CAR of a certificate must be equal to the * the CHR of the next certificate in the chain */ check((next_cert->body->certificate_authority_reference && trust_anchor->body->certificate_holder_reference && next_cert->body->certificate_authority_reference->length == trust_anchor->body->certificate_holder_reference->length && memcmp(trust_anchor->body->certificate_holder_reference->data, next_cert->body->certificate_authority_reference->data, trust_anchor->body->certificate_holder_reference->length) == 0), "Current CHR does not match next CAR"); i = CVC_verify_signature(next_cert, ctx->pub_key); check((i > 0), "Could not verify current signature"); /* Certificate has been verified as next part of the chain */ if (ctx->current_cert) CVC_CERT_free(ctx->current_cert); ctx->current_cert = CVC_CERT_dup(next_cert); if (!ctx->current_cert) goto err; /* Set a (new) trust anchor */ if (CVC_get_role(next_cert->body->chat) == CVC_CVCA) { if (ctx->new_trust_anchor) CVC_CERT_free(ctx->new_trust_anchor); ctx->new_trust_anchor = CVC_CERT_dup(next_cert); if (!ctx->new_trust_anchor) goto err; } ok = TA_CTX_set_parameters(ctx, next_cert, bn_ctx); err: return ok; }