v3_ncons.c revision 69939df2891f62f7f00ff2ac275f1cd81a67454c
1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* v3_ncons.c */ 24969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin/* 34969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * project. 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 2003 The OpenSSL Project. All rights reserved. 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright 144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * notice, this list of conditions and the following disclaimer. 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the documentation and/or other materials provided with the 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distribution. 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * software must display the following acknowledgment: 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * endorse or promote products derived from this software without 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * prior written permission. For written permission, please contact 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * licensing@OpenSSL.org. 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL" 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * nor may "OpenSSL" appear in their names without prior written 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * permission of the OpenSSL Project. 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * acknowledgment: 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com). This product includes software written by Tim 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */ 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdio.h> 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h> 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/asn1t.h> 62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/conf.h> 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/mem.h> 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/obj.h> 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/x509v3.h> 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 6869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan#include "../internal.h" 6969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan 7069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, 724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin X509V3_CTX *ctx, 734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin STACK_OF(CONF_VALUE) *nval); 744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjaminstatic int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, 754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO *bp, int ind); 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, 774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, 784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int ind, const char *name); 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_dn(X509_NAME *sub, X509_NAME *nm); 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyconst X509V3_EXT_METHOD v3_name_constraints = { 894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin NID_name_constraints, 0, 904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_ITEM_ref(NAME_CONSTRAINTS), 914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 0, 0, 0, 0, 924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 0, 0, 934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 0, v2i_NAME_CONSTRAINTS, 944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin i2r_NAME_CONSTRAINTS, 0, 954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin NULL 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}; 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 98d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyASN1_SEQUENCE(GENERAL_SUBTREE) = { 994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), 1004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), 1014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1) 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} ASN1_SEQUENCE_END(GENERAL_SUBTREE) 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 104d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyASN1_SEQUENCE(NAME_CONSTRAINTS) = { 1054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, 1064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_SUBTREE, 0), 1074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, 1084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_SUBTREE, 1), 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} ASN1_SEQUENCE_END(NAME_CONSTRAINTS) 1104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 112d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyIMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) 113d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyIMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, 1164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 1174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 1184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin size_t i; 1194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin CONF_VALUE tval, *val; 1204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin STACK_OF(GENERAL_SUBTREE) **ptree = NULL; 1214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin NAME_CONSTRAINTS *ncons = NULL; 1224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_SUBTREE *sub = NULL; 1234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ncons = NAME_CONSTRAINTS_new(); 1244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!ncons) 1254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto memerr; 1264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 1274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin val = sk_CONF_VALUE_value(nval, i); 1284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!strncmp(val->name, "permitted", 9) && val->name[9]) { 1294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ptree = &ncons->permittedSubtrees; 1304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tval.name = val->name + 10; 1314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { 1324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ptree = &ncons->excludedSubtrees; 1334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tval.name = val->name + 9; 1344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else { 1354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); 1364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto err; 1374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 1384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tval.value = val->value; 1394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin sub = GENERAL_SUBTREE_new(); 1404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) 1414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto err; 1424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!*ptree) 1434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin *ptree = sk_GENERAL_SUBTREE_new_null(); 1444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) 1454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin goto memerr; 1464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin sub = NULL; 1474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 1484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return ncons; 1504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin memerr: 1524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); 1534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin err: 1544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (ncons) 1554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin NAME_CONSTRAINTS_free(ncons); 1564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (sub) 1574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_SUBTREE_free(sub); 1584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return NULL; 1604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 162d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, 1634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO *bp, int ind) 1644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 1654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin NAME_CONSTRAINTS *ncons = a; 1664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin do_i2r_name_constraints(method, ncons->permittedSubtrees, 1674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin bp, ind, "Permitted"); 1684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin do_i2r_name_constraints(method, ncons->excludedSubtrees, 1694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin bp, ind, "Excluded"); 1704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 1714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 173d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, 1744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin STACK_OF(GENERAL_SUBTREE) *trees, 1754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO *bp, int ind, const char *name) 1764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 1774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_SUBTREE *tree; 1784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin size_t i; 1794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (sk_GENERAL_SUBTREE_num(trees) > 0) 1804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_printf(bp, "%*s%s:\n", ind, "", name); 1814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { 1824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin tree = sk_GENERAL_SUBTREE_value(trees, i); 1834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_printf(bp, "%*s", ind + 2, ""); 1844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (tree->base->type == GEN_IPADD) 1854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin print_nc_ipadd(bp, tree->base->d.ip); 1864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else 1874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_NAME_print(bp, tree->base); 1884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_puts(bp, "\n"); 1894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 1904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 1914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 192d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 193d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) 1944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 1954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int i, len; 1964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin unsigned char *p; 1974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin p = ip->data; 1984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin len = ip->length; 1994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_puts(bp, "IP:"); 2004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (len == 8) { 2014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", 2024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); 2034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else if (len == 32) { 2044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0; i < 16; i++) { 2054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_printf(bp, "%X", p[0] << 8 | p[1]); 2064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin p += 2; 2074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (i == 7) 2084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_puts(bp, "/"); 2094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else if (i != 15) 2104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_puts(bp, ":"); 2114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 2124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } else 2134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin BIO_printf(bp, "IP Address:<invalid>"); 2144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return 1; 2154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 2164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin/* 2184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * Check a certificate conforms to a specified set of constraints. Return 2194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * values: X509_V_OK: All constraints obeyed. 2204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. 2214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. 2224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. 2234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. 2244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint 2254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * syntax. X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of 2264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * name 2274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * 228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 230d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) 2314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 2324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int r, i; 2334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin size_t j; 2344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin X509_NAME *nm; 235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin nm = X509_get_subject_name(x); 237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (X509_NAME_entry_count(nm) > 0) { 2394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_NAME gntmp; 2404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin gntmp.type = GEN_DIRNAME; 2414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin gntmp.d.directoryName = nm; 242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin r = nc_match(&gntmp, nc); 244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (r != X509_V_OK) 2464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return r; 247d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin gntmp.type = GEN_EMAIL; 249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Process any email address attributes in subject name */ 251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = -1;;) { 2534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin X509_NAME_ENTRY *ne; 2544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i); 2554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (i == -1) 2564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin break; 2574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin ne = X509_NAME_get_entry(nm, i); 2584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); 2594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) 2604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; 261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin r = nc_match(&gntmp, nc); 263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (r != X509_V_OK) 2654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return r; 2664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++) { 2714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j); 2724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin r = nc_match(gen, nc); 2734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (r != X509_V_OK) 2744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return r; 2754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 276d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 280d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 281d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) 2824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 2834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin GENERAL_SUBTREE *sub; 2844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int r, match = 0; 2854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin size_t i; 2864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* 2884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * Permitted subtrees: if any subtrees exist of matching the type at 2894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * least one subtree must match. 2904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin */ 2914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 2924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { 2934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); 2944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (gen->type != sub->base->type) 2954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin continue; 2964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (sub->minimum || sub->maximum) 2974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_SUBTREE_MINMAX; 2984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If we already have a match don't bother trying any more */ 2994969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (match == 2) 3004969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin continue; 3014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (match == 0) 3024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin match = 1; 3034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin r = nc_match_single(gen, sub->base); 3044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (r == X509_V_OK) 3054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin match = 2; 3064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else if (r != X509_V_ERR_PERMITTED_VIOLATION) 3074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return r; 3084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (match == 1) 3114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 3124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Excluded subtrees: must not match any of these */ 3144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { 3164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); 3174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (gen->type != sub->base->type) 3184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin continue; 3194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (sub->minimum || sub->maximum) 3204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_SUBTREE_MINMAX; 3214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin r = nc_match_single(gen, sub->base); 3234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (r == X509_V_OK) 3244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_EXCLUDED_VIOLATION; 3254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else if (r != X509_V_ERR_PERMITTED_VIOLATION) 3264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return r; 3274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 3314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 334d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) 3354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 3364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin switch (base->type) { 3374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case GEN_DIRNAME: 3384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return nc_dn(gen->d.directoryName, base->d.directoryName); 339d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3404969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case GEN_DNS: 3414969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return nc_dns(gen->d.dNSName, base->d.dNSName); 342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case GEN_EMAIL: 3444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return nc_email(gen->d.rfc822Name, base->d.rfc822Name); 345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin case GEN_URI: 3474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return nc_uri(gen->d.uniformResourceIdentifier, 3484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin base->d.uniformResourceIdentifier); 349d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin default: 3514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; 3524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 355d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin/* 3574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * directoryName name constraint matching. The canonical encoding of 3584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * X509_NAME makes this comparison easy. It is matched if the subtree is a 3594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * subset of the name. 360d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 361d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 362d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_dn(X509_NAME *nm, X509_NAME *base) 3634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 3644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Ensure canonical encodings are up to date. */ 3654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) 3664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_OUT_OF_MEM; 3674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (base->modified && i2d_X509_NAME(base, NULL) < 0) 3684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_OUT_OF_MEM; 3694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (base->canon_enclen > nm->canon_enclen) 3704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 37169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan if (OPENSSL_memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) 3724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 3734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 3744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 376d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) 3774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 3784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin char *baseptr = (char *)base->data; 3794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin char *dnsptr = (char *)dns->data; 3804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Empty matches everything */ 3814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!*baseptr) 3824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 3834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* 3844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * Otherwise can add zero or more components on the left so compare RHS 3854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin * and if dns is longer and expect '.' as preceding character. 3864969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin */ 3874969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (dns->length > base->length) { 3884969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin dnsptr += dns->length - base->length; 3894969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (*baseptr != '.' && dnsptr[-1] != '.') 3904969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 3914969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 3924969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3934969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (OPENSSL_strcasecmp(baseptr, dnsptr)) 3944969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 3954969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3964969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 3974969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 3984969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 399d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 400d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) 4014969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 4024969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *baseptr = (char *)base->data; 4034969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *emlptr = (char *)eml->data; 4044969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4054969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *baseat = strchr(baseptr, '@'); 4064969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *emlat = strchr(emlptr, '@'); 4074969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!emlat) 4084969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; 4094969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Special case: inital '.' is RHS match */ 4104969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!baseat && (*baseptr == '.')) { 4114969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (eml->length > base->length) { 4124969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin emlptr += eml->length - base->length; 4134969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!OPENSSL_strcasecmp(baseptr, emlptr)) 4144969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 4154969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4164969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 4174969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4184969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4194969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* If we have anything before '@' match local part */ 4204969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4214969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (baseat) { 4224969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (baseat != baseptr) { 4234969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if ((baseat - baseptr) != (emlat - emlptr)) 4244969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 4254969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Case sensitive match of local part */ 4264969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (strncmp(baseptr, emlptr, emlat - emlptr)) 4274969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 4284969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4294969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Position base after '@' */ 4304969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin baseptr = baseat + 1; 4314969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4324969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin emlptr = emlat + 1; 4334969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Just have hostname left to match: case insensitive */ 4344969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (OPENSSL_strcasecmp(baseptr, emlptr)) 4354969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 4364969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4374969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 4384969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4394969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 441d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) 4424969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin{ 4434969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *baseptr = (char *)base->data; 4444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *hostptr = (char *)uri->data; 4454969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin const char *p = strchr(hostptr, ':'); 4464969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin int hostlen; 4474969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Check for foo:// and skip past it */ 4484969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!p || (p[1] != '/') || (p[2] != '/')) 4494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; 4504969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin hostptr = p + 3; 4514969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4524969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Determine length of hostname part of URI */ 4534969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4544969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Look for a port indicator as end of hostname first */ 4554969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4564969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin p = strchr(hostptr, ':'); 4574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Otherwise look for trailing slash */ 4584969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!p) 4594969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin p = strchr(hostptr, '/'); 4604969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!p) 4624969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin hostlen = strlen(hostptr); 4634969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin else 4644969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin hostlen = p - hostptr; 4654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4664969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (hostlen == 0) 4674969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; 4684969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4694969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin /* Special case: inital '.' is RHS match */ 4704969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (*baseptr == '.') { 4714969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (hostlen > base->length) { 4724969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin p = hostptr + hostlen - base->length; 4734969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if (!OPENSSL_strncasecmp(p, baseptr, base->length)) 4744969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 4754969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4764969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 4774969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin } 4784969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4794969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin if ((base->length != (int)hostlen) 4804969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin || OPENSSL_strncasecmp(hostptr, baseptr, hostlen)) 4814969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_ERR_PERMITTED_VIOLATION; 4824969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4834969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin return X509_V_OK; 4844969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 4854969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin} 486