/*
 * Copyright 1995-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 <stdio.h>
#include "internal/cryptlib.h"
#include "internal/refcount.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "crypto/asn1.h"
#include "crypto/x509.h"
#include "x509_local.h"

int X509_set_version(X509 *x, long version)
{
    if (x == NULL)
        return 0;
    if (version == 0) {
        ASN1_INTEGER_free(x->cert_info.version);
        x->cert_info.version = NULL;
        return 1;
    }
    if (x->cert_info.version == NULL) {
        if ((x->cert_info.version = ASN1_INTEGER_new()) == NULL)
            return 0;
    }
    return ASN1_INTEGER_set(x->cert_info.version, version);
}

int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
{
    ASN1_INTEGER *in;

    if (x == NULL)
        return 0;
    in = &x->cert_info.serialNumber;
    if (in != serial)
        return ASN1_STRING_copy(in, serial);
    return 1;
}

int X509_set_issuer_name(X509 *x, const X509_NAME *name)
{
    if (x == NULL)
        return 0;
    return X509_NAME_set(&x->cert_info.issuer, name);
}

int X509_set_subject_name(X509 *x, const X509_NAME *name)
{
    if (x == NULL)
        return 0;
    return X509_NAME_set(&x->cert_info.subject, name);
}

int ossl_x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm)
{
    ASN1_TIME *in;
    in = *ptm;
    if (in != tm) {
        in = ASN1_STRING_dup(tm);
        if (in != NULL) {
            ASN1_TIME_free(*ptm);
            *ptm = in;
        }
    }
    return (in != NULL);
}

int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm)
{
    if (x == NULL)
        return 0;
    return ossl_x509_set1_time(&x->cert_info.validity.notBefore, tm);
}

int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm)
{
    if (x == NULL)
        return 0;
    return ossl_x509_set1_time(&x->cert_info.validity.notAfter, tm);
}

int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
{
    if (x == NULL)
        return 0;
    return X509_PUBKEY_set(&(x->cert_info.key), pkey);
}

int X509_up_ref(X509 *x)
{
    int i;

    if (CRYPTO_UP_REF(&x->references, &i, x->lock) <= 0)
        return 0;

    REF_PRINT_COUNT("X509", x);
    REF_ASSERT_ISNT(i < 2);
    return ((i > 1) ? 1 : 0);
}

long X509_get_version(const X509 *x)
{
    return ASN1_INTEGER_get(x->cert_info.version);
}

const ASN1_TIME *X509_get0_notBefore(const X509 *x)
{
    return x->cert_info.validity.notBefore;
}

const ASN1_TIME *X509_get0_notAfter(const X509 *x)
{
    return x->cert_info.validity.notAfter;
}

ASN1_TIME *X509_getm_notBefore(const X509 *x)
{
    return x->cert_info.validity.notBefore;
}

ASN1_TIME *X509_getm_notAfter(const X509 *x)
{
    return x->cert_info.validity.notAfter;
}

int X509_get_signature_type(const X509 *x)
{
    return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg.algorithm));
}

X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x)
{
    return x->cert_info.key;
}

const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x)
{
    return x->cert_info.extensions;
}

void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid,
                    const ASN1_BIT_STRING **psuid)
{
    if (piuid != NULL)
        *piuid = x->cert_info.issuerUID;
    if (psuid != NULL)
        *psuid = x->cert_info.subjectUID;
}

const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x)
{
    return &x->cert_info.signature;
}

int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid,
                      int *secbits, uint32_t *flags)
{
    if (mdnid != NULL)
        *mdnid = siginf->mdnid;
    if (pknid != NULL)
        *pknid = siginf->pknid;
    if (secbits != NULL)
        *secbits = siginf->secbits;
    if (flags != NULL)
        *flags = siginf->flags;
    return (siginf->flags & X509_SIG_INFO_VALID) != 0;
}

void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid,
                       int secbits, uint32_t flags)
{
    siginf->mdnid = mdnid;
    siginf->pknid = pknid;
    siginf->secbits = secbits;
    siginf->flags = flags;
}

int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
                            uint32_t *flags)
{
    X509_check_purpose(x, -1, -1);
    return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags);
}

/* Modify *siginf according to alg and sig. Return 1 on success, else 0. */
static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
                              const ASN1_STRING *sig)
{
    int pknid, mdnid;
    const EVP_MD *md;
    const EVP_PKEY_ASN1_METHOD *ameth;

    siginf->mdnid = NID_undef;
    siginf->pknid = NID_undef;
    siginf->secbits = -1;
    siginf->flags = 0;
    if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)
            || pknid == NID_undef) {
        ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_SIGID_ALGS);
        return 0;
    }
    siginf->mdnid = mdnid;
    siginf->pknid = pknid;

    switch (mdnid) {
    case NID_undef:
        /* If we have one, use a custom handler for this algorithm */
        ameth = EVP_PKEY_asn1_find(NULL, pknid);
        if (ameth == NULL || ameth->siginf_set == NULL
                || !ameth->siginf_set(siginf, alg, sig)) {
            ERR_raise(ERR_LIB_X509, X509_R_ERROR_USING_SIGINF_SET);
            return 0;
        }
        break;
        /*
         * SHA1 and MD5 are known to be broken. Reduce security bits so that
         * they're no longer accepted at security level 1.
         * The real values don't really matter as long as they're lower than 80,
         * which is our security level 1.
         */
    case NID_sha1:
        /*
         * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack
         * for SHA1 at2^63.4
         */
        siginf->secbits = 63;
        break;
    case NID_md5:
        /*
         * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf
         * puts a chosen-prefix attack for MD5 at 2^39.
         */
        siginf->secbits = 39;
        break;
    case NID_id_GostR3411_94:
        /*
         * There is a collision attack on GOST R 34.11-94 at 2^105, see
         * https://link.springer.com/chapter/10.1007%2F978-3-540-85174-5_10
         */
        siginf->secbits = 105;
        break;
    default:
        /* Security bits: half number of bits in digest */
        if ((md = EVP_get_digestbynid(mdnid)) == NULL) {
            ERR_raise(ERR_LIB_X509, X509_R_ERROR_GETTING_MD_BY_NID);
            return 0;
        }
        siginf->secbits = EVP_MD_get_size(md) * 4;
        break;
    }
    switch (mdnid) {
    case NID_sha1:
    case NID_sha256:
    case NID_sha384:
    case NID_sha512:
        siginf->flags |= X509_SIG_INFO_TLS;
    }
    siginf->flags |= X509_SIG_INFO_VALID;
    return 1;
}

/* Returns 1 on success, 0 on failure */
int ossl_x509_init_sig_info(X509 *x)
{
    return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
}
