1/*
2 * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include "internal/cryptlib.h"
12#include <openssl/asn1t.h>
13#include <openssl/conf.h>
14#include <openssl/x509v3.h>
15#include "ext_dat.h"
16
17static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
18                                    X509V3_CTX *ctx,
19                                    STACK_OF(CONF_VALUE) *nval);
20static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
21                                                    *method, void *eku, STACK_OF(CONF_VALUE)
22                                                    *extlist);
23
24const X509V3_EXT_METHOD ossl_v3_ext_ku = {
25    NID_ext_key_usage, 0,
26    ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
27    0, 0, 0, 0,
28    0, 0,
29    i2v_EXTENDED_KEY_USAGE,
30    v2i_EXTENDED_KEY_USAGE,
31    0, 0,
32    NULL
33};
34
35/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
36const X509V3_EXT_METHOD ossl_v3_ocsp_accresp = {
37    NID_id_pkix_OCSP_acceptableResponses, 0,
38    ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
39    0, 0, 0, 0,
40    0, 0,
41    i2v_EXTENDED_KEY_USAGE,
42    v2i_EXTENDED_KEY_USAGE,
43    0, 0,
44    NULL
45};
46
47ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) =
48        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
49ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
50
51IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
52
53static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
54                                                    *method, void *a, STACK_OF(CONF_VALUE)
55                                                    *ext_list)
56{
57    EXTENDED_KEY_USAGE *eku = a;
58    int i;
59    ASN1_OBJECT *obj;
60    char obj_tmp[80];
61    for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
62        obj = sk_ASN1_OBJECT_value(eku, i);
63        i2t_ASN1_OBJECT(obj_tmp, 80, obj);
64        X509V3_add_value(NULL, obj_tmp, &ext_list);
65    }
66    return ext_list;
67}
68
69static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
70                                    X509V3_CTX *ctx,
71                                    STACK_OF(CONF_VALUE) *nval)
72{
73    EXTENDED_KEY_USAGE *extku;
74    char *extval;
75    ASN1_OBJECT *objtmp;
76    CONF_VALUE *val;
77    const int num = sk_CONF_VALUE_num(nval);
78    int i;
79
80    extku = sk_ASN1_OBJECT_new_reserve(NULL, num);
81    if (extku == NULL) {
82        ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
83        sk_ASN1_OBJECT_free(extku);
84        return NULL;
85    }
86
87    for (i = 0; i < num; i++) {
88        val = sk_CONF_VALUE_value(nval, i);
89        if (val->value)
90            extval = val->value;
91        else
92            extval = val->name;
93        if ((objtmp = OBJ_txt2obj(extval, 0)) == NULL) {
94            sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
95            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER,
96                           "%s", extval);
97            return NULL;
98        }
99        sk_ASN1_OBJECT_push(extku, objtmp);  /* no failure as it was reserved */
100    }
101    return extku;
102}
103