1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/x509/x509_trs.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,310 @@
1.4 +/* x509_trs.c */
1.5 +/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
1.6 + * project 1999.
1.7 + */
1.8 +/* ====================================================================
1.9 + * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
1.10 + *
1.11 + * Redistribution and use in source and binary forms, with or without
1.12 + * modification, are permitted provided that the following conditions
1.13 + * are met:
1.14 + *
1.15 + * 1. Redistributions of source code must retain the above copyright
1.16 + * notice, this list of conditions and the following disclaimer.
1.17 + *
1.18 + * 2. Redistributions in binary form must reproduce the above copyright
1.19 + * notice, this list of conditions and the following disclaimer in
1.20 + * the documentation and/or other materials provided with the
1.21 + * distribution.
1.22 + *
1.23 + * 3. All advertising materials mentioning features or use of this
1.24 + * software must display the following acknowledgment:
1.25 + * "This product includes software developed by the OpenSSL Project
1.26 + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
1.27 + *
1.28 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.29 + * endorse or promote products derived from this software without
1.30 + * prior written permission. For written permission, please contact
1.31 + * licensing@OpenSSL.org.
1.32 + *
1.33 + * 5. Products derived from this software may not be called "OpenSSL"
1.34 + * nor may "OpenSSL" appear in their names without prior written
1.35 + * permission of the OpenSSL Project.
1.36 + *
1.37 + * 6. Redistributions of any form whatsoever must retain the following
1.38 + * acknowledgment:
1.39 + * "This product includes software developed by the OpenSSL Project
1.40 + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
1.41 + *
1.42 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.43 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.44 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.45 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.46 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.47 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.48 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.49 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.50 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.51 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.52 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.53 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.54 + * ====================================================================
1.55 + *
1.56 + * This product includes cryptographic software written by Eric Young
1.57 + * (eay@cryptsoft.com). This product includes software written by Tim
1.58 + * Hudson (tjh@cryptsoft.com).
1.59 + *
1.60 + */
1.61 + /*
1.62 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.63 + */
1.64 +
1.65 +#include <stdio.h>
1.66 +#include "cryptlib.h"
1.67 +#include <openssl/x509v3.h>
1.68 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.69 +#include "libcrypto_wsd_macros.h"
1.70 +#include "libcrypto_wsd.h"
1.71 +#endif
1.72 +
1.73 +
1.74 +static int tr_cmp(const X509_TRUST * const *a,
1.75 + const X509_TRUST * const *b);
1.76 +static void trtable_free(X509_TRUST *p);
1.77 +
1.78 +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
1.79 +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
1.80 +static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
1.81 +
1.82 +static int obj_trust(int id, X509 *x, int flags);
1.83 +static int (*default_trust)(int id, X509 *x, int flags) = obj_trust;
1.84 +
1.85 +
1.86 +#ifndef EMULATOR
1.87 +/* WARNING: the following table should be kept in order of trust
1.88 + * and without any gaps so we can just subtract the minimum trust
1.89 + * value to get an index into the table
1.90 + */
1.91 +
1.92 +static X509_TRUST trstandard[] = {
1.93 +{X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
1.94 +{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL},
1.95 +{X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, NULL},
1.96 +{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL},
1.97 +{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL},
1.98 +{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL},
1.99 +{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL}
1.100 +};
1.101 +#else
1.102 +static const X509_TRUST trstandard[] = {
1.103 +{X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
1.104 +{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL},
1.105 +{X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, NULL},
1.106 +{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL},
1.107 +{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, NULL},
1.108 +{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, NULL},
1.109 +{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL}
1.110 +};
1.111 +#endif
1.112 +#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST))
1.113 +
1.114 +IMPLEMENT_STACK_OF(X509_TRUST)
1.115 +#ifndef EMULATOR
1.116 +static STACK_OF(X509_TRUST) *trtable = NULL;
1.117 +#else
1.118 +GET_STATIC_VAR_FROM_TLS(trtable,x509_trs,STACK_OF(X509_TRUST) *)
1.119 +#define trtable (*GET_WSD_VAR_NAME(trtable,x509_trs, s)())
1.120 +#endif
1.121 +
1.122 +static int tr_cmp(const X509_TRUST * const *a,
1.123 + const X509_TRUST * const *b)
1.124 +{
1.125 + return (*a)->trust - (*b)->trust;
1.126 +}
1.127 +
1.128 +EXPORT_C int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int)
1.129 +{
1.130 + int (*oldtrust)(int , X509 *, int);
1.131 + oldtrust = default_trust;
1.132 + default_trust = trust;
1.133 + return oldtrust;
1.134 +}
1.135 +
1.136 +
1.137 +EXPORT_C int X509_check_trust(X509 *x, int id, int flags)
1.138 +{
1.139 + X509_TRUST *pt;
1.140 + int idx;
1.141 + if(id == -1) return 1;
1.142 + idx = X509_TRUST_get_by_id(id);
1.143 + if(idx == -1) return default_trust(id, x, flags);
1.144 + pt = X509_TRUST_get0(idx);
1.145 + return pt->check_trust(pt, x, flags);
1.146 +}
1.147 +
1.148 +EXPORT_C int X509_TRUST_get_count(void)
1.149 +{
1.150 + if(!trtable) return X509_TRUST_COUNT;
1.151 + return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
1.152 +}
1.153 +
1.154 +EXPORT_C X509_TRUST * X509_TRUST_get0(int idx)
1.155 +{
1.156 + if(idx < 0) return NULL;
1.157 + if(idx < (int)X509_TRUST_COUNT) return ((X509_TRUST *)trstandard + idx);
1.158 + return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
1.159 +}
1.160 +
1.161 +EXPORT_C int X509_TRUST_get_by_id(int id)
1.162 +{
1.163 + X509_TRUST tmp;
1.164 + int idx;
1.165 + if((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
1.166 + return id - X509_TRUST_MIN;
1.167 + tmp.trust = id;
1.168 + if(!trtable) return -1;
1.169 + idx = sk_X509_TRUST_find(trtable, &tmp);
1.170 + if(idx == -1) return -1;
1.171 + return idx + X509_TRUST_COUNT;
1.172 +}
1.173 +
1.174 +EXPORT_C int X509_TRUST_set(int *t, int trust)
1.175 +{
1.176 + if(X509_TRUST_get_by_id(trust) == -1) {
1.177 + X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST);
1.178 + return 0;
1.179 + }
1.180 + *t = trust;
1.181 + return 1;
1.182 +}
1.183 +
1.184 +EXPORT_C int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
1.185 + char *name, int arg1, void *arg2)
1.186 +{
1.187 + int idx;
1.188 + X509_TRUST *trtmp;
1.189 + /* This is set according to what we change: application can't set it */
1.190 + flags &= ~X509_TRUST_DYNAMIC;
1.191 + /* This will always be set for application modified trust entries */
1.192 + flags |= X509_TRUST_DYNAMIC_NAME;
1.193 + /* Get existing entry if any */
1.194 + idx = X509_TRUST_get_by_id(id);
1.195 + /* Need a new entry */
1.196 + if(idx == -1) {
1.197 + if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
1.198 + X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
1.199 + return 0;
1.200 + }
1.201 + trtmp->flags = X509_TRUST_DYNAMIC;
1.202 + } else trtmp = X509_TRUST_get0(idx);
1.203 +
1.204 + /* OPENSSL_free existing name if dynamic */
1.205 + if(trtmp->flags & X509_TRUST_DYNAMIC_NAME) OPENSSL_free(trtmp->name);
1.206 + /* dup supplied name */
1.207 + if(!(trtmp->name = BUF_strdup(name))) {
1.208 + X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
1.209 + return 0;
1.210 + }
1.211 + /* Keep the dynamic flag of existing entry */
1.212 + trtmp->flags &= X509_TRUST_DYNAMIC;
1.213 + /* Set all other flags */
1.214 + trtmp->flags |= flags;
1.215 +
1.216 + trtmp->trust = id;
1.217 + trtmp->check_trust = ck;
1.218 + trtmp->arg1 = arg1;
1.219 + trtmp->arg2 = arg2;
1.220 +
1.221 + /* If its a new entry manage the dynamic table */
1.222 + if(idx == -1) {
1.223 + if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
1.224 + X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
1.225 + return 0;
1.226 + }
1.227 + if (!sk_X509_TRUST_push(trtable, trtmp)) {
1.228 + X509err(X509_F_X509_TRUST_ADD,ERR_R_MALLOC_FAILURE);
1.229 + return 0;
1.230 + }
1.231 + }
1.232 + return 1;
1.233 +}
1.234 +
1.235 +static void trtable_free(X509_TRUST *p)
1.236 + {
1.237 + if(!p) return;
1.238 + if (p->flags & X509_TRUST_DYNAMIC)
1.239 + {
1.240 + if (p->flags & X509_TRUST_DYNAMIC_NAME)
1.241 + OPENSSL_free(p->name);
1.242 + OPENSSL_free(p);
1.243 + }
1.244 + }
1.245 +
1.246 +EXPORT_C void X509_TRUST_cleanup(void)
1.247 +{
1.248 + unsigned int i;
1.249 + for(i = 0; i < X509_TRUST_COUNT; i++) trtable_free((X509_TRUST *)trstandard + i);
1.250 + sk_X509_TRUST_pop_free(trtable, trtable_free);
1.251 + trtable = NULL;
1.252 +}
1.253 +
1.254 +EXPORT_C int X509_TRUST_get_flags(X509_TRUST *xp)
1.255 +{
1.256 + return xp->flags;
1.257 +}
1.258 +
1.259 +EXPORT_C char *X509_TRUST_get0_name(X509_TRUST *xp)
1.260 +{
1.261 + return xp->name;
1.262 +}
1.263 +
1.264 +EXPORT_C int X509_TRUST_get_trust(X509_TRUST *xp)
1.265 +{
1.266 + return xp->trust;
1.267 +}
1.268 +
1.269 +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
1.270 +{
1.271 + if(x->aux && (x->aux->trust || x->aux->reject))
1.272 + return obj_trust(trust->arg1, x, flags);
1.273 + /* we don't have any trust settings: for compatibility
1.274 + * we return trusted if it is self signed
1.275 + */
1.276 + return trust_compat(trust, x, flags);
1.277 +}
1.278 +
1.279 +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
1.280 +{
1.281 + if(x->aux) return obj_trust(trust->arg1, x, flags);
1.282 + return X509_TRUST_UNTRUSTED;
1.283 +}
1.284 +
1.285 +static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
1.286 +{
1.287 + X509_check_purpose(x, -1, 0);
1.288 + if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED;
1.289 + else return X509_TRUST_UNTRUSTED;
1.290 +}
1.291 +
1.292 +static int obj_trust(int id, X509 *x, int flags)
1.293 +{
1.294 + ASN1_OBJECT *obj;
1.295 + int i;
1.296 + X509_CERT_AUX *ax;
1.297 + ax = x->aux;
1.298 + if(!ax) return X509_TRUST_UNTRUSTED;
1.299 + if(ax->reject) {
1.300 + for(i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
1.301 + obj = sk_ASN1_OBJECT_value(ax->reject, i);
1.302 + if(OBJ_obj2nid(obj) == id) return X509_TRUST_REJECTED;
1.303 + }
1.304 + }
1.305 + if(ax->trust) {
1.306 + for(i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
1.307 + obj = sk_ASN1_OBJECT_value(ax->trust, i);
1.308 + if(OBJ_obj2nid(obj) == id) return X509_TRUST_TRUSTED;
1.309 + }
1.310 + }
1.311 + return X509_TRUST_UNTRUSTED;
1.312 +}
1.313 +