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