1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2012-2020 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 <openssl/crypto.h>
12e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
13e1051a39Sopenharmony_ci#include <openssl/conf.h>
14e1051a39Sopenharmony_ci#include <openssl/x509v3.h>
15e1051a39Sopenharmony_ci
16e1051a39Sopenharmony_ci/* Multi string module: add table entries from a given section */
17e1051a39Sopenharmony_ci
18e1051a39Sopenharmony_cistatic int do_tcreate(const char *value, const char *name);
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_cistatic int stbl_module_init(CONF_IMODULE *md, const CONF *cnf)
21e1051a39Sopenharmony_ci{
22e1051a39Sopenharmony_ci    int i;
23e1051a39Sopenharmony_ci    const char *stbl_section;
24e1051a39Sopenharmony_ci    STACK_OF(CONF_VALUE) *sktmp;
25e1051a39Sopenharmony_ci    CONF_VALUE *mval;
26e1051a39Sopenharmony_ci
27e1051a39Sopenharmony_ci    stbl_section = CONF_imodule_get_value(md);
28e1051a39Sopenharmony_ci    if ((sktmp = NCONF_get_section(cnf, stbl_section)) == NULL) {
29e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_ASN1, ASN1_R_ERROR_LOADING_SECTION);
30e1051a39Sopenharmony_ci        return 0;
31e1051a39Sopenharmony_ci    }
32e1051a39Sopenharmony_ci    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
33e1051a39Sopenharmony_ci        mval = sk_CONF_VALUE_value(sktmp, i);
34e1051a39Sopenharmony_ci        if (!do_tcreate(mval->value, mval->name)) {
35e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_VALUE);
36e1051a39Sopenharmony_ci            return 0;
37e1051a39Sopenharmony_ci        }
38e1051a39Sopenharmony_ci    }
39e1051a39Sopenharmony_ci    return 1;
40e1051a39Sopenharmony_ci}
41e1051a39Sopenharmony_ci
42e1051a39Sopenharmony_cistatic void stbl_module_finish(CONF_IMODULE *md)
43e1051a39Sopenharmony_ci{
44e1051a39Sopenharmony_ci    ASN1_STRING_TABLE_cleanup();
45e1051a39Sopenharmony_ci}
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_civoid ASN1_add_stable_module(void)
48e1051a39Sopenharmony_ci{
49e1051a39Sopenharmony_ci    CONF_module_add("stbl_section", stbl_module_init, stbl_module_finish);
50e1051a39Sopenharmony_ci}
51e1051a39Sopenharmony_ci
52e1051a39Sopenharmony_ci/*
53e1051a39Sopenharmony_ci * Create an table entry based on a name value pair. format is oid_name =
54e1051a39Sopenharmony_ci * n1:v1, n2:v2,... where name is "min", "max", "mask" or "flags".
55e1051a39Sopenharmony_ci */
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_cistatic int do_tcreate(const char *value, const char *name)
58e1051a39Sopenharmony_ci{
59e1051a39Sopenharmony_ci    char *eptr;
60e1051a39Sopenharmony_ci    int nid, i, rv = 0;
61e1051a39Sopenharmony_ci    long tbl_min = -1, tbl_max = -1;
62e1051a39Sopenharmony_ci    unsigned long tbl_mask = 0, tbl_flags = 0;
63e1051a39Sopenharmony_ci    STACK_OF(CONF_VALUE) *lst = NULL;
64e1051a39Sopenharmony_ci    CONF_VALUE *cnf = NULL;
65e1051a39Sopenharmony_ci    nid = OBJ_sn2nid(name);
66e1051a39Sopenharmony_ci    if (nid == NID_undef)
67e1051a39Sopenharmony_ci        nid = OBJ_ln2nid(name);
68e1051a39Sopenharmony_ci    if (nid == NID_undef)
69e1051a39Sopenharmony_ci        goto err;
70e1051a39Sopenharmony_ci    lst = X509V3_parse_list(value);
71e1051a39Sopenharmony_ci    if (!lst)
72e1051a39Sopenharmony_ci        goto err;
73e1051a39Sopenharmony_ci    for (i = 0; i < sk_CONF_VALUE_num(lst); i++) {
74e1051a39Sopenharmony_ci        cnf = sk_CONF_VALUE_value(lst, i);
75e1051a39Sopenharmony_ci        if (strcmp(cnf->name, "min") == 0) {
76e1051a39Sopenharmony_ci            tbl_min = strtoul(cnf->value, &eptr, 0);
77e1051a39Sopenharmony_ci            if (*eptr)
78e1051a39Sopenharmony_ci                goto err;
79e1051a39Sopenharmony_ci        } else if (strcmp(cnf->name, "max") == 0) {
80e1051a39Sopenharmony_ci            tbl_max = strtoul(cnf->value, &eptr, 0);
81e1051a39Sopenharmony_ci            if (*eptr)
82e1051a39Sopenharmony_ci                goto err;
83e1051a39Sopenharmony_ci        } else if (strcmp(cnf->name, "mask") == 0) {
84e1051a39Sopenharmony_ci            if (!ASN1_str2mask(cnf->value, &tbl_mask) || !tbl_mask)
85e1051a39Sopenharmony_ci                goto err;
86e1051a39Sopenharmony_ci        } else if (strcmp(cnf->name, "flags") == 0) {
87e1051a39Sopenharmony_ci            if (strcmp(cnf->value, "nomask") == 0)
88e1051a39Sopenharmony_ci                tbl_flags = STABLE_NO_MASK;
89e1051a39Sopenharmony_ci            else if (strcmp(cnf->value, "none") == 0)
90e1051a39Sopenharmony_ci                tbl_flags = STABLE_FLAGS_CLEAR;
91e1051a39Sopenharmony_ci            else
92e1051a39Sopenharmony_ci                goto err;
93e1051a39Sopenharmony_ci        } else
94e1051a39Sopenharmony_ci            goto err;
95e1051a39Sopenharmony_ci    }
96e1051a39Sopenharmony_ci    rv = 1;
97e1051a39Sopenharmony_ci err:
98e1051a39Sopenharmony_ci    if (rv == 0) {
99e1051a39Sopenharmony_ci        if (cnf)
100e1051a39Sopenharmony_ci            ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE,
101e1051a39Sopenharmony_ci                           "field=%s, value=%s", cnf->name, cnf->value);
102e1051a39Sopenharmony_ci        else
103e1051a39Sopenharmony_ci            ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE,
104e1051a39Sopenharmony_ci                           "name=%s, value=%s", name, value);
105e1051a39Sopenharmony_ci    } else {
106e1051a39Sopenharmony_ci        rv = ASN1_STRING_TABLE_add(nid, tbl_min, tbl_max,
107e1051a39Sopenharmony_ci                                   tbl_mask, tbl_flags);
108e1051a39Sopenharmony_ci        if (!rv)
109e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
110e1051a39Sopenharmony_ci    }
111e1051a39Sopenharmony_ci    sk_CONF_VALUE_pop_free(lst, X509V3_conf_free);
112e1051a39Sopenharmony_ci    return rv;
113e1051a39Sopenharmony_ci}
114