1 /* 2 * Copyright 2004-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 /* 11 * This file is dual-licensed and is also available under the following 12 * terms: 13 * 14 * Copyright (c) 2004 Kungliga Tekniska Högskolan 15 * (Royal Institute of Technology, Stockholm, Sweden). 16 * All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 22 * 1. Redistributions of source code must retain the above copyright 23 * notice, this list of conditions and the following disclaimer. 24 * 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 29 * 3. Neither the name of the Institute nor the names of its contributors 30 * may be used to endorse or promote products derived from this software 31 * without specific prior written permission. 32 * 33 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43 * SUCH DAMAGE. 44 */ 45 46 #include <stdio.h> 47 #include "internal/cryptlib.h" 48 #include <openssl/conf.h> 49 #include <openssl/x509v3.h> 50 #include "ext_dat.h" 51 52 static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, 53 BIO *out, int indent); 54 static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, 55 X509V3_CTX *ctx, char *str); 56 57 const X509V3_EXT_METHOD ossl_v3_pci = 58 { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), 59 0, 0, 0, 0, 60 0, 0, 61 NULL, NULL, 62 (X509V3_EXT_I2R)i2r_pci, 63 (X509V3_EXT_R2I)r2i_pci, 64 NULL, 65 }; 66 67 static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, 68 BIO *out, int indent) 69 { 70 BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); 71 if (pci->pcPathLengthConstraint) 72 i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); 73 else 74 BIO_printf(out, "infinite"); 75 BIO_puts(out, "\n"); 76 BIO_printf(out, "%*sPolicy Language: ", indent, ""); 77 i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); 78 if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) 79 BIO_printf(out, "\n%*sPolicy Text: %.*s", indent, "", 80 pci->proxyPolicy->policy->length, 81 pci->proxyPolicy->policy->data); 82 return 1; 83 } 84 85 static int process_pci_value(CONF_VALUE *val, 86 ASN1_OBJECT **language, ASN1_INTEGER **pathlen, 87 ASN1_OCTET_STRING **policy) 88 { 89 int free_policy = 0; 90 91 if (strcmp(val->name, "language") == 0) { 92 if (*language) { 93 ERR_raise(ERR_LIB_X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); 94 X509V3_conf_err(val); 95 return 0; 96 } 97 if ((*language = OBJ_txt2obj(val->value, 0)) == NULL) { 98 ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); 99 X509V3_conf_err(val); 100 return 0; 101 } 102 } else if (strcmp(val->name, "pathlen") == 0) { 103 if (*pathlen) { 104 ERR_raise(ERR_LIB_X509V3, 105 X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); 106 X509V3_conf_err(val); 107 return 0; 108 } 109 if (!X509V3_get_value_int(val, pathlen)) { 110 ERR_raise(ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH); 111 X509V3_conf_err(val); 112 return 0; 113 } 114 } else if (strcmp(val->name, "policy") == 0) { 115 unsigned char *tmp_data = NULL; 116 long val_len; 117 118 if (*policy == NULL) { 119 *policy = ASN1_OCTET_STRING_new(); 120 if (*policy == NULL) { 121 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 122 X509V3_conf_err(val); 123 return 0; 124 } 125 free_policy = 1; 126 } 127 if (strncmp(val->value, "hex:", 4) == 0) { 128 unsigned char *tmp_data2 = 129 OPENSSL_hexstr2buf(val->value + 4, &val_len); 130 131 if (!tmp_data2) { 132 X509V3_conf_err(val); 133 goto err; 134 } 135 136 tmp_data = OPENSSL_realloc((*policy)->data, 137 (*policy)->length + val_len + 1); 138 if (tmp_data) { 139 (*policy)->data = tmp_data; 140 memcpy(&(*policy)->data[(*policy)->length], 141 tmp_data2, val_len); 142 (*policy)->length += val_len; 143 (*policy)->data[(*policy)->length] = '\0'; 144 } else { 145 OPENSSL_free(tmp_data2); 146 /* 147 * realloc failure implies the original data space is b0rked 148 * too! 149 */ 150 OPENSSL_free((*policy)->data); 151 (*policy)->data = NULL; 152 (*policy)->length = 0; 153 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 154 X509V3_conf_err(val); 155 goto err; 156 } 157 OPENSSL_free(tmp_data2); 158 } else if (strncmp(val->value, "file:", 5) == 0) { 159 unsigned char buf[2048]; 160 int n; 161 BIO *b = BIO_new_file(val->value + 5, "r"); 162 if (!b) { 163 ERR_raise(ERR_LIB_X509V3, ERR_R_BIO_LIB); 164 X509V3_conf_err(val); 165 goto err; 166 } 167 while ((n = BIO_read(b, buf, sizeof(buf))) > 0 168 || (n == 0 && BIO_should_retry(b))) { 169 if (!n) 170 continue; 171 172 tmp_data = OPENSSL_realloc((*policy)->data, 173 (*policy)->length + n + 1); 174 175 if (!tmp_data) { 176 OPENSSL_free((*policy)->data); 177 (*policy)->data = NULL; 178 (*policy)->length = 0; 179 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 180 X509V3_conf_err(val); 181 BIO_free_all(b); 182 goto err; 183 } 184 185 (*policy)->data = tmp_data; 186 memcpy(&(*policy)->data[(*policy)->length], buf, n); 187 (*policy)->length += n; 188 (*policy)->data[(*policy)->length] = '\0'; 189 } 190 BIO_free_all(b); 191 192 if (n < 0) { 193 ERR_raise(ERR_LIB_X509V3, ERR_R_BIO_LIB); 194 X509V3_conf_err(val); 195 goto err; 196 } 197 } else if (strncmp(val->value, "text:", 5) == 0) { 198 val_len = strlen(val->value + 5); 199 tmp_data = OPENSSL_realloc((*policy)->data, 200 (*policy)->length + val_len + 1); 201 if (tmp_data) { 202 (*policy)->data = tmp_data; 203 memcpy(&(*policy)->data[(*policy)->length], 204 val->value + 5, val_len); 205 (*policy)->length += val_len; 206 (*policy)->data[(*policy)->length] = '\0'; 207 } else { 208 /* 209 * realloc failure implies the original data space is b0rked 210 * too! 211 */ 212 OPENSSL_free((*policy)->data); 213 (*policy)->data = NULL; 214 (*policy)->length = 0; 215 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 216 X509V3_conf_err(val); 217 goto err; 218 } 219 } else { 220 ERR_raise(ERR_LIB_X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); 221 X509V3_conf_err(val); 222 goto err; 223 } 224 if (!tmp_data) { 225 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 226 X509V3_conf_err(val); 227 goto err; 228 } 229 } 230 return 1; 231 err: 232 if (free_policy) { 233 ASN1_OCTET_STRING_free(*policy); 234 *policy = NULL; 235 } 236 return 0; 237 } 238 239 static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, 240 X509V3_CTX *ctx, char *value) 241 { 242 PROXY_CERT_INFO_EXTENSION *pci = NULL; 243 STACK_OF(CONF_VALUE) *vals; 244 ASN1_OBJECT *language = NULL; 245 ASN1_INTEGER *pathlen = NULL; 246 ASN1_OCTET_STRING *policy = NULL; 247 int i, j; 248 249 vals = X509V3_parse_list(value); 250 for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { 251 CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); 252 253 if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { 254 ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING); 255 X509V3_conf_err(cnf); 256 goto err; 257 } 258 if (*cnf->name == '@') { 259 STACK_OF(CONF_VALUE) *sect; 260 int success_p = 1; 261 262 sect = X509V3_get_section(ctx, cnf->name + 1); 263 if (!sect) { 264 ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SECTION); 265 X509V3_conf_err(cnf); 266 goto err; 267 } 268 for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) { 269 success_p = 270 process_pci_value(sk_CONF_VALUE_value(sect, j), 271 &language, &pathlen, &policy); 272 } 273 X509V3_section_free(ctx, sect); 274 if (!success_p) 275 goto err; 276 } else { 277 if (!process_pci_value(cnf, &language, &pathlen, &policy)) { 278 X509V3_conf_err(cnf); 279 goto err; 280 } 281 } 282 } 283 284 /* Language is mandatory */ 285 if (!language) { 286 ERR_raise(ERR_LIB_X509V3, 287 X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); 288 goto err; 289 } 290 i = OBJ_obj2nid(language); 291 if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) { 292 ERR_raise(ERR_LIB_X509V3, 293 X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); 294 goto err; 295 } 296 297 pci = PROXY_CERT_INFO_EXTENSION_new(); 298 if (pci == NULL) { 299 ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); 300 goto err; 301 } 302 303 pci->proxyPolicy->policyLanguage = language; 304 language = NULL; 305 pci->proxyPolicy->policy = policy; 306 policy = NULL; 307 pci->pcPathLengthConstraint = pathlen; 308 pathlen = NULL; 309 goto end; 310 err: 311 ASN1_OBJECT_free(language); 312 ASN1_INTEGER_free(pathlen); 313 pathlen = NULL; 314 ASN1_OCTET_STRING_free(policy); 315 policy = NULL; 316 PROXY_CERT_INFO_EXTENSION_free(pci); 317 pci = NULL; 318 end: 319 sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); 320 return pci; 321 } 322