Esempio n. 1
0
void SCT_print(const SCT *sct, BIO *out, int indent,
               const CTLOG_STORE *log_store)
{
    const CTLOG *log = NULL;

    if (log_store != NULL) {
        log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id,
                                         sct->log_id_len);
    }

    BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, "");
    BIO_printf(out, "\n%*sVersion   : ", indent + 4, "");

    if (sct->version != SCT_VERSION_V1) {
        BIO_printf(out, "unknown\n%*s", indent + 16, "");
        BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len);
        return;
    }

    BIO_printf(out, "v1 (0x0)");

    if (log != NULL) {
        BIO_printf(out, "\n%*sLog       : %s", indent + 4, "",
                   CTLOG_get0_name(log));
    }

    BIO_printf(out, "\n%*sLog ID    : ", indent + 4, "");
    BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len);

    BIO_printf(out, "\n%*sTimestamp : ", indent + 4, "");
    timestamp_print(sct->timestamp, out);

    BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
    if (sct->ext_len == 0)
        BIO_printf(out, "none");
    else
        BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len);

    BIO_printf(out, "\n%*sSignature : ", indent + 4, "");
    SCT_signature_algorithms_print(sct, out);
    BIO_printf(out, "\n%*s            ", indent + 4, "");
    BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len);
}
Esempio n. 2
0
int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
{
    int is_sct_valid = -1;
    SCT_CTX *sctx = NULL;
    X509_PUBKEY *pub = NULL, *log_pkey = NULL;
    const CTLOG *log;

    /*
     * With an unrecognized SCT version we don't know what such an SCT means,
     * let alone validate one.  So we return validation failure (0).
     */
    if (sct->version != SCT_VERSION_V1) {
        sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION;
        return 0;
    }

    log = CTLOG_STORE_get0_log_by_id(ctx->log_store,
                                     sct->log_id, sct->log_id_len);

    /* Similarly, an SCT from an unknown log also cannot be validated. */
    if (log == NULL) {
        sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG;
        return 0;
    }

    sctx = SCT_CTX_new();
    if (sctx == NULL)
        goto err;

    if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1)
        goto err;
    if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1)
        goto err;

    if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) {
        EVP_PKEY *issuer_pkey;

        if (ctx->issuer == NULL) {
            sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
            goto end;
        }

        issuer_pkey = X509_get0_pubkey(ctx->issuer);

        if (X509_PUBKEY_set(&pub, issuer_pkey) != 1)
            goto err;
        if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1)
            goto err;
    }

    /*
     * XXX: Potential for optimization.  This repeats some idempotent heavy
     * lifting on the certificate for each candidate SCT, and appears to not
     * use any information in the SCT itself, only the certificate is
     * processed.  So it may make more sense to to do this just once, perhaps
     * associated with the shared (by all SCTs) policy eval ctx.
     *
     * XXX: Failure here is global (SCT independent) and represents either an
     * issue with the certificate (e.g. duplicate extensions) or an out of
     * memory condition.  When the certificate is incompatible with CT, we just
     * mark the SCTs invalid, rather than report a failure to determine the
     * validation status.  That way, callbacks that want to do "soft" SCT
     * processing will not abort handshakes with false positive internal
     * errors.  Since the function does not distinguish between certificate
     * issues (peer's fault) and internal problems (out fault) the safe thing
     * to do is to report a validation failure and let the callback or
     * application decide what to do.
     */
    if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1)
        sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
    else
        sct->validation_status = SCT_verify(sctx, sct) == 1 ?
            SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID;

end:
    is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID;
err:
    X509_PUBKEY_free(pub);
    X509_PUBKEY_free(log_pkey);
    SCT_CTX_free(sctx);

    return is_sct_valid;
}