mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-10 16:03:48 +08:00
@@ -1,68 +1,22 @@
|
||||
/* v3_ncons.c */
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
* Copyright 2003-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/asn1_int.h"
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "internal/x509_int.h"
|
||||
#include "ext_dat.h"
|
||||
|
||||
static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
X509V3_CTX *ctx,
|
||||
STACK_OF(CONF_VALUE) *nval);
|
||||
@@ -70,7 +24,7 @@ static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
|
||||
BIO *bp, int ind);
|
||||
static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
|
||||
STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp,
|
||||
int ind, char *name);
|
||||
int ind, const char *name);
|
||||
static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
|
||||
|
||||
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
|
||||
@@ -79,6 +33,7 @@ static int nc_dn(X509_NAME *sub, X509_NAME *nm);
|
||||
static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
|
||||
static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
|
||||
static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
|
||||
static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base);
|
||||
|
||||
const X509V3_EXT_METHOD v3_name_constraints = {
|
||||
NID_name_constraints, 0,
|
||||
@@ -115,15 +70,16 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
|
||||
NAME_CONSTRAINTS *ncons = NULL;
|
||||
GENERAL_SUBTREE *sub = NULL;
|
||||
|
||||
ncons = NAME_CONSTRAINTS_new();
|
||||
if (!ncons)
|
||||
if (ncons == NULL)
|
||||
goto memerr;
|
||||
for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
|
||||
val = sk_CONF_VALUE_value(nval, i);
|
||||
if (!strncmp(val->name, "permitted", 9) && val->name[9]) {
|
||||
if (strncmp(val->name, "permitted", 9) == 0 && val->name[9]) {
|
||||
ptree = &ncons->permittedSubtrees;
|
||||
tval.name = val->name + 10;
|
||||
} else if (!strncmp(val->name, "excluded", 8) && val->name[8]) {
|
||||
} else if (strncmp(val->name, "excluded", 8) == 0 && val->name[8]) {
|
||||
ptree = &ncons->excludedSubtrees;
|
||||
tval.name = val->name + 9;
|
||||
} else {
|
||||
@@ -136,9 +92,9 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
goto memerr;
|
||||
if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
|
||||
goto err;
|
||||
if (!*ptree)
|
||||
if (*ptree == NULL)
|
||||
*ptree = sk_GENERAL_SUBTREE_new_null();
|
||||
if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub))
|
||||
if (*ptree == NULL || !sk_GENERAL_SUBTREE_push(*ptree, sub))
|
||||
goto memerr;
|
||||
sub = NULL;
|
||||
}
|
||||
@@ -148,10 +104,8 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
|
||||
memerr:
|
||||
X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
|
||||
err:
|
||||
if (ncons)
|
||||
NAME_CONSTRAINTS_free(ncons);
|
||||
if (sub)
|
||||
GENERAL_SUBTREE_free(sub);
|
||||
NAME_CONSTRAINTS_free(ncons);
|
||||
GENERAL_SUBTREE_free(sub);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -169,7 +123,7 @@ static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
|
||||
|
||||
static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
|
||||
STACK_OF(GENERAL_SUBTREE) *trees,
|
||||
BIO *bp, int ind, char *name)
|
||||
BIO *bp, int ind, const char *name)
|
||||
{
|
||||
GENERAL_SUBTREE *tree;
|
||||
int i;
|
||||
@@ -245,7 +199,8 @@ int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
|
||||
/* Process any email address attributes in subject name */
|
||||
|
||||
for (i = -1;;) {
|
||||
X509_NAME_ENTRY *ne;
|
||||
const X509_NAME_ENTRY *ne;
|
||||
|
||||
i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i);
|
||||
if (i == -1)
|
||||
break;
|
||||
@@ -273,6 +228,51 @@ int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
|
||||
|
||||
}
|
||||
|
||||
int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)
|
||||
{
|
||||
int r, i;
|
||||
X509_NAME *nm;
|
||||
|
||||
ASN1_STRING stmp;
|
||||
GENERAL_NAME gntmp;
|
||||
stmp.flags = 0;
|
||||
stmp.type = V_ASN1_IA5STRING;
|
||||
gntmp.type = GEN_DNS;
|
||||
gntmp.d.dNSName = &stmp;
|
||||
|
||||
nm = X509_get_subject_name(x);
|
||||
|
||||
/* Process any commonName attributes in subject name */
|
||||
|
||||
for (i = -1;;) {
|
||||
X509_NAME_ENTRY *ne;
|
||||
ASN1_STRING *hn;
|
||||
i = X509_NAME_get_index_by_NID(nm, NID_commonName, i);
|
||||
if (i == -1)
|
||||
break;
|
||||
ne = X509_NAME_get_entry(nm, i);
|
||||
hn = X509_NAME_ENTRY_get_data(ne);
|
||||
/* Only process attributes that look like host names */
|
||||
if (asn1_valid_host(hn)) {
|
||||
unsigned char *h;
|
||||
int hlen = ASN1_STRING_to_UTF8(&h, hn);
|
||||
if (hlen <= 0)
|
||||
return X509_V_ERR_OUT_OF_MEM;
|
||||
|
||||
stmp.length = hlen;
|
||||
stmp.data = h;
|
||||
|
||||
r = nc_match(&gntmp, nc);
|
||||
|
||||
OPENSSL_free(h);
|
||||
|
||||
if (r != X509_V_OK)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return X509_V_OK;
|
||||
}
|
||||
|
||||
static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
|
||||
{
|
||||
GENERAL_SUBTREE *sub;
|
||||
@@ -341,6 +341,9 @@ static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
|
||||
return nc_uri(gen->d.uniformResourceIdentifier,
|
||||
base->d.uniformResourceIdentifier);
|
||||
|
||||
case GEN_IPADD:
|
||||
return nc_ip(gen->d.iPAddress, base->d.iPAddress);
|
||||
|
||||
default:
|
||||
return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
|
||||
}
|
||||
@@ -400,11 +403,11 @@ static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
|
||||
const char *emlat = strchr(emlptr, '@');
|
||||
if (!emlat)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
/* Special case: inital '.' is RHS match */
|
||||
/* Special case: initial '.' is RHS match */
|
||||
if (!baseat && (*baseptr == '.')) {
|
||||
if (eml->length > base->length) {
|
||||
emlptr += eml->length - base->length;
|
||||
if (!strcasecmp(baseptr, emlptr))
|
||||
if (strcasecmp(baseptr, emlptr) == 0)
|
||||
return X509_V_OK;
|
||||
}
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
@@ -460,11 +463,11 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
|
||||
if (hostlen == 0)
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
|
||||
/* Special case: inital '.' is RHS match */
|
||||
/* Special case: initial '.' is RHS match */
|
||||
if (*baseptr == '.') {
|
||||
if (hostlen > base->length) {
|
||||
p = hostptr + hostlen - base->length;
|
||||
if (!strncasecmp(p, baseptr, base->length))
|
||||
if (strncasecmp(p, baseptr, base->length) == 0)
|
||||
return X509_V_OK;
|
||||
}
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
@@ -477,3 +480,34 @@ static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
|
||||
return X509_V_OK;
|
||||
|
||||
}
|
||||
|
||||
static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base)
|
||||
{
|
||||
int hostlen, baselen, i;
|
||||
unsigned char *hostptr, *baseptr, *maskptr;
|
||||
hostptr = ip->data;
|
||||
hostlen = ip->length;
|
||||
baseptr = base->data;
|
||||
baselen = base->length;
|
||||
|
||||
/* Invalid if not IPv4 or IPv6 */
|
||||
if (!((hostlen == 4) || (hostlen == 16)))
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
if (!((baselen == 8) || (baselen == 32)))
|
||||
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
|
||||
|
||||
/* Do not match IPv4 with IPv6 */
|
||||
if (hostlen * 2 != baselen)
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
maskptr = base->data + hostlen;
|
||||
|
||||
/* Considering possible not aligned base ipAddress */
|
||||
/* Not checking for wrong mask definition: i.e.: 255.0.255.0 */
|
||||
for (i = 0; i < hostlen; i++)
|
||||
if ((hostptr[i] & maskptr[i]) != (baseptr[i] & maskptr[i]))
|
||||
return X509_V_ERR_PERMITTED_VIOLATION;
|
||||
|
||||
return X509_V_OK;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user