summaryrefslogtreecommitdiffstats
path: root/drivers/ssb/main.c
AgeCommit message (Expand)Author
2012-03-20Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-nextLinus Torvalds
2012-02-06ssb: add support for bcm5354Hauke Mehrtens
2012-01-24Remove useless get_driver()/put_driver() callsAlan Stern
2011-10-31ssb: Add module.h to the real modules in drivers/ssbPaul Gortmaker
2011-08-24ssb: fix DMA translation for some specific boardsRafał Miłecki
2011-07-25Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jik...Linus Torvalds
2011-07-22ssb: return correct translation bit for 64-bit DMARafał Miłecki
2011-07-07Update my e-mail addressMichael Büsch
2011-06-27ssb: fix ssb clock rate according to broadcom sourceHauke Mehrtens
2011-06-22ssb: add __devinit to some functionsHauke Mehrtens
2011-05-13ssb: fix pcicore build breakageJohn W. Linville
2011-05-11ssb: move ssb_commit_settings and export itRafał Miłecki
2011-04-26ssb: update reject bit for Target State LowRafał Miłecki
2011-04-26ssb: mark bus as powered up earlierRafał Miłecki
2011-02-18ssb: reset device only if it was enabledRafał Miłecki
2011-02-18ssb: when needed, reject IM input while disabling deviceRafał Miłecki
2011-02-18ssb: Make ssb_wait_bit multi-bit safeMichael Büsch
2010-12-02ssb: Add sysfs attributes to ssb devicesHauke Mehrtens
2010-09-29pcmcia: convert pcmcia_request_configuration to pcmcia_enable_deviceDominik Brodowski
2010-08-06Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6Linus Torvalds
2010-07-30pcmcia: remove cs_types.hDominik Brodowski
2010-06-04ssb: remove the ssb DMA APIFUJITA Tomonori
2010-06-04ssb: add dma_dev to ssb_device structureFUJITA Tomonori
2010-05-20Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6Linus Torvalds
2010-05-10pcmcia: re-work pcmcia_request_irq()Dominik Brodowski
2010-05-05Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil...John W. Linville
2010-04-26ssb: Make bus registration failure not be silentLarry Finger
2010-03-30include cleanup: Update gfp.h and slab.h includes to prepare for breaking imp...Tejun Heo
2010-02-03ssb: Fix CONFIG_SSB_SDIOHOST typoMichael Buesch
2009-11-23ssb: Fix SPROM writingMichael Buesch
2009-09-09ssb: Implement SDIO host bus supportAlbert Herranz
2009-09-08ssb: Fail ssb modinit, if attach of the buses failed.Michael Buesch
2008-11-21ssb: struct device - replace bus_id with dev_name(), dev_set_name()Kay Sievers
2008-09-27[SSB] Initialise dma_mask for SSB_BUSTYPE_SSB devicesAurelien Jarno
2008-08-18ssb: allow compilation on systems without PCIHolger Schurig
2008-06-27ssb, b43, b43legacy, b44: Rewrite SSB DMA APIMichael Buesch
2008-06-13ssb: Fix coherent DMA mask for PCI devicesMichael Buesch
2008-04-17Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds...David S. Miller
2008-04-15ssb: Fix usage of struct device used for DMAingMichael Buesch
2008-04-14Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/ne...David S. Miller
2008-04-08ssb: Add support for block-I/OMichael Buesch
2008-04-08ssb: Fix build for non-PCIhostMichael Buesch
2008-04-08ssb: Turn suspend/resume upside downMichael Buesch
2008-04-08ssb-pcmcia: IRQ and DMA related fixesMichael Buesch
2008-04-07b43legacy: fix bcm4303 crashStefano Brivio
2008-03-13ssb: Add SPROM/invariants support for PCMCIA devicesMichael Buesch
2008-03-06ssb: Add Gigabit Ethernet driverMichael Buesch
2008-02-29ssb: Add support for 8bit register accessMichael Buesch
2008-02-20ssb: Fix pcicore cardbus modeMichael Buesch
2008-02-20ssb: Make the GPIO API reentrancy safeMichael Buesch
'#n319'>319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
/*
 * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <string.h>
#include <openssl/ocsp.h>
#include <openssl/err.h>
#include "internal/sizes.h"
#include "ocsp_local.h"

static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
                            STACK_OF(X509) *certs, unsigned long flags);
static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain);
static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp,
                          OCSP_CERTID **ret);
static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
                               STACK_OF(OCSP_SINGLERESP) *sresp);
static int ocsp_check_delegated(X509 *x);
static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
                                const X509_NAME *nm, STACK_OF(X509) *certs,
                                unsigned long flags);

/* Returns 1 on success, 0 on failure, or -1 on fatal error */
static int ocsp_verify_signer(X509 *signer, int response,
                              X509_STORE *st, unsigned long flags,
                              STACK_OF(X509) *untrusted, STACK_OF(X509) **chain)
{
    X509_STORE_CTX *ctx = X509_STORE_CTX_new();
    X509_VERIFY_PARAM *vp;
    int ret = -1;

    if (ctx == NULL) {
        ERR_raise(ERR_LIB_OCSP, ERR_R_MALLOC_FAILURE);
        goto end;
    }
    if (!X509_STORE_CTX_init(ctx, st, signer, untrusted)) {
        ERR_raise(ERR_LIB_OCSP, ERR_R_X509_LIB);
        goto end;
    }
    if ((vp = X509_STORE_CTX_get0_param(ctx)) == NULL)
        goto end;
    if ((flags & OCSP_PARTIAL_CHAIN) != 0)
        X509_VERIFY_PARAM_set_flags(vp, X509_V_FLAG_PARTIAL_CHAIN);
    if (response
            && X509_get_ext_by_NID(signer, NID_id_pkix_OCSP_noCheck, -1) >= 0)
        /*
         * Locally disable revocation status checking for OCSP responder cert.
         * Done here for CRLs; TODO should be done also for OCSP-based checks.
         */
        X509_VERIFY_PARAM_clear_flags(vp, X509_V_FLAG_CRL_CHECK);
    X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER);
    X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST);
    /* TODO: why is X509_TRUST_OCSP_REQUEST set? Seems to get ignored. */

    ret = X509_verify_cert(ctx);
    if (ret <= 0) {
        ret = X509_STORE_CTX_get_error(ctx);
        ERR_raise_data(ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR,
                       "Verify error: %s", X509_verify_cert_error_string(ret));
        goto end;
    }
    if (chain != NULL)
        *chain = X509_STORE_CTX_get1_chain(ctx);

 end:
    X509_STORE_CTX_free(ctx);
    return ret;
}

static int ocsp_verify(OCSP_REQUEST *req, OCSP_BASICRESP *bs,
                       X509 *signer, unsigned long flags)
{
    EVP_PKEY *skey;
    int ret = 1;

    if ((flags & OCSP_NOSIGS) == 0) {
        if ((skey = X509_get0_pubkey(signer)) == NULL) {
            ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY);
            return -1;
        }
        if (req != NULL)
            ret = OCSP_REQUEST_verify(req, skey, signer->libctx, signer->propq);
        else
            ret = OCSP_BASICRESP_verify(bs, skey, signer->libctx, signer->propq);
        if (ret <= 0)
            ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNATURE_FAILURE);
    }
    return ret;
}

/* Verify a basic response message */
int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
                      X509_STORE *st, unsigned long flags)
{
    X509 *signer, *x;
    STACK_OF(X509) *chain = NULL;
    STACK_OF(X509) *untrusted = NULL;
    int ret = ocsp_find_signer(&signer, bs, certs, flags);

    if (ret == 0) {
        ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
        goto end;
    }
    if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0)
        flags |= OCSP_NOVERIFY;

    if ((ret = ocsp_verify(NULL, bs, signer, flags)) <= 0)
        goto end;
    if ((flags & OCSP_NOVERIFY) == 0) {
        ret = -1;
        if ((flags & OCSP_NOCHAIN) == 0) {
            if ((untrusted = sk_X509_dup(bs->certs)) == NULL)
                goto end;
            if (!X509_add_certs(untrusted, certs, X509_ADD_FLAG_DEFAULT))
                goto end;
        }
        ret = ocsp_verify_signer(signer, 1, st, flags, untrusted, &chain);
        if (ret <= 0)
            goto end;
        if ((flags & OCSP_NOCHECKS) != 0) {
            ret = 1;
            goto end;
        }
        /*
         * At this point we have a valid certificate chain need to verify it
         * against the OCSP issuer criteria.
         */
        ret = ocsp_check_issuer(bs, chain);

        /* If fatal error or valid match then finish */
        if (ret != 0)
            goto end;

        /*
         * Easy case: explicitly trusted. Get root CA and check for explicit
         * trust
         */
        if ((flags & OCSP_NOEXPLICIT) != 0)
            goto end;

        x = sk_X509_value(chain, sk_X509_num(chain) - 1);
        if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) {
            ERR_raise(ERR_LIB_OCSP, OCSP_R_ROOT_CA_NOT_TRUSTED);
            ret = 0;
            goto end;
        }
        ret = 1;
    }

 end:
    sk_X509_pop_free(chain, X509_free);
    sk_X509_free(untrusted);
    return ret;
}

int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer,
                          STACK_OF(X509) *extra_certs)
{
    return ocsp_find_signer(signer, bs, extra_certs, 0) > 0;
}

static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
                            STACK_OF(X509) *certs, unsigned long flags)
{
    X509 *signer;
    OCSP_RESPID *rid = &bs->tbsResponseData.responderId;

    if ((signer = ocsp_find_signer_sk(certs, rid)) != NULL) {
        *psigner = signer;
        return 2;
    }
    if ((flags & OCSP_NOINTERN) == 0 &&
        (signer = ocsp_find_signer_sk(bs->certs, rid))) {
        *psigner = signer;
        return 1;
    }
    /* Maybe lookup from store if by subject name */

    *psigner = NULL;
    return 0;
}

static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
{
    int i, r;
    unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
    EVP_MD *md;
    X509 *x;