/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "cert.h"
#include "certt.h"
#include "secder.h"
#include "keyhi.h"
#include "secitem.h"
#include "secasn1.h"
#include "secerr.h"

SEC_ASN1_MKSUB(SEC_AnyTemplate)

const SEC_ASN1Template CERT_AttributeTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTAttribute) },
    { SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) },
    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue),
      SEC_ASN1_SUB(SEC_AnyTemplate) },
    { 0 }
};

const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = {
    { SEC_ASN1_SET_OF, 0, CERT_AttributeTemplate },
};

const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTCertificateRequest) },
    { SEC_ASN1_INTEGER,
      offsetof(CERTCertificateRequest, version) },
    { SEC_ASN1_INLINE,
      offsetof(CERTCertificateRequest, subject),
      CERT_NameTemplate },
    { SEC_ASN1_INLINE,
      offsetof(CERTCertificateRequest, subjectPublicKeyInfo),
      CERT_SubjectPublicKeyInfoTemplate },
    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(CERTCertificateRequest, attributes),
      CERT_SetOfAttributeTemplate },
    { 0 }
};

SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate)

CERTCertificate *
CERT_CreateCertificate(unsigned long serialNumber,
                       CERTName *issuer,
                       CERTValidity *validity,
                       CERTCertificateRequest *req)
{
    CERTCertificate *c;
    int rv;
    PLArenaPool *arena;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        return (0);
    }

    c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));

    if (!c) {
        PORT_FreeArena(arena, PR_FALSE);
        return 0;
    }

    c->referenceCount = 1;
    c->arena = arena;

    /*
     * Default is a plain version 1.
     * If extensions are added, it will get changed as appropriate.
     */
    rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1);
    if (rv)
        goto loser;

    rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber);
    if (rv)
        goto loser;

    rv = CERT_CopyName(arena, &c->issuer, issuer);
    if (rv)
        goto loser;

    rv = CERT_CopyValidity(arena, &c->validity, validity);
    if (rv)
        goto loser;

    rv = CERT_CopyName(arena, &c->subject, &req->subject);
    if (rv)
        goto loser;
    rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
                                         &req->subjectPublicKeyInfo);
    if (rv)
        goto loser;

    return c;

loser:
    CERT_DestroyCertificate(c);
    return 0;
}

/************************************************************************/
/* It's clear from the comments that the original author of this
 * function expected the template for certificate requests to treat
 * the attributes as a SET OF ANY.  This function expected to be
 * passed an array of SECItems each of which contained an already encoded
 * Attribute.  But the cert request template does not treat the
 * Attributes as a SET OF ANY, and AFAIK never has.  Instead the template
 * encodes attributes as a SET OF xxxxxxx.  That is, it expects to encode
 * each of the Attributes, not have them pre-encoded.  Consequently an
 * array of SECItems containing encoded Attributes is of no value to this
 * function.  But we cannot change the signature of this public function.
 * It must continue to take SECItems.
 *
 * I have recoded this function so that each SECItem contains an
 * encoded cert extension.  The encoded cert extensions form the list for the
 * single attribute of the cert request. In this implementation there is at most
 * one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST.
 */

CERTCertificateRequest *
CERT_CreateCertificateRequest(CERTName *subject,
                              CERTSubjectPublicKeyInfo *spki,
                              SECItem **attributes)
{
    CERTCertificateRequest *certreq;
    PLArenaPool *arena;
    CERTAttribute *attribute;
    SECOidData *oidData;
    SECStatus rv;
    int i = 0;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        return NULL;
    }

    certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
    if (!certreq) {
        PORT_FreeArena(arena, PR_FALSE);
        return NULL;
    }
    /* below here it is safe to goto loser */

    certreq->arena = arena;

    rv = DER_SetUInteger(arena, &certreq->version,
                         SEC_CERTIFICATE_REQUEST_VERSION);
    if (rv != SECSuccess)
        goto loser;

    rv = CERT_CopyName(arena, &certreq->subject, subject);
    if (rv != SECSuccess)
        goto loser;

    rv = SECKEY_CopySubjectPublicKeyInfo(arena,
                                         &certreq->subjectPublicKeyInfo,
                                         spki);
    if (rv != SECSuccess)
        goto loser;

    certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute *, 2);
    if (!certreq->attributes)
        goto loser;

    /* Copy over attribute information */
    if (!attributes || !attributes[0]) {
        /*
	 ** Invent empty attribute information. According to the
	 ** pkcs#10 spec, attributes has this ASN.1 type:
	 **
	 ** attributes [0] IMPLICIT Attributes
	 **
	 ** Which means, we should create a NULL terminated list
	 ** with the first entry being NULL;
	 */
        certreq->attributes[0] = NULL;
        return certreq;
    }

    /* allocate space for attributes */
    attribute = PORT_ArenaZNew(arena, CERTAttribute);
    if (!attribute)
        goto loser;

    oidData = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
    PORT_Assert(oidData);
    if (!oidData)
        goto loser;
    rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
    if (rv != SECSuccess)
        goto loser;

    for (i = 0; attributes[i] != NULL; i++)
        ;
    attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i + 1);
    if (!attribute->attrValue)
        goto loser;

    /* copy attributes */
    for (i = 0; attributes[i]; i++) {
        /*
	** Attributes are a SetOf Attribute which implies
	** lexigraphical ordering.  It is assumes that the
	** attributes are passed in sorted.  If we need to
	** add functionality to sort them, there is an
	** example in the PKCS 7 code.
	*/
        attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
        if (!attribute->attrValue[i])
            goto loser;
    }

    certreq->attributes[0] = attribute;

    return certreq;

loser:
    CERT_DestroyCertificateRequest(certreq);
    return NULL;
}

void
CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
{
    if (req && req->arena) {
        PORT_FreeArena(req->arena, PR_FALSE);
    }
    return;
}

static void
setCRExt(void *o, CERTCertExtension **exts)
{
    ((CERTCertificateRequest *)o)->attributes = (struct CERTAttributeStr **)exts;
}

/*
** Set up to start gathering cert extensions for a cert request.
** The list is created as CertExtensions and converted to an
** attribute list by CERT_FinishCRAttributes().
 */
extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
                                  void (*setExts)(void *object, CERTCertExtension **exts));
void *
CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
{
    return (cert_StartExtensions((void *)req, req->arena, setCRExt));
}

/*
** At entry req->attributes actually contains an list of cert extensions--
** req-attributes is overloaded until the list is DER encoded (the first
** ...EncodeItem() below).
** We turn this into an attribute list by encapsulating it
** in a PKCS 10 Attribute structure
 */
SECStatus
CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
{
    SECItem *extlist;
    SECOidData *oidrec;
    CERTAttribute *attribute;

    if (!req || !req->arena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (req->attributes == NULL || req->attributes[0] == NULL)
        return SECSuccess;

    extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes,
                                 SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
    if (extlist == NULL)
        return (SECFailure);

    oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
    if (oidrec == NULL)
        return SECFailure;

    /* now change the list of cert extensions into a list of attributes
     */
    req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute *, 2);

    attribute = PORT_ArenaZNew(req->arena, CERTAttribute);

    if (req->attributes == NULL || attribute == NULL ||
        SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
    attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem *, 2);

    if (attribute->attrValue == NULL)
        return SECFailure;

    attribute->attrValue[0] = extlist;
    attribute->attrValue[1] = NULL;
    req->attributes[0] = attribute;
    req->attributes[1] = NULL;

    return SECSuccess;
}

SECStatus
CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
                                     CERTCertExtension ***exts)
{
    if (req == NULL || exts == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (req->attributes == NULL || *req->attributes == NULL)
        return SECSuccess;

    if ((*req->attributes)->attrValue == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    return (SEC_ASN1DecodeItem(req->arena, exts,
                               SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
                               (*req->attributes)->attrValue[0]));
}
