1 /*
2  * Copyright (C) 2003-2016 Free Software Foundation, Inc.
3  * Copyright (C) 2012-2016 Nikos Mavrogiannopoulos
4  * Copyright (C) 2016-2017 Red Hat, Inc.
5  *
6  * Author: Nikos Mavrogiannopoulos
7  *
8  * This file is part of GnuTLS.
9  *
10  * The GnuTLS is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public License
12  * as published by the Free Software Foundation; either version 2.1 of
13  * the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program.  If not, see <https://www.gnu.org/licenses/>
22  *
23  */
24 
25 /* This file contains functions to handle PKCS #10 certificate
26    requests, see RFC 2986.
27  */
28 
29 #include "gnutls_int.h"
30 
31 #include <datum.h>
32 #include <global.h>
33 #include "errors.h"
34 #include <common.h>
35 #include <x509.h>
36 #include <x509_b64.h>
37 #include <gnutls/x509-ext.h>
38 #include "x509_int.h"
39 #include <libtasn1.h>
40 #include <pk.h>
41 #include "attributes.h"
42 
43 /**
44  * gnutls_x509_crq_init:
45  * @crq: A pointer to the type to be initialized
46  *
47  * This function will initialize a PKCS#10 certificate request
48  * structure.
49  *
50  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
51  *   negative error value.
52  **/
gnutls_x509_crq_init(gnutls_x509_crq_t * crq)53 int gnutls_x509_crq_init(gnutls_x509_crq_t * crq)
54 {
55 	int result;
56 
57 	FAIL_IF_LIB_ERROR;
58 
59 	*crq = gnutls_calloc(1, sizeof(gnutls_x509_crq_int));
60 	if (!*crq)
61 		return GNUTLS_E_MEMORY_ERROR;
62 
63 	result = asn1_create_element(_gnutls_get_pkix(),
64 				     "PKIX1.pkcs-10-CertificationRequest",
65 				     &((*crq)->crq));
66 	if (result != ASN1_SUCCESS) {
67 		gnutls_assert();
68 		gnutls_free(*crq);
69 		return _gnutls_asn2err(result);
70 	}
71 
72 	return 0;
73 }
74 
75 /**
76  * gnutls_x509_crq_deinit:
77  * @crq: the type to be deinitialized
78  *
79  * This function will deinitialize a PKCS#10 certificate request
80  * structure.
81  **/
gnutls_x509_crq_deinit(gnutls_x509_crq_t crq)82 void gnutls_x509_crq_deinit(gnutls_x509_crq_t crq)
83 {
84 	if (!crq)
85 		return;
86 
87 	if (crq->crq)
88 		asn1_delete_structure(&crq->crq);
89 
90 	gnutls_free(crq);
91 }
92 
93 #define PEM_CRQ "NEW CERTIFICATE REQUEST"
94 #define PEM_CRQ2 "CERTIFICATE REQUEST"
95 
96 /**
97  * gnutls_x509_crq_import:
98  * @crq: The data to store the parsed certificate request.
99  * @data: The DER or PEM encoded certificate.
100  * @format: One of DER or PEM
101  *
102  * This function will convert the given DER or PEM encoded certificate
103  * request to a #gnutls_x509_crq_t type.  The output will be
104  * stored in @crq.
105  *
106  * If the Certificate is PEM encoded it should have a header of "NEW
107  * CERTIFICATE REQUEST".
108  *
109  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
110  *   negative error value.
111  **/
112 int
gnutls_x509_crq_import(gnutls_x509_crq_t crq,const gnutls_datum_t * data,gnutls_x509_crt_fmt_t format)113 gnutls_x509_crq_import(gnutls_x509_crq_t crq,
114 		       const gnutls_datum_t * data,
115 		       gnutls_x509_crt_fmt_t format)
116 {
117 	int result = 0, need_free = 0;
118 	gnutls_datum_t _data;
119 
120 	if (crq == NULL) {
121 		gnutls_assert();
122 		return GNUTLS_E_INVALID_REQUEST;
123 	}
124 
125 	_data.data = data->data;
126 	_data.size = data->size;
127 
128 	/* If the Certificate is in PEM format then decode it
129 	 */
130 	if (format == GNUTLS_X509_FMT_PEM) {
131 		/* Try the first header */
132 		result =
133 		    _gnutls_fbase64_decode(PEM_CRQ, data->data, data->size,
134 					   &_data);
135 
136 		if (result < 0)	/* Go for the second header */
137 			result =
138 			    _gnutls_fbase64_decode(PEM_CRQ2, data->data,
139 						   data->size, &_data);
140 
141 		if (result < 0) {
142 			gnutls_assert();
143 			return result;
144 		}
145 
146 		need_free = 1;
147 	}
148 
149 	result =
150 	    _asn1_strict_der_decode(&crq->crq, _data.data, _data.size, NULL);
151 	if (result != ASN1_SUCCESS) {
152 		result = _gnutls_asn2err(result);
153 		gnutls_assert();
154 		goto cleanup;
155 	}
156 
157 	result = 0;
158 
159       cleanup:
160 	if (need_free)
161 		_gnutls_free_datum(&_data);
162 	return result;
163 }
164 
165 /**
166  * gnutls_x509_crq_get_signature_algorithm:
167  * @crq: should contain a #gnutls_x509_cr_t type
168  *
169  * This function will return a value of the #gnutls_sign_algorithm_t
170  * enumeration that is the signature algorithm that has been used to
171  * sign this certificate request.
172  *
173  * Since 3.6.0 this function never returns a negative error code.
174  * Error cases and unknown/unsupported signature algorithms are
175  * mapped to %GNUTLS_SIGN_UNKNOWN.
176  *
177  * Returns: a #gnutls_sign_algorithm_t value
178  *
179  * Since: 3.4.0
180  **/
gnutls_x509_crq_get_signature_algorithm(gnutls_x509_crq_t crq)181 int gnutls_x509_crq_get_signature_algorithm(gnutls_x509_crq_t crq)
182 {
183 	return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(crq->crq,
184 						    "signatureAlgorithm"));
185 }
186 
187 /**
188  * gnutls_x509_crq_get_private_key_usage_period:
189  * @crq: should contain a #gnutls_x509_crq_t type
190  * @activation: The activation time
191  * @expiration: The expiration time
192  * @critical: the extension status
193  *
194  * This function will return the expiration and activation
195  * times of the private key of the certificate.
196  *
197  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
198  * if the extension is not present, otherwise a negative error value.
199  **/
200 int
gnutls_x509_crq_get_private_key_usage_period(gnutls_x509_crq_t crq,time_t * activation,time_t * expiration,unsigned int * critical)201 gnutls_x509_crq_get_private_key_usage_period(gnutls_x509_crq_t crq,
202 					     time_t * activation,
203 					     time_t * expiration,
204 					     unsigned int *critical)
205 {
206 	int result, ret;
207 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
208 	uint8_t buf[128];
209 	size_t buf_size = sizeof(buf);
210 
211 	if (crq == NULL) {
212 		gnutls_assert();
213 		return GNUTLS_E_INVALID_REQUEST;
214 	}
215 
216 	ret = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.16", 0,
217 						   buf, &buf_size,
218 						   critical);
219 	if (ret < 0)
220 		return gnutls_assert_val(ret);
221 
222 	result = asn1_create_element
223 	    (_gnutls_get_pkix(), "PKIX1.PrivateKeyUsagePeriod", &c2);
224 	if (result != ASN1_SUCCESS) {
225 		gnutls_assert();
226 		ret = _gnutls_asn2err(result);
227 		goto cleanup;
228 	}
229 
230 	result = _asn1_strict_der_decode(&c2, buf, buf_size, NULL);
231 	if (result != ASN1_SUCCESS) {
232 		gnutls_assert();
233 		ret = _gnutls_asn2err(result);
234 		goto cleanup;
235 	}
236 
237 	if (activation)
238 		*activation = _gnutls_x509_get_time(c2, "notBefore", 1);
239 
240 	if (expiration)
241 		*expiration = _gnutls_x509_get_time(c2, "notAfter", 1);
242 
243 	ret = 0;
244 
245       cleanup:
246 	asn1_delete_structure(&c2);
247 
248 	return ret;
249 }
250 
251 
252 /**
253  * gnutls_x509_crq_get_dn:
254  * @crq: should contain a #gnutls_x509_crq_t type
255  * @buf: a pointer to a structure to hold the name (may be %NULL)
256  * @buf_size: initially holds the size of @buf
257  *
258  * This function will copy the name of the Certificate request subject
259  * to the provided buffer.  The name will be in the form
260  * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC 2253. The output string
261  * @buf will be ASCII or UTF-8 encoded, depending on the certificate
262  * data.
263  *
264  * This function does not output a fully RFC4514 compliant string, if
265  * that is required see gnutls_x509_crq_get_dn3().
266  *
267  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
268  *   long enough, and in that case the *@buf_size will be updated with
269  *   the required size.  On success 0 is returned.
270  **/
271 int
gnutls_x509_crq_get_dn(gnutls_x509_crq_t crq,char * buf,size_t * buf_size)272 gnutls_x509_crq_get_dn(gnutls_x509_crq_t crq, char *buf, size_t * buf_size)
273 {
274 	if (crq == NULL) {
275 		gnutls_assert();
276 		return GNUTLS_E_INVALID_REQUEST;
277 	}
278 
279 	return _gnutls_x509_parse_dn(crq->crq,
280 				     "certificationRequestInfo.subject.rdnSequence",
281 				     buf, buf_size, GNUTLS_X509_DN_FLAG_COMPAT);
282 }
283 
284 /**
285  * gnutls_x509_crq_get_dn2:
286  * @crq: should contain a #gnutls_x509_crq_t type
287  * @dn: a pointer to a structure to hold the name
288  *
289  * This function will allocate buffer and copy the name of the Certificate
290  * request. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
291  * described in RFC4514. The output string will be ASCII or UTF-8
292  * encoded, depending on the certificate data.
293  *
294  * This function does not output a fully RFC4514 compliant string, if
295  * that is required see gnutls_x509_crq_get_dn3().
296  *
297  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
298  *   negative error value. and a negative error code on error.
299  *
300  * Since: 3.1.10
301  **/
gnutls_x509_crq_get_dn2(gnutls_x509_crq_t crq,gnutls_datum_t * dn)302 int gnutls_x509_crq_get_dn2(gnutls_x509_crq_t crq, gnutls_datum_t * dn)
303 {
304 	if (crq == NULL) {
305 		gnutls_assert();
306 		return GNUTLS_E_INVALID_REQUEST;
307 	}
308 
309 	return _gnutls_x509_get_dn(crq->crq,
310 				   "certificationRequestInfo.subject.rdnSequence",
311 				   dn, GNUTLS_X509_DN_FLAG_COMPAT);
312 }
313 
314 /**
315  * gnutls_x509_crq_get_dn3:
316  * @crq: should contain a #gnutls_x509_crq_t type
317  * @dn: a pointer to a structure to hold the name
318  * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
319  *
320  * This function will allocate buffer and copy the name of the Certificate
321  * request. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
322  * described in RFC4514. The output string will be ASCII or UTF-8
323  * encoded, depending on the certificate data.
324  *
325  * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
326  * format will match the format output by previous to 3.5.6 versions of GnuTLS
327  * which was not not fully RFC4514-compliant.
328  *
329  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
330  *   negative error value. and a negative error code on error.
331  *
332  * Since: 3.5.7
333  **/
gnutls_x509_crq_get_dn3(gnutls_x509_crq_t crq,gnutls_datum_t * dn,unsigned flags)334 int gnutls_x509_crq_get_dn3(gnutls_x509_crq_t crq, gnutls_datum_t * dn, unsigned flags)
335 {
336 	if (crq == NULL) {
337 		gnutls_assert();
338 		return GNUTLS_E_INVALID_REQUEST;
339 	}
340 
341 	return _gnutls_x509_get_dn(crq->crq,
342 				   "certificationRequestInfo.subject.rdnSequence",
343 				   dn, flags);
344 }
345 
346 /**
347  * gnutls_x509_crq_get_dn_by_oid:
348  * @crq: should contain a gnutls_x509_crq_t type
349  * @oid: holds an Object Identifier in a null terminated string
350  * @indx: In case multiple same OIDs exist in the RDN, this specifies
351  *   which to get. Use (0) to get the first one.
352  * @raw_flag: If non-zero returns the raw DER data of the DN part.
353  * @buf: a pointer to a structure to hold the name (may be %NULL)
354  * @buf_size: initially holds the size of @buf
355  *
356  * This function will extract the part of the name of the Certificate
357  * request subject, specified by the given OID. The output will be
358  * encoded as described in RFC2253. The output string will be ASCII
359  * or UTF-8 encoded, depending on the certificate data.
360  *
361  * Some helper macros with popular OIDs can be found in gnutls/x509.h
362  * If raw flag is (0), this function will only return known OIDs as
363  * text. Other OIDs will be DER encoded, as described in RFC2253 --
364  * in hex format with a '\#' prefix.  You can check about known OIDs
365  * using gnutls_x509_dn_oid_known().
366  *
367  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
368  *   not long enough, and in that case the *@buf_size will be
369  *   updated with the required size.  On success 0 is returned.
370  **/
371 int
gnutls_x509_crq_get_dn_by_oid(gnutls_x509_crq_t crq,const char * oid,unsigned indx,unsigned int raw_flag,void * buf,size_t * buf_size)372 gnutls_x509_crq_get_dn_by_oid(gnutls_x509_crq_t crq, const char *oid,
373 			      unsigned indx, unsigned int raw_flag,
374 			      void *buf, size_t * buf_size)
375 {
376 	gnutls_datum_t td;
377 	int ret;
378 
379 	if (crq == NULL) {
380 		gnutls_assert();
381 		return GNUTLS_E_INVALID_REQUEST;
382 	}
383 
384 	ret = _gnutls_x509_parse_dn_oid
385 	    (crq->crq,
386 	     "certificationRequestInfo.subject.rdnSequence",
387 	     oid, indx, raw_flag, &td);
388 	if (ret < 0)
389 		return gnutls_assert_val(ret);
390 
391 	return _gnutls_strdatum_to_buf(&td, buf, buf_size);
392 }
393 
394 /**
395  * gnutls_x509_crq_get_dn_oid:
396  * @crq: should contain a gnutls_x509_crq_t type
397  * @indx: Specifies which DN OID to get. Use (0) to get the first one.
398  * @oid: a pointer to a structure to hold the name (may be %NULL)
399  * @sizeof_oid: initially holds the size of @oid
400  *
401  * This function will extract the requested OID of the name of the
402  * certificate request subject, specified by the given index.
403  *
404  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
405  *   not long enough, and in that case the *@sizeof_oid will be
406  *   updated with the required size.  On success 0 is returned.
407  **/
408 int
gnutls_x509_crq_get_dn_oid(gnutls_x509_crq_t crq,unsigned indx,void * oid,size_t * sizeof_oid)409 gnutls_x509_crq_get_dn_oid(gnutls_x509_crq_t crq,
410 			   unsigned indx, void *oid, size_t * sizeof_oid)
411 {
412 	if (crq == NULL) {
413 		gnutls_assert();
414 		return GNUTLS_E_INVALID_REQUEST;
415 	}
416 
417 	return _gnutls_x509_get_dn_oid(crq->crq,
418 				       "certificationRequestInfo.subject.rdnSequence",
419 				       indx, oid, sizeof_oid);
420 }
421 
422 /**
423  * gnutls_x509_crq_get_challenge_password:
424  * @crq: should contain a #gnutls_x509_crq_t type
425  * @pass: will hold a (0)-terminated password string
426  * @pass_size: Initially holds the size of @pass.
427  *
428  * This function will return the challenge password in the request.
429  * The challenge password is intended to be used for requesting a
430  * revocation of the certificate.
431  *
432  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
433  *   negative error value.
434  **/
435 int
gnutls_x509_crq_get_challenge_password(gnutls_x509_crq_t crq,char * pass,size_t * pass_size)436 gnutls_x509_crq_get_challenge_password(gnutls_x509_crq_t crq,
437 				       char *pass, size_t * pass_size)
438 {
439 	gnutls_datum_t td;
440 	int ret;
441 
442 	if (crq == NULL) {
443 		gnutls_assert();
444 		return GNUTLS_E_INVALID_REQUEST;
445 	}
446 
447 	ret =
448 	    _x509_parse_attribute(crq->crq,
449 			    "certificationRequestInfo.attributes",
450 			    "1.2.840.113549.1.9.7", 0, 0, &td);
451 	if (ret < 0)
452 		return gnutls_assert_val(ret);
453 
454 	return _gnutls_strdatum_to_buf(&td, pass, pass_size);
455 }
456 
457 /**
458  * gnutls_x509_crq_set_attribute_by_oid:
459  * @crq: should contain a #gnutls_x509_crq_t type
460  * @oid: holds an Object Identifier in a null-terminated string
461  * @buf: a pointer to a structure that holds the attribute data
462  * @buf_size: holds the size of @buf
463  *
464  * This function will set the attribute in the certificate request
465  * specified by the given Object ID. The provided attribute must be be DER
466  * encoded.
467  *
468  * Attributes in a certificate request is an optional set of data
469  * appended to the request. Their interpretation depends on the CA policy.
470  *
471  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
472  *   negative error value.
473  **/
474 int
gnutls_x509_crq_set_attribute_by_oid(gnutls_x509_crq_t crq,const char * oid,void * buf,size_t buf_size)475 gnutls_x509_crq_set_attribute_by_oid(gnutls_x509_crq_t crq,
476 				     const char *oid, void *buf,
477 				     size_t buf_size)
478 {
479 	gnutls_datum_t data;
480 
481 	data.data = buf;
482 	data.size = buf_size;
483 
484 	if (crq == NULL) {
485 		gnutls_assert();
486 		return GNUTLS_E_INVALID_REQUEST;
487 	}
488 
489 	return _x509_set_attribute(crq->crq,
490 			     "certificationRequestInfo.attributes", oid,
491 			     &data);
492 }
493 
494 /**
495  * gnutls_x509_crq_get_attribute_by_oid:
496  * @crq: should contain a #gnutls_x509_crq_t type
497  * @oid: holds an Object Identifier in null-terminated string
498  * @indx: In case multiple same OIDs exist in the attribute list, this
499  *   specifies which to get, use (0) to get the first one
500  * @buf: a pointer to a structure to hold the attribute data (may be %NULL)
501  * @buf_size: initially holds the size of @buf
502  *
503  * This function will return the attribute in the certificate request
504  * specified by the given Object ID.  The attribute will be DER
505  * encoded.
506  *
507  * Attributes in a certificate request is an optional set of data
508  * appended to the request. Their interpretation depends on the CA policy.
509  *
510  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
511  *   negative error value.
512  **/
513 int
gnutls_x509_crq_get_attribute_by_oid(gnutls_x509_crq_t crq,const char * oid,unsigned indx,void * buf,size_t * buf_size)514 gnutls_x509_crq_get_attribute_by_oid(gnutls_x509_crq_t crq,
515 				     const char *oid, unsigned indx, void *buf,
516 				     size_t * buf_size)
517 {
518 	int ret;
519 	gnutls_datum_t td;
520 
521 	if (crq == NULL) {
522 		gnutls_assert();
523 		return GNUTLS_E_INVALID_REQUEST;
524 	}
525 
526 	ret =
527 	    _x509_parse_attribute(crq->crq,
528 			    "certificationRequestInfo.attributes", oid,
529 			    indx, 1, &td);
530 	if (ret < 0)
531 		return gnutls_assert_val(ret);
532 
533 	return _gnutls_strdatum_to_buf(&td, buf, buf_size);
534 }
535 
536 /**
537  * gnutls_x509_crq_set_dn_by_oid:
538  * @crq: should contain a #gnutls_x509_crq_t type
539  * @oid: holds an Object Identifier in a (0)-terminated string
540  * @raw_flag: must be 0, or 1 if the data are DER encoded
541  * @data: a pointer to the input data
542  * @sizeof_data: holds the size of @data
543  *
544  * This function will set the part of the name of the Certificate
545  * request subject, specified by the given OID.  The input string
546  * should be ASCII or UTF-8 encoded.
547  *
548  * Some helper macros with popular OIDs can be found in gnutls/x509.h
549  * With this function you can only set the known OIDs.  You can test
550  * for known OIDs using gnutls_x509_dn_oid_known().  For OIDs that are
551  * not known (by gnutls) you should properly DER encode your data, and
552  * call this function with raw_flag set.
553  *
554  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
555  *   negative error value.
556  **/
557 int
gnutls_x509_crq_set_dn_by_oid(gnutls_x509_crq_t crq,const char * oid,unsigned int raw_flag,const void * data,unsigned int sizeof_data)558 gnutls_x509_crq_set_dn_by_oid(gnutls_x509_crq_t crq, const char *oid,
559 			      unsigned int raw_flag, const void *data,
560 			      unsigned int sizeof_data)
561 {
562 	if (sizeof_data == 0 || data == NULL || crq == NULL) {
563 		return GNUTLS_E_INVALID_REQUEST;
564 	}
565 
566 	return _gnutls_x509_set_dn_oid(crq->crq,
567 				       "certificationRequestInfo.subject",
568 				       oid, raw_flag, data, sizeof_data);
569 }
570 
571 /**
572  * gnutls_x509_crq_set_version:
573  * @crq: should contain a #gnutls_x509_crq_t type
574  * @version: holds the version number, for v1 Requests must be 1
575  *
576  * This function will set the version of the certificate request.  For
577  * version 1 requests this must be one.
578  *
579  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
580  *   negative error value.
581  **/
582 int
gnutls_x509_crq_set_version(gnutls_x509_crq_t crq,unsigned int version)583 gnutls_x509_crq_set_version(gnutls_x509_crq_t crq, unsigned int version)
584 {
585 	int result;
586 	unsigned char null = version;
587 
588 	if (crq == NULL) {
589 		gnutls_assert();
590 		return GNUTLS_E_INVALID_REQUEST;
591 	}
592 
593 	if (null > 0)
594 		null--;
595 
596 	result =
597 	    asn1_write_value(crq->crq, "certificationRequestInfo.version",
598 			     &null, 1);
599 	if (result != ASN1_SUCCESS) {
600 		gnutls_assert();
601 		return _gnutls_asn2err(result);
602 	}
603 
604 	return 0;
605 }
606 
607 /**
608  * gnutls_x509_crq_get_version:
609  * @crq: should contain a #gnutls_x509_crq_t type
610  *
611  * This function will return the version of the specified Certificate
612  * request.
613  *
614  * Returns: version of certificate request, or a negative error code on
615  *   error.
616  **/
gnutls_x509_crq_get_version(gnutls_x509_crq_t crq)617 int gnutls_x509_crq_get_version(gnutls_x509_crq_t crq)
618 {
619 	uint8_t version[8];
620 	int len, result;
621 
622 	if (crq == NULL) {
623 		gnutls_assert();
624 		return GNUTLS_E_INVALID_REQUEST;
625 	}
626 
627 	len = sizeof(version);
628 	if ((result =
629 	     asn1_read_value(crq->crq, "certificationRequestInfo.version",
630 			     version, &len)) != ASN1_SUCCESS) {
631 
632 		if (result == ASN1_ELEMENT_NOT_FOUND)
633 			return 1;	/* the DEFAULT version */
634 		gnutls_assert();
635 		return _gnutls_asn2err(result);
636 	}
637 
638 	return (int) version[0] + 1;
639 }
640 
641 /**
642  * gnutls_x509_crq_set_key:
643  * @crq: should contain a #gnutls_x509_crq_t type
644  * @key: holds a private key
645  *
646  * This function will set the public parameters from the given private
647  * key to the request.
648  *
649  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
650  *   negative error value.
651  **/
652 int
gnutls_x509_crq_set_key(gnutls_x509_crq_t crq,gnutls_x509_privkey_t key)653 gnutls_x509_crq_set_key(gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
654 {
655 	int result;
656 
657 	if (crq == NULL) {
658 		gnutls_assert();
659 		return GNUTLS_E_INVALID_REQUEST;
660 	}
661 
662 	result = _gnutls_x509_encode_and_copy_PKI_params
663 	    (crq->crq,
664 	     "certificationRequestInfo.subjectPKInfo",
665 	     &key->params);
666 
667 	if (result < 0) {
668 		gnutls_assert();
669 		return result;
670 	}
671 
672 	return 0;
673 }
674 
675 /**
676  * gnutls_x509_crq_get_key_rsa_raw:
677  * @crq: Holds the certificate
678  * @m: will hold the modulus
679  * @e: will hold the public exponent
680  *
681  * This function will export the RSA public key's parameters found in
682  * the given structure.  The new parameters will be allocated using
683  * gnutls_malloc() and will be stored in the appropriate datum.
684  *
685  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
686  *   negative error value.
687  *
688  * Since: 2.8.0
689  **/
690 int
gnutls_x509_crq_get_key_rsa_raw(gnutls_x509_crq_t crq,gnutls_datum_t * m,gnutls_datum_t * e)691 gnutls_x509_crq_get_key_rsa_raw(gnutls_x509_crq_t crq,
692 				gnutls_datum_t * m, gnutls_datum_t * e)
693 {
694 	int ret;
695 	gnutls_pk_params_st params;
696 
697 	gnutls_pk_params_init(&params);
698 
699 	if (crq == NULL) {
700 		gnutls_assert();
701 		return GNUTLS_E_INVALID_REQUEST;
702 	}
703 
704 	ret = gnutls_x509_crq_get_pk_algorithm(crq, NULL);
705 	if (ret != GNUTLS_PK_RSA) {
706 		gnutls_assert();
707 		return GNUTLS_E_INVALID_REQUEST;
708 	}
709 
710 	ret = _gnutls_x509_crq_get_mpis(crq, &params);
711 	if (ret < 0) {
712 		gnutls_assert();
713 		return ret;
714 	}
715 
716 	ret = _gnutls_mpi_dprint(params.params[0], m);
717 	if (ret < 0) {
718 		gnutls_assert();
719 		goto cleanup;
720 	}
721 
722 	ret = _gnutls_mpi_dprint(params.params[1], e);
723 	if (ret < 0) {
724 		gnutls_assert();
725 		_gnutls_free_datum(m);
726 		goto cleanup;
727 	}
728 
729 	ret = 0;
730 
731       cleanup:
732 	gnutls_pk_params_release(&params);
733 	return ret;
734 }
735 
736 /**
737  * gnutls_x509_crq_set_key_rsa_raw:
738  * @crq: should contain a #gnutls_x509_crq_t type
739  * @m: holds the modulus
740  * @e: holds the public exponent
741  *
742  * This function will set the public parameters from the given private
743  * key to the request. Only RSA keys are currently supported.
744  *
745  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
746  *   negative error value.
747  *
748  * Since: 2.6.0
749  **/
750 int
gnutls_x509_crq_set_key_rsa_raw(gnutls_x509_crq_t crq,const gnutls_datum_t * m,const gnutls_datum_t * e)751 gnutls_x509_crq_set_key_rsa_raw(gnutls_x509_crq_t crq,
752 				const gnutls_datum_t * m,
753 				const gnutls_datum_t * e)
754 {
755 	int result, ret;
756 	size_t siz = 0;
757 	gnutls_pk_params_st temp_params;
758 
759 	gnutls_pk_params_init(&temp_params);
760 
761 	if (crq == NULL) {
762 		gnutls_assert();
763 		return GNUTLS_E_INVALID_REQUEST;
764 	}
765 
766 	memset(&temp_params, 0, sizeof(temp_params));
767 
768 	siz = m->size;
769 	if (_gnutls_mpi_init_scan_nz(&temp_params.params[0], m->data, siz)) {
770 		gnutls_assert();
771 		ret = GNUTLS_E_MPI_SCAN_FAILED;
772 		goto error;
773 	}
774 
775 	siz = e->size;
776 	if (_gnutls_mpi_init_scan_nz(&temp_params.params[1], e->data, siz)) {
777 		gnutls_assert();
778 		ret = GNUTLS_E_MPI_SCAN_FAILED;
779 		goto error;
780 	}
781 
782 	temp_params.params_nr = RSA_PUBLIC_PARAMS;
783 	temp_params.algo = GNUTLS_PK_RSA;
784 
785 	result = _gnutls_x509_encode_and_copy_PKI_params
786 	    (crq->crq,
787 	     "certificationRequestInfo.subjectPKInfo",
788 	     &temp_params);
789 
790 	if (result < 0) {
791 		gnutls_assert();
792 		ret = result;
793 		goto error;
794 	}
795 
796 	ret = 0;
797 
798       error:
799 	gnutls_pk_params_release(&temp_params);
800 	return ret;
801 }
802 
803 /**
804  * gnutls_x509_crq_set_challenge_password:
805  * @crq: should contain a #gnutls_x509_crq_t type
806  * @pass: holds a (0)-terminated password
807  *
808  * This function will set a challenge password to be used when
809  * revoking the request.
810  *
811  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
812  *   negative error value.
813  **/
814 int
gnutls_x509_crq_set_challenge_password(gnutls_x509_crq_t crq,const char * pass)815 gnutls_x509_crq_set_challenge_password(gnutls_x509_crq_t crq,
816 				       const char *pass)
817 {
818 	int result;
819 	char *password = NULL;
820 
821 	if (crq == NULL || pass == NULL) {
822 		gnutls_assert();
823 		return GNUTLS_E_INVALID_REQUEST;
824 	}
825 
826 	/* Add the attribute.
827 	 */
828 	result =
829 	    asn1_write_value(crq->crq,
830 			     "certificationRequestInfo.attributes", "NEW",
831 			     1);
832 	if (result != ASN1_SUCCESS) {
833 		gnutls_assert();
834 		return _gnutls_asn2err(result);
835 	}
836 
837 	if (pass) {
838 		gnutls_datum_t out;
839 		result = _gnutls_utf8_password_normalize(pass, strlen(pass), &out, 0);
840 		if (result < 0)
841 			return gnutls_assert_val(result);
842 
843 		password = (char*)out.data;
844 	}
845 
846 	assert(password != NULL);
847 
848 	result = _gnutls_x509_encode_and_write_attribute
849 	    ("1.2.840.113549.1.9.7", crq->crq,
850 	     "certificationRequestInfo.attributes.?LAST", password,
851 	     strlen(password), 1);
852 	if (result < 0) {
853 		gnutls_assert();
854 		goto cleanup;
855 	}
856 
857 	result = 0;
858 
859  cleanup:
860 	gnutls_free(password);
861 	return result;
862 }
863 
864 /**
865  * gnutls_x509_crq_sign2:
866  * @crq: should contain a #gnutls_x509_crq_t type
867  * @key: holds a private key
868  * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA256
869  * @flags: must be 0
870  *
871  * This function will sign the certificate request with a private key.
872  * This must be the same key as the one used in
873  * gnutls_x509_crt_set_key() since a certificate request is self
874  * signed.
875  *
876  * This must be the last step in a certificate request generation
877  * since all the previously set parameters are now signed.
878  *
879  * A known limitation of this function is, that a newly-signed request will not
880  * be fully functional (e.g., for signature verification), until it
881  * is exported an re-imported.
882  *
883  * After GnuTLS 3.6.1 the value of @dig may be %GNUTLS_DIG_UNKNOWN,
884  * and in that case, a suitable but reasonable for the key algorithm will be selected.
885  *
886  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
887  *   %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
888  *   information in the certificate request (e.g., the version using
889  *   gnutls_x509_crq_set_version()).
890  *
891  **/
892 int
gnutls_x509_crq_sign2(gnutls_x509_crq_t crq,gnutls_x509_privkey_t key,gnutls_digest_algorithm_t dig,unsigned int flags)893 gnutls_x509_crq_sign2(gnutls_x509_crq_t crq, gnutls_x509_privkey_t key,
894 		      gnutls_digest_algorithm_t dig, unsigned int flags)
895 {
896 	int result;
897 	gnutls_privkey_t privkey;
898 
899 	if (crq == NULL) {
900 		gnutls_assert();
901 		return GNUTLS_E_INVALID_REQUEST;
902 	}
903 
904 	result = gnutls_privkey_init(&privkey);
905 	if (result < 0) {
906 		gnutls_assert();
907 		return result;
908 	}
909 
910 	result = gnutls_privkey_import_x509(privkey, key, 0);
911 	if (result < 0) {
912 		gnutls_assert();
913 		goto fail;
914 	}
915 
916 	result = gnutls_x509_crq_privkey_sign(crq, privkey, dig, flags);
917 	if (result < 0) {
918 		gnutls_assert();
919 		goto fail;
920 	}
921 
922 	result = 0;
923 
924       fail:
925 	gnutls_privkey_deinit(privkey);
926 
927 	return result;
928 }
929 
930 /**
931  * gnutls_x509_crq_sign:
932  * @crq: should contain a #gnutls_x509_crq_t type
933  * @key: holds a private key
934  *
935  * This function is the same a gnutls_x509_crq_sign2() with no flags,
936  * and an appropriate hash algorithm. The hash algorithm used may
937  * vary between versions of GnuTLS, and it is tied to the security
938  * level of the issuer's public key.
939  *
940  * A known limitation of this function is, that a newly-signed request will not
941  * be fully functional (e.g., for signature verification), until it
942  * is exported an re-imported.
943  *
944  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
945  *   negative error value.
946  */
gnutls_x509_crq_sign(gnutls_x509_crq_t crq,gnutls_x509_privkey_t key)947 int gnutls_x509_crq_sign(gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
948 {
949 	return gnutls_x509_crq_sign2(crq, key, 0, 0);
950 }
951 
952 /**
953  * gnutls_x509_crq_export:
954  * @crq: should contain a #gnutls_x509_crq_t type
955  * @format: the format of output params. One of PEM or DER.
956  * @output_data: will contain a certificate request PEM or DER encoded
957  * @output_data_size: holds the size of output_data (and will be
958  *   replaced by the actual size of parameters)
959  *
960  * This function will export the certificate request to a PEM or DER
961  * encoded PKCS10 structure.
962  *
963  * If the buffer provided is not long enough to hold the output, then
964  * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
965  * *@output_data_size will be updated.
966  *
967  * If the structure is PEM encoded, it will have a header of "BEGIN
968  * NEW CERTIFICATE REQUEST".
969  *
970  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
971  *   negative error value.
972  **/
973 int
gnutls_x509_crq_export(gnutls_x509_crq_t crq,gnutls_x509_crt_fmt_t format,void * output_data,size_t * output_data_size)974 gnutls_x509_crq_export(gnutls_x509_crq_t crq,
975 		       gnutls_x509_crt_fmt_t format, void *output_data,
976 		       size_t * output_data_size)
977 {
978 	if (crq == NULL) {
979 		gnutls_assert();
980 		return GNUTLS_E_INVALID_REQUEST;
981 	}
982 
983 	return _gnutls_x509_export_int(crq->crq, format, PEM_CRQ,
984 				       output_data, output_data_size);
985 }
986 
987 /**
988  * gnutls_x509_crq_export2:
989  * @crq: should contain a #gnutls_x509_crq_t type
990  * @format: the format of output params. One of PEM or DER.
991  * @out: will contain a certificate request PEM or DER encoded
992  *
993  * This function will export the certificate request to a PEM or DER
994  * encoded PKCS10 structure.
995  *
996  * The output buffer is allocated using gnutls_malloc().
997  *
998  * If the structure is PEM encoded, it will have a header of "BEGIN
999  * NEW CERTIFICATE REQUEST".
1000  *
1001  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1002  *   negative error value.
1003  *
1004  * Since 3.1.3
1005  **/
1006 int
gnutls_x509_crq_export2(gnutls_x509_crq_t crq,gnutls_x509_crt_fmt_t format,gnutls_datum_t * out)1007 gnutls_x509_crq_export2(gnutls_x509_crq_t crq,
1008 			gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
1009 {
1010 	if (crq == NULL) {
1011 		gnutls_assert();
1012 		return GNUTLS_E_INVALID_REQUEST;
1013 	}
1014 
1015 	return _gnutls_x509_export_int2(crq->crq, format, PEM_CRQ, out);
1016 }
1017 
1018 /**
1019  * gnutls_x509_crq_get_pk_algorithm:
1020  * @crq: should contain a #gnutls_x509_crq_t type
1021  * @bits: if bits is non-%NULL it will hold the size of the parameters' in bits
1022  *
1023  * This function will return the public key algorithm of a PKCS#10
1024  * certificate request.
1025  *
1026  * If bits is non-%NULL, it should have enough size to hold the
1027  * parameters size in bits.  For RSA the bits returned is the modulus.
1028  * For DSA the bits returned are of the public exponent.
1029  *
1030  * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1031  *   success, or a negative error code on error.
1032  **/
1033 int
gnutls_x509_crq_get_pk_algorithm(gnutls_x509_crq_t crq,unsigned int * bits)1034 gnutls_x509_crq_get_pk_algorithm(gnutls_x509_crq_t crq, unsigned int *bits)
1035 {
1036 	int result;
1037 
1038 	if (crq == NULL) {
1039 		gnutls_assert();
1040 		return GNUTLS_E_INVALID_REQUEST;
1041 	}
1042 
1043 	result = _gnutls_x509_get_pk_algorithm
1044 	    (crq->crq, "certificationRequestInfo.subjectPKInfo", NULL, bits);
1045 	if (result < 0) {
1046 		gnutls_assert();
1047 		return result;
1048 	}
1049 
1050 	return result;
1051 }
1052 
1053 /**
1054  * gnutls_x509_crq_get_spki;
1055  * @crq: should contain a #gnutls_x509_crq_t type
1056  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1057  * @flags: must be zero
1058  *
1059  * This function will return the public key information of a PKCS#10
1060  * certificate request. The provided @spki must be initialized.
1061  *
1062  * Returns: Zero on success, or a negative error code on error.
1063  **/
1064 int
gnutls_x509_crq_get_spki(gnutls_x509_crq_t crq,gnutls_x509_spki_t spki,unsigned int flags)1065 gnutls_x509_crq_get_spki(gnutls_x509_crq_t crq,
1066 			 gnutls_x509_spki_t spki,
1067 			 unsigned int flags)
1068 {
1069 	int result;
1070 	gnutls_x509_spki_st params;
1071 
1072 	if (crq == NULL) {
1073 		gnutls_assert();
1074 		return GNUTLS_E_INVALID_REQUEST;
1075 	}
1076 
1077 	memset(&params, 0, sizeof(params));
1078 
1079 	spki->pk = gnutls_x509_crq_get_pk_algorithm(crq, NULL);
1080 
1081 	result = _gnutls_x509_crq_read_spki_params(crq, &params);
1082 	if (result < 0) {
1083 		gnutls_assert();
1084 		return result;
1085 	}
1086 
1087 	if (params.pk == GNUTLS_PK_UNKNOWN)
1088 		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1089 
1090 	spki->rsa_pss_dig = params.rsa_pss_dig;
1091 	spki->salt_size = params.salt_size;
1092 
1093 	return 0;
1094 }
1095 
1096 /**
1097  * gnutls_x509_crq_get_signature_oid:
1098  * @crq: should contain a #gnutls_x509_crq_t type
1099  * @oid: a pointer to a buffer to hold the OID (may be null)
1100  * @oid_size: initially holds the size of @oid
1101  *
1102  * This function will return the OID of the signature algorithm
1103  * that has been used to sign this certificate request. This function
1104  * is useful in the case gnutls_x509_crq_get_signature_algorithm()
1105  * returned %GNUTLS_SIGN_UNKNOWN.
1106  *
1107  * Returns: zero or a negative error code on error.
1108  *
1109  * Since: 3.5.0
1110  **/
gnutls_x509_crq_get_signature_oid(gnutls_x509_crq_t crq,char * oid,size_t * oid_size)1111 int gnutls_x509_crq_get_signature_oid(gnutls_x509_crq_t crq, char *oid, size_t *oid_size)
1112 {
1113 	char str[MAX_OID_SIZE];
1114 	int len, result, ret;
1115 	gnutls_datum_t out;
1116 
1117 	len = sizeof(str);
1118 	result = asn1_read_value(crq->crq, "signatureAlgorithm.algorithm", str, &len);
1119 	if (result != ASN1_SUCCESS) {
1120 		gnutls_assert();
1121 		return _gnutls_asn2err(result);
1122 	}
1123 
1124 	out.data = (void*)str;
1125 	out.size = len;
1126 
1127 	ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
1128 	if (ret < 0) {
1129 		gnutls_assert();
1130 		return ret;
1131 	}
1132 
1133 	return 0;
1134 }
1135 
1136 /**
1137  * gnutls_x509_crq_get_pk_oid:
1138  * @crq: should contain a #gnutls_x509_crq_t type
1139  * @oid: a pointer to a buffer to hold the OID (may be null)
1140  * @oid_size: initially holds the size of @oid
1141  *
1142  * This function will return the OID of the public key algorithm
1143  * on that certificate request. This function
1144  * is useful in the case gnutls_x509_crq_get_pk_algorithm()
1145  * returned %GNUTLS_PK_UNKNOWN.
1146  *
1147  * Returns: zero or a negative error code on error.
1148  *
1149  * Since: 3.5.0
1150  **/
gnutls_x509_crq_get_pk_oid(gnutls_x509_crq_t crq,char * oid,size_t * oid_size)1151 int gnutls_x509_crq_get_pk_oid(gnutls_x509_crq_t crq, char *oid, size_t *oid_size)
1152 {
1153 	char str[MAX_OID_SIZE];
1154 	int len, result, ret;
1155 	gnutls_datum_t out;
1156 
1157 	len = sizeof(str);
1158 	result = asn1_read_value(crq->crq, "certificationRequestInfo.subjectPKInfo.algorithm.algorithm", str, &len);
1159 	if (result != ASN1_SUCCESS) {
1160 		gnutls_assert();
1161 		return _gnutls_asn2err(result);
1162 	}
1163 
1164 	out.data = (void*)str;
1165 	out.size = len;
1166 
1167 	ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
1168 	if (ret < 0) {
1169 		gnutls_assert();
1170 		return ret;
1171 	}
1172 
1173 	return 0;
1174 }
1175 
1176 /**
1177  * gnutls_x509_crq_get_attribute_info:
1178  * @crq: should contain a #gnutls_x509_crq_t type
1179  * @indx: Specifies which attribute number to get. Use (0) to get the first one.
1180  * @oid: a pointer to a structure to hold the OID
1181  * @sizeof_oid: initially holds the maximum size of @oid, on return
1182  *   holds actual size of @oid.
1183  *
1184  * This function will return the requested attribute OID in the
1185  * certificate, and the critical flag for it.  The attribute OID will
1186  * be stored as a string in the provided buffer.  Use
1187  * gnutls_x509_crq_get_attribute_data() to extract the data.
1188  *
1189  * If the buffer provided is not long enough to hold the output, then
1190  * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1191  * returned.
1192  *
1193  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1194  *   negative error code in case of an error.  If your have reached the
1195  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1196  *   will be returned.
1197  *
1198  * Since: 2.8.0
1199  **/
1200 int
gnutls_x509_crq_get_attribute_info(gnutls_x509_crq_t crq,unsigned indx,void * oid,size_t * sizeof_oid)1201 gnutls_x509_crq_get_attribute_info(gnutls_x509_crq_t crq, unsigned indx,
1202 				   void *oid, size_t * sizeof_oid)
1203 {
1204 	int result;
1205 	char name[MAX_NAME_SIZE];
1206 	int len;
1207 
1208 	if (!crq) {
1209 		gnutls_assert();
1210 		return GNUTLS_E_INVALID_REQUEST;
1211 	}
1212 
1213 	snprintf(name, sizeof(name),
1214 		 "certificationRequestInfo.attributes.?%u.type", indx + 1);
1215 
1216 	len = *sizeof_oid;
1217 	result = asn1_read_value(crq->crq, name, oid, &len);
1218 	*sizeof_oid = len;
1219 
1220 	if (result == ASN1_ELEMENT_NOT_FOUND)
1221 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1222 	else if (result < 0) {
1223 		gnutls_assert();
1224 		return _gnutls_asn2err(result);
1225 	}
1226 
1227 	return 0;
1228 
1229 }
1230 
1231 /**
1232  * gnutls_x509_crq_get_attribute_data:
1233  * @crq: should contain a #gnutls_x509_crq_t type
1234  * @indx: Specifies which attribute number to get. Use (0) to get the first one.
1235  * @data: a pointer to a structure to hold the data (may be null)
1236  * @sizeof_data: initially holds the size of @oid
1237  *
1238  * This function will return the requested attribute data in the
1239  * certificate request.  The attribute data will be stored as a string in the
1240  * provided buffer.
1241  *
1242  * Use gnutls_x509_crq_get_attribute_info() to extract the OID.
1243  * Use gnutls_x509_crq_get_attribute_by_oid() instead,
1244  * if you want to get data indexed by the attribute OID rather than
1245  * sequence.
1246  *
1247  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1248  *   negative error code in case of an error.  If your have reached the
1249  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1250  *   will be returned.
1251  *
1252  * Since: 2.8.0
1253  **/
1254 int
gnutls_x509_crq_get_attribute_data(gnutls_x509_crq_t crq,unsigned indx,void * data,size_t * sizeof_data)1255 gnutls_x509_crq_get_attribute_data(gnutls_x509_crq_t crq, unsigned indx,
1256 				   void *data, size_t * sizeof_data)
1257 {
1258 	int result, len;
1259 	char name[MAX_NAME_SIZE];
1260 
1261 	if (!crq) {
1262 		gnutls_assert();
1263 		return GNUTLS_E_INVALID_REQUEST;
1264 	}
1265 
1266 	snprintf(name, sizeof(name),
1267 		 "certificationRequestInfo.attributes.?%u.values.?1",
1268 		 indx + 1);
1269 
1270 	len = *sizeof_data;
1271 	result = asn1_read_value(crq->crq, name, data, &len);
1272 	*sizeof_data = len;
1273 
1274 	if (result == ASN1_ELEMENT_NOT_FOUND)
1275 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1276 	else if (result < 0) {
1277 		gnutls_assert();
1278 		return _gnutls_asn2err(result);
1279 	}
1280 
1281 	return 0;
1282 }
1283 
1284 /**
1285  * gnutls_x509_crq_get_extension_info:
1286  * @crq: should contain a #gnutls_x509_crq_t type
1287  * @indx: Specifies which extension number to get. Use (0) to get the first one.
1288  * @oid: a pointer to store the OID
1289  * @sizeof_oid: initially holds the maximum size of @oid, on return
1290  *   holds actual size of @oid.
1291  * @critical: output variable with critical flag, may be NULL.
1292  *
1293  * This function will return the requested extension OID in the
1294  * certificate, and the critical flag for it.  The extension OID will
1295  * be stored as a string in the provided buffer.  Use
1296  * gnutls_x509_crq_get_extension_data() to extract the data.
1297  *
1298  * If the buffer provided is not long enough to hold the output, then
1299  * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1300  * returned.
1301  *
1302  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1303  *   negative error code in case of an error.  If your have reached the
1304  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1305  *   will be returned.
1306  *
1307  * Since: 2.8.0
1308  **/
1309 int
gnutls_x509_crq_get_extension_info(gnutls_x509_crq_t crq,unsigned indx,void * oid,size_t * sizeof_oid,unsigned int * critical)1310 gnutls_x509_crq_get_extension_info(gnutls_x509_crq_t crq, unsigned indx,
1311 				   void *oid, size_t * sizeof_oid,
1312 				   unsigned int *critical)
1313 {
1314 	int result;
1315 	char str_critical[10];
1316 	char name[MAX_NAME_SIZE];
1317 	char *extensions = NULL;
1318 	size_t extensions_size = 0;
1319 	ASN1_TYPE c2;
1320 	int len;
1321 
1322 	if (!crq) {
1323 		gnutls_assert();
1324 		return GNUTLS_E_INVALID_REQUEST;
1325 	}
1326 
1327 	/* read extensionRequest */
1328 	result =
1329 	    gnutls_x509_crq_get_attribute_by_oid(crq,
1330 						 "1.2.840.113549.1.9.14",
1331 						 0, NULL,
1332 						 &extensions_size);
1333 	if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
1334 		extensions = gnutls_malloc(extensions_size);
1335 		if (extensions == NULL) {
1336 			gnutls_assert();
1337 			return GNUTLS_E_MEMORY_ERROR;
1338 		}
1339 
1340 		result = gnutls_x509_crq_get_attribute_by_oid(crq,
1341 							      "1.2.840.113549.1.9.14",
1342 							      0,
1343 							      extensions,
1344 							      &extensions_size);
1345 	}
1346 	if (result < 0) {
1347 		gnutls_assert();
1348 		goto out;
1349 	}
1350 
1351 	result =
1352 	    asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extensions",
1353 				&c2);
1354 	if (result != ASN1_SUCCESS) {
1355 		gnutls_assert();
1356 		result = _gnutls_asn2err(result);
1357 		goto out;
1358 	}
1359 
1360 	result = _asn1_strict_der_decode(&c2, extensions, extensions_size, NULL);
1361 	if (result != ASN1_SUCCESS) {
1362 		gnutls_assert();
1363 		asn1_delete_structure(&c2);
1364 		result = _gnutls_asn2err(result);
1365 		goto out;
1366 	}
1367 
1368 	snprintf(name, sizeof(name), "?%u.extnID", indx + 1);
1369 
1370 	len = *sizeof_oid;
1371 	result = asn1_read_value(c2, name, oid, &len);
1372 	*sizeof_oid = len;
1373 
1374 	if (result == ASN1_ELEMENT_NOT_FOUND) {
1375 		asn1_delete_structure(&c2);
1376 		result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1377 		goto out;
1378 	} else if (result < 0) {
1379 		gnutls_assert();
1380 		asn1_delete_structure(&c2);
1381 		result = _gnutls_asn2err(result);
1382 		goto out;
1383 	}
1384 
1385 	snprintf(name, sizeof(name), "?%u.critical", indx + 1);
1386 	len = sizeof(str_critical);
1387 	result = asn1_read_value(c2, name, str_critical, &len);
1388 
1389 	asn1_delete_structure(&c2);
1390 
1391 	if (result < 0) {
1392 		gnutls_assert();
1393 		result = _gnutls_asn2err(result);
1394 		goto out;
1395 	}
1396 
1397 	if (critical) {
1398 		if (str_critical[0] == 'T')
1399 			*critical = 1;
1400 		else
1401 			*critical = 0;
1402 	}
1403 
1404 	result = 0;
1405 
1406       out:
1407 	gnutls_free(extensions);
1408 	return result;
1409 }
1410 
1411 /**
1412  * gnutls_x509_crq_get_extension_data:
1413  * @crq: should contain a #gnutls_x509_crq_t type
1414  * @indx: Specifies which extension number to get. Use (0) to get the first one.
1415  * @data: a pointer to a structure to hold the data (may be null)
1416  * @sizeof_data: initially holds the size of @oid
1417  *
1418  * This function will return the requested extension data in the
1419  * certificate.  The extension data will be stored as a string in the
1420  * provided buffer.
1421  *
1422  * Use gnutls_x509_crq_get_extension_info() to extract the OID and
1423  * critical flag.  Use gnutls_x509_crq_get_extension_by_oid() instead,
1424  * if you want to get data indexed by the extension OID rather than
1425  * sequence.
1426  *
1427  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1428  *   negative error code in case of an error.  If your have reached the
1429  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1430  *   will be returned.
1431  *
1432  * Since: 2.8.0
1433  **/
1434 int
gnutls_x509_crq_get_extension_data(gnutls_x509_crq_t crq,unsigned indx,void * data,size_t * sizeof_data)1435 gnutls_x509_crq_get_extension_data(gnutls_x509_crq_t crq, unsigned indx,
1436 				   void *data, size_t * sizeof_data)
1437 {
1438 	int ret;
1439 	gnutls_datum_t raw;
1440 
1441 	ret = gnutls_x509_crq_get_extension_data2(crq, indx, &raw);
1442 	if (ret < 0)
1443 		return gnutls_assert_val(ret);
1444 
1445 	ret = _gnutls_copy_data(&raw, data, sizeof_data);
1446 	if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && data == NULL)
1447 		ret = 0;
1448 	gnutls_free(raw.data);
1449 	return ret;
1450 }
1451 
1452 /**
1453  * gnutls_x509_crq_get_extension_data2:
1454  * @crq: should contain a #gnutls_x509_crq_t type
1455  * @extension_id: An X.509 extension OID.
1456  * @indx: Specifies which extension OID to read. Use (0) to get the first one.
1457  * @data: will contain the extension DER-encoded data
1458  *
1459  * This function will return the requested extension data in the
1460  * certificate request.  The extension data will be allocated using
1461  * gnutls_malloc().
1462  *
1463  * Use gnutls_x509_crq_get_extension_info() to extract the OID.
1464  *
1465  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1466  *   otherwise a negative error code is returned.  If you have reached the
1467  *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1468  *   will be returned.
1469  *
1470  * Since: 3.3.0
1471  **/
1472 int
gnutls_x509_crq_get_extension_data2(gnutls_x509_crq_t crq,unsigned indx,gnutls_datum_t * data)1473 gnutls_x509_crq_get_extension_data2(gnutls_x509_crq_t crq,
1474 			       unsigned indx, gnutls_datum_t * data)
1475 {
1476 	int ret, result;
1477 	char name[MAX_NAME_SIZE];
1478 	unsigned char *extensions = NULL;
1479 	size_t extensions_size = 0;
1480 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1481 
1482 	if (!crq) {
1483 		gnutls_assert();
1484 		return GNUTLS_E_INVALID_REQUEST;
1485 	}
1486 
1487 	/* read extensionRequest */
1488 	ret =
1489 	    gnutls_x509_crq_get_attribute_by_oid(crq,
1490 						 "1.2.840.113549.1.9.14",
1491 						 0, NULL,
1492 						 &extensions_size);
1493 	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
1494 		gnutls_assert();
1495 		if (ret == 0)
1496 			return GNUTLS_E_INTERNAL_ERROR;
1497 		return ret;
1498 	}
1499 
1500 	extensions = gnutls_malloc(extensions_size);
1501 	if (extensions == NULL) {
1502 		gnutls_assert();
1503 		return GNUTLS_E_MEMORY_ERROR;
1504 	}
1505 
1506 	ret =
1507 	    gnutls_x509_crq_get_attribute_by_oid(crq,
1508 						 "1.2.840.113549.1.9.14",
1509 						 0, extensions,
1510 						 &extensions_size);
1511 	if (ret < 0) {
1512 		gnutls_assert();
1513 		goto cleanup;
1514 	}
1515 
1516 	result =
1517 	    asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extensions",
1518 				&c2);
1519 	if (result != ASN1_SUCCESS) {
1520 		gnutls_assert();
1521 		ret = _gnutls_asn2err(result);
1522 		goto cleanup;
1523 	}
1524 
1525 	result = _asn1_strict_der_decode(&c2, extensions, extensions_size, NULL);
1526 	if (result != ASN1_SUCCESS) {
1527 		gnutls_assert();
1528 		ret = _gnutls_asn2err(result);
1529 		goto cleanup;
1530 	}
1531 
1532 	snprintf(name, sizeof(name), "?%u.extnValue", indx + 1);
1533 
1534 	ret = _gnutls_x509_read_value(c2, name, data);
1535 	if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
1536 		ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1537 		goto cleanup;
1538 	} else if (ret < 0) {
1539 		gnutls_assert();
1540 		goto cleanup;
1541 	}
1542 
1543 	ret = 0;
1544  cleanup:
1545 	asn1_delete_structure(&c2);
1546 	gnutls_free(extensions);
1547 	return ret;
1548 }
1549 
1550 /**
1551  * gnutls_x509_crq_get_key_usage:
1552  * @crq: should contain a #gnutls_x509_crq_t type
1553  * @key_usage: where the key usage bits will be stored
1554  * @critical: will be non-zero if the extension is marked as critical
1555  *
1556  * This function will return certificate's key usage, by reading the
1557  * keyUsage X.509 extension (2.5.29.15).  The key usage value will
1558  * ORed values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1559  * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1560  * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1561  * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1562  * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1563  *
1564  * Returns: the certificate key usage, or a negative error code in case of
1565  *   parsing error.  If the certificate does not contain the keyUsage
1566  *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1567  *   returned.
1568  *
1569  * Since: 2.8.0
1570  **/
1571 int
gnutls_x509_crq_get_key_usage(gnutls_x509_crq_t crq,unsigned int * key_usage,unsigned int * critical)1572 gnutls_x509_crq_get_key_usage(gnutls_x509_crq_t crq,
1573 			      unsigned int *key_usage,
1574 			      unsigned int *critical)
1575 {
1576 	int result;
1577 	uint8_t buf[128];
1578 	size_t buf_size = sizeof(buf);
1579 	gnutls_datum_t bd;
1580 
1581 	if (crq == NULL) {
1582 		gnutls_assert();
1583 		return GNUTLS_E_INVALID_REQUEST;
1584 	}
1585 
1586 	result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.15", 0,
1587 						      buf, &buf_size,
1588 						      critical);
1589 	if (result < 0) {
1590 		gnutls_assert();
1591 		return result;
1592 	}
1593 
1594 	bd.data = buf;
1595 	bd.size = buf_size;
1596 	result = gnutls_x509_ext_import_key_usage(&bd, key_usage);
1597 	if (result < 0) {
1598 		gnutls_assert();
1599 		return result;
1600 	}
1601 
1602 	return 0;
1603 }
1604 
1605 /**
1606  * gnutls_x509_crq_get_basic_constraints:
1607  * @crq: should contain a #gnutls_x509_crq_t type
1608  * @critical: will be non-zero if the extension is marked as critical
1609  * @ca: pointer to output integer indicating CA status, may be NULL,
1610  *   value is 1 if the certificate CA flag is set, 0 otherwise.
1611  * @pathlen: pointer to output integer indicating path length (may be
1612  *   NULL), non-negative error codes indicate a present pathLenConstraint
1613  *   field and the actual value, -1 indicate that the field is absent.
1614  *
1615  * This function will read the certificate's basic constraints, and
1616  * return the certificates CA status.  It reads the basicConstraints
1617  * X.509 extension (2.5.29.19).
1618  *
1619  * Returns: If the certificate is a CA a positive value will be
1620  *   returned, or (0) if the certificate does not have CA flag set.
1621  *   A negative error code may be returned in case of errors.  If the
1622  *   certificate does not contain the basicConstraints extension
1623  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1624  *
1625  * Since: 2.8.0
1626  **/
1627 int
gnutls_x509_crq_get_basic_constraints(gnutls_x509_crq_t crq,unsigned int * critical,unsigned int * ca,int * pathlen)1628 gnutls_x509_crq_get_basic_constraints(gnutls_x509_crq_t crq,
1629 				      unsigned int *critical,
1630 				      unsigned int *ca, int *pathlen)
1631 {
1632 	int result;
1633 	unsigned int tmp_ca;
1634 	uint8_t buf[256];
1635 	size_t buf_size = sizeof(buf);
1636 	gnutls_datum_t bd;
1637 
1638 	if (crq == NULL) {
1639 		gnutls_assert();
1640 		return GNUTLS_E_INVALID_REQUEST;
1641 	}
1642 
1643 	result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.19", 0,
1644 						      buf, &buf_size,
1645 						      critical);
1646 	if (result < 0) {
1647 		gnutls_assert();
1648 		return result;
1649 	}
1650 
1651 	bd.data = buf;
1652 	bd.size = buf_size;
1653 	result = gnutls_x509_ext_import_basic_constraints(&bd, &tmp_ca, pathlen);
1654 	if (ca)
1655 		*ca = tmp_ca;
1656 
1657 	if (result < 0) {
1658 		gnutls_assert();
1659 		return result;
1660 	}
1661 
1662 	return tmp_ca;
1663 }
1664 
1665 static int
get_subject_alt_name(gnutls_x509_crq_t crq,unsigned int seq,void * ret,size_t * ret_size,unsigned int * ret_type,unsigned int * critical,int othername_oid)1666 get_subject_alt_name(gnutls_x509_crq_t crq,
1667 		     unsigned int seq, void *ret,
1668 		     size_t * ret_size, unsigned int *ret_type,
1669 		     unsigned int *critical, int othername_oid)
1670 {
1671 	int result;
1672 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1673 	gnutls_x509_subject_alt_name_t type;
1674 	gnutls_datum_t dnsname = { NULL, 0 };
1675 	size_t dns_size = 0;
1676 
1677 	if (crq == NULL) {
1678 		gnutls_assert();
1679 		return GNUTLS_E_INVALID_REQUEST;
1680 	}
1681 
1682 	if (ret)
1683 		memset(ret, 0, *ret_size);
1684 	else
1685 		*ret_size = 0;
1686 
1687 	/* Extract extension.
1688 	 */
1689 	result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17", 0,
1690 						      NULL, &dns_size,
1691 						      critical);
1692 	if (result < 0) {
1693 		gnutls_assert();
1694 		return result;
1695 	}
1696 
1697 	dnsname.size = dns_size;
1698 	dnsname.data = gnutls_malloc(dnsname.size);
1699 	if (dnsname.data == NULL) {
1700 		gnutls_assert();
1701 		return GNUTLS_E_MEMORY_ERROR;
1702 	}
1703 
1704 	result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17", 0,
1705 						      dnsname.data,
1706 						      &dns_size, critical);
1707 	if (result < 0) {
1708 		gnutls_assert();
1709 		gnutls_free(dnsname.data);
1710 		return result;
1711 	}
1712 
1713 	result = asn1_create_element
1714 	    (_gnutls_get_pkix(), "PKIX1.SubjectAltName", &c2);
1715 	if (result != ASN1_SUCCESS) {
1716 		gnutls_assert();
1717 		gnutls_free(dnsname.data);
1718 		return _gnutls_asn2err(result);
1719 	}
1720 
1721 	result = _asn1_strict_der_decode(&c2, dnsname.data, dnsname.size, NULL);
1722 	gnutls_free(dnsname.data);
1723 	if (result != ASN1_SUCCESS) {
1724 		gnutls_assert();
1725 		asn1_delete_structure(&c2);
1726 		return _gnutls_asn2err(result);
1727 	}
1728 
1729 	result = _gnutls_parse_general_name(c2, "", seq, ret, ret_size,
1730 					    ret_type, othername_oid);
1731 	asn1_delete_structure(&c2);
1732 	if (result < 0) {
1733 		return result;
1734 	}
1735 
1736 	type = result;
1737 
1738 	return type;
1739 }
1740 
1741 /**
1742  * gnutls_x509_crq_get_subject_alt_name:
1743  * @crq: should contain a #gnutls_x509_crq_t type
1744  * @seq: specifies the sequence number of the alt name, 0 for the
1745  *   first one, 1 for the second etc.
1746  * @ret: is the place where the alternative name will be copied to
1747  * @ret_size: holds the size of ret.
1748  * @ret_type: holds the #gnutls_x509_subject_alt_name_t name type
1749  * @critical: will be non-zero if the extension is marked as critical
1750  *   (may be null)
1751  *
1752  * This function will return the alternative names, contained in the
1753  * given certificate.  It is the same as
1754  * gnutls_x509_crq_get_subject_alt_name() except for the fact that it
1755  * will return the type of the alternative name in @ret_type even if
1756  * the function fails for some reason (i.e.  the buffer provided is
1757  * not enough).
1758  *
1759  * Returns: the alternative subject name type on success, one of the
1760  *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1761  *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1762  *   hold the value.  In that case @ret_size will be updated with the
1763  *   required size.  If the certificate request does not have an
1764  *   Alternative name with the specified sequence number then
1765  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1766  *
1767  * Since: 2.8.0
1768  **/
1769 int
gnutls_x509_crq_get_subject_alt_name(gnutls_x509_crq_t crq,unsigned int seq,void * ret,size_t * ret_size,unsigned int * ret_type,unsigned int * critical)1770 gnutls_x509_crq_get_subject_alt_name(gnutls_x509_crq_t crq,
1771 				     unsigned int seq, void *ret,
1772 				     size_t * ret_size,
1773 				     unsigned int *ret_type,
1774 				     unsigned int *critical)
1775 {
1776 	return get_subject_alt_name(crq, seq, ret, ret_size, ret_type,
1777 				    critical, 0);
1778 }
1779 
1780 /**
1781  * gnutls_x509_crq_get_subject_alt_othername_oid:
1782  * @crq: should contain a #gnutls_x509_crq_t type
1783  * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1784  * @ret: is the place where the otherName OID will be copied to
1785  * @ret_size: holds the size of ret.
1786  *
1787  * This function will extract the type OID of an otherName Subject
1788  * Alternative Name, contained in the given certificate, and return
1789  * the type as an enumerated element.
1790  *
1791  * This function is only useful if
1792  * gnutls_x509_crq_get_subject_alt_name() returned
1793  * %GNUTLS_SAN_OTHERNAME.
1794  *
1795  * Returns: the alternative subject name type on success, one of the
1796  *   enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs,
1797  *   it will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1798  *   e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1799  *   unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1800  *   @ret_size is not large enough to hold the value.  In that case
1801  *   @ret_size will be updated with the required size.  If the
1802  *   certificate does not have an Alternative name with the specified
1803  *   sequence number and with the otherName type then
1804  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1805  *
1806  * Since: 2.8.0
1807  **/
1808 int
gnutls_x509_crq_get_subject_alt_othername_oid(gnutls_x509_crq_t crq,unsigned int seq,void * ret,size_t * ret_size)1809 gnutls_x509_crq_get_subject_alt_othername_oid(gnutls_x509_crq_t crq,
1810 					      unsigned int seq,
1811 					      void *ret, size_t * ret_size)
1812 {
1813 	return get_subject_alt_name(crq, seq, ret, ret_size, NULL, NULL,
1814 				    1);
1815 }
1816 
1817 /**
1818  * gnutls_x509_crq_get_extension_by_oid:
1819  * @crq: should contain a #gnutls_x509_crq_t type
1820  * @oid: holds an Object Identifier in a null terminated string
1821  * @indx: In case multiple same OIDs exist in the extensions, this
1822  *   specifies which to get. Use (0) to get the first one.
1823  * @buf: a pointer to a structure to hold the name (may be null)
1824  * @buf_size: initially holds the size of @buf
1825  * @critical: will be non-zero if the extension is marked as critical
1826  *
1827  * This function will return the extension specified by the OID in
1828  * the certificate.  The extensions will be returned as binary data
1829  * DER encoded, in the provided buffer.
1830  *
1831  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1832  *   negative error code in case of an error.  If the certificate does not
1833  *   contain the specified extension
1834  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1835  *
1836  * Since: 2.8.0
1837  **/
1838 int
gnutls_x509_crq_get_extension_by_oid(gnutls_x509_crq_t crq,const char * oid,unsigned indx,void * buf,size_t * buf_size,unsigned int * critical)1839 gnutls_x509_crq_get_extension_by_oid(gnutls_x509_crq_t crq,
1840 				     const char *oid, unsigned indx,
1841 				     void *buf, size_t * buf_size,
1842 				     unsigned int *critical)
1843 {
1844 	int result;
1845 	unsigned int i;
1846 	char _oid[MAX_OID_SIZE];
1847 	size_t oid_size;
1848 
1849 	for (i = 0;; i++) {
1850 		oid_size = sizeof(_oid);
1851 		result =
1852 		    gnutls_x509_crq_get_extension_info(crq, i, _oid,
1853 						       &oid_size,
1854 						       critical);
1855 		if (result < 0) {
1856 			gnutls_assert();
1857 			return result;
1858 		}
1859 
1860 		if (strcmp(oid, _oid) == 0) {	/* found */
1861 			if (indx == 0)
1862 				return
1863 				    gnutls_x509_crq_get_extension_data(crq,
1864 								       i,
1865 								       buf,
1866 								       buf_size);
1867 			else
1868 				indx--;
1869 		}
1870 	}
1871 
1872 
1873 	return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1874 
1875 }
1876 
1877 /**
1878  * gnutls_x509_crq_get_extension_by_oid2:
1879  * @crq: should contain a #gnutls_x509_crq_t type
1880  * @oid: holds an Object Identifier in a null terminated string
1881  * @indx: In case multiple same OIDs exist in the extensions, this
1882  *   specifies which to get. Use (0) to get the first one.
1883  * @output: will hold the allocated extension data
1884  * @critical: will be non-zero if the extension is marked as critical
1885  *
1886  * This function will return the extension specified by the OID in
1887  * the certificate.  The extensions will be returned as binary data
1888  * DER encoded, in the provided buffer.
1889  *
1890  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1891  *   negative error code in case of an error.  If the certificate does not
1892  *   contain the specified extension
1893  *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1894  *
1895  * Since: 3.3.8
1896  **/
1897 int
gnutls_x509_crq_get_extension_by_oid2(gnutls_x509_crq_t crq,const char * oid,unsigned indx,gnutls_datum_t * output,unsigned int * critical)1898 gnutls_x509_crq_get_extension_by_oid2(gnutls_x509_crq_t crq,
1899 				     const char *oid, unsigned indx,
1900 				     gnutls_datum_t *output,
1901 				     unsigned int *critical)
1902 {
1903 	int result;
1904 	unsigned int i;
1905 	char _oid[MAX_OID_SIZE];
1906 	size_t oid_size;
1907 
1908 	for (i = 0;; i++) {
1909 		oid_size = sizeof(_oid);
1910 		result =
1911 		    gnutls_x509_crq_get_extension_info(crq, i, _oid,
1912 						       &oid_size,
1913 						       critical);
1914 		if (result < 0) {
1915 			gnutls_assert();
1916 			return result;
1917 		}
1918 
1919 		if (strcmp(oid, _oid) == 0) {	/* found */
1920 			if (indx == 0)
1921 				return
1922 				    gnutls_x509_crq_get_extension_data2(crq,
1923 								       i,
1924 								       output);
1925 			else
1926 				indx--;
1927 		}
1928 	}
1929 
1930 	return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1931 
1932 }
1933 
1934 /**
1935  * gnutls_x509_crq_set_subject_alt_name:
1936  * @crq: a certificate request of type #gnutls_x509_crq_t
1937  * @nt: is one of the #gnutls_x509_subject_alt_name_t enumerations
1938  * @data: The data to be set
1939  * @data_size: The size of data to be set
1940  * @flags: %GNUTLS_FSAN_SET to clear previous data or
1941  *   %GNUTLS_FSAN_APPEND to append.
1942  *
1943  * This function will set the subject alternative name certificate
1944  * extension.  It can set the following types:
1945  *
1946  * %GNUTLS_SAN_DNSNAME: as a text string
1947  *
1948  * %GNUTLS_SAN_RFC822NAME: as a text string
1949  *
1950  * %GNUTLS_SAN_URI: as a text string
1951  *
1952  * %GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
1953  *
1954  * %GNUTLS_SAN_OTHERNAME_XMPP: as a UTF8 string
1955  *
1956  * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
1957  * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
1958  *
1959  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1960  *   negative error value.
1961  *
1962  * Since: 2.8.0
1963  **/
1964 int
gnutls_x509_crq_set_subject_alt_name(gnutls_x509_crq_t crq,gnutls_x509_subject_alt_name_t nt,const void * data,unsigned int data_size,unsigned int flags)1965 gnutls_x509_crq_set_subject_alt_name(gnutls_x509_crq_t crq,
1966 				     gnutls_x509_subject_alt_name_t nt,
1967 				     const void *data,
1968 				     unsigned int data_size,
1969 				     unsigned int flags)
1970 {
1971 	int result = 0;
1972 	gnutls_datum_t der_data = { NULL, 0 };
1973 	gnutls_datum_t prev_der_data = { NULL, 0 };
1974 	unsigned int critical = 0;
1975 	size_t prev_data_size = 0;
1976 
1977 	if (crq == NULL) {
1978 		gnutls_assert();
1979 		return GNUTLS_E_INVALID_REQUEST;
1980 	}
1981 
1982 	/* Check if the extension already exists.
1983 	 */
1984 	if (flags & GNUTLS_FSAN_APPEND) {
1985 		result =
1986 		    gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17",
1987 							 0, NULL,
1988 							 &prev_data_size,
1989 							 &critical);
1990 		prev_der_data.size = prev_data_size;
1991 
1992 		switch (result) {
1993 		case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
1994 			/* Replacing non-existing data means the same as set data. */
1995 			break;
1996 
1997 		case GNUTLS_E_SUCCESS:
1998 			prev_der_data.data =
1999 			    gnutls_malloc(prev_der_data.size);
2000 			if (prev_der_data.data == NULL) {
2001 				gnutls_assert();
2002 				return GNUTLS_E_MEMORY_ERROR;
2003 			}
2004 
2005 			result =
2006 			    gnutls_x509_crq_get_extension_by_oid(crq,
2007 								 "2.5.29.17",
2008 								 0,
2009 								 prev_der_data.
2010 								 data,
2011 								 &prev_data_size,
2012 								 &critical);
2013 			if (result < 0) {
2014 				gnutls_assert();
2015 				gnutls_free(prev_der_data.data);
2016 				return result;
2017 			}
2018 			break;
2019 
2020 		default:
2021 			gnutls_assert();
2022 			return result;
2023 		}
2024 	}
2025 
2026 	/* generate the extension.
2027 	 */
2028 	result = _gnutls_x509_ext_gen_subject_alt_name(nt, NULL, data, data_size,
2029 						       &prev_der_data,
2030 						       &der_data);
2031 	gnutls_free(prev_der_data.data);
2032 	if (result < 0) {
2033 		gnutls_assert();
2034 		goto finish;
2035 	}
2036 
2037 	result =
2038 	    _gnutls_x509_crq_set_extension(crq, "2.5.29.17", &der_data,
2039 					   critical);
2040 
2041 	_gnutls_free_datum(&der_data);
2042 
2043 	if (result < 0) {
2044 		gnutls_assert();
2045 		return result;
2046 	}
2047 
2048 	return 0;
2049 
2050       finish:
2051 	return result;
2052 }
2053 
2054 /**
2055  * gnutls_x509_crq_set_subject_alt_othername:
2056  * @crq: a certificate request of type #gnutls_x509_crq_t
2057  * @oid: is the othername OID
2058  * @data: The data to be set
2059  * @data_size: The size of data to be set
2060  * @flags: %GNUTLS_FSAN_SET to clear previous data or
2061  *   %GNUTLS_FSAN_APPEND to append.
2062  *
2063  * This function will set the subject alternative name certificate
2064  * extension.  It can set the following types:
2065  *
2066  * The values set must be binary values and must be properly DER encoded.
2067  *
2068  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2069  *   negative error value.
2070  *
2071  * Since: 3.5.0
2072  **/
2073 int
gnutls_x509_crq_set_subject_alt_othername(gnutls_x509_crq_t crq,const char * oid,const void * data,unsigned int data_size,unsigned int flags)2074 gnutls_x509_crq_set_subject_alt_othername(gnutls_x509_crq_t crq,
2075 				     const char *oid,
2076 				     const void *data,
2077 				     unsigned int data_size,
2078 				     unsigned int flags)
2079 {
2080 	int result = 0;
2081 	gnutls_datum_t der_data = { NULL, 0 };
2082 	gnutls_datum_t encoded_data = { NULL, 0 };
2083 	gnutls_datum_t prev_der_data = { NULL, 0 };
2084 	unsigned int critical = 0;
2085 	size_t prev_data_size = 0;
2086 
2087 	if (crq == NULL) {
2088 		gnutls_assert();
2089 		return GNUTLS_E_INVALID_REQUEST;
2090 	}
2091 
2092 	/* Check if the extension already exists.
2093 	 */
2094 	if (flags & GNUTLS_FSAN_APPEND) {
2095 		result =
2096 		    gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17",
2097 							 0, NULL,
2098 							 &prev_data_size,
2099 							 &critical);
2100 		prev_der_data.size = prev_data_size;
2101 
2102 		switch (result) {
2103 		case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
2104 			/* Replacing non-existing data means the same as set data. */
2105 			break;
2106 
2107 		case GNUTLS_E_SUCCESS:
2108 			prev_der_data.data =
2109 			    gnutls_malloc(prev_der_data.size);
2110 			if (prev_der_data.data == NULL) {
2111 				gnutls_assert();
2112 				return GNUTLS_E_MEMORY_ERROR;
2113 			}
2114 
2115 			result =
2116 			    gnutls_x509_crq_get_extension_by_oid(crq,
2117 								 "2.5.29.17",
2118 								 0,
2119 								 prev_der_data.
2120 								 data,
2121 								 &prev_data_size,
2122 								 &critical);
2123 			if (result < 0) {
2124 				gnutls_assert();
2125 				goto finish;
2126 			}
2127 			break;
2128 
2129 		default:
2130 			gnutls_assert();
2131 			return result;
2132 		}
2133 	}
2134 
2135 	result = _gnutls_encode_othername_data(flags, data, data_size, &encoded_data);
2136 	if (result < 0) {
2137 		gnutls_assert();
2138 		goto finish;
2139 	}
2140 
2141 	/* generate the extension.
2142 	 */
2143 	result = _gnutls_x509_ext_gen_subject_alt_name(GNUTLS_SAN_OTHERNAME, oid,
2144 						       encoded_data.data, encoded_data.size,
2145 						       &prev_der_data,
2146 						       &der_data);
2147 	if (result < 0) {
2148 		gnutls_assert();
2149 		goto finish;
2150 	}
2151 
2152 	result =
2153 	    _gnutls_x509_crq_set_extension(crq, "2.5.29.17", &der_data,
2154 					   critical);
2155 
2156 	if (result < 0) {
2157 		gnutls_assert();
2158 		goto finish;
2159 	}
2160 
2161 	result = 0;
2162 
2163       finish:
2164 	_gnutls_free_datum(&prev_der_data);
2165 	_gnutls_free_datum(&der_data);
2166 	_gnutls_free_datum(&encoded_data);
2167 	return result;
2168 }
2169 
2170 /**
2171  * gnutls_x509_crq_set_basic_constraints:
2172  * @crq: a certificate request of type #gnutls_x509_crq_t
2173  * @ca: true(1) or false(0) depending on the Certificate authority status.
2174  * @pathLenConstraint: non-negative error codes indicate maximum length of path,
2175  *   and negative error codes indicate that the pathLenConstraints field should
2176  *   not be present.
2177  *
2178  * This function will set the basicConstraints certificate extension.
2179  *
2180  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2181  *   negative error value.
2182  *
2183  * Since: 2.8.0
2184  **/
2185 int
gnutls_x509_crq_set_basic_constraints(gnutls_x509_crq_t crq,unsigned int ca,int pathLenConstraint)2186 gnutls_x509_crq_set_basic_constraints(gnutls_x509_crq_t crq,
2187 				      unsigned int ca,
2188 				      int pathLenConstraint)
2189 {
2190 	int result;
2191 	gnutls_datum_t der_data;
2192 
2193 	if (crq == NULL) {
2194 		gnutls_assert();
2195 		return GNUTLS_E_INVALID_REQUEST;
2196 	}
2197 
2198 	/* generate the extension.
2199 	 */
2200 	result = gnutls_x509_ext_export_basic_constraints(ca, pathLenConstraint, &der_data);
2201 	if (result < 0) {
2202 		gnutls_assert();
2203 		return result;
2204 	}
2205 
2206 	result =
2207 	    _gnutls_x509_crq_set_extension(crq, "2.5.29.19", &der_data, 1);
2208 
2209 	_gnutls_free_datum(&der_data);
2210 
2211 	if (result < 0) {
2212 		gnutls_assert();
2213 		return result;
2214 	}
2215 
2216 	return 0;
2217 }
2218 
2219 /**
2220  * gnutls_x509_crq_set_key_usage:
2221  * @crq: a certificate request of type #gnutls_x509_crq_t
2222  * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
2223  *
2224  * This function will set the keyUsage certificate extension.
2225  *
2226  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2227  *   negative error value.
2228  *
2229  * Since: 2.8.0
2230  **/
2231 int
gnutls_x509_crq_set_key_usage(gnutls_x509_crq_t crq,unsigned int usage)2232 gnutls_x509_crq_set_key_usage(gnutls_x509_crq_t crq, unsigned int usage)
2233 {
2234 	int result;
2235 	gnutls_datum_t der_data;
2236 
2237 	if (crq == NULL) {
2238 		gnutls_assert();
2239 		return GNUTLS_E_INVALID_REQUEST;
2240 	}
2241 
2242 	/* generate the extension.
2243 	 */
2244 	result =
2245 	    gnutls_x509_ext_export_key_usage(usage, &der_data);
2246 	if (result < 0) {
2247 		gnutls_assert();
2248 		return result;
2249 	}
2250 
2251 	result =
2252 	    _gnutls_x509_crq_set_extension(crq, "2.5.29.15", &der_data, 1);
2253 
2254 	_gnutls_free_datum(&der_data);
2255 
2256 	if (result < 0) {
2257 		gnutls_assert();
2258 		return result;
2259 	}
2260 
2261 	return 0;
2262 }
2263 
2264 /**
2265  * gnutls_x509_crq_get_key_purpose_oid:
2266  * @crq: should contain a #gnutls_x509_crq_t type
2267  * @indx: This specifies which OID to return, use (0) to get the first one
2268  * @oid: a pointer to store the OID (may be %NULL)
2269  * @sizeof_oid: initially holds the size of @oid
2270  * @critical: output variable with critical flag, may be %NULL.
2271  *
2272  * This function will extract the key purpose OIDs of the Certificate
2273  * specified by the given index.  These are stored in the Extended Key
2274  * Usage extension (2.5.29.37).  See the GNUTLS_KP_* definitions for
2275  * human readable names.
2276  *
2277  * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2278  *   not long enough, and in that case the *@sizeof_oid will be
2279  *   updated with the required size.  On success 0 is returned.
2280  *
2281  * Since: 2.8.0
2282  **/
2283 int
gnutls_x509_crq_get_key_purpose_oid(gnutls_x509_crq_t crq,unsigned indx,void * oid,size_t * sizeof_oid,unsigned int * critical)2284 gnutls_x509_crq_get_key_purpose_oid(gnutls_x509_crq_t crq,
2285 				    unsigned indx, void *oid,
2286 				    size_t * sizeof_oid,
2287 				    unsigned int *critical)
2288 {
2289 	char tmpstr[MAX_NAME_SIZE];
2290 	int result, len;
2291 	gnutls_datum_t prev = { NULL, 0 };
2292 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2293 	size_t prev_size = 0;
2294 
2295 	if (oid)
2296 		memset(oid, 0, *sizeof_oid);
2297 	else
2298 		*sizeof_oid = 0;
2299 
2300 	/* Extract extension.
2301 	 */
2302 	result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.37", 0,
2303 						      NULL, &prev_size,
2304 						      critical);
2305 	prev.size = prev_size;
2306 
2307 	if (result < 0) {
2308 		gnutls_assert();
2309 		return result;
2310 	}
2311 
2312 	prev.data = gnutls_malloc(prev.size);
2313 	if (prev.data == NULL) {
2314 		gnutls_assert();
2315 		return GNUTLS_E_MEMORY_ERROR;
2316 	}
2317 
2318 	result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.37", 0,
2319 						      prev.data,
2320 						      &prev_size,
2321 						      critical);
2322 	if (result < 0) {
2323 		gnutls_assert();
2324 		gnutls_free(prev.data);
2325 		return result;
2326 	}
2327 
2328 	result = asn1_create_element
2329 	    (_gnutls_get_pkix(), "PKIX1.ExtKeyUsageSyntax", &c2);
2330 	if (result != ASN1_SUCCESS) {
2331 		gnutls_assert();
2332 		gnutls_free(prev.data);
2333 		return _gnutls_asn2err(result);
2334 	}
2335 
2336 	result = _asn1_strict_der_decode(&c2, prev.data, prev.size, NULL);
2337 	gnutls_free(prev.data);
2338 	if (result != ASN1_SUCCESS) {
2339 		gnutls_assert();
2340 		asn1_delete_structure(&c2);
2341 		return _gnutls_asn2err(result);
2342 	}
2343 
2344 	indx++;
2345 	/* create a string like "?1"
2346 	 */
2347 	snprintf(tmpstr, sizeof(tmpstr), "?%u", indx);
2348 
2349 	len = *sizeof_oid;
2350 	result = asn1_read_value(c2, tmpstr, oid, &len);
2351 
2352 	*sizeof_oid = len;
2353 	asn1_delete_structure(&c2);
2354 
2355 	if (result == ASN1_VALUE_NOT_FOUND
2356 	    || result == ASN1_ELEMENT_NOT_FOUND) {
2357 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2358 	}
2359 
2360 	if (result != ASN1_SUCCESS) {
2361 		if (result != ASN1_MEM_ERROR)
2362 			gnutls_assert();
2363 		return _gnutls_asn2err(result);
2364 	}
2365 
2366 	return 0;
2367 }
2368 
2369 /**
2370  * gnutls_x509_crq_set_key_purpose_oid:
2371  * @crq: a certificate of type #gnutls_x509_crq_t
2372  * @oid: a pointer to a null-terminated string that holds the OID
2373  * @critical: Whether this extension will be critical or not
2374  *
2375  * This function will set the key purpose OIDs of the Certificate.
2376  * These are stored in the Extended Key Usage extension (2.5.29.37)
2377  * See the GNUTLS_KP_* definitions for human readable names.
2378  *
2379  * Subsequent calls to this function will append OIDs to the OID list.
2380  *
2381  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2382  *   negative error value.
2383  *
2384  * Since: 2.8.0
2385  **/
2386 int
gnutls_x509_crq_set_key_purpose_oid(gnutls_x509_crq_t crq,const void * oid,unsigned int critical)2387 gnutls_x509_crq_set_key_purpose_oid(gnutls_x509_crq_t crq,
2388 				    const void *oid, unsigned int critical)
2389 {
2390 	int result;
2391 	gnutls_datum_t prev = { NULL, 0 }, der_data;
2392 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2393 	size_t prev_size = 0;
2394 
2395 	/* Read existing extension, if there is one.
2396 	 */
2397 	result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.37", 0,
2398 						      NULL, &prev_size,
2399 						      &critical);
2400 	prev.size = prev_size;
2401 
2402 	switch (result) {
2403 	case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
2404 		/* No existing extension, that's fine. */
2405 		break;
2406 
2407 	case GNUTLS_E_SUCCESS:
2408 		prev.data = gnutls_malloc(prev.size);
2409 		if (prev.data == NULL) {
2410 			gnutls_assert();
2411 			return GNUTLS_E_MEMORY_ERROR;
2412 		}
2413 
2414 		result =
2415 		    gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.37",
2416 							 0, prev.data,
2417 							 &prev_size,
2418 							 &critical);
2419 		if (result < 0) {
2420 			gnutls_assert();
2421 			gnutls_free(prev.data);
2422 			return result;
2423 		}
2424 		break;
2425 
2426 	default:
2427 		gnutls_assert();
2428 		return result;
2429 	}
2430 
2431 	result = asn1_create_element(_gnutls_get_pkix(),
2432 				     "PKIX1.ExtKeyUsageSyntax", &c2);
2433 	if (result != ASN1_SUCCESS) {
2434 		gnutls_assert();
2435 		gnutls_free(prev.data);
2436 		return _gnutls_asn2err(result);
2437 	}
2438 
2439 	if (prev.data) {
2440 		/* decode it.
2441 		 */
2442 		result =
2443 		    _asn1_strict_der_decode(&c2, prev.data, prev.size, NULL);
2444 		gnutls_free(prev.data);
2445 		if (result != ASN1_SUCCESS) {
2446 			gnutls_assert();
2447 			asn1_delete_structure(&c2);
2448 			return _gnutls_asn2err(result);
2449 		}
2450 	}
2451 
2452 	/* generate the extension.
2453 	 */
2454 	/* 1. create a new element.
2455 	 */
2456 	result = asn1_write_value(c2, "", "NEW", 1);
2457 	if (result != ASN1_SUCCESS) {
2458 		gnutls_assert();
2459 		asn1_delete_structure(&c2);
2460 		return _gnutls_asn2err(result);
2461 	}
2462 
2463 	/* 2. Add the OID.
2464 	 */
2465 	result = asn1_write_value(c2, "?LAST", oid, 1);
2466 	if (result != ASN1_SUCCESS) {
2467 		gnutls_assert();
2468 		asn1_delete_structure(&c2);
2469 		return _gnutls_asn2err(result);
2470 	}
2471 
2472 	result = _gnutls_x509_der_encode(c2, "", &der_data, 0);
2473 	asn1_delete_structure(&c2);
2474 
2475 	if (result != ASN1_SUCCESS) {
2476 		gnutls_assert();
2477 		return _gnutls_asn2err(result);
2478 	}
2479 
2480 	result = _gnutls_x509_crq_set_extension(crq, "2.5.29.37",
2481 						&der_data, critical);
2482 	_gnutls_free_datum(&der_data);
2483 	if (result < 0) {
2484 		gnutls_assert();
2485 		return result;
2486 	}
2487 
2488 	return 0;
2489 }
2490 
2491 /**
2492  * gnutls_x509_crq_get_key_id:
2493  * @crq: a certificate of type #gnutls_x509_crq_t
2494  * @flags: should be one of the flags from %gnutls_keyid_flags_t
2495  * @output_data: will contain the key ID
2496  * @output_data_size: holds the size of output_data (and will be
2497  *   replaced by the actual size of parameters)
2498  *
2499  * This function will return a unique ID that depends on the public key
2500  * parameters.  This ID can be used in checking whether a certificate
2501  * corresponds to the given private key.
2502  *
2503  * If the buffer provided is not long enough to hold the output, then
2504  * *@output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2505  * be returned.  The output will normally be a SHA-1 hash output,
2506  * which is 20 bytes.
2507  *
2508  * Returns: In case of failure a negative error code will be
2509  *   returned, and 0 on success.
2510  *
2511  * Since: 2.8.0
2512  **/
2513 int
gnutls_x509_crq_get_key_id(gnutls_x509_crq_t crq,unsigned int flags,unsigned char * output_data,size_t * output_data_size)2514 gnutls_x509_crq_get_key_id(gnutls_x509_crq_t crq, unsigned int flags,
2515 			   unsigned char *output_data,
2516 			   size_t * output_data_size)
2517 {
2518 	int ret = 0;
2519 	gnutls_pk_params_st params;
2520 
2521 	if (crq == NULL) {
2522 		gnutls_assert();
2523 		return GNUTLS_E_INVALID_REQUEST;
2524 	}
2525 
2526 	ret = _gnutls_x509_crq_get_mpis(crq, &params);
2527 	if (ret < 0) {
2528 		gnutls_assert();
2529 		return ret;
2530 	}
2531 
2532 	ret =
2533 	    _gnutls_get_key_id(&params, output_data, output_data_size, flags);
2534 
2535 	gnutls_pk_params_release(&params);
2536 
2537 	return ret;
2538 }
2539 
2540 /**
2541  * gnutls_x509_crq_privkey_sign:
2542  * @crq: should contain a #gnutls_x509_crq_t type
2543  * @key: holds a private key
2544  * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
2545  * @flags: must be 0
2546  *
2547  * This function will sign the certificate request with a private key.
2548  * This must be the same key as the one used in
2549  * gnutls_x509_crt_set_key() since a certificate request is self
2550  * signed.
2551  *
2552  * This must be the last step in a certificate request generation
2553  * since all the previously set parameters are now signed.
2554  *
2555  * A known limitation of this function is, that a newly-signed request will not
2556  * be fully functional (e.g., for signature verification), until it
2557  * is exported an re-imported.
2558  *
2559  * After GnuTLS 3.6.1 the value of @dig may be %GNUTLS_DIG_UNKNOWN,
2560  * and in that case, a suitable but reasonable for the key algorithm will be selected.
2561  *
2562  * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2563  *   %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
2564  *   information in the certificate request (e.g., the version using
2565  *   gnutls_x509_crq_set_version()).
2566  *
2567  * Since: 2.12.0
2568  **/
2569 int
gnutls_x509_crq_privkey_sign(gnutls_x509_crq_t crq,gnutls_privkey_t key,gnutls_digest_algorithm_t dig,unsigned int flags)2570 gnutls_x509_crq_privkey_sign(gnutls_x509_crq_t crq, gnutls_privkey_t key,
2571 			     gnutls_digest_algorithm_t dig,
2572 			     unsigned int flags)
2573 {
2574 	int result;
2575 	gnutls_datum_t signature;
2576 	gnutls_datum_t tbs;
2577 	gnutls_pk_algorithm_t pk;
2578 	gnutls_x509_spki_st params;
2579 	const gnutls_sign_entry_st *se;
2580 
2581 	if (crq == NULL) {
2582 		gnutls_assert();
2583 		return GNUTLS_E_INVALID_REQUEST;
2584 	}
2585 
2586 	/* Make sure version field is set. */
2587 	if (gnutls_x509_crq_get_version(crq) ==
2588 	    GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
2589 		result = gnutls_x509_crq_set_version(crq, 1);
2590 		if (result < 0) {
2591 			gnutls_assert();
2592 			return result;
2593 		}
2594 	}
2595 
2596 	if (dig == 0) {
2597 		/* attempt to find a reasonable choice */
2598 		gnutls_pubkey_t pubkey;
2599 		int ret;
2600 
2601 		ret = gnutls_pubkey_init(&pubkey);
2602 		if (ret < 0)
2603 			return gnutls_assert_val(ret);
2604 
2605 		ret = gnutls_pubkey_import_privkey(pubkey, key, 0, 0);
2606 		if (ret < 0) {
2607 			gnutls_pubkey_deinit(pubkey);
2608 			return gnutls_assert_val(ret);
2609 		}
2610 		ret = gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &dig, NULL);
2611 		gnutls_pubkey_deinit(pubkey);
2612 
2613 		if (ret < 0)
2614 			return gnutls_assert_val(ret);
2615 	}
2616 
2617 	result = _gnutls_privkey_get_spki_params(key, &params);
2618 	if (result < 0) {
2619 		gnutls_assert();
2620 		return result;
2621 	}
2622 
2623 	pk = gnutls_privkey_get_pk_algorithm(key, NULL);
2624 	result = _gnutls_privkey_update_spki_params(key, pk, dig, 0, &params);
2625 	if (result < 0) {
2626 		gnutls_assert();
2627 		return result;
2628 	}
2629 
2630 	/* Step 1. Self sign the request.
2631 	 */
2632 	result =
2633 	    _gnutls_x509_get_tbs(crq->crq, "certificationRequestInfo",
2634 				 &tbs);
2635 
2636 	if (result < 0) {
2637 		gnutls_assert();
2638 		return result;
2639 	}
2640 
2641 	se = _gnutls_pk_to_sign_entry(params.pk, dig);
2642 	if (se == NULL)
2643 		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2644 
2645 	FIX_SIGN_PARAMS(params, flags, dig);
2646 
2647 	result = privkey_sign_and_hash_data(key, se,
2648 					    &tbs, &signature, &params);
2649 	gnutls_free(tbs.data);
2650 
2651 	if (result < 0) {
2652 		gnutls_assert();
2653 		return result;
2654 	}
2655 
2656 	/* Step 2. write the signature (bits)
2657 	 */
2658 	result =
2659 	    asn1_write_value(crq->crq, "signature", signature.data,
2660 			     signature.size * 8);
2661 
2662 	_gnutls_free_datum(&signature);
2663 
2664 	if (result != ASN1_SUCCESS) {
2665 		gnutls_assert();
2666 		return _gnutls_asn2err(result);
2667 	}
2668 
2669 	/* Step 3. Write the signatureAlgorithm field.
2670 	 */
2671 	result =
2672 	    _gnutls_x509_write_sign_params(crq->crq, "signatureAlgorithm",
2673 					   se, &params);
2674 	if (result < 0) {
2675 		gnutls_assert();
2676 		return result;
2677 	}
2678 
2679 	return 0;
2680 }
2681 
2682 
2683 /**
2684  * gnutls_x509_crq_verify:
2685  * @crq: is the crq to be verified
2686  * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
2687  *
2688  * This function will verify self signature in the certificate
2689  * request and return its status.
2690  *
2691  * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2692  * is returned, and zero or positive code on success.
2693  *
2694  * Since 2.12.0
2695  **/
gnutls_x509_crq_verify(gnutls_x509_crq_t crq,unsigned int flags)2696 int gnutls_x509_crq_verify(gnutls_x509_crq_t crq, unsigned int flags)
2697 {
2698 	gnutls_datum_t data = { NULL, 0 };
2699 	gnutls_datum_t signature = { NULL, 0 };
2700 	gnutls_pk_params_st params;
2701 	gnutls_x509_spki_st sign_params;
2702 	const gnutls_sign_entry_st *se;
2703 	int ret;
2704 
2705 	gnutls_pk_params_init(&params);
2706 
2707 	ret =
2708 	    _gnutls_x509_get_signed_data(crq->crq, NULL,
2709 					 "certificationRequestInfo",
2710 					 &data);
2711 	if (ret < 0) {
2712 		gnutls_assert();
2713 		return ret;
2714 	}
2715 
2716 	ret =
2717 	    _gnutls_x509_get_signature_algorithm(crq->crq,
2718 						 "signatureAlgorithm");
2719 	if (ret < 0) {
2720 		gnutls_assert();
2721 		goto cleanup;
2722 	}
2723 
2724 	se = _gnutls_sign_to_entry(ret);
2725 	if (se == NULL) {
2726 		gnutls_assert();
2727 		ret = GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
2728 		goto cleanup;
2729 	}
2730 
2731 	ret =
2732 	    _gnutls_x509_get_signature(crq->crq, "signature", &signature);
2733 	if (ret < 0) {
2734 		gnutls_assert();
2735 		goto cleanup;
2736 	}
2737 
2738 	ret = _gnutls_x509_crq_get_mpis(crq, &params);
2739 	if (ret < 0) {
2740 		gnutls_assert();
2741 		goto cleanup;
2742 	}
2743 
2744 	ret = _gnutls_x509_read_sign_params(crq->crq,
2745 					    "signatureAlgorithm",
2746 					    &sign_params);
2747 	if (ret < 0) {
2748 		gnutls_assert();
2749 		goto cleanup;
2750 	}
2751 
2752 	ret =
2753 	    pubkey_verify_data(se, hash_to_entry(se->hash), &data, &signature,
2754 			       &params, &sign_params, flags);
2755 	if (ret < 0) {
2756 		gnutls_assert();
2757 		goto cleanup;
2758 	}
2759 
2760 	ret = 0;
2761 
2762       cleanup:
2763 	_gnutls_free_datum(&data);
2764 	_gnutls_free_datum(&signature);
2765 	gnutls_pk_params_release(&params);
2766 
2767 	return ret;
2768 }
2769 
2770 /**
2771  * gnutls_x509_crq_set_private_key_usage_period:
2772  * @crq: a certificate of type #gnutls_x509_crq_t
2773  * @activation: The activation time
2774  * @expiration: The expiration time
2775  *
2776  * This function will set the private key usage period extension (2.5.29.16).
2777  *
2778  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2779  *   negative error value.
2780  **/
2781 int
gnutls_x509_crq_set_private_key_usage_period(gnutls_x509_crq_t crq,time_t activation,time_t expiration)2782 gnutls_x509_crq_set_private_key_usage_period(gnutls_x509_crq_t crq,
2783 					     time_t activation,
2784 					     time_t expiration)
2785 {
2786 	int result;
2787 	gnutls_datum_t der_data;
2788 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2789 
2790 	if (crq == NULL) {
2791 		gnutls_assert();
2792 		return GNUTLS_E_INVALID_REQUEST;
2793 	}
2794 
2795 	result =
2796 	    asn1_create_element(_gnutls_get_pkix(),
2797 				"PKIX1.PrivateKeyUsagePeriod", &c2);
2798 	if (result != ASN1_SUCCESS) {
2799 		gnutls_assert();
2800 		return _gnutls_asn2err(result);
2801 	}
2802 
2803 	result = _gnutls_x509_set_time(c2, "notBefore", activation, 1);
2804 	if (result < 0) {
2805 		gnutls_assert();
2806 		goto cleanup;
2807 	}
2808 
2809 	result = _gnutls_x509_set_time(c2, "notAfter", expiration, 1);
2810 	if (result < 0) {
2811 		gnutls_assert();
2812 		goto cleanup;
2813 	}
2814 
2815 	result = _gnutls_x509_der_encode(c2, "", &der_data, 0);
2816 	if (result < 0) {
2817 		gnutls_assert();
2818 		goto cleanup;
2819 	}
2820 
2821 	result = _gnutls_x509_crq_set_extension(crq, "2.5.29.16",
2822 						&der_data, 0);
2823 
2824 	_gnutls_free_datum(&der_data);
2825 
2826       cleanup:
2827 	asn1_delete_structure(&c2);
2828 
2829 	return result;
2830 }
2831 
2832 /**
2833  * gnutls_x509_crq_get_tlsfeatures:
2834  * @crq: An X.509 certificate request
2835  * @features: If the function succeeds, the
2836  *   features will be stored in this variable.
2837  * @flags: zero or %GNUTLS_EXT_FLAG_APPEND
2838  * @critical: the extension status
2839  *
2840  * This function will get the X.509 TLS features
2841  * extension structure from the certificate request.
2842  * The returned structure needs to be freed using
2843  * gnutls_x509_tlsfeatures_deinit().
2844  *
2845  * When the @flags is set to %GNUTLS_EXT_FLAG_APPEND,
2846  * then if the @features structure is empty this function will behave
2847  * identically as if the flag was not set. Otherwise if there are elements
2848  * in the @features structure then they will be merged with.
2849  *
2850  * Note that @features must be initialized prior to calling this function.
2851  *
2852  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2853  *   otherwise a negative error value.
2854  *
2855  * Since: 3.5.1
2856  **/
gnutls_x509_crq_get_tlsfeatures(gnutls_x509_crq_t crq,gnutls_x509_tlsfeatures_t features,unsigned int flags,unsigned int * critical)2857 int gnutls_x509_crq_get_tlsfeatures(gnutls_x509_crq_t crq,
2858 				    gnutls_x509_tlsfeatures_t features,
2859 				    unsigned int flags,
2860 				    unsigned int *critical)
2861 {
2862 	int ret;
2863 	gnutls_datum_t der = {NULL, 0};
2864 
2865 	if (crq == NULL) {
2866 		gnutls_assert();
2867 		return GNUTLS_E_INVALID_REQUEST;
2868 	}
2869 
2870 	if ((ret =
2871 		 gnutls_x509_crq_get_extension_by_oid2(crq, GNUTLS_X509EXT_OID_TLSFEATURES, 0,
2872 						&der, critical)) < 0)
2873 	{
2874 		return ret;
2875 	}
2876 
2877 	if (der.size == 0 || der.data == NULL) {
2878 		gnutls_assert();
2879 		return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2880 	}
2881 
2882 	ret = gnutls_x509_ext_import_tlsfeatures(&der, features, flags);
2883 	if (ret < 0) {
2884 		gnutls_assert();
2885 		goto cleanup;
2886 	}
2887 
2888 	ret = 0;
2889  cleanup:
2890 	gnutls_free(der.data);
2891 	return ret;
2892 }
2893 
2894 /**
2895  * gnutls_x509_crq_set_tlsfeatures:
2896  * @crq: An X.509 certificate request
2897  * @features: If the function succeeds, the
2898  *   features will be added to the certificate
2899  *   request.
2900  *
2901  * This function will set the certificate request's
2902  * X.509 TLS extension from the given structure.
2903  *
2904  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2905  *   otherwise a negative error value.
2906  *
2907  * Since: 3.5.1
2908  **/
gnutls_x509_crq_set_tlsfeatures(gnutls_x509_crq_t crq,gnutls_x509_tlsfeatures_t features)2909 int gnutls_x509_crq_set_tlsfeatures(gnutls_x509_crq_t crq,
2910 				    gnutls_x509_tlsfeatures_t features)
2911 {
2912 	int ret;
2913 	gnutls_datum_t der;
2914 
2915 	if (crq == NULL || features == NULL) {
2916 		gnutls_assert();
2917 		return GNUTLS_E_INVALID_REQUEST;
2918 	}
2919 
2920 	ret = gnutls_x509_ext_export_tlsfeatures(features, &der);
2921 	if (ret < 0) {
2922 		gnutls_assert();
2923 		return ret;
2924 	}
2925 
2926 	ret = _gnutls_x509_crq_set_extension(crq, GNUTLS_X509EXT_OID_TLSFEATURES, &der, 0);
2927 
2928 	_gnutls_free_datum(&der);
2929 
2930 	if (ret < 0) {
2931 		gnutls_assert();
2932 	}
2933 
2934 	return ret;
2935 }
2936 
2937 /**
2938  * gnutls_x509_crq_set_extension_by_oid:
2939  * @crq: a certificate of type #gnutls_x509_crq_t
2940  * @oid: holds an Object Identifier in null terminated string
2941  * @buf: a pointer to a DER encoded data
2942  * @sizeof_buf: holds the size of @buf
2943  * @critical: should be non-zero if the extension is to be marked as critical
2944  *
2945  * This function will set an the extension, by the specified OID, in
2946  * the certificate request.  The extension data should be binary data DER
2947  * encoded.
2948  *
2949  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2950  *   negative error value.
2951  **/
2952 int
gnutls_x509_crq_set_extension_by_oid(gnutls_x509_crq_t crq,const char * oid,const void * buf,size_t sizeof_buf,unsigned int critical)2953 gnutls_x509_crq_set_extension_by_oid(gnutls_x509_crq_t crq,
2954 				     const char *oid, const void *buf,
2955 				     size_t sizeof_buf,
2956 				     unsigned int critical)
2957 {
2958 	int result;
2959 	gnutls_datum_t der_data;
2960 
2961 	der_data.data = (void *) buf;
2962 	der_data.size = sizeof_buf;
2963 
2964 	if (crq == NULL) {
2965 		gnutls_assert();
2966 		return GNUTLS_E_INVALID_REQUEST;
2967 	}
2968 
2969 	result =
2970 	    _gnutls_x509_crq_set_extension(crq, oid, &der_data, critical);
2971 	if (result < 0) {
2972 		gnutls_assert();
2973 		return result;
2974 	}
2975 
2976 	return 0;
2977 
2978 }
2979 
2980 /**
2981  * gnutls_x509_crq_set_spki:
2982  * @crq: a certificate request of type #gnutls_x509_crq_t
2983  * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
2984  * @flags: must be zero
2985  *
2986  * This function will set the certificate request's subject public key
2987  * information explicitly. This is intended to be used in the cases
2988  * where a single public key (e.g., RSA) can be used for multiple
2989  * signature algorithms (RSA PKCS1-1.5, and RSA-PSS).
2990  *
2991  * To export the public key (i.e., the SubjectPublicKeyInfo part), check
2992  * gnutls_pubkey_import_x509().
2993  *
2994  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2995  *   negative error value.
2996  *
2997  * Since: 3.6.0
2998  **/
2999 int
gnutls_x509_crq_set_spki(gnutls_x509_crq_t crq,const gnutls_x509_spki_t spki,unsigned int flags)3000 gnutls_x509_crq_set_spki(gnutls_x509_crq_t crq,
3001 			 const gnutls_x509_spki_t spki,
3002 			 unsigned int flags)
3003 {
3004 	int ret;
3005 	gnutls_pk_algorithm_t crq_pk;
3006 	gnutls_x509_spki_st tpki;
3007 	gnutls_pk_params_st params;
3008 	unsigned bits;
3009 
3010 	if (crq == NULL) {
3011 		gnutls_assert();
3012 		return GNUTLS_E_INVALID_REQUEST;
3013 	}
3014 
3015 	ret = _gnutls_x509_crq_get_mpis(crq, &params);
3016 	if (ret < 0) {
3017 		gnutls_assert();
3018 		return ret;
3019 	}
3020 
3021 	bits = pubkey_to_bits(&params);
3022 	crq_pk = params.algo;
3023 
3024 	if (!_gnutls_pk_are_compat(crq_pk, spki->pk)) {
3025                 ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
3026                 goto cleanup;
3027 	}
3028 
3029 	if (spki->pk != GNUTLS_PK_RSA_PSS) {
3030 		if (crq_pk == spki->pk) {
3031 			ret = 0;
3032 			goto cleanup;
3033 		}
3034 
3035 		gnutls_assert();
3036 		ret = GNUTLS_E_INVALID_REQUEST;
3037 		goto cleanup;
3038 	}
3039 
3040 	memset(&tpki, 0, sizeof(gnutls_x509_spki_st));
3041 
3042 	if (crq_pk == GNUTLS_PK_RSA) {
3043 		const mac_entry_st *me;
3044 
3045 		me = hash_to_entry(spki->rsa_pss_dig);
3046 		if (unlikely(me == NULL)) {
3047 			gnutls_assert();
3048 			ret = GNUTLS_E_INVALID_REQUEST;
3049 			goto cleanup;
3050 		}
3051 
3052 		tpki.pk = spki->pk;
3053 		tpki.rsa_pss_dig = spki->rsa_pss_dig;
3054 
3055 		/* If salt size is zero, find the optimal salt size. */
3056 		if (spki->salt_size == 0) {
3057 			ret =
3058 			    _gnutls_find_rsa_pss_salt_size(bits, me,
3059 							   spki->salt_size);
3060 			if (ret < 0) {
3061 				gnutls_assert();
3062 				goto cleanup;
3063 			}
3064 			tpki.salt_size = ret;
3065 		} else
3066 			tpki.salt_size = spki->salt_size;
3067 	} else if (crq_pk == GNUTLS_PK_RSA_PSS) {
3068 		ret = _gnutls_x509_crq_read_spki_params(crq, &tpki);
3069 		if (ret < 0) {
3070 			gnutls_assert();
3071 			goto cleanup;
3072 		}
3073 
3074 		tpki.salt_size = spki->salt_size;
3075 		tpki.rsa_pss_dig = spki->rsa_pss_dig;
3076 	}
3077 
3078 	memcpy(&params.spki, &tpki, sizeof(tpki));
3079 	ret = _gnutls_x509_check_pubkey_params(&params);
3080 	if (ret < 0) {
3081 		gnutls_assert();
3082 		goto cleanup;
3083 	}
3084 
3085 	ret = _gnutls_x509_write_spki_params(crq->crq,
3086 						"certificationRequestInfo."
3087 						"subjectPKInfo."
3088 						"algorithm",
3089 						&tpki);
3090 	if (ret < 0) {
3091 		gnutls_assert();
3092 		goto cleanup;
3093 	}
3094 
3095 	ret = 0;
3096  cleanup:
3097 	gnutls_pk_params_release(&params);
3098 	return ret;
3099 }
3100