Coverage Report

Created: 2022-08-24 06:30

/src/libressl/crypto/x509/x509_purp.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: x509_purp.c,v 1.16 2022/05/10 19:42:52 tb Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project 2001.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58
59
#include <stdio.h>
60
#include <string.h>
61
62
#include <openssl/opensslconf.h>
63
64
#include <openssl/err.h>
65
#include <openssl/x509v3.h>
66
#include <openssl/x509_vfy.h>
67
68
#include "x509_internal.h"
69
#include "x509_lcl.h"
70
71
0
#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
72
#define ku_reject(x, usage) \
73
0
  (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
74
#define xku_reject(x, usage) \
75
0
  (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
76
#define ns_reject(x, usage) \
77
0
  (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
78
79
void x509v3_cache_extensions(X509 *x);
80
81
static int check_ssl_ca(const X509 *x);
82
static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
83
    int ca);
84
static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
85
    int ca);
86
static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
87
    int ca);
88
static int purpose_smime(const X509 *x, int ca);
89
static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
90
    int ca);
91
static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
92
    int ca);
93
static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
94
    int ca);
95
static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
96
    int ca);
97
static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
98
static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
99
100
static int xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b);
101
static void xptable_free(X509_PURPOSE *p);
102
103
static X509_PURPOSE xstandard[] = {
104
  {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, check_purpose_ssl_client, "SSL client", "sslclient", NULL},
105
  {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ssl_server, "SSL server", "sslserver", NULL},
106
  {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL},
107
  {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL},
108
  {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL},
109
  {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL},
110
  {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL},
111
  {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, "OCSP helper", "ocsphelper", NULL},
112
  {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", NULL},
113
};
114
115
0
#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE))
116
117
static STACK_OF(X509_PURPOSE) *xptable = NULL;
118
119
static int
120
xp_cmp(const X509_PURPOSE * const *a, const X509_PURPOSE * const *b)
121
0
{
122
0
  return (*a)->purpose - (*b)->purpose;
123
0
}
124
125
/* As much as I'd like to make X509_check_purpose use a "const" X509*
126
 * I really can't because it does recalculate hashes and do other non-const
127
 * things. */
128
int
129
X509_check_purpose(X509 *x, int id, int ca)
130
0
{
131
0
  int idx;
132
0
  const X509_PURPOSE *pt;
133
134
0
  if (!(x->ex_flags & EXFLAG_SET)) {
135
0
    CRYPTO_w_lock(CRYPTO_LOCK_X509);
136
0
    x509v3_cache_extensions(x);
137
0
    CRYPTO_w_unlock(CRYPTO_LOCK_X509);
138
0
    if (x->ex_flags & EXFLAG_INVALID)
139
0
      return -1;
140
0
  }
141
0
  if (id == -1)
142
0
    return 1;
143
0
  idx = X509_PURPOSE_get_by_id(id);
144
0
  if (idx == -1)
145
0
    return -1;
146
0
  pt = X509_PURPOSE_get0(idx);
147
0
  return pt->check_purpose(pt, x, ca);
148
0
}
149
150
int
151
X509_PURPOSE_set(int *p, int purpose)
152
0
{
153
0
  if (X509_PURPOSE_get_by_id(purpose) == -1) {
154
0
    X509V3error(X509V3_R_INVALID_PURPOSE);
155
0
    return 0;
156
0
  }
157
0
  *p = purpose;
158
0
  return 1;
159
0
}
160
161
int
162
X509_PURPOSE_get_count(void)
163
0
{
164
0
  if (!xptable)
165
0
    return X509_PURPOSE_COUNT;
166
0
  return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
167
0
}
168
169
X509_PURPOSE *
170
X509_PURPOSE_get0(int idx)
171
0
{
172
0
  if (idx < 0)
173
0
    return NULL;
174
0
  if (idx < (int)X509_PURPOSE_COUNT)
175
0
    return xstandard + idx;
176
0
  return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
177
0
}
178
179
int
180
X509_PURPOSE_get_by_sname(const char *sname)
181
0
{
182
0
  int i;
183
0
  X509_PURPOSE *xptmp;
184
185
0
  for (i = 0; i < X509_PURPOSE_get_count(); i++) {
186
0
    xptmp = X509_PURPOSE_get0(i);
187
0
    if (!strcmp(xptmp->sname, sname))
188
0
      return i;
189
0
  }
190
0
  return -1;
191
0
}
192
193
int
194
X509_PURPOSE_get_by_id(int purpose)
195
0
{
196
0
  X509_PURPOSE tmp;
197
0
  int idx;
198
199
0
  if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
200
0
    return purpose - X509_PURPOSE_MIN;
201
0
  tmp.purpose = purpose;
202
0
  if (!xptable)
203
0
    return -1;
204
0
  idx = sk_X509_PURPOSE_find(xptable, &tmp);
205
0
  if (idx == -1)
206
0
    return -1;
207
0
  return idx + X509_PURPOSE_COUNT;
208
0
}
209
210
int
211
X509_PURPOSE_add(int id, int trust, int flags,
212
    int (*ck)(const X509_PURPOSE *, const X509 *, int), const char *name,
213
    const char *sname, void *arg)
214
0
{
215
0
  int idx;
216
0
  X509_PURPOSE *ptmp;
217
0
  char *name_dup, *sname_dup;
218
219
0
  name_dup = sname_dup = NULL;
220
221
0
  if (name == NULL || sname == NULL) {
222
0
    X509V3error(X509V3_R_INVALID_NULL_ARGUMENT);
223
0
    return 0;
224
0
  }
225
226
  /* This is set according to what we change: application can't set it */
227
0
  flags &= ~X509_PURPOSE_DYNAMIC;
228
  /* This will always be set for application modified trust entries */
229
0
  flags |= X509_PURPOSE_DYNAMIC_NAME;
230
  /* Get existing entry if any */
231
0
  idx = X509_PURPOSE_get_by_id(id);
232
  /* Need a new entry */
233
0
  if (idx == -1) {
234
0
    if ((ptmp = malloc(sizeof(X509_PURPOSE))) == NULL) {
235
0
      X509V3error(ERR_R_MALLOC_FAILURE);
236
0
      return 0;
237
0
    }
238
0
    ptmp->flags = X509_PURPOSE_DYNAMIC;
239
0
  } else
240
0
    ptmp = X509_PURPOSE_get0(idx);
241
242
0
  if ((name_dup = strdup(name)) == NULL)
243
0
    goto err;
244
0
  if ((sname_dup = strdup(sname)) == NULL)
245
0
    goto err;
246
247
  /* free existing name if dynamic */
248
0
  if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
249
0
    free(ptmp->name);
250
0
    free(ptmp->sname);
251
0
  }
252
  /* dup supplied name */
253
0
  ptmp->name = name_dup;
254
0
  ptmp->sname = sname_dup;
255
  /* Keep the dynamic flag of existing entry */
256
0
  ptmp->flags &= X509_PURPOSE_DYNAMIC;
257
  /* Set all other flags */
258
0
  ptmp->flags |= flags;
259
260
0
  ptmp->purpose = id;
261
0
  ptmp->trust = trust;
262
0
  ptmp->check_purpose = ck;
263
0
  ptmp->usr_data = arg;
264
265
  /* If its a new entry manage the dynamic table */
266
0
  if (idx == -1) {
267
0
    if (xptable == NULL &&
268
0
        (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL)
269
0
      goto err;
270
0
    if (sk_X509_PURPOSE_push(xptable, ptmp) == 0)
271
0
      goto err;
272
0
  }
273
0
  return 1;
274
275
0
err:
276
0
  free(name_dup);
277
0
  free(sname_dup);
278
0
  if (idx == -1)
279
0
    free(ptmp);
280
0
  X509V3error(ERR_R_MALLOC_FAILURE);
281
0
  return 0;
282
0
}
283
284
static void
285
xptable_free(X509_PURPOSE *p)
286
0
{
287
0
  if (!p)
288
0
    return;
289
0
  if (p->flags & X509_PURPOSE_DYNAMIC) {
290
0
    if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
291
0
      free(p->name);
292
0
      free(p->sname);
293
0
    }
294
0
    free(p);
295
0
  }
296
0
}
297
298
void
299
X509_PURPOSE_cleanup(void)
300
0
{
301
0
  sk_X509_PURPOSE_pop_free(xptable, xptable_free);
302
0
  xptable = NULL;
303
0
}
304
305
int
306
X509_PURPOSE_get_id(const X509_PURPOSE *xp)
307
0
{
308
0
  return xp->purpose;
309
0
}
310
311
char *
312
X509_PURPOSE_get0_name(const X509_PURPOSE *xp)
313
0
{
314
0
  return xp->name;
315
0
}
316
317
char *
318
X509_PURPOSE_get0_sname(const X509_PURPOSE *xp)
319
0
{
320
0
  return xp->sname;
321
0
}
322
323
int
324
X509_PURPOSE_get_trust(const X509_PURPOSE *xp)
325
0
{
326
0
  return xp->trust;
327
0
}
328
329
static int
330
nid_cmp(const int *a, const int *b)
331
0
{
332
0
  return *a - *b;
333
0
}
334
335
static int nid_cmp_BSEARCH_CMP_FN(const void *, const void *);
336
static int nid_cmp(int const *, int const *);
337
static int *OBJ_bsearch_nid(int *key, int const *base, int num);
338
339
static int
340
nid_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
341
0
{
342
0
  int const *a = a_;
343
0
  int const *b = b_;
344
0
  return nid_cmp(a, b);
345
0
}
346
347
static int *
348
OBJ_bsearch_nid(int *key, int const *base, int num)
349
0
{
350
0
  return (int *)OBJ_bsearch_(key, base, num, sizeof(int),
351
0
      nid_cmp_BSEARCH_CMP_FN);
352
0
}
353
354
int
355
X509_supported_extension(X509_EXTENSION *ex)
356
0
{
357
  /* This table is a list of the NIDs of supported extensions:
358
   * that is those which are used by the verify process. If
359
   * an extension is critical and doesn't appear in this list
360
   * then the verify process will normally reject the certificate.
361
   * The list must be kept in numerical order because it will be
362
   * searched using bsearch.
363
   */
364
365
0
  static const int supported_nids[] = {
366
0
    NID_netscape_cert_type, /* 71 */
367
0
    NID_key_usage,   /* 83 */
368
0
    NID_subject_alt_name, /* 85 */
369
0
    NID_basic_constraints, /* 87 */
370
0
    NID_certificate_policies, /* 89 */
371
0
    NID_ext_key_usage, /* 126 */
372
0
#ifndef OPENSSL_NO_RFC3779
373
0
    NID_sbgp_ipAddrBlock,   /* 290 */
374
0
    NID_sbgp_autonomousSysNum, /* 291 */
375
0
#endif
376
0
    NID_policy_constraints, /* 401 */
377
0
    NID_proxyCertInfo, /* 663 */
378
0
    NID_name_constraints, /* 666 */
379
0
    NID_policy_mappings, /* 747 */
380
    NID_inhibit_any_policy  /* 748 */
381
0
  };
382
383
0
  int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
384
385
0
  if (ex_nid == NID_undef)
386
0
    return 0;
387
388
0
  if (OBJ_bsearch_nid(&ex_nid, supported_nids,
389
0
      sizeof(supported_nids) / sizeof(int)))
390
0
    return 1;
391
0
  return 0;
392
0
}
393
394
static void
395
setup_dp(X509 *x, DIST_POINT *dp)
396
0
{
397
0
  X509_NAME *iname = NULL;
398
0
  int i;
399
400
0
  if (dp->reasons) {
401
0
    if (dp->reasons->length > 0)
402
0
      dp->dp_reasons = dp->reasons->data[0];
403
0
    if (dp->reasons->length > 1)
404
0
      dp->dp_reasons |= (dp->reasons->data[1] << 8);
405
0
    dp->dp_reasons &= CRLDP_ALL_REASONS;
406
0
  } else
407
0
    dp->dp_reasons = CRLDP_ALL_REASONS;
408
0
  if (!dp->distpoint || (dp->distpoint->type != 1))
409
0
    return;
410
0
  for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
411
0
    GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
412
0
    if (gen->type == GEN_DIRNAME) {
413
0
      iname = gen->d.directoryName;
414
0
      break;
415
0
    }
416
0
  }
417
0
  if (!iname)
418
0
    iname = X509_get_issuer_name(x);
419
420
0
  DIST_POINT_set_dpname(dp->distpoint, iname);
421
422
0
}
423
424
static void
425
setup_crldp(X509 *x)
426
0
{
427
0
  int i;
428
429
0
  x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL);
430
0
  if (x->crldp == NULL && i != -1) {
431
0
    x->ex_flags |= EXFLAG_INVALID;
432
0
    return;
433
0
  }
434
435
0
  for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
436
0
    setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
437
0
}
438
439
void
440
x509v3_cache_extensions(X509 *x)
441
0
{
442
0
  BASIC_CONSTRAINTS *bs;
443
0
  PROXY_CERT_INFO_EXTENSION *pci;
444
0
  ASN1_BIT_STRING *usage;
445
0
  ASN1_BIT_STRING *ns;
446
0
  EXTENDED_KEY_USAGE *extusage;
447
0
  X509_EXTENSION *ex;
448
0
  int i;
449
450
0
  if (x->ex_flags & EXFLAG_SET)
451
0
    return;
452
453
0
  X509_digest(x, X509_CERT_HASH_EVP, x->hash, NULL);
454
455
  /* V1 should mean no extensions ... */
456
0
  if (!X509_get_version(x))
457
0
    x->ex_flags |= EXFLAG_V1;
458
459
  /* Handle basic constraints */
460
0
  if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL))) {
461
0
    if (bs->ca)
462
0
      x->ex_flags |= EXFLAG_CA;
463
0
    if (bs->pathlen) {
464
0
      if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) ||
465
0
          !bs->ca) {
466
0
        x->ex_flags |= EXFLAG_INVALID;
467
0
        x->ex_pathlen = 0;
468
0
      } else
469
0
        x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
470
0
    } else
471
0
      x->ex_pathlen = -1;
472
0
    BASIC_CONSTRAINTS_free(bs);
473
0
    x->ex_flags |= EXFLAG_BCONS;
474
0
  } else if (i != -1) {
475
0
    x->ex_flags |= EXFLAG_INVALID;
476
0
  }
477
478
  /* Handle proxy certificates */
479
0
  if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &i, NULL))) {
480
0
    if (x->ex_flags & EXFLAG_CA ||
481
0
        X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 ||
482
0
        X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
483
0
      x->ex_flags |= EXFLAG_INVALID;
484
0
    }
485
0
    if (pci->pcPathLengthConstraint) {
486
0
      if (pci->pcPathLengthConstraint->type ==
487
0
          V_ASN1_NEG_INTEGER) {
488
0
        x->ex_flags |= EXFLAG_INVALID;
489
0
        x->ex_pcpathlen = 0;
490
0
      } else
491
0
        x->ex_pcpathlen =
492
0
            ASN1_INTEGER_get(pci->
493
0
              pcPathLengthConstraint);
494
0
    } else
495
0
      x->ex_pcpathlen = -1;
496
0
    PROXY_CERT_INFO_EXTENSION_free(pci);
497
0
    x->ex_flags |= EXFLAG_PROXY;
498
0
  } else if (i != -1) {
499
0
    x->ex_flags |= EXFLAG_INVALID;
500
0
  }
501
502
  /* Handle key usage */
503
0
  if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL))) {
504
0
    if (usage->length > 0) {
505
0
      x->ex_kusage = usage->data[0];
506
0
      if (usage->length > 1)
507
0
        x->ex_kusage |= usage->data[1] << 8;
508
0
    } else
509
0
      x->ex_kusage = 0;
510
0
    x->ex_flags |= EXFLAG_KUSAGE;
511
0
    ASN1_BIT_STRING_free(usage);
512
0
  } else if (i != -1) {
513
0
    x->ex_flags |= EXFLAG_INVALID;
514
0
  }
515
516
0
  x->ex_xkusage = 0;
517
0
  if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL))) {
518
0
    x->ex_flags |= EXFLAG_XKUSAGE;
519
0
    for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
520
0
      switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
521
0
      case NID_server_auth:
522
0
        x->ex_xkusage |= XKU_SSL_SERVER;
523
0
        break;
524
525
0
      case NID_client_auth:
526
0
        x->ex_xkusage |= XKU_SSL_CLIENT;
527
0
        break;
528
529
0
      case NID_email_protect:
530
0
        x->ex_xkusage |= XKU_SMIME;
531
0
        break;
532
533
0
      case NID_code_sign:
534
0
        x->ex_xkusage |= XKU_CODE_SIGN;
535
0
        break;
536
537
0
      case NID_ms_sgc:
538
0
      case NID_ns_sgc:
539
0
        x->ex_xkusage |= XKU_SGC;
540
0
        break;
541
542
0
      case NID_OCSP_sign:
543
0
        x->ex_xkusage |= XKU_OCSP_SIGN;
544
0
        break;
545
546
0
      case NID_time_stamp:
547
0
        x->ex_xkusage |= XKU_TIMESTAMP;
548
0
        break;
549
550
0
      case NID_dvcs:
551
0
        x->ex_xkusage |= XKU_DVCS;
552
0
        break;
553
554
0
      case NID_anyExtendedKeyUsage:
555
0
        x->ex_xkusage |= XKU_ANYEKU;
556
0
        break;
557
0
      }
558
0
    }
559
0
    sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
560
0
  } else if (i != -1) {
561
0
    x->ex_flags |= EXFLAG_INVALID;
562
0
  }
563
564
0
  if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &i, NULL))) {
565
0
    if (ns->length > 0)
566
0
      x->ex_nscert = ns->data[0];
567
0
    else
568
0
      x->ex_nscert = 0;
569
0
    x->ex_flags |= EXFLAG_NSCERT;
570
0
    ASN1_BIT_STRING_free(ns);
571
0
  } else if (i != -1) {
572
0
    x->ex_flags |= EXFLAG_INVALID;
573
0
  }
574
575
0
  x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &i, NULL);
576
0
  if (x->skid == NULL && i != -1)
577
0
    x->ex_flags |= EXFLAG_INVALID;
578
0
  x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &i, NULL);
579
0
  if (x->akid == NULL && i != -1)
580
0
    x->ex_flags |= EXFLAG_INVALID;
581
582
  /* Does subject name match issuer? */
583
0
  if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
584
0
    x->ex_flags |= EXFLAG_SI;
585
    /* If SKID matches AKID also indicate self signed. */
586
0
    if (X509_check_akid(x, x->akid) == X509_V_OK &&
587
0
        !ku_reject(x, KU_KEY_CERT_SIGN))
588
0
      x->ex_flags |= EXFLAG_SS;
589
0
  }
590
591
0
  x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &i, NULL);
592
0
  if (x->altname == NULL && i != -1)
593
0
    x->ex_flags |= EXFLAG_INVALID;
594
0
  x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
595
0
  if (!x->nc && (i != -1))
596
0
    x->ex_flags |= EXFLAG_INVALID;
597
0
  setup_crldp(x);
598
599
0
#ifndef OPENSSL_NO_RFC3779
600
0
  x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL);
601
0
  if (x->rfc3779_addr == NULL && i != -1)
602
0
    x->ex_flags |= EXFLAG_INVALID;
603
0
  if (!X509v3_addr_is_canonical(x->rfc3779_addr))
604
0
    x->ex_flags |= EXFLAG_INVALID;
605
0
  x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, &i, NULL);
606
0
  if (x->rfc3779_asid == NULL && i != -1)
607
0
    x->ex_flags |= EXFLAG_INVALID;
608
0
  if (!X509v3_asid_is_canonical(x->rfc3779_asid))
609
0
    x->ex_flags |= EXFLAG_INVALID;
610
0
#endif
611
612
0
  for (i = 0; i < X509_get_ext_count(x); i++) {
613
0
    ex = X509_get_ext(x, i);
614
0
    if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) ==
615
0
        NID_freshest_crl)
616
0
      x->ex_flags |= EXFLAG_FRESHEST;
617
0
    if (!X509_EXTENSION_get_critical(ex))
618
0
      continue;
619
0
    if (!X509_supported_extension(ex)) {
620
0
      x->ex_flags |= EXFLAG_CRITICAL;
621
0
      break;
622
0
    }
623
0
  }
624
625
0
  x509_verify_cert_info_populate(x);
626
627
0
  x->ex_flags |= EXFLAG_SET;
628
0
}
629
630
/* CA checks common to all purposes
631
 * return codes:
632
 * 0 not a CA
633
 * 1 is a CA
634
 * 2 basicConstraints absent so "maybe" a CA
635
 * 3 basicConstraints absent but self signed V1.
636
 * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
637
 */
638
639
static int
640
check_ca(const X509 *x)
641
0
{
642
  /* keyUsage if present should allow cert signing */
643
0
  if (ku_reject(x, KU_KEY_CERT_SIGN))
644
0
    return 0;
645
0
  if (x->ex_flags & EXFLAG_BCONS) {
646
0
    if (x->ex_flags & EXFLAG_CA)
647
0
      return 1;
648
    /* If basicConstraints says not a CA then say so */
649
0
    else
650
0
      return 0;
651
0
  } else {
652
    /* we support V1 roots for...  uh, I don't really know why. */
653
0
    if ((x->ex_flags & V1_ROOT) == V1_ROOT)
654
0
      return 3;
655
    /* If key usage present it must have certSign so tolerate it */
656
0
    else if (x->ex_flags & EXFLAG_KUSAGE)
657
0
      return 4;
658
    /* Older certificates could have Netscape-specific CA types */
659
0
    else if (x->ex_flags & EXFLAG_NSCERT &&
660
0
        x->ex_nscert & NS_ANY_CA)
661
0
      return 5;
662
    /* can this still be regarded a CA certificate?  I doubt it */
663
0
    return 0;
664
0
  }
665
0
}
666
667
int
668
X509_check_ca(X509 *x)
669
0
{
670
0
  if (!(x->ex_flags & EXFLAG_SET)) {
671
0
    CRYPTO_w_lock(CRYPTO_LOCK_X509);
672
0
    x509v3_cache_extensions(x);
673
0
    CRYPTO_w_unlock(CRYPTO_LOCK_X509);
674
0
  }
675
676
0
  return check_ca(x);
677
0
}
678
679
/* Check SSL CA: common checks for SSL client and server */
680
static int
681
check_ssl_ca(const X509 *x)
682
0
{
683
0
  int ca_ret;
684
685
0
  ca_ret = check_ca(x);
686
0
  if (!ca_ret)
687
0
    return 0;
688
  /* check nsCertType if present */
689
0
  if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA)
690
0
    return ca_ret;
691
0
  else
692
0
    return 0;
693
0
}
694
695
static int
696
check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
697
0
{
698
0
  if (xku_reject(x, XKU_SSL_CLIENT))
699
0
    return 0;
700
0
  if (ca)
701
0
    return check_ssl_ca(x);
702
  /* We need to do digital signatures with it */
703
0
  if (ku_reject(x, KU_DIGITAL_SIGNATURE))
704
0
    return 0;
705
  /* nsCertType if present should allow SSL client use */
706
0
  if (ns_reject(x, NS_SSL_CLIENT))
707
0
    return 0;
708
0
  return 1;
709
0
}
710
711
static int
712
check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
713
0
{
714
0
  if (xku_reject(x, XKU_SSL_SERVER|XKU_SGC))
715
0
    return 0;
716
0
  if (ca)
717
0
    return check_ssl_ca(x);
718
719
0
  if (ns_reject(x, NS_SSL_SERVER))
720
0
    return 0;
721
  /* Now as for keyUsage: we'll at least need to sign OR encipher */
722
0
  if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT))
723
0
    return 0;
724
725
0
  return 1;
726
0
}
727
728
static int
729
check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
730
0
{
731
0
  int ret;
732
733
0
  ret = check_purpose_ssl_server(xp, x, ca);
734
0
  if (!ret || ca)
735
0
    return ret;
736
  /* We need to encipher or Netscape complains */
737
0
  if (ku_reject(x, KU_KEY_ENCIPHERMENT))
738
0
    return 0;
739
0
  return ret;
740
0
}
741
742
/* common S/MIME checks */
743
static int
744
purpose_smime(const X509 *x, int ca)
745
0
{
746
0
  if (xku_reject(x, XKU_SMIME))
747
0
    return 0;
748
0
  if (ca) {
749
0
    int ca_ret;
750
0
    ca_ret = check_ca(x);
751
0
    if (!ca_ret)
752
0
      return 0;
753
    /* check nsCertType if present */
754
0
    if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA)
755
0
      return ca_ret;
756
0
    else
757
0
      return 0;
758
0
  }
759
0
  if (x->ex_flags & EXFLAG_NSCERT) {
760
0
    if (x->ex_nscert & NS_SMIME)
761
0
      return 1;
762
    /* Workaround for some buggy certificates */
763
0
    if (x->ex_nscert & NS_SSL_CLIENT)
764
0
      return 2;
765
0
    return 0;
766
0
  }
767
0
  return 1;
768
0
}
769
770
static int
771
check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
772
0
{
773
0
  int ret;
774
775
0
  ret = purpose_smime(x, ca);
776
0
  if (!ret || ca)
777
0
    return ret;
778
0
  if (ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION))
779
0
    return 0;
780
0
  return ret;
781
0
}
782
783
static int
784
check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
785
0
{
786
0
  int ret;
787
788
0
  ret = purpose_smime(x, ca);
789
0
  if (!ret || ca)
790
0
    return ret;
791
0
  if (ku_reject(x, KU_KEY_ENCIPHERMENT))
792
0
    return 0;
793
0
  return ret;
794
0
}
795
796
static int
797
check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
798
0
{
799
0
  if (ca) {
800
0
    int ca_ret;
801
0
    if ((ca_ret = check_ca(x)) != 2)
802
0
      return ca_ret;
803
0
    else
804
0
      return 0;
805
0
  }
806
0
  if (ku_reject(x, KU_CRL_SIGN))
807
0
    return 0;
808
0
  return 1;
809
0
}
810
811
/* OCSP helper: this is *not* a full OCSP check. It just checks that
812
 * each CA is valid. Additional checks must be made on the chain.
813
 */
814
static int
815
ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
816
0
{
817
  /* Must be a valid CA.  Should we really support the "I don't know"
818
     value (2)? */
819
0
  if (ca)
820
0
    return check_ca(x);
821
  /* leaf certificate is checked in OCSP_verify() */
822
0
  return 1;
823
0
}
824
825
static int
826
check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
827
0
{
828
0
  int i_ext;
829
830
  /* If ca is true we must return if this is a valid CA certificate. */
831
0
  if (ca)
832
0
    return check_ca(x);
833
834
  /*
835
   * Check the optional key usage field:
836
   * if Key Usage is present, it must be one of digitalSignature
837
   * and/or nonRepudiation (other values are not consistent and shall
838
   * be rejected).
839
   */
840
0
  if ((x->ex_flags & EXFLAG_KUSAGE) &&
841
0
      ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
842
0
      !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
843
0
    return 0;
844
845
  /* Only time stamp key usage is permitted and it's required. */
846
0
  if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
847
0
    return 0;
848
849
  /* Extended Key Usage MUST be critical */
850
0
  i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
851
0
  if (i_ext >= 0) {
852
0
    X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);
853
0
    if (!X509_EXTENSION_get_critical(ext))
854
0
      return 0;
855
0
  }
856
857
0
  return 1;
858
0
}
859
860
static int
861
no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
862
0
{
863
0
  return 1;
864
0
}
865
866
/* Various checks to see if one certificate issued the second.
867
 * This can be used to prune a set of possible issuer certificates
868
 * which have been looked up using some simple method such as by
869
 * subject name.
870
 * These are:
871
 * 1. Check issuer_name(subject) == subject_name(issuer)
872
 * 2. If akid(subject) exists check it matches issuer
873
 * 3. If key_usage(issuer) exists check it supports certificate signing
874
 * returns 0 for OK, positive for reason for mismatch, reasons match
875
 * codes for X509_verify_cert()
876
 */
877
878
int
879
X509_check_issued(X509 *issuer, X509 *subject)
880
0
{
881
0
  if (X509_NAME_cmp(X509_get_subject_name(issuer),
882
0
      X509_get_issuer_name(subject)))
883
0
    return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
884
0
  if (!(issuer->ex_flags & EXFLAG_SET)) {
885
0
    CRYPTO_w_lock(CRYPTO_LOCK_X509);
886
0
    x509v3_cache_extensions(issuer);
887
0
    CRYPTO_w_unlock(CRYPTO_LOCK_X509);
888
0
  }
889
0
  if (issuer->ex_flags & EXFLAG_INVALID)
890
0
    return X509_V_ERR_UNSPECIFIED;
891
0
  if (!(subject->ex_flags & EXFLAG_SET)) {
892
0
    CRYPTO_w_lock(CRYPTO_LOCK_X509);
893
0
    x509v3_cache_extensions(subject);
894
0
    CRYPTO_w_unlock(CRYPTO_LOCK_X509);
895
0
  }
896
0
  if (subject->ex_flags & EXFLAG_INVALID)
897
0
    return X509_V_ERR_UNSPECIFIED;
898
899
0
  if (subject->akid) {
900
0
    int ret = X509_check_akid(issuer, subject->akid);
901
0
    if (ret != X509_V_OK)
902
0
      return ret;
903
0
  }
904
905
0
  if (subject->ex_flags & EXFLAG_PROXY) {
906
0
    if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
907
0
      return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
908
0
  } else if (ku_reject(issuer, KU_KEY_CERT_SIGN))
909
0
    return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
910
0
  return X509_V_OK;
911
0
}
912
913
int
914
X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
915
0
{
916
0
  if (!akid)
917
0
    return X509_V_OK;
918
919
  /* Check key ids (if present) */
920
0
  if (akid->keyid && issuer->skid &&
921
0
      ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid) )
922
0
    return X509_V_ERR_AKID_SKID_MISMATCH;
923
  /* Check serial number */
924
0
  if (akid->serial &&
925
0
      ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
926
0
    return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
927
  /* Check issuer name */
928
0
  if (akid->issuer) {
929
    /* Ugh, for some peculiar reason AKID includes
930
     * SEQUENCE OF GeneralName. So look for a DirName.
931
     * There may be more than one but we only take any
932
     * notice of the first.
933
     */
934
0
    GENERAL_NAMES *gens;
935
0
    GENERAL_NAME *gen;
936
0
    X509_NAME *nm = NULL;
937
0
    int i;
938
0
    gens = akid->issuer;
939
0
    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
940
0
      gen = sk_GENERAL_NAME_value(gens, i);
941
0
      if (gen->type == GEN_DIRNAME) {
942
0
        nm = gen->d.dirn;
943
0
        break;
944
0
      }
945
0
    }
946
0
    if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
947
0
      return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
948
0
  }
949
0
  return X509_V_OK;
950
0
}
951
952
uint32_t
953
X509_get_extension_flags(X509 *x)
954
0
{
955
  /* Call for side-effect of computing hash and caching extensions */
956
0
  if (X509_check_purpose(x, -1, -1) != 1)
957
0
    return EXFLAG_INVALID;
958
959
0
  return x->ex_flags;
960
0
}
961
962
uint32_t
963
X509_get_key_usage(X509 *x)
964
0
{
965
  /* Call for side-effect of computing hash and caching extensions */
966
0
  if (X509_check_purpose(x, -1, -1) != 1)
967
0
    return 0;
968
969
0
  if (x->ex_flags & EXFLAG_KUSAGE)
970
0
    return x->ex_kusage;
971
972
0
  return UINT32_MAX;
973
0
}
974
975
uint32_t
976
X509_get_extended_key_usage(X509 *x)
977
0
{
978
  /* Call for side-effect of computing hash and caching extensions */
979
0
  if (X509_check_purpose(x, -1, -1) != 1)
980
0
    return 0;
981
982
0
  if (x->ex_flags & EXFLAG_XKUSAGE)
983
0
    return x->ex_xkusage;
984
985
0
  return UINT32_MAX;
986
0
}