/* 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/. */

/*
 * X.509 v3 Subject Key Usage Extension
 *
 */

#include "prtypes.h"
#include "seccomon.h"
#include "secdert.h"
#include "secoidt.h"
#include "secasn1t.h"
#include "secasn1.h"
#include "secport.h"
#include "certt.h"
#include "genname.h"
#include "secerr.h"

SEC_ASN1_MKSUB(SEC_IntegerTemplate)
SEC_ASN1_MKSUB(SEC_OctetStringTemplate)

const SEC_ASN1Template CERTAuthKeyIDTemplate[] = {
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
      offsetof(CERTAuthKeyID, keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
      offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
      offsetof(CERTAuthKeyID, authCertSerialNumber),
      SEC_ASN1_SUB(SEC_IntegerTemplate) },
    { 0 }
};

SECStatus
CERT_EncodeAuthKeyID(PLArenaPool *arena, CERTAuthKeyID *value,
                     SECItem *encodedValue)
{
    SECStatus rv = SECFailure;

    PORT_Assert(value);
    PORT_Assert(arena);
    PORT_Assert(value->DERAuthCertIssuer == NULL);
    PORT_Assert(encodedValue);

    do {

        /* If both of the authCertIssuer and the serial number exist, encode
           the name first.  Otherwise, it is an error if one exist and the other
           is not.
         */
        if (value->authCertIssuer) {
            if (!value->authCertSerialNumber.data) {
                PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
                break;
            }

            value->DERAuthCertIssuer =
                cert_EncodeGeneralNames(arena, value->authCertIssuer);
            if (!value->DERAuthCertIssuer) {
                PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
                break;
            }
        } else if (value->authCertSerialNumber.data) {
            PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
            break;
        }

        if (SEC_ASN1EncodeItem(arena, encodedValue, value,
                               CERTAuthKeyIDTemplate) == NULL)
            break;
        rv = SECSuccess;

    } while (0);
    return (rv);
}

CERTAuthKeyID *
CERT_DecodeAuthKeyID(PLArenaPool *arena, const SECItem *encodedValue)
{
    CERTAuthKeyID *value = NULL;
    SECStatus rv = SECFailure;
    void *mark;
    SECItem newEncodedValue;

    PORT_Assert(arena);

    do {
        mark = PORT_ArenaMark(arena);
        value = (CERTAuthKeyID *)PORT_ArenaZAlloc(arena, sizeof(*value));
        if (value == NULL)
            break;
        value->DERAuthCertIssuer = NULL;
        /* copy the DER into the arena, since Quick DER returns data that points
           into the DER input, which may get freed by the caller */
        rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
        if (rv != SECSuccess) {
            break;
        }

        rv = SEC_QuickDERDecodeItem(arena, value, CERTAuthKeyIDTemplate,
                                    &newEncodedValue);
        if (rv != SECSuccess)
            break;

        value->authCertIssuer =
            cert_DecodeGeneralNames(arena, value->DERAuthCertIssuer);
        if (value->authCertIssuer == NULL)
            break;

        /* what if the general name contains other format but not URI ?
           hl
         */
        if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
            (!value->authCertSerialNumber.data && value->authCertIssuer)) {
            PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
            break;
        }
    } while (0);

    if (rv != SECSuccess) {
        PORT_ArenaRelease(arena, mark);
        return ((CERTAuthKeyID *)NULL);
    }
    PORT_ArenaUnmark(arena, mark);
    return (value);
}
