/*
 * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright Nokia 2007-2019
 * Copyright Siemens AG 2015-2019
 *
 * 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 "cmp_local.h"

/* explicit #includes not strictly needed since implied by the above: */
#include <openssl/asn1t.h>
#include <openssl/cmp.h>
#include <openssl/crmf.h>
#include <openssl/err.h>
#include <openssl/x509.h>

/*
 * This function is also used by the internal verify_PBMAC() in cmp_vfy.c.
 *
 * Calculate protection for given PKImessage according to
 * the algorithm and parameters in the message header's protectionAlg
 * using the credentials, library context, and property criteria in the ctx.
 *
 * returns ASN1_BIT_STRING representing the protection on success, else NULL
 */
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx,
                                          const OSSL_CMP_MSG *msg)
{
    ASN1_BIT_STRING *prot = NULL;
    OSSL_CMP_PROTECTEDPART prot_part;
    const ASN1_OBJECT *algorOID = NULL;
    const void *ppval = NULL;
    int pptype = 0;

    if (!ossl_assert(ctx != NULL && msg != NULL))
        return NULL;

    /* construct data to be signed */
    prot_part.header = msg->header;
    prot_part.body = msg->body;

    if (msg->header->protectionAlg == NULL) {
        ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_ALGORITHM_ID);
        return NULL;
    }
    X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg);

    if (OBJ_obj2nid(algorOID) == NID_id_PasswordBasedMAC) {
        int len;
        size_t prot_part_der_len;
        unsigned char *prot_part_der = NULL;
        size_t sig_len;
        unsigned char *protection = NULL;
        OSSL_CRMF_PBMPARAMETER *pbm = NULL;
        ASN1_STRING *pbm_str = NULL;
        const unsigned char *pbm_str_uc = NULL;

        if (ctx->secretValue == NULL) {
            ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PBM_SECRET);
            return NULL;
        }
        if (ppval == NULL) {
            ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CALCULATING_PROTECTION);
            return NULL;
        }

        len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der);
        if (len < 0 || prot_part_der == NULL) {
            ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CALCULATING_PROTECTION);
            goto end;
        }
        prot_part_der_len = (size_t)len;

        pbm_str = (ASN1_STRING *)ppval;
        pbm_str_uc = pbm_str->data;
        pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, pbm_str->length);
        if (pbm == NULL) {
            ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_ALGORITHM_OID);
            goto end;
        }

        if (!OSSL_CRMF_pbm_new(ctx->libctx, ctx->propq,
                               pbm, prot_part_der, prot_part_der_len,
                               ctx->secretValue->data, ctx->secretValue->length,
                               &protection, &sig_len))
            goto end;

        if ((prot = ASN1_BIT_STRING_new()) == NULL)
            return NULL;
        /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
        prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        prot->flags |= ASN1_STRING_FLAG_BITS_LEFT;
        if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) {
            ASN1_BIT_STRING_free(prot);
            prot = NULL;
        }
    end:
        OSSL_CRMF_PBMPARAMETER_free(pbm);
        OPENSSL_free(protection);
        OPENSSL_free(prot_part_der);
        return prot;
    } else {
        int md_nid;
        const EVP_MD *md = NULL;

        if (ctx->pkey == NULL) {
            ERR_raise(ERR_LIB_CMP,
                      CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
            return NULL;
        }
        if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_nid, NULL)
                || (md = EVP_get_digestbynid(md_nid)) == NULL) {
            ERR_raise(ERR_LIB_CMP, CMP_R_UNKNOWN_ALGORITHM_ID);
            return NULL;
        }

        if ((prot = ASN1_BIT_STRING_new()) == NULL)
            return NULL;
        if (ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), NULL,
                              NULL, prot, &prot_part, NULL, ctx->pkey, md,
                              ctx->libctx, ctx->propq))
            return prot;
        ASN1_BIT_STRING_free(prot);
        return NULL;
    }
}

int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
{
    if (!ossl_assert(ctx != NULL && msg != NULL))
        return 0;

    /* Add first ctx->cert and its chain if using signature-based protection */
    if (!ctx->unprotectedSend && ctx->secretValue == NULL
            && ctx->cert != NULL && ctx->pkey != NULL) {
        int prepend = X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP
            | X509_ADD_FLAG_PREPEND | X509_ADD_FLAG_NO_SS;

        /* if not yet done try to build chain using available untrusted certs */
        if (ctx->chain == NULL) {
            ossl_cmp_debug(ctx,
                           "trying to build chain for own CMP signer cert");
            ctx->chain = X509_build_chain(ctx->cert, ctx->untrusted, NULL, 0,
                                          ctx->libctx, ctx->propq);
            if (ctx->chain != NULL) {
                ossl_cmp_debug(ctx,
                               "success building chain for own CMP signer cert");
            } else {
                /* dump errors to avoid confusion when printing further ones */
                OSSL_CMP_CTX_print_errors(ctx);
                ossl_cmp_warn(ctx,
                              "could not build chain for own CMP signer cert");
            }
        }
        if (ctx->chain != NULL) {
            if (!ossl_x509_add_certs_new(&msg->extraCerts, ctx->chain, prepend))
                return 0;
        } else {
            /* make sure that at least our own signer cert is included first */
            if (!ossl_x509_add_cert_new(&msg->extraCerts, ctx->cert, prepend))
                return 0;
            ossl_cmp_debug(ctx, "fallback: adding just own CMP signer cert");
        }
    }

    /* add any additional certificates from ctx->extraCertsOut */
    if (!ossl_x509_add_certs_new(&msg->extraCerts, ctx->extraCertsOut,
                                 X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
        return 0;

    /* in case extraCerts are empty list avoid empty ASN.1 sequence */
    if (sk_X509_num(msg->extraCerts) == 0) {
        sk_X509_free(msg->extraCerts);
        msg->extraCerts = NULL;
    }
    return 1;
}

/*
 * Create an X509_ALGOR structure for PasswordBasedMAC protection based on
 * the pbm settings in the context
 */
static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg)
{
    OSSL_CRMF_PBMPARAMETER *pbm = NULL;
    unsigned char *pbm_der = NULL;
    int pbm_der_len;
    ASN1_STRING *pbm_str = NULL;

    if (!ossl_assert(ctx != NULL))
        return 0;

    pbm = OSSL_CRMF_pbmp_new(ctx->libctx, ctx->pbm_slen,
                             EVP_MD_get_type(ctx->pbm_owf), ctx->pbm_itercnt,
                             ctx->pbm_mac);
    pbm_str = ASN1_STRING_new();
    if (pbm == NULL || pbm_str == NULL)
        goto err;

    if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0)
        goto err;

    if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len))
        goto err;
    if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL)
        goto err;
    OPENSSL_free(pbm_der);

    X509_ALGOR_set0(*alg, OBJ_nid2obj(NID_id_PasswordBasedMAC),
                    V_ASN1_SEQUENCE, pbm_str);
    OSSL_CRMF_PBMPARAMETER_free(pbm);
    return 1;

 err:
    ASN1_STRING_free(pbm_str);
    OPENSSL_free(pbm_der);
    OSSL_CRMF_PBMPARAMETER_free(pbm);
    return 0;
}

static int set_sig_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg)
{
    int nid = 0;
    ASN1_OBJECT *algo = NULL;

    if (!OBJ_find_sigid_by_algs(&nid, EVP_MD_get_type(ctx->digest),
                                EVP_PKEY_get_id(ctx->pkey))) {
        ERR_raise(ERR_LIB_CMP, CMP_R_UNSUPPORTED_KEY_TYPE);
        return 0;
    }
    if ((algo = OBJ_nid2obj(nid)) == NULL)
        return 0;
    if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL)
        return 0;

    if (X509_ALGOR_set0(*alg, algo, V_ASN1_UNDEF, NULL))
        return 1;
    ASN1_OBJECT_free(algo);
    return 0;
}

static int set_senderKID(const OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg,
                         const ASN1_OCTET_STRING *id)
{
    if (id == NULL)
        id = ctx->referenceValue; /* standard for PBM, fallback for sig-based */
    return id == NULL || ossl_cmp_hdr_set1_senderKID(msg->header, id);
}

int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
{
    if (!ossl_assert(ctx != NULL && msg != NULL))
        return 0;

    /*
     * For the case of re-protection remove pre-existing protection.
     */
    X509_ALGOR_free(msg->header->protectionAlg);
    msg->header->protectionAlg = NULL;
    ASN1_BIT_STRING_free(msg->protection);
    msg->protection = NULL;

    if (ctx->unprotectedSend) {
        if (!set_senderKID(ctx, msg, NULL))
            goto err;
    } else if (ctx->secretValue != NULL) {
        /* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */
        if (!set_pbmac_algor(ctx, &msg->header->protectionAlg))
            goto err;
        if (!set_senderKID(ctx, msg, NULL))
            goto err;

        /*
         * will add any additional certificates from ctx->extraCertsOut
         * while not needed to validate the protection certificate,
         * the option to do this might be handy for certain use cases
         */
    } else if (ctx->cert != NULL && ctx->pkey != NULL) {
        /* use MSG_SIG_ALG according to 5.1.3.3 if client cert and key given */

        /* make sure that key and certificate match */
        if (!X509_check_private_key(ctx->cert, ctx->pkey)) {
            ERR_raise(ERR_LIB_CMP, CMP_R_CERT_AND_KEY_DO_NOT_MATCH);
            goto err;
        }

        if (!set_sig_algor(ctx, &msg->header->protectionAlg))
            goto err;
        /* set senderKID to keyIdentifier of the cert according to 5.1.1 */
        if (!set_senderKID(ctx, msg, X509_get0_subject_key_id(ctx->cert)))
            goto err;

        /*
         * will add ctx->cert followed, if possible, by its chain built
         * from ctx->untrusted, and then ctx->extraCertsOut
         */
    } else {
        ERR_raise(ERR_LIB_CMP,
                  CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION);
        goto err;
    }
    if (!ctx->unprotectedSend
            && ((msg->protection = ossl_cmp_calc_protection(ctx, msg)) == NULL))
        goto err;

    /*
     * For signature-based protection add ctx->cert followed by its chain.
     * Finally add any additional certificates from ctx->extraCertsOut;
     * even if not needed to validate the protection
     * the option to do this might be handy for certain use cases.
     */
    if (!ossl_cmp_msg_add_extraCerts(ctx, msg))
        goto err;

    /*
     * As required by RFC 4210 section 5.1.1., if the sender name is not known
     * to the client it set to NULL-DN. In this case for identification at least
     * the senderKID must be set, where we took the referenceValue as fallback.
     */
    if (!(ossl_cmp_general_name_is_NULL_DN(msg->header->sender)
          && msg->header->senderKID == NULL))
        return 1;
    ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_SENDER_IDENTIFICATION);

 err:
    ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROTECTING_MESSAGE);
    return 0;
}
