Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/x509/x509_ext.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2014-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2016 Red Hat, Inc.
4
 *
5
 * This file is part of GnuTLS.
6
 *
7
 * The GnuTLS is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public License
9
 * as published by the Free Software Foundation; either version 2.1 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
19
 *
20
 */
21
22
/* This file contains functions to handle X.509 certificate extensions (the x509-ext API)
23
 */
24
25
#include "gnutls_int.h"
26
#include <datum.h>
27
#include "errors.h"
28
#include <common.h>
29
#include <x509.h>
30
#include <x509_b64.h>
31
#include "x509_ext_int.h"
32
#include "virt-san.h"
33
#include <gnutls/x509-ext.h>
34
#include "intprops.h"
35
36
0
#define MAX_ENTRIES 64
37
struct gnutls_subject_alt_names_st {
38
  struct name_st *names;
39
  unsigned int size;
40
};
41
42
/**
43
 * gnutls_subject_alt_names_init:
44
 * @sans: The alternative names
45
 *
46
 * This function will initialize an alternative names structure.
47
 *
48
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
49
 *
50
 * Since: 3.3.0
51
 **/
52
int gnutls_subject_alt_names_init(gnutls_subject_alt_names_t * sans)
53
0
{
54
0
  *sans = gnutls_calloc(1, sizeof(struct gnutls_subject_alt_names_st));
55
0
  if (*sans == NULL) {
56
0
    gnutls_assert();
57
0
    return GNUTLS_E_MEMORY_ERROR;
58
0
  }
59
60
0
  return 0;
61
0
}
62
63
static void subject_alt_names_deinit(gnutls_subject_alt_names_t sans)
64
0
{
65
0
  unsigned int i;
66
67
0
  for (i = 0; i < sans->size; i++) {
68
0
    gnutls_free(sans->names[i].san.data);
69
0
    gnutls_free(sans->names[i].othername_oid.data);
70
0
  }
71
0
  gnutls_free(sans->names);
72
0
}
73
74
/**
75
 * gnutls_subject_alt_names_deinit:
76
 * @sans: The alternative names
77
 *
78
 * This function will deinitialize an alternative names structure.
79
 *
80
 * Since: 3.3.0
81
 **/
82
void gnutls_subject_alt_names_deinit(gnutls_subject_alt_names_t sans)
83
0
{
84
0
  subject_alt_names_deinit(sans);
85
0
  gnutls_free(sans);
86
0
}
87
88
/**
89
 * gnutls_subject_alt_names_get:
90
 * @sans: The alternative names
91
 * @seq: The index of the name to get
92
 * @san_type: Will hold the type of the name (of %gnutls_subject_alt_names_t)
93
 * @san: The alternative name data (should be treated as constant)
94
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME (should be treated as constant)
95
 *
96
 * This function will return a specific alternative name as stored in
97
 * the @sans type. The returned values should be treated as constant
98
 * and valid for the lifetime of @sans.
99
 *
100
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
101
 * if the index is out of bounds, otherwise a negative error value.
102
 *
103
 * Since: 3.3.0
104
 **/
105
int gnutls_subject_alt_names_get(gnutls_subject_alt_names_t sans,
106
         unsigned int seq, unsigned int *san_type,
107
         gnutls_datum_t * san,
108
         gnutls_datum_t * othername_oid)
109
0
{
110
0
  if (seq >= sans->size)
111
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
112
113
0
  if (san) {
114
0
    memcpy(san, &sans->names[seq].san, sizeof(gnutls_datum_t));
115
0
  }
116
117
0
  if (san_type)
118
0
    *san_type = sans->names[seq].type;
119
120
0
  if (othername_oid != NULL
121
0
      && sans->names[seq].type == GNUTLS_SAN_OTHERNAME) {
122
0
    othername_oid->data = sans->names[seq].othername_oid.data;
123
0
    othername_oid->size = sans->names[seq].othername_oid.size;
124
0
  }
125
126
0
  return 0;
127
0
}
128
129
/* This is the same as gnutls_subject_alt_names_set() but will not
130
 * copy the strings. It expects all the provided input to be already
131
 * allocated by gnutls. */
132
static
133
int subject_alt_names_set(struct name_st **names,
134
        unsigned int *size,
135
        unsigned int san_type,
136
        gnutls_datum_t * san, char *othername_oid,
137
        unsigned raw)
138
0
{
139
0
  void *tmp;
140
0
  int ret;
141
142
0
  if (unlikely(INT_ADD_OVERFLOW(*size, 1))) {
143
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
144
0
  }
145
146
0
  tmp = _gnutls_reallocarray(*names, *size + 1, sizeof((*names)[0]));
147
0
  if (tmp == NULL) {
148
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
149
0
  }
150
0
  *names = tmp;
151
152
0
  ret =
153
0
      _gnutls_alt_name_assign_virt_type(&(*names)[*size], san_type, san,
154
0
                othername_oid, raw);
155
0
  if (ret < 0)
156
0
    return gnutls_assert_val(ret);
157
158
0
  (*size)++;
159
0
  return 0;
160
0
}
161
162
/**
163
 * gnutls_subject_alt_names_set:
164
 * @sans: The alternative names
165
 * @san_type: The type of the name (of %gnutls_subject_alt_names_t)
166
 * @san: The alternative name data
167
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
168
 *
169
 * This function will store the specified alternative name in
170
 * the @sans.
171
 *
172
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
173
 * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
174
 *
175
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
176
 *
177
 * Since: 3.3.0
178
 **/
179
int gnutls_subject_alt_names_set(gnutls_subject_alt_names_t sans,
180
         unsigned int san_type,
181
         const gnutls_datum_t * san,
182
         const char *othername_oid)
183
0
{
184
0
  int ret;
185
0
  gnutls_datum_t copy;
186
0
  char *ooc;
187
188
0
  ret = _gnutls_set_strdatum(&copy, san->data, san->size);
189
0
  if (ret < 0)
190
0
    return gnutls_assert_val(ret);
191
192
0
  if (othername_oid != NULL)
193
0
    ooc = gnutls_strdup(othername_oid);
194
0
  else
195
0
    ooc = NULL;
196
0
  ret = subject_alt_names_set(&sans->names, &sans->size,
197
0
            san_type, &copy, ooc, 0);
198
0
  if (ret < 0) {
199
0
    gnutls_free(copy.data);
200
0
    return gnutls_assert_val(ret);
201
0
  }
202
203
0
  return 0;
204
0
}
205
206
/**
207
 * gnutls_x509_ext_import_subject_alt_names:
208
 * @ext: The DER-encoded extension data
209
 * @sans: The alternative names
210
 * @flags: should be zero
211
 *
212
 * This function will export the alternative names in the provided DER-encoded
213
 * SubjectAltName PKIX extension, to a %gnutls_subject_alt_names_t type. @sans
214
 * must be initialized.
215
 *
216
 * This function will succeed even if there no subject alternative names
217
 * in the structure.
218
 *
219
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
220
 *
221
 * Since: 3.3.0
222
 **/
223
int gnutls_x509_ext_import_subject_alt_names(const gnutls_datum_t * ext,
224
               gnutls_subject_alt_names_t sans,
225
               unsigned int flags)
226
0
{
227
0
  asn1_node c2 = NULL;
228
0
  int result, ret;
229
0
  unsigned int i;
230
0
  gnutls_datum_t san, othername_oid;
231
0
  unsigned type;
232
233
0
  result =
234
0
      asn1_create_element(_gnutls_get_pkix(), "PKIX1.GeneralNames", &c2);
235
0
  if (result != ASN1_SUCCESS) {
236
0
    gnutls_assert();
237
0
    return _gnutls_asn2err(result);
238
0
  }
239
240
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
241
0
  if (result != ASN1_SUCCESS) {
242
0
    gnutls_assert();
243
0
    ret = _gnutls_asn2err(result);
244
0
    goto cleanup;
245
0
  }
246
247
0
  for (i = 0;; i++) {
248
0
    san.data = NULL;
249
0
    san.size = 0;
250
0
    othername_oid.data = NULL;
251
252
0
    ret = _gnutls_parse_general_name2(c2, "", i, &san, &type, 0);
253
0
    if (ret < 0)
254
0
      break;
255
256
0
    if (type == GNUTLS_SAN_OTHERNAME) {
257
0
      ret =
258
0
          _gnutls_parse_general_name2(c2, "", i,
259
0
              &othername_oid,
260
0
              NULL, 1);
261
0
      if (ret < 0)
262
0
        break;
263
264
0
    } else if (san.size == 0 || san.data == NULL) {
265
0
      ret = gnutls_assert_val(GNUTLS_E_X509_UNKNOWN_SAN);
266
0
      break;
267
0
    }
268
269
0
    ret = subject_alt_names_set(&sans->names, &sans->size,
270
0
              type, &san,
271
0
              (char *)othername_oid.data, 1);
272
0
    if (ret < 0)
273
0
      break;
274
0
  }
275
276
0
  sans->size = i;
277
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
278
0
    gnutls_free(san.data);
279
0
    gnutls_free(othername_oid.data);
280
0
    gnutls_assert();
281
0
    goto cleanup;
282
0
  }
283
284
0
  ret = 0;
285
0
 cleanup:
286
0
  asn1_delete_structure(&c2);
287
0
  return ret;
288
0
}
289
290
/**
291
 * gnutls_x509_ext_export_subject_alt_names:
292
 * @sans: The alternative names
293
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
294
 *
295
 * This function will convert the provided alternative names structure to a
296
 * DER-encoded SubjectAltName PKIX extension. The output data in @ext will be allocated using
297
 * gnutls_malloc().
298
 *
299
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
300
 *
301
 * Since: 3.3.0
302
 **/
303
int gnutls_x509_ext_export_subject_alt_names(gnutls_subject_alt_names_t sans,
304
               gnutls_datum_t * ext)
305
0
{
306
0
  asn1_node c2 = NULL;
307
0
  int result, ret;
308
0
  unsigned i;
309
310
0
  result =
311
0
      asn1_create_element(_gnutls_get_pkix(), "PKIX1.GeneralNames", &c2);
312
0
  if (result != ASN1_SUCCESS) {
313
0
    gnutls_assert();
314
0
    return _gnutls_asn2err(result);
315
0
  }
316
317
0
  for (i = 0; i < sans->size; i++) {
318
0
    if (sans->names[i].type == GNUTLS_SAN_OTHERNAME) {
319
0
      ret =
320
0
          _gnutls_write_new_othername(c2, "",
321
0
              (char *)sans->
322
0
              names[i].othername_oid.
323
0
              data,
324
0
              sans->names[i].san.data,
325
0
              sans->names[i].
326
0
              san.size);
327
0
    } else {
328
0
      ret =
329
0
          _gnutls_write_new_general_name(c2, "",
330
0
                 sans->names[i].type,
331
0
                 sans->names[i].
332
0
                 san.data,
333
0
                 sans->names[i].
334
0
                 san.size);
335
0
    }
336
337
0
    if (ret < 0) {
338
0
      gnutls_assert();
339
0
      goto cleanup;
340
0
    }
341
0
  }
342
343
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
344
0
  if (ret < 0) {
345
0
    gnutls_assert();
346
0
    goto cleanup;
347
0
  }
348
349
0
  ret = 0;
350
351
0
 cleanup:
352
0
  asn1_delete_structure(&c2);
353
0
  return ret;
354
0
}
355
356
/**
357
 * gnutls_x509_ext_import_name_constraints:
358
 * @ext: a DER encoded extension
359
 * @nc: The nameconstraints
360
 * @flags: zero or %GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND
361
 *
362
 * This function will return an intermediate type containing
363
 * the name constraints of the provided NameConstraints extension. That
364
 * can be used in combination with gnutls_x509_name_constraints_check()
365
 * to verify whether a server's name is in accordance with the constraints.
366
 *
367
 * When the @flags is set to %GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND, then if 
368
 * the @nc type is empty this function will behave identically as if the flag was not set.
369
 * Otherwise if there are elements in the @nc structure then the
370
 * constraints will be merged with the existing constraints following
371
 * RFC5280 p6.1.4 (excluded constraints will be appended, permitted
372
 * will be intersected).
373
 *
374
 * Note that @nc must be initialized prior to calling this function.
375
 *
376
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
377
 * if the extension is not present, otherwise a negative error value.
378
 *
379
 * Since: 3.3.0
380
 **/
381
int gnutls_x509_ext_import_name_constraints(const gnutls_datum_t * ext,
382
              gnutls_x509_name_constraints_t nc,
383
              unsigned int flags)
384
0
{
385
0
  int result, ret;
386
0
  asn1_node c2 = NULL;
387
0
  gnutls_x509_name_constraints_t nc2 = NULL;
388
389
0
  result = asn1_create_element
390
0
      (_gnutls_get_pkix(), "PKIX1.NameConstraints", &c2);
391
0
  if (result != ASN1_SUCCESS) {
392
0
    gnutls_assert();
393
0
    return _gnutls_asn2err(result);
394
0
  }
395
396
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
397
0
  if (result != ASN1_SUCCESS) {
398
0
    gnutls_assert();
399
0
    ret = _gnutls_asn2err(result);
400
0
    goto cleanup;
401
0
  }
402
403
0
  if (flags & GNUTLS_NAME_CONSTRAINTS_FLAG_APPEND &&
404
0
      (nc->permitted != NULL || nc->excluded != NULL)) {
405
0
    ret = gnutls_x509_name_constraints_init(&nc2);
406
0
    if (ret < 0) {
407
0
      gnutls_assert();
408
0
      goto cleanup;
409
0
    }
410
411
0
    ret =
412
0
        _gnutls_extract_name_constraints(c2, "permittedSubtrees",
413
0
                 &nc2->permitted);
414
0
    if (ret < 0) {
415
0
      gnutls_assert();
416
0
      goto cleanup;
417
0
    }
418
419
0
    ret =
420
0
        _gnutls_extract_name_constraints(c2, "excludedSubtrees",
421
0
                 &nc2->excluded);
422
0
    if (ret < 0) {
423
0
      gnutls_assert();
424
0
      goto cleanup;
425
0
    }
426
427
0
    ret = _gnutls_x509_name_constraints_merge(nc, nc2);
428
0
    if (ret < 0) {
429
0
      gnutls_assert();
430
0
      goto cleanup;
431
0
    }
432
0
  } else {
433
0
    _gnutls_name_constraints_node_free(nc->permitted);
434
0
    _gnutls_name_constraints_node_free(nc->excluded);
435
436
0
    ret =
437
0
        _gnutls_extract_name_constraints(c2, "permittedSubtrees",
438
0
                 &nc->permitted);
439
0
    if (ret < 0) {
440
0
      gnutls_assert();
441
0
      goto cleanup;
442
0
    }
443
444
0
    ret =
445
0
        _gnutls_extract_name_constraints(c2, "excludedSubtrees",
446
0
                 &nc->excluded);
447
0
    if (ret < 0) {
448
0
      gnutls_assert();
449
0
      goto cleanup;
450
0
    }
451
0
  }
452
453
0
  ret = 0;
454
455
0
 cleanup:
456
0
  asn1_delete_structure(&c2);
457
0
  if (nc2)
458
0
    gnutls_x509_name_constraints_deinit(nc2);
459
460
0
  return ret;
461
0
}
462
463
/**
464
 * gnutls_x509_ext_export_name_constraints:
465
 * @nc: The nameconstraints
466
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
467
 *
468
 * This function will convert the provided name constraints type to a
469
 * DER-encoded PKIX NameConstraints (2.5.29.30) extension. The output data in 
470
 * @ext will be allocated using gnutls_malloc().
471
 *
472
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
473
 *
474
 * Since: 3.3.0
475
 **/
476
int gnutls_x509_ext_export_name_constraints(gnutls_x509_name_constraints_t nc,
477
              gnutls_datum_t * ext)
478
0
{
479
0
  int ret, result;
480
0
  uint8_t null = 0;
481
0
  asn1_node c2 = NULL;
482
0
  struct name_constraints_node_st *tmp;
483
484
0
  if (nc->permitted == NULL && nc->excluded == NULL)
485
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
486
487
0
  result = asn1_create_element
488
0
      (_gnutls_get_pkix(), "PKIX1.NameConstraints", &c2);
489
0
  if (result != ASN1_SUCCESS) {
490
0
    gnutls_assert();
491
0
    return _gnutls_asn2err(result);
492
0
  }
493
494
0
  if (nc->permitted == NULL) {
495
0
    (void)asn1_write_value(c2, "permittedSubtrees", NULL, 0);
496
0
  } else {
497
0
    tmp = nc->permitted;
498
0
    do {
499
0
      result =
500
0
          asn1_write_value(c2, "permittedSubtrees", "NEW", 1);
501
0
      if (result != ASN1_SUCCESS) {
502
0
        gnutls_assert();
503
0
        ret = _gnutls_asn2err(result);
504
0
        goto cleanup;
505
0
      }
506
507
0
      result =
508
0
          asn1_write_value(c2,
509
0
               "permittedSubtrees.?LAST.maximum",
510
0
               NULL, 0);
511
0
      if (result != ASN1_SUCCESS) {
512
0
        gnutls_assert();
513
0
        ret = _gnutls_asn2err(result);
514
0
        goto cleanup;
515
0
      }
516
517
0
      result =
518
0
          asn1_write_value(c2,
519
0
               "permittedSubtrees.?LAST.minimum",
520
0
               &null, 1);
521
0
      if (result != ASN1_SUCCESS) {
522
0
        gnutls_assert();
523
0
        ret = _gnutls_asn2err(result);
524
0
        goto cleanup;
525
0
      }
526
527
0
      ret =
528
0
          _gnutls_write_general_name(c2,
529
0
                   "permittedSubtrees.?LAST.base",
530
0
                   tmp->type,
531
0
                   tmp->name.data,
532
0
                   tmp->name.size);
533
0
      if (ret < 0) {
534
0
        gnutls_assert();
535
0
        goto cleanup;
536
0
      }
537
0
      tmp = tmp->next;
538
0
    } while (tmp != NULL);
539
0
  }
540
541
0
  if (nc->excluded == NULL) {
542
0
    (void)asn1_write_value(c2, "excludedSubtrees", NULL, 0);
543
0
  } else {
544
0
    tmp = nc->excluded;
545
0
    do {
546
0
      result =
547
0
          asn1_write_value(c2, "excludedSubtrees", "NEW", 1);
548
0
      if (result != ASN1_SUCCESS) {
549
0
        gnutls_assert();
550
0
        ret = _gnutls_asn2err(result);
551
0
        goto cleanup;
552
0
      }
553
554
0
      result =
555
0
          asn1_write_value(c2,
556
0
               "excludedSubtrees.?LAST.maximum",
557
0
               NULL, 0);
558
0
      if (result != ASN1_SUCCESS) {
559
0
        gnutls_assert();
560
0
        ret = _gnutls_asn2err(result);
561
0
        goto cleanup;
562
0
      }
563
564
0
      result =
565
0
          asn1_write_value(c2,
566
0
               "excludedSubtrees.?LAST.minimum",
567
0
               &null, 1);
568
0
      if (result != ASN1_SUCCESS) {
569
0
        gnutls_assert();
570
0
        ret = _gnutls_asn2err(result);
571
0
        goto cleanup;
572
0
      }
573
574
0
      ret =
575
0
          _gnutls_write_general_name(c2,
576
0
                   "excludedSubtrees.?LAST.base",
577
0
                   tmp->type,
578
0
                   tmp->name.data,
579
0
                   tmp->name.size);
580
0
      if (ret < 0) {
581
0
        gnutls_assert();
582
0
        goto cleanup;
583
0
      }
584
0
      tmp = tmp->next;
585
0
    } while (tmp != NULL);
586
587
0
  }
588
589
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
590
0
  if (ret < 0) {
591
0
    gnutls_assert();
592
0
    goto cleanup;
593
0
  }
594
595
0
  ret = 0;
596
597
0
 cleanup:
598
0
  asn1_delete_structure(&c2);
599
0
  return ret;
600
0
}
601
602
/**
603
 * gnutls_x509_ext_import_subject_key_id:
604
 * @ext: a DER encoded extension
605
 * @id: will contain the subject key ID
606
 *
607
 * This function will return the subject key ID stored in the provided
608
 * SubjectKeyIdentifier extension. The ID will be allocated using
609
 * gnutls_malloc().
610
 *
611
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
612
 * if the extension is not present, otherwise a negative error value.
613
 *
614
 * Since: 3.3.0
615
 **/
616
int gnutls_x509_ext_import_subject_key_id(const gnutls_datum_t * ext,
617
            gnutls_datum_t * id)
618
0
{
619
0
  int result, ret;
620
0
  asn1_node c2 = NULL;
621
622
0
  if (ext->size == 0 || ext->data == NULL) {
623
0
    gnutls_assert();
624
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
625
0
  }
626
627
0
  result = asn1_create_element
628
0
      (_gnutls_get_pkix(), "PKIX1.SubjectKeyIdentifier", &c2);
629
0
  if (result != ASN1_SUCCESS) {
630
0
    gnutls_assert();
631
0
    return _gnutls_asn2err(result);
632
0
  }
633
634
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
635
0
  if (result != ASN1_SUCCESS) {
636
0
    gnutls_assert();
637
0
    ret = _gnutls_asn2err(result);
638
0
    goto cleanup;
639
0
  }
640
641
0
  ret = _gnutls_x509_read_value(c2, "", id);
642
0
  if (ret < 0) {
643
0
    gnutls_assert();
644
0
    goto cleanup;
645
0
  }
646
647
0
  ret = 0;
648
0
 cleanup:
649
0
  asn1_delete_structure(&c2);
650
651
0
  return ret;
652
653
0
}
654
655
/**
656
 * gnutls_x509_ext_export_subject_key_id:
657
 * @id: The key identifier
658
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
659
 *
660
 * This function will convert the provided key identifier to a
661
 * DER-encoded PKIX SubjectKeyIdentifier extension. 
662
 * The output data in @ext will be allocated using
663
 * gnutls_malloc().
664
 *
665
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
666
 *
667
 * Since: 3.3.0
668
 **/
669
int gnutls_x509_ext_export_subject_key_id(const gnutls_datum_t * id,
670
            gnutls_datum_t * ext)
671
0
{
672
0
  asn1_node c2 = NULL;
673
0
  int ret, result;
674
675
0
  result =
676
0
      asn1_create_element(_gnutls_get_pkix(),
677
0
        "PKIX1.SubjectKeyIdentifier", &c2);
678
0
  if (result != ASN1_SUCCESS) {
679
0
    gnutls_assert();
680
0
    return _gnutls_asn2err(result);
681
0
  }
682
683
0
  result = asn1_write_value(c2, "", id->data, id->size);
684
0
  if (result != ASN1_SUCCESS) {
685
0
    gnutls_assert();
686
0
    ret = _gnutls_asn2err(result);
687
0
    goto cleanup;
688
0
  }
689
690
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
691
0
  if (ret < 0) {
692
0
    gnutls_assert();
693
0
    goto cleanup;
694
0
  }
695
696
0
  ret = 0;
697
0
 cleanup:
698
0
  asn1_delete_structure(&c2);
699
0
  return ret;
700
0
}
701
702
struct gnutls_x509_aki_st {
703
  gnutls_datum_t id;
704
  struct gnutls_subject_alt_names_st cert_issuer;
705
  gnutls_datum_t serial;
706
};
707
708
/**
709
 * gnutls_x509_aki_init:
710
 * @aki: The authority key ID type
711
 *
712
 * This function will initialize an authority key ID.
713
 *
714
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
715
 *
716
 * Since: 3.3.0
717
 **/
718
int gnutls_x509_aki_init(gnutls_x509_aki_t * aki)
719
0
{
720
0
  *aki = gnutls_calloc(1, sizeof(struct gnutls_x509_aki_st));
721
0
  if (*aki == NULL)
722
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
723
724
0
  return 0;
725
0
}
726
727
/**
728
 * gnutls_x509_aki_deinit:
729
 * @aki: The authority key identifier type
730
 *
731
 * This function will deinitialize an authority key identifier.
732
 *
733
 * Since: 3.3.0
734
 **/
735
void gnutls_x509_aki_deinit(gnutls_x509_aki_t aki)
736
0
{
737
0
  gnutls_free(aki->serial.data);
738
0
  gnutls_free(aki->id.data);
739
0
  subject_alt_names_deinit(&aki->cert_issuer);
740
0
  gnutls_free(aki);
741
0
}
742
743
/**
744
 * gnutls_x509_aki_get_id:
745
 * @aki: The authority key ID
746
 * @id: Will hold the identifier
747
 *
748
 * This function will return the key identifier as stored in
749
 * the @aki type. The identifier should be treated as constant.
750
 *
751
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
752
 * if the index is out of bounds, otherwise a negative error value.
753
 *
754
 * Since: 3.3.0
755
 **/
756
int gnutls_x509_aki_get_id(gnutls_x509_aki_t aki, gnutls_datum_t * id)
757
0
{
758
0
  if (aki->id.size == 0)
759
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
760
761
0
  memcpy(id, &aki->id, sizeof(gnutls_datum_t));
762
0
  return 0;
763
0
}
764
765
/**
766
 * gnutls_x509_aki_set_id:
767
 * @aki: The authority key ID
768
 * @id: the key identifier
769
 *
770
 * This function will set the keyIdentifier to be stored in the @aki
771
 * type.
772
 *
773
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
774
 *
775
 * Since: 3.3.0
776
 **/
777
int gnutls_x509_aki_set_id(gnutls_x509_aki_t aki, const gnutls_datum_t * id)
778
0
{
779
0
  return _gnutls_set_datum(&aki->id, id->data, id->size);
780
0
}
781
782
/**
783
 * gnutls_x509_aki_set_cert_issuer:
784
 * @aki: The authority key ID
785
 * @san_type: the type of the name (of %gnutls_subject_alt_names_t), may be null
786
 * @san: The alternative name data
787
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
788
 * @serial: The authorityCertSerialNumber number (may be null)
789
 *
790
 * This function will set the authorityCertIssuer name and the authorityCertSerialNumber 
791
 * to be stored in the @aki type. When storing multiple names, the serial
792
 * should be set on the first call, and subsequent calls should use a %NULL serial.
793
 *
794
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
795
 * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
796
 *
797
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
798
 *
799
 * Since: 3.3.0
800
 **/
801
int gnutls_x509_aki_set_cert_issuer(gnutls_x509_aki_t aki,
802
            unsigned int san_type,
803
            const gnutls_datum_t * san,
804
            const char *othername_oid,
805
            const gnutls_datum_t * serial)
806
0
{
807
0
  int ret;
808
0
  gnutls_datum_t t_san, t_othername_oid = { NULL, 0 };
809
810
0
  ret = _gnutls_set_datum(&aki->serial, serial->data, serial->size);
811
0
  if (ret < 0)
812
0
    return gnutls_assert_val(ret);
813
814
0
  aki->cert_issuer.names[aki->cert_issuer.size].type = san_type;
815
816
0
  ret = _gnutls_set_strdatum(&t_san, san->data, san->size);
817
0
  if (ret < 0)
818
0
    return gnutls_assert_val(ret);
819
820
0
  if (othername_oid) {
821
0
    t_othername_oid.data = (uint8_t *) gnutls_strdup(othername_oid);
822
0
    if (t_othername_oid.data == NULL) {
823
0
      gnutls_free(t_san.data);
824
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
825
0
    }
826
0
    t_othername_oid.size = strlen(othername_oid);
827
0
  }
828
829
0
  ret =
830
0
      subject_alt_names_set(&aki->cert_issuer.names,
831
0
          &aki->cert_issuer.size, san_type, &t_san,
832
0
          (char *)t_othername_oid.data, 0);
833
0
  if (ret < 0) {
834
0
    gnutls_assert();
835
0
    return ret;
836
0
  }
837
838
0
  return 0;
839
0
}
840
841
/**
842
 * gnutls_x509_aki_get_cert_issuer:
843
 * @aki: The authority key ID
844
 * @seq: The index of the name to get
845
 * @san_type: Will hold the type of the name (of %gnutls_subject_alt_names_t)
846
 * @san: The alternative name data
847
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
848
 * @serial: The authorityCertSerialNumber number
849
 *
850
 * This function will return a specific authorityCertIssuer name as stored in
851
 * the @aki type, as well as the authorityCertSerialNumber. All the returned
852
 * values should be treated as constant, and may be set to %NULL when are not required.
853
 *
854
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
855
 * if the index is out of bounds, otherwise a negative error value.
856
 *
857
 * Since: 3.3.0
858
 **/
859
int gnutls_x509_aki_get_cert_issuer(gnutls_x509_aki_t aki, unsigned int seq,
860
            unsigned int *san_type,
861
            gnutls_datum_t * san,
862
            gnutls_datum_t * othername_oid,
863
            gnutls_datum_t * serial)
864
0
{
865
0
  if (seq >= aki->cert_issuer.size)
866
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
867
868
0
  if (aki->serial.size == 0)
869
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
870
871
0
  if (serial)
872
0
    memcpy(serial, &aki->serial, sizeof(gnutls_datum_t));
873
874
0
  if (san) {
875
0
    memcpy(san, &aki->cert_issuer.names[seq].san,
876
0
           sizeof(gnutls_datum_t));
877
0
  }
878
879
0
  if (othername_oid != NULL
880
0
      && aki->cert_issuer.names[seq].type == GNUTLS_SAN_OTHERNAME) {
881
0
    othername_oid->data =
882
0
        aki->cert_issuer.names[seq].othername_oid.data;
883
0
    othername_oid->size =
884
0
        aki->cert_issuer.names[seq].othername_oid.size;
885
0
  }
886
887
0
  if (san_type)
888
0
    *san_type = aki->cert_issuer.names[seq].type;
889
890
0
  return 0;
891
892
0
}
893
894
/**
895
 * gnutls_x509_ext_import_authority_key_id:
896
 * @ext: a DER encoded extension
897
 * @aki: An initialized authority key identifier type
898
 * @flags: should be zero
899
 *
900
 * This function will return the subject key ID stored in the provided
901
 * AuthorityKeyIdentifier extension.
902
 *
903
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
904
 * if the extension is not present, otherwise a negative error value.
905
 *
906
 * Since: 3.3.0
907
 **/
908
int gnutls_x509_ext_import_authority_key_id(const gnutls_datum_t * ext,
909
              gnutls_x509_aki_t aki,
910
              unsigned int flags)
911
0
{
912
0
  int ret;
913
0
  unsigned i;
914
0
  asn1_node c2 = NULL;
915
0
  gnutls_datum_t san, othername_oid;
916
0
  unsigned type;
917
918
0
  ret = asn1_create_element
919
0
      (_gnutls_get_pkix(), "PKIX1.AuthorityKeyIdentifier", &c2);
920
0
  if (ret != ASN1_SUCCESS) {
921
0
    gnutls_assert();
922
0
    return _gnutls_asn2err(ret);
923
0
  }
924
925
0
  ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
926
0
  if (ret != ASN1_SUCCESS) {
927
0
    gnutls_assert();
928
0
    ret = _gnutls_asn2err(ret);
929
0
    goto cleanup;
930
0
  }
931
932
  /* Read authorityCertIssuer */
933
0
  for (i = 0;; i++) {
934
0
    san.data = NULL;
935
0
    san.size = 0;
936
0
    othername_oid.data = NULL;
937
938
0
    ret = _gnutls_parse_general_name2(c2, "authorityCertIssuer", i,
939
0
              &san, &type, 0);
940
0
    if (ret < 0)
941
0
      break;
942
943
0
    if (type == GNUTLS_SAN_OTHERNAME) {
944
0
      ret =
945
0
          _gnutls_parse_general_name2(c2,
946
0
              "authorityCertIssuer",
947
0
              i,
948
0
              &othername_oid,
949
0
              NULL, 1);
950
0
      if (ret < 0)
951
0
        break;
952
0
    }
953
954
0
    ret = subject_alt_names_set(&aki->cert_issuer.names,
955
0
              &aki->cert_issuer.size,
956
0
              type, &san,
957
0
              (char *)othername_oid.data, 1);
958
0
    if (ret < 0)
959
0
      break;
960
0
  }
961
962
0
  assert(ret < 0);
963
0
  aki->cert_issuer.size = i;
964
0
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
965
0
      && ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
966
0
    gnutls_assert();
967
0
    gnutls_free(san.data);
968
0
    gnutls_free(othername_oid.data);
969
0
    goto cleanup;
970
0
  }
971
972
  /* Read the serial number */
973
0
  ret =
974
0
      _gnutls_x509_read_value(c2, "authorityCertSerialNumber",
975
0
            &aki->serial);
976
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
977
0
      && ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
978
0
    gnutls_assert();
979
0
    goto cleanup;
980
0
  }
981
982
  /* Read the key identifier */
983
0
  ret = _gnutls_x509_read_value(c2, "keyIdentifier", &aki->id);
984
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
985
0
      && ret != GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
986
0
    gnutls_assert();
987
0
    goto cleanup;
988
0
  }
989
990
0
  ret = 0;
991
992
0
 cleanup:
993
0
  asn1_delete_structure(&c2);
994
995
0
  return ret;
996
0
}
997
998
/**
999
 * gnutls_x509_ext_export_authority_key_id:
1000
 * @aki: An initialized authority key identifier
1001
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1002
 *
1003
 * This function will convert the provided key identifier to a
1004
 * DER-encoded PKIX AuthorityKeyIdentifier extension. 
1005
 * The output data in @ext will be allocated using
1006
 * gnutls_malloc().
1007
 *
1008
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
1009
 *
1010
 * Since: 3.3.0
1011
 **/
1012
int gnutls_x509_ext_export_authority_key_id(gnutls_x509_aki_t aki,
1013
              gnutls_datum_t * ext)
1014
0
{
1015
0
  asn1_node c2 = NULL;
1016
0
  unsigned i;
1017
0
  int result, ret;
1018
1019
0
  result =
1020
0
      asn1_create_element(_gnutls_get_pkix(),
1021
0
        "PKIX1.AuthorityKeyIdentifier", &c2);
1022
0
  if (result != ASN1_SUCCESS) {
1023
0
    gnutls_assert();
1024
0
    return _gnutls_asn2err(result);
1025
0
  }
1026
1027
0
  if (aki->id.data != NULL) {
1028
0
    result =
1029
0
        asn1_write_value(c2, "keyIdentifier", aki->id.data,
1030
0
             aki->id.size);
1031
0
    if (result != ASN1_SUCCESS) {
1032
0
      gnutls_assert();
1033
0
      ret = _gnutls_asn2err(result);
1034
0
      goto cleanup;
1035
0
    }
1036
0
  } else {
1037
0
    (void)asn1_write_value(c2, "keyIdentifier", NULL, 0);
1038
0
  }
1039
1040
0
  if (aki->serial.data != NULL) {
1041
0
    result =
1042
0
        asn1_write_value(c2, "authorityCertSerialNumber",
1043
0
             aki->serial.data, aki->serial.size);
1044
0
    if (result != ASN1_SUCCESS) {
1045
0
      gnutls_assert();
1046
0
      ret = _gnutls_asn2err(result);
1047
0
      goto cleanup;
1048
0
    }
1049
0
  } else {
1050
0
    (void)asn1_write_value(c2, "authorityCertSerialNumber", NULL,
1051
0
               0);
1052
0
  }
1053
1054
0
  if (aki->cert_issuer.size == 0) {
1055
0
    (void)asn1_write_value(c2, "authorityCertIssuer", NULL, 0);
1056
0
  } else {
1057
0
    for (i = 0; i < aki->cert_issuer.size; i++) {
1058
0
      ret =
1059
0
          _gnutls_write_new_general_name(c2,
1060
0
                 "authorityCertIssuer",
1061
0
                 aki->cert_issuer.
1062
0
                 names[i].type,
1063
0
                 aki->
1064
0
                 cert_issuer.names[i].
1065
0
                 san.data,
1066
0
                 aki->cert_issuer.
1067
0
                 names[i].san.size);
1068
0
      if (ret < 0) {
1069
0
        gnutls_assert();
1070
0
        goto cleanup;
1071
0
      }
1072
0
    }
1073
0
  }
1074
1075
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
1076
0
  if (ret < 0) {
1077
0
    gnutls_assert();
1078
0
    goto cleanup;
1079
0
  }
1080
1081
0
  ret = 0;
1082
0
 cleanup:
1083
0
  asn1_delete_structure(&c2);
1084
0
  return ret;
1085
1086
0
}
1087
1088
/**
1089
 * gnutls_x509_ext_import_key_usage:
1090
 * @ext: the DER encoded extension data
1091
 * @key_usage: where the key usage bits will be stored
1092
 *
1093
 * This function will return certificate's key usage, by reading the DER
1094
 * data of the keyUsage X.509 extension (2.5.29.15). The key usage value will ORed
1095
 * values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1096
 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1097
 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1098
 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1099
 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1100
 *
1101
 * Returns: the certificate key usage, or a negative error code in case of
1102
 *   parsing error.  If the certificate does not contain the keyUsage
1103
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1104
 *   returned.
1105
 *
1106
 * Since: 3.3.0
1107
 **/
1108
int gnutls_x509_ext_import_key_usage(const gnutls_datum_t * ext,
1109
             unsigned int *key_usage)
1110
0
{
1111
0
  asn1_node c2 = NULL;
1112
0
  int len, result;
1113
0
  uint8_t str[2];
1114
1115
0
  str[0] = str[1] = 0;
1116
0
  *key_usage = 0;
1117
1118
0
  if ((result = asn1_create_element
1119
0
       (_gnutls_get_pkix(), "PKIX1.KeyUsage", &c2)) != ASN1_SUCCESS) {
1120
0
    gnutls_assert();
1121
0
    return _gnutls_asn2err(result);
1122
0
  }
1123
1124
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1125
0
  if (result != ASN1_SUCCESS) {
1126
0
    gnutls_assert();
1127
0
    asn1_delete_structure(&c2);
1128
0
    return _gnutls_asn2err(result);
1129
0
  }
1130
1131
0
  len = sizeof(str);
1132
0
  result = asn1_read_value(c2, "", str, &len);
1133
0
  if (result != ASN1_SUCCESS) {
1134
0
    gnutls_assert();
1135
0
    asn1_delete_structure(&c2);
1136
0
    return _gnutls_asn2err(result);
1137
0
  }
1138
1139
0
  *key_usage = str[0] | (str[1] << 8);
1140
1141
0
  asn1_delete_structure(&c2);
1142
1143
0
  return 0;
1144
0
}
1145
1146
static int _last_key_usage_set_bit(int usage)
1147
0
{
1148
/* the byte ordering is a bit strange here, see how GNUTLS_KEY_* is laid out, and how 
1149
 * asn1_write_value() writes out BIT STRING objects.
1150
 */
1151
0
  if (usage & GNUTLS_KEY_DECIPHER_ONLY)
1152
0
    return 9;
1153
0
  else if (usage & GNUTLS_KEY_ENCIPHER_ONLY)
1154
0
    return 8;
1155
0
  else if (usage & GNUTLS_KEY_CRL_SIGN)
1156
0
    return 7;
1157
0
  else if (usage & GNUTLS_KEY_KEY_CERT_SIGN)
1158
0
    return 6;
1159
0
  else if (usage & GNUTLS_KEY_KEY_AGREEMENT)
1160
0
    return 5;
1161
0
  else if (usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
1162
0
    return 4;
1163
0
  else if (usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
1164
0
    return 3;
1165
0
  else if (usage & GNUTLS_KEY_NON_REPUDIATION)
1166
0
    return 2;
1167
0
  else if (usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
1168
0
    return 1;
1169
0
  else
1170
0
    return 0;
1171
0
}
1172
1173
/**
1174
 * gnutls_x509_ext_export_key_usage:
1175
 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
1176
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1177
 *
1178
 * This function will convert the keyUsage bit string to a DER
1179
 * encoded PKIX extension. The @ext data will be allocated using
1180
 * gnutls_malloc().
1181
 *
1182
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1183
 *   negative error value.
1184
 *
1185
 * Since: 3.3.0
1186
 **/
1187
int gnutls_x509_ext_export_key_usage(unsigned int usage, gnutls_datum_t * ext)
1188
0
{
1189
0
  asn1_node c2 = NULL;
1190
0
  int result;
1191
0
  uint8_t str[2];
1192
1193
0
  result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.KeyUsage", &c2);
1194
0
  if (result != ASN1_SUCCESS) {
1195
0
    gnutls_assert();
1196
0
    return _gnutls_asn2err(result);
1197
0
  }
1198
1199
0
  str[0] = usage & 0xff;
1200
0
  str[1] = usage >> 8;
1201
1202
  /* Since KeyUsage is a BIT STRING, the input to asn1_write_value
1203
   * is the number of bits to be written/read. */
1204
0
  result = asn1_write_value(c2, "", str, _last_key_usage_set_bit(usage));
1205
0
  if (result != ASN1_SUCCESS) {
1206
0
    gnutls_assert();
1207
0
    asn1_delete_structure(&c2);
1208
0
    return _gnutls_asn2err(result);
1209
0
  }
1210
1211
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
1212
1213
0
  asn1_delete_structure(&c2);
1214
1215
0
  if (result < 0) {
1216
0
    gnutls_assert();
1217
0
    return result;
1218
0
  }
1219
1220
0
  return 0;
1221
0
}
1222
1223
/**
1224
 * gnutls_x509_ext_import_inhibit_anypolicy:
1225
 * @ext: the DER encoded extension data
1226
 * @skipcerts: will hold the number of certificates after which anypolicy is no longer acceptable.
1227
 *
1228
 * This function will return certificate's value of SkipCerts,
1229
 * by reading the DER data of the Inhibit anyPolicy X.509 extension (2.5.29.54).
1230
 *
1231
 * The @skipcerts value is the number of additional certificates that
1232
 * may appear in the path before the anyPolicy (%GNUTLS_X509_OID_POLICY_ANY)
1233
 * is no longer acceptable.
1234
 *
1235
 * Returns: zero, or a negative error code in case of
1236
 *   parsing error.  If the certificate does not contain the Inhibit anyPolicy
1237
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1238
 *   returned.
1239
 *
1240
 * Since: 3.6.0
1241
 **/
1242
int gnutls_x509_ext_import_inhibit_anypolicy(const gnutls_datum_t * ext,
1243
               unsigned int *skipcerts)
1244
0
{
1245
0
  int ret;
1246
1247
0
  ret = _gnutls_x509_read_der_uint(ext->data, ext->size, skipcerts);
1248
0
  if (ret < 0) {
1249
0
    gnutls_assert();
1250
0
  }
1251
1252
0
  return ret;
1253
0
}
1254
1255
/**
1256
 * gnutls_x509_ext_export_inhibit_anypolicy:
1257
 * @skipcerts: number of certificates after which anypolicy is no longer acceptable.
1258
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1259
 *
1260
 * This function will convert the @skipcerts value to a DER
1261
 * encoded Inhibit AnyPolicy PKIX extension. The @ext data will be allocated using
1262
 * gnutls_malloc().
1263
 *
1264
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1265
 *   negative error value.
1266
 *
1267
 * Since: 3.6.0
1268
 **/
1269
int gnutls_x509_ext_export_inhibit_anypolicy(unsigned int skipcerts,
1270
               gnutls_datum_t * ext)
1271
0
{
1272
0
  asn1_node c2 = NULL;
1273
0
  int result, ret;
1274
1275
0
  result =
1276
0
      asn1_create_element(_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey",
1277
0
        &c2);
1278
0
  if (result != ASN1_SUCCESS) {
1279
0
    gnutls_assert();
1280
0
    return _gnutls_asn2err(result);
1281
0
  }
1282
1283
0
  ret = _gnutls_x509_write_uint32(c2, "", skipcerts);
1284
0
  if (ret < 0) {
1285
0
    gnutls_assert();
1286
0
    goto cleanup;
1287
0
  }
1288
1289
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
1290
0
  if (ret < 0) {
1291
0
    gnutls_assert();
1292
0
    goto cleanup;
1293
0
  }
1294
1295
0
  ret = 0;
1296
1297
0
 cleanup:
1298
0
  asn1_delete_structure(&c2);
1299
1300
0
  return ret;
1301
0
}
1302
1303
/**
1304
 * gnutls_x509_ext_import_private_key_usage_period:
1305
 * @ext: the DER encoded extension data
1306
 * @activation: Will hold the activation time
1307
 * @expiration: Will hold the expiration time
1308
 *
1309
 * This function will return the expiration and activation
1310
 * times of the private key as written in the
1311
 * PKIX extension 2.5.29.16.
1312
 *
1313
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1314
 *   negative error value.
1315
 *
1316
 * Since: 3.3.0
1317
 **/
1318
int gnutls_x509_ext_import_private_key_usage_period(const gnutls_datum_t * ext,
1319
                time_t * activation,
1320
                time_t * expiration)
1321
0
{
1322
0
  int result, ret;
1323
0
  asn1_node c2 = NULL;
1324
1325
0
  result = asn1_create_element
1326
0
      (_gnutls_get_pkix(), "PKIX1.PrivateKeyUsagePeriod", &c2);
1327
0
  if (result != ASN1_SUCCESS) {
1328
0
    gnutls_assert();
1329
0
    ret = _gnutls_asn2err(result);
1330
0
    goto cleanup;
1331
0
  }
1332
1333
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1334
0
  if (result != ASN1_SUCCESS) {
1335
0
    gnutls_assert();
1336
0
    ret = _gnutls_asn2err(result);
1337
0
    goto cleanup;
1338
0
  }
1339
1340
0
  if (activation)
1341
0
    *activation = _gnutls_x509_get_time(c2, "notBefore", 1);
1342
1343
0
  if (expiration)
1344
0
    *expiration = _gnutls_x509_get_time(c2, "notAfter", 1);
1345
1346
0
  ret = 0;
1347
1348
0
 cleanup:
1349
0
  asn1_delete_structure(&c2);
1350
1351
0
  return ret;
1352
0
}
1353
1354
/**
1355
 * gnutls_x509_ext_export_private_key_usage_period:
1356
 * @activation: The activation time
1357
 * @expiration: The expiration time
1358
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1359
 *
1360
 * This function will convert the periods provided to a private key
1361
 * usage DER encoded extension (2.5.29.16).
1362
 (
1363
 * The @ext data will be allocated using
1364
 * gnutls_malloc().
1365
 *
1366
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1367
 *   negative error value.
1368
 *
1369
 * Since: 3.3.0
1370
 **/
1371
int gnutls_x509_ext_export_private_key_usage_period(time_t activation,
1372
                time_t expiration,
1373
                gnutls_datum_t * ext)
1374
0
{
1375
0
  int result;
1376
0
  asn1_node c2 = NULL;
1377
1378
0
  result =
1379
0
      asn1_create_element(_gnutls_get_pkix(),
1380
0
        "PKIX1.PrivateKeyUsagePeriod", &c2);
1381
0
  if (result != ASN1_SUCCESS) {
1382
0
    gnutls_assert();
1383
0
    return _gnutls_asn2err(result);
1384
0
  }
1385
1386
0
  result = _gnutls_x509_set_time(c2, "notBefore", activation, 1);
1387
0
  if (result < 0) {
1388
0
    gnutls_assert();
1389
0
    goto cleanup;
1390
0
  }
1391
1392
0
  result = _gnutls_x509_set_time(c2, "notAfter", expiration, 1);
1393
0
  if (result < 0) {
1394
0
    gnutls_assert();
1395
0
    goto cleanup;
1396
0
  }
1397
1398
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
1399
0
  if (result < 0) {
1400
0
    gnutls_assert();
1401
0
    goto cleanup;
1402
0
  }
1403
1404
0
 cleanup:
1405
0
  asn1_delete_structure(&c2);
1406
1407
0
  return result;
1408
1409
0
}
1410
1411
/**
1412
 * gnutls_x509_ext_import_basic_constraints:
1413
 * @ext: the DER encoded extension data
1414
 * @ca: will be non zero if the CA status is true
1415
 * @pathlen: the path length constraint; will be set to -1 for no limit
1416
 *
1417
 * This function will return the CA status and path length constraint
1418
 * as written in the PKIX extension 2.5.29.19.
1419
 *
1420
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1421
 *   negative error value.
1422
 *
1423
 * Since: 3.3.0
1424
 **/
1425
int gnutls_x509_ext_import_basic_constraints(const gnutls_datum_t * ext,
1426
               unsigned int *ca, int *pathlen)
1427
0
{
1428
0
  asn1_node c2 = NULL;
1429
0
  char str[128] = "";
1430
0
  int len, result;
1431
1432
0
  if ((result = asn1_create_element
1433
0
       (_gnutls_get_pkix(), "PKIX1.BasicConstraints",
1434
0
        &c2)) != ASN1_SUCCESS) {
1435
0
    gnutls_assert();
1436
0
    return _gnutls_asn2err(result);
1437
0
  }
1438
1439
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1440
0
  if (result != ASN1_SUCCESS) {
1441
0
    gnutls_assert();
1442
0
    result = _gnutls_asn2err(result);
1443
0
    goto cleanup;
1444
0
  }
1445
1446
0
  if (pathlen) {
1447
0
    result = _gnutls_x509_read_uint(c2, "pathLenConstraint",
1448
0
            (unsigned int *)
1449
0
            pathlen);
1450
0
    if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1451
0
      *pathlen = -1;
1452
0
    else if (result != GNUTLS_E_SUCCESS) {
1453
0
      gnutls_assert();
1454
0
      result = _gnutls_asn2err(result);
1455
0
      goto cleanup;
1456
0
    }
1457
0
  }
1458
1459
  /* the default value of cA is false.
1460
   */
1461
0
  len = sizeof(str) - 1;
1462
0
  result = asn1_read_value(c2, "cA", str, &len);
1463
0
  if (result == ASN1_SUCCESS && strcmp(str, "TRUE") == 0)
1464
0
    *ca = 1;
1465
0
  else
1466
0
    *ca = 0;
1467
1468
0
  result = 0;
1469
0
 cleanup:
1470
0
  asn1_delete_structure(&c2);
1471
1472
0
  return result;
1473
1474
0
}
1475
1476
/**
1477
 * gnutls_x509_ext_export_basic_constraints:
1478
 * @ca: non-zero for a CA
1479
 * @pathlen: The path length constraint (set to -1 for no constraint)
1480
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1481
 *
1482
 * This function will convert the parameters provided to a basic constraints
1483
 * DER encoded extension (2.5.29.19).
1484
 (
1485
 * The @ext data will be allocated using
1486
 * gnutls_malloc().
1487
 *
1488
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1489
 *   negative error value.
1490
 *
1491
 * Since: 3.3.0
1492
 **/
1493
int gnutls_x509_ext_export_basic_constraints(unsigned int ca, int pathlen,
1494
               gnutls_datum_t * ext)
1495
0
{
1496
0
  asn1_node c2 = NULL;
1497
0
  const char *str;
1498
0
  int result;
1499
1500
0
  if (ca == 0)
1501
0
    str = "FALSE";
1502
0
  else
1503
0
    str = "TRUE";
1504
1505
0
  result =
1506
0
      asn1_create_element(_gnutls_get_pkix(),
1507
0
        "PKIX1.BasicConstraints", &c2);
1508
0
  if (result != ASN1_SUCCESS) {
1509
0
    gnutls_assert();
1510
0
    result = _gnutls_asn2err(result);
1511
0
    goto cleanup;
1512
0
  }
1513
1514
0
  result = asn1_write_value(c2, "cA", str, 1);
1515
0
  if (result != ASN1_SUCCESS) {
1516
0
    gnutls_assert();
1517
0
    result = _gnutls_asn2err(result);
1518
0
    goto cleanup;
1519
0
  }
1520
1521
0
  if (pathlen < 0) {
1522
0
    result = asn1_write_value(c2, "pathLenConstraint", NULL, 0);
1523
0
    if (result < 0)
1524
0
      result = _gnutls_asn2err(result);
1525
0
  } else
1526
0
    result =
1527
0
        _gnutls_x509_write_uint32(c2, "pathLenConstraint", pathlen);
1528
0
  if (result < 0) {
1529
0
    gnutls_assert();
1530
0
    goto cleanup;
1531
0
  }
1532
1533
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
1534
0
  if (result < 0) {
1535
0
    gnutls_assert();
1536
0
    goto cleanup;
1537
0
  }
1538
1539
0
  result = 0;
1540
1541
0
 cleanup:
1542
0
  asn1_delete_structure(&c2);
1543
0
  return result;
1544
1545
0
}
1546
1547
/**
1548
 * gnutls_x509_ext_import_proxy:
1549
 * @ext: the DER encoded extension data
1550
 * @pathlen: pointer to output integer indicating path length (may be
1551
 *   NULL), non-negative error codes indicate a present pCPathLenConstraint
1552
 *   field and the actual value, -1 indicate that the field is absent.
1553
 * @policyLanguage: output variable with OID of policy language
1554
 * @policy: output variable with policy data
1555
 * @sizeof_policy: output variable with size of policy data
1556
 *
1557
 * This function will return the information from a proxy certificate
1558
 * extension. It reads the ProxyCertInfo X.509 extension (1.3.6.1.5.5.7.1.14).
1559
 * The @policyLanguage and @policy values must be deinitialized using gnutls_free() after use.
1560
 *
1561
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1562
 *   negative error value.
1563
 *
1564
 * Since: 3.3.0
1565
 **/
1566
int gnutls_x509_ext_import_proxy(const gnutls_datum_t * ext, int *pathlen,
1567
         char **policyLanguage, char **policy,
1568
         size_t *sizeof_policy)
1569
0
{
1570
0
  asn1_node c2 = NULL;
1571
0
  int result;
1572
0
  gnutls_datum_t value1 = { NULL, 0 };
1573
0
  gnutls_datum_t value2 = { NULL, 0 };
1574
1575
0
  if ((result = asn1_create_element
1576
0
       (_gnutls_get_pkix(), "PKIX1.ProxyCertInfo",
1577
0
        &c2)) != ASN1_SUCCESS) {
1578
0
    gnutls_assert();
1579
0
    return _gnutls_asn2err(result);
1580
0
  }
1581
1582
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1583
0
  if (result != ASN1_SUCCESS) {
1584
0
    gnutls_assert();
1585
0
    result = _gnutls_asn2err(result);
1586
0
    goto cleanup;
1587
0
  }
1588
1589
0
  if (pathlen) {
1590
0
    result = _gnutls_x509_read_uint(c2, "pCPathLenConstraint",
1591
0
            (unsigned int *)
1592
0
            pathlen);
1593
0
    if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1594
0
      *pathlen = -1;
1595
0
    else if (result != GNUTLS_E_SUCCESS) {
1596
0
      gnutls_assert();
1597
0
      result = _gnutls_asn2err(result);
1598
0
      goto cleanup;
1599
0
    }
1600
0
  }
1601
1602
0
  result = _gnutls_x509_read_value(c2, "proxyPolicy.policyLanguage",
1603
0
           &value1);
1604
0
  if (result < 0) {
1605
0
    gnutls_assert();
1606
0
    goto cleanup;
1607
0
  }
1608
1609
0
  result = _gnutls_x509_read_value(c2, "proxyPolicy.policy", &value2);
1610
0
  if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
1611
0
    if (policy)
1612
0
      *policy = NULL;
1613
0
    if (sizeof_policy)
1614
0
      *sizeof_policy = 0;
1615
0
  } else if (result < 0) {
1616
0
    gnutls_assert();
1617
0
    goto cleanup;
1618
0
  } else {
1619
0
    if (policy) {
1620
0
      *policy = (char *)value2.data;
1621
0
      value2.data = NULL;
1622
0
    }
1623
0
    if (sizeof_policy)
1624
0
      *sizeof_policy = value2.size;
1625
0
  }
1626
1627
0
  if (policyLanguage) {
1628
0
    *policyLanguage = (char *)value1.data;
1629
0
    value1.data = NULL;
1630
0
  }
1631
1632
0
  result = 0;
1633
0
 cleanup:
1634
0
  gnutls_free(value1.data);
1635
0
  gnutls_free(value2.data);
1636
0
  asn1_delete_structure(&c2);
1637
1638
0
  return result;
1639
0
}
1640
1641
/**
1642
 * gnutls_x509_ext_export_proxy:
1643
 * @pathLenConstraint: A negative value will remove the path length constraint,
1644
 *   while non-negative values will be set as the length of the pathLenConstraints field.
1645
 * @policyLanguage: OID describing the language of @policy.
1646
 * @policy: uint8_t byte array with policy language, can be %NULL
1647
 * @sizeof_policy: size of @policy.
1648
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
1649
 *
1650
 * This function will convert the parameters provided to a proxyCertInfo extension.
1651
 *
1652
 * The @ext data will be allocated using gnutls_malloc().
1653
 *
1654
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1655
 *   negative error value.
1656
 *
1657
 * Since: 3.3.0
1658
 **/
1659
int gnutls_x509_ext_export_proxy(int pathLenConstraint,
1660
         const char *policyLanguage, const char *policy,
1661
         size_t sizeof_policy, gnutls_datum_t * ext)
1662
0
{
1663
0
  asn1_node c2 = NULL;
1664
0
  int result;
1665
1666
0
  result = asn1_create_element(_gnutls_get_pkix(),
1667
0
             "PKIX1.ProxyCertInfo", &c2);
1668
0
  if (result != ASN1_SUCCESS) {
1669
0
    gnutls_assert();
1670
0
    return _gnutls_asn2err(result);
1671
0
  }
1672
1673
0
  if (pathLenConstraint < 0) {
1674
0
    result = asn1_write_value(c2, "pCPathLenConstraint", NULL, 0);
1675
0
    if (result != ASN1_SUCCESS) {
1676
0
      gnutls_assert();
1677
0
      result = _gnutls_asn2err(result);
1678
0
      goto cleanup;
1679
0
    }
1680
0
  } else {
1681
0
    result =
1682
0
        _gnutls_x509_write_uint32(c2, "pCPathLenConstraint",
1683
0
                pathLenConstraint);
1684
1685
0
    if (result < 0) {
1686
0
      gnutls_assert();
1687
0
      goto cleanup;
1688
0
    }
1689
0
  }
1690
1691
0
  result = asn1_write_value(c2, "proxyPolicy.policyLanguage",
1692
0
          policyLanguage, 1);
1693
0
  if (result < 0) {
1694
0
    gnutls_assert();
1695
0
    result = _gnutls_asn2err(result);
1696
0
    goto cleanup;
1697
0
  }
1698
1699
0
  result = asn1_write_value(c2, "proxyPolicy.policy",
1700
0
          policy, sizeof_policy);
1701
0
  if (result < 0) {
1702
0
    gnutls_assert();
1703
0
    result = _gnutls_asn2err(result);
1704
0
    goto cleanup;
1705
0
  }
1706
1707
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
1708
0
  if (result < 0) {
1709
0
    gnutls_assert();
1710
0
    goto cleanup;
1711
0
  }
1712
1713
0
  result = 0;
1714
0
 cleanup:
1715
0
  asn1_delete_structure(&c2);
1716
0
  return result;
1717
1718
0
}
1719
1720
static int decode_user_notice(const void *data, size_t size,
1721
            gnutls_datum_t * txt)
1722
0
{
1723
0
  asn1_node c2 = NULL;
1724
0
  int ret, len;
1725
0
  char choice_type[64];
1726
0
  char name[128];
1727
0
  gnutls_datum_t td = { NULL, 0 }, utd;
1728
1729
0
  ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.UserNotice", &c2);
1730
0
  if (ret != ASN1_SUCCESS) {
1731
0
    gnutls_assert();
1732
0
    ret = GNUTLS_E_PARSING_ERROR;
1733
0
    goto cleanup;
1734
0
  }
1735
1736
0
  ret = _asn1_strict_der_decode(&c2, data, size, NULL);
1737
0
  if (ret != ASN1_SUCCESS) {
1738
0
    gnutls_assert();
1739
0
    ret = GNUTLS_E_PARSING_ERROR;
1740
0
    goto cleanup;
1741
0
  }
1742
1743
0
  len = sizeof(choice_type);
1744
0
  ret = asn1_read_value(c2, "explicitText", choice_type, &len);
1745
0
  if (ret != ASN1_SUCCESS) {
1746
0
    gnutls_assert();
1747
0
    ret = GNUTLS_E_PARSING_ERROR;
1748
0
    goto cleanup;
1749
0
  }
1750
1751
0
  if (strcmp(choice_type, "utf8String") != 0
1752
0
      && strcmp(choice_type, "ia5String") != 0
1753
0
      && strcmp(choice_type, "bmpString") != 0
1754
0
      && strcmp(choice_type, "visibleString") != 0) {
1755
0
    gnutls_assert();
1756
0
    ret = GNUTLS_E_PARSING_ERROR;
1757
0
    goto cleanup;
1758
0
  }
1759
1760
0
  snprintf(name, sizeof(name), "explicitText.%s", choice_type);
1761
1762
0
  ret = _gnutls_x509_read_value(c2, name, &td);
1763
0
  if (ret < 0) {
1764
0
    gnutls_assert();
1765
0
    goto cleanup;
1766
0
  }
1767
1768
0
  if (strcmp(choice_type, "bmpString") == 0) { /* convert to UTF-8 */
1769
0
    ret = _gnutls_ucs2_to_utf8(td.data, td.size, &utd, 1);
1770
0
    _gnutls_free_datum(&td);
1771
0
    if (ret < 0) {
1772
0
      gnutls_assert();
1773
0
      goto cleanup;
1774
0
    }
1775
1776
0
    td.data = utd.data;
1777
0
    td.size = utd.size;
1778
0
  } else {
1779
    /* _gnutls_x509_read_value allows that */
1780
0
    td.data[td.size] = 0;
1781
0
  }
1782
1783
0
  txt->data = (void *)td.data;
1784
0
  txt->size = td.size;
1785
0
  ret = 0;
1786
1787
0
 cleanup:
1788
0
  asn1_delete_structure(&c2);
1789
0
  return ret;
1790
1791
0
}
1792
1793
struct gnutls_x509_policies_st {
1794
  struct gnutls_x509_policy_st policy[MAX_ENTRIES];
1795
  unsigned int size;
1796
};
1797
1798
/**
1799
 * gnutls_x509_policies_init:
1800
 * @policies: The authority key ID
1801
 *
1802
 * This function will initialize an authority key ID type.
1803
 *
1804
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
1805
 *
1806
 * Since: 3.3.0
1807
 **/
1808
int gnutls_x509_policies_init(gnutls_x509_policies_t * policies)
1809
0
{
1810
0
  *policies = gnutls_calloc(1, sizeof(struct gnutls_x509_policies_st));
1811
0
  if (*policies == NULL)
1812
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1813
1814
0
  return 0;
1815
0
}
1816
1817
/**
1818
 * gnutls_x509_policies_deinit:
1819
 * @policies: The authority key identifier
1820
 *
1821
 * This function will deinitialize an authority key identifier type.
1822
 *
1823
 * Since: 3.3.0
1824
 **/
1825
void gnutls_x509_policies_deinit(gnutls_x509_policies_t policies)
1826
0
{
1827
0
  unsigned i;
1828
1829
0
  for (i = 0; i < policies->size; i++) {
1830
0
    gnutls_x509_policy_release(&policies->policy[i]);
1831
0
  }
1832
0
  gnutls_free(policies);
1833
0
}
1834
1835
/**
1836
 * gnutls_x509_policies_get:
1837
 * @policies: The policies
1838
 * @seq: The index of the name to get
1839
 * @policy: Will hold the policy
1840
 *
1841
 * This function will return a specific policy as stored in
1842
 * the @policies type. The returned values should be treated as constant
1843
 * and valid for the lifetime of @policies.
1844
 *
1845
 * The any policy OID is available as the %GNUTLS_X509_OID_POLICY_ANY macro.
1846
 *
1847
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1848
 * if the index is out of bounds, otherwise a negative error value.
1849
 *
1850
 * Since: 3.3.0
1851
 **/
1852
int gnutls_x509_policies_get(gnutls_x509_policies_t policies,
1853
           unsigned int seq,
1854
           struct gnutls_x509_policy_st *policy)
1855
0
{
1856
0
  if (seq >= policies->size)
1857
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1858
1859
0
  if (policy) {
1860
0
    memcpy(policy, &policies->policy[seq],
1861
0
           sizeof(struct gnutls_x509_policy_st));
1862
0
  }
1863
1864
0
  return 0;
1865
0
}
1866
1867
void _gnutls_x509_policies_erase(gnutls_x509_policies_t policies,
1868
         unsigned int seq)
1869
0
{
1870
0
  if (seq >= policies->size)
1871
0
    return;
1872
1873
0
  memset(&policies->policy[seq], 0, sizeof(struct gnutls_x509_policy_st));
1874
0
}
1875
1876
/**
1877
 * gnutls_x509_policies_set:
1878
 * @policies: An initialized policies
1879
 * @seq: The index of the name to get
1880
 * @policy: Contains the policy to set
1881
 *
1882
 * This function will store the specified policy in
1883
 * the provided @policies.
1884
 *
1885
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
1886
 *
1887
 * Since: 3.3.0
1888
 **/
1889
int gnutls_x509_policies_set(gnutls_x509_policies_t policies,
1890
           const struct gnutls_x509_policy_st *policy)
1891
0
{
1892
0
  unsigned i;
1893
1894
0
  if (policies->size + 1 > MAX_ENTRIES)
1895
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1896
1897
0
  policies->policy[policies->size].oid = gnutls_strdup(policy->oid);
1898
0
  if (policies->policy[policies->size].oid == NULL)
1899
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1900
1901
0
  for (i = 0; i < policy->qualifiers; i++) {
1902
0
    policies->policy[policies->size].qualifier[i].type =
1903
0
        policy->qualifier[i].type;
1904
0
    policies->policy[policies->size].qualifier[i].size =
1905
0
        policy->qualifier[i].size;
1906
0
    policies->policy[policies->size].qualifier[i].data =
1907
0
        gnutls_malloc(policy->qualifier[i].size + 1);
1908
0
    if (policies->policy[policies->size].qualifier[i].data == NULL)
1909
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1910
0
    memcpy(policies->policy[policies->size].qualifier[i].data,
1911
0
           policy->qualifier[i].data, policy->qualifier[i].size);
1912
0
    policies->policy[policies->size].qualifier[i].data[policy->
1913
0
                   qualifier[i].
1914
0
                   size] = 0;
1915
0
  }
1916
1917
0
  policies->policy[policies->size].qualifiers = policy->qualifiers;
1918
0
  policies->size++;
1919
1920
0
  return 0;
1921
0
}
1922
1923
/**
1924
 * gnutls_x509_ext_import_policies:
1925
 * @ext: the DER encoded extension data
1926
 * @policies: A pointer to an initialized policies.
1927
 * @flags: should be zero
1928
 *
1929
 * This function will extract the certificate policy extension (2.5.29.32) 
1930
 * and store it the provided policies.
1931
 *
1932
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
1933
 *
1934
 * Since: 3.3.0
1935
 **/
1936
int gnutls_x509_ext_import_policies(const gnutls_datum_t * ext,
1937
            gnutls_x509_policies_t policies,
1938
            unsigned int flags)
1939
0
{
1940
0
  asn1_node c2 = NULL;
1941
0
  char tmpstr[128];
1942
0
  char tmpoid[MAX_OID_SIZE];
1943
0
  gnutls_datum_t tmpd = { NULL, 0 };
1944
0
  int ret, len;
1945
0
  unsigned i, j, current = 0;
1946
1947
0
  ret = asn1_create_element
1948
0
      (_gnutls_get_pkix(), "PKIX1.certificatePolicies", &c2);
1949
0
  if (ret != ASN1_SUCCESS) {
1950
0
    gnutls_assert();
1951
0
    ret = _gnutls_asn2err(ret);
1952
0
    goto cleanup;
1953
0
  }
1954
1955
0
  ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
1956
0
  if (ret != ASN1_SUCCESS) {
1957
0
    gnutls_assert();
1958
0
    ret = _gnutls_asn2err(ret);
1959
0
    goto cleanup;
1960
0
  }
1961
1962
0
  for (j = 0;; j++) {
1963
0
    if (j >= MAX_ENTRIES)
1964
0
      break;
1965
1966
0
    memset(&policies->policy[j], 0,
1967
0
           sizeof(struct gnutls_x509_policy_st));
1968
1969
    /* create a string like "?1"
1970
     */
1971
0
    snprintf(tmpstr, sizeof(tmpstr), "?%u.policyIdentifier", j + 1);
1972
0
    current = j + 1;
1973
1974
0
    ret = _gnutls_x509_read_value(c2, tmpstr, &tmpd);
1975
0
    if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1976
0
      break;
1977
1978
0
    if (ret < 0) {
1979
0
      gnutls_assert();
1980
0
      goto full_cleanup;
1981
0
    }
1982
1983
0
    policies->policy[j].oid = (void *)tmpd.data;
1984
0
    tmpd.data = NULL;
1985
1986
0
    for (i = 0; i < GNUTLS_MAX_QUALIFIERS; i++) {
1987
0
      gnutls_datum_t td;
1988
1989
0
      snprintf(tmpstr, sizeof(tmpstr),
1990
0
         "?%u.policyQualifiers.?%u.policyQualifierId",
1991
0
         j + 1, i + 1);
1992
1993
0
      len = sizeof(tmpoid);
1994
0
      ret = asn1_read_value(c2, tmpstr, tmpoid, &len);
1995
1996
0
      if (ret == ASN1_ELEMENT_NOT_FOUND)
1997
0
        break; /* finished */
1998
1999
0
      if (ret != ASN1_SUCCESS) {
2000
0
        gnutls_assert();
2001
0
        ret = _gnutls_asn2err(ret);
2002
0
        goto full_cleanup;
2003
0
      }
2004
2005
0
      if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.1") == 0) {
2006
0
        snprintf(tmpstr, sizeof(tmpstr),
2007
0
           "?%u.policyQualifiers.?%u.qualifier",
2008
0
           j + 1, i + 1);
2009
2010
0
        ret =
2011
0
            _gnutls_x509_read_string(c2, tmpstr, &td,
2012
0
                   ASN1_ETYPE_IA5_STRING,
2013
0
                   0);
2014
0
        if (ret < 0) {
2015
0
          gnutls_assert();
2016
0
          goto full_cleanup;
2017
0
        }
2018
2019
0
        policies->policy[j].qualifier[i].data =
2020
0
            (void *)td.data;
2021
0
        policies->policy[j].qualifier[i].size = td.size;
2022
0
        td.data = NULL;
2023
0
        policies->policy[j].qualifier[i].type =
2024
0
            GNUTLS_X509_QUALIFIER_URI;
2025
0
      } else if (strcmp(tmpoid, "1.3.6.1.5.5.7.2.2") == 0) {
2026
0
        gnutls_datum_t txt = { NULL, 0 };
2027
2028
0
        snprintf(tmpstr, sizeof(tmpstr),
2029
0
           "?%u.policyQualifiers.?%u.qualifier",
2030
0
           j + 1, i + 1);
2031
2032
0
        ret = _gnutls_x509_read_value(c2, tmpstr, &td);
2033
0
        if (ret < 0) {
2034
0
          gnutls_assert();
2035
0
          goto full_cleanup;
2036
0
        }
2037
2038
0
        ret =
2039
0
            decode_user_notice(td.data, td.size, &txt);
2040
0
        gnutls_free(td.data);
2041
2042
0
        if (ret < 0) {
2043
0
          gnutls_assert();
2044
0
          goto full_cleanup;
2045
0
        }
2046
2047
0
        policies->policy[j].qualifier[i].data =
2048
0
            (void *)txt.data;
2049
0
        policies->policy[j].qualifier[i].size =
2050
0
            txt.size;
2051
0
        policies->policy[j].qualifier[i].type =
2052
0
            GNUTLS_X509_QUALIFIER_NOTICE;
2053
0
      } else
2054
0
        policies->policy[j].qualifier[i].type =
2055
0
            GNUTLS_X509_QUALIFIER_UNKNOWN;
2056
2057
0
      policies->policy[j].qualifiers++;
2058
0
    }
2059
2060
0
  }
2061
2062
0
  policies->size = j;
2063
2064
0
  ret = 0;
2065
0
  goto cleanup;
2066
2067
0
 full_cleanup:
2068
0
  for (j = 0; j < current; j++)
2069
0
    gnutls_x509_policy_release(&policies->policy[j]);
2070
2071
0
 cleanup:
2072
0
  _gnutls_free_datum(&tmpd);
2073
0
  asn1_delete_structure(&c2);
2074
0
  return ret;
2075
2076
0
}
2077
2078
static int encode_user_notice(const gnutls_datum_t * txt,
2079
            gnutls_datum_t * der_data)
2080
0
{
2081
0
  int result;
2082
0
  asn1_node c2 = NULL;
2083
2084
0
  if ((result =
2085
0
       asn1_create_element(_gnutls_get_pkix(),
2086
0
         "PKIX1.UserNotice", &c2)) != ASN1_SUCCESS) {
2087
0
    gnutls_assert();
2088
0
    result = _gnutls_asn2err(result);
2089
0
    goto error;
2090
0
  }
2091
2092
  /* delete noticeRef */
2093
0
  result = asn1_write_value(c2, "noticeRef", NULL, 0);
2094
0
  if (result != ASN1_SUCCESS) {
2095
0
    gnutls_assert();
2096
0
    result = _gnutls_asn2err(result);
2097
0
    goto error;
2098
0
  }
2099
2100
0
  result = asn1_write_value(c2, "explicitText", "utf8String", 1);
2101
0
  if (result != ASN1_SUCCESS) {
2102
0
    gnutls_assert();
2103
0
    result = _gnutls_asn2err(result);
2104
0
    goto error;
2105
0
  }
2106
2107
0
  result =
2108
0
      asn1_write_value(c2, "explicitText.utf8String", txt->data,
2109
0
           txt->size);
2110
0
  if (result != ASN1_SUCCESS) {
2111
0
    gnutls_assert();
2112
0
    result = _gnutls_asn2err(result);
2113
0
    goto error;
2114
0
  }
2115
2116
0
  result = _gnutls_x509_der_encode(c2, "", der_data, 0);
2117
0
  if (result < 0) {
2118
0
    gnutls_assert();
2119
0
    goto error;
2120
0
  }
2121
2122
0
  result = 0;
2123
2124
0
 error:
2125
0
  asn1_delete_structure(&c2);
2126
0
  return result;
2127
2128
0
}
2129
2130
/**
2131
 * gnutls_x509_ext_export_policies:
2132
 * @policies: A pointer to an initialized policies.
2133
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2134
 *
2135
 * This function will convert the provided policies, to a certificate policy
2136
 * DER encoded extension (2.5.29.32).
2137
 *
2138
 * The @ext data will be allocated using gnutls_malloc().
2139
 *
2140
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2141
 *
2142
 * Since: 3.3.0
2143
 **/
2144
int gnutls_x509_ext_export_policies(gnutls_x509_policies_t policies,
2145
            gnutls_datum_t * ext)
2146
0
{
2147
0
  int result;
2148
0
  unsigned i, j;
2149
0
  gnutls_datum_t der_data = { NULL, 0 }, tmpd;
2150
0
  asn1_node c2 = NULL;
2151
0
  const char *oid;
2152
2153
0
  result =
2154
0
      asn1_create_element(_gnutls_get_pkix(),
2155
0
        "PKIX1.certificatePolicies", &c2);
2156
0
  if (result != ASN1_SUCCESS) {
2157
0
    gnutls_assert();
2158
0
    result = _gnutls_asn2err(result);
2159
0
    goto cleanup;
2160
0
  }
2161
2162
0
  for (j = 0; j < policies->size; j++) {
2163
    /* 1. write a new policy */
2164
0
    result = asn1_write_value(c2, "", "NEW", 1);
2165
0
    if (result != ASN1_SUCCESS) {
2166
0
      gnutls_assert();
2167
0
      result = _gnutls_asn2err(result);
2168
0
      goto cleanup;
2169
0
    }
2170
2171
    /* 2. Add the OID.
2172
     */
2173
0
    result =
2174
0
        asn1_write_value(c2, "?LAST.policyIdentifier",
2175
0
             policies->policy[j].oid, 1);
2176
0
    if (result != ASN1_SUCCESS) {
2177
0
      gnutls_assert();
2178
0
      result = _gnutls_asn2err(result);
2179
0
      goto cleanup;
2180
0
    }
2181
2182
0
    if (policies->policy[j].qualifiers == 0) {
2183
      /* remove the optional policyQualifiers if none are present. */
2184
0
      result =
2185
0
          asn1_write_value(c2, "?LAST.policyQualifiers", NULL,
2186
0
               0);
2187
0
      if (result != ASN1_SUCCESS) {
2188
0
        gnutls_assert();
2189
0
        result = _gnutls_asn2err(result);
2190
0
        goto cleanup;
2191
0
      }
2192
0
    }
2193
2194
0
    for (i = 0;
2195
0
         i < MIN(policies->policy[j].qualifiers,
2196
0
           GNUTLS_MAX_QUALIFIERS); i++) {
2197
0
      result =
2198
0
          asn1_write_value(c2, "?LAST.policyQualifiers",
2199
0
               "NEW", 1);
2200
0
      if (result != ASN1_SUCCESS) {
2201
0
        gnutls_assert();
2202
0
        result = _gnutls_asn2err(result);
2203
0
        goto cleanup;
2204
0
      }
2205
2206
0
      if (policies->policy[j].qualifier[i].type ==
2207
0
          GNUTLS_X509_QUALIFIER_URI)
2208
0
        oid = "1.3.6.1.5.5.7.2.1";
2209
0
      else if (policies->policy[j].qualifier[i].type ==
2210
0
         GNUTLS_X509_QUALIFIER_NOTICE)
2211
0
        oid = "1.3.6.1.5.5.7.2.2";
2212
0
      else {
2213
0
        result =
2214
0
            gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2215
0
        goto cleanup;
2216
0
      }
2217
2218
0
      result =
2219
0
          asn1_write_value(c2,
2220
0
               "?LAST.policyQualifiers.?LAST.policyQualifierId",
2221
0
               oid, 1);
2222
0
      if (result != ASN1_SUCCESS) {
2223
0
        gnutls_assert();
2224
0
        result = _gnutls_asn2err(result);
2225
0
        goto cleanup;
2226
0
      }
2227
2228
0
      if (policies->policy[j].qualifier[i].type ==
2229
0
          GNUTLS_X509_QUALIFIER_URI) {
2230
0
        tmpd.data =
2231
0
            (void *)policies->policy[j].qualifier[i].
2232
0
            data;
2233
0
        tmpd.size =
2234
0
            policies->policy[j].qualifier[i].size;
2235
0
        result =
2236
0
            _gnutls_x509_write_string(c2,
2237
0
                    "?LAST.policyQualifiers.?LAST.qualifier",
2238
0
                    &tmpd,
2239
0
                    ASN1_ETYPE_IA5_STRING);
2240
0
        if (result < 0) {
2241
0
          gnutls_assert();
2242
0
          goto cleanup;
2243
0
        }
2244
0
      } else if (policies->policy[j].qualifier[i].type ==
2245
0
           GNUTLS_X509_QUALIFIER_NOTICE) {
2246
0
        tmpd.data =
2247
0
            (void *)policies->policy[j].qualifier[i].
2248
0
            data;
2249
0
        tmpd.size =
2250
0
            policies->policy[j].qualifier[i].size;
2251
2252
0
        if (tmpd.size > 200) {
2253
0
          gnutls_assert();
2254
0
          result = GNUTLS_E_INVALID_REQUEST;
2255
0
          goto cleanup;
2256
0
        }
2257
2258
0
        result = encode_user_notice(&tmpd, &der_data);
2259
0
        if (result < 0) {
2260
0
          gnutls_assert();
2261
0
          goto cleanup;
2262
0
        }
2263
2264
0
        result =
2265
0
            _gnutls_x509_write_value(c2,
2266
0
                   "?LAST.policyQualifiers.?LAST.qualifier",
2267
0
                   &der_data);
2268
0
        _gnutls_free_datum(&der_data);
2269
0
        if (result < 0) {
2270
0
          gnutls_assert();
2271
0
          goto cleanup;
2272
0
        }
2273
0
      }
2274
0
    }
2275
0
  }
2276
2277
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
2278
0
  if (result < 0) {
2279
0
    gnutls_assert();
2280
0
    goto cleanup;
2281
0
  }
2282
2283
0
 cleanup:
2284
0
  asn1_delete_structure(&c2);
2285
2286
0
  return result;
2287
0
}
2288
2289
struct crl_dist_point_st {
2290
  unsigned int type;
2291
  gnutls_datum_t san;
2292
  unsigned int reasons;
2293
};
2294
2295
struct gnutls_x509_crl_dist_points_st {
2296
  struct crl_dist_point_st *points;
2297
  unsigned int size;
2298
};
2299
2300
/**
2301
 * gnutls_x509_crl_dist_points_init:
2302
 * @cdp: The CRL distribution points
2303
 *
2304
 * This function will initialize a CRL distribution points type.
2305
 *
2306
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2307
 *
2308
 * Since: 3.3.0
2309
 **/
2310
int gnutls_x509_crl_dist_points_init(gnutls_x509_crl_dist_points_t * cdp)
2311
0
{
2312
0
  *cdp = gnutls_calloc(1, sizeof(struct gnutls_x509_crl_dist_points_st));
2313
0
  if (*cdp == NULL)
2314
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2315
2316
0
  return 0;
2317
0
}
2318
2319
/**
2320
 * gnutls_x509_crl_dist_points_deinit:
2321
 * @cdp: The CRL distribution points
2322
 *
2323
 * This function will deinitialize a CRL distribution points type.
2324
 *
2325
 * Since: 3.3.0
2326
 **/
2327
void gnutls_x509_crl_dist_points_deinit(gnutls_x509_crl_dist_points_t cdp)
2328
0
{
2329
0
  unsigned i;
2330
2331
0
  for (i = 0; i < cdp->size; i++) {
2332
0
    gnutls_free(cdp->points[i].san.data);
2333
0
  }
2334
0
  gnutls_free(cdp->points);
2335
0
  gnutls_free(cdp);
2336
0
}
2337
2338
/**
2339
 * gnutls_x509_crl_dist_points_get:
2340
 * @cdp: The CRL distribution points
2341
 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2342
 * @type: The name type of the corresponding name (gnutls_x509_subject_alt_name_t)
2343
 * @san: The distribution point names (to be treated as constant)
2344
 * @reasons: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
2345
 *
2346
 * This function retrieves the individual CRL distribution points (2.5.29.31),
2347
 * contained in provided type. 
2348
 *
2349
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2350
 * if the index is out of bounds, otherwise a negative error value.
2351
 **/
2352
2353
int gnutls_x509_crl_dist_points_get(gnutls_x509_crl_dist_points_t cdp,
2354
            unsigned int seq, unsigned int *type,
2355
            gnutls_datum_t * san, unsigned int *reasons)
2356
0
{
2357
0
  if (seq >= cdp->size)
2358
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2359
2360
0
  if (reasons)
2361
0
    *reasons = cdp->points[seq].reasons;
2362
2363
0
  if (type)
2364
0
    *type = cdp->points[seq].type;
2365
2366
0
  if (san) {
2367
0
    san->data = cdp->points[seq].san.data;
2368
0
    san->size = cdp->points[seq].san.size;
2369
0
  }
2370
2371
0
  return 0;
2372
0
}
2373
2374
static
2375
int crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,
2376
      gnutls_x509_subject_alt_name_t type,
2377
      const gnutls_datum_t * san, unsigned int reasons)
2378
0
{
2379
0
  void *tmp;
2380
2381
0
  if (unlikely(INT_ADD_OVERFLOW(cdp->size, 1))) {
2382
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2383
0
  }
2384
2385
  /* new dist point */
2386
0
  tmp = _gnutls_reallocarray(cdp->points, cdp->size + 1,
2387
0
           sizeof(cdp->points[0]));
2388
0
  if (tmp == NULL) {
2389
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2390
0
  }
2391
0
  cdp->points = tmp;
2392
2393
0
  cdp->points[cdp->size].type = type;
2394
0
  cdp->points[cdp->size].san.data = san->data;
2395
0
  cdp->points[cdp->size].san.size = san->size;
2396
0
  cdp->points[cdp->size].reasons = reasons;
2397
2398
0
  cdp->size++;
2399
0
  return 0;
2400
2401
0
}
2402
2403
/**
2404
 * gnutls_x509_crl_dist_points_set:
2405
 * @cdp: The CRL distribution points
2406
 * @type: The type of the name (of %gnutls_subject_alt_names_t)
2407
 * @san: The point name data
2408
 * @reasons: Revocation reasons. An ORed sequence of flags from %gnutls_x509_crl_reason_flags_t.
2409
 *
2410
 * This function will store the specified CRL distribution point value
2411
 * the @cdp type.
2412
 *
2413
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
2414
 *
2415
 * Since: 3.3.0
2416
 **/
2417
int gnutls_x509_crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,
2418
            gnutls_x509_subject_alt_name_t type,
2419
            const gnutls_datum_t * san,
2420
            unsigned int reasons)
2421
0
{
2422
0
  int ret;
2423
0
  gnutls_datum_t t_san;
2424
2425
0
  ret = _gnutls_set_datum(&t_san, san->data, san->size);
2426
0
  if (ret < 0)
2427
0
    return gnutls_assert_val(ret);
2428
2429
0
  ret = crl_dist_points_set(cdp, type, &t_san, reasons);
2430
0
  if (ret < 0) {
2431
0
    gnutls_free(t_san.data);
2432
0
    return gnutls_assert_val(ret);
2433
0
  }
2434
2435
0
  return 0;
2436
0
}
2437
2438
/**
2439
 * gnutls_x509_ext_import_crl_dist_points:
2440
 * @ext: the DER encoded extension data
2441
 * @cdp: A pointer to an initialized CRL distribution points.
2442
 * @flags: should be zero
2443
 *
2444
 * This function will extract the CRL distribution points extension (2.5.29.31) 
2445
 * and store it into the provided type.
2446
 *
2447
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2448
 *
2449
 * Since: 3.3.0
2450
 **/
2451
int gnutls_x509_ext_import_crl_dist_points(const gnutls_datum_t * ext,
2452
             gnutls_x509_crl_dist_points_t cdp,
2453
             unsigned int flags)
2454
0
{
2455
0
  int result;
2456
0
  asn1_node c2 = NULL;
2457
0
  char name[MAX_NAME_SIZE];
2458
0
  int len, ret;
2459
0
  uint8_t reasons[2];
2460
0
  unsigned i, type, rflags, j;
2461
0
  gnutls_datum_t san = { NULL, 0 };
2462
2463
0
  result = asn1_create_element
2464
0
      (_gnutls_get_pkix(), "PKIX1.CRLDistributionPoints", &c2);
2465
0
  if (result != ASN1_SUCCESS) {
2466
0
    gnutls_assert();
2467
0
    return _gnutls_asn2err(result);
2468
0
  }
2469
2470
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
2471
2472
0
  if (result != ASN1_SUCCESS) {
2473
0
    gnutls_assert();
2474
0
    ret = _gnutls_asn2err(result);
2475
0
    goto cleanup;
2476
0
  }
2477
2478
  /* Return the different names from the first CRLDistr. point.
2479
   * The whole thing is a mess.
2480
   */
2481
2482
0
  i = 0;
2483
0
  do {
2484
0
    snprintf(name, sizeof(name), "?%u.reasons", (unsigned)i + 1);
2485
2486
0
    len = sizeof(reasons);
2487
0
    result = asn1_read_value(c2, name, reasons, &len);
2488
2489
0
    if (result != ASN1_VALUE_NOT_FOUND &&
2490
0
        result != ASN1_ELEMENT_NOT_FOUND &&
2491
0
        result != ASN1_SUCCESS) {
2492
0
      gnutls_assert();
2493
0
      ret = _gnutls_asn2err(result);
2494
0
      break;
2495
0
    }
2496
2497
0
    if (result == ASN1_VALUE_NOT_FOUND
2498
0
        || result == ASN1_ELEMENT_NOT_FOUND)
2499
0
      rflags = 0;
2500
0
    else
2501
0
      rflags = reasons[0] | (reasons[1] << 8);
2502
2503
0
    snprintf(name, sizeof(name),
2504
0
       "?%u.distributionPoint.fullName", (unsigned)i + 1);
2505
2506
0
    for (j = 0;; j++) {
2507
0
      san.data = NULL;
2508
0
      san.size = 0;
2509
2510
0
      ret =
2511
0
          _gnutls_parse_general_name2(c2, name, j, &san,
2512
0
              &type, 0);
2513
0
      if (j > 0
2514
0
          && ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2515
0
        ret = 0;
2516
0
        break;
2517
0
      }
2518
0
      if (ret < 0)
2519
0
        break;
2520
2521
0
      ret = crl_dist_points_set(cdp, type, &san, rflags);
2522
0
      if (ret < 0)
2523
0
        break;
2524
0
      san.data = NULL;  /* it is now in cdp */
2525
0
    }
2526
2527
0
    i++;
2528
0
  } while (ret >= 0);
2529
2530
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2531
0
    gnutls_assert();
2532
0
    gnutls_free(san.data);
2533
0
    goto cleanup;
2534
0
  }
2535
2536
0
  ret = 0;
2537
0
 cleanup:
2538
0
  asn1_delete_structure(&c2);
2539
0
  return ret;
2540
0
}
2541
2542
/**
2543
 * gnutls_x509_ext_export_crl_dist_points:
2544
 * @cdp: A pointer to an initialized CRL distribution points.
2545
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2546
 *
2547
 * This function will convert the provided policies, to a certificate policy
2548
 * DER encoded extension (2.5.29.31).
2549
 *
2550
 * The @ext data will be allocated using gnutls_malloc().
2551
 *
2552
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2553
 *
2554
 * Since: 3.3.0
2555
 **/
2556
int gnutls_x509_ext_export_crl_dist_points(gnutls_x509_crl_dist_points_t cdp,
2557
             gnutls_datum_t * ext)
2558
0
{
2559
0
  asn1_node c2 = NULL;
2560
0
  int result;
2561
0
  uint8_t reasons[2];
2562
0
  unsigned i;
2563
2564
0
  result =
2565
0
      asn1_create_element(_gnutls_get_pkix(),
2566
0
        "PKIX1.CRLDistributionPoints", &c2);
2567
0
  if (result != ASN1_SUCCESS) {
2568
0
    gnutls_assert();
2569
0
    result = _gnutls_asn2err(result);
2570
0
    goto cleanup;
2571
0
  }
2572
2573
0
  for (i = 0; i < cdp->size; i++) {
2574
2575
0
    if (i == 0
2576
0
        || cdp->points[i].reasons != cdp->points[i - 1].reasons) {
2577
0
      result = asn1_write_value(c2, "", "NEW", 1);
2578
0
      if (result != ASN1_SUCCESS) {
2579
0
        gnutls_assert();
2580
0
        result = _gnutls_asn2err(result);
2581
0
        goto cleanup;
2582
0
      }
2583
2584
0
      if (cdp->points[i].reasons) {
2585
0
        reasons[0] = cdp->points[i].reasons & 0xff;
2586
0
        reasons[1] = cdp->points[i].reasons >> 8;
2587
2588
0
        result =
2589
0
            asn1_write_value(c2, "?LAST.reasons",
2590
0
                 reasons, 2);
2591
0
      } else {
2592
0
        result =
2593
0
            asn1_write_value(c2, "?LAST.reasons", NULL,
2594
0
                 0);
2595
0
      }
2596
2597
0
      if (result != ASN1_SUCCESS) {
2598
0
        gnutls_assert();
2599
0
        result = _gnutls_asn2err(result);
2600
0
        goto cleanup;
2601
0
      }
2602
2603
0
      result =
2604
0
          asn1_write_value(c2, "?LAST.cRLIssuer", NULL, 0);
2605
0
      if (result != ASN1_SUCCESS) {
2606
0
        gnutls_assert();
2607
0
        result = _gnutls_asn2err(result);
2608
0
        goto cleanup;
2609
0
      }
2610
      /* When used as type CHOICE.
2611
       */
2612
0
      result =
2613
0
          asn1_write_value(c2, "?LAST.distributionPoint",
2614
0
               "fullName", 1);
2615
0
      if (result != ASN1_SUCCESS) {
2616
0
        gnutls_assert();
2617
0
        result = _gnutls_asn2err(result);
2618
0
        goto cleanup;
2619
0
      }
2620
0
    }
2621
2622
0
    result =
2623
0
        _gnutls_write_new_general_name(c2,
2624
0
               "?LAST.distributionPoint.fullName",
2625
0
               cdp->points[i].type,
2626
0
               cdp->points[i].san.data,
2627
0
               cdp->points[i].san.size);
2628
0
    if (result < 0) {
2629
0
      gnutls_assert();
2630
0
      goto cleanup;
2631
0
    }
2632
0
  }
2633
2634
0
  result = _gnutls_x509_der_encode(c2, "", ext, 0);
2635
0
  if (result < 0) {
2636
0
    gnutls_assert();
2637
0
    goto cleanup;
2638
0
  }
2639
2640
0
  result = 0;
2641
2642
0
 cleanup:
2643
0
  asn1_delete_structure(&c2);
2644
2645
0
  return result;
2646
2647
0
}
2648
2649
struct gnutls_x509_aia_st {
2650
  struct {
2651
    gnutls_datum_t oid;
2652
    unsigned int san_type;
2653
    gnutls_datum_t san;
2654
  } *aia;
2655
  unsigned int size;
2656
};
2657
2658
/**
2659
 * gnutls_x509_aia_init:
2660
 * @aia: The authority info access
2661
 *
2662
 * This function will initialize an authority info access type.
2663
 *
2664
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2665
 *
2666
 * Since: 3.3.0
2667
 **/
2668
int gnutls_x509_aia_init(gnutls_x509_aia_t * aia)
2669
0
{
2670
0
  *aia = gnutls_calloc(1, sizeof(struct gnutls_x509_aia_st));
2671
0
  if (*aia == NULL)
2672
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2673
2674
0
  return 0;
2675
0
}
2676
2677
/**
2678
 * gnutls_x509_aia_deinit:
2679
 * @aia: The authority info access
2680
 *
2681
 * This function will deinitialize an authority info access type.
2682
 *
2683
 * Since: 3.3.0
2684
 **/
2685
void gnutls_x509_aia_deinit(gnutls_x509_aia_t aia)
2686
0
{
2687
0
  unsigned i;
2688
2689
0
  for (i = 0; i < aia->size; i++) {
2690
0
    gnutls_free(aia->aia[i].san.data);
2691
0
    gnutls_free(aia->aia[i].oid.data);
2692
0
  }
2693
0
  gnutls_free(aia->aia);
2694
0
  gnutls_free(aia);
2695
0
}
2696
2697
/**
2698
 * gnutls_x509_aia_get:
2699
 * @aia: The authority info access
2700
 * @seq: specifies the sequence number of the access descriptor (0 for the first one, 1 for the second etc.)
2701
 * @oid: the type of available data; to be treated as constant.
2702
 * @san_type: Will hold the type of the name of %gnutls_subject_alt_names_t (may be null).
2703
 * @san: the access location name; to be treated as constant (may be null).
2704
 *
2705
 * This function reads from the Authority Information Access type.
2706
 *
2707
 * The @seq input parameter is used to indicate which member of the
2708
 * sequence the caller is interested in.  The first member is 0, the
2709
 * second member 1 and so on.  When the @seq value is out of bounds,
2710
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
2711
 *
2712
 * Typically @oid is %GNUTLS_OID_AD_CAISSUERS or %GNUTLS_OID_AD_OCSP.
2713
 *
2714
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2715
 *
2716
 * Since: 3.3.0
2717
 **/
2718
int gnutls_x509_aia_get(gnutls_x509_aia_t aia, unsigned int seq,
2719
      gnutls_datum_t * oid,
2720
      unsigned *san_type, gnutls_datum_t * san)
2721
0
{
2722
0
  if (seq >= aia->size)
2723
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
2724
2725
0
  if (san_type)
2726
0
    *san_type = aia->aia[seq].san_type;
2727
0
  if (san) {
2728
0
    san->data = aia->aia[seq].san.data;
2729
0
    san->size = aia->aia[seq].san.size;
2730
0
  }
2731
2732
0
  if (oid) {
2733
0
    oid->data = aia->aia[seq].oid.data;
2734
0
    oid->size = aia->aia[seq].oid.size;
2735
0
  }
2736
2737
0
  return 0;
2738
0
}
2739
2740
int _gnutls_alt_name_process(gnutls_datum_t * out, unsigned type,
2741
           const gnutls_datum_t * san, unsigned raw)
2742
0
{
2743
0
  int ret;
2744
0
  if (type == GNUTLS_SAN_DNSNAME && !raw) {
2745
0
    ret = gnutls_idna_map((char *)san->data, san->size, out, 0);
2746
0
    if (ret < 0) {
2747
0
      return gnutls_assert_val(ret);
2748
0
    }
2749
0
  } else if (type == GNUTLS_SAN_RFC822NAME && !raw) {
2750
0
    ret = _gnutls_idna_email_map((char *)san->data, san->size, out);
2751
0
    if (ret < 0) {
2752
0
      return gnutls_assert_val(ret);
2753
0
    }
2754
0
  } else if (type == GNUTLS_SAN_URI && !raw) {
2755
0
    if (!_gnutls_str_is_print((char *)san->data, san->size)) {
2756
0
      _gnutls_debug_log("non-ASCII URIs are not supported\n");
2757
0
      return
2758
0
          gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
2759
0
    } else {
2760
0
      ret = _gnutls_set_strdatum(out, san->data, san->size);
2761
0
      if (ret < 0)
2762
0
        return gnutls_assert_val(ret);
2763
0
    }
2764
0
  } else {
2765
0
    ret = _gnutls_set_strdatum(out, san->data, san->size);
2766
0
    if (ret < 0)
2767
0
      return gnutls_assert_val(ret);
2768
0
  }
2769
2770
0
  return 0;
2771
0
}
2772
2773
/**
2774
 * gnutls_x509_aia_set:
2775
 * @aia: The authority info access
2776
 * @oid: the type of data.
2777
 * @san_type: The type of the name (of %gnutls_subject_alt_names_t)
2778
 * @san: The alternative name data
2779
 * @othername_oid: The object identifier if @san_type is %GNUTLS_SAN_OTHERNAME
2780
 *
2781
 * This function will store the specified alternative name in
2782
 * the @aia type. 
2783
 *
2784
 * Typically the value for @oid should be %GNUTLS_OID_AD_OCSP, or
2785
 * %GNUTLS_OID_AD_CAISSUERS.
2786
 *
2787
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, and %GNUTLS_SAN_DNSNAME,
2788
 * are converted to ACE format when necessary.
2789
 *
2790
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
2791
 *
2792
 * Since: 3.3.0
2793
 **/
2794
int gnutls_x509_aia_set(gnutls_x509_aia_t aia,
2795
      const char *oid,
2796
      unsigned san_type, const gnutls_datum_t * san)
2797
0
{
2798
0
  int ret;
2799
0
  void *tmp;
2800
0
  unsigned indx;
2801
2802
0
  if (unlikely(INT_ADD_OVERFLOW(aia->size, 1))) {
2803
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2804
0
  }
2805
2806
0
  tmp =
2807
0
      _gnutls_reallocarray(aia->aia, aia->size + 1, sizeof(aia->aia[0]));
2808
0
  if (tmp == NULL) {
2809
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2810
0
  }
2811
0
  aia->aia = tmp;
2812
0
  indx = aia->size;
2813
2814
0
  aia->aia[indx].san_type = san_type;
2815
0
  if (oid) {
2816
0
    aia->aia[indx].oid.data = (void *)gnutls_strdup(oid);
2817
0
    aia->aia[indx].oid.size = strlen(oid);
2818
0
  } else {
2819
0
    aia->aia[indx].oid.data = NULL;
2820
0
    aia->aia[indx].oid.size = 0;
2821
0
  }
2822
2823
0
  ret = _gnutls_alt_name_process(&aia->aia[indx].san, san_type, san, 0);
2824
0
  if (ret < 0)
2825
0
    return gnutls_assert_val(ret);
2826
2827
0
  aia->size++;
2828
2829
0
  return 0;
2830
0
}
2831
2832
static int parse_aia(asn1_node c2, gnutls_x509_aia_t aia)
2833
0
{
2834
0
  int len;
2835
0
  char nptr[MAX_NAME_SIZE];
2836
0
  int ret, result;
2837
0
  char tmpoid[MAX_OID_SIZE];
2838
0
  void *tmp;
2839
0
  unsigned i, indx;
2840
2841
0
  for (i = 1;; i++) {
2842
0
    snprintf(nptr, sizeof(nptr), "?%u.accessMethod", i);
2843
2844
0
    len = sizeof(tmpoid);
2845
0
    result = asn1_read_value(c2, nptr, tmpoid, &len);
2846
0
    if (result == ASN1_VALUE_NOT_FOUND
2847
0
        || result == ASN1_ELEMENT_NOT_FOUND) {
2848
0
      ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2849
0
      break;
2850
0
    }
2851
2852
0
    if (result != ASN1_SUCCESS) {
2853
0
      gnutls_assert();
2854
0
      return _gnutls_asn2err(result);
2855
0
    }
2856
2857
0
    indx = aia->size;
2858
0
    if (unlikely(INT_ADD_OVERFLOW(aia->size, 1))) {
2859
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2860
0
    }
2861
0
    tmp = _gnutls_reallocarray(aia->aia, aia->size + 1,
2862
0
             sizeof(aia->aia[0]));
2863
0
    if (tmp == NULL) {
2864
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2865
0
    }
2866
0
    aia->aia = tmp;
2867
2868
0
    snprintf(nptr, sizeof(nptr), "?%u.accessLocation", i);
2869
2870
0
    ret =
2871
0
        _gnutls_parse_general_name2(c2, nptr, -1,
2872
0
            &aia->aia[indx].san,
2873
0
            &aia->aia[indx].san_type, 0);
2874
0
    if (ret < 0)
2875
0
      break;
2876
2877
    /* we do the strdup after parsing to avoid a memory leak */
2878
0
    aia->aia[indx].oid.data = (void *)gnutls_strdup(tmpoid);
2879
0
    aia->aia[indx].oid.size = strlen(tmpoid);
2880
2881
0
    aia->size++;
2882
2883
0
    if (aia->aia[indx].oid.data == NULL) {
2884
0
      gnutls_assert();
2885
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
2886
0
    }
2887
0
  }
2888
2889
0
  assert(ret < 0);
2890
0
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
2891
0
    return ret;
2892
0
  }
2893
2894
0
  return 0;
2895
0
}
2896
2897
/**
2898
 * gnutls_x509_ext_import_aia:
2899
 * @ext: The DER-encoded extension data
2900
 * @aia: The authority info access
2901
 * @flags: should be zero
2902
 *
2903
 * This function extracts the Authority Information Access (AIA)
2904
 * extension from the provided DER-encoded data; see RFC 5280 section 4.2.2.1 
2905
 * for more information on the extension.  The
2906
 * AIA extension holds a sequence of AccessDescription (AD) data.
2907
 *
2908
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
2909
 *
2910
 * Since: 3.3.0
2911
 **/
2912
int gnutls_x509_ext_import_aia(const gnutls_datum_t * ext,
2913
             gnutls_x509_aia_t aia, unsigned int flags)
2914
0
{
2915
0
  int ret;
2916
0
  asn1_node c2 = NULL;
2917
2918
0
  if (ext->size == 0 || ext->data == NULL) {
2919
0
    gnutls_assert();
2920
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2921
0
  }
2922
2923
0
  ret = asn1_create_element(_gnutls_get_pkix(),
2924
0
          "PKIX1.AuthorityInfoAccessSyntax", &c2);
2925
0
  if (ret != ASN1_SUCCESS) {
2926
0
    gnutls_assert();
2927
0
    return _gnutls_asn2err(ret);
2928
0
  }
2929
2930
0
  ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
2931
0
  if (ret != ASN1_SUCCESS) {
2932
0
    gnutls_assert();
2933
0
    ret = _gnutls_asn2err(ret);
2934
0
    goto cleanup;
2935
0
  }
2936
2937
0
  ret = parse_aia(c2, aia);
2938
0
  if (ret < 0) {
2939
0
    gnutls_assert();
2940
0
  }
2941
2942
0
 cleanup:
2943
0
  asn1_delete_structure(&c2);
2944
2945
0
  return ret;
2946
2947
0
}
2948
2949
/**
2950
 * gnutls_x509_ext_export_aia:
2951
 * @aia: The authority info access
2952
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
2953
 *
2954
 * This function will DER encode the Authority Information Access (AIA)
2955
 * extension; see RFC 5280 section 4.2.2.1 for more information on the
2956
 * extension.  
2957
 *
2958
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2959
 *   negative error value.
2960
 *
2961
 * Since: 3.3.0
2962
 **/
2963
int gnutls_x509_ext_export_aia(gnutls_x509_aia_t aia, gnutls_datum_t * ext)
2964
0
{
2965
0
  int ret, result;
2966
0
  asn1_node c2 = NULL;
2967
0
  unsigned int i;
2968
2969
0
  ret = asn1_create_element(_gnutls_get_pkix(),
2970
0
          "PKIX1.AuthorityInfoAccessSyntax", &c2);
2971
0
  if (ret != ASN1_SUCCESS) {
2972
0
    gnutls_assert();
2973
0
    return _gnutls_asn2err(ret);
2974
0
  }
2975
2976
  /* 1. create a new element.
2977
   */
2978
0
  for (i = 0; i < aia->size; i++) {
2979
0
    result = asn1_write_value(c2, "", "NEW", 1);
2980
0
    if (result != ASN1_SUCCESS) {
2981
0
      gnutls_assert();
2982
0
      ret = _gnutls_asn2err(result);
2983
0
      goto cleanup;
2984
0
    }
2985
2986
    /* 2. Add the OID.
2987
     */
2988
0
    result =
2989
0
        asn1_write_value(c2, "?LAST.accessMethod",
2990
0
             aia->aia[i].oid.data, 1);
2991
0
    if (result != ASN1_SUCCESS) {
2992
0
      gnutls_assert();
2993
0
      ret = _gnutls_asn2err(result);
2994
0
      goto cleanup;
2995
0
    }
2996
2997
0
    ret =
2998
0
        _gnutls_write_general_name(c2,
2999
0
                 "?LAST.accessLocation",
3000
0
                 aia->aia[i].san_type,
3001
0
                 aia->aia[i].san.data,
3002
0
                 aia->aia[i].san.size);
3003
0
    if (ret < 0) {
3004
0
      gnutls_assert();
3005
0
      goto cleanup;
3006
0
    }
3007
0
  }
3008
3009
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
3010
0
  if (ret < 0) {
3011
0
    gnutls_assert();
3012
0
    goto cleanup;
3013
0
  }
3014
3015
0
 cleanup:
3016
0
  asn1_delete_structure(&c2);
3017
3018
0
  return ret;
3019
0
}
3020
3021
struct gnutls_x509_key_purposes_st {
3022
  gnutls_datum_t oid[MAX_ENTRIES];
3023
  unsigned int size;
3024
};
3025
3026
/**
3027
 * gnutls_subject_alt_names_init:
3028
 * @p: The key purposes
3029
 *
3030
 * This function will initialize an alternative names type.
3031
 *
3032
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3033
 *
3034
 * Since: 3.3.0
3035
 **/
3036
int gnutls_x509_key_purpose_init(gnutls_x509_key_purposes_t * p)
3037
0
{
3038
0
  *p = gnutls_calloc(1, sizeof(struct gnutls_x509_key_purposes_st));
3039
0
  if (*p == NULL) {
3040
0
    gnutls_assert();
3041
0
    return GNUTLS_E_MEMORY_ERROR;
3042
0
  }
3043
3044
0
  return 0;
3045
0
}
3046
3047
static void key_purposes_deinit(gnutls_x509_key_purposes_t p)
3048
0
{
3049
0
  unsigned int i;
3050
3051
0
  for (i = 0; i < p->size; i++) {
3052
0
    gnutls_free(p->oid[i].data);
3053
0
  }
3054
0
}
3055
3056
/**
3057
 * gnutls_x509_key_purpose_deinit:
3058
 * @p: The key purposes
3059
 *
3060
 * This function will deinitialize a key purposes type.
3061
 *
3062
 * Since: 3.3.0
3063
 **/
3064
void gnutls_x509_key_purpose_deinit(gnutls_x509_key_purposes_t p)
3065
0
{
3066
0
  key_purposes_deinit(p);
3067
0
  gnutls_free(p);
3068
0
}
3069
3070
/**
3071
 * gnutls_x509_key_purpose_set:
3072
 * @p: The key purposes
3073
 * @oid: The object identifier of the key purpose
3074
 *
3075
 * This function will store the specified key purpose in the
3076
 * purposes.
3077
 *
3078
 * Returns: On success, %GNUTLS_E_SUCCESS (0), otherwise a negative error value.
3079
 *
3080
 * Since: 3.3.0
3081
 **/
3082
int gnutls_x509_key_purpose_set(gnutls_x509_key_purposes_t p, const char *oid)
3083
0
{
3084
0
  if (p->size + 1 > MAX_ENTRIES)
3085
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3086
3087
0
  p->oid[p->size].data = (void *)gnutls_strdup(oid);
3088
0
  if (p->oid[p->size].data == NULL)
3089
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3090
3091
0
  p->oid[p->size].size = strlen(oid);
3092
0
  p->size++;
3093
3094
0
  return 0;
3095
0
}
3096
3097
/**
3098
 * gnutls_x509_key_purpose_get:
3099
 * @p: The key purposes
3100
 * @idx: The index of the key purpose to retrieve
3101
 * @oid: Will hold the object identifier of the key purpose (to be treated as constant)
3102
 *
3103
 * This function will retrieve the specified by the index key purpose in the
3104
 * purposes type. The object identifier will be a null terminated string.
3105
 *
3106
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
3107
 * if the index is out of bounds, otherwise a negative error value.
3108
 *
3109
 * Since: 3.3.0
3110
 **/
3111
int gnutls_x509_key_purpose_get(gnutls_x509_key_purposes_t p, unsigned idx,
3112
        gnutls_datum_t * oid)
3113
0
{
3114
0
  if (idx >= p->size)
3115
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
3116
3117
0
  oid->data = p->oid[idx].data;
3118
0
  oid->size = p->oid[idx].size;
3119
3120
0
  return 0;
3121
0
}
3122
3123
/**
3124
 * gnutls_x509_ext_import_key_purposes:
3125
 * @ext: The DER-encoded extension data
3126
 * @p: The key purposes
3127
 * @flags: should be zero
3128
 *
3129
 * This function will extract the key purposes in the provided DER-encoded
3130
 * ExtKeyUsageSyntax PKIX extension, to a %gnutls_x509_key_purposes_t type. 
3131
 * The data must be initialized.
3132
 * 
3133
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3134
 *
3135
 * Since: 3.3.0
3136
 **/
3137
int gnutls_x509_ext_import_key_purposes(const gnutls_datum_t * ext,
3138
          gnutls_x509_key_purposes_t p,
3139
          unsigned int flags)
3140
0
{
3141
0
  char tmpstr[MAX_NAME_SIZE];
3142
0
  int result, ret;
3143
0
  asn1_node c2 = NULL;
3144
0
  gnutls_datum_t oid = { NULL, 0 };
3145
0
  unsigned i;
3146
3147
0
  result = asn1_create_element
3148
0
      (_gnutls_get_pkix(), "PKIX1.ExtKeyUsageSyntax", &c2);
3149
0
  if (result != ASN1_SUCCESS) {
3150
0
    gnutls_assert();
3151
0
    return _gnutls_asn2err(result);
3152
0
  }
3153
3154
0
  result = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
3155
0
  if (result != ASN1_SUCCESS) {
3156
0
    gnutls_assert();
3157
0
    ret = _gnutls_asn2err(result);
3158
0
    goto cleanup;
3159
0
  }
3160
3161
0
  key_purposes_deinit(p);
3162
0
  i = 0;
3163
0
  p->size = 0;
3164
3165
0
  for (; i < MAX_ENTRIES; i++) {
3166
    /* create a string like "?1"
3167
     */
3168
0
    snprintf(tmpstr, sizeof(tmpstr), "?%u", i + 1);
3169
3170
0
    ret = _gnutls_x509_read_value(c2, tmpstr, &oid);
3171
0
    if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
3172
0
      break;
3173
0
    }
3174
3175
0
    if (ret < 0) {
3176
0
      gnutls_assert();
3177
0
      goto cleanup;
3178
0
    }
3179
3180
0
    p->oid[i].data = oid.data;
3181
0
    p->oid[i].size = oid.size;
3182
3183
0
    oid.data = NULL;
3184
0
    oid.size = 0;
3185
0
    p->size++;
3186
0
  }
3187
3188
0
  ret = 0;
3189
0
 cleanup:
3190
0
  gnutls_free(oid.data);
3191
0
  asn1_delete_structure(&c2);
3192
3193
0
  return ret;
3194
3195
0
}
3196
3197
/**
3198
 * gnutls_x509_ext_export_key_purposes:
3199
 * @p: The key purposes
3200
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
3201
 *
3202
 * This function will convert the key purposes type to a
3203
 * DER-encoded PKIX ExtKeyUsageSyntax (2.5.29.37) extension. The output data in 
3204
 * @ext will be allocated using gnutls_malloc().
3205
 *
3206
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3207
 *
3208
 * Since: 3.3.0
3209
 **/
3210
int gnutls_x509_ext_export_key_purposes(gnutls_x509_key_purposes_t p,
3211
          gnutls_datum_t * ext)
3212
0
{
3213
0
  int result, ret;
3214
0
  asn1_node c2 = NULL;
3215
0
  unsigned i;
3216
3217
0
  result = asn1_create_element
3218
0
      (_gnutls_get_pkix(), "PKIX1.ExtKeyUsageSyntax", &c2);
3219
0
  if (result != ASN1_SUCCESS) {
3220
0
    gnutls_assert();
3221
0
    return _gnutls_asn2err(result);
3222
0
  }
3223
3224
  /* generate the extension.
3225
   */
3226
0
  for (i = 0; i < p->size; i++) {
3227
    /* 1. create a new element.
3228
     */
3229
0
    result = asn1_write_value(c2, "", "NEW", 1);
3230
0
    if (result != ASN1_SUCCESS) {
3231
0
      gnutls_assert();
3232
0
      ret = _gnutls_asn2err(result);
3233
0
      goto cleanup;
3234
0
    }
3235
3236
    /* 2. Add the OID.
3237
     */
3238
0
    result = asn1_write_value(c2, "?LAST", p->oid[i].data, 1);
3239
0
    if (result != ASN1_SUCCESS) {
3240
0
      gnutls_assert();
3241
0
      ret = _gnutls_asn2err(result);
3242
0
      goto cleanup;
3243
0
    }
3244
0
  }
3245
3246
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
3247
0
  if (ret < 0) {
3248
0
    gnutls_assert();
3249
0
    goto cleanup;
3250
0
  }
3251
3252
0
  ret = 0;
3253
3254
0
 cleanup:
3255
0
  asn1_delete_structure(&c2);
3256
0
  return ret;
3257
0
}
3258
3259
/**
3260
 * gnutls_ext_deinit:
3261
 * @ext: The extensions structure
3262
 *
3263
 * This function will deinitialize an extensions structure.
3264
 *
3265
 * Since: 3.3.8
3266
 **/
3267
void gnutls_x509_ext_deinit(gnutls_x509_ext_st * ext)
3268
0
{
3269
0
  gnutls_free(ext->oid);
3270
0
  gnutls_free(ext->data.data);
3271
0
}
3272
3273
int _gnutls_x509_decode_ext(const gnutls_datum_t * der,
3274
          gnutls_x509_ext_st * out)
3275
0
{
3276
0
  asn1_node c2 = NULL;
3277
0
  char str_critical[10];
3278
0
  char oid[MAX_OID_SIZE];
3279
0
  int result, len, ret;
3280
3281
0
  memset(out, 0, sizeof(*out));
3282
3283
  /* decode der */
3284
0
  result =
3285
0
      asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extension", &c2);
3286
0
  if (result != ASN1_SUCCESS) {
3287
0
    gnutls_assert();
3288
0
    return _gnutls_asn2err(result);
3289
0
  }
3290
3291
0
  result = _asn1_strict_der_decode(&c2, der->data, der->size, NULL);
3292
0
  if (result != ASN1_SUCCESS) {
3293
0
    gnutls_assert();
3294
0
    ret = _gnutls_asn2err(result);
3295
0
    goto cleanup;
3296
0
  }
3297
3298
0
  len = sizeof(oid) - 1;
3299
0
  result = asn1_read_value(c2, "extnID", oid, &len);
3300
0
  if (result != ASN1_SUCCESS) {
3301
0
    gnutls_assert();
3302
0
    ret = _gnutls_asn2err(result);
3303
0
    goto cleanup;
3304
0
  }
3305
3306
0
  len = sizeof(str_critical) - 1;
3307
0
  result = asn1_read_value(c2, "critical", str_critical, &len);
3308
0
  if (result != ASN1_SUCCESS) {
3309
0
    gnutls_assert();
3310
0
    ret = _gnutls_asn2err(result);
3311
0
    goto cleanup;
3312
0
  }
3313
3314
0
  if (str_critical[0] == 'T')
3315
0
    out->critical = 1;
3316
0
  else
3317
0
    out->critical = 0;
3318
3319
0
  ret = _gnutls_x509_read_value(c2, "extnValue", &out->data);
3320
0
  if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
3321
0
      || ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
3322
0
    out->data.data = NULL;
3323
0
    out->data.size = 0;
3324
0
  } else if (ret < 0) {
3325
0
    gnutls_assert();
3326
0
    goto fail;
3327
0
  }
3328
3329
0
  out->oid = gnutls_strdup(oid);
3330
0
  if (out->oid == NULL) {
3331
0
    ret = GNUTLS_E_MEMORY_ERROR;
3332
0
    goto fail;
3333
0
  }
3334
3335
0
  ret = 0;
3336
0
  goto cleanup;
3337
0
 fail:
3338
0
  memset(out, 0, sizeof(*out));
3339
0
 cleanup:
3340
0
  asn1_delete_structure(&c2);
3341
0
  return ret;
3342
3343
0
}
3344
3345
/* flags can be zero or GNUTLS_EXT_FLAG_APPEND
3346
 */
3347
static int parse_tlsfeatures(asn1_node c2, gnutls_x509_tlsfeatures_t f,
3348
           unsigned flags)
3349
0
{
3350
0
  char nptr[MAX_NAME_SIZE];
3351
0
  int result;
3352
0
  unsigned i, indx, j;
3353
0
  unsigned int feature;
3354
3355
0
  if (!(flags & GNUTLS_EXT_FLAG_APPEND))
3356
0
    f->size = 0;
3357
3358
0
  for (i = 1;; i++) {
3359
0
    unsigned skip = 0;
3360
0
    snprintf(nptr, sizeof(nptr), "?%u", i);
3361
3362
0
    result = _gnutls_x509_read_uint(c2, nptr, &feature);
3363
3364
0
    if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND
3365
0
        || result == GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
3366
0
      break;
3367
0
    } else if (result != GNUTLS_E_SUCCESS) {
3368
0
      gnutls_assert();
3369
0
      return _gnutls_asn2err(result);
3370
0
    }
3371
3372
0
    if (feature > UINT16_MAX) {
3373
0
      gnutls_assert();
3374
0
      return GNUTLS_E_CERTIFICATE_ERROR;
3375
0
    }
3376
3377
    /* skip duplicates */
3378
0
    for (j = 0; j < f->size; j++) {
3379
0
      if (f->feature[j] == feature) {
3380
0
        skip = 1;
3381
0
        break;
3382
0
      }
3383
0
    }
3384
3385
0
    if (!skip) {
3386
0
      if (f->size >=
3387
0
          sizeof(f->feature) / sizeof(f->feature[0])) {
3388
0
        gnutls_assert();
3389
0
        return GNUTLS_E_INTERNAL_ERROR;
3390
0
      }
3391
3392
0
      indx = f->size;
3393
0
      f->feature[indx] = feature;
3394
0
      f->size++;
3395
0
    }
3396
0
  }
3397
3398
0
  return 0;
3399
0
}
3400
3401
/**
3402
 * gnutls_x509_ext_import_tlsfeatures:
3403
 * @ext: The DER-encoded extension data
3404
 * @f: The features structure
3405
 * @flags: zero or %GNUTLS_EXT_FLAG_APPEND
3406
 *
3407
 * This function will export the features in the provided DER-encoded
3408
 * TLS Features PKIX extension, to a %gnutls_x509_tlsfeatures_t type. @f
3409
 * must be initialized.
3410
 *
3411
 * When the @flags is set to %GNUTLS_EXT_FLAG_APPEND,
3412
 * then if the @features structure is empty this function will behave
3413
 * identically as if the flag was not set. Otherwise if there are elements 
3414
 * in the @features structure then they will be merged with.
3415
 *
3416
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3417
 *
3418
 * Since: 3.5.1
3419
 **/
3420
int gnutls_x509_ext_import_tlsfeatures(const gnutls_datum_t * ext,
3421
               gnutls_x509_tlsfeatures_t f,
3422
               unsigned int flags)
3423
0
{
3424
0
  int ret;
3425
0
  asn1_node c2 = NULL;
3426
3427
0
  if (ext->size == 0 || ext->data == NULL) {
3428
0
    gnutls_assert();
3429
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3430
0
  }
3431
3432
0
  ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.TlsFeatures", &c2);
3433
0
  if (ret != ASN1_SUCCESS) {
3434
0
    gnutls_assert();
3435
0
    return _gnutls_asn2err(ret);
3436
0
  }
3437
3438
0
  ret = _asn1_strict_der_decode(&c2, ext->data, ext->size, NULL);
3439
0
  if (ret != ASN1_SUCCESS) {
3440
0
    gnutls_assert();
3441
0
    ret = _gnutls_asn2err(ret);
3442
0
    goto cleanup;
3443
0
  }
3444
3445
0
  ret = parse_tlsfeatures(c2, f, flags);
3446
0
  if (ret < 0) {
3447
0
    gnutls_assert();
3448
0
  }
3449
3450
0
 cleanup:
3451
0
  asn1_delete_structure(&c2);
3452
3453
0
  return ret;
3454
0
}
3455
3456
/**
3457
 * gnutls_x509_ext_export_tlsfeatures:
3458
 * @f: The features structure
3459
 * @ext: The DER-encoded extension data; must be freed using gnutls_free().
3460
 *
3461
 * This function will convert the provided TLS features structure structure to a
3462
 * DER-encoded TLS features PKIX extension. The output data in @ext will be allocated using
3463
 * gnutls_malloc().
3464
 *
3465
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
3466
 *
3467
 * Since: 3.5.1
3468
 **/
3469
int gnutls_x509_ext_export_tlsfeatures(gnutls_x509_tlsfeatures_t f,
3470
               gnutls_datum_t * ext)
3471
0
{
3472
0
  if (f == NULL) {
3473
0
    gnutls_assert();
3474
0
    return GNUTLS_E_INVALID_REQUEST;
3475
0
  }
3476
3477
0
  asn1_node c2 = NULL;
3478
0
  int ret;
3479
0
  unsigned i;
3480
3481
0
  ret = asn1_create_element(_gnutls_get_pkix(), "PKIX1.TlsFeatures", &c2);
3482
0
  if (ret != ASN1_SUCCESS) {
3483
0
    gnutls_assert();
3484
0
    return _gnutls_asn2err(ret);
3485
0
  }
3486
3487
0
  for (i = 0; i < f->size; ++i) {
3488
3489
0
    ret = asn1_write_value(c2, "", "NEW", 1);
3490
0
    if (ret != ASN1_SUCCESS) {
3491
0
      gnutls_assert();
3492
0
      ret = _gnutls_asn2err(ret);
3493
0
      goto cleanup;
3494
0
    }
3495
3496
0
    ret = _gnutls_x509_write_uint32(c2, "?LAST", f->feature[i]);
3497
0
    if (ret != GNUTLS_E_SUCCESS) {
3498
0
      gnutls_assert();
3499
0
      goto cleanup;
3500
0
    }
3501
0
  }
3502
3503
0
  ret = _gnutls_x509_der_encode(c2, "", ext, 0);
3504
0
  if (ret < 0) {
3505
0
    gnutls_assert();
3506
0
    goto cleanup;
3507
0
  }
3508
3509
0
  ret = 0;
3510
3511
0
 cleanup:
3512
0
  asn1_delete_structure(&c2);
3513
0
  return ret;
3514
0
}
3515
3516
/**
3517
 * gnutls_x509_tlsfeatures_add:
3518
 * @f: The TLS features
3519
 * @feature: The feature to add
3520
 *
3521
 * This function will append a feature to the X.509 TLS features
3522
 * extension structure.
3523
 *
3524
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
3525
 *   otherwise a negative error value.
3526
 *
3527
 * Since: 3.5.1
3528
 **/
3529
int gnutls_x509_tlsfeatures_add(gnutls_x509_tlsfeatures_t f,
3530
        unsigned int feature)
3531
0
{
3532
0
  if (f == NULL) {
3533
0
    gnutls_assert();
3534
0
    return GNUTLS_E_INVALID_REQUEST;
3535
0
  }
3536
3537
0
  if (feature > UINT16_MAX)
3538
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3539
3540
0
  if (f->size >= sizeof(f->feature) / sizeof(f->feature[0]))
3541
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
3542
3543
0
  f->feature[f->size++] = feature;
3544
3545
0
  return 0;
3546
0
}
3547
3548
0
#define SCT_V1_LOGID_SIZE 32
3549
struct ct_sct_st {
3550
  int version;
3551
  uint8_t logid[SCT_V1_LOGID_SIZE];
3552
  uint64_t timestamp;
3553
  gnutls_sign_algorithm_t sigalg;
3554
  gnutls_datum_t signature;
3555
};
3556
3557
struct gnutls_x509_ct_scts_st {
3558
  struct ct_sct_st *scts;
3559
  size_t size;
3560
};
3561
3562
static void _gnutls_free_scts(struct gnutls_x509_ct_scts_st *scts)
3563
0
{
3564
0
  for (size_t i = 0; i < scts->size; i++)
3565
0
    _gnutls_free_datum(&scts->scts[i].signature);
3566
0
  gnutls_free(scts->scts);
3567
0
  scts->size = 0;
3568
0
}
3569
3570
/**
3571
 * gnutls_x509_ext_ct_scts_init:
3572
 * @scts: The SCT list
3573
 *
3574
 * This function will initialize a Certificate Transparency SCT list.
3575
 *
3576
 * Returns: %GNUTLS_E_SUCCESS (0) on success, otherwise a negative error value.
3577
 **/
3578
int gnutls_x509_ext_ct_scts_init(gnutls_x509_ct_scts_t * scts)
3579
0
{
3580
0
  *scts = gnutls_calloc(1, sizeof(struct gnutls_x509_ct_scts_st));
3581
0
  if (*scts == NULL)
3582
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3583
0
  return 0;
3584
0
}
3585
3586
/**
3587
 * gnutls_x509_ext_ct_scts_deinit:
3588
 * @scts: The SCT list
3589
 *
3590
 * This function will deinitialize a Certificate Transparency SCT list.
3591
 **/
3592
void gnutls_x509_ext_ct_scts_deinit(gnutls_x509_ct_scts_t scts)
3593
0
{
3594
0
  _gnutls_free_scts(scts);
3595
0
  gnutls_free(scts);
3596
0
}
3597
3598
struct sct_sign_algorithm_st {
3599
  uint8_t codepoint[2];
3600
  gnutls_sign_algorithm_t sign_algo;
3601
};
3602
3603
static const struct sct_sign_algorithm_st algos[] = {
3604
  {
3605
   .codepoint = {0x01, 0x01},
3606
   .sign_algo = GNUTLS_SIGN_RSA_MD5},
3607
  {
3608
   .codepoint = {0x02, 0x01},
3609
   .sign_algo = GNUTLS_SIGN_RSA_SHA1},
3610
  {
3611
   .codepoint = {0x03, 0x01},
3612
   .sign_algo = GNUTLS_SIGN_RSA_SHA224},
3613
  {
3614
   .codepoint = {0x04, 0x01},
3615
   .sign_algo = GNUTLS_SIGN_RSA_SHA256},
3616
  {
3617
   .codepoint = {0x05, 0x01},
3618
   .sign_algo = GNUTLS_SIGN_RSA_SHA384},
3619
  {
3620
   .codepoint = {0x06, 0x01},
3621
   .sign_algo = GNUTLS_SIGN_RSA_SHA512,
3622
   },
3623
  {
3624
   .codepoint = {0x02, 0x02},
3625
   .sign_algo = GNUTLS_SIGN_DSA_SHA1},
3626
  {
3627
   .codepoint = {0x03, 0x02},
3628
   .sign_algo = GNUTLS_SIGN_DSA_SHA224},
3629
  {
3630
   .codepoint = {0x04, 0x02},
3631
   .sign_algo = GNUTLS_SIGN_DSA_SHA256},
3632
  {
3633
   .codepoint = {0x05, 0x02},
3634
   .sign_algo = GNUTLS_SIGN_DSA_SHA384},
3635
  {
3636
   .codepoint = {0x06, 0x02},
3637
   .sign_algo = GNUTLS_SIGN_DSA_SHA512,
3638
   },
3639
  {
3640
   .codepoint = {0x02, 0x03},
3641
   .sign_algo = GNUTLS_SIGN_ECDSA_SHA1},
3642
  {
3643
   .codepoint = {0x03, 0x03},
3644
   .sign_algo = GNUTLS_SIGN_ECDSA_SHA224},
3645
  {
3646
   .codepoint = {0x04, 0x03},
3647
   .sign_algo = GNUTLS_SIGN_ECDSA_SHA256},
3648
  {
3649
   .codepoint = {0x05, 0x03},
3650
   .sign_algo = GNUTLS_SIGN_ECDSA_SHA384},
3651
  {
3652
   .codepoint = {0x06, 0x03},
3653
   .sign_algo = GNUTLS_SIGN_ECDSA_SHA512,
3654
   }
3655
};
3656
3657
static gnutls_sign_algorithm_t get_sigalg(uint8_t hash_algo, uint8_t sig_algo)
3658
0
{
3659
0
  const struct sct_sign_algorithm_st *algo;
3660
0
  size_t i, num_algos = sizeof(algos) / sizeof(algos[0]);
3661
3662
0
  if (hash_algo == 0 || sig_algo == 0)
3663
0
    return GNUTLS_SIGN_UNKNOWN;
3664
3665
0
  for (i = 0; i < num_algos; i++) {
3666
0
    algo = &algos[i];
3667
0
    if (algo->codepoint[0] == hash_algo
3668
0
        && algo->codepoint[1] == sig_algo)
3669
0
      break;
3670
0
  }
3671
3672
0
  if (i == num_algos)
3673
0
    return GNUTLS_SIGN_UNKNOWN;
3674
3675
0
  return algo->sign_algo;
3676
0
}
3677
3678
static int write_sigalg(gnutls_sign_algorithm_t sigalg, uint8_t out[])
3679
0
{
3680
0
  const struct sct_sign_algorithm_st *algo;
3681
0
  size_t i, num_algos = sizeof(algos) / sizeof(algos[0]);
3682
3683
0
  for (i = 0; i < num_algos; i++) {
3684
0
    algo = &algos[i];
3685
0
    if (algo->sign_algo == sigalg)
3686
0
      break;
3687
0
  }
3688
3689
0
  if (i == num_algos)
3690
0
    return GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
3691
3692
0
  out[0] = algo->codepoint[0];
3693
0
  out[1] = algo->codepoint[1];
3694
0
  return 0;
3695
0
}
3696
3697
static int _gnutls_parse_ct_sct(uint8_t * ptr, uint16_t length,
3698
        struct ct_sct_st *sct)
3699
0
{
3700
0
  uint16_t sig_length;
3701
0
  uint8_t hash_algo, sig_algo;
3702
3703
0
  sct->signature.size = 0;
3704
0
  sct->signature.data = NULL;
3705
3706
0
  DECR_LENGTH_RET(length, 1, GNUTLS_E_PREMATURE_TERMINATION);
3707
0
  sct->version = (int)*ptr;
3708
0
  ptr++;
3709
3710
  /* LogID
3711
   * In version 1, it has a fixed length of 32 bytes.
3712
   */
3713
0
  DECR_LENGTH_RET(length, SCT_V1_LOGID_SIZE,
3714
0
      GNUTLS_E_PREMATURE_TERMINATION);
3715
0
  memcpy(sct->logid, ptr, SCT_V1_LOGID_SIZE);
3716
0
  ptr += SCT_V1_LOGID_SIZE;
3717
3718
  /* Timestamp */
3719
0
  DECR_LENGTH_RET(length, sizeof(uint64_t),
3720
0
      GNUTLS_E_PREMATURE_TERMINATION);
3721
0
  sct->timestamp = (uint64_t) _gnutls_read_uint64(ptr);
3722
0
  ptr += sizeof(uint64_t);
3723
3724
  /*
3725
   * There are no extensions defined in SCT v1.
3726
   * Check that there are actually no extensions - the following two bytes should be zero.
3727
   */
3728
0
  DECR_LENGTH_RET(length, 2, GNUTLS_E_PREMATURE_TERMINATION);
3729
0
  if (*ptr != 0 || *(ptr + 1) != 0)
3730
0
    return gnutls_assert_val(GNUTLS_E_UNEXPECTED_EXTENSIONS_LENGTH);
3731
0
  ptr += 2;
3732
3733
  /*
3734
   * Hash and signature algorithms, modeled after
3735
   * SignatureAndHashAlgorithm structure, as defined in
3736
   * RFC 5246, section 7.4.1.4.1.
3737
   * We take both values separately (hash and signature),
3738
   * and return them as a gnutls_sign_algorithm_t enum value.
3739
   */
3740
0
  DECR_LENGTH_RET(length, 2, GNUTLS_E_PREMATURE_TERMINATION);
3741
0
  hash_algo = *ptr++;
3742
0
  sig_algo = *ptr++;
3743
3744
0
  sct->sigalg = get_sigalg(hash_algo, sig_algo);
3745
0
  if (sct->sigalg == GNUTLS_SIGN_UNKNOWN)
3746
0
    return
3747
0
        gnutls_assert_val(GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM);
3748
3749
  /* Signature, length and content */
3750
0
  DECR_LENGTH_RET(length, sizeof(uint16_t),
3751
0
      GNUTLS_E_PREMATURE_TERMINATION);
3752
0
  sig_length = _gnutls_read_uint16(ptr);
3753
0
  ptr += sizeof(uint16_t);
3754
0
  if (sig_length == 0)
3755
0
    return gnutls_assert_val(GNUTLS_E_PREMATURE_TERMINATION);
3756
3757
  /* Remaining length should be sig_length at this point.
3758
   * If not, that means there is more data than what the length field said it was,
3759
   * and hence we must treat this as an error. */
3760
0
  if (length != sig_length)
3761
0
    return gnutls_assert_val(GNUTLS_E_ASN1_DER_OVERFLOW);
3762
3763
0
  if (_gnutls_set_datum(&sct->signature, ptr, sig_length) < 0)
3764
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3765
3766
0
  return 0;
3767
0
}
3768
3769
static int _gnutls_ct_sct_add(struct ct_sct_st *sct,
3770
            struct ct_sct_st **scts, size_t *size)
3771
0
{
3772
0
  struct ct_sct_st *new_scts;
3773
3774
0
  new_scts =
3775
0
      _gnutls_reallocarray(*scts, *size + 1, sizeof(struct ct_sct_st));
3776
0
  if (new_scts == NULL)
3777
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
3778
3779
0
  memcpy(&new_scts[*size], sct, sizeof(struct ct_sct_st));
3780
0
  (*size)++;
3781
0
  *scts = new_scts;
3782
3783
0
  return 0;
3784
0
}
3785
3786
static int _gnutls_export_ct_v1_sct(gnutls_buffer_st * buf,
3787
            const struct ct_sct_st *sct)
3788
0
{
3789
0
  int ret;
3790
0
  uint8_t tstamp_out[8], sigalg[2];
3791
  /* There are no extensions defined for v1 */
3792
0
  const uint8_t extensions[2] = { 0x00, 0x00 };
3793
0
  size_t length_offset;
3794
3795
  /* Length field; filled later */
3796
0
  length_offset = buf->length;
3797
0
  if ((ret = _gnutls_buffer_append_prefix(buf, 16, 0)) < 0)
3798
0
    return gnutls_assert_val(ret);
3799
3800
  /* Version */
3801
0
  if ((ret = _gnutls_buffer_append_data(buf,
3802
0
                &sct->version,
3803
0
                sizeof(uint8_t))) < 0)
3804
0
    return gnutls_assert_val(ret);
3805
3806
  /* Log ID - has a fixed 32-byte size in version 1 */
3807
0
  if ((ret = _gnutls_buffer_append_data(buf,
3808
0
                sct->logid,
3809
0
                SCT_V1_LOGID_SIZE)) < 0)
3810
0
    return gnutls_assert_val(ret);
3811
3812
  /* Timestamp */
3813
0
  _gnutls_write_uint64(sct->timestamp, tstamp_out);
3814
0
  if ((ret = _gnutls_buffer_append_data(buf,
3815
0
                tstamp_out,
3816
0
                sizeof(tstamp_out))) < 0)
3817
0
    return gnutls_assert_val(ret);
3818
3819
  /* Extensions */
3820
0
  if ((ret = _gnutls_buffer_append_data(buf,
3821
0
                extensions,
3822
0
                sizeof(extensions))) < 0)
3823
0
    return gnutls_assert_val(ret);
3824
3825
  /* Hash and signature algorithms */
3826
0
  if ((ret = write_sigalg(sct->sigalg, sigalg)) < 0)
3827
0
    return gnutls_assert_val(ret);
3828
3829
0
  if ((ret = _gnutls_buffer_append_data(buf, sigalg, sizeof(sigalg))) < 0)
3830
0
    return gnutls_assert_val(ret);
3831
3832
  /* Signature */
3833
0
  if ((ret = _gnutls_buffer_append_data_prefix(buf, 16,
3834
0
                 sct->signature.data,
3835
0
                 sct->signature.size)) < 0)
3836
0
    return gnutls_assert_val(ret);
3837
3838
  /* Fill the length */
3839
0
  _gnutls_write_uint16(buf->length - length_offset - 2,
3840
0
           buf->data + length_offset);
3841
3842
0
  return 0;
3843
0
}
3844
3845
/**
3846
 * gnutls_x509_ext_ct_import_scts:
3847
 * @ext: a DER-encoded extension
3848
 * @scts: The SCT list
3849
 * @flags: should be zero
3850
 *
3851
 * This function will read a SignedCertificateTimestampList structure
3852
 * from the DER data of the X.509 Certificate Transparency SCT extension
3853
 * (OID 1.3.6.1.4.1.11129.2.4.2).
3854
 *
3855
 * The list of SCTs (Signed Certificate Timestamps) is placed on @scts,
3856
 * which must be previously initialized with gnutls_x509_ext_ct_scts_init().
3857
 *
3858
 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error value.
3859
 **/
3860
int gnutls_x509_ext_ct_import_scts(const gnutls_datum_t * ext,
3861
           gnutls_x509_ct_scts_t scts,
3862
           unsigned int flags)
3863
0
{
3864
0
  int retval;
3865
0
  uint8_t *ptr;
3866
0
  uint16_t length, sct_length;
3867
0
  struct ct_sct_st sct;
3868
0
  gnutls_datum_t scts_content;
3869
3870
0
  if (flags != 0)
3871
0
    return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
3872
3873
0
  retval =
3874
0
      _gnutls_x509_decode_string(ASN1_ETYPE_OCTET_STRING,
3875
0
               ext->data, ext->size, &scts_content, 0);
3876
0
  if (retval < 0)
3877
0
    return gnutls_assert_val(retval);
3878
3879
0
  if (scts_content.size < 2) {
3880
0
    gnutls_free(scts_content.data);
3881
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3882
0
  }
3883
3884
0
  length = _gnutls_read_uint16(scts_content.data);
3885
0
  if (length < 4) {
3886
0
    gnutls_free(scts_content.data);
3887
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3888
0
  }
3889
3890
0
  ptr = &scts_content.data[2];
3891
0
  while (length > 0) {
3892
0
    if (length < 2)
3893
0
      break;
3894
3895
0
    sct_length = _gnutls_read_uint16(ptr);
3896
0
    if (sct_length == 0 || sct_length > length)
3897
0
      break;
3898
3899
0
    ptr += sizeof(uint16_t);
3900
0
    length -= sizeof(uint16_t);
3901
3902
    /*
3903
     * _gnutls_parse_ct_sct() will try to read exactly sct_length bytes,
3904
     * returning an error if it can't
3905
     */
3906
0
    if (_gnutls_parse_ct_sct(ptr, sct_length, &sct) < 0)
3907
0
      break;
3908
0
    if (_gnutls_ct_sct_add(&sct, &scts->scts, &scts->size) < 0)
3909
0
      break;
3910
3911
0
    ptr += sct_length;
3912
0
    length -= sct_length;
3913
0
  }
3914
3915
0
  _gnutls_free_datum(&scts_content);
3916
3917
0
  if (length > 0) {
3918
0
    gnutls_assert();
3919
0
    _gnutls_free_scts(scts);
3920
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3921
0
  }
3922
3923
0
  return GNUTLS_E_SUCCESS;
3924
0
}
3925
3926
/**
3927
 * gnutls_x509_ext_ct_export_scts:
3928
 * @scts: An initialized SCT list
3929
 * @ext: The DER-encoded extension data; must be freed with gnutls_free()
3930
 *
3931
 * This function will convert the provided list of SCTs to a DER-encoded
3932
 * SignedCertificateTimestampList extension (1.3.6.1.4.1.11129.2.4.2).
3933
 * The output data in @ext will be allocated using gnutls_malloc().
3934
 *
3935
 * Returns: %GNUTLS_E_SUCCESS (0) on success or a negative error value.
3936
 **/
3937
int gnutls_x509_ext_ct_export_scts(const gnutls_x509_ct_scts_t scts,
3938
           gnutls_datum_t * ext)
3939
0
{
3940
0
  int ret;
3941
0
  gnutls_buffer_st buf;
3942
3943
0
  _gnutls_buffer_init(&buf);
3944
3945
  /* Start with the length of the whole string; the actual
3946
   * length is filled later */
3947
0
  _gnutls_buffer_append_prefix(&buf, 16, 0);
3948
3949
0
  for (size_t i = 0; i < scts->size; i++) {
3950
0
    if ((ret = _gnutls_export_ct_v1_sct(&buf, &scts->scts[i])) < 0) {
3951
0
      gnutls_assert();
3952
0
      goto cleanup;
3953
0
    }
3954
0
  }
3955
3956
  /* Fill the length */
3957
0
  _gnutls_write_uint16(buf.length - 2, buf.data);
3958
3959
  /* DER-encode the whole thing as an opaque OCTET STRING, as the spec mandates */
3960
0
  ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
3961
0
           buf.data, buf.length, ext);
3962
0
  if (ret < 0) {
3963
0
    gnutls_assert();
3964
0
    goto cleanup;
3965
0
  }
3966
3967
0
  ret = GNUTLS_E_SUCCESS;
3968
3969
0
 cleanup:
3970
0
  _gnutls_buffer_clear(&buf);
3971
0
  return ret;
3972
0
}
3973
3974
/**
3975
 * gnutls_x509_ct_sct_get_version:
3976
 * @scts: A list of SCTs
3977
 * @idx: The index of the target SCT in the list
3978
 * @version_out: The version of the target SCT.
3979
 *
3980
 * This function obtains the version of the SCT at the given position
3981
 * in the SCT list.
3982
 *
3983
 * The version of that SCT will be placed on @version_out.
3984
 *
3985
 * Return : %GNUTLS_E_SUCCESS (0) is returned on success,
3986
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if @idx exceeds the number of SCTs in the list
3987
 *   and %GNUTLS_E_INVALID_REQUEST if the SCT's version is different than 1, as that's currently
3988
 *   the only defined version.
3989
 **/
3990
int gnutls_x509_ct_sct_get_version(gnutls_x509_ct_scts_t scts, unsigned idx,
3991
           unsigned int *version_out)
3992
0
{
3993
0
  int version;
3994
3995
0
  if (idx >= scts->size)
3996
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
3997
3998
  /*
3999
   * Currently, only version 1 SCTs are defined (RFC 6962).
4000
   * A version 1 SCT has actually the value 0 in the 'version' field.
4001
   */
4002
0
  version = scts->scts[idx].version;
4003
0
  if (version != 0 || version_out == NULL)
4004
0
    return GNUTLS_E_INVALID_REQUEST;
4005
4006
0
  *version_out = 1;
4007
0
  return GNUTLS_E_SUCCESS;
4008
0
}
4009
4010
/**
4011
 * gnutls_x509_ct_sct_get:
4012
 * @scts: A list of SCTs
4013
 * @idx: The index of the target SCT in the list
4014
 * @timestamp: The timestamp of the SCT
4015
 * @logid: The LogID field of the SCT; must be freed with gnutls_free()
4016
 * @sigalg: The signature algorithm
4017
 * @signature: The signature of the SCT; must be freed with gnutls_free()
4018
 *
4019
 * This function will return a specific SCT (Signed Certificate Timestamp)
4020
 * stored in the SCT list @scts.
4021
 *
4022
 * The datums holding the SCT's LogId and signature will be allocated
4023
 * using gnutls_malloc().
4024
 *
4025
 * Returns: %GNUTLS_E_SUCCESS (0) will be returned on success,
4026
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE if @idx exceeds the number of SCTs in the list
4027
 * or a negative error value.
4028
 **/
4029
int gnutls_x509_ct_sct_get(const gnutls_x509_ct_scts_t scts, unsigned idx,
4030
         time_t * timestamp,
4031
         gnutls_datum_t * logid,
4032
         gnutls_sign_algorithm_t * sigalg,
4033
         gnutls_datum_t * signature)
4034
0
{
4035
0
  int retval = 0;
4036
0
  struct ct_sct_st *sct;
4037
4038
0
  if (idx >= scts->size)
4039
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
4040
4041
0
  sct = &scts->scts[idx];
4042
0
  if (sct->version != 0)
4043
0
    return GNUTLS_E_INVALID_REQUEST;
4044
4045
0
  if (signature) {
4046
0
    retval = _gnutls_set_datum(signature,
4047
0
             sct->signature.data,
4048
0
             sct->signature.size);
4049
0
    if (retval < 0)
4050
0
      return retval;
4051
0
  }
4052
4053
0
  if (logid) {
4054
0
    retval = _gnutls_set_datum(logid,
4055
0
             sct->logid, SCT_V1_LOGID_SIZE);
4056
0
    if (retval < 0) {
4057
0
      _gnutls_free_datum(signature);
4058
0
      return retval;
4059
0
    }
4060
0
  }
4061
4062
0
  if (timestamp)
4063
0
    *timestamp = sct->timestamp / 1000;
4064
4065
0
  if (sigalg)
4066
0
    *sigalg = sct->sigalg;
4067
4068
0
  return GNUTLS_E_SUCCESS;
4069
0
}