Coverage Report

Created: 2025-03-18 06:55

/src/gnutls/lib/x509/x509_write.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2003-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2016-2017 Red Hat, Inc.
4
 *
5
 * Author: Nikos Mavrogiannopoulos
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
/* This file contains functions to handle X.509 certificate generation.
25
 */
26
27
#include "gnutls_int.h"
28
29
#include "datum.h"
30
#include "global.h"
31
#include "errors.h"
32
#include "common.h"
33
#include "x509.h"
34
#include <gnutls/x509-ext.h>
35
#include "x509_b64.h"
36
#include "x509_int.h"
37
#include <libtasn1.h>
38
#include "pk.h"
39
40
static void disable_optional_stuff(gnutls_x509_crt_t cert);
41
42
/**
43
 * gnutls_x509_crt_set_dn_by_oid:
44
 * @crt: a certificate of type #gnutls_x509_crt_t
45
 * @oid: holds an Object Identifier in a null terminated string
46
 * @raw_flag: must be 0, or 1 if the data are DER encoded
47
 * @name: a pointer to the name
48
 * @sizeof_name: holds the size of @name
49
 *
50
 * This function will set the part of the name of the Certificate
51
 * subject, specified by the given OID. The input string should be
52
 * ASCII or UTF-8 encoded.
53
 *
54
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
55
 * With this function you can only set the known OIDs. You can test
56
 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
57
 * not known (by gnutls) you should properly DER encode your data,
58
 * and call this function with @raw_flag set.
59
 *
60
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
61
 *   negative error value.
62
 **/
63
int gnutls_x509_crt_set_dn_by_oid(gnutls_x509_crt_t crt, const char *oid,
64
          unsigned int raw_flag, const void *name,
65
          unsigned int sizeof_name)
66
0
{
67
0
  if (sizeof_name == 0 || name == NULL || crt == NULL) {
68
0
    return GNUTLS_E_INVALID_REQUEST;
69
0
  }
70
71
0
  MODIFIED(crt);
72
73
0
  return _gnutls_x509_set_dn_oid(crt->cert, "tbsCertificate.subject", oid,
74
0
               raw_flag, name, sizeof_name);
75
0
}
76
77
/**
78
 * gnutls_x509_crt_set_issuer_dn_by_oid:
79
 * @crt: a certificate of type #gnutls_x509_crt_t
80
 * @oid: holds an Object Identifier in a null terminated string
81
 * @raw_flag: must be 0, or 1 if the data are DER encoded
82
 * @name: a pointer to the name
83
 * @sizeof_name: holds the size of @name
84
 *
85
 * This function will set the part of the name of the Certificate
86
 * issuer, specified by the given OID.  The input string should be
87
 * ASCII or UTF-8 encoded.
88
 *
89
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
90
 * With this function you can only set the known OIDs. You can test
91
 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
92
 * not known (by gnutls) you should properly DER encode your data,
93
 * and call this function with @raw_flag set.
94
 *
95
 * Normally you do not need to call this function, since the signing
96
 * operation will copy the signer's name as the issuer of the
97
 * certificate.
98
 *
99
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
100
 *   negative error value.
101
 **/
102
int gnutls_x509_crt_set_issuer_dn_by_oid(gnutls_x509_crt_t crt, const char *oid,
103
           unsigned int raw_flag,
104
           const void *name,
105
           unsigned int sizeof_name)
106
0
{
107
0
  if (sizeof_name == 0 || name == NULL || crt == NULL) {
108
0
    return GNUTLS_E_INVALID_REQUEST;
109
0
  }
110
111
0
  MODIFIED(crt);
112
113
0
  return _gnutls_x509_set_dn_oid(crt->cert, "tbsCertificate.issuer", oid,
114
0
               raw_flag, name, sizeof_name);
115
0
}
116
117
/**
118
 * gnutls_x509_crt_set_proxy_dn:
119
 * @crt: a gnutls_x509_crt_t type with the new proxy cert
120
 * @eecrt: the end entity certificate that will be issuing the proxy
121
 * @raw_flag: must be 0, or 1 if the CN is DER encoded
122
 * @name: a pointer to the CN name, may be NULL (but MUST then be added later)
123
 * @sizeof_name: holds the size of @name
124
 *
125
 * This function will set the subject in @crt to the end entity's
126
 * @eecrt subject name, and add a single Common Name component @name
127
 * of size @sizeof_name.  This corresponds to the required proxy
128
 * certificate naming style.  Note that if @name is %NULL, you MUST
129
 * set it later by using gnutls_x509_crt_set_dn_by_oid() or similar.
130
 *
131
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
132
 *   negative error value.
133
 **/
134
int gnutls_x509_crt_set_proxy_dn(gnutls_x509_crt_t crt, gnutls_x509_crt_t eecrt,
135
         unsigned int raw_flag, const void *name,
136
         unsigned int sizeof_name)
137
0
{
138
0
  int result;
139
140
0
  if (crt == NULL || eecrt == NULL) {
141
0
    return GNUTLS_E_INVALID_REQUEST;
142
0
  }
143
144
0
  MODIFIED(crt);
145
146
0
  result = asn1_copy_node(crt->cert, "tbsCertificate.subject",
147
0
        eecrt->cert, "tbsCertificate.subject");
148
0
  if (result != ASN1_SUCCESS) {
149
0
    gnutls_assert();
150
0
    return _gnutls_asn2err(result);
151
0
  }
152
153
0
  if (name && sizeof_name) {
154
0
    return _gnutls_x509_set_dn_oid(crt->cert,
155
0
                 "tbsCertificate.subject",
156
0
                 GNUTLS_OID_X520_COMMON_NAME,
157
0
                 raw_flag, name, sizeof_name);
158
0
  }
159
160
0
  return 0;
161
0
}
162
163
/**
164
 * gnutls_x509_crt_set_version:
165
 * @crt: a certificate of type #gnutls_x509_crt_t
166
 * @version: holds the version number. For X.509v1 certificates must be 1.
167
 *
168
 * This function will set the version of the certificate.  This must
169
 * be one for X.509 version 1, and so on.  Plain certificates without
170
 * extensions must have version set to one.
171
 *
172
 * To create well-formed certificates, you must specify version 3 if
173
 * you use any certificate extensions.  Extensions are created by
174
 * functions such as gnutls_x509_crt_set_subject_alt_name()
175
 * or gnutls_x509_crt_set_key_usage().
176
 *
177
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
178
 *   negative error value.
179
 **/
180
int gnutls_x509_crt_set_version(gnutls_x509_crt_t crt, unsigned int version)
181
0
{
182
0
  int result;
183
0
  unsigned char null = version;
184
185
0
  if (crt == NULL || version == 0 || version >= 0x80) {
186
0
    gnutls_assert();
187
0
    return GNUTLS_E_INVALID_REQUEST;
188
0
  }
189
190
0
  MODIFIED(crt);
191
192
0
  if (null > 0)
193
0
    null--;
194
195
0
  result =
196
0
    asn1_write_value(crt->cert, "tbsCertificate.version", &null, 1);
197
0
  if (result != ASN1_SUCCESS) {
198
0
    gnutls_assert();
199
0
    return _gnutls_asn2err(result);
200
0
  }
201
202
0
  return 0;
203
0
}
204
205
/**
206
 * gnutls_x509_crt_set_key:
207
 * @crt: a certificate of type #gnutls_x509_crt_t
208
 * @key: holds a private key
209
 *
210
 * This function will set the public parameters from the given
211
 * private key to the certificate.
212
 *
213
 * To export the public key (i.e., the SubjectPublicKeyInfo part), check
214
 * gnutls_pubkey_import_x509().
215
 *
216
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
217
 *   negative error value.
218
 *
219
 **/
220
int gnutls_x509_crt_set_key(gnutls_x509_crt_t crt, gnutls_x509_privkey_t key)
221
0
{
222
0
  int result;
223
224
0
  if (crt == NULL) {
225
0
    gnutls_assert();
226
0
    return GNUTLS_E_INVALID_REQUEST;
227
0
  }
228
229
0
  MODIFIED(crt);
230
231
0
  result = _gnutls_x509_encode_and_copy_PKI_params(
232
0
    crt->cert, "tbsCertificate.subjectPublicKeyInfo", &key->params);
233
234
0
  if (result < 0) {
235
0
    gnutls_assert();
236
0
    return result;
237
0
  }
238
239
0
  return 0;
240
0
}
241
242
/**
243
 * gnutls_x509_crt_set_crq:
244
 * @crt: a certificate of type #gnutls_x509_crt_t
245
 * @crq: holds a certificate request
246
 *
247
 * This function will set the name and public parameters as well as
248
 * the extensions from the given certificate request to the certificate. 
249
 * Only RSA keys are currently supported.
250
 *
251
 * Note that this function will only set the @crq if it is self
252
 * signed and the signature is correct. See gnutls_x509_crq_sign2().
253
 *
254
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
255
 *   negative error value.
256
 **/
257
int gnutls_x509_crt_set_crq(gnutls_x509_crt_t crt, gnutls_x509_crq_t crq)
258
0
{
259
0
  int result;
260
261
0
  if (crt == NULL || crq == NULL) {
262
0
    gnutls_assert();
263
0
    return GNUTLS_E_INVALID_REQUEST;
264
0
  }
265
266
0
  MODIFIED(crt);
267
268
0
  result = gnutls_x509_crq_verify(crq, 0);
269
0
  if (result < 0)
270
0
    return gnutls_assert_val(result);
271
272
0
  result = asn1_copy_node(crt->cert, "tbsCertificate.subject", crq->crq,
273
0
        "certificationRequestInfo.subject");
274
0
  if (result != ASN1_SUCCESS) {
275
0
    gnutls_assert();
276
0
    return _gnutls_asn2err(result);
277
0
  }
278
279
0
  result = asn1_copy_node(crt->cert,
280
0
        "tbsCertificate.subjectPublicKeyInfo", crq->crq,
281
0
        "certificationRequestInfo.subjectPKInfo");
282
0
  if (result != ASN1_SUCCESS) {
283
0
    gnutls_assert();
284
0
    return _gnutls_asn2err(result);
285
0
  }
286
287
0
  return 0;
288
0
}
289
290
/**
291
 * gnutls_x509_crt_set_crq_extensions:
292
 * @crt: a certificate of type #gnutls_x509_crt_t
293
 * @crq: holds a certificate request
294
 *
295
 * This function will set the extensions from the given request to the
296
 * certificate.
297
 *
298
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
299
 *   negative error value.
300
 *
301
 * Since: 2.8.0
302
 **/
303
int gnutls_x509_crt_set_crq_extensions(gnutls_x509_crt_t crt,
304
               gnutls_x509_crq_t crq)
305
0
{
306
0
  return gnutls_x509_crt_set_crq_extension_by_oid(crt, crq, NULL, 0);
307
0
}
308
309
/**
310
 * gnutls_x509_crt_set_crq_extension_by_oid:
311
 * @crt: a certificate of type #gnutls_x509_crt_t
312
 * @crq: holds a certificate request
313
 * @oid: the object identifier of the OID to copy
314
 * @flags: should be zero
315
 *
316
 * This function will set the extension specify by @oid from the given request to the
317
 * certificate.
318
 *
319
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
320
 *   negative error value.
321
 *
322
 * Since: 3.5.1
323
 **/
324
int gnutls_x509_crt_set_crq_extension_by_oid(gnutls_x509_crt_t crt,
325
               gnutls_x509_crq_t crq,
326
               const char *oid, unsigned flags)
327
0
{
328
0
  size_t i;
329
330
0
  if (crt == NULL || crq == NULL) {
331
0
    gnutls_assert();
332
0
    return GNUTLS_E_INVALID_REQUEST;
333
0
  }
334
335
0
  MODIFIED(crt);
336
337
0
  for (i = 0;; i++) {
338
0
    int result;
339
0
    char local_oid[MAX_OID_SIZE];
340
0
    size_t local_oid_size;
341
0
    uint8_t *extensions;
342
0
    size_t extensions_size;
343
0
    unsigned int critical;
344
0
    gnutls_datum_t ext;
345
346
0
    local_oid_size = sizeof(local_oid);
347
0
    result = gnutls_x509_crq_get_extension_info(
348
0
      crq, i, local_oid, &local_oid_size, &critical);
349
0
    if (result < 0) {
350
0
      if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
351
0
        break;
352
353
0
      gnutls_assert();
354
0
      return result;
355
0
    }
356
357
0
    if (oid && strcmp(local_oid, oid) != 0)
358
0
      continue;
359
360
0
    extensions_size = 0;
361
0
    result = gnutls_x509_crq_get_extension_data(crq, i, NULL,
362
0
                  &extensions_size);
363
0
    if (result < 0) {
364
0
      gnutls_assert();
365
0
      return result;
366
0
    }
367
368
0
    extensions = gnutls_malloc(extensions_size);
369
0
    if (extensions == NULL) {
370
0
      gnutls_assert();
371
0
      return GNUTLS_E_MEMORY_ERROR;
372
0
    }
373
374
0
    result = gnutls_x509_crq_get_extension_data(crq, i, extensions,
375
0
                  &extensions_size);
376
0
    if (result < 0) {
377
0
      gnutls_assert();
378
0
      gnutls_free(extensions);
379
0
      return result;
380
0
    }
381
382
0
    ext.data = extensions;
383
0
    ext.size = extensions_size;
384
385
0
    result = _gnutls_x509_crt_set_extension(crt, local_oid, &ext,
386
0
              critical);
387
0
    gnutls_free(extensions);
388
0
    if (result < 0) {
389
0
      gnutls_assert();
390
0
      return result;
391
0
    }
392
0
  }
393
394
0
  return 0;
395
0
}
396
397
/**
398
 * gnutls_x509_crt_set_extension_by_oid:
399
 * @crt: a certificate of type #gnutls_x509_crt_t
400
 * @oid: holds an Object Identifier in null terminated string
401
 * @buf: a pointer to a DER encoded data
402
 * @sizeof_buf: holds the size of @buf
403
 * @critical: should be non-zero if the extension is to be marked as critical
404
 *
405
 * This function will set an the extension, by the specified OID, in
406
 * the certificate.  The extension data should be binary data DER
407
 * encoded.
408
 *
409
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
410
 *   negative error value.
411
 **/
412
int gnutls_x509_crt_set_extension_by_oid(gnutls_x509_crt_t crt, const char *oid,
413
           const void *buf, size_t sizeof_buf,
414
           unsigned int critical)
415
0
{
416
0
  int result;
417
0
  gnutls_datum_t der_data;
418
419
0
  der_data.data = (void *)buf;
420
0
  der_data.size = sizeof_buf;
421
422
0
  if (crt == NULL) {
423
0
    gnutls_assert();
424
0
    return GNUTLS_E_INVALID_REQUEST;
425
0
  }
426
427
0
  result = _gnutls_x509_crt_set_extension(crt, oid, &der_data, critical);
428
0
  if (result < 0) {
429
0
    gnutls_assert();
430
0
    return result;
431
0
  }
432
433
0
  return 0;
434
0
}
435
436
/**
437
 * gnutls_x509_crt_set_basic_constraints:
438
 * @crt: a certificate of type #gnutls_x509_crt_t
439
 * @ca: true(1) or false(0). Depending on the Certificate authority status.
440
 * @pathLenConstraint: non-negative error codes indicate maximum length of path,
441
 *   and negative error codes indicate that the pathLenConstraints field should
442
 *   not be present.
443
 *
444
 * This function will set the basicConstraints certificate extension.
445
 *
446
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
447
 *   negative error value.
448
 **/
449
int gnutls_x509_crt_set_basic_constraints(gnutls_x509_crt_t crt,
450
            unsigned int ca,
451
            int pathLenConstraint)
452
0
{
453
0
  int result;
454
0
  gnutls_datum_t der_data;
455
456
0
  if (crt == NULL) {
457
0
    gnutls_assert();
458
0
    return GNUTLS_E_INVALID_REQUEST;
459
0
  }
460
461
  /* generate the extension.
462
   */
463
0
  result = gnutls_x509_ext_export_basic_constraints(ca, pathLenConstraint,
464
0
                &der_data);
465
0
  if (result < 0) {
466
0
    gnutls_assert();
467
0
    return result;
468
0
  }
469
470
0
  result = _gnutls_x509_crt_set_extension(crt, "2.5.29.19", &der_data, 1);
471
472
0
  _gnutls_free_datum(&der_data);
473
474
0
  if (result < 0) {
475
0
    gnutls_assert();
476
0
    return result;
477
0
  }
478
479
0
  return 0;
480
0
}
481
482
/**
483
 * gnutls_x509_crt_set_ca_status:
484
 * @crt: a certificate of type #gnutls_x509_crt_t
485
 * @ca: true(1) or false(0). Depending on the Certificate authority status.
486
 *
487
 * This function will set the basicConstraints certificate extension.
488
 * Use gnutls_x509_crt_set_basic_constraints() if you want to control
489
 * the pathLenConstraint field too.
490
 *
491
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
492
 *   negative error value.
493
 **/
494
int gnutls_x509_crt_set_ca_status(gnutls_x509_crt_t crt, unsigned int ca)
495
0
{
496
0
  return gnutls_x509_crt_set_basic_constraints(crt, ca, -1);
497
0
}
498
499
/**
500
 * gnutls_x509_crt_set_key_usage:
501
 * @crt: a certificate of type #gnutls_x509_crt_t
502
 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
503
 *
504
 * This function will set the keyUsage certificate extension.
505
 *
506
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
507
 *   negative error value.
508
 **/
509
int gnutls_x509_crt_set_key_usage(gnutls_x509_crt_t crt, unsigned int usage)
510
0
{
511
0
  int result;
512
0
  gnutls_datum_t der_data;
513
514
0
  if (crt == NULL) {
515
0
    gnutls_assert();
516
0
    return GNUTLS_E_INVALID_REQUEST;
517
0
  }
518
519
  /* generate the extension.
520
   */
521
0
  result = gnutls_x509_ext_export_key_usage(usage, &der_data);
522
0
  if (result < 0) {
523
0
    gnutls_assert();
524
0
    return result;
525
0
  }
526
527
0
  result = _gnutls_x509_crt_set_extension(crt, "2.5.29.15", &der_data, 1);
528
529
0
  _gnutls_free_datum(&der_data);
530
531
0
  if (result < 0) {
532
0
    gnutls_assert();
533
0
    return result;
534
0
  }
535
536
0
  return 0;
537
0
}
538
539
/**
540
 * gnutls_x509_crt_set_inhibit_anypolicy:
541
 * @crt: a certificate of type #gnutls_x509_crt_t
542
 * @skipcerts: number of certificates after which anypolicy is no longer acceptable.
543
 *
544
 * This function will set the Inhibit anyPolicy certificate extension.
545
 *
546
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
547
 *   negative error value.
548
 **/
549
int gnutls_x509_crt_set_inhibit_anypolicy(gnutls_x509_crt_t crt,
550
            unsigned int skipcerts)
551
0
{
552
0
  int ret;
553
0
  gnutls_datum_t der_data;
554
555
0
  if (crt == NULL) {
556
0
    gnutls_assert();
557
0
    return GNUTLS_E_INVALID_REQUEST;
558
0
  }
559
560
  /* generate the extension.
561
   */
562
0
  ret = gnutls_x509_ext_export_inhibit_anypolicy(skipcerts, &der_data);
563
0
  if (ret < 0) {
564
0
    gnutls_assert();
565
0
    return ret;
566
0
  }
567
568
0
  ret = _gnutls_x509_crt_set_extension(crt, "2.5.29.54", &der_data, 1);
569
0
  _gnutls_free_datum(&der_data);
570
571
0
  if (ret < 0) {
572
0
    gnutls_assert();
573
0
    return ret;
574
0
  }
575
576
0
  return 0;
577
0
}
578
579
/**
580
 * gnutls_x509_crt_set_subject_alternative_name:
581
 * @crt: a certificate of type #gnutls_x509_crt_t
582
 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
583
 * @data_string: The data to be set, a (0) terminated string
584
 *
585
 * This function will set the subject alternative name certificate
586
 * extension. This function assumes that data can be expressed as a null
587
 * terminated string.
588
 *
589
 * The name of the function is unfortunate since it is inconsistent with
590
 * gnutls_x509_crt_get_subject_alt_name().
591
 *
592
 * See gnutls_x509_crt_set_subject_alt_name() for more information.
593
 *
594
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
595
 *   negative error value.
596
 **/
597
int gnutls_x509_crt_set_subject_alternative_name(
598
  gnutls_x509_crt_t crt, gnutls_x509_subject_alt_name_t type,
599
  const char *data_string)
600
0
{
601
0
  if (crt == NULL) {
602
0
    gnutls_assert();
603
0
    return GNUTLS_E_INVALID_REQUEST;
604
0
  }
605
606
  /* only handle text extensions */
607
0
  if (type != GNUTLS_SAN_DNSNAME && type != GNUTLS_SAN_RFC822NAME &&
608
0
      type != GNUTLS_SAN_URI) {
609
0
    gnutls_assert();
610
0
    return GNUTLS_E_INVALID_REQUEST;
611
0
  }
612
613
0
  return gnutls_x509_crt_set_subject_alt_name(
614
0
    crt, type, data_string, strlen(data_string), GNUTLS_FSAN_SET);
615
0
}
616
617
/**
618
 * gnutls_x509_crt_set_subject_alt_name:
619
 * @crt: a certificate of type #gnutls_x509_crt_t
620
 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
621
 * @data: The data to be set
622
 * @data_size: The size of data to be set
623
 * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. 
624
 *
625
 * This function will set the subject alternative name certificate
626
 * extension. It can set the following types: %GNUTLS_SAN_DNSNAME as a text string,
627
 * %GNUTLS_SAN_RFC822NAME as a text string, %GNUTLS_SAN_URI as a text string,
628
 * %GNUTLS_SAN_IPADDRESS as a binary IP address (4 or 16 bytes),
629
 * %GNUTLS_SAN_OTHERNAME_XMPP as a UTF8 string (since 3.5.0).
630
 *
631
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
632
 * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
633
 *
634
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
635
 *   negative error value.
636
 *
637
 * Since: 2.6.0
638
 **/
639
int gnutls_x509_crt_set_subject_alt_name(gnutls_x509_crt_t crt,
640
           gnutls_x509_subject_alt_name_t type,
641
           const void *data,
642
           unsigned int data_size,
643
           unsigned int flags)
644
0
{
645
0
  int result;
646
0
  gnutls_datum_t der_data = { NULL, 0 };
647
0
  gnutls_datum_t prev_der_data = { NULL, 0 };
648
0
  unsigned int critical = 0;
649
650
0
  if (crt == NULL) {
651
0
    gnutls_assert();
652
0
    return GNUTLS_E_INVALID_REQUEST;
653
0
  }
654
655
  /* Check if the extension already exists.
656
   */
657
658
0
  if (flags & GNUTLS_FSAN_APPEND) {
659
0
    result = _gnutls_x509_crt_get_extension(
660
0
      crt, "2.5.29.17", 0, &prev_der_data, &critical);
661
0
    if (result < 0 &&
662
0
        result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
663
0
      gnutls_assert();
664
0
      return result;
665
0
    }
666
0
  }
667
668
  /* generate the extension.
669
   */
670
0
  result = _gnutls_x509_ext_gen_subject_alt_name(
671
0
    type, NULL, data, data_size, &prev_der_data, &der_data);
672
673
0
  if (result < 0) {
674
0
    gnutls_assert();
675
0
    goto finish;
676
0
  }
677
678
0
  result = _gnutls_x509_crt_set_extension(crt, "2.5.29.17", &der_data,
679
0
            critical);
680
681
0
  _gnutls_free_datum(&der_data);
682
683
0
  if (result < 0) {
684
0
    gnutls_assert();
685
0
    return result;
686
0
  }
687
688
0
  result = 0;
689
690
0
finish:
691
0
  _gnutls_free_datum(&prev_der_data);
692
0
  return result;
693
0
}
694
695
/**
696
 * gnutls_x509_crt_set_issuer_alt_name:
697
 * @crt: a certificate of type #gnutls_x509_crt_t
698
 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
699
 * @data: The data to be set
700
 * @data_size: The size of data to be set
701
 * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. 
702
 *
703
 * This function will set the issuer alternative name certificate
704
 * extension. It can set the same types as gnutls_x509_crt_set_subject_alt_name().
705
 *
706
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
707
 * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
708
 *
709
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
710
 *   negative error value.
711
 *
712
 * Since: 3.3.0
713
 **/
714
int gnutls_x509_crt_set_issuer_alt_name(gnutls_x509_crt_t crt,
715
          gnutls_x509_subject_alt_name_t type,
716
          const void *data,
717
          unsigned int data_size,
718
          unsigned int flags)
719
0
{
720
0
  int result;
721
0
  gnutls_datum_t der_data = { NULL, 0 };
722
0
  gnutls_datum_t prev_der_data = { NULL, 0 };
723
0
  unsigned int critical = 0;
724
725
0
  if (crt == NULL) {
726
0
    gnutls_assert();
727
0
    return GNUTLS_E_INVALID_REQUEST;
728
0
  }
729
730
  /* Check if the extension already exists.
731
   */
732
733
0
  if (flags & GNUTLS_FSAN_APPEND) {
734
0
    result = _gnutls_x509_crt_get_extension(
735
0
      crt, "2.5.29.18", 0, &prev_der_data, &critical);
736
0
    if (result < 0 &&
737
0
        result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
738
0
      gnutls_assert();
739
0
      return result;
740
0
    }
741
0
  }
742
743
  /* generate the extension.
744
   */
745
0
  result = _gnutls_x509_ext_gen_subject_alt_name(
746
0
    type, NULL, data, data_size, &prev_der_data, &der_data);
747
748
0
  if (result < 0) {
749
0
    gnutls_assert();
750
0
    goto finish;
751
0
  }
752
753
0
  result = _gnutls_x509_crt_set_extension(crt, "2.5.29.18", &der_data,
754
0
            critical);
755
756
0
  _gnutls_free_datum(&der_data);
757
758
0
  if (result < 0) {
759
0
    gnutls_assert();
760
0
    return result;
761
0
  }
762
763
0
  result = 0;
764
765
0
finish:
766
0
  _gnutls_free_datum(&prev_der_data);
767
0
  return result;
768
0
}
769
770
int _gnutls_encode_othername_data(unsigned flags, const void *data,
771
          unsigned data_size, gnutls_datum_t *output)
772
0
{
773
0
  int ret;
774
0
  if (flags & GNUTLS_FSAN_ENCODE_OCTET_STRING) {
775
0
    ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING, data,
776
0
             data_size, output);
777
0
  } else if (flags & GNUTLS_FSAN_ENCODE_UTF8_STRING) {
778
0
    ret = _gnutls_x509_encode_string(ASN1_ETYPE_UTF8_STRING, data,
779
0
             data_size, output);
780
0
  } else {
781
0
    ret = _gnutls_set_datum(output, data, data_size);
782
0
  }
783
0
  return ret;
784
0
}
785
786
/**
787
 * gnutls_x509_crt_set_subject_alt_othername:
788
 * @crt: a certificate of type #gnutls_x509_crt_t
789
 * @oid: The other name OID
790
 * @data: The data to be set
791
 * @data_size: The size of data to be set
792
 * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. 
793
 *
794
 * This function will set an "othername" to the subject alternative name certificate
795
 * extension.
796
 *
797
 * The values set are set as binary values and are expected to have the proper DER encoding.
798
 * For convenience the flags %GNUTLS_FSAN_ENCODE_OCTET_STRING and %GNUTLS_FSAN_ENCODE_UTF8_STRING
799
 * can be used to encode the provided data.
800
 *
801
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
802
 *   negative error value.
803
 *
804
 * Since: 3.5.0
805
 **/
806
int gnutls_x509_crt_set_subject_alt_othername(gnutls_x509_crt_t crt,
807
                const char *oid, const void *data,
808
                unsigned int data_size,
809
                unsigned int flags)
810
0
{
811
0
  int result;
812
0
  gnutls_datum_t der_data = { NULL, 0 };
813
0
  gnutls_datum_t prev_der_data = { NULL, 0 };
814
0
  gnutls_datum_t encoded_data = { NULL, 0 };
815
0
  unsigned int critical = 0;
816
817
0
  if (crt == NULL) {
818
0
    gnutls_assert();
819
0
    return GNUTLS_E_INVALID_REQUEST;
820
0
  }
821
822
  /* Check if the extension already exists.
823
   */
824
825
0
  if (flags & GNUTLS_FSAN_APPEND) {
826
0
    result = _gnutls_x509_crt_get_extension(
827
0
      crt, "2.5.29.17", 0, &prev_der_data, &critical);
828
0
    if (result < 0 &&
829
0
        result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
830
0
      gnutls_assert();
831
0
      return result;
832
0
    }
833
0
  }
834
835
0
  result = _gnutls_encode_othername_data(flags, data, data_size,
836
0
                 &encoded_data);
837
0
  if (result < 0) {
838
0
    gnutls_assert();
839
0
    goto finish;
840
0
  }
841
842
  /* generate the extension.
843
   */
844
0
  result = _gnutls_x509_ext_gen_subject_alt_name(
845
0
    GNUTLS_SAN_OTHERNAME, oid, encoded_data.data, encoded_data.size,
846
0
    &prev_der_data, &der_data);
847
848
0
  if (result < 0) {
849
0
    gnutls_assert();
850
0
    goto finish;
851
0
  }
852
853
0
  result = _gnutls_x509_crt_set_extension(crt, "2.5.29.17", &der_data,
854
0
            critical);
855
856
0
  if (result < 0) {
857
0
    gnutls_assert();
858
0
    goto finish;
859
0
  }
860
861
0
  result = 0;
862
863
0
finish:
864
0
  _gnutls_free_datum(&der_data);
865
0
  _gnutls_free_datum(&prev_der_data);
866
0
  _gnutls_free_datum(&encoded_data);
867
0
  return result;
868
0
}
869
870
/**
871
 * gnutls_x509_crt_set_issuer_alt_othername:
872
 * @crt: a certificate of type #gnutls_x509_crt_t
873
 * @oid: The other name OID
874
 * @data: The data to be set
875
 * @data_size: The size of data to be set
876
 * @flags: GNUTLS_FSAN_SET to clear previous data or GNUTLS_FSAN_APPEND to append. 
877
 *
878
 * This function will set an "othername" to the issuer alternative name certificate
879
 * extension.
880
 *
881
 * The values set are set as binary values and are expected to have the proper DER encoding.
882
 * For convenience the flags %GNUTLS_FSAN_ENCODE_OCTET_STRING and %GNUTLS_FSAN_ENCODE_UTF8_STRING
883
 * can be used to encode the provided data.
884
 *
885
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
886
 *   negative error value.
887
 *
888
 * Since: 3.5.0
889
 **/
890
int gnutls_x509_crt_set_issuer_alt_othername(gnutls_x509_crt_t crt,
891
               const char *oid, const void *data,
892
               unsigned int data_size,
893
               unsigned int flags)
894
0
{
895
0
  int result;
896
0
  gnutls_datum_t der_data = { NULL, 0 };
897
0
  gnutls_datum_t prev_der_data = { NULL, 0 };
898
0
  gnutls_datum_t encoded_data = { NULL, 0 };
899
0
  unsigned int critical = 0;
900
901
0
  if (crt == NULL) {
902
0
    gnutls_assert();
903
0
    return GNUTLS_E_INVALID_REQUEST;
904
0
  }
905
906
  /* Check if the extension already exists.
907
   */
908
909
0
  if (flags & GNUTLS_FSAN_APPEND) {
910
0
    result = _gnutls_x509_crt_get_extension(
911
0
      crt, "2.5.29.18", 0, &prev_der_data, &critical);
912
0
    if (result < 0 &&
913
0
        result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
914
0
      gnutls_assert();
915
0
      return result;
916
0
    }
917
0
  }
918
919
0
  result = _gnutls_encode_othername_data(flags, data, data_size,
920
0
                 &encoded_data);
921
0
  if (result < 0) {
922
0
    gnutls_assert();
923
0
    goto finish;
924
0
  }
925
926
  /* generate the extension.
927
   */
928
0
  result = _gnutls_x509_ext_gen_subject_alt_name(
929
0
    GNUTLS_SAN_OTHERNAME, oid, encoded_data.data, encoded_data.size,
930
0
    &prev_der_data, &der_data);
931
0
  if (result < 0) {
932
0
    gnutls_assert();
933
0
    goto finish;
934
0
  }
935
936
0
  result = _gnutls_x509_crt_set_extension(crt, "2.5.29.18", &der_data,
937
0
            critical);
938
939
0
  if (result < 0) {
940
0
    gnutls_assert();
941
0
    goto finish;
942
0
  }
943
944
0
  result = 0;
945
946
0
finish:
947
0
  _gnutls_free_datum(&der_data);
948
0
  _gnutls_free_datum(&prev_der_data);
949
0
  _gnutls_free_datum(&encoded_data);
950
0
  return result;
951
0
}
952
953
/**
954
 * gnutls_x509_crt_set_proxy:
955
 * @crt: a certificate of type #gnutls_x509_crt_t
956
 * @pathLenConstraint: non-negative error codes indicate maximum length of path,
957
 *   and negative error codes indicate that the pathLenConstraints field should
958
 *   not be present.
959
 * @policyLanguage: OID describing the language of @policy.
960
 * @policy: uint8_t byte array with policy language, can be %NULL
961
 * @sizeof_policy: size of @policy.
962
 *
963
 * This function will set the proxyCertInfo extension.
964
 *
965
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
966
 *   negative error value.
967
 **/
968
int gnutls_x509_crt_set_proxy(gnutls_x509_crt_t crt, int pathLenConstraint,
969
            const char *policyLanguage, const char *policy,
970
            size_t sizeof_policy)
971
0
{
972
0
  int result;
973
0
  gnutls_datum_t der_data;
974
975
0
  if (crt == NULL) {
976
0
    gnutls_assert();
977
0
    return GNUTLS_E_INVALID_REQUEST;
978
0
  }
979
980
  /* generate the extension.
981
   */
982
0
  result = gnutls_x509_ext_export_proxy(pathLenConstraint, policyLanguage,
983
0
                policy, sizeof_policy, &der_data);
984
0
  if (result < 0) {
985
0
    gnutls_assert();
986
0
    return result;
987
0
  }
988
989
0
  result = _gnutls_x509_crt_set_extension(crt, "1.3.6.1.5.5.7.1.14",
990
0
            &der_data, 1);
991
992
0
  _gnutls_free_datum(&der_data);
993
994
0
  if (result < 0) {
995
0
    gnutls_assert();
996
0
    return result;
997
0
  }
998
999
0
  return 0;
1000
0
}
1001
1002
/**
1003
 * gnutls_x509_crt_set_private_key_usage_period:
1004
 * @crt: a certificate of type #gnutls_x509_crt_t
1005
 * @activation: The activation time
1006
 * @expiration: The expiration time
1007
 *
1008
 * This function will set the private key usage period extension (2.5.29.16).
1009
 *
1010
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1011
 *   negative error value.
1012
 **/
1013
int gnutls_x509_crt_set_private_key_usage_period(gnutls_x509_crt_t crt,
1014
             time_t activation,
1015
             time_t expiration)
1016
0
{
1017
0
  int result;
1018
0
  gnutls_datum_t der_data;
1019
1020
0
  if (crt == NULL) {
1021
0
    gnutls_assert();
1022
0
    return GNUTLS_E_INVALID_REQUEST;
1023
0
  }
1024
1025
0
  result = gnutls_x509_ext_export_private_key_usage_period(
1026
0
    activation, expiration, &der_data);
1027
0
  if (result < 0) {
1028
0
    gnutls_assert();
1029
0
    goto cleanup;
1030
0
  }
1031
1032
0
  result = _gnutls_x509_crt_set_extension(crt, "2.5.29.16", &der_data, 0);
1033
1034
0
  _gnutls_free_datum(&der_data);
1035
1036
0
cleanup:
1037
0
  return result;
1038
0
}
1039
1040
/**
1041
 * gnutls_x509_crt_sign2:
1042
 * @crt: a certificate of type #gnutls_x509_crt_t
1043
 * @issuer: is the certificate of the certificate issuer
1044
 * @issuer_key: holds the issuer's private key
1045
 * @dig: The message digest to use, %GNUTLS_DIG_SHA256 is a safe choice
1046
 * @flags: must be 0
1047
 *
1048
 * This function will sign the certificate with the issuer's private key, and
1049
 * will copy the issuer's information into the certificate.
1050
 *
1051
 * This must be the last step in a certificate generation since all
1052
 * the previously set parameters are now signed.
1053
 *
1054
 * A known limitation of this function is, that a newly-signed certificate will not
1055
 * be fully functional (e.g., for signature verification), until it
1056
 * is exported an re-imported.
1057
 *
1058
 * After GnuTLS 3.6.1 the value of @dig may be %GNUTLS_DIG_UNKNOWN,
1059
 * and in that case, a suitable but reasonable for the key algorithm will be selected.
1060
 *
1061
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1062
 *   negative error value.
1063
 **/
1064
int gnutls_x509_crt_sign2(gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
1065
        gnutls_x509_privkey_t issuer_key,
1066
        gnutls_digest_algorithm_t dig, unsigned int flags)
1067
0
{
1068
0
  int result;
1069
0
  gnutls_privkey_t privkey;
1070
1071
0
  if (crt == NULL || issuer == NULL || issuer_key == NULL) {
1072
0
    gnutls_assert();
1073
0
    return GNUTLS_E_INVALID_REQUEST;
1074
0
  }
1075
1076
0
  MODIFIED(crt);
1077
1078
0
  result = gnutls_privkey_init(&privkey);
1079
0
  if (result < 0) {
1080
0
    gnutls_assert();
1081
0
    return result;
1082
0
  }
1083
1084
0
  result = gnutls_privkey_import_x509(privkey, issuer_key, 0);
1085
0
  if (result < 0) {
1086
0
    gnutls_assert();
1087
0
    goto fail;
1088
0
  }
1089
1090
0
  result = gnutls_x509_crt_privkey_sign(crt, issuer, privkey, dig, flags);
1091
0
  if (result < 0) {
1092
0
    gnutls_assert();
1093
0
    goto fail;
1094
0
  }
1095
1096
0
  result = 0;
1097
1098
0
fail:
1099
0
  gnutls_privkey_deinit(privkey);
1100
1101
0
  return result;
1102
0
}
1103
1104
/**
1105
 * gnutls_x509_crt_sign:
1106
 * @crt: a certificate of type #gnutls_x509_crt_t
1107
 * @issuer: is the certificate of the certificate issuer
1108
 * @issuer_key: holds the issuer's private key
1109
 *
1110
 * This function is the same a gnutls_x509_crt_sign2() with no flags,
1111
 * and an appropriate hash algorithm. The hash algorithm used may
1112
 * vary between versions of GnuTLS, and it is tied to the security
1113
 * level of the issuer's public key.
1114
 *
1115
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1116
 *   negative error value.
1117
 **/
1118
int gnutls_x509_crt_sign(gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
1119
       gnutls_x509_privkey_t issuer_key)
1120
0
{
1121
0
  return gnutls_x509_crt_sign2(crt, issuer, issuer_key, 0, 0);
1122
0
}
1123
1124
/**
1125
 * gnutls_x509_crt_set_activation_time:
1126
 * @cert: a certificate of type #gnutls_x509_crt_t
1127
 * @act_time: The actual time
1128
 *
1129
 * This function will set the time this certificate was or will be
1130
 * activated.
1131
 *
1132
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1133
 *   negative error value.
1134
 **/
1135
int gnutls_x509_crt_set_activation_time(gnutls_x509_crt_t cert, time_t act_time)
1136
0
{
1137
0
  if (cert == NULL) {
1138
0
    gnutls_assert();
1139
0
    return GNUTLS_E_INVALID_REQUEST;
1140
0
  }
1141
1142
0
  MODIFIED(cert);
1143
1144
0
  return _gnutls_x509_set_time(
1145
0
    cert->cert, "tbsCertificate.validity.notBefore", act_time, 0);
1146
0
}
1147
1148
/**
1149
 * gnutls_x509_crt_set_expiration_time:
1150
 * @cert: a certificate of type #gnutls_x509_crt_t
1151
 * @exp_time: The actual time
1152
 *
1153
 * This function will set the time this Certificate will expire.
1154
 * Setting an expiration time to (time_t)-1 will set
1155
 * to the no well-defined expiration date value.
1156
 *
1157
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1158
 *   negative error value.
1159
 **/
1160
int gnutls_x509_crt_set_expiration_time(gnutls_x509_crt_t cert, time_t exp_time)
1161
0
{
1162
0
  if (cert == NULL) {
1163
0
    gnutls_assert();
1164
0
    return GNUTLS_E_INVALID_REQUEST;
1165
0
  }
1166
1167
0
  MODIFIED(cert);
1168
1169
0
  return _gnutls_x509_set_time(
1170
0
    cert->cert, "tbsCertificate.validity.notAfter", exp_time, 0);
1171
0
}
1172
1173
/**
1174
 * gnutls_x509_crt_set_serial:
1175
 * @cert: a certificate of type #gnutls_x509_crt_t
1176
 * @serial: The serial number
1177
 * @serial_size: Holds the size of the serial field.
1178
 *
1179
 * This function will set the X.509 certificate's serial number.
1180
 * While the serial number is an integer, it is often handled
1181
 * as an opaque field by several CAs. For this reason this function
1182
 * accepts any kind of data as a serial number. To be consistent
1183
 * with the X.509/PKIX specifications the provided @serial should be 
1184
 * a big-endian positive number (i.e. its leftmost bit should be zero).
1185
 *
1186
 * The size of the serial is restricted to 20 bytes maximum by RFC5280.
1187
 * This function allows writing more than 20 bytes but the generated
1188
 * certificates in that case may be rejected by other implementations.
1189
 *
1190
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1191
 *   negative error value.
1192
 **/
1193
int gnutls_x509_crt_set_serial(gnutls_x509_crt_t cert, const void *serial,
1194
             size_t serial_size)
1195
0
{
1196
0
  int ret;
1197
0
  unsigned all_zero, i;
1198
0
  const unsigned char *pserial = serial;
1199
1200
0
  if (cert == NULL) {
1201
0
    gnutls_assert();
1202
0
    return GNUTLS_E_INVALID_REQUEST;
1203
0
  }
1204
1205
  /* check for non-zero serial */
1206
0
  all_zero = 1;
1207
0
  for (i = 0; i < serial_size; i++) {
1208
0
    if (pserial[i] != 0) {
1209
0
      all_zero = 0;
1210
0
      break;
1211
0
    }
1212
0
  }
1213
1214
0
  if (all_zero) {
1215
0
    _gnutls_debug_log("error: certificate serial is zero\n");
1216
0
    return GNUTLS_E_INVALID_REQUEST;
1217
0
  }
1218
1219
0
  MODIFIED(cert);
1220
1221
0
  ret = asn1_write_value(cert->cert, "tbsCertificate.serialNumber",
1222
0
             serial, serial_size);
1223
0
  if (ret != ASN1_SUCCESS) {
1224
0
    gnutls_assert();
1225
0
    return _gnutls_asn2err(ret);
1226
0
  }
1227
1228
0
  return 0;
1229
0
}
1230
1231
/**
1232
 * gnutls_x509_crt_set_issuer_unique_id:
1233
 * @cert: a certificate of type #gnutls_x509_crt_t
1234
 * @id: The unique ID
1235
 * @id_size: Holds the size of the unique ID.
1236
 *
1237
 * This function will set the X.509 certificate's issuer unique ID field.
1238
 *
1239
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1240
 *   negative error value.
1241
 *
1242
 * Since: 3.4.7
1243
 **/
1244
int gnutls_x509_crt_set_issuer_unique_id(gnutls_x509_crt_t cert, const void *id,
1245
           size_t id_size)
1246
0
{
1247
0
  int ret;
1248
1249
0
  if (cert == NULL) {
1250
0
    gnutls_assert();
1251
0
    return GNUTLS_E_INVALID_REQUEST;
1252
0
  }
1253
1254
0
  MODIFIED(cert);
1255
1256
0
  ret = asn1_write_value(cert->cert, "tbsCertificate.issuerUniqueID", id,
1257
0
             id_size * 8);
1258
0
  if (ret != ASN1_SUCCESS) {
1259
0
    gnutls_assert();
1260
0
    return _gnutls_asn2err(ret);
1261
0
  }
1262
1263
0
  return 0;
1264
0
}
1265
1266
/**
1267
 * gnutls_x509_crt_set_subject_unique_id:
1268
 * @cert: a certificate of type #gnutls_x509_crt_t
1269
 * @id: The unique ID
1270
 * @id_size: Holds the size of the unique ID.
1271
 *
1272
 * This function will set the X.509 certificate's subject unique ID field.
1273
 *
1274
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1275
 *   negative error value.
1276
 *
1277
 * Since: 3.4.7
1278
 **/
1279
int gnutls_x509_crt_set_subject_unique_id(gnutls_x509_crt_t cert,
1280
            const void *id, size_t id_size)
1281
0
{
1282
0
  int ret;
1283
1284
0
  if (cert == NULL) {
1285
0
    gnutls_assert();
1286
0
    return GNUTLS_E_INVALID_REQUEST;
1287
0
  }
1288
1289
0
  MODIFIED(cert);
1290
1291
0
  ret = asn1_write_value(cert->cert, "tbsCertificate.subjectUniqueID", id,
1292
0
             id_size * 8);
1293
0
  if (ret != ASN1_SUCCESS) {
1294
0
    gnutls_assert();
1295
0
    return _gnutls_asn2err(ret);
1296
0
  }
1297
1298
0
  return 0;
1299
0
}
1300
1301
/* If OPTIONAL fields have not been initialized then
1302
 * disable them.
1303
 */
1304
static void disable_optional_stuff(gnutls_x509_crt_t cert)
1305
0
{
1306
0
  asn1_data_node_st n;
1307
0
  asn1_node node;
1308
0
  unsigned remove_subject_unique_id = 1;
1309
0
  unsigned remove_issuer_unique_id = 1;
1310
1311
0
  node = asn1_find_node(cert->cert, "tbsCertificate.issuerUniqueID");
1312
0
  if (node) {
1313
0
    if (asn1_read_node_value(node, &n) == ASN1_SUCCESS &&
1314
0
        n.value_len != 0)
1315
0
      remove_issuer_unique_id = 0;
1316
0
  }
1317
1318
0
  node = asn1_find_node(cert->cert, "tbsCertificate.subjectUniqueID");
1319
0
  if (node) {
1320
0
    if (asn1_read_node_value(node, &n) == ASN1_SUCCESS &&
1321
0
        n.value_len != 0)
1322
0
      remove_subject_unique_id = 0;
1323
0
  }
1324
1325
0
  if (remove_issuer_unique_id)
1326
0
    (void)asn1_write_value(
1327
0
      cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0);
1328
1329
0
  if (remove_subject_unique_id)
1330
0
    (void)asn1_write_value(
1331
0
      cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0);
1332
1333
0
  if (cert->use_extensions == 0) {
1334
0
    _gnutls_debug_log("Disabling X.509 extensions.\n");
1335
0
    (void)asn1_write_value(cert->cert, "tbsCertificate.extensions",
1336
0
               NULL, 0);
1337
0
  }
1338
1339
0
  return;
1340
0
}
1341
1342
/**
1343
 * gnutls_x509_crt_set_crl_dist_points:
1344
 * @crt: a certificate of type #gnutls_x509_crt_t
1345
 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
1346
 * @data_string: The data to be set
1347
 * @reason_flags: revocation reasons
1348
 *
1349
 * This function will set the CRL distribution points certificate extension.
1350
 *
1351
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1352
 *   negative error value.
1353
 **/
1354
int gnutls_x509_crt_set_crl_dist_points(gnutls_x509_crt_t crt,
1355
          gnutls_x509_subject_alt_name_t type,
1356
          const void *data_string,
1357
          unsigned int reason_flags)
1358
0
{
1359
0
  return gnutls_x509_crt_set_crl_dist_points2(
1360
0
    crt, type, data_string, strlen(data_string), reason_flags);
1361
0
}
1362
1363
/**
1364
 * gnutls_x509_crt_set_crl_dist_points2:
1365
 * @crt: a certificate of type #gnutls_x509_crt_t
1366
 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
1367
 * @data: The data to be set
1368
 * @data_size: The data size
1369
 * @reason_flags: revocation reasons
1370
 *
1371
 * This function will set the CRL distribution points certificate extension.
1372
 *
1373
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1374
 *   negative error value.
1375
 *
1376
 * Since: 2.6.0
1377
 **/
1378
int gnutls_x509_crt_set_crl_dist_points2(gnutls_x509_crt_t crt,
1379
           gnutls_x509_subject_alt_name_t type,
1380
           const void *data,
1381
           unsigned int data_size,
1382
           unsigned int reason_flags)
1383
0
{
1384
0
  int ret;
1385
0
  gnutls_datum_t der_data = { NULL, 0 };
1386
0
  gnutls_datum_t old_der = { NULL, 0 };
1387
0
  unsigned int critical;
1388
0
  gnutls_x509_crl_dist_points_t cdp = NULL;
1389
0
  gnutls_datum_t san;
1390
1391
0
  if (crt == NULL) {
1392
0
    gnutls_assert();
1393
0
    return GNUTLS_E_INVALID_REQUEST;
1394
0
  }
1395
1396
0
  ret = gnutls_x509_crl_dist_points_init(&cdp);
1397
0
  if (ret < 0)
1398
0
    return gnutls_assert_val(ret);
1399
1400
  /* Check if the extension already exists.
1401
   */
1402
0
  ret = _gnutls_x509_crt_get_extension(crt, "2.5.29.31", 0, &old_der,
1403
0
               &critical);
1404
1405
0
  if (ret >= 0 && old_der.data != NULL) {
1406
0
    ret = gnutls_x509_ext_import_crl_dist_points(&old_der, cdp, 0);
1407
0
    if (ret < 0) {
1408
0
      gnutls_assert();
1409
0
      goto cleanup;
1410
0
    }
1411
0
  }
1412
1413
0
  san.data = (void *)data;
1414
0
  san.size = data_size;
1415
0
  ret = gnutls_x509_crl_dist_points_set(cdp, type, &san, reason_flags);
1416
0
  if (ret < 0) {
1417
0
    gnutls_assert();
1418
0
    goto cleanup;
1419
0
  }
1420
1421
  /* generate the extension.
1422
   */
1423
0
  ret = gnutls_x509_ext_export_crl_dist_points(cdp, &der_data);
1424
0
  if (ret < 0) {
1425
0
    gnutls_assert();
1426
0
    goto cleanup;
1427
0
  }
1428
1429
0
  ret = _gnutls_x509_crt_set_extension(crt, "2.5.29.31", &der_data, 0);
1430
1431
0
  if (ret < 0) {
1432
0
    gnutls_assert();
1433
0
    goto cleanup;
1434
0
  }
1435
1436
0
  ret = 0;
1437
0
cleanup:
1438
0
  _gnutls_free_datum(&der_data);
1439
0
  _gnutls_free_datum(&old_der);
1440
0
  if (cdp != NULL)
1441
0
    gnutls_x509_crl_dist_points_deinit(cdp);
1442
1443
0
  return ret;
1444
0
}
1445
1446
/**
1447
 * gnutls_x509_crt_cpy_crl_dist_points:
1448
 * @dst: a certificate of type #gnutls_x509_crt_t
1449
 * @src: the certificate where the dist points will be copied from
1450
 *
1451
 * This function will copy the CRL distribution points certificate
1452
 * extension, from the source to the destination certificate.
1453
 * This may be useful to copy from a CA certificate to issued ones.
1454
 *
1455
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1456
 *   negative error value.
1457
 **/
1458
int gnutls_x509_crt_cpy_crl_dist_points(gnutls_x509_crt_t dst,
1459
          gnutls_x509_crt_t src)
1460
0
{
1461
0
  int result;
1462
0
  gnutls_datum_t der_data;
1463
0
  unsigned int critical;
1464
1465
0
  if (dst == NULL || src == NULL) {
1466
0
    gnutls_assert();
1467
0
    return GNUTLS_E_INVALID_REQUEST;
1468
0
  }
1469
1470
  /* Check if the extension already exists.
1471
   */
1472
0
  result = _gnutls_x509_crt_get_extension(src, "2.5.29.31", 0, &der_data,
1473
0
            &critical);
1474
0
  if (result < 0) {
1475
0
    gnutls_assert();
1476
0
    return result;
1477
0
  }
1478
1479
0
  result = _gnutls_x509_crt_set_extension(dst, "2.5.29.31", &der_data,
1480
0
            critical);
1481
0
  _gnutls_free_datum(&der_data);
1482
1483
0
  if (result < 0) {
1484
0
    gnutls_assert();
1485
0
    return result;
1486
0
  }
1487
1488
0
  return 0;
1489
0
}
1490
1491
/**
1492
 * gnutls_x509_crt_set_subject_key_id:
1493
 * @cert: a certificate of type #gnutls_x509_crt_t
1494
 * @id: The key ID
1495
 * @id_size: Holds the size of the subject key ID field.
1496
 *
1497
 * This function will set the X.509 certificate's subject key ID
1498
 * extension.
1499
 *
1500
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1501
 *   negative error value.
1502
 **/
1503
int gnutls_x509_crt_set_subject_key_id(gnutls_x509_crt_t cert, const void *id,
1504
               size_t id_size)
1505
0
{
1506
0
  int result;
1507
0
  gnutls_datum_t old_id, der_data;
1508
0
  gnutls_datum_t d_id;
1509
0
  unsigned int critical;
1510
1511
0
  if (cert == NULL) {
1512
0
    gnutls_assert();
1513
0
    return GNUTLS_E_INVALID_REQUEST;
1514
0
  }
1515
1516
  /* Check if the extension already exists.
1517
   */
1518
0
  result = _gnutls_x509_crt_get_extension(cert, "2.5.29.14", 0, &old_id,
1519
0
            &critical);
1520
1521
0
  if (result >= 0)
1522
0
    _gnutls_free_datum(&old_id);
1523
0
  if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1524
0
    gnutls_assert();
1525
0
    return GNUTLS_E_INVALID_REQUEST;
1526
0
  }
1527
1528
  /* generate the extension.
1529
   */
1530
0
  d_id.data = (void *)id;
1531
0
  d_id.size = id_size;
1532
1533
0
  result = gnutls_x509_ext_export_subject_key_id(&d_id, &der_data);
1534
0
  if (result < 0) {
1535
0
    gnutls_assert();
1536
0
    return result;
1537
0
  }
1538
1539
0
  result =
1540
0
    _gnutls_x509_crt_set_extension(cert, "2.5.29.14", &der_data, 0);
1541
1542
0
  _gnutls_free_datum(&der_data);
1543
1544
0
  if (result < 0) {
1545
0
    gnutls_assert();
1546
0
    return result;
1547
0
  }
1548
1549
0
  return 0;
1550
0
}
1551
1552
/**
1553
 * gnutls_x509_crt_set_authority_key_id:
1554
 * @cert: a certificate of type #gnutls_x509_crt_t
1555
 * @id: The key ID
1556
 * @id_size: Holds the size of the key ID field.
1557
 *
1558
 * This function will set the X.509 certificate's authority key ID extension.
1559
 * Only the keyIdentifier field can be set with this function.
1560
 *
1561
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1562
 *   negative error value.
1563
 **/
1564
int gnutls_x509_crt_set_authority_key_id(gnutls_x509_crt_t cert, const void *id,
1565
           size_t id_size)
1566
0
{
1567
0
  int result;
1568
0
  gnutls_datum_t old_id, der_data;
1569
0
  unsigned int critical;
1570
1571
0
  if (cert == NULL) {
1572
0
    gnutls_assert();
1573
0
    return GNUTLS_E_INVALID_REQUEST;
1574
0
  }
1575
1576
  /* Check if the extension already exists.
1577
   */
1578
0
  result = _gnutls_x509_crt_get_extension(cert, "2.5.29.35", 0, &old_id,
1579
0
            &critical);
1580
1581
0
  if (result >= 0)
1582
0
    _gnutls_free_datum(&old_id);
1583
0
  if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1584
0
    gnutls_assert();
1585
0
    return GNUTLS_E_INVALID_REQUEST;
1586
0
  }
1587
1588
  /* generate the extension.
1589
   */
1590
0
  result = _gnutls_x509_ext_gen_auth_key_id(id, id_size, &der_data);
1591
0
  if (result < 0) {
1592
0
    gnutls_assert();
1593
0
    return result;
1594
0
  }
1595
1596
0
  result =
1597
0
    _gnutls_x509_crt_set_extension(cert, "2.5.29.35", &der_data, 0);
1598
1599
0
  _gnutls_free_datum(&der_data);
1600
1601
0
  if (result < 0) {
1602
0
    gnutls_assert();
1603
0
    return result;
1604
0
  }
1605
1606
0
  return 0;
1607
0
}
1608
1609
/**
1610
 * gnutls_x509_crt_set_key_purpose_oid:
1611
 * @cert: a certificate of type #gnutls_x509_crt_t
1612
 * @oid: a pointer to a null terminated string that holds the OID
1613
 * @critical: Whether this extension will be critical or not
1614
 *
1615
 * This function will set the key purpose OIDs of the Certificate.
1616
 * These are stored in the Extended Key Usage extension (2.5.29.37)
1617
 * See the GNUTLS_KP_* definitions for human readable names.
1618
 *
1619
 * Subsequent calls to this function will append OIDs to the OID list.
1620
 *
1621
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1622
 *   otherwise a negative error code is returned.
1623
 **/
1624
int gnutls_x509_crt_set_key_purpose_oid(gnutls_x509_crt_t cert, const void *oid,
1625
          unsigned int critical)
1626
0
{
1627
0
  int ret;
1628
0
  gnutls_datum_t old_id = { NULL, 0 };
1629
0
  gnutls_datum_t der = { NULL, 0 };
1630
0
  gnutls_x509_key_purposes_t p = NULL;
1631
1632
0
  if (cert == NULL) {
1633
0
    gnutls_assert();
1634
0
    return GNUTLS_E_INVALID_REQUEST;
1635
0
  }
1636
1637
0
  ret = gnutls_x509_key_purpose_init(&p);
1638
0
  if (ret < 0)
1639
0
    return gnutls_assert_val(ret);
1640
1641
  /* Check if the extension already exists.
1642
   */
1643
0
  ret = _gnutls_x509_crt_get_extension(cert, "2.5.29.37", 0, &old_id,
1644
0
               NULL);
1645
1646
0
  if (ret >= 0) {
1647
0
    ret = gnutls_x509_ext_import_key_purposes(&old_id, p, 0);
1648
0
    if (ret < 0) {
1649
0
      gnutls_assert();
1650
0
      goto cleanup;
1651
0
    }
1652
0
  }
1653
1654
0
  ret = gnutls_x509_key_purpose_set(p, oid);
1655
0
  if (ret < 0) {
1656
0
    gnutls_assert();
1657
0
    goto cleanup;
1658
0
  }
1659
1660
0
  ret = gnutls_x509_ext_export_key_purposes(p, &der);
1661
0
  if (ret < 0) {
1662
0
    gnutls_assert();
1663
0
    goto cleanup;
1664
0
  }
1665
1666
0
  ret = _gnutls_x509_crt_set_extension(cert, "2.5.29.37", &der, critical);
1667
0
  if (ret < 0) {
1668
0
    gnutls_assert();
1669
0
    goto cleanup;
1670
0
  }
1671
1672
0
  ret = 0;
1673
0
cleanup:
1674
0
  _gnutls_free_datum(&der);
1675
0
  _gnutls_free_datum(&old_id);
1676
0
  if (p != NULL)
1677
0
    gnutls_x509_key_purpose_deinit(p);
1678
1679
0
  return ret;
1680
0
}
1681
1682
/**
1683
 * gnutls_x509_crt_privkey_sign:
1684
 * @crt: a certificate of type #gnutls_x509_crt_t
1685
 * @issuer: is the certificate of the certificate issuer
1686
 * @issuer_key: holds the issuer's private key
1687
 * @dig: The message digest to use, %GNUTLS_DIG_SHA256 is a safe choice
1688
 * @flags: must be 0
1689
 *
1690
 * This function will sign the certificate with the issuer's private key, and
1691
 * will copy the issuer's information into the certificate.
1692
 *
1693
 * This must be the last step in a certificate generation since all
1694
 * the previously set parameters are now signed.
1695
 *
1696
 * A known limitation of this function is, that a newly-signed certificate will not
1697
 * be fully functional (e.g., for signature verification), until it
1698
 * is exported an re-imported.
1699
 *
1700
 * After GnuTLS 3.6.1 the value of @dig may be %GNUTLS_DIG_UNKNOWN,
1701
 * and in that case, a suitable but reasonable for the key algorithm will be selected.
1702
 *
1703
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1704
 *   negative error value.
1705
 **/
1706
int gnutls_x509_crt_privkey_sign(gnutls_x509_crt_t crt,
1707
         gnutls_x509_crt_t issuer,
1708
         gnutls_privkey_t issuer_key,
1709
         gnutls_digest_algorithm_t dig,
1710
         unsigned int flags)
1711
0
{
1712
0
  int result;
1713
1714
0
  if (crt == NULL || issuer == NULL || issuer_key == NULL) {
1715
0
    gnutls_assert();
1716
0
    return GNUTLS_E_INVALID_REQUEST;
1717
0
  }
1718
1719
0
  if (dig == 0) {
1720
0
    result = gnutls_x509_crt_get_preferred_hash_algorithm(
1721
0
      issuer, &dig, NULL);
1722
0
    if (result < 0)
1723
0
      return gnutls_assert_val(result);
1724
0
  }
1725
1726
0
  MODIFIED(crt);
1727
1728
  /* disable all the unneeded OPTIONAL fields.
1729
   */
1730
0
  disable_optional_stuff(crt);
1731
1732
0
  result = _gnutls_check_cert_sanity(crt);
1733
0
  if (result < 0) {
1734
0
    gnutls_assert();
1735
0
    return result;
1736
0
  }
1737
1738
0
  result = _gnutls_x509_pkix_sign(crt->cert, "tbsCertificate", dig, flags,
1739
0
          issuer, issuer_key);
1740
0
  if (result < 0) {
1741
0
    gnutls_assert();
1742
0
    return result;
1743
0
  }
1744
1745
0
  return 0;
1746
0
}
1747
1748
/**
1749
 * gnutls_x509_crt_set_authority_info_access:
1750
 * @crt: Holds the certificate
1751
 * @what: what data to get, a #gnutls_info_access_what_t type.
1752
 * @data: output data to be freed with gnutls_free().
1753
 *
1754
 * This function sets the Authority Information Access (AIA)
1755
 * extension, see RFC 5280 section 4.2.2.1 for more information.  
1756
 *
1757
 * The type of data stored in @data is specified via @what which
1758
 * should be #gnutls_info_access_what_t values.
1759
 *
1760
 * If @what is %GNUTLS_IA_OCSP_URI, @data will hold the OCSP URI.
1761
 * If @what is %GNUTLS_IA_CAISSUERS_URI, @data will hold the caIssuers
1762
 * URI.  
1763
 *
1764
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1765
 *   negative error value.
1766
 *
1767
 * Since: 3.0
1768
 **/
1769
int gnutls_x509_crt_set_authority_info_access(gnutls_x509_crt_t crt, int what,
1770
                gnutls_datum_t *data)
1771
0
{
1772
0
  int ret;
1773
0
  gnutls_datum_t der = { NULL, 0 };
1774
0
  gnutls_datum_t new_der = { NULL, 0 };
1775
0
  gnutls_x509_aia_t aia_ctx = NULL;
1776
0
  const char *oid;
1777
0
  unsigned int c;
1778
1779
0
  if (crt == NULL)
1780
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1781
1782
0
  ret = gnutls_x509_aia_init(&aia_ctx);
1783
0
  if (ret < 0) {
1784
0
    gnutls_assert();
1785
0
    return ret;
1786
0
  }
1787
1788
0
  ret = _gnutls_x509_crt_get_extension(crt, GNUTLS_OID_AIA, 0, &der, &c);
1789
0
  if (ret >= 0) { /* decode it */
1790
0
    ret = gnutls_x509_ext_import_aia(&der, aia_ctx, 0);
1791
0
    if (ret < 0) {
1792
0
      gnutls_assert();
1793
0
      goto cleanup;
1794
0
    }
1795
0
  }
1796
1797
0
  if (what == GNUTLS_IA_OCSP_URI)
1798
0
    oid = GNUTLS_OID_AD_OCSP;
1799
0
  else if (what == GNUTLS_IA_CAISSUERS_URI)
1800
0
    oid = GNUTLS_OID_AD_CAISSUERS;
1801
0
  else
1802
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1803
0
  ret = gnutls_x509_aia_set(aia_ctx, oid, GNUTLS_SAN_URI, data);
1804
0
  if (ret < 0) {
1805
0
    gnutls_assert();
1806
0
    goto cleanup;
1807
0
  }
1808
1809
0
  ret = gnutls_x509_ext_export_aia(aia_ctx, &new_der);
1810
0
  if (ret < 0) {
1811
0
    gnutls_assert();
1812
0
    goto cleanup;
1813
0
  }
1814
1815
0
  ret = _gnutls_x509_crt_set_extension(crt, GNUTLS_OID_AIA, &new_der, 0);
1816
0
  if (ret < 0) {
1817
0
    gnutls_assert();
1818
0
    goto cleanup;
1819
0
  }
1820
1821
0
cleanup:
1822
0
  if (aia_ctx != NULL)
1823
0
    gnutls_x509_aia_deinit(aia_ctx);
1824
0
  _gnutls_free_datum(&new_der);
1825
0
  _gnutls_free_datum(&der);
1826
1827
0
  return ret;
1828
0
}
1829
1830
/**
1831
 * gnutls_x509_crt_set_policy:
1832
 * @crt: should contain a #gnutls_x509_crt_t type
1833
 * @policy: A pointer to a policy
1834
 * @critical: use non-zero if the extension is marked as critical
1835
 *
1836
 * This function will set the certificate policy extension (2.5.29.32).
1837
 * Multiple calls to this function append a new policy.
1838
 *
1839
 * Note the maximum text size for the qualifier %GNUTLS_X509_QUALIFIER_NOTICE
1840
 * is 200 characters. This function will fail with %GNUTLS_E_INVALID_REQUEST
1841
 * if this is exceeded.
1842
 *
1843
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1844
 *   negative error value.
1845
 *
1846
 * Since: 3.1.5
1847
 **/
1848
int gnutls_x509_crt_set_policy(gnutls_x509_crt_t crt,
1849
             const struct gnutls_x509_policy_st *policy,
1850
             unsigned int critical)
1851
0
{
1852
0
  int ret;
1853
0
  gnutls_datum_t der_data = { NULL, 0 }, prev_der_data = { NULL, 0 };
1854
0
  gnutls_x509_policies_t policies = NULL;
1855
1856
0
  if (crt == NULL) {
1857
0
    gnutls_assert();
1858
0
    return GNUTLS_E_INVALID_REQUEST;
1859
0
  }
1860
1861
0
  ret = gnutls_x509_policies_init(&policies);
1862
0
  if (ret < 0) {
1863
0
    gnutls_assert();
1864
0
    return ret;
1865
0
  }
1866
1867
0
  ret = _gnutls_x509_crt_get_extension(crt, "2.5.29.32", 0,
1868
0
               &prev_der_data, NULL);
1869
0
  if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1870
0
    gnutls_assert();
1871
0
    goto cleanup;
1872
0
  }
1873
1874
0
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
1875
0
    ret = gnutls_x509_ext_import_policies(&prev_der_data, policies,
1876
0
                  0);
1877
0
    if (ret < 0) {
1878
0
      gnutls_assert();
1879
0
      goto cleanup;
1880
0
    }
1881
0
  }
1882
1883
0
  ret = gnutls_x509_policies_set(policies, policy);
1884
0
  if (ret < 0) {
1885
0
    gnutls_assert();
1886
0
    goto cleanup;
1887
0
  }
1888
1889
0
  ret = gnutls_x509_ext_export_policies(policies, &der_data);
1890
0
  if (ret < 0) {
1891
0
    gnutls_assert();
1892
0
    goto cleanup;
1893
0
  }
1894
1895
0
  ret = _gnutls_x509_crt_set_extension(crt, "2.5.29.32", &der_data, 0);
1896
1897
0
cleanup:
1898
0
  if (policies != NULL)
1899
0
    gnutls_x509_policies_deinit(policies);
1900
0
  _gnutls_free_datum(&prev_der_data);
1901
0
  _gnutls_free_datum(&der_data);
1902
1903
0
  return ret;
1904
0
}
1905
1906
/**
1907
 * gnutls_x509_crt_set_spki:
1908
 * @crt: a certificate of type #gnutls_x509_crt_t
1909
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1910
 * @flags: must be zero
1911
 *
1912
 * This function will set the certificate's subject public key
1913
 * information explicitly. This is intended to be used in the cases
1914
 * where a single public key (e.g., RSA) can be used for multiple
1915
 * signature algorithms (RSA PKCS1-1.5, and RSA-PSS).
1916
 *
1917
 * To export the public key (i.e., the SubjectPublicKeyInfo part), check
1918
 * gnutls_pubkey_import_x509().
1919
 *
1920
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1921
 *   negative error value.
1922
 *
1923
 * Since: 3.6.0
1924
 **/
1925
int gnutls_x509_crt_set_spki(gnutls_x509_crt_t crt,
1926
           const gnutls_x509_spki_t spki, unsigned int flags)
1927
0
{
1928
0
  int ret;
1929
0
  gnutls_pk_algorithm_t crt_pk;
1930
0
  gnutls_x509_spki_st tpki;
1931
0
  gnutls_pk_params_st params;
1932
0
  unsigned bits;
1933
1934
0
  if (crt == NULL) {
1935
0
    gnutls_assert();
1936
0
    return GNUTLS_E_INVALID_REQUEST;
1937
0
  }
1938
1939
0
  ret = _gnutls_x509_crt_get_mpis(crt, &params);
1940
0
  if (ret < 0) {
1941
0
    gnutls_assert();
1942
0
    return ret;
1943
0
  }
1944
1945
0
  bits = pubkey_to_bits(&params);
1946
0
  crt_pk = params.algo;
1947
1948
0
  if (!_gnutls_pk_are_compat(crt_pk, spki->pk)) {
1949
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1950
0
    goto cleanup;
1951
0
  }
1952
1953
0
  if (spki->pk != GNUTLS_PK_RSA_PSS) {
1954
0
    if (crt_pk == spki->pk) {
1955
0
      ret = 0;
1956
0
      goto cleanup;
1957
0
    }
1958
1959
0
    gnutls_assert();
1960
0
    ret = GNUTLS_E_INVALID_REQUEST;
1961
0
    goto cleanup;
1962
0
  }
1963
1964
0
  memset(&tpki, 0, sizeof(gnutls_x509_spki_st));
1965
1966
0
  if (crt_pk == GNUTLS_PK_RSA) {
1967
0
    const mac_entry_st *me;
1968
1969
0
    me = hash_to_entry(spki->rsa_pss_dig);
1970
0
    if (unlikely(me == NULL)) {
1971
0
      gnutls_assert();
1972
0
      ret = GNUTLS_E_INVALID_REQUEST;
1973
0
      goto cleanup;
1974
0
    }
1975
1976
0
    tpki.pk = spki->pk;
1977
0
    tpki.rsa_pss_dig = spki->rsa_pss_dig;
1978
1979
    /* If salt size is zero, find the optimal salt size. */
1980
0
    if (spki->salt_size == 0) {
1981
0
      ret = _gnutls_find_rsa_pss_salt_size(bits, me,
1982
0
                   spki->salt_size);
1983
0
      if (ret < 0) {
1984
0
        gnutls_assert();
1985
0
        goto cleanup;
1986
0
      }
1987
0
      tpki.salt_size = ret;
1988
0
    } else
1989
0
      tpki.salt_size = spki->salt_size;
1990
0
  } else if (crt_pk == GNUTLS_PK_RSA_PSS) {
1991
0
    ret = _gnutls_x509_crt_read_spki_params(crt, &tpki);
1992
0
    if (ret < 0) {
1993
0
      gnutls_assert();
1994
0
      goto cleanup;
1995
0
    }
1996
1997
0
    tpki.salt_size = spki->salt_size;
1998
0
    tpki.rsa_pss_dig = spki->rsa_pss_dig;
1999
0
  }
2000
2001
0
  ret = _gnutls_x509_spki_copy(&params.spki, &tpki);
2002
0
  if (ret < 0) {
2003
0
    gnutls_assert();
2004
0
    goto cleanup;
2005
0
  }
2006
0
  ret = _gnutls_x509_check_pubkey_params(&params);
2007
0
  if (ret < 0) {
2008
0
    gnutls_assert();
2009
0
    goto cleanup;
2010
0
  }
2011
2012
0
  MODIFIED(crt);
2013
2014
0
  ret = _gnutls_x509_write_spki_params(crt->cert,
2015
0
               "tbsCertificate."
2016
0
               "subjectPublicKeyInfo.algorithm",
2017
0
               &tpki);
2018
0
  if (ret < 0) {
2019
0
    gnutls_assert();
2020
0
    goto cleanup;
2021
0
  }
2022
2023
0
  ret = 0;
2024
0
cleanup:
2025
0
  gnutls_pk_params_release(&params);
2026
0
  _gnutls_x509_spki_clear(&tpki);
2027
0
  return ret;
2028
0
}