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, &params);
2042 	if (ret < 0) {
2043 		gnutls_assert();
2044 		return ret;
2045 	}
2046 
2047 	bits = pubkey_to_bits(&params);
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(&params.spki, &tpki, sizeof(tpki));
2104 	ret = _gnutls_x509_check_pubkey_params(&params);
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(&params);
2124 	return ret;
2125 }
2126