diff options
author | beck <> | 2016-11-05 20:14:59 +0000 |
---|---|---|
committer | beck <> | 2016-11-05 20:14:59 +0000 |
commit | 7b6bcaa93d2188a6cb2fb807134db0f89431dac3 (patch) | |
tree | 53bfe8b60583155aa7efbd2eec5361c8d3415475 | |
parent | 3deb5afd0a0dc2544bc4b40d483329904ef852b1 (diff) | |
download | openbsd-7b6bcaa93d2188a6cb2fb807134db0f89431dac3.tar.gz openbsd-7b6bcaa93d2188a6cb2fb807134db0f89431dac3.tar.bz2 openbsd-7b6bcaa93d2188a6cb2fb807134db0f89431dac3.zip |
Part one of the alt chains changes, bring in newer modifications to
VERIFY_PARAMS - based on boringssl.
ok jsing@ miod@
-rw-r--r-- | src/lib/libcrypto/x509/vpm_int.h | 70 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.h | 34 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_vpm.c | 380 |
3 files changed, 411 insertions, 73 deletions
diff --git a/src/lib/libcrypto/x509/vpm_int.h b/src/lib/libcrypto/x509/vpm_int.h index e69de29bb2..3bd357bddd 100644 --- a/src/lib/libcrypto/x509/vpm_int.h +++ b/src/lib/libcrypto/x509/vpm_int.h | |||
@@ -0,0 +1,70 @@ | |||
1 | /* $OpenBSD: vpm_int.h,v 1.2 2016/11/05 20:14:59 beck Exp $ */ | ||
2 | /* | ||
3 | * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project | ||
4 | * 2013. | ||
5 | */ | ||
6 | /* ==================================================================== | ||
7 | * Copyright (c) 2013 The OpenSSL Project. All rights reserved. | ||
8 | * | ||
9 | * Redistribution and use in source and binary forms, with or without | ||
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in | ||
18 | * the documentation and/or other materials provided with the | ||
19 | * distribution. | ||
20 | * | ||
21 | * 3. All advertising materials mentioning features or use of this | ||
22 | * software must display the following acknowledgment: | ||
23 | * "This product includes software developed by the OpenSSL Project | ||
24 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
25 | * | ||
26 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
27 | * endorse or promote products derived from this software without | ||
28 | * prior written permission. For written permission, please contact | ||
29 | * licensing@OpenSSL.org. | ||
30 | * | ||
31 | * 5. Products derived from this software may not be called "OpenSSL" | ||
32 | * nor may "OpenSSL" appear in their names without prior written | ||
33 | * permission of the OpenSSL Project. | ||
34 | * | ||
35 | * 6. Redistributions of any form whatsoever must retain the following | ||
36 | * acknowledgment: | ||
37 | * "This product includes software developed by the OpenSSL Project | ||
38 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
39 | * | ||
40 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
41 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
42 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
43 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
44 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
45 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
46 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
47 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
49 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
50 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
51 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
52 | * ==================================================================== | ||
53 | * | ||
54 | * This product includes cryptographic software written by Eric Young | ||
55 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
56 | * Hudson (tjh@cryptsoft.com). | ||
57 | * | ||
58 | */ | ||
59 | |||
60 | /* internal only structure to hold additional X509_VERIFY_PARAM data */ | ||
61 | |||
62 | struct X509_VERIFY_PARAM_ID_st { | ||
63 | STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */ | ||
64 | unsigned int hostflags; /* Flags to control matching features */ | ||
65 | char *peername; /* Matching hostname in peer certificate */ | ||
66 | char *email; /* If not NULL email address to match */ | ||
67 | size_t emaillen; | ||
68 | unsigned char *ip; /* If not NULL IP address to match */ | ||
69 | size_t iplen; /* Length of IP address */ | ||
70 | }; | ||
diff --git a/src/lib/libcrypto/x509/x509_vfy.h b/src/lib/libcrypto/x509/x509_vfy.h index e3a1db2407..4b81e8a2cd 100644 --- a/src/lib/libcrypto/x509/x509_vfy.h +++ b/src/lib/libcrypto/x509/x509_vfy.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_vfy.h,v 1.16 2015/09/14 16:13:39 jsing Exp $ */ | 1 | /* $OpenBSD: x509_vfy.h,v 1.17 2016/11/05 20:14:59 beck Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -147,6 +147,8 @@ typedef struct x509_lookup_method_st | |||
147 | X509_OBJECT *ret); | 147 | X509_OBJECT *ret); |
148 | } X509_LOOKUP_METHOD; | 148 | } X509_LOOKUP_METHOD; |
149 | 149 | ||
150 | typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID; | ||
151 | |||
150 | /* This structure hold all parameters associated with a verify operation | 152 | /* This structure hold all parameters associated with a verify operation |
151 | * by including an X509_VERIFY_PARAM structure in related structures the | 153 | * by including an X509_VERIFY_PARAM structure in related structures the |
152 | * parameters used can be customized | 154 | * parameters used can be customized |
@@ -162,7 +164,8 @@ typedef struct X509_VERIFY_PARAM_st | |||
162 | int trust; /* trust setting to check */ | 164 | int trust; /* trust setting to check */ |
163 | int depth; /* Verify depth */ | 165 | int depth; /* Verify depth */ |
164 | STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ | 166 | STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ |
165 | } X509_VERIFY_PARAM; | 167 | X509_VERIFY_PARAM_ID *id; /* opaque ID data */ |
168 | } X509_VERIFY_PARAM; | ||
166 | 169 | ||
167 | DECLARE_STACK_OF(X509_VERIFY_PARAM) | 170 | DECLARE_STACK_OF(X509_VERIFY_PARAM) |
168 | 171 | ||
@@ -288,8 +291,7 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); | |||
288 | (long)(type),NULL) | 291 | (long)(type),NULL) |
289 | 292 | ||
290 | #define X509_V_OK 0 | 293 | #define X509_V_OK 0 |
291 | /* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */ | 294 | #define X509_V_ERR_UNSPECIFIED 1 |
292 | |||
293 | #define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 | 295 | #define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 |
294 | #define X509_V_ERR_UNABLE_TO_GET_CRL 3 | 296 | #define X509_V_ERR_UNABLE_TO_GET_CRL 3 |
295 | #define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 | 297 | #define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 |
@@ -351,6 +353,16 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); | |||
351 | /* The application is not happy */ | 353 | /* The application is not happy */ |
352 | #define X509_V_ERR_APPLICATION_VERIFICATION 50 | 354 | #define X509_V_ERR_APPLICATION_VERIFICATION 50 |
353 | 355 | ||
356 | /* Host, email and IP check errors */ | ||
357 | #define X509_V_ERR_HOSTNAME_MISMATCH 62 | ||
358 | #define X509_V_ERR_EMAIL_MISMATCH 63 | ||
359 | #define X509_V_ERR_IP_ADDRESS_MISMATCH 64 | ||
360 | |||
361 | /* Caller error */ | ||
362 | #define X509_V_ERR_INVALID_CALL 65 | ||
363 | /* Issuer lookup error */ | ||
364 | #define X509_V_ERR_STORE_LOOKUP 66 | ||
365 | |||
354 | /* Certificate verify flags */ | 366 | /* Certificate verify flags */ |
355 | 367 | ||
356 | /* Send issuer+subject checks to verify_cb */ | 368 | /* Send issuer+subject checks to verify_cb */ |
@@ -383,6 +395,16 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); | |||
383 | #define X509_V_FLAG_USE_DELTAS 0x2000 | 395 | #define X509_V_FLAG_USE_DELTAS 0x2000 |
384 | /* Check selfsigned CA signature */ | 396 | /* Check selfsigned CA signature */ |
385 | #define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 | 397 | #define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 |
398 | /* Use trusted store first */ | ||
399 | #define X509_V_FLAG_TRUSTED_FIRST 0x8000 | ||
400 | /* Allow partial chains if at least one certificate is in trusted store */ | ||
401 | #define X509_V_FLAG_PARTIAL_CHAIN 0x80000 | ||
402 | |||
403 | /* If the initial chain is not trusted, do not attempt to build an alternative | ||
404 | * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag | ||
405 | * will force the behaviour to match that of previous versions. */ | ||
406 | #define X509_V_FLAG_NO_ALT_CHAINS 0x100000 | ||
407 | |||
386 | /* Do not check certificate or CRL validity against current time. */ | 408 | /* Do not check certificate or CRL validity against current time. */ |
387 | #define X509_V_FLAG_NO_CHECK_TIME 0x200000 | 409 | #define X509_V_FLAG_NO_CHECK_TIME 0x200000 |
388 | 410 | ||
@@ -519,6 +541,10 @@ int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, | |||
519 | ASN1_OBJECT *policy); | 541 | ASN1_OBJECT *policy); |
520 | int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, | 542 | int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, |
521 | STACK_OF(ASN1_OBJECT) *policies); | 543 | STACK_OF(ASN1_OBJECT) *policies); |
544 | int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, | ||
545 | size_t emaillen); | ||
546 | int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, | ||
547 | size_t iplen); | ||
522 | int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); | 548 | int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); |
523 | 549 | ||
524 | int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); | 550 | int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); |
diff --git a/src/lib/libcrypto/x509/x509_vpm.c b/src/lib/libcrypto/x509/x509_vpm.c index 8ec972050d..46375d798b 100644 --- a/src/lib/libcrypto/x509/x509_vpm.c +++ b/src/lib/libcrypto/x509/x509_vpm.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_vpm.c,v 1.11 2014/09/29 04:16:49 miod Exp $ */ | 1 | /* $OpenBSD: x509_vpm.c,v 1.12 2016/11/05 20:14:59 beck Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 2004. | 3 | * project 2004. |
4 | */ | 4 | */ |
@@ -62,14 +62,108 @@ | |||
62 | #include <openssl/buffer.h> | 62 | #include <openssl/buffer.h> |
63 | #include <openssl/crypto.h> | 63 | #include <openssl/crypto.h> |
64 | #include <openssl/lhash.h> | 64 | #include <openssl/lhash.h> |
65 | #include <openssl/stack.h> | ||
65 | #include <openssl/x509.h> | 66 | #include <openssl/x509.h> |
66 | #include <openssl/x509v3.h> | 67 | #include <openssl/x509v3.h> |
67 | 68 | ||
69 | #include "vpm_int.h" | ||
70 | |||
68 | /* X509_VERIFY_PARAM functions */ | 71 | /* X509_VERIFY_PARAM functions */ |
69 | 72 | ||
73 | #define SET_HOST 0 | ||
74 | #define ADD_HOST 1 | ||
75 | |||
76 | static void | ||
77 | str_free(char *s) | ||
78 | { | ||
79 | free(s); | ||
80 | } | ||
81 | |||
82 | #define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) | ||
83 | |||
84 | |||
85 | /* | ||
86 | * Post 1.0.1 sk function "deep_copy". For the moment we simply make | ||
87 | * these take void * and use them directly without a glorious blob of | ||
88 | * obfuscating macros of dubious value in front of them. All this in | ||
89 | * preparation for a rototilling of safestack.h (likely inspired by | ||
90 | * this). | ||
91 | */ | ||
92 | static void * | ||
93 | sk_deep_copy(void *sk_void, void *copy_func_void, void *free_func_void) | ||
94 | { | ||
95 | _STACK *sk = sk_void; | ||
96 | void *(*copy_func)(void *) = copy_func_void; | ||
97 | void (*free_func)(void *) = copy_func_void; | ||
98 | _STACK *ret = sk_dup(sk); | ||
99 | |||
100 | if (ret == NULL) | ||
101 | return NULL; | ||
102 | |||
103 | size_t i; | ||
104 | for (i = 0; i < ret->num; i++) { | ||
105 | if (ret->data[i] == NULL) | ||
106 | continue; | ||
107 | ret->data[i] = copy_func(ret->data[i]); | ||
108 | if (ret->data[i] == NULL) { | ||
109 | size_t j; | ||
110 | for (j = 0; j < i; j++) { | ||
111 | if (ret->data[j] != NULL) | ||
112 | free_func(ret->data[j]); | ||
113 | } | ||
114 | sk_free(ret); | ||
115 | return NULL; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | static int | ||
123 | int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode, | ||
124 | const char *name, size_t namelen) | ||
125 | { | ||
126 | char *copy; | ||
127 | |||
128 | /* | ||
129 | * Refuse names with embedded NUL bytes. | ||
130 | * XXX: Do we need to push an error onto the error stack? | ||
131 | */ | ||
132 | if (name && memchr(name, '\0', namelen)) | ||
133 | return 0; | ||
134 | |||
135 | if (mode == SET_HOST && id->hosts) { | ||
136 | string_stack_free(id->hosts); | ||
137 | id->hosts = NULL; | ||
138 | } | ||
139 | if (name == NULL || namelen == 0) | ||
140 | return 1; | ||
141 | copy = strndup(name, namelen); | ||
142 | if (copy == NULL) | ||
143 | return 0; | ||
144 | |||
145 | if (id->hosts == NULL && | ||
146 | (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { | ||
147 | free(copy); | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | if (!sk_OPENSSL_STRING_push(id->hosts, copy)) { | ||
152 | free(copy); | ||
153 | if (sk_OPENSSL_STRING_num(id->hosts) == 0) { | ||
154 | sk_OPENSSL_STRING_free(id->hosts); | ||
155 | id->hosts = NULL; | ||
156 | } | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | return 1; | ||
161 | } | ||
162 | |||
70 | static void | 163 | static void |
71 | x509_verify_param_zero(X509_VERIFY_PARAM *param) | 164 | x509_verify_param_zero(X509_VERIFY_PARAM *param) |
72 | { | 165 | { |
166 | X509_VERIFY_PARAM_ID *paramid; | ||
73 | if (!param) | 167 | if (!param) |
74 | return; | 168 | return; |
75 | param->name = NULL; | 169 | param->name = NULL; |
@@ -83,14 +177,35 @@ x509_verify_param_zero(X509_VERIFY_PARAM *param) | |||
83 | sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); | 177 | sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); |
84 | param->policies = NULL; | 178 | param->policies = NULL; |
85 | } | 179 | } |
180 | paramid = param->id; | ||
181 | if (paramid->hosts) { | ||
182 | string_stack_free(paramid->hosts); | ||
183 | paramid->hosts = NULL; | ||
184 | } | ||
185 | free(paramid->peername); | ||
186 | paramid->peername = NULL; | ||
187 | free(paramid->email); | ||
188 | paramid->email = NULL; | ||
189 | paramid->emaillen = 0; | ||
190 | free(paramid->ip); | ||
191 | paramid->ip = NULL; | ||
192 | paramid->iplen = 0; | ||
86 | } | 193 | } |
87 | 194 | ||
88 | X509_VERIFY_PARAM * | 195 | X509_VERIFY_PARAM * |
89 | X509_VERIFY_PARAM_new(void) | 196 | X509_VERIFY_PARAM_new(void) |
90 | { | 197 | { |
91 | X509_VERIFY_PARAM *param; | 198 | X509_VERIFY_PARAM *param; |
92 | 199 | X509_VERIFY_PARAM_ID *paramid; | |
93 | param = calloc(1, sizeof(X509_VERIFY_PARAM)); | 200 | param = calloc(1, sizeof(X509_VERIFY_PARAM)); |
201 | if (param == NULL) | ||
202 | return NULL; | ||
203 | paramid = calloc (1, sizeof(X509_VERIFY_PARAM_ID)); | ||
204 | if (paramid == NULL) { | ||
205 | free(param); | ||
206 | return NULL; | ||
207 | } | ||
208 | param->id = paramid; | ||
94 | x509_verify_param_zero(param); | 209 | x509_verify_param_zero(param); |
95 | return param; | 210 | return param; |
96 | } | 211 | } |
@@ -98,7 +213,10 @@ X509_VERIFY_PARAM_new(void) | |||
98 | void | 213 | void |
99 | X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) | 214 | X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) |
100 | { | 215 | { |
216 | if (param == NULL) | ||
217 | return; | ||
101 | x509_verify_param_zero(param); | 218 | x509_verify_param_zero(param); |
219 | free(param->id); | ||
102 | free(param); | 220 | free(param); |
103 | } | 221 | } |
104 | 222 | ||
@@ -139,21 +257,27 @@ X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) | |||
139 | (to_overwrite || \ | 257 | (to_overwrite || \ |
140 | ((src->field != def) && (to_default || (dest->field == def)))) | 258 | ((src->field != def) && (to_default || (dest->field == def)))) |
141 | 259 | ||
260 | /* As above but for ID fields */ | ||
261 | |||
262 | #define test_x509_verify_param_copy_id(idf, def) \ | ||
263 | test_x509_verify_param_copy(id->idf, def) | ||
264 | |||
142 | /* Macro to test and copy a field if necessary */ | 265 | /* Macro to test and copy a field if necessary */ |
143 | 266 | ||
144 | #define x509_verify_param_copy(field, def) \ | 267 | #define x509_verify_param_copy(field, def) \ |
145 | if (test_x509_verify_param_copy(field, def)) \ | 268 | if (test_x509_verify_param_copy(field, def)) \ |
146 | dest->field = src->field | 269 | dest->field = src->field |
147 | 270 | ||
148 | |||
149 | int | 271 | int |
150 | X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) | 272 | X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) |
151 | { | 273 | { |
152 | unsigned long inh_flags; | 274 | unsigned long inh_flags; |
153 | int to_default, to_overwrite; | 275 | int to_default, to_overwrite; |
276 | X509_VERIFY_PARAM_ID *id; | ||
154 | 277 | ||
155 | if (!src) | 278 | if (!src) |
156 | return 1; | 279 | return 1; |
280 | id = src->id; | ||
157 | inh_flags = dest->inh_flags | src->inh_flags; | 281 | inh_flags = dest->inh_flags | src->inh_flags; |
158 | 282 | ||
159 | if (inh_flags & X509_VP_FLAG_ONCE) | 283 | if (inh_flags & X509_VP_FLAG_ONCE) |
@@ -194,6 +318,32 @@ X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, const X509_VERIFY_PARAM *src) | |||
194 | return 0; | 318 | return 0; |
195 | } | 319 | } |
196 | 320 | ||
321 | /* Copy the host flags if and only if we're copying the host list */ | ||
322 | if (test_x509_verify_param_copy_id(hosts, NULL)) { | ||
323 | if (dest->id->hosts) { | ||
324 | string_stack_free(dest->id->hosts); | ||
325 | dest->id->hosts = NULL; | ||
326 | } | ||
327 | if (id->hosts) { | ||
328 | dest->id->hosts = | ||
329 | sk_deep_copy(id->hosts, strdup, str_free); | ||
330 | if (dest->id->hosts == NULL) | ||
331 | return 0; | ||
332 | dest->id->hostflags = id->hostflags; | ||
333 | } | ||
334 | } | ||
335 | |||
336 | if (test_x509_verify_param_copy_id(email, NULL)) { | ||
337 | if (!X509_VERIFY_PARAM_set1_email(dest, id->email, | ||
338 | id->emaillen)) | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | if (test_x509_verify_param_copy_id(ip, NULL)) { | ||
343 | if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen)) | ||
344 | return 0; | ||
345 | } | ||
346 | |||
197 | return 1; | 347 | return 1; |
198 | } | 348 | } |
199 | 349 | ||
@@ -209,6 +359,33 @@ X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from) | |||
209 | return ret; | 359 | return ret; |
210 | } | 360 | } |
211 | 361 | ||
362 | static int | ||
363 | int_x509_param_set1(char **pdest, size_t *pdestlen, const char *src, | ||
364 | size_t srclen) | ||
365 | { | ||
366 | char *tmp; | ||
367 | if (src) { | ||
368 | if (srclen == 0) { | ||
369 | if ((tmp = strdup(src)) == NULL) | ||
370 | return 0; | ||
371 | srclen = strlen(src); | ||
372 | } else { | ||
373 | if ((tmp = malloc(srclen)) == NULL) | ||
374 | return 0; | ||
375 | memcpy(tmp, src, srclen); | ||
376 | } | ||
377 | } else { | ||
378 | tmp = NULL; | ||
379 | srclen = 0; | ||
380 | } | ||
381 | if (*pdest) | ||
382 | free(*pdest); | ||
383 | *pdest = tmp; | ||
384 | if (pdestlen) | ||
385 | *pdestlen = srclen; | ||
386 | return 1; | ||
387 | } | ||
388 | |||
212 | int | 389 | int |
213 | X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) | 390 | X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) |
214 | { | 391 | { |
@@ -318,82 +495,121 @@ X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, | |||
318 | } | 495 | } |
319 | 496 | ||
320 | int | 497 | int |
498 | X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, | ||
499 | const char *name, size_t namelen) | ||
500 | { | ||
501 | return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen); | ||
502 | } | ||
503 | |||
504 | int | ||
505 | X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, | ||
506 | const char *name, size_t namelen) | ||
507 | { | ||
508 | return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen); | ||
509 | } | ||
510 | |||
511 | void | ||
512 | X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags) | ||
513 | { | ||
514 | param->id->hostflags = flags; | ||
515 | } | ||
516 | |||
517 | char * | ||
518 | X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) | ||
519 | { | ||
520 | return param->id->peername; | ||
521 | } | ||
522 | |||
523 | int | ||
524 | X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, | ||
525 | size_t emaillen) | ||
526 | { | ||
527 | return int_x509_param_set1(¶m->id->email, ¶m->id->emaillen, | ||
528 | email, emaillen); | ||
529 | } | ||
530 | |||
531 | int | ||
532 | X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, | ||
533 | size_t iplen) | ||
534 | { | ||
535 | if (iplen != 0 && iplen != 4 && iplen != 16) | ||
536 | return 0; | ||
537 | return int_x509_param_set1((char **)¶m->id->ip, ¶m->id->iplen, | ||
538 | (char *)ip, iplen); | ||
539 | } | ||
540 | |||
541 | int | ||
542 | X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) | ||
543 | { | ||
544 | unsigned char ipout[16]; | ||
545 | size_t iplen; | ||
546 | |||
547 | iplen = (size_t)a2i_ipadd(ipout, ipasc); | ||
548 | if (iplen == 0) | ||
549 | return 0; | ||
550 | return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); | ||
551 | } | ||
552 | |||
553 | int | ||
321 | X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) | 554 | X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) |
322 | { | 555 | { |
323 | return param->depth; | 556 | return param->depth; |
324 | } | 557 | } |
325 | 558 | ||
326 | /* Default verify parameters: these are used for various | 559 | const char * |
327 | * applications and can be overridden by the user specified table. | 560 | X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) |
328 | * NB: the 'name' field *must* be in alphabetical order because it | 561 | { |
329 | * will be searched using OBJ_search. | 562 | return param->name; |
563 | } | ||
564 | |||
565 | static const X509_VERIFY_PARAM_ID _empty_id = { NULL }; | ||
566 | |||
567 | #define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id | ||
568 | |||
569 | /* | ||
570 | * Default verify parameters: these are used for various applications and can | ||
571 | * be overridden by the user specified table. | ||
330 | */ | 572 | */ |
331 | 573 | ||
332 | static const X509_VERIFY_PARAM default_table[] = { | 574 | static const X509_VERIFY_PARAM default_table[] = { |
333 | { | 575 | { |
334 | "default", /* X509 default parameters */ | 576 | .name = "default", |
335 | 0, /* Check time */ | 577 | .depth = 100, |
336 | 0, /* internal flags */ | 578 | .id = vpm_empty_id |
337 | 0, /* flags */ | ||
338 | 0, /* purpose */ | ||
339 | 0, /* trust */ | ||
340 | 100, /* depth */ | ||
341 | NULL /* policies */ | ||
342 | }, | 579 | }, |
343 | { | 580 | { |
344 | "pkcs7", /* S/MIME sign parameters */ | 581 | .name = "pkcs7", |
345 | 0, /* Check time */ | 582 | .purpose = X509_PURPOSE_SMIME_SIGN, |
346 | 0, /* internal flags */ | 583 | .trust = X509_TRUST_EMAIL, |
347 | 0, /* flags */ | 584 | .depth = -1, |
348 | X509_PURPOSE_SMIME_SIGN, /* purpose */ | 585 | .id = vpm_empty_id |
349 | X509_TRUST_EMAIL, /* trust */ | ||
350 | -1, /* depth */ | ||
351 | NULL /* policies */ | ||
352 | }, | 586 | }, |
353 | { | 587 | { |
354 | "smime_sign", /* S/MIME sign parameters */ | 588 | .name = "smime_sign", |
355 | 0, /* Check time */ | 589 | .purpose = X509_PURPOSE_SMIME_SIGN, |
356 | 0, /* internal flags */ | 590 | .trust = X509_TRUST_EMAIL, |
357 | 0, /* flags */ | 591 | .depth = -1, |
358 | X509_PURPOSE_SMIME_SIGN, /* purpose */ | 592 | .id = vpm_empty_id |
359 | X509_TRUST_EMAIL, /* trust */ | ||
360 | -1, /* depth */ | ||
361 | NULL /* policies */ | ||
362 | }, | 593 | }, |
363 | { | 594 | { |
364 | "ssl_client", /* SSL/TLS client parameters */ | 595 | .name = "ssl_client", |
365 | 0, /* Check time */ | 596 | .purpose = X509_PURPOSE_SSL_CLIENT, |
366 | 0, /* internal flags */ | 597 | .trust = X509_TRUST_SSL_CLIENT, |
367 | 0, /* flags */ | 598 | .depth = -1, |
368 | X509_PURPOSE_SSL_CLIENT, /* purpose */ | 599 | .id = vpm_empty_id |
369 | X509_TRUST_SSL_CLIENT, /* trust */ | ||
370 | -1, /* depth */ | ||
371 | NULL /* policies */ | ||
372 | }, | 600 | }, |
373 | { | 601 | { |
374 | "ssl_server", /* SSL/TLS server parameters */ | 602 | .name = "ssl_server", |
375 | 0, /* Check time */ | 603 | .purpose = X509_PURPOSE_SSL_SERVER, |
376 | 0, /* internal flags */ | 604 | .trust = X509_TRUST_SSL_SERVER, |
377 | 0, /* flags */ | 605 | .depth = -1, |
378 | X509_PURPOSE_SSL_SERVER, /* purpose */ | 606 | .id = vpm_empty_id |
379 | X509_TRUST_SSL_SERVER, /* trust */ | ||
380 | -1, /* depth */ | ||
381 | NULL /* policies */ | ||
382 | } | 607 | } |
383 | }; | 608 | }; |
384 | 609 | ||
385 | static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; | 610 | static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; |
386 | 611 | ||
387 | static int | 612 | static int |
388 | table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) | ||
389 | { | ||
390 | return strcmp(a->name, b->name); | ||
391 | } | ||
392 | |||
393 | DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); | ||
394 | IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); | ||
395 | |||
396 | static int | ||
397 | param_cmp(const X509_VERIFY_PARAM * const *a, | 613 | param_cmp(const X509_VERIFY_PARAM * const *a, |
398 | const X509_VERIFY_PARAM * const *b) | 614 | const X509_VERIFY_PARAM * const *b) |
399 | { | 615 | { |
@@ -403,19 +619,21 @@ param_cmp(const X509_VERIFY_PARAM * const *a, | |||
403 | int | 619 | int |
404 | X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) | 620 | X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) |
405 | { | 621 | { |
406 | int idx; | ||
407 | X509_VERIFY_PARAM *ptmp; | 622 | X509_VERIFY_PARAM *ptmp; |
408 | |||
409 | if (!param_table) { | 623 | if (!param_table) { |
410 | param_table = sk_X509_VERIFY_PARAM_new(param_cmp); | 624 | param_table = sk_X509_VERIFY_PARAM_new(param_cmp); |
411 | if (!param_table) | 625 | if (!param_table) |
412 | return 0; | 626 | return 0; |
413 | } else { | 627 | } else { |
414 | idx = sk_X509_VERIFY_PARAM_find(param_table, param); | 628 | size_t idx; |
415 | if (idx != -1) { | 629 | |
416 | ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); | 630 | if ((idx = sk_X509_VERIFY_PARAM_find(param_table, param)) |
631 | != -1) { | ||
632 | ptmp = sk_X509_VERIFY_PARAM_value(param_table, | ||
633 | idx); | ||
417 | X509_VERIFY_PARAM_free(ptmp); | 634 | X509_VERIFY_PARAM_free(ptmp); |
418 | (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); | 635 | (void)sk_X509_VERIFY_PARAM_delete(param_table, |
636 | idx); | ||
419 | } | 637 | } |
420 | } | 638 | } |
421 | if (!sk_X509_VERIFY_PARAM_push(param_table, param)) | 639 | if (!sk_X509_VERIFY_PARAM_push(param_table, param)) |
@@ -423,20 +641,44 @@ X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) | |||
423 | return 1; | 641 | return 1; |
424 | } | 642 | } |
425 | 643 | ||
426 | const X509_VERIFY_PARAM * | 644 | int |
427 | X509_VERIFY_PARAM_lookup(const char *name) | 645 | X509_VERIFY_PARAM_get_count(void) |
646 | { | ||
647 | int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); | ||
648 | if (param_table) | ||
649 | num += sk_X509_VERIFY_PARAM_num(param_table); | ||
650 | return num; | ||
651 | } | ||
652 | |||
653 | const | ||
654 | X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id) | ||
655 | { | ||
656 | int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); | ||
657 | if (id < num) | ||
658 | return default_table + id; | ||
659 | return sk_X509_VERIFY_PARAM_value(param_table, id - num); | ||
660 | } | ||
661 | |||
662 | const | ||
663 | X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) | ||
428 | { | 664 | { |
429 | int idx; | ||
430 | X509_VERIFY_PARAM pm; | 665 | X509_VERIFY_PARAM pm; |
666 | unsigned int i, limit; | ||
431 | 667 | ||
432 | pm.name = (char *)name; | 668 | pm.name = (char *)name; |
433 | if (param_table) { | 669 | if (param_table) { |
434 | idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); | 670 | size_t idx; |
435 | if (idx != -1) | 671 | if ((idx = sk_X509_VERIFY_PARAM_find(param_table, &pm)) != -1) |
436 | return sk_X509_VERIFY_PARAM_value(param_table, idx); | 672 | return sk_X509_VERIFY_PARAM_value(param_table, idx); |
437 | } | 673 | } |
438 | return OBJ_bsearch_table(&pm, default_table, | 674 | |
439 | sizeof(default_table)/sizeof(X509_VERIFY_PARAM)); | 675 | limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); |
676 | for (i = 0; i < limit; i++) { | ||
677 | if (strcmp(default_table[i].name, name) == 0) { | ||
678 | return &default_table[i]; | ||
679 | } | ||
680 | } | ||
681 | return NULL; | ||
440 | } | 682 | } |
441 | 683 | ||
442 | void | 684 | void |