Coverage Report

Created: 2023-03-26 08:33

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