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(¶ms);
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, ¶ms);
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(¶ms);
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(¶ms, 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, ¶ms);
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, ¶ms);
2527 if (ret < 0) {
2528 gnutls_assert();
2529 return ret;
2530 }
2531
2532 ret =
2533 _gnutls_get_key_id(¶ms, output_data, output_data_size, flags);
2534
2535 gnutls_pk_params_release(¶ms);
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, ¶ms);
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, ¶ms);
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, ¶ms);
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, ¶ms);
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(¶ms);
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, ¶ms);
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 ¶ms, &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(¶ms);
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, ¶ms);
3016 if (ret < 0) {
3017 gnutls_assert();
3018 return ret;
3019 }
3020
3021 bits = pubkey_to_bits(¶ms);
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(¶ms.spki, &tpki, sizeof(tpki));
3079 ret = _gnutls_x509_check_pubkey_params(¶ms);
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(¶ms);
3098 return ret;
3099 }
3100