// Is this certificate still good? The responder named inside it asked, each answer checked for who
// signed it and when, and what it means when the answer is forged, stale, or for someone else.
//
//   OCSP_SAMPLES=http://127.0.0.1:9000 quillo run ocsp.qwe
//   then open http://localhost:8080/urls, /status, /signers and /refused
//
// A program has its certificate and issuer on disk. OCSP_SAMPLES is a test CA with its own
// responder, which serves certificates for this example at /certs.

use "ocsp.qwer"

let SAMPLES = env("OCSP_SAMPLES", "http://127.0.0.1:9000")
fn certs() = http.get(`${SAMPLES}/certs`).json

route GET /urls {
    let c = certs()
    let req = ocsp_request(c.good, c.issuer, {})?
    let bare = ocsp_request(c.good, c.issuer, { nonce: false, hash: "sha256" })?
    let urls = ocsp_urls(c.good)?
    let short = (l) => map(l, (u) => replace(u, SAMPLES, ""))
    {
        ocsp: short(urls.ocsp),
        ca_issuers: short(urls.ca_issuers),
        crl: short(urls.crl),
        none: ocsp_urls(c.bare)?.ocsp,
        nonce_bytes: len(req.nonce) / 2,
        no_nonce: bare.nonce,
        posted: req.url == ocsp_urls(c.good)?.ocsp[0],
        by_get: starts_with(req.get_url, `${SAMPLES}/ocsp/M`),
    }
}

route GET /status {
    let c = certs()
    let good = ocsp_check(c.good, c.issuer, {})?
    let gone = ocsp_check(c.revoked, c.issuer, {})?
    let lost = ocsp_check(c.unknown, c.issuer, {})?
    {
        good: { status: good.status, good: good.good, signed_by: good.signed_by, nonce: good.nonce_checked, next: good.next_update > good.this_update },
        revoked: { status: gone.status, good: gone.good, reason: gone.reason, at: gone.revoked_at },
        unknown: { status: lost.status, good: lost.good },
        sha256: ocsp_check(c.good, c.issuer, { hash: "sha256" })?.status,
        ec: ocsp_check(c.ec, c.ec_issuer, {})?.status,
    }
}

// Two ways a CA may sign: itself, or through a responder certificate it issued for that.
route GET /signers {
    let c = certs()
    let got = ocsp_check(c.delegated, c.issuer, {})?
    let raw = http.get(`${SAMPLES}/raw?kind=good`).body
    {
        delegated: [got.status, got.signed_by],
        read: ocsp_read(raw, c.good, c.issuer, {})?.status,
        dump: ocsp_dump(raw)?.responses[0].status,
        no_right: ocsp_check(c.no_eku, c.issuer, {}).error,
        wrong_issuer: ocsp_check(c.other_signed, c.issuer, {}).error,
    }
}

route GET /refused {
    let c = certs()
    {
        forged: ocsp_check(c.forged, c.issuer, {}).error,
        stranger: ocsp_check(c.stranger, c.issuer, {}).error,
        stale: ocsp_check(c.stale, c.issuer, {}).error,
        future: ocsp_check(c.future, c.issuer, {}).error,
        replay: ocsp_check(c.replay, c.issuer, {}).error,
        someone_else: ocsp_check(c.mismatch, c.issuer, {}).error,
        busy: ocsp_check(c.busy, c.issuer, {}).error,
        wrong_ca: ocsp_check(c.good, c.ec_issuer, {}).error,
        no_url: ocsp_check(c.bare, c.issuer, {}).error,
        not_pem: ocsp_check("nope", c.issuer, {}).error,
    }
}
