/* 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 "plarena.h"

#include "seccomon.h"
#include "secitem.h"
#include "secasn1.h"
#include "secder.h"
#include "cert.h"
#include "secerr.h"
#include "secoid.h"
#include "sechash.h"
#include "keyhi.h"
#include "cryptohi.h"
#include "ocsp.h"
#include "ocspti.h"
#include "ocspi.h"
#include "pk11pub.h"

extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[];
extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[];
extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[];

ocspCertStatus *
ocsp_CreateCertStatus(PLArenaPool *arena,
                      ocspCertStatusType status,
                      PRTime revocationTime)
{
    ocspCertStatus *cs;

    if (!arena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    switch (status) {
        case ocspCertStatus_good:
        case ocspCertStatus_unknown:
        case ocspCertStatus_revoked:
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return NULL;
    }

    cs = PORT_ArenaZNew(arena, ocspCertStatus);
    if (!cs)
        return NULL;
    cs->certStatusType = status;
    switch (status) {
        case ocspCertStatus_good:
            cs->certStatusInfo.goodInfo = SECITEM_AllocItem(arena, NULL, 0);
            if (!cs->certStatusInfo.goodInfo)
                return NULL;
            break;
        case ocspCertStatus_unknown:
            cs->certStatusInfo.unknownInfo = SECITEM_AllocItem(arena, NULL, 0);
            if (!cs->certStatusInfo.unknownInfo)
                return NULL;
            break;
        case ocspCertStatus_revoked:
            cs->certStatusInfo.revokedInfo =
                PORT_ArenaZNew(arena, ocspRevokedInfo);
            if (!cs->certStatusInfo.revokedInfo)
                return NULL;
            cs->certStatusInfo.revokedInfo->revocationReason =
                SECITEM_AllocItem(arena, NULL, 0);
            if (!cs->certStatusInfo.revokedInfo->revocationReason)
                return NULL;
            if (DER_TimeToGeneralizedTimeArena(arena,
                                               &cs->certStatusInfo.revokedInfo->revocationTime,
                                               revocationTime) !=
                SECSuccess)
                return NULL;
            break;
        default:
            PORT_Assert(PR_FALSE);
    }
    return cs;
}

static const SEC_ASN1Template mySEC_EnumeratedTemplate[] = {
    { SEC_ASN1_ENUMERATED, 0, NULL, sizeof(SECItem) }
};

static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = {
    { SEC_ASN1_POINTER, 0, mySEC_EnumeratedTemplate }
};

static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = {
    { SEC_ASN1_GENERALIZED_TIME,
      offsetof(ocspRevokedInfo, revocationTime) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(ocspRevokedInfo, revocationReason),
      mySEC_PointerToEnumeratedTemplate },
    { 0 }
};

static const SEC_ASN1Template ocsp_PointerToEncodeRevokedInfoTemplate[] = {
    { SEC_ASN1_POINTER, 0,
      ocsp_EncodeRevokedInfoTemplate }
};

static const SEC_ASN1Template mySEC_NullTemplate[] = {
    { SEC_ASN1_NULL, 0, NULL, sizeof(SECItem) }
};

static const SEC_ASN1Template ocsp_CertStatusTemplate[] = {
    { SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType),
      0, sizeof(ocspCertStatus) },
    { SEC_ASN1_CONTEXT_SPECIFIC | 0,
      0, mySEC_NullTemplate, ocspCertStatus_good },
    { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
          SEC_ASN1_CONTEXT_SPECIFIC | 1,
      offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
      ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
    { SEC_ASN1_CONTEXT_SPECIFIC | 2,
      0, mySEC_NullTemplate, ocspCertStatus_unknown },
    { 0 }
};

static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(SECAlgorithmID) },
    { SEC_ASN1_OBJECT_ID,
      offsetof(SECAlgorithmID, algorithm) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
      offsetof(SECAlgorithmID, parameters) },
    { 0 }
};

static const SEC_ASN1Template mySEC_AnyTemplate[] = {
    { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
};

static const SEC_ASN1Template mySEC_SequenceOfAnyTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF, 0, mySEC_AnyTemplate }
};

static const SEC_ASN1Template mySEC_PointerToSequenceOfAnyTemplate[] = {
    { SEC_ASN1_POINTER, 0, mySEC_SequenceOfAnyTemplate }
};

static const SEC_ASN1Template mySEC_IntegerTemplate[] = {
    { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) }
};

static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = {
    { SEC_ASN1_POINTER, 0, mySEC_IntegerTemplate }
};

static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = {
    { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
};

static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
    { SEC_ASN1_POINTER, 0, mySEC_GeneralizedTimeTemplate }
};

static const SEC_ASN1Template ocsp_myCertIDTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTOCSPCertID) },
    { SEC_ASN1_INLINE,
      offsetof(CERTOCSPCertID, hashAlgorithm),
      mySECOID_AlgorithmIDTemplate },
    { SEC_ASN1_OCTET_STRING,
      offsetof(CERTOCSPCertID, issuerNameHash) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(CERTOCSPCertID, issuerKeyHash) },
    { SEC_ASN1_INTEGER,
      offsetof(CERTOCSPCertID, serialNumber) },
    { 0 }
};

static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTCertExtension) },
    { SEC_ASN1_OBJECT_ID,
      offsetof(CERTCertExtension, id) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
      offsetof(CERTCertExtension, critical) },
    { SEC_ASN1_OCTET_STRING,
      offsetof(CERTCertExtension, value) },
    { 0 }
};

static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF, 0, myCERT_CertExtensionTemplate }
};

static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[] = {
    { SEC_ASN1_POINTER, 0, myCERT_SequenceOfCertExtensionTemplate }
};

static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTOCSPSingleResponse) },
    { SEC_ASN1_POINTER,
      offsetof(CERTOCSPSingleResponse, certID),
      ocsp_myCertIDTemplate },
    { SEC_ASN1_ANY,
      offsetof(CERTOCSPSingleResponse, derCertStatus) },
    { SEC_ASN1_GENERALIZED_TIME,
      offsetof(CERTOCSPSingleResponse, thisUpdate) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(CERTOCSPSingleResponse, nextUpdate),
      mySEC_PointerToGeneralizedTimeTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
      offsetof(CERTOCSPSingleResponse, singleExtensions),
      myCERT_PointerToSequenceOfCertExtensionTemplate },
    { 0 }
};

static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspResponseData) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(ocspResponseData, version),
      mySEC_PointerToIntegerTemplate },
    { SEC_ASN1_ANY,
      offsetof(ocspResponseData, derResponderID) },
    { SEC_ASN1_GENERALIZED_TIME,
      offsetof(ocspResponseData, producedAt) },
    { SEC_ASN1_SEQUENCE_OF,
      offsetof(ocspResponseData, responses),
      ocsp_mySingleResponseTemplate },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
      offsetof(ocspResponseData, responseExtensions),
      myCERT_PointerToSequenceOfCertExtensionTemplate },
    { 0 }
};

static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(ocspBasicOCSPResponse) },
    { SEC_ASN1_POINTER,
      offsetof(ocspBasicOCSPResponse, tbsResponseData),
      ocsp_myResponseDataTemplate },
    { SEC_ASN1_INLINE,
      offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
      mySECOID_AlgorithmIDTemplate },
    { SEC_ASN1_BIT_STRING,
      offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
          SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
      offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
      mySEC_PointerToSequenceOfAnyTemplate },
    { 0 }
};

static CERTOCSPSingleResponse *
ocsp_CreateSingleResponse(PLArenaPool *arena,
                          CERTOCSPCertID *id, ocspCertStatus *status,
                          PRTime thisUpdate, const PRTime *nextUpdate)
{
    CERTOCSPSingleResponse *sr;

    if (!arena || !id || !status) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    sr = PORT_ArenaZNew(arena, CERTOCSPSingleResponse);
    if (!sr)
        return NULL;
    sr->arena = arena;
    sr->certID = id;
    sr->certStatus = status;
    if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate) !=
        SECSuccess)
        return NULL;
    sr->nextUpdate = NULL;
    if (nextUpdate) {
        sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0);
        if (!sr->nextUpdate)
            return NULL;
        if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate) !=
            SECSuccess)
            return NULL;
    }

    sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension *, 1);
    if (!sr->singleExtensions)
        return NULL;

    sr->singleExtensions[0] = NULL;

    if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus,
                            status, ocsp_CertStatusTemplate))
        return NULL;

    return sr;
}

CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
                                  CERTOCSPCertID *id,
                                  PRTime thisUpdate,
                                  const PRTime *nextUpdate)
{
    ocspCertStatus *cs;
    if (!arena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    cs = ocsp_CreateCertStatus(arena, ocspCertStatus_good, 0);
    if (!cs)
        return NULL;
    return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
}

CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
                                     CERTOCSPCertID *id,
                                     PRTime thisUpdate,
                                     const PRTime *nextUpdate)
{
    ocspCertStatus *cs;
    if (!arena) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    cs = ocsp_CreateCertStatus(arena, ocspCertStatus_unknown, 0);
    if (!cs)
        return NULL;
    return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
}

CERTOCSPSingleResponse *
CERT_CreateOCSPSingleResponseRevoked(
    PLArenaPool *arena,
    CERTOCSPCertID *id,
    PRTime thisUpdate,
    const PRTime *nextUpdate,
    PRTime revocationTime,
    const CERTCRLEntryReasonCode *revocationReason)
{
    ocspCertStatus *cs;
    /* revocationReason is not yet supported, so it must be NULL. */
    if (!arena || revocationReason) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    cs = ocsp_CreateCertStatus(arena, ocspCertStatus_revoked, revocationTime);
    if (!cs)
        return NULL;
    return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
}

/* responderCert == 0 means:
 * create a response with an invalid signature (for testing purposes) */
SECItem *
CERT_CreateEncodedOCSPSuccessResponse(
    PLArenaPool *arena,
    CERTCertificate *responderCert,
    CERTOCSPResponderIDType responderIDType,
    PRTime producedAt,
    CERTOCSPSingleResponse **responses,
    void *wincx)
{
    PLArenaPool *tmpArena;
    ocspResponseData *rd = NULL;
    ocspResponderID *rid = NULL;
    const SEC_ASN1Template *responderIDTemplate = NULL;
    ocspBasicOCSPResponse *br = NULL;
    ocspResponseBytes *rb = NULL;
    CERTOCSPResponse *response = NULL;

    SECOidTag algID;
    SECOidData *od = NULL;
    SECKEYPrivateKey *privKey = NULL;
    SECItem *result = NULL;

    if (!arena || !responses) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    if (responderIDType != ocspResponderID_byName &&
        responderIDType != ocspResponderID_byKey) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!tmpArena)
        return NULL;

    rd = PORT_ArenaZNew(tmpArena, ocspResponseData);
    if (!rd)
        goto done;
    rid = PORT_ArenaZNew(tmpArena, ocspResponderID);
    if (!rid)
        goto done;
    br = PORT_ArenaZNew(tmpArena, ocspBasicOCSPResponse);
    if (!br)
        goto done;
    rb = PORT_ArenaZNew(tmpArena, ocspResponseBytes);
    if (!rb)
        goto done;
    response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse);
    if (!response)
        goto done;

    rd->version.data = NULL;
    rd->version.len = 0;
    rd->responseExtensions = NULL;
    rd->responses = responses;
    if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) !=
        SECSuccess)
        goto done;

    if (!responderCert) {
        /* use invalid signature for testing purposes */
        unsigned char dummyChar = 'd';
        SECItem dummy;

        dummy.len = 1;
        dummy.data = &dummyChar;

        /* it's easier to produdce a keyHash out of nowhere,
    	 * than to produce an encoded subject,
    	 * so for our dummy response we always use byKey
    	 */

        rid->responderIDType = ocspResponderID_byKey;
        if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
                              &dummy))
            goto done;

        if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
                                ocsp_ResponderIDByKeyTemplate))
            goto done;

        br->tbsResponseData = rd;

        if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
                                ocsp_myResponseDataTemplate))
            goto done;

        br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1);
        if (!br->responseSignature.derCerts)
            goto done;
        br->responseSignature.derCerts[0] = NULL;

        algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
        if (algID == SEC_OID_UNKNOWN)
            goto done;

        /* match the regular signature code, which doesn't use the arena */
        if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1))
            goto done;
        PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);

        /* convert len-in-bytes to len-in-bits */
        br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
    } else {
        rid->responderIDType = responderIDType;
        if (responderIDType == ocspResponderID_byName) {
            responderIDTemplate = ocsp_ResponderIDByNameTemplate;
            if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
                              &responderCert->subject) != SECSuccess)
                goto done;
        } else {
            responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
            if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert,
                                                SEC_OID_SHA1, &rid->responderIDValue.keyHash))
                goto done;
        }

        if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
                                responderIDTemplate))
            goto done;

        br->tbsResponseData = rd;

        if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
                                ocsp_myResponseDataTemplate))
            goto done;

        br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1);
        if (!br->responseSignature.derCerts)
            goto done;
        br->responseSignature.derCerts[0] = NULL;

        privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
        if (!privKey)
            goto done;

        algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
        if (algID == SEC_OID_UNKNOWN)
            goto done;

        if (SEC_SignData(&br->responseSignature.signature,
                         br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
                         privKey, algID) !=
            SECSuccess)
            goto done;

        /* convert len-in-bytes to len-in-bits */
        br->responseSignature.signature.len = br->responseSignature.signature.len << 3;

        /* br->responseSignature.signature wasn't allocated from arena,
	     * we must free it when done. */
    }

    if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) !=
        SECSuccess)
        goto done;

    if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
                            ocsp_EncodeBasicOCSPResponseTemplate))
        goto done;

    rb->responseTypeTag = SEC_OID_PKIX_OCSP_BASIC_RESPONSE;

    od = SECOID_FindOIDByTag(rb->responseTypeTag);
    if (!od)
        goto done;

    rb->responseType = od->oid;
    rb->decodedResponse.basic = br;

    response->arena = tmpArena;
    response->responseBytes = rb;
    response->statusValue = ocspResponse_successful;

    if (!SEC_ASN1EncodeInteger(tmpArena, &response->responseStatus,
                               response->statusValue))
        goto done;

    result = SEC_ASN1EncodeItem(arena, NULL, response, ocsp_OCSPResponseTemplate);

done:
    if (privKey)
        SECKEY_DestroyPrivateKey(privKey);
    if (br && br->responseSignature.signature.data)
        SECITEM_FreeItem(&br->responseSignature.signature, PR_FALSE);
    PORT_FreeArena(tmpArena, PR_FALSE);

    return result;
}

static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(CERTOCSPResponse) },
    { SEC_ASN1_ENUMERATED,
      offsetof(CERTOCSPResponse, responseStatus) },
    { 0, 0,
      mySEC_NullTemplate },
    { 0 }
};

SECItem *
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error)
{
    CERTOCSPResponse response;
    SECItem *result = NULL;

    switch (error) {
        case SEC_ERROR_OCSP_MALFORMED_REQUEST:
            response.statusValue = ocspResponse_malformedRequest;
            break;
        case SEC_ERROR_OCSP_SERVER_ERROR:
            response.statusValue = ocspResponse_internalError;
            break;
        case SEC_ERROR_OCSP_TRY_SERVER_LATER:
            response.statusValue = ocspResponse_tryLater;
            break;
        case SEC_ERROR_OCSP_REQUEST_NEEDS_SIG:
            response.statusValue = ocspResponse_sigRequired;
            break;
        case SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST:
            response.statusValue = ocspResponse_unauthorized;
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return NULL;
    }

    if (!SEC_ASN1EncodeInteger(NULL, &response.responseStatus,
                               response.statusValue))
        return NULL;

    result = SEC_ASN1EncodeItem(arena, NULL, &response,
                                ocsp_OCSPErrorResponseTemplate);

    SECITEM_FreeItem(&response.responseStatus, PR_FALSE);

    return result;
}
