/*
 * Copyright 1999-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
 */

#include <stdio.h>
#include <stdlib.h>
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
#include <openssl/err.h>

int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
                              STACK_OF(X509_ALGOR) *cap)
{
    ASN1_STRING *seq;

    if ((seq = ASN1_STRING_new()) == NULL) {
        ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data,
                                ASN1_ITEM_rptr(X509_ALGORS));
    return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
                                      V_ASN1_SEQUENCE, seq);
}

STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
{
    ASN1_TYPE *cap;
    const unsigned char *p;

    cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
    if (cap == NULL || (cap->type != V_ASN1_SEQUENCE))
        return NULL;
    p = cap->value.sequence->data;
    return (STACK_OF(X509_ALGOR) *)
        ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
                      ASN1_ITEM_rptr(X509_ALGORS));
}

/* Basic smime-capabilities OID and optional integer arg */
int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
{
    ASN1_INTEGER *nbit = NULL;
    X509_ALGOR *alg;

    if ((alg = X509_ALGOR_new()) == NULL) {
        ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    ASN1_OBJECT_free(alg->algorithm);
    alg->algorithm = OBJ_nid2obj(nid);
    if (arg > 0) {
        if ((alg->parameter = ASN1_TYPE_new()) == NULL) {
            goto err;
        }
        if ((nbit = ASN1_INTEGER_new()) == NULL) {
            goto err;
        }
        if (!ASN1_INTEGER_set(nbit, arg)) {
            goto err;
        }
        alg->parameter->value.integer = nbit;
        alg->parameter->type = V_ASN1_INTEGER;
        nbit = NULL;
    }
    if (!sk_X509_ALGOR_push(sk, alg)) {
        goto err;
    }
    return 1;
err:
    ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
    ASN1_INTEGER_free(nbit);
    X509_ALGOR_free(alg);
    return 0;
}

int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
{
    if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
        return 0;
    if (!coid)
        coid = OBJ_nid2obj(NID_pkcs7_data);
    return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
                                      V_ASN1_OBJECT, coid);
}

int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
{
    if (t == NULL && (t = X509_gmtime_adj(NULL, 0)) == NULL) {
        ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
                                      V_ASN1_UTCTIME, t);
}

int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
                             const unsigned char *md, int mdlen)
{
    ASN1_OCTET_STRING *os;
    os = ASN1_OCTET_STRING_new();
    if (os == NULL)
        return 0;
    if (!ASN1_STRING_set(os, md, mdlen)
        || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
                                       V_ASN1_OCTET_STRING, os)) {
        ASN1_OCTET_STRING_free(os);
        return 0;
    }
    return 1;
}
