mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-11 00:13:55 +08:00
@@ -1,66 +1,18 @@
|
||||
/* v3_purp.c */
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2001.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2004 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 1999-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/numbers.h"
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/x509_vfy.h>
|
||||
#include "internal/x509_int.h"
|
||||
|
||||
static void x509v3_cache_extensions(X509 *x);
|
||||
|
||||
@@ -108,9 +60,7 @@ static X509_PURPOSE xstandard[] = {
|
||||
NULL},
|
||||
};
|
||||
|
||||
#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
|
||||
|
||||
IMPLEMENT_STACK_OF(X509_PURPOSE)
|
||||
#define X509_PURPOSE_COUNT OSSL_NELEM(xstandard)
|
||||
|
||||
static STACK_OF(X509_PURPOSE) *xptable = NULL;
|
||||
|
||||
@@ -129,10 +79,11 @@ int X509_check_purpose(X509 *x, int id, int ca)
|
||||
int idx;
|
||||
const X509_PURPOSE *pt;
|
||||
if (!(x->ex_flags & EXFLAG_SET)) {
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509);
|
||||
CRYPTO_THREAD_write_lock(x->lock);
|
||||
x509v3_cache_extensions(x);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
|
||||
CRYPTO_THREAD_unlock(x->lock);
|
||||
}
|
||||
/* Return if side-effect only call */
|
||||
if (id == -1)
|
||||
return 1;
|
||||
idx = X509_PURPOSE_get_by_id(id);
|
||||
@@ -168,13 +119,13 @@ X509_PURPOSE *X509_PURPOSE_get0(int idx)
|
||||
return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
|
||||
}
|
||||
|
||||
int X509_PURPOSE_get_by_sname(char *sname)
|
||||
int X509_PURPOSE_get_by_sname(const char *sname)
|
||||
{
|
||||
int i;
|
||||
X509_PURPOSE *xptmp;
|
||||
for (i = 0; i < X509_PURPOSE_get_count(); i++) {
|
||||
xptmp = X509_PURPOSE_get0(i);
|
||||
if (!strcmp(xptmp->sname, sname))
|
||||
if (strcmp(xptmp->sname, sname) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@@ -197,7 +148,7 @@ int X509_PURPOSE_get_by_id(int purpose)
|
||||
|
||||
int X509_PURPOSE_add(int id, int trust, int flags,
|
||||
int (*ck) (const X509_PURPOSE *, const X509 *, int),
|
||||
char *name, char *sname, void *arg)
|
||||
const char *name, const char *sname, void *arg)
|
||||
{
|
||||
int idx;
|
||||
X509_PURPOSE *ptmp;
|
||||
@@ -211,7 +162,7 @@ int X509_PURPOSE_add(int id, int trust, int flags,
|
||||
idx = X509_PURPOSE_get_by_id(id);
|
||||
/* Need a new entry */
|
||||
if (idx == -1) {
|
||||
if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
|
||||
if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) {
|
||||
X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
@@ -225,11 +176,11 @@ int X509_PURPOSE_add(int id, int trust, int flags,
|
||||
OPENSSL_free(ptmp->sname);
|
||||
}
|
||||
/* dup supplied name */
|
||||
ptmp->name = BUF_strdup(name);
|
||||
ptmp->sname = BUF_strdup(sname);
|
||||
ptmp->name = OPENSSL_strdup(name);
|
||||
ptmp->sname = OPENSSL_strdup(sname);
|
||||
if (!ptmp->name || !ptmp->sname) {
|
||||
X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
/* Keep the dynamic flag of existing entry */
|
||||
ptmp->flags &= X509_PURPOSE_DYNAMIC;
|
||||
@@ -243,16 +194,24 @@ int X509_PURPOSE_add(int id, int trust, int flags,
|
||||
|
||||
/* If its a new entry manage the dynamic table */
|
||||
if (idx == -1) {
|
||||
if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
|
||||
if (xptable == NULL
|
||||
&& (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) {
|
||||
X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
|
||||
X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
err:
|
||||
if (idx == -1) {
|
||||
OPENSSL_free(ptmp->name);
|
||||
OPENSSL_free(ptmp->sname);
|
||||
OPENSSL_free(ptmp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xptable_free(X509_PURPOSE *p)
|
||||
@@ -270,29 +229,26 @@ static void xptable_free(X509_PURPOSE *p)
|
||||
|
||||
void X509_PURPOSE_cleanup(void)
|
||||
{
|
||||
unsigned int i;
|
||||
sk_X509_PURPOSE_pop_free(xptable, xptable_free);
|
||||
for (i = 0; i < X509_PURPOSE_COUNT; i++)
|
||||
xptable_free(xstandard + i);
|
||||
xptable = NULL;
|
||||
}
|
||||
|
||||
int X509_PURPOSE_get_id(X509_PURPOSE *xp)
|
||||
int X509_PURPOSE_get_id(const X509_PURPOSE *xp)
|
||||
{
|
||||
return xp->purpose;
|
||||
}
|
||||
|
||||
char *X509_PURPOSE_get0_name(X509_PURPOSE *xp)
|
||||
char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp)
|
||||
{
|
||||
return xp->name;
|
||||
}
|
||||
|
||||
char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp)
|
||||
char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp)
|
||||
{
|
||||
return xp->sname;
|
||||
}
|
||||
|
||||
int X509_PURPOSE_get_trust(X509_PURPOSE *xp)
|
||||
int X509_PURPOSE_get_trust(const X509_PURPOSE *xp)
|
||||
{
|
||||
return xp->trust;
|
||||
}
|
||||
@@ -321,7 +277,6 @@ int X509_supported_extension(X509_EXTENSION *ex)
|
||||
NID_subject_alt_name, /* 85 */
|
||||
NID_basic_constraints, /* 87 */
|
||||
NID_certificate_policies, /* 89 */
|
||||
NID_crl_distribution_points, /* 103 */
|
||||
NID_ext_key_usage, /* 126 */
|
||||
#ifndef OPENSSL_NO_RFC3779
|
||||
NID_sbgp_ipAddrBlock, /* 290 */
|
||||
@@ -339,8 +294,7 @@ int X509_supported_extension(X509_EXTENSION *ex)
|
||||
if (ex_nid == NID_undef)
|
||||
return 0;
|
||||
|
||||
if (OBJ_bsearch_nid(&ex_nid, supported_nids,
|
||||
sizeof(supported_nids) / sizeof(int)))
|
||||
if (OBJ_bsearch_nid(&ex_nid, supported_nids, OSSL_NELEM(supported_nids)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -397,13 +351,19 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
ASN1_BIT_STRING *ns;
|
||||
EXTENDED_KEY_USAGE *extusage;
|
||||
X509_EXTENSION *ex;
|
||||
|
||||
const EVP_MD *md;
|
||||
int i;
|
||||
#ifndef OPENSSL_NO_SHA
|
||||
md = EVP_sha1();
|
||||
#elif !defined(OPENSSL_NO_SM3)
|
||||
md = EVP_sm3();
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (x->ex_flags & EXFLAG_SET)
|
||||
return;
|
||||
#ifndef OPENSSL_NO_SHA
|
||||
X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
|
||||
#endif
|
||||
X509_digest(x, md, x->sha1_hash, NULL);
|
||||
/* V1 should mean no extensions ... */
|
||||
if (!X509_get_version(x))
|
||||
x->ex_flags |= EXFLAG_V1;
|
||||
@@ -576,12 +536,22 @@ static int check_ca(const X509 *x)
|
||||
}
|
||||
}
|
||||
|
||||
void X509_set_proxy_flag(X509 *x)
|
||||
{
|
||||
x->ex_flags |= EXFLAG_PROXY;
|
||||
}
|
||||
|
||||
void X509_set_proxy_pathlen(X509 *x, long l)
|
||||
{
|
||||
x->ex_pcpathlen = l;
|
||||
}
|
||||
|
||||
int X509_check_ca(X509 *x)
|
||||
{
|
||||
if (!(x->ex_flags & EXFLAG_SET)) {
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509);
|
||||
CRYPTO_THREAD_write_lock(x->lock);
|
||||
x509v3_cache_extensions(x);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509);
|
||||
CRYPTO_THREAD_unlock(x->lock);
|
||||
}
|
||||
|
||||
return check_ca(x);
|
||||
@@ -763,7 +733,7 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
|
||||
return 0;
|
||||
|
||||
/* Extended Key Usage MUST be critical */
|
||||
i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1);
|
||||
i_ext = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
|
||||
if (i_ext >= 0) {
|
||||
X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext);
|
||||
if (!X509_EXTENSION_get_critical(ext))
|
||||
@@ -851,3 +821,53 @@ int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
|
||||
}
|
||||
return X509_V_OK;
|
||||
}
|
||||
|
||||
uint32_t X509_get_extension_flags(X509 *x)
|
||||
{
|
||||
/* Call for side-effect of computing hash and caching extensions */
|
||||
X509_check_purpose(x, -1, -1);
|
||||
return x->ex_flags;
|
||||
}
|
||||
|
||||
uint32_t X509_get_key_usage(X509 *x)
|
||||
{
|
||||
/* Call for side-effect of computing hash and caching extensions */
|
||||
X509_check_purpose(x, -1, -1);
|
||||
if (x->ex_flags & EXFLAG_KUSAGE)
|
||||
return x->ex_kusage;
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
uint32_t X509_get_extended_key_usage(X509 *x)
|
||||
{
|
||||
/* Call for side-effect of computing hash and caching extensions */
|
||||
X509_check_purpose(x, -1, -1);
|
||||
if (x->ex_flags & EXFLAG_XKUSAGE)
|
||||
return x->ex_xkusage;
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x)
|
||||
{
|
||||
/* Call for side-effect of computing hash and caching extensions */
|
||||
X509_check_purpose(x, -1, -1);
|
||||
return x->skid;
|
||||
}
|
||||
|
||||
long X509_get_pathlen(X509 *x)
|
||||
{
|
||||
/* Called for side effect of caching extensions */
|
||||
if (X509_check_purpose(x, -1, -1) != 1
|
||||
|| (x->ex_flags & EXFLAG_BCONS) == 0)
|
||||
return -1;
|
||||
return x->ex_pathlen;
|
||||
}
|
||||
|
||||
long X509_get_proxy_pathlen(X509 *x)
|
||||
{
|
||||
/* Called for side effect of caching extensions */
|
||||
if (X509_check_purpose(x, -1, -1) != 1
|
||||
|| (x->ex_flags & EXFLAG_PROXY) == 0)
|
||||
return -1;
|
||||
return x->ex_pcpathlen;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user