/*
 * Copyright 2007-2020 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
 */

/*
 * Test CMP DER parsing.
 */

#include <openssl/bio.h>
#include <openssl/cmp.h>
#include "../crypto/cmp/cmp_local.h"
#include <openssl/err.h>
#include "fuzzer.h"
#include "rand.inc"

int FuzzerInitialize(int *argc, char ***argv)
{
    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
    ERR_clear_error();
    CRYPTO_free_ex_index(0, -1);
    FuzzerSetRand();
    return 1;
}

static int num_responses;

static OSSL_CMP_MSG *transfer_cb(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req)
{
    if (num_responses++ > 2)
        return NULL; /* prevent loops due to repeated pollRep */
    return OSSL_CMP_MSG_dup((OSSL_CMP_MSG *)
                            OSSL_CMP_CTX_get_transfer_cb_arg(ctx));
}

static int print_noop(const char *func, const char *file, int line,
                      OSSL_CMP_severity level, const char *msg)
{
    return 1;
}

static int allow_unprotected(const OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *rep,
                             int invalid_protection, int expected_type)
{
    return 1;
}

static void cmp_client_process_response(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
{
    X509_NAME *name = X509_NAME_new();
    ASN1_INTEGER *serial = ASN1_INTEGER_new();

    ctx->unprotectedSend = 1; /* satisfy ossl_cmp_msg_protect() */
    ctx->disableConfirm = 1; /* check just one response message */
    ctx->popoMethod = OSSL_CRMF_POPO_NONE; /* satisfy ossl_cmp_certReq_new() */
    ctx->oldCert = X509_new(); /* satisfy crm_new() and ossl_cmp_rr_new() */
    if (!OSSL_CMP_CTX_set1_secretValue(ctx, (unsigned char *)"",
                                       0) /* prevent too unspecific error */
            || ctx->oldCert == NULL
            || name == NULL || !X509_set_issuer_name(ctx->oldCert, name)
            || serial == NULL || !X509_set_serialNumber(ctx->oldCert, serial))
        goto err;

    (void)OSSL_CMP_CTX_set_transfer_cb(ctx, transfer_cb);
    (void)OSSL_CMP_CTX_set_transfer_cb_arg(ctx, msg);
    (void)OSSL_CMP_CTX_set_log_cb(ctx, print_noop);
    num_responses = 0;
    switch (msg->body != NULL ? msg->body->type : -1) {
    case OSSL_CMP_PKIBODY_IP:
        (void)OSSL_CMP_exec_IR_ses(ctx);
        break;
    case OSSL_CMP_PKIBODY_CP:
        (void)OSSL_CMP_exec_CR_ses(ctx);
        (void)OSSL_CMP_exec_P10CR_ses(ctx);
        break;
    case OSSL_CMP_PKIBODY_KUP:
        (void)OSSL_CMP_exec_KUR_ses(ctx);
        break;
    case OSSL_CMP_PKIBODY_POLLREP:
        ctx->status = OSSL_CMP_PKISTATUS_waiting;
        (void)OSSL_CMP_try_certreq(ctx, OSSL_CMP_PKIBODY_CR, NULL);
        break;
    case OSSL_CMP_PKIBODY_RP:
        (void)OSSL_CMP_exec_RR_ses(ctx);
        break;
    case OSSL_CMP_PKIBODY_GENP:
        sk_OSSL_CMP_ITAV_pop_free(OSSL_CMP_exec_GENM_ses(ctx),
                                  OSSL_CMP_ITAV_free);
        break;
    default:
        (void)ossl_cmp_msg_check_received(ctx, msg, allow_unprotected, 0);
        break;
    }
 err:
    X509_NAME_free(name);
    ASN1_INTEGER_free(serial);
}

static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
                                            const OSSL_CMP_MSG *cert_req,
                                            int certReqId,
                                            const OSSL_CRMF_MSG *crm,
                                            const X509_REQ *p10cr,
                                            X509 **certOut,
                                            STACK_OF(X509) **chainOut,
                                            STACK_OF(X509) **caPubs)
{
    CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
    return NULL;
}

static OSSL_CMP_PKISI *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
                                  const OSSL_CMP_MSG *rr,
                                  const X509_NAME *issuer,
                                  const ASN1_INTEGER *serial)
{
    CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
    return NULL;
}

static int process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
                        const OSSL_CMP_MSG *genm,
                        const STACK_OF(OSSL_CMP_ITAV) *in,
                        STACK_OF(OSSL_CMP_ITAV) **out)
{
    CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
    return 0;
}

static void process_error(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *error,
                          const OSSL_CMP_PKISI *statusInfo,
                          const ASN1_INTEGER *errorCode,
                          const OSSL_CMP_PKIFREETEXT *errorDetails)
{
    CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
}

static int process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
                            const OSSL_CMP_MSG *certConf, int certReqId,
                            const ASN1_OCTET_STRING *certHash,
                            const OSSL_CMP_PKISI *si)
{
    CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
    return 0;
}

static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
                           const OSSL_CMP_MSG *pollReq, int certReqId,
                           OSSL_CMP_MSG **certReq, int64_t *check_after)
{
    CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
    return 0;
}

int FuzzerTestOneInput(const uint8_t *buf, size_t len)
{
    OSSL_CMP_MSG *msg;
    BIO *in;

    if (len == 0)
        return 0;

    in = BIO_new(BIO_s_mem());
    OPENSSL_assert((size_t)BIO_write(in, buf, len) == len);
    msg = d2i_OSSL_CMP_MSG_bio(in, NULL);
    if (msg != NULL) {
        BIO *out = BIO_new(BIO_s_null());
        OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new();
        OSSL_CMP_CTX *client_ctx = OSSL_CMP_CTX_new();

        i2d_OSSL_CMP_MSG_bio(out, msg);
        ASN1_item_print(out, (ASN1_VALUE *)msg, 4,
                        ASN1_ITEM_rptr(OSSL_CMP_MSG), NULL);
        BIO_free(out);

        if (client_ctx != NULL)
            cmp_client_process_response(client_ctx, msg);
        if (srv_ctx != NULL
            && OSSL_CMP_CTX_set_log_cb(OSSL_CMP_SRV_CTX_get0_cmp_ctx(srv_ctx),
                                       print_noop)
            && OSSL_CMP_SRV_CTX_init(srv_ctx, NULL, process_cert_request,
                                     process_rr, process_genm, process_error,
                                     process_certConf, process_pollReq))
            OSSL_CMP_MSG_free(OSSL_CMP_SRV_process_request(srv_ctx, msg));

        OSSL_CMP_CTX_free(client_ctx);
        OSSL_CMP_SRV_CTX_free(srv_ctx);
        OSSL_CMP_MSG_free(msg);
    }

    BIO_free(in);
    ERR_clear_error();

    return 0;
}

void FuzzerCleanup(void)
{
}
