/*
 * 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, 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_update(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)
{
    ERR_raise(ERR_LIB_CMP, 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)
{
    ERR_raise(ERR_LIB_CMP, 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)
{
    ERR_raise(ERR_LIB_CMP, 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)
{
    ERR_raise(ERR_LIB_CMP, 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)
{
    ERR_raise(ERR_LIB_CMP, 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)
{
    ERR_raise(ERR_LIB_CMP, 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(NULL, NULL);
        OSSL_CMP_CTX *client_ctx = OSSL_CMP_CTX_new(NULL, NULL);

        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)
{
}
