1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <stdio.h>
11e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
12e1051a39Sopenharmony_ci#include <openssl/objects.h>
13e1051a39Sopenharmony_ci#include <openssl/x509.h>
14e1051a39Sopenharmony_ci#include <openssl/pem.h>
15e1051a39Sopenharmony_ci#include <openssl/x509v3.h>
16e1051a39Sopenharmony_ci#include <openssl/ocsp.h>
17e1051a39Sopenharmony_ci#include "ocsp_local.h"
18e1051a39Sopenharmony_ci#include <openssl/asn1t.h>
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_ci/* Convert a certificate and its issuer to an OCSP_CERTID */
21e1051a39Sopenharmony_ci
22e1051a39Sopenharmony_ciOCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject,
23e1051a39Sopenharmony_ci                             const X509 *issuer)
24e1051a39Sopenharmony_ci{
25e1051a39Sopenharmony_ci    const X509_NAME *iname;
26e1051a39Sopenharmony_ci    const ASN1_INTEGER *serial;
27e1051a39Sopenharmony_ci    ASN1_BIT_STRING *ikey;
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci    if (!dgst)
30e1051a39Sopenharmony_ci        dgst = EVP_sha1();
31e1051a39Sopenharmony_ci    if (subject) {
32e1051a39Sopenharmony_ci        iname = X509_get_issuer_name(subject);
33e1051a39Sopenharmony_ci        serial = X509_get0_serialNumber(subject);
34e1051a39Sopenharmony_ci    } else {
35e1051a39Sopenharmony_ci        iname = X509_get_subject_name(issuer);
36e1051a39Sopenharmony_ci        serial = NULL;
37e1051a39Sopenharmony_ci    }
38e1051a39Sopenharmony_ci    ikey = X509_get0_pubkey_bitstr(issuer);
39e1051a39Sopenharmony_ci    return OCSP_cert_id_new(dgst, iname, ikey, serial);
40e1051a39Sopenharmony_ci}
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_ciOCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
43e1051a39Sopenharmony_ci                              const X509_NAME *issuerName,
44e1051a39Sopenharmony_ci                              const ASN1_BIT_STRING *issuerKey,
45e1051a39Sopenharmony_ci                              const ASN1_INTEGER *serialNumber)
46e1051a39Sopenharmony_ci{
47e1051a39Sopenharmony_ci    int nid;
48e1051a39Sopenharmony_ci    unsigned int i;
49e1051a39Sopenharmony_ci    X509_ALGOR *alg;
50e1051a39Sopenharmony_ci    OCSP_CERTID *cid = NULL;
51e1051a39Sopenharmony_ci    unsigned char md[EVP_MAX_MD_SIZE];
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ci    if ((cid = OCSP_CERTID_new()) == NULL)
54e1051a39Sopenharmony_ci        goto err;
55e1051a39Sopenharmony_ci
56e1051a39Sopenharmony_ci    alg = &cid->hashAlgorithm;
57e1051a39Sopenharmony_ci    ASN1_OBJECT_free(alg->algorithm);
58e1051a39Sopenharmony_ci    if ((nid = EVP_MD_get_type(dgst)) == NID_undef) {
59e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_OCSP, OCSP_R_UNKNOWN_NID);
60e1051a39Sopenharmony_ci        goto err;
61e1051a39Sopenharmony_ci    }
62e1051a39Sopenharmony_ci    if ((alg->algorithm = OBJ_nid2obj(nid)) == NULL)
63e1051a39Sopenharmony_ci        goto err;
64e1051a39Sopenharmony_ci    if ((alg->parameter = ASN1_TYPE_new()) == NULL)
65e1051a39Sopenharmony_ci        goto err;
66e1051a39Sopenharmony_ci    alg->parameter->type = V_ASN1_NULL;
67e1051a39Sopenharmony_ci
68e1051a39Sopenharmony_ci    if (!X509_NAME_digest(issuerName, dgst, md, &i))
69e1051a39Sopenharmony_ci        goto digerr;
70e1051a39Sopenharmony_ci    if (!(ASN1_OCTET_STRING_set(&cid->issuerNameHash, md, i)))
71e1051a39Sopenharmony_ci        goto err;
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_ci    /* Calculate the issuerKey hash, excluding tag and length */
74e1051a39Sopenharmony_ci    if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
75e1051a39Sopenharmony_ci        goto err;
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci    if (!(ASN1_OCTET_STRING_set(&cid->issuerKeyHash, md, i)))
78e1051a39Sopenharmony_ci        goto err;
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_ci    if (serialNumber) {
81e1051a39Sopenharmony_ci        if (ASN1_STRING_copy(&cid->serialNumber, serialNumber) == 0)
82e1051a39Sopenharmony_ci            goto err;
83e1051a39Sopenharmony_ci    }
84e1051a39Sopenharmony_ci    return cid;
85e1051a39Sopenharmony_ci digerr:
86e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_ERR);
87e1051a39Sopenharmony_ci err:
88e1051a39Sopenharmony_ci    OCSP_CERTID_free(cid);
89e1051a39Sopenharmony_ci    return NULL;
90e1051a39Sopenharmony_ci}
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_ciint OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b)
93e1051a39Sopenharmony_ci{
94e1051a39Sopenharmony_ci    int ret;
95e1051a39Sopenharmony_ci    ret = OBJ_cmp(a->hashAlgorithm.algorithm, b->hashAlgorithm.algorithm);
96e1051a39Sopenharmony_ci    if (ret)
97e1051a39Sopenharmony_ci        return ret;
98e1051a39Sopenharmony_ci    ret = ASN1_OCTET_STRING_cmp(&a->issuerNameHash, &b->issuerNameHash);
99e1051a39Sopenharmony_ci    if (ret)
100e1051a39Sopenharmony_ci        return ret;
101e1051a39Sopenharmony_ci    return ASN1_OCTET_STRING_cmp(&a->issuerKeyHash, &b->issuerKeyHash);
102e1051a39Sopenharmony_ci}
103e1051a39Sopenharmony_ci
104e1051a39Sopenharmony_ciint OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b)
105e1051a39Sopenharmony_ci{
106e1051a39Sopenharmony_ci    int ret;
107e1051a39Sopenharmony_ci    ret = OCSP_id_issuer_cmp(a, b);
108e1051a39Sopenharmony_ci    if (ret)
109e1051a39Sopenharmony_ci        return ret;
110e1051a39Sopenharmony_ci    return ASN1_INTEGER_cmp(&a->serialNumber, &b->serialNumber);
111e1051a39Sopenharmony_ci}
112e1051a39Sopenharmony_ci
113e1051a39Sopenharmony_ciIMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)
114