source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_vpm.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 17.2 KB
Line 
1/*
2 * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11
12#include "internal/cryptlib.h"
13#include <openssl/crypto.h>
14#include <openssl/lhash.h>
15#include <openssl/buffer.h>
16#include <openssl/x509.h>
17#include <openssl/x509v3.h>
18#include "internal/x509_int.h"
19
20#include "x509_lcl.h"
21
22/* X509_VERIFY_PARAM functions */
23
24#define SET_HOST 0
25#define ADD_HOST 1
26
27static char *str_copy(const char *s)
28{
29 return OPENSSL_strdup(s);
30}
31
32static void str_free(char *s)
33{
34 OPENSSL_free(s);
35}
36
37static int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode,
38 const char *name, size_t namelen)
39{
40 char *copy;
41
42 /*
43 * Refuse names with embedded NUL bytes, except perhaps as final byte.
44 * XXX: Do we need to push an error onto the error stack?
45 */
46 if (namelen == 0 || name == NULL)
47 namelen = name ? strlen(name) : 0;
48 else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen))
49 return 0;
50 if (namelen > 0 && name[namelen - 1] == '\0')
51 --namelen;
52
53 if (mode == SET_HOST) {
54 sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free);
55 vpm->hosts = NULL;
56 }
57 if (name == NULL || namelen == 0)
58 return 1;
59
60 copy = OPENSSL_strndup(name, namelen);
61 if (copy == NULL)
62 return 0;
63
64 if (vpm->hosts == NULL &&
65 (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
66 OPENSSL_free(copy);
67 return 0;
68 }
69
70 if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) {
71 OPENSSL_free(copy);
72 if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) {
73 sk_OPENSSL_STRING_free(vpm->hosts);
74 vpm->hosts = NULL;
75 }
76 return 0;
77 }
78
79 return 1;
80}
81
82static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
83{
84 if (!param)
85 return;
86 param->name = NULL;
87 param->purpose = 0;
88 param->trust = X509_TRUST_DEFAULT;
89 /*
90 * param->inh_flags = X509_VP_FLAG_DEFAULT;
91 */
92 param->inh_flags = 0;
93 param->flags = 0;
94 param->depth = -1;
95 param->auth_level = -1; /* -1 means unset, 0 is explicit */
96 sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
97 param->policies = NULL;
98 sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
99 param->hosts = NULL;
100 OPENSSL_free(param->peername);
101 param->peername = NULL;
102 OPENSSL_free(param->email);
103 param->email = NULL;
104 param->emaillen = 0;
105 OPENSSL_free(param->ip);
106 param->ip = NULL;
107 param->iplen = 0;
108}
109
110X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
111{
112 X509_VERIFY_PARAM *param;
113
114 param = OPENSSL_zalloc(sizeof(*param));
115 if (param == NULL)
116 return NULL;
117 x509_verify_param_zero(param);
118 return param;
119}
120
121void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
122{
123 if (!param)
124 return;
125 x509_verify_param_zero(param);
126 OPENSSL_free(param);
127}
128
129/*-
130 * This function determines how parameters are "inherited" from one structure
131 * to another. There are several different ways this can happen.
132 *
133 * 1. If a child structure needs to have its values initialized from a parent
134 * they are simply copied across. For example SSL_CTX copied to SSL.
135 * 2. If the structure should take on values only if they are currently unset.
136 * For example the values in an SSL structure will take appropriate value
137 * for SSL servers or clients but only if the application has not set new
138 * ones.
139 *
140 * The "inh_flags" field determines how this function behaves.
141 *
142 * Normally any values which are set in the default are not copied from the
143 * destination and verify flags are ORed together.
144 *
145 * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
146 * to the destination. Effectively the values in "to" become default values
147 * which will be used only if nothing new is set in "from".
148 *
149 * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
150 * they are set or not. Flags is still Ored though.
151 *
152 * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
153 * of ORed.
154 *
155 * If X509_VP_FLAG_LOCKED is set then no values are copied.
156 *
157 * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
158 * after the next call.
159 */
160
161/* Macro to test if a field should be copied from src to dest */
162
163#define test_x509_verify_param_copy(field, def) \
164 (to_overwrite || \
165 ((src->field != def) && (to_default || (dest->field == def))))
166
167/* Macro to test and copy a field if necessary */
168
169#define x509_verify_param_copy(field, def) \
170 if (test_x509_verify_param_copy(field, def)) \
171 dest->field = src->field
172
173int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
174 const X509_VERIFY_PARAM *src)
175{
176 unsigned long inh_flags;
177 int to_default, to_overwrite;
178 if (!src)
179 return 1;
180 inh_flags = dest->inh_flags | src->inh_flags;
181
182 if (inh_flags & X509_VP_FLAG_ONCE)
183 dest->inh_flags = 0;
184
185 if (inh_flags & X509_VP_FLAG_LOCKED)
186 return 1;
187
188 if (inh_flags & X509_VP_FLAG_DEFAULT)
189 to_default = 1;
190 else
191 to_default = 0;
192
193 if (inh_flags & X509_VP_FLAG_OVERWRITE)
194 to_overwrite = 1;
195 else
196 to_overwrite = 0;
197
198 x509_verify_param_copy(purpose, 0);
199 x509_verify_param_copy(trust, X509_TRUST_DEFAULT);
200 x509_verify_param_copy(depth, -1);
201 x509_verify_param_copy(auth_level, -1);
202
203 /* If overwrite or check time not set, copy across */
204
205 if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
206 dest->check_time = src->check_time;
207 dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
208 /* Don't need to copy flag: that is done below */
209 }
210
211 if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
212 dest->flags = 0;
213
214 dest->flags |= src->flags;
215
216 if (test_x509_verify_param_copy(policies, NULL)) {
217 if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
218 return 0;
219 }
220
221 /* Copy the host flags if and only if we're copying the host list */
222 if (test_x509_verify_param_copy(hosts, NULL)) {
223 sk_OPENSSL_STRING_pop_free(dest->hosts, str_free);
224 dest->hosts = NULL;
225 if (src->hosts) {
226 dest->hosts =
227 sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free);
228 if (dest->hosts == NULL)
229 return 0;
230 dest->hostflags = src->hostflags;
231 }
232 }
233
234 if (test_x509_verify_param_copy(email, NULL)) {
235 if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen))
236 return 0;
237 }
238
239 if (test_x509_verify_param_copy(ip, NULL)) {
240 if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen))
241 return 0;
242 }
243
244 return 1;
245}
246
247int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
248 const X509_VERIFY_PARAM *from)
249{
250 unsigned long save_flags = to->inh_flags;
251 int ret;
252 to->inh_flags |= X509_VP_FLAG_DEFAULT;
253 ret = X509_VERIFY_PARAM_inherit(to, from);
254 to->inh_flags = save_flags;
255 return ret;
256}
257
258static int int_x509_param_set1(char **pdest, size_t *pdestlen,
259 const char *src, size_t srclen)
260{
261 void *tmp;
262 if (src) {
263 if (srclen == 0)
264 srclen = strlen(src);
265
266 tmp = OPENSSL_memdup(src, srclen);
267 if (tmp == NULL)
268 return 0;
269 } else {
270 tmp = NULL;
271 srclen = 0;
272 }
273 OPENSSL_free(*pdest);
274 *pdest = tmp;
275 if (pdestlen != NULL)
276 *pdestlen = srclen;
277 return 1;
278}
279
280int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
281{
282 OPENSSL_free(param->name);
283 param->name = OPENSSL_strdup(name);
284 if (param->name)
285 return 1;
286 return 0;
287}
288
289int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
290{
291 param->flags |= flags;
292 if (flags & X509_V_FLAG_POLICY_MASK)
293 param->flags |= X509_V_FLAG_POLICY_CHECK;
294 return 1;
295}
296
297int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
298 unsigned long flags)
299{
300 param->flags &= ~flags;
301 return 1;
302}
303
304unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
305{
306 return param->flags;
307}
308
309uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param)
310{
311 return param->inh_flags;
312}
313
314int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, uint32_t flags)
315{
316 param->inh_flags = flags;
317 return 1;
318}
319
320int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
321{
322 return X509_PURPOSE_set(&param->purpose, purpose);
323}
324
325int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
326{
327 return X509_TRUST_set(&param->trust, trust);
328}
329
330void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
331{
332 param->depth = depth;
333}
334
335void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
336{
337 param->auth_level = auth_level;
338}
339
340time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param)
341{
342 return param->check_time;
343}
344
345void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
346{
347 param->check_time = t;
348 param->flags |= X509_V_FLAG_USE_CHECK_TIME;
349}
350
351int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
352 ASN1_OBJECT *policy)
353{
354 if (!param->policies) {
355 param->policies = sk_ASN1_OBJECT_new_null();
356 if (!param->policies)
357 return 0;
358 }
359 if (!sk_ASN1_OBJECT_push(param->policies, policy))
360 return 0;
361 return 1;
362}
363
364int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
365 STACK_OF(ASN1_OBJECT) *policies)
366{
367 int i;
368 ASN1_OBJECT *oid, *doid;
369
370 if (!param)
371 return 0;
372 sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
373
374 if (!policies) {
375 param->policies = NULL;
376 return 1;
377 }
378
379 param->policies = sk_ASN1_OBJECT_new_null();
380 if (!param->policies)
381 return 0;
382
383 for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
384 oid = sk_ASN1_OBJECT_value(policies, i);
385 doid = OBJ_dup(oid);
386 if (!doid)
387 return 0;
388 if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
389 ASN1_OBJECT_free(doid);
390 return 0;
391 }
392 }
393 param->flags |= X509_V_FLAG_POLICY_CHECK;
394 return 1;
395}
396
397int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
398 const char *name, size_t namelen)
399{
400 return int_x509_param_set_hosts(param, SET_HOST, name, namelen);
401}
402
403int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
404 const char *name, size_t namelen)
405{
406 return int_x509_param_set_hosts(param, ADD_HOST, name, namelen);
407}
408
409void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
410 unsigned int flags)
411{
412 param->hostflags = flags;
413}
414
415char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
416{
417 return param->peername;
418}
419
420/*
421 * Move peername from one param structure to another, freeing any name present
422 * at the target. If the source is a NULL parameter structure, free and zero
423 * the target peername.
424 */
425void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to,
426 X509_VERIFY_PARAM *from)
427{
428 char *peername = (from != NULL) ? from->peername : NULL;
429
430 if (to->peername != peername) {
431 OPENSSL_free(to->peername);
432 to->peername = peername;
433 }
434 if (from)
435 from->peername = NULL;
436}
437
438int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
439 const char *email, size_t emaillen)
440{
441 return int_x509_param_set1(&param->email, &param->emaillen,
442 email, emaillen);
443}
444
445int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
446 const unsigned char *ip, size_t iplen)
447{
448 if (iplen != 0 && iplen != 4 && iplen != 16)
449 return 0;
450 return int_x509_param_set1((char **)&param->ip, &param->iplen,
451 (char *)ip, iplen);
452}
453
454int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
455{
456 unsigned char ipout[16];
457 size_t iplen;
458
459 iplen = (size_t)a2i_ipadd(ipout, ipasc);
460 if (iplen == 0)
461 return 0;
462 return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
463}
464
465int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
466{
467 return param->depth;
468}
469
470int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param)
471{
472 return param->auth_level;
473}
474
475const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
476{
477 return param->name;
478}
479
480#define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0
481
482/*
483 * Default verify parameters: these are used for various applications and can
484 * be overridden by the user specified table. NB: the 'name' field *must* be
485 * in alphabetical order because it will be searched using OBJ_search.
486 */
487
488static const X509_VERIFY_PARAM default_table[] = {
489 {
490 "default", /* X509 default parameters */
491 0, /* Check time */
492 0, /* internal flags */
493 X509_V_FLAG_TRUSTED_FIRST, /* flags */
494 0, /* purpose */
495 0, /* trust */
496 100, /* depth */
497 -1, /* auth_level */
498 NULL, /* policies */
499 vpm_empty_id},
500 {
501 "pkcs7", /* S/MIME sign parameters */
502 0, /* Check time */
503 0, /* internal flags */
504 0, /* flags */
505 X509_PURPOSE_SMIME_SIGN, /* purpose */
506 X509_TRUST_EMAIL, /* trust */
507 -1, /* depth */
508 -1, /* auth_level */
509 NULL, /* policies */
510 vpm_empty_id},
511 {
512 "smime_sign", /* S/MIME sign parameters */
513 0, /* Check time */
514 0, /* internal flags */
515 0, /* flags */
516 X509_PURPOSE_SMIME_SIGN, /* purpose */
517 X509_TRUST_EMAIL, /* trust */
518 -1, /* depth */
519 -1, /* auth_level */
520 NULL, /* policies */
521 vpm_empty_id},
522 {
523 "ssl_client", /* SSL/TLS client parameters */
524 0, /* Check time */
525 0, /* internal flags */
526 0, /* flags */
527 X509_PURPOSE_SSL_CLIENT, /* purpose */
528 X509_TRUST_SSL_CLIENT, /* trust */
529 -1, /* depth */
530 -1, /* auth_level */
531 NULL, /* policies */
532 vpm_empty_id},
533 {
534 "ssl_server", /* SSL/TLS server parameters */
535 0, /* Check time */
536 0, /* internal flags */
537 0, /* flags */
538 X509_PURPOSE_SSL_SERVER, /* purpose */
539 X509_TRUST_SSL_SERVER, /* trust */
540 -1, /* depth */
541 -1, /* auth_level */
542 NULL, /* policies */
543 vpm_empty_id}
544};
545
546static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
547
548static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
549{
550 return strcmp(a->name, b->name);
551}
552
553DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table);
554IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table);
555
556static int param_cmp(const X509_VERIFY_PARAM *const *a,
557 const X509_VERIFY_PARAM *const *b)
558{
559 return strcmp((*a)->name, (*b)->name);
560}
561
562int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
563{
564 int idx;
565 X509_VERIFY_PARAM *ptmp;
566 if (param_table == NULL) {
567 param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
568 if (param_table == NULL)
569 return 0;
570 } else {
571 idx = sk_X509_VERIFY_PARAM_find(param_table, param);
572 if (idx != -1) {
573 ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
574 X509_VERIFY_PARAM_free(ptmp);
575 (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
576 }
577 }
578 if (!sk_X509_VERIFY_PARAM_push(param_table, param))
579 return 0;
580 return 1;
581}
582
583int X509_VERIFY_PARAM_get_count(void)
584{
585 int num = OSSL_NELEM(default_table);
586 if (param_table)
587 num += sk_X509_VERIFY_PARAM_num(param_table);
588 return num;
589}
590
591const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
592{
593 int num = OSSL_NELEM(default_table);
594 if (id < num)
595 return default_table + id;
596 return sk_X509_VERIFY_PARAM_value(param_table, id - num);
597}
598
599const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
600{
601 int idx;
602 X509_VERIFY_PARAM pm;
603
604 pm.name = (char *)name;
605 if (param_table) {
606 idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
607 if (idx != -1)
608 return sk_X509_VERIFY_PARAM_value(param_table, idx);
609 }
610 return OBJ_bsearch_table(&pm, default_table, OSSL_NELEM(default_table));
611}
612
613void X509_VERIFY_PARAM_table_cleanup(void)
614{
615 sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
616 param_table = NULL;
617}
Note: See TracBrowser for help on using the repository browser.