Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 1 | /* |
Richard Levitte | 4333b89 | 2021-01-28 13:54:57 +0100 | [diff] [blame] | 2 | * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. |
Rich Salz | d2e9e32 | 2016-05-17 14:51:26 -0400 | [diff] [blame] | 3 | * |
Richard Levitte | 4286ca4 | 2018-12-06 14:00:54 +0100 | [diff] [blame] | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
Rich Salz | d2e9e32 | 2016-05-17 14:51:26 -0400 | [diff] [blame] | 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 |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 8 | */ |
Rich Salz | d2e9e32 | 2016-05-17 14:51:26 -0400 | [diff] [blame] | 9 | |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 10 | /* extension creation utilities */ |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 11 | |
Dr. Stephen Henson | e527ba0 | 1999-02-22 01:26:40 +0000 | [diff] [blame] | 12 | #include <stdio.h> |
Dr. Matthias St. Pierre | 25f2138 | 2019-09-28 00:45:33 +0200 | [diff] [blame] | 13 | #include "crypto/ctype.h" |
Richard Levitte | b39fc56 | 2015-05-14 16:56:48 +0200 | [diff] [blame] | 14 | #include "internal/cryptlib.h" |
Bodo Möller | ec57782 | 1999-04-23 22:13:45 +0000 | [diff] [blame] | 15 | #include <openssl/conf.h> |
| 16 | #include <openssl/x509.h> |
Dr. Matthias St. Pierre | 25f2138 | 2019-09-28 00:45:33 +0200 | [diff] [blame] | 17 | #include "crypto/x509.h" |
Bodo Möller | ec57782 | 1999-04-23 22:13:45 +0000 | [diff] [blame] | 18 | #include <openssl/x509v3.h> |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 19 | |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 20 | static int v3_check_critical(const char **value); |
| 21 | static int v3_check_generic(const char **value); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 22 | static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 23 | int crit, const char *value); |
| 24 | static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 25 | int crit, int type, |
| 26 | X509V3_CTX *ctx); |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 27 | static char *conf_lhash_get_string(void *db, const char *section, const char *value); |
| 28 | static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, const char *section); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 29 | static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, |
| 30 | int ext_nid, int crit, void *ext_struc); |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 31 | static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 32 | long *ext_len); |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 33 | |
| 34 | static X509_EXTENSION *X509V3_EXT_nconf_int(CONF *conf, X509V3_CTX *ctx, |
| 35 | const char *section, |
| 36 | const char *name, const char *value) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 37 | { |
| 38 | int crit; |
| 39 | int ext_type; |
| 40 | X509_EXTENSION *ret; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 41 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 42 | crit = v3_check_critical(&value); |
| 43 | if ((ext_type = v3_check_generic(&value))) |
| 44 | return v3_generic_extension(name, value, crit, ext_type, ctx); |
| 45 | ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); |
| 46 | if (!ret) { |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 47 | if (section != NULL) |
Richard Levitte | a150f8e | 2020-11-04 16:14:00 +0100 | [diff] [blame] | 48 | ERR_raise_data(ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION, |
| 49 | "section=%s, name=%s, value=%s", |
| 50 | section, name, value); |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 51 | else |
Richard Levitte | a150f8e | 2020-11-04 16:14:00 +0100 | [diff] [blame] | 52 | ERR_raise_data(ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION, |
| 53 | "name=%s, value=%s", name, value); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 54 | } |
| 55 | return ret; |
| 56 | } |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 57 | |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 58 | X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, |
| 59 | const char *value) |
| 60 | { |
| 61 | return X509V3_EXT_nconf_int(conf, ctx, NULL, name, value); |
| 62 | } |
| 63 | |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 64 | X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 65 | const char *value) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 66 | { |
| 67 | int crit; |
| 68 | int ext_type; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 69 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 70 | crit = v3_check_critical(&value); |
| 71 | if ((ext_type = v3_check_generic(&value))) |
| 72 | return v3_generic_extension(OBJ_nid2sn(ext_nid), |
| 73 | value, crit, ext_type, ctx); |
| 74 | return do_ext_nconf(conf, ctx, ext_nid, crit, value); |
| 75 | } |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 76 | |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 77 | /* CONF *conf: Config file */ |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 78 | /* char *value: Value */ |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 79 | static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 80 | int crit, const char *value) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 81 | { |
| 82 | const X509V3_EXT_METHOD *method; |
| 83 | X509_EXTENSION *ext; |
| 84 | STACK_OF(CONF_VALUE) *nval; |
| 85 | void *ext_struc; |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 86 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 87 | if (ext_nid == NID_undef) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 88 | ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 89 | return NULL; |
| 90 | } |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 91 | if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 92 | ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 93 | return NULL; |
| 94 | } |
| 95 | /* Now get internal extension representation based on type */ |
| 96 | if (method->v2i) { |
| 97 | if (*value == '@') |
| 98 | nval = NCONF_get_section(conf, value + 1); |
| 99 | else |
| 100 | nval = X509V3_parse_list(value); |
Matt Caswell | 8605abf | 2016-06-10 15:30:09 +0100 | [diff] [blame] | 101 | if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { |
Richard Levitte | a150f8e | 2020-11-04 16:14:00 +0100 | [diff] [blame] | 102 | ERR_raise_data(ERR_LIB_X509V3, X509V3_R_INVALID_EXTENSION_STRING, |
| 103 | "name=%s,section=%s", OBJ_nid2sn(ext_nid), value); |
Matt Caswell | 8605abf | 2016-06-10 15:30:09 +0100 | [diff] [blame] | 104 | if (*value != '@') |
David Benjamin | e125c12 | 2016-07-26 11:36:23 -0400 | [diff] [blame] | 105 | sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 106 | return NULL; |
| 107 | } |
| 108 | ext_struc = method->v2i(method, ctx, nval); |
| 109 | if (*value != '@') |
| 110 | sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); |
| 111 | if (!ext_struc) |
| 112 | return NULL; |
| 113 | } else if (method->s2i) { |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 114 | if ((ext_struc = method->s2i(method, ctx, value)) == NULL) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 115 | return NULL; |
| 116 | } else if (method->r2i) { |
| 117 | if (!ctx->db || !ctx->db_meth) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 118 | ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_CONFIG_DATABASE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 119 | return NULL; |
| 120 | } |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 121 | if ((ext_struc = method->r2i(method, ctx, value)) == NULL) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 122 | return NULL; |
| 123 | } else { |
Richard Levitte | a150f8e | 2020-11-04 16:14:00 +0100 | [diff] [blame] | 124 | ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED, |
| 125 | "name=%s", OBJ_nid2sn(ext_nid)); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 126 | return NULL; |
| 127 | } |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 128 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 129 | ext = do_ext_i2d(method, ext_nid, crit, ext_struc); |
| 130 | if (method->it) |
| 131 | ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); |
| 132 | else |
| 133 | method->ext_free(ext_struc); |
| 134 | return ext; |
Dr. Stephen Henson | c8b4185 | 1999-05-09 16:39:11 +0000 | [diff] [blame] | 135 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 136 | } |
Dr. Stephen Henson | c8b4185 | 1999-05-09 16:39:11 +0000 | [diff] [blame] | 137 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 138 | static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, |
| 139 | int ext_nid, int crit, void *ext_struc) |
| 140 | { |
| 141 | unsigned char *ext_der = NULL; |
| 142 | int ext_len; |
| 143 | ASN1_OCTET_STRING *ext_oct = NULL; |
| 144 | X509_EXTENSION *ext; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 145 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 146 | /* Convert internal representation to DER */ |
| 147 | if (method->it) { |
| 148 | ext_der = NULL; |
| 149 | ext_len = |
| 150 | ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); |
| 151 | if (ext_len < 0) |
| 152 | goto merr; |
| 153 | } else { |
| 154 | unsigned char *p; |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 155 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 156 | ext_len = method->i2d(ext_struc, NULL); |
Shane Lontis | 42e7d2f | 2021-04-12 13:58:14 +1000 | [diff] [blame] | 157 | if (ext_len <= 0) |
| 158 | goto merr; |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 159 | if ((ext_der = OPENSSL_malloc(ext_len)) == NULL) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 160 | goto merr; |
| 161 | p = ext_der; |
| 162 | method->i2d(ext_struc, &p); |
| 163 | } |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 164 | if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 165 | goto merr; |
| 166 | ext_oct->data = ext_der; |
| 167 | ext_der = NULL; |
| 168 | ext_oct->length = ext_len; |
Dr. Stephen Henson | 2aff772 | 2000-12-13 13:47:33 +0000 | [diff] [blame] | 169 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 170 | ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); |
| 171 | if (!ext) |
| 172 | goto merr; |
Dr. Stephen Henson | f422a51 | 2015-03-14 04:16:42 +0000 | [diff] [blame] | 173 | ASN1_OCTET_STRING_free(ext_oct); |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 174 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 175 | return ext; |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 176 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 177 | merr: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 178 | ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); |
Rich Salz | b548a1f | 2015-05-01 10:02:07 -0400 | [diff] [blame] | 179 | OPENSSL_free(ext_der); |
Rich Salz | 0dfb939 | 2015-03-24 07:52:24 -0400 | [diff] [blame] | 180 | ASN1_OCTET_STRING_free(ext_oct); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 181 | return NULL; |
Dr. Stephen Henson | c8b4185 | 1999-05-09 16:39:11 +0000 | [diff] [blame] | 182 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 183 | } |
Dr. Stephen Henson | c8b4185 | 1999-05-09 16:39:11 +0000 | [diff] [blame] | 184 | |
| 185 | /* Given an internal structure, nid and critical flag create an extension */ |
| 186 | |
| 187 | X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 188 | { |
| 189 | const X509V3_EXT_METHOD *method; |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 190 | |
| 191 | if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 192 | ERR_raise(ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 193 | return NULL; |
| 194 | } |
| 195 | return do_ext_i2d(method, ext_nid, crit, ext_struc); |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 196 | } |
| 197 | |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 198 | /* Check the extension string for critical flag */ |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 199 | static int v3_check_critical(const char **value) |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 200 | { |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 201 | const char *p = *value; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 202 | |
Dr. David von Oheimb | 2ff286c | 2021-06-21 08:55:50 +0200 | [diff] [blame] | 203 | if (!CHECK_AND_SKIP_PREFIX(p, "critical,")) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 204 | return 0; |
Pauli | a1df06b | 2017-08-21 07:19:17 +1000 | [diff] [blame] | 205 | while (ossl_isspace(*p)) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 206 | p++; |
| 207 | *value = p; |
| 208 | return 1; |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 209 | } |
| 210 | |
| 211 | /* Check extension string for generic extension and return the type */ |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 212 | static int v3_check_generic(const char **value) |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 213 | { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 214 | int gen_type = 0; |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 215 | const char *p = *value; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 216 | |
Dr. David von Oheimb | 2ff286c | 2021-06-21 08:55:50 +0200 | [diff] [blame] | 217 | if (CHECK_AND_SKIP_PREFIX(p, "DER:")) { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 218 | gen_type = 1; |
Dr. David von Oheimb | 2ff286c | 2021-06-21 08:55:50 +0200 | [diff] [blame] | 219 | } else if (CHECK_AND_SKIP_PREFIX(p, "ASN1:")) { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 220 | gen_type = 2; |
| 221 | } else |
| 222 | return 0; |
Dr. Stephen Henson | 9ea1b87 | 2002-11-12 13:34:51 +0000 | [diff] [blame] | 223 | |
Pauli | a1df06b | 2017-08-21 07:19:17 +1000 | [diff] [blame] | 224 | while (ossl_isspace(*p)) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 225 | p++; |
| 226 | *value = p; |
| 227 | return gen_type; |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 228 | } |
| 229 | |
Dr. Stephen Henson | c79b16e | 1999-08-25 16:59:26 +0000 | [diff] [blame] | 230 | /* Create a generic extension: for now just handle DER type */ |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 231 | static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 232 | int crit, int gen_type, |
| 233 | X509V3_CTX *ctx) |
| 234 | { |
| 235 | unsigned char *ext_der = NULL; |
Gunnar Kudrjavets | 4c9b0a0 | 2015-05-06 10:16:55 +0100 | [diff] [blame] | 236 | long ext_len = 0; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 237 | ASN1_OBJECT *obj = NULL; |
| 238 | ASN1_OCTET_STRING *oct = NULL; |
| 239 | X509_EXTENSION *extension = NULL; |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 240 | |
| 241 | if ((obj = OBJ_txt2obj(ext, 0)) == NULL) { |
Richard Levitte | a150f8e | 2020-11-04 16:14:00 +0100 | [diff] [blame] | 242 | ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR, |
| 243 | "name=%s", ext); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 244 | goto err; |
| 245 | } |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 246 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 247 | if (gen_type == 1) |
Rich Salz | 14f051a | 2016-04-13 15:58:28 -0400 | [diff] [blame] | 248 | ext_der = OPENSSL_hexstr2buf(value, &ext_len); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 249 | else if (gen_type == 2) |
| 250 | ext_der = generic_asn1(value, ctx, &ext_len); |
Dr. Stephen Henson | 9ea1b87 | 2002-11-12 13:34:51 +0000 | [diff] [blame] | 251 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 252 | if (ext_der == NULL) { |
Richard Levitte | a150f8e | 2020-11-04 16:14:00 +0100 | [diff] [blame] | 253 | ERR_raise_data(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR, |
| 254 | "value=%s", value); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 255 | goto err; |
| 256 | } |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 257 | |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 258 | if ((oct = ASN1_OCTET_STRING_new()) == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 259 | ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 260 | goto err; |
| 261 | } |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 262 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 263 | oct->data = ext_der; |
| 264 | oct->length = ext_len; |
| 265 | ext_der = NULL; |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 266 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 267 | extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 268 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 269 | err: |
| 270 | ASN1_OBJECT_free(obj); |
Dr. Stephen Henson | f422a51 | 2015-03-14 04:16:42 +0000 | [diff] [blame] | 271 | ASN1_OCTET_STRING_free(oct); |
Rich Salz | b548a1f | 2015-05-01 10:02:07 -0400 | [diff] [blame] | 272 | OPENSSL_free(ext_der); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 273 | return extension; |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 274 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 275 | } |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 276 | |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 277 | static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 278 | long *ext_len) |
| 279 | { |
| 280 | ASN1_TYPE *typ; |
| 281 | unsigned char *ext_der = NULL; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 282 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 283 | typ = ASN1_generate_v3(value, ctx); |
| 284 | if (typ == NULL) |
| 285 | return NULL; |
| 286 | *ext_len = i2d_ASN1_TYPE(typ, &ext_der); |
| 287 | ASN1_TYPE_free(typ); |
| 288 | return ext_der; |
| 289 | } |
Dr. Stephen Henson | 388ff0b | 1999-02-14 16:48:22 +0000 | [diff] [blame] | 290 | |
Dr. Stephen Henson | ebaa2cf | 2010-03-03 19:56:34 +0000 | [diff] [blame] | 291 | static void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 292 | { |
| 293 | int idx; |
| 294 | ASN1_OBJECT *obj; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 295 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 296 | obj = X509_EXTENSION_get_object(dext); |
Dr. David von Oheimb | d8ab30b | 2021-01-08 23:18:19 +0100 | [diff] [blame] | 297 | while ((idx = X509v3_get_ext_by_OBJ(sk, obj, -1)) >= 0) |
| 298 | X509_EXTENSION_free(X509v3_delete_ext(sk, idx)); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 299 | } |
Dr. Stephen Henson | ebaa2cf | 2010-03-03 19:56:34 +0000 | [diff] [blame] | 300 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 301 | /* |
| 302 | * This is the main function: add a bunch of extensions based on a config |
Dr. David von Oheimb | f902716 | 2020-12-07 13:28:39 +0100 | [diff] [blame] | 303 | * file section to an extension STACK. Just check in case sk == NULL. |
Dr. David von Oheimb | ab8af35 | 2020-12-11 19:30:40 +0100 | [diff] [blame] | 304 | * Note that on error new elements may have been added to *sk if sk != NULL. |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 305 | */ |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 306 | int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 307 | STACK_OF(X509_EXTENSION) **sk) |
| 308 | { |
| 309 | X509_EXTENSION *ext; |
| 310 | STACK_OF(CONF_VALUE) *nval; |
Dr. David von Oheimb | adbd77f | 2021-08-17 23:13:28 +0200 | [diff] [blame] | 311 | const CONF_VALUE *val; |
| 312 | int i, akid = -1, skid = -1; |
Rich Salz | 75ebbd9 | 2015-05-06 13:43:59 -0400 | [diff] [blame] | 313 | |
| 314 | if ((nval = NCONF_get_section(conf, section)) == NULL) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 315 | return 0; |
| 316 | for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { |
| 317 | val = sk_CONF_VALUE_value(nval, i); |
Dr. David von Oheimb | adbd77f | 2021-08-17 23:13:28 +0200 | [diff] [blame] | 318 | if (strcmp(val->name, "authorityKeyIdentifier") == 0) |
| 319 | akid = i; |
| 320 | else if (strcmp(val->name, "subjectKeyIdentifier") == 0) |
| 321 | skid = i; |
| 322 | } |
| 323 | for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { |
| 324 | val = sk_CONF_VALUE_value(nval, i); |
| 325 | if (skid > akid && akid >= 0) { |
| 326 | /* make sure SKID is handled before AKID */ |
| 327 | if (i == akid) |
| 328 | val = sk_CONF_VALUE_value(nval, skid); |
| 329 | else if (i == skid) |
| 330 | val = sk_CONF_VALUE_value(nval, akid); |
| 331 | } |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 332 | if ((ext = X509V3_EXT_nconf_int(conf, ctx, val->section, |
| 333 | val->name, val->value)) == NULL) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 334 | return 0; |
Pavel Kopyl | abcf241 | 2017-11-07 15:28:18 +0300 | [diff] [blame] | 335 | if (sk != NULL) { |
Dr. David von Oheimb | f902716 | 2020-12-07 13:28:39 +0100 | [diff] [blame] | 336 | if (ctx->flags == X509V3_CTX_REPLACE) |
| 337 | delete_ext(*sk, ext); |
Pavel Kopyl | abcf241 | 2017-11-07 15:28:18 +0300 | [diff] [blame] | 338 | if (X509v3_add_ext(sk, ext, -1) == NULL) { |
| 339 | X509_EXTENSION_free(ext); |
| 340 | return 0; |
| 341 | } |
| 342 | } |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 343 | X509_EXTENSION_free(ext); |
| 344 | } |
| 345 | return 1; |
| 346 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 347 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 348 | /* |
Dr. David von Oheimb | ab8af35 | 2020-12-11 19:30:40 +0100 | [diff] [blame] | 349 | * Add extensions to a certificate. Just check in case cert == NULL. |
| 350 | * Note that on error new elements may remain added to cert if cert != NULL. |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 351 | */ |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 352 | int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 353 | X509 *cert) |
| 354 | { |
| 355 | STACK_OF(X509_EXTENSION) **sk = NULL; |
Dr. David von Oheimb | ab8af35 | 2020-12-11 19:30:40 +0100 | [diff] [blame] | 356 | if (cert != NULL) |
Dr. Stephen Henson | 5cf6abd | 2015-09-16 18:40:26 +0100 | [diff] [blame] | 357 | sk = &cert->cert_info.extensions; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 358 | return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); |
| 359 | } |
Dr. Stephen Henson | 9aeaf1b | 1999-01-24 00:50:01 +0000 | [diff] [blame] | 360 | |
Dr. David von Oheimb | ab8af35 | 2020-12-11 19:30:40 +0100 | [diff] [blame] | 361 | /* |
| 362 | * Add extensions to a CRL. Just check in case crl == NULL. |
| 363 | * Note that on error new elements may remain added to crl if crl != NULL. |
| 364 | */ |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 365 | int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 366 | X509_CRL *crl) |
| 367 | { |
| 368 | STACK_OF(X509_EXTENSION) **sk = NULL; |
Dr. David von Oheimb | ab8af35 | 2020-12-11 19:30:40 +0100 | [diff] [blame] | 369 | if (crl != NULL) |
Dr. Stephen Henson | 7aef39a | 2015-09-16 00:24:43 +0100 | [diff] [blame] | 370 | sk = &crl->crl.extensions; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 371 | return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); |
| 372 | } |
Dr. Stephen Henson | 1756d40 | 1999-03-06 19:33:29 +0000 | [diff] [blame] | 373 | |
Dr. David von Oheimb | ab8af35 | 2020-12-11 19:30:40 +0100 | [diff] [blame] | 374 | /* |
| 375 | * Add extensions to certificate request. Just check in case req is NULL. |
| 376 | * Note that on error new elements may remain added to req if req != NULL. |
| 377 | */ |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 378 | int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 379 | X509_REQ *req) |
| 380 | { |
Dr. David von Oheimb | ab8af35 | 2020-12-11 19:30:40 +0100 | [diff] [blame] | 381 | STACK_OF(X509_EXTENSION) *exts = NULL; |
| 382 | int ret = X509V3_EXT_add_nconf_sk(conf, ctx, section, &exts); |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 383 | |
Dr. David von Oheimb | ab8af35 | 2020-12-11 19:30:40 +0100 | [diff] [blame] | 384 | if (ret && req != NULL && exts != NULL) |
| 385 | ret = X509_REQ_add_extensions(req, exts); |
| 386 | sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); |
| 387 | return ret; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 388 | } |
Dr. Stephen Henson | c79b16e | 1999-08-25 16:59:26 +0000 | [diff] [blame] | 389 | |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 390 | /* Config database functions */ |
| 391 | |
FdaSilvaYY | c8f717f | 2016-06-12 18:20:40 +0200 | [diff] [blame] | 392 | char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 393 | { |
| 394 | if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 395 | ERR_raise(ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 396 | return NULL; |
| 397 | } |
| 398 | if (ctx->db_meth->get_string) |
| 399 | return ctx->db_meth->get_string(ctx->db, name, section); |
| 400 | return NULL; |
| 401 | } |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 402 | |
FdaSilvaYY | c8f717f | 2016-06-12 18:20:40 +0200 | [diff] [blame] | 403 | STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 404 | { |
| 405 | if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 406 | ERR_raise(ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 407 | return NULL; |
| 408 | } |
| 409 | if (ctx->db_meth->get_section) |
| 410 | return ctx->db_meth->get_section(ctx->db, section); |
| 411 | return NULL; |
| 412 | } |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 413 | |
Ulf Möller | 6b691a5 | 1999-04-19 21:31:43 +0000 | [diff] [blame] | 414 | void X509V3_string_free(X509V3_CTX *ctx, char *str) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 415 | { |
| 416 | if (!str) |
| 417 | return; |
| 418 | if (ctx->db_meth->free_string) |
| 419 | ctx->db_meth->free_string(ctx->db, str); |
| 420 | } |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 421 | |
Dr. Stephen Henson | ba404b5 | 1999-06-20 22:18:16 +0000 | [diff] [blame] | 422 | void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 423 | { |
| 424 | if (!section) |
| 425 | return; |
| 426 | if (ctx->db_meth->free_section) |
| 427 | ctx->db_meth->free_section(ctx->db, section); |
| 428 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 429 | |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 430 | static char *nconf_get_string(void *db, const char *section, const char *value) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 431 | { |
| 432 | return NCONF_get_string(db, section, value); |
| 433 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 434 | |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 435 | static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, const char *section) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 436 | { |
| 437 | return NCONF_get_section(db, section); |
| 438 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 439 | |
| 440 | static X509V3_CONF_METHOD nconf_method = { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 441 | nconf_get_string, |
| 442 | nconf_get_section, |
| 443 | NULL, |
| 444 | NULL |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 445 | }; |
| 446 | |
| 447 | void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 448 | { |
Dr. David von Oheimb | 41e597a | 2020-12-24 11:25:47 +0100 | [diff] [blame] | 449 | if (ctx == NULL) { |
| 450 | ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); |
| 451 | return; |
| 452 | } |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 453 | ctx->db_meth = &nconf_method; |
| 454 | ctx->db = conf; |
| 455 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 456 | |
| 457 | void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 458 | X509_CRL *crl, int flags) |
| 459 | { |
Dr. David von Oheimb | 41e597a | 2020-12-24 11:25:47 +0100 | [diff] [blame] | 460 | if (ctx == NULL) { |
| 461 | ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); |
| 462 | return; |
| 463 | } |
| 464 | ctx->flags = flags; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 465 | ctx->issuer_cert = issuer; |
| 466 | ctx->subject_cert = subj; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 467 | ctx->subject_req = req; |
Dr. David von Oheimb | 41e597a | 2020-12-24 11:25:47 +0100 | [diff] [blame] | 468 | ctx->crl = crl; |
| 469 | ctx->db_meth = NULL; |
| 470 | ctx->db = NULL; |
| 471 | ctx->issuer_pkey = NULL; |
| 472 | } |
| 473 | |
| 474 | /* For API backward compatibility, this is separate from X509V3_set_ctx() */ |
| 475 | int X509V3_set_issuer_pkey(X509V3_CTX *ctx, EVP_PKEY *pkey) |
| 476 | { |
| 477 | if (ctx == NULL) { |
| 478 | ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); |
| 479 | return 0; |
| 480 | } |
| 481 | if (ctx->subject_cert == NULL && pkey != NULL) { |
| 482 | ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_INVALID_ARGUMENT); |
| 483 | return 0; |
| 484 | } |
| 485 | ctx->issuer_pkey = pkey; |
| 486 | return 1; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 487 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 488 | |
| 489 | /* Old conf compatibility functions */ |
| 490 | |
Ben Laurie | 3c1d6bb | 2008-05-26 11:24:29 +0000 | [diff] [blame] | 491 | X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 492 | const char *name, const char *value) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 493 | { |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 494 | CONF *ctmp; |
| 495 | X509_EXTENSION *ret; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 496 | |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 497 | if ((ctmp = NCONF_new(NULL)) == NULL) |
| 498 | return NULL; |
| 499 | CONF_set_nconf(ctmp, conf); |
| 500 | ret = X509V3_EXT_nconf(ctmp, ctx, name, value); |
Tomas Mraz | c2b94c0 | 2021-08-05 12:44:58 +0200 | [diff] [blame] | 501 | CONF_set_nconf(ctmp, NULL); |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 502 | NCONF_free(ctmp); |
| 503 | return ret; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 504 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 505 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 506 | X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 507 | X509V3_CTX *ctx, int ext_nid, const char *value) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 508 | { |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 509 | CONF *ctmp; |
| 510 | X509_EXTENSION *ret; |
| 511 | |
| 512 | if ((ctmp = NCONF_new(NULL)) == NULL) |
| 513 | return NULL; |
| 514 | CONF_set_nconf(ctmp, conf); |
| 515 | ret = X509V3_EXT_nconf_nid(ctmp, ctx, ext_nid, value); |
Tomas Mraz | c2b94c0 | 2021-08-05 12:44:58 +0200 | [diff] [blame] | 516 | CONF_set_nconf(ctmp, NULL); |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 517 | NCONF_free(ctmp); |
| 518 | return ret; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 519 | } |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 520 | |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 521 | static char *conf_lhash_get_string(void *db, const char *section, const char *value) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 522 | { |
| 523 | return CONF_get_string(db, section, value); |
| 524 | } |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 525 | |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 526 | static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, const char *section) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 527 | { |
| 528 | return CONF_get_section(db, section); |
| 529 | } |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 530 | |
| 531 | static X509V3_CONF_METHOD conf_lhash_method = { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 532 | conf_lhash_get_string, |
| 533 | conf_lhash_get_section, |
| 534 | NULL, |
| 535 | NULL |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 536 | }; |
| 537 | |
Ben Laurie | 3c1d6bb | 2008-05-26 11:24:29 +0000 | [diff] [blame] | 538 | void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 539 | { |
Dr. David von Oheimb | 41e597a | 2020-12-24 11:25:47 +0100 | [diff] [blame] | 540 | if (ctx == NULL) { |
| 541 | ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); |
| 542 | return; |
| 543 | } |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 544 | ctx->db_meth = &conf_lhash_method; |
| 545 | ctx->db = lhash; |
| 546 | } |
Dr. Stephen Henson | 1d48dd0 | 1999-04-16 23:57:04 +0000 | [diff] [blame] | 547 | |
Ben Laurie | 3c1d6bb | 2008-05-26 11:24:29 +0000 | [diff] [blame] | 548 | int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 549 | const char *section, X509 *cert) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 550 | { |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 551 | CONF *ctmp; |
| 552 | int ret; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 553 | |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 554 | if ((ctmp = NCONF_new(NULL)) == NULL) |
| 555 | return 0; |
| 556 | CONF_set_nconf(ctmp, conf); |
| 557 | ret = X509V3_EXT_add_nconf(ctmp, ctx, section, cert); |
Tomas Mraz | c2b94c0 | 2021-08-05 12:44:58 +0200 | [diff] [blame] | 558 | CONF_set_nconf(ctmp, NULL); |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 559 | NCONF_free(ctmp); |
| 560 | return ret; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 561 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 562 | |
| 563 | /* Same as above but for a CRL */ |
| 564 | |
Ben Laurie | 3c1d6bb | 2008-05-26 11:24:29 +0000 | [diff] [blame] | 565 | int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 566 | const char *section, X509_CRL *crl) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 567 | { |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 568 | CONF *ctmp; |
| 569 | int ret; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 570 | |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 571 | if ((ctmp = NCONF_new(NULL)) == NULL) |
| 572 | return 0; |
| 573 | CONF_set_nconf(ctmp, conf); |
| 574 | ret = X509V3_EXT_CRL_add_nconf(ctmp, ctx, section, crl); |
Tomas Mraz | c2b94c0 | 2021-08-05 12:44:58 +0200 | [diff] [blame] | 575 | CONF_set_nconf(ctmp, NULL); |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 576 | NCONF_free(ctmp); |
| 577 | return ret; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 578 | } |
Dr. Stephen Henson | b7a26e6 | 2001-06-28 11:41:50 +0000 | [diff] [blame] | 579 | |
| 580 | /* Add extensions to certificate request */ |
| 581 | |
Ben Laurie | 3c1d6bb | 2008-05-26 11:24:29 +0000 | [diff] [blame] | 582 | int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, |
FdaSilvaYY | 3470795 | 2016-05-14 23:09:34 +0200 | [diff] [blame] | 583 | const char *section, X509_REQ *req) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 584 | { |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 585 | CONF *ctmp; |
| 586 | int ret; |
Dr. David von Oheimb | 02ae130 | 2020-06-26 20:40:19 +0200 | [diff] [blame] | 587 | |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 588 | if ((ctmp = NCONF_new(NULL)) == NULL) |
| 589 | return 0; |
| 590 | CONF_set_nconf(ctmp, conf); |
| 591 | ret = X509V3_EXT_REQ_add_nconf(ctmp, ctx, section, req); |
Tomas Mraz | c2b94c0 | 2021-08-05 12:44:58 +0200 | [diff] [blame] | 592 | CONF_set_nconf(ctmp, NULL); |
Tomas Mraz | b3c2ed7 | 2021-05-27 11:00:35 +0200 | [diff] [blame] | 593 | NCONF_free(ctmp); |
| 594 | return ret; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 595 | } |