Corrected bugs in record parsing.
[gnutls.git] / lib / x509 / crq.c
blob672447fd25b1b6b3d881ccccdd062a18a7bb8596
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains functions to handle PKCS #10 certificate
24 requests, see RFC 2986.
27 #include <gnutls_int.h>
29 #include <gnutls_datum.h>
30 #include <gnutls_global.h>
31 #include <gnutls_errors.h>
32 #include <common.h>
33 #include <gnutls_x509.h>
34 #include <x509_b64.h>
35 #include "x509_int.h"
36 #include <libtasn1.h>
38 /**
39 * gnutls_x509_crq_init:
40 * @crq: The structure to be initialized
42 * This function will initialize a PKCS#10 certificate request
43 * structure.
45 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
46 * negative error value.
47 **/
48 int
49 gnutls_x509_crq_init (gnutls_x509_crq_t * crq)
51 int result;
53 *crq = gnutls_calloc (1, sizeof (gnutls_x509_crq_int));
54 if (!*crq)
55 return GNUTLS_E_MEMORY_ERROR;
57 result = asn1_create_element (_gnutls_get_pkix (),
58 "PKIX1.pkcs-10-CertificationRequest",
59 &((*crq)->crq));
60 if (result != ASN1_SUCCESS)
62 gnutls_assert ();
63 gnutls_free (*crq);
64 return _gnutls_asn2err (result);
67 return 0;
70 /**
71 * gnutls_x509_crq_deinit:
72 * @crq: The structure to be initialized
74 * This function will deinitialize a PKCS#10 certificate request
75 * structure.
76 **/
77 void
78 gnutls_x509_crq_deinit (gnutls_x509_crq_t crq)
80 if (!crq)
81 return;
83 if (crq->crq)
84 asn1_delete_structure (&crq->crq);
86 gnutls_free (crq);
89 #define PEM_CRQ "NEW CERTIFICATE REQUEST"
90 #define PEM_CRQ2 "CERTIFICATE REQUEST"
92 /**
93 * gnutls_x509_crq_import:
94 * @crq: The structure to store the parsed certificate request.
95 * @data: The DER or PEM encoded certificate.
96 * @format: One of DER or PEM
98 * This function will convert the given DER or PEM encoded certificate
99 * request to a #gnutls_x509_crq_t structure. The output will be
100 * stored in @crq.
102 * If the Certificate is PEM encoded it should have a header of "NEW
103 * CERTIFICATE REQUEST".
105 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
106 * negative error value.
109 gnutls_x509_crq_import (gnutls_x509_crq_t crq,
110 const gnutls_datum_t * data,
111 gnutls_x509_crt_fmt_t format)
113 int result = 0, need_free = 0;
114 gnutls_datum_t _data;
116 if (crq == NULL)
118 gnutls_assert ();
119 return GNUTLS_E_INVALID_REQUEST;
122 _data.data = data->data;
123 _data.size = data->size;
125 /* If the Certificate is in PEM format then decode it
127 if (format == GNUTLS_X509_FMT_PEM)
129 /* Try the first header */
130 result = _gnutls_fbase64_decode (PEM_CRQ, data->data, data->size, &_data);
132 if (result < 0) /* Go for the second header */
133 result =
134 _gnutls_fbase64_decode (PEM_CRQ2, data->data, data->size, &_data);
136 if (result < 0)
138 gnutls_assert ();
139 return result;
142 need_free = 1;
145 result = asn1_der_decoding (&crq->crq, _data.data, _data.size, NULL);
146 if (result != ASN1_SUCCESS)
148 result = _gnutls_asn2err (result);
149 gnutls_assert ();
150 goto cleanup;
153 result = 0;
155 cleanup:
156 if (need_free)
157 _gnutls_free_datum (&_data);
158 return result;
162 * gnutls_x509_crq_get_private_key_usage_period:
163 * @cert: should contain a #gnutls_x509_crq_t structure
164 * @activation: The activation time
165 * @expiration: The expiration time
166 * @critical: the extension status
168 * This function will return the expiration and activation
169 * times of the private key of the certificate.
171 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
172 * if the extension is not present, otherwise a negative error value.
175 gnutls_x509_crq_get_private_key_usage_period (gnutls_x509_crq_t crq, time_t* activation, time_t* expiration,
176 unsigned int *critical)
178 int result, ret;
179 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
180 uint8_t buf[128];
181 size_t buf_size = sizeof (buf);
183 if (crq == NULL)
185 gnutls_assert ();
186 return GNUTLS_E_INVALID_REQUEST;
189 ret = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.16", 0,
190 buf, &buf_size, critical);
191 if (ret < 0)
192 return gnutls_assert_val(ret);
194 result = asn1_create_element
195 (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2);
196 if (result != ASN1_SUCCESS)
198 gnutls_assert ();
199 ret = _gnutls_asn2err (result);
200 goto cleanup;
203 result = asn1_der_decoding (&c2, buf, buf_size, NULL);
204 if (result != ASN1_SUCCESS)
206 gnutls_assert ();
207 ret = _gnutls_asn2err (result);
208 goto cleanup;
211 if (activation)
212 *activation = _gnutls_x509_get_time (c2,
213 "notBefore", 1);
215 if (expiration)
216 *expiration = _gnutls_x509_get_time (c2,
217 "notAfter", 1);
219 ret = 0;
221 cleanup:
222 asn1_delete_structure (&c2);
224 return ret;
229 * gnutls_x509_crq_get_dn:
230 * @crq: should contain a #gnutls_x509_crq_t structure
231 * @buf: a pointer to a structure to hold the name (may be %NULL)
232 * @sizeof_buf: initially holds the size of @buf
234 * This function will copy the name of the Certificate request subject
235 * to the provided buffer. The name will be in the form
236 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC 2253. The output string
237 * @buf will be ASCII or UTF-8 encoded, depending on the certificate
238 * data.
240 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
241 * long enough, and in that case the *@sizeof_buf will be updated with
242 * the required size. On success 0 is returned.
245 gnutls_x509_crq_get_dn (gnutls_x509_crq_t crq, char *buf, size_t * sizeof_buf)
247 if (crq == NULL)
249 gnutls_assert ();
250 return GNUTLS_E_INVALID_REQUEST;
253 return _gnutls_x509_parse_dn (crq->crq,
254 "certificationRequestInfo.subject.rdnSequence",
255 buf, sizeof_buf);
259 * gnutls_x509_crq_get_dn_by_oid:
260 * @crq: should contain a gnutls_x509_crq_t structure
261 * @oid: holds an Object Identified in null terminated string
262 * @indx: In case multiple same OIDs exist in the RDN, this specifies
263 * which to send. Use (0) to get the first one.
264 * @raw_flag: If non-zero returns the raw DER data of the DN part.
265 * @buf: a pointer to a structure to hold the name (may be %NULL)
266 * @sizeof_buf: initially holds the size of @buf
268 * This function will extract the part of the name of the Certificate
269 * request subject, specified by the given OID. The output will be
270 * encoded as described in RFC2253. The output string will be ASCII
271 * or UTF-8 encoded, depending on the certificate data.
273 * Some helper macros with popular OIDs can be found in gnutls/x509.h
274 * If raw flag is (0), this function will only return known OIDs as
275 * text. Other OIDs will be DER encoded, as described in RFC2253 --
276 * in hex format with a '\#' prefix. You can check about known OIDs
277 * using gnutls_x509_dn_oid_known().
279 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
280 * not long enough, and in that case the *@sizeof_buf will be
281 * updated with the required size. On success 0 is returned.
284 gnutls_x509_crq_get_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
285 int indx, unsigned int raw_flag,
286 void *buf, size_t * sizeof_buf)
288 gnutls_datum_t td;
289 int ret;
291 if (crq == NULL)
293 gnutls_assert ();
294 return GNUTLS_E_INVALID_REQUEST;
297 ret = _gnutls_x509_parse_dn_oid
298 (crq->crq,
299 "certificationRequestInfo.subject.rdnSequence",
300 oid, indx, raw_flag, &td);
301 if (ret < 0)
302 return gnutls_assert_val(ret);
304 return _gnutls_strdatum_to_buf (&td, buf, sizeof_buf);
308 * gnutls_x509_crq_get_dn_oid:
309 * @crq: should contain a gnutls_x509_crq_t structure
310 * @indx: Specifies which DN OID to send. Use (0) to get the first one.
311 * @oid: a pointer to a structure to hold the name (may be %NULL)
312 * @sizeof_oid: initially holds the size of @oid
314 * This function will extract the requested OID of the name of the
315 * certificate request subject, specified by the given index.
317 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
318 * not long enough, and in that case the *@sizeof_oid will be
319 * updated with the required size. On success 0 is returned.
322 gnutls_x509_crq_get_dn_oid (gnutls_x509_crq_t crq,
323 int indx, void *oid, size_t * sizeof_oid)
325 if (crq == NULL)
327 gnutls_assert ();
328 return GNUTLS_E_INVALID_REQUEST;
331 return _gnutls_x509_get_dn_oid (crq->crq,
332 "certificationRequestInfo.subject.rdnSequence",
333 indx, oid, sizeof_oid);
336 /* Parses an Attribute list in the asn1_struct, and searches for the
337 * given OID. The index indicates the attribute value to be returned.
339 * If raw==0 only printable data are returned, or
340 * GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE.
342 * asn1_attr_name must be a string in the form
343 * "certificationRequestInfo.attributes"
346 static int
347 parse_attribute (ASN1_TYPE asn1_struct,
348 const char *attr_name, const char *given_oid, int indx,
349 int raw, gnutls_datum_t * out)
351 int k1, result;
352 char tmpbuffer1[ASN1_MAX_NAME_SIZE];
353 char tmpbuffer3[ASN1_MAX_NAME_SIZE];
354 char value[200];
355 gnutls_datum_t td;
356 char oid[MAX_OID_SIZE];
357 int len;
359 k1 = 0;
363 k1++;
364 /* create a string like "attribute.?1"
366 if (attr_name[0] != 0)
367 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", attr_name, k1);
368 else
369 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
371 len = sizeof (value) - 1;
372 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
374 if (result == ASN1_ELEMENT_NOT_FOUND)
376 gnutls_assert ();
377 break;
380 if (result != ASN1_VALUE_NOT_FOUND)
382 gnutls_assert ();
383 result = _gnutls_asn2err (result);
384 goto cleanup;
387 /* Move to the attibute type and values
389 /* Read the OID
391 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer1);
392 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
394 len = sizeof (oid) - 1;
395 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
397 if (result == ASN1_ELEMENT_NOT_FOUND)
398 break;
399 else if (result != ASN1_SUCCESS)
401 gnutls_assert ();
402 result = _gnutls_asn2err (result);
403 goto cleanup;
406 if (strcmp (oid, given_oid) == 0)
407 { /* Found the OID */
409 /* Read the Value
411 snprintf (tmpbuffer3, sizeof (tmpbuffer3), "%s.values.?%u",
412 tmpbuffer1, indx + 1);
414 len = sizeof (value) - 1;
415 result = _gnutls_x509_read_value (asn1_struct, tmpbuffer3, &td);
417 if (result != ASN1_SUCCESS)
419 gnutls_assert ();
420 result = _gnutls_asn2err (result);
421 goto cleanup;
424 if (raw == 0)
426 result =
427 _gnutls_x509_dn_to_string
428 (oid, td.data, td.size, out);
430 _gnutls_free_datum(&td);
432 if (result < 0)
434 gnutls_assert ();
435 goto cleanup;
437 return 0;
439 else
440 { /* raw!=0 */
441 out->data = td.data;
442 out->size = td.size;
444 return 0;
449 while (1);
451 gnutls_assert ();
453 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
455 cleanup:
456 return result;
460 * gnutls_x509_crq_get_challenge_password:
461 * @crq: should contain a #gnutls_x509_crq_t structure
462 * @buf: will hold a (0)-terminated password string
463 * @sizeof_buf: Initially holds the size of @pass.
465 * This function will return the challenge password in the request.
466 * The challenge password is intended to be used for requesting a
467 * revocation of the certificate.
469 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
470 * negative error value.
473 gnutls_x509_crq_get_challenge_password (gnutls_x509_crq_t crq,
474 char *buf, size_t * sizeof_buf)
476 gnutls_datum_t td;
477 int ret;
479 if (crq == NULL)
481 gnutls_assert ();
482 return GNUTLS_E_INVALID_REQUEST;
485 ret = parse_attribute (crq->crq, "certificationRequestInfo.attributes",
486 "1.2.840.113549.1.9.7", 0, 0, &td);
487 if (ret < 0)
488 return gnutls_assert_val(ret);
490 return _gnutls_strdatum_to_buf (&td, buf, sizeof_buf);
493 /* This function will attempt to set the requested attribute in
494 * the given X509v3 certificate.
496 * Critical will be either 0 or 1.
498 static int
499 add_attribute (ASN1_TYPE asn, const char *root, const char *attribute_id,
500 const gnutls_datum_t * ext_data)
502 int result;
503 char name[ASN1_MAX_NAME_SIZE];
505 snprintf (name, sizeof (name), "%s", root);
507 /* Add a new attribute in the list.
509 result = asn1_write_value (asn, name, "NEW", 1);
510 if (result != ASN1_SUCCESS)
512 gnutls_assert ();
513 return _gnutls_asn2err (result);
516 snprintf (name, sizeof (name), "%s.?LAST.type", root);
518 result = asn1_write_value (asn, name, attribute_id, 1);
519 if (result != ASN1_SUCCESS)
521 gnutls_assert ();
522 return _gnutls_asn2err (result);
525 snprintf (name, sizeof (name), "%s.?LAST.values", root);
527 result = asn1_write_value (asn, name, "NEW", 1);
528 if (result != ASN1_SUCCESS)
530 gnutls_assert ();
531 return _gnutls_asn2err (result);
534 snprintf (name, sizeof (name), "%s.?LAST.values.?LAST", root);
536 result = _gnutls_x509_write_value (asn, name, ext_data);
537 if (result < 0)
539 gnutls_assert ();
540 return result;
543 return 0;
546 /* Overwrite the given attribute (using the index)
547 * index here starts from one.
549 static int
550 overwrite_attribute (ASN1_TYPE asn, const char *root, unsigned int indx,
551 const gnutls_datum_t * ext_data)
553 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
554 int result;
556 snprintf (name, sizeof (name), "%s.?%u", root, indx);
558 _gnutls_str_cpy (name2, sizeof (name2), name);
559 _gnutls_str_cat (name2, sizeof (name2), ".values.?LAST");
561 result = _gnutls_x509_write_value (asn, name2, ext_data);
562 if (result < 0)
564 gnutls_assert ();
565 return result;
569 return 0;
572 static int
573 set_attribute (ASN1_TYPE asn, const char *root,
574 const char *ext_id, const gnutls_datum_t * ext_data)
576 int result;
577 int k, len;
578 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
579 char extnID[MAX_OID_SIZE];
581 /* Find the index of the given attribute.
583 k = 0;
586 k++;
588 snprintf (name, sizeof (name), "%s.?%u", root, k);
590 len = sizeof (extnID) - 1;
591 result = asn1_read_value (asn, name, extnID, &len);
593 /* move to next
596 if (result == ASN1_ELEMENT_NOT_FOUND)
598 break;
604 _gnutls_str_cpy (name2, sizeof (name2), name);
605 _gnutls_str_cat (name2, sizeof (name2), ".type");
607 len = sizeof (extnID) - 1;
608 result = asn1_read_value (asn, name2, extnID, &len);
610 if (result == ASN1_ELEMENT_NOT_FOUND)
612 gnutls_assert ();
613 break;
615 else if (result != ASN1_SUCCESS)
617 gnutls_assert ();
618 return _gnutls_asn2err (result);
621 /* Handle Extension
623 if (strcmp (extnID, ext_id) == 0)
625 /* attribute was found
627 return overwrite_attribute (asn, root, k, ext_data);
632 while (0);
634 while (1);
636 if (result == ASN1_ELEMENT_NOT_FOUND)
638 return add_attribute (asn, root, ext_id, ext_data);
640 else
642 gnutls_assert ();
643 return _gnutls_asn2err (result);
647 return 0;
651 * gnutls_x509_crq_set_attribute_by_oid:
652 * @crq: should contain a #gnutls_x509_crq_t structure
653 * @oid: holds an Object Identified in (0)-terminated string
654 * @buf: a pointer to a structure that holds the attribute data
655 * @sizeof_buf: holds the size of @buf
657 * This function will set the attribute in the certificate request
658 * specified by the given Object ID. The attribute must be be DER
659 * encoded.
661 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
662 * negative error value.
665 gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq,
666 const char *oid, void *buf,
667 size_t sizeof_buf)
669 gnutls_datum_t data;
671 data.data = buf;
672 data.size = sizeof_buf;
674 if (crq == NULL)
676 gnutls_assert ();
677 return GNUTLS_E_INVALID_REQUEST;
680 return set_attribute (crq->crq, "certificationRequestInfo.attributes",
681 oid, &data);
685 * gnutls_x509_crq_get_attribute_by_oid:
686 * @crq: should contain a #gnutls_x509_crq_t structure
687 * @oid: holds an Object Identified in (0)-terminated string
688 * @indx: In case multiple same OIDs exist in the attribute list, this
689 * specifies which to send, use (0) to get the first one
690 * @buf: a pointer to a structure to hold the attribute data (may be %NULL)
691 * @sizeof_buf: initially holds the size of @buf
693 * This function will return the attribute in the certificate request
694 * specified by the given Object ID. The attribute will be DER
695 * encoded.
697 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
698 * negative error value.
701 gnutls_x509_crq_get_attribute_by_oid (gnutls_x509_crq_t crq,
702 const char *oid, int indx, void *buf,
703 size_t * sizeof_buf)
705 int ret;
706 gnutls_datum_t td;
708 if (crq == NULL)
710 gnutls_assert ();
711 return GNUTLS_E_INVALID_REQUEST;
714 ret = parse_attribute (crq->crq, "certificationRequestInfo.attributes",
715 oid, indx, 1, &td);
716 if (ret < 0)
717 return gnutls_assert_val(ret);
719 return _gnutls_strdatum_to_buf (&td, buf, sizeof_buf);
723 * gnutls_x509_crq_set_dn_by_oid:
724 * @crq: should contain a #gnutls_x509_crq_t structure
725 * @oid: holds an Object Identifier in a (0)-terminated string
726 * @raw_flag: must be 0, or 1 if the data are DER encoded
727 * @data: a pointer to the input data
728 * @sizeof_data: holds the size of @data
730 * This function will set the part of the name of the Certificate
731 * request subject, specified by the given OID. The input string
732 * should be ASCII or UTF-8 encoded.
734 * Some helper macros with popular OIDs can be found in gnutls/x509.h
735 * With this function you can only set the known OIDs. You can test
736 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
737 * not known (by gnutls) you should properly DER encode your data, and
738 * call this function with raw_flag set.
740 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
741 * negative error value.
744 gnutls_x509_crq_set_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
745 unsigned int raw_flag, const void *data,
746 unsigned int sizeof_data)
748 if (sizeof_data == 0 || data == NULL || crq == NULL)
750 return GNUTLS_E_INVALID_REQUEST;
753 return _gnutls_x509_set_dn_oid (crq->crq,
754 "certificationRequestInfo.subject", oid,
755 raw_flag, data, sizeof_data);
759 * gnutls_x509_crq_set_version:
760 * @crq: should contain a #gnutls_x509_crq_t structure
761 * @version: holds the version number, for v1 Requests must be 1
763 * This function will set the version of the certificate request. For
764 * version 1 requests this must be one.
766 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
767 * negative error value.
770 gnutls_x509_crq_set_version (gnutls_x509_crq_t crq, unsigned int version)
772 int result;
773 unsigned char null = version;
775 if (crq == NULL)
777 gnutls_assert ();
778 return GNUTLS_E_INVALID_REQUEST;
781 if (null > 0)
782 null--;
784 result =
785 asn1_write_value (crq->crq, "certificationRequestInfo.version", &null, 1);
786 if (result != ASN1_SUCCESS)
788 gnutls_assert ();
789 return _gnutls_asn2err (result);
792 return 0;
796 * gnutls_x509_crq_get_version:
797 * @crq: should contain a #gnutls_x509_crq_t structure
799 * This function will return the version of the specified Certificate
800 * request.
802 * Returns: version of certificate request, or a negative error code on
803 * error.
806 gnutls_x509_crq_get_version (gnutls_x509_crq_t crq)
808 uint8_t version[8];
809 int len, result;
811 if (crq == NULL)
813 gnutls_assert ();
814 return GNUTLS_E_INVALID_REQUEST;
817 len = sizeof (version);
818 if ((result =
819 asn1_read_value (crq->crq, "certificationRequestInfo.version",
820 version, &len)) != ASN1_SUCCESS)
823 if (result == ASN1_ELEMENT_NOT_FOUND)
824 return 1; /* the DEFAULT version */
825 gnutls_assert ();
826 return _gnutls_asn2err (result);
829 return (int) version[0] + 1;
833 * gnutls_x509_crq_set_key:
834 * @crq: should contain a #gnutls_x509_crq_t structure
835 * @key: holds a private key
837 * This function will set the public parameters from the given private
838 * key to the request.
840 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
841 * negative error value.
844 gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
846 int result;
848 if (crq == NULL)
850 gnutls_assert ();
851 return GNUTLS_E_INVALID_REQUEST;
854 result = _gnutls_x509_encode_and_copy_PKI_params
855 (crq->crq,
856 "certificationRequestInfo.subjectPKInfo",
857 key->pk_algorithm, &key->params);
859 if (result < 0)
861 gnutls_assert ();
862 return result;
865 return 0;
869 * gnutls_x509_crq_get_key_rsa_raw:
870 * @crq: Holds the certificate
871 * @m: will hold the modulus
872 * @e: will hold the public exponent
874 * This function will export the RSA public key's parameters found in
875 * the given structure. The new parameters will be allocated using
876 * gnutls_malloc() and will be stored in the appropriate datum.
878 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
879 * negative error value.
881 * Since: 2.8.0
884 gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq,
885 gnutls_datum_t * m, gnutls_datum_t * e)
887 int ret;
888 gnutls_pk_params_st params;
890 gnutls_pk_params_init(&params);
892 if (crq == NULL)
894 gnutls_assert ();
895 return GNUTLS_E_INVALID_REQUEST;
898 ret = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
899 if (ret != GNUTLS_PK_RSA)
901 gnutls_assert ();
902 return GNUTLS_E_INVALID_REQUEST;
905 ret = _gnutls_x509_crq_get_mpis (crq, &params);
906 if (ret < 0)
908 gnutls_assert ();
909 return ret;
912 ret = _gnutls_mpi_dprint (params.params[0], m);
913 if (ret < 0)
915 gnutls_assert ();
916 goto cleanup;
919 ret = _gnutls_mpi_dprint (params.params[1], e);
920 if (ret < 0)
922 gnutls_assert ();
923 _gnutls_free_datum (m);
924 goto cleanup;
927 ret = 0;
929 cleanup:
930 gnutls_pk_params_release(&params);
931 return ret;
935 * gnutls_x509_crq_set_key_rsa_raw:
936 * @crq: should contain a #gnutls_x509_crq_t structure
937 * @m: holds the modulus
938 * @e: holds the public exponent
940 * This function will set the public parameters from the given private
941 * key to the request. Only RSA keys are currently supported.
943 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
944 * negative error value.
946 * Since: 2.6.0
949 gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq,
950 const gnutls_datum_t * m,
951 const gnutls_datum_t * e)
953 int result, ret;
954 size_t siz = 0;
955 gnutls_pk_params_st temp_params;
957 gnutls_pk_params_init(&temp_params);
959 if (crq == NULL)
961 gnutls_assert ();
962 return GNUTLS_E_INVALID_REQUEST;
965 memset (&temp_params, 0, sizeof (temp_params));
967 siz = m->size;
968 if (_gnutls_mpi_scan_nz (&temp_params.params[0], m->data, siz))
970 gnutls_assert ();
971 ret = GNUTLS_E_MPI_SCAN_FAILED;
972 goto error;
975 siz = e->size;
976 if (_gnutls_mpi_scan_nz (&temp_params.params[1], e->data, siz))
978 gnutls_assert ();
979 ret = GNUTLS_E_MPI_SCAN_FAILED;
980 goto error;
983 temp_params.params_nr = RSA_PUBLIC_PARAMS;
985 result = _gnutls_x509_encode_and_copy_PKI_params
986 (crq->crq,
987 "certificationRequestInfo.subjectPKInfo",
988 GNUTLS_PK_RSA, &temp_params);
990 if (result < 0)
992 gnutls_assert ();
993 ret = result;
994 goto error;
997 ret = 0;
999 error:
1000 gnutls_pk_params_release(&temp_params);
1001 return ret;
1005 * gnutls_x509_crq_set_challenge_password:
1006 * @crq: should contain a #gnutls_x509_crq_t structure
1007 * @pass: holds a (0)-terminated password
1009 * This function will set a challenge password to be used when
1010 * revoking the request.
1012 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1013 * negative error value.
1016 gnutls_x509_crq_set_challenge_password (gnutls_x509_crq_t crq,
1017 const char *pass)
1019 int result;
1021 if (crq == NULL)
1023 gnutls_assert ();
1024 return GNUTLS_E_INVALID_REQUEST;
1027 /* Add the attribute.
1029 result = asn1_write_value (crq->crq, "certificationRequestInfo.attributes",
1030 "NEW", 1);
1031 if (result != ASN1_SUCCESS)
1033 gnutls_assert ();
1034 return _gnutls_asn2err (result);
1037 result = _gnutls_x509_encode_and_write_attribute
1038 ("1.2.840.113549.1.9.7", crq->crq,
1039 "certificationRequestInfo.attributes.?LAST", pass, strlen (pass), 1);
1040 if (result < 0)
1042 gnutls_assert ();
1043 return result;
1046 return 0;
1050 * gnutls_x509_crq_sign2:
1051 * @crq: should contain a #gnutls_x509_crq_t structure
1052 * @key: holds a private key
1053 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
1054 * @flags: must be 0
1056 * This function will sign the certificate request with a private key.
1057 * This must be the same key as the one used in
1058 * gnutls_x509_crt_set_key() since a certificate request is self
1059 * signed.
1061 * This must be the last step in a certificate request generation
1062 * since all the previously set parameters are now signed.
1064 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1065 * %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
1066 * information in the certificate request (e.g., the version using
1067 * gnutls_x509_crq_set_version()).
1071 gnutls_x509_crq_sign2 (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key,
1072 gnutls_digest_algorithm_t dig, unsigned int flags)
1074 int result;
1075 gnutls_privkey_t privkey;
1077 if (crq == NULL)
1079 gnutls_assert ();
1080 return GNUTLS_E_INVALID_REQUEST;
1083 result = gnutls_privkey_init (&privkey);
1084 if (result < 0)
1086 gnutls_assert ();
1087 return result;
1090 result = gnutls_privkey_import_x509 (privkey, key, 0);
1091 if (result < 0)
1093 gnutls_assert ();
1094 goto fail;
1097 result = gnutls_x509_crq_privkey_sign (crq, privkey, dig, flags);
1098 if (result < 0)
1100 gnutls_assert ();
1101 goto fail;
1104 result = 0;
1106 fail:
1107 gnutls_privkey_deinit (privkey);
1109 return result;
1113 * gnutls_x509_crq_sign:
1114 * @crq: should contain a #gnutls_x509_crq_t structure
1115 * @key: holds a private key
1117 * This function is the same a gnutls_x509_crq_sign2() with no flags,
1118 * and SHA1 as the hash algorithm.
1120 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1121 * negative error value.
1123 * Deprecated: Use gnutls_x509_crq_privkey_sign() instead.
1126 gnutls_x509_crq_sign (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
1128 return gnutls_x509_crq_sign2 (crq, key, GNUTLS_DIG_SHA1, 0);
1132 * gnutls_x509_crq_export:
1133 * @crq: should contain a #gnutls_x509_crq_t structure
1134 * @format: the format of output params. One of PEM or DER.
1135 * @output_data: will contain a certificate request PEM or DER encoded
1136 * @output_data_size: holds the size of output_data (and will be
1137 * replaced by the actual size of parameters)
1139 * This function will export the certificate request to a PEM or DER
1140 * encoded PKCS10 structure.
1142 * If the buffer provided is not long enough to hold the output, then
1143 * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
1144 * *@output_data_size will be updated.
1146 * If the structure is PEM encoded, it will have a header of "BEGIN
1147 * NEW CERTIFICATE REQUEST".
1149 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1150 * negative error value.
1153 gnutls_x509_crq_export (gnutls_x509_crq_t crq,
1154 gnutls_x509_crt_fmt_t format, void *output_data,
1155 size_t * output_data_size)
1157 if (crq == NULL)
1159 gnutls_assert ();
1160 return GNUTLS_E_INVALID_REQUEST;
1163 return _gnutls_x509_export_int (crq->crq, format, PEM_CRQ,
1164 output_data, output_data_size);
1168 * gnutls_x509_crq_export2:
1169 * @crq: should contain a #gnutls_x509_crq_t structure
1170 * @format: the format of output params. One of PEM or DER.
1171 * @out: will contain a certificate request PEM or DER encoded
1173 * This function will export the certificate request to a PEM or DER
1174 * encoded PKCS10 structure.
1176 * The output buffer is allocated using gnutls_malloc().
1178 * If the structure is PEM encoded, it will have a header of "BEGIN
1179 * NEW CERTIFICATE REQUEST".
1181 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1182 * negative error value.
1184 * Since 3.1.3
1187 gnutls_x509_crq_export2 (gnutls_x509_crq_t crq,
1188 gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
1190 if (crq == NULL)
1192 gnutls_assert ();
1193 return GNUTLS_E_INVALID_REQUEST;
1196 return _gnutls_x509_export_int2 (crq->crq, format, PEM_CRQ, out);
1200 * gnutls_x509_crq_get_pk_algorithm:
1201 * @crq: should contain a #gnutls_x509_crq_t structure
1202 * @bits: if bits is non-%NULL it will hold the size of the parameters' in bits
1204 * This function will return the public key algorithm of a PKCS#10
1205 * certificate request.
1207 * If bits is non-%NULL, it should have enough size to hold the
1208 * parameters size in bits. For RSA the bits returned is the modulus.
1209 * For DSA the bits returned are of the public exponent.
1211 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1212 * success, or a negative error code on error.
1215 gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits)
1217 int result;
1219 if (crq == NULL)
1221 gnutls_assert ();
1222 return GNUTLS_E_INVALID_REQUEST;
1225 result = _gnutls_x509_get_pk_algorithm
1226 (crq->crq, "certificationRequestInfo.subjectPKInfo", bits);
1227 if (result < 0)
1229 gnutls_assert ();
1232 return result;
1236 * gnutls_x509_crq_get_attribute_info:
1237 * @crq: should contain a #gnutls_x509_crq_t structure
1238 * @indx: Specifies which attribute OID to send. Use (0) to get the first one.
1239 * @oid: a pointer to a structure to hold the OID
1240 * @sizeof_oid: initially holds the maximum size of @oid, on return
1241 * holds actual size of @oid.
1243 * This function will return the requested attribute OID in the
1244 * certificate, and the critical flag for it. The attribute OID will
1245 * be stored as a string in the provided buffer. Use
1246 * gnutls_x509_crq_get_attribute_data() to extract the data.
1248 * If the buffer provided is not long enough to hold the output, then
1249 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1250 * returned.
1252 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1253 * negative error code in case of an error. If your have reached the
1254 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1255 * will be returned.
1257 * Since: 2.8.0
1260 gnutls_x509_crq_get_attribute_info (gnutls_x509_crq_t crq, int indx,
1261 void *oid, size_t * sizeof_oid)
1263 int result;
1264 char name[ASN1_MAX_NAME_SIZE];
1265 int len;
1267 if (!crq)
1269 gnutls_assert ();
1270 return GNUTLS_E_INVALID_REQUEST;
1273 snprintf (name, sizeof (name),
1274 "certificationRequestInfo.attributes.?%u.type", indx + 1);
1276 len = *sizeof_oid;
1277 result = asn1_read_value (crq->crq, name, oid, &len);
1278 *sizeof_oid = len;
1280 if (result == ASN1_ELEMENT_NOT_FOUND)
1281 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1282 else if (result < 0)
1284 gnutls_assert ();
1285 return _gnutls_asn2err (result);
1288 return 0;
1293 * gnutls_x509_crq_get_attribute_data:
1294 * @crq: should contain a #gnutls_x509_crq_t structure
1295 * @indx: Specifies which attribute OID to send. Use (0) to get the first one.
1296 * @data: a pointer to a structure to hold the data (may be null)
1297 * @sizeof_data: initially holds the size of @oid
1299 * This function will return the requested attribute data in the
1300 * certificate request. The attribute data will be stored as a string in the
1301 * provided buffer.
1303 * Use gnutls_x509_crq_get_attribute_info() to extract the OID.
1304 * Use gnutls_x509_crq_get_attribute_by_oid() instead,
1305 * if you want to get data indexed by the attribute OID rather than
1306 * sequence.
1308 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1309 * negative error code in case of an error. If your have reached the
1310 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1311 * will be returned.
1313 * Since: 2.8.0
1316 gnutls_x509_crq_get_attribute_data (gnutls_x509_crq_t crq, int indx,
1317 void *data, size_t * sizeof_data)
1319 int result, len;
1320 char name[ASN1_MAX_NAME_SIZE];
1322 if (!crq)
1324 gnutls_assert ();
1325 return GNUTLS_E_INVALID_REQUEST;
1328 snprintf (name, sizeof (name),
1329 "certificationRequestInfo.attributes.?%u.values.?1", indx + 1);
1331 len = *sizeof_data;
1332 result = asn1_read_value (crq->crq, name, data, &len);
1333 *sizeof_data = len;
1335 if (result == ASN1_ELEMENT_NOT_FOUND)
1336 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1337 else if (result < 0)
1339 gnutls_assert ();
1340 return _gnutls_asn2err (result);
1343 return 0;
1347 * gnutls_x509_crq_get_extension_info:
1348 * @crq: should contain a #gnutls_x509_crq_t structure
1349 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1350 * @oid: a pointer to a structure to hold the OID
1351 * @sizeof_oid: initially holds the maximum size of @oid, on return
1352 * holds actual size of @oid.
1353 * @critical: output variable with critical flag, may be NULL.
1355 * This function will return the requested extension OID in the
1356 * certificate, and the critical flag for it. The extension OID will
1357 * be stored as a string in the provided buffer. Use
1358 * gnutls_x509_crq_get_extension_data() to extract the data.
1360 * If the buffer provided is not long enough to hold the output, then
1361 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1362 * returned.
1364 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1365 * negative error code in case of an error. If your have reached the
1366 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1367 * will be returned.
1369 * Since: 2.8.0
1372 gnutls_x509_crq_get_extension_info (gnutls_x509_crq_t crq, int indx,
1373 void *oid, size_t * sizeof_oid,
1374 unsigned int *critical)
1376 int result;
1377 char str_critical[10];
1378 char name[ASN1_MAX_NAME_SIZE];
1379 char *extensions = NULL;
1380 size_t extensions_size = 0;
1381 ASN1_TYPE c2;
1382 int len;
1384 if (!crq)
1386 gnutls_assert ();
1387 return GNUTLS_E_INVALID_REQUEST;
1390 /* read extensionRequest */
1391 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1392 0, NULL, &extensions_size);
1393 if (result == GNUTLS_E_SHORT_MEMORY_BUFFER)
1395 extensions = gnutls_malloc (extensions_size);
1396 if (extensions == NULL)
1398 gnutls_assert ();
1399 return GNUTLS_E_MEMORY_ERROR;
1402 result = gnutls_x509_crq_get_attribute_by_oid (crq,
1403 "1.2.840.113549.1.9.14",
1404 0, extensions,
1405 &extensions_size);
1407 if (result < 0)
1409 gnutls_assert ();
1410 goto out;
1413 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
1414 if (result != ASN1_SUCCESS)
1416 gnutls_assert ();
1417 result = _gnutls_asn2err (result);
1418 goto out;
1421 result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
1422 if (result != ASN1_SUCCESS)
1424 gnutls_assert ();
1425 asn1_delete_structure (&c2);
1426 result = _gnutls_asn2err (result);
1427 goto out;
1430 snprintf (name, sizeof (name), "?%u.extnID", indx + 1);
1432 len = *sizeof_oid;
1433 result = asn1_read_value (c2, name, oid, &len);
1434 *sizeof_oid = len;
1436 if (result == ASN1_ELEMENT_NOT_FOUND)
1438 asn1_delete_structure (&c2);
1439 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1440 goto out;
1442 else if (result < 0)
1444 gnutls_assert ();
1445 asn1_delete_structure (&c2);
1446 result = _gnutls_asn2err (result);
1447 goto out;
1450 snprintf (name, sizeof (name), "?%u.critical", indx + 1);
1451 len = sizeof (str_critical);
1452 result = asn1_read_value (c2, name, str_critical, &len);
1454 asn1_delete_structure (&c2);
1456 if (result < 0)
1458 gnutls_assert ();
1459 result = _gnutls_asn2err (result);
1460 goto out;
1463 if (critical)
1465 if (str_critical[0] == 'T')
1466 *critical = 1;
1467 else
1468 *critical = 0;
1471 result = 0;
1473 out:
1474 gnutls_free (extensions);
1475 return result;
1479 * gnutls_x509_crq_get_extension_data:
1480 * @crq: should contain a #gnutls_x509_crq_t structure
1481 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1482 * @data: a pointer to a structure to hold the data (may be null)
1483 * @sizeof_data: initially holds the size of @oid
1485 * This function will return the requested extension data in the
1486 * certificate. The extension data will be stored as a string in the
1487 * provided buffer.
1489 * Use gnutls_x509_crq_get_extension_info() to extract the OID and
1490 * critical flag. Use gnutls_x509_crq_get_extension_by_oid() instead,
1491 * if you want to get data indexed by the extension OID rather than
1492 * sequence.
1494 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1495 * negative error code in case of an error. If your have reached the
1496 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1497 * will be returned.
1499 * Since: 2.8.0
1502 gnutls_x509_crq_get_extension_data (gnutls_x509_crq_t crq, int indx,
1503 void *data, size_t * sizeof_data)
1505 int result, len;
1506 char name[ASN1_MAX_NAME_SIZE];
1507 unsigned char *extensions;
1508 size_t extensions_size = 0;
1509 ASN1_TYPE c2;
1511 if (!crq)
1513 gnutls_assert ();
1514 return GNUTLS_E_INVALID_REQUEST;
1517 /* read extensionRequest */
1518 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1519 0, NULL, &extensions_size);
1520 if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
1522 gnutls_assert ();
1523 if (result == 0)
1524 return GNUTLS_E_INTERNAL_ERROR;
1525 return result;
1528 extensions = gnutls_malloc (extensions_size);
1529 if (extensions == NULL)
1531 gnutls_assert ();
1532 return GNUTLS_E_MEMORY_ERROR;
1535 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1536 0, extensions,
1537 &extensions_size);
1538 if (result < 0)
1540 gnutls_assert ();
1541 return result;
1544 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
1545 if (result != ASN1_SUCCESS)
1547 gnutls_assert ();
1548 gnutls_free (extensions);
1549 return _gnutls_asn2err (result);
1552 result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
1553 gnutls_free (extensions);
1554 if (result != ASN1_SUCCESS)
1556 gnutls_assert ();
1557 asn1_delete_structure (&c2);
1558 return _gnutls_asn2err (result);
1561 snprintf (name, sizeof (name), "?%u.extnValue", indx + 1);
1563 len = *sizeof_data;
1564 result = asn1_read_value (c2, name, data, &len);
1565 *sizeof_data = len;
1567 asn1_delete_structure (&c2);
1569 if (result == ASN1_ELEMENT_NOT_FOUND)
1570 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1571 else if (result < 0)
1573 gnutls_assert ();
1574 return _gnutls_asn2err (result);
1577 return 0;
1581 * gnutls_x509_crq_get_key_usage:
1582 * @crq: should contain a #gnutls_x509_crq_t structure
1583 * @key_usage: where the key usage bits will be stored
1584 * @critical: will be non-zero if the extension is marked as critical
1586 * This function will return certificate's key usage, by reading the
1587 * keyUsage X.509 extension (2.5.29.15). The key usage value will
1588 * ORed values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1589 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1590 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1591 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1592 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1594 * Returns: the certificate key usage, or a negative error code in case of
1595 * parsing error. If the certificate does not contain the keyUsage
1596 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1597 * returned.
1599 * Since: 2.8.0
1602 gnutls_x509_crq_get_key_usage (gnutls_x509_crq_t crq,
1603 unsigned int *key_usage,
1604 unsigned int *critical)
1606 int result;
1607 uint16_t _usage;
1608 uint8_t buf[128];
1609 size_t buf_size = sizeof (buf);
1611 if (crq == NULL)
1613 gnutls_assert ();
1614 return GNUTLS_E_INVALID_REQUEST;
1617 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.15", 0,
1618 buf, &buf_size, critical);
1619 if (result < 0)
1621 gnutls_assert ();
1622 return result;
1625 result = _gnutls_x509_ext_extract_keyUsage (&_usage, buf, buf_size);
1627 *key_usage = _usage;
1629 if (result < 0)
1631 gnutls_assert ();
1632 return result;
1635 return 0;
1639 * gnutls_x509_crq_get_basic_constraints:
1640 * @crq: should contain a #gnutls_x509_crq_t structure
1641 * @critical: will be non-zero if the extension is marked as critical
1642 * @ca: pointer to output integer indicating CA status, may be NULL,
1643 * value is 1 if the certificate CA flag is set, 0 otherwise.
1644 * @pathlen: pointer to output integer indicating path length (may be
1645 * NULL), non-negative error codes indicate a present pathLenConstraint
1646 * field and the actual value, -1 indicate that the field is absent.
1648 * This function will read the certificate's basic constraints, and
1649 * return the certificates CA status. It reads the basicConstraints
1650 * X.509 extension (2.5.29.19).
1652 * Returns: If the certificate is a CA a positive value will be
1653 * returned, or (0) if the certificate does not have CA flag set.
1654 * A negative error code may be returned in case of errors. If the
1655 * certificate does not contain the basicConstraints extension
1656 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1658 * Since: 2.8.0
1661 gnutls_x509_crq_get_basic_constraints (gnutls_x509_crq_t crq,
1662 unsigned int *critical,
1663 unsigned int *ca, int *pathlen)
1665 int result;
1666 unsigned int tmp_ca;
1667 uint8_t buf[256];
1668 size_t buf_size = sizeof (buf);
1670 if (crq == NULL)
1672 gnutls_assert ();
1673 return GNUTLS_E_INVALID_REQUEST;
1676 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.19", 0,
1677 buf, &buf_size, critical);
1678 if (result < 0)
1680 gnutls_assert ();
1681 return result;
1684 result =
1685 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca,
1686 pathlen, buf, buf_size);
1687 if (ca)
1688 *ca = tmp_ca;
1690 if (result < 0)
1692 gnutls_assert ();
1693 return result;
1696 return tmp_ca;
1699 static int
1700 get_subject_alt_name (gnutls_x509_crq_t crq,
1701 unsigned int seq, void *ret,
1702 size_t * ret_size, unsigned int *ret_type,
1703 unsigned int *critical, int othername_oid)
1705 int result;
1706 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1707 gnutls_x509_subject_alt_name_t type;
1708 gnutls_datum_t dnsname = { NULL, 0 };
1709 size_t dns_size = 0;
1711 if (crq == NULL)
1713 gnutls_assert ();
1714 return GNUTLS_E_INVALID_REQUEST;
1717 if (ret)
1718 memset (ret, 0, *ret_size);
1719 else
1720 *ret_size = 0;
1722 /* Extract extension.
1724 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1725 NULL, &dns_size, critical);
1726 if (result < 0)
1728 gnutls_assert ();
1729 return result;
1732 dnsname.size = dns_size;
1733 dnsname.data = gnutls_malloc (dnsname.size);
1734 if (dnsname.data == NULL)
1736 gnutls_assert ();
1737 return GNUTLS_E_MEMORY_ERROR;
1740 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1741 dnsname.data, &dns_size,
1742 critical);
1743 if (result < 0)
1745 gnutls_assert ();
1746 gnutls_free (dnsname.data);
1747 return result;
1750 result = asn1_create_element
1751 (_gnutls_get_pkix (), "PKIX1.SubjectAltName", &c2);
1752 if (result != ASN1_SUCCESS)
1754 gnutls_assert ();
1755 gnutls_free (dnsname.data);
1756 return _gnutls_asn2err (result);
1759 result = asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
1760 gnutls_free (dnsname.data);
1761 if (result != ASN1_SUCCESS)
1763 gnutls_assert ();
1764 asn1_delete_structure (&c2);
1765 return _gnutls_asn2err (result);
1768 result = _gnutls_parse_general_name (c2, "", seq, ret, ret_size,
1769 ret_type, othername_oid);
1770 asn1_delete_structure (&c2);
1771 if (result < 0)
1773 return result;
1776 type = result;
1778 return type;
1782 * gnutls_x509_crq_get_subject_alt_name:
1783 * @crq: should contain a #gnutls_x509_crq_t structure
1784 * @seq: specifies the sequence number of the alt name, 0 for the
1785 * first one, 1 for the second etc.
1786 * @ret: is the place where the alternative name will be copied to
1787 * @ret_size: holds the size of ret.
1788 * @ret_type: holds the #gnutls_x509_subject_alt_name_t name type
1789 * @critical: will be non-zero if the extension is marked as critical
1790 * (may be null)
1792 * This function will return the alternative names, contained in the
1793 * given certificate. It is the same as
1794 * gnutls_x509_crq_get_subject_alt_name() except for the fact that it
1795 * will return the type of the alternative name in @ret_type even if
1796 * the function fails for some reason (i.e. the buffer provided is
1797 * not enough).
1799 * Returns: the alternative subject name type on success, one of the
1800 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1801 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1802 * hold the value. In that case @ret_size will be updated with the
1803 * required size. If the certificate request does not have an
1804 * Alternative name with the specified sequence number then
1805 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1807 * Since: 2.8.0
1810 gnutls_x509_crq_get_subject_alt_name (gnutls_x509_crq_t crq,
1811 unsigned int seq, void *ret,
1812 size_t * ret_size,
1813 unsigned int *ret_type,
1814 unsigned int *critical)
1816 return get_subject_alt_name (crq, seq, ret, ret_size, ret_type, critical,
1821 * gnutls_x509_crq_get_subject_alt_othername_oid:
1822 * @crq: should contain a #gnutls_x509_crq_t structure
1823 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1824 * @ret: is the place where the otherName OID will be copied to
1825 * @ret_size: holds the size of ret.
1827 * This function will extract the type OID of an otherName Subject
1828 * Alternative Name, contained in the given certificate, and return
1829 * the type as an enumerated element.
1831 * This function is only useful if
1832 * gnutls_x509_crq_get_subject_alt_name() returned
1833 * %GNUTLS_SAN_OTHERNAME.
1835 * Returns: the alternative subject name type on success, one of the
1836 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs,
1837 * it will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1838 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1839 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1840 * @ret_size is not large enough to hold the value. In that case
1841 * @ret_size will be updated with the required size. If the
1842 * certificate does not have an Alternative name with the specified
1843 * sequence number and with the otherName type then
1844 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1846 * Since: 2.8.0
1849 gnutls_x509_crq_get_subject_alt_othername_oid (gnutls_x509_crq_t crq,
1850 unsigned int seq,
1851 void *ret, size_t * ret_size)
1853 return get_subject_alt_name (crq, seq, ret, ret_size, NULL, NULL, 1);
1857 * gnutls_x509_crq_get_extension_by_oid:
1858 * @crq: should contain a #gnutls_x509_crq_t structure
1859 * @oid: holds an Object Identified in null terminated string
1860 * @indx: In case multiple same OIDs exist in the extensions, this
1861 * specifies which to send. Use (0) to get the first one.
1862 * @buf: a pointer to a structure to hold the name (may be null)
1863 * @sizeof_buf: initially holds the size of @buf
1864 * @critical: will be non-zero if the extension is marked as critical
1866 * This function will return the extension specified by the OID in
1867 * the certificate. The extensions will be returned as binary data
1868 * DER encoded, in the provided buffer.
1870 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1871 * negative error code in case of an error. If the certificate does not
1872 * contain the specified extension
1873 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1875 * Since: 2.8.0
1878 gnutls_x509_crq_get_extension_by_oid (gnutls_x509_crq_t crq,
1879 const char *oid, int indx,
1880 void *buf, size_t * sizeof_buf,
1881 unsigned int *critical)
1883 int result;
1884 unsigned int i;
1885 char _oid[MAX_OID_SIZE];
1886 size_t oid_size;
1888 for (i = 0;; i++)
1890 oid_size = sizeof (_oid);
1891 result =
1892 gnutls_x509_crq_get_extension_info (crq, i, _oid, &oid_size,
1893 critical);
1894 if (result < 0)
1896 gnutls_assert ();
1897 return result;
1900 if (strcmp (oid, _oid) == 0)
1901 { /* found */
1902 if (indx == 0)
1903 return gnutls_x509_crq_get_extension_data (crq, i, buf,
1904 sizeof_buf);
1905 else
1906 indx--;
1911 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1916 * gnutls_x509_crq_set_subject_alt_name:
1917 * @crq: a certificate request of type #gnutls_x509_crq_t
1918 * @nt: is one of the #gnutls_x509_subject_alt_name_t enumerations
1919 * @data: The data to be set
1920 * @data_size: The size of data to be set
1921 * @flags: %GNUTLS_FSAN_SET to clear previous data or
1922 * %GNUTLS_FSAN_APPEND to append.
1924 * This function will set the subject alternative name certificate
1925 * extension. It can set the following types:
1927 * %GNUTLS_SAN_DNSNAME: as a text string
1929 * %GNUTLS_SAN_RFC822NAME: as a text string
1931 * %GNUTLS_SAN_URI: as a text string
1933 * %GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
1935 * Other values can be set as binary values with the proper DER encoding.
1937 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1938 * negative error value.
1940 * Since: 2.8.0
1943 gnutls_x509_crq_set_subject_alt_name (gnutls_x509_crq_t crq,
1944 gnutls_x509_subject_alt_name_t nt,
1945 const void *data,
1946 unsigned int data_size,
1947 unsigned int flags)
1949 int result = 0;
1950 gnutls_datum_t der_data = { NULL, 0 };
1951 gnutls_datum_t prev_der_data = { NULL, 0 };
1952 unsigned int critical = 0;
1953 size_t prev_data_size = 0;
1955 if (crq == NULL)
1957 gnutls_assert ();
1958 return GNUTLS_E_INVALID_REQUEST;
1961 /* Check if the extension already exists.
1963 if (flags == GNUTLS_FSAN_APPEND)
1965 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1966 NULL, &prev_data_size,
1967 &critical);
1968 prev_der_data.size = prev_data_size;
1970 switch (result)
1972 case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
1973 /* Replacing non-existing data means the same as set data. */
1974 break;
1976 case GNUTLS_E_SUCCESS:
1977 prev_der_data.data = gnutls_malloc (prev_der_data.size);
1978 if (prev_der_data.data == NULL)
1980 gnutls_assert ();
1981 return GNUTLS_E_MEMORY_ERROR;
1984 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1985 prev_der_data.data,
1986 &prev_data_size,
1987 &critical);
1988 if (result < 0)
1990 gnutls_assert ();
1991 gnutls_free (prev_der_data.data);
1992 return result;
1994 break;
1996 default:
1997 gnutls_assert ();
1998 return result;
2002 /* generate the extension.
2004 result = _gnutls_x509_ext_gen_subject_alt_name (nt, data, data_size,
2005 &prev_der_data, &der_data);
2006 gnutls_free (prev_der_data.data);
2007 if (result < 0)
2009 gnutls_assert ();
2010 goto finish;
2013 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.17", &der_data,
2014 critical);
2016 _gnutls_free_datum (&der_data);
2018 if (result < 0)
2020 gnutls_assert ();
2021 return result;
2024 return 0;
2026 finish:
2027 return result;
2031 * gnutls_x509_crq_set_basic_constraints:
2032 * @crq: a certificate request of type #gnutls_x509_crq_t
2033 * @ca: true(1) or false(0) depending on the Certificate authority status.
2034 * @pathLenConstraint: non-negative error codes indicate maximum length of path,
2035 * and negative error codes indicate that the pathLenConstraints field should
2036 * not be present.
2038 * This function will set the basicConstraints certificate extension.
2040 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2041 * negative error value.
2043 * Since: 2.8.0
2046 gnutls_x509_crq_set_basic_constraints (gnutls_x509_crq_t crq,
2047 unsigned int ca, int pathLenConstraint)
2049 int result;
2050 gnutls_datum_t der_data;
2052 if (crq == NULL)
2054 gnutls_assert ();
2055 return GNUTLS_E_INVALID_REQUEST;
2058 /* generate the extension.
2060 result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint,
2061 &der_data);
2062 if (result < 0)
2064 gnutls_assert ();
2065 return result;
2068 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.19", &der_data, 1);
2070 _gnutls_free_datum (&der_data);
2072 if (result < 0)
2074 gnutls_assert ();
2075 return result;
2078 return 0;
2082 * gnutls_x509_crq_set_key_usage:
2083 * @crq: a certificate request of type #gnutls_x509_crq_t
2084 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
2086 * This function will set the keyUsage certificate extension.
2088 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2089 * negative error value.
2091 * Since: 2.8.0
2094 gnutls_x509_crq_set_key_usage (gnutls_x509_crq_t crq, unsigned int usage)
2096 int result;
2097 gnutls_datum_t der_data;
2099 if (crq == NULL)
2101 gnutls_assert ();
2102 return GNUTLS_E_INVALID_REQUEST;
2105 /* generate the extension.
2107 result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data);
2108 if (result < 0)
2110 gnutls_assert ();
2111 return result;
2114 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.15", &der_data, 1);
2116 _gnutls_free_datum (&der_data);
2118 if (result < 0)
2120 gnutls_assert ();
2121 return result;
2124 return 0;
2128 * gnutls_x509_crq_get_key_purpose_oid:
2129 * @crq: should contain a #gnutls_x509_crq_t structure
2130 * @indx: This specifies which OID to return, use (0) to get the first one
2131 * @oid: a pointer to a buffer to hold the OID (may be %NULL)
2132 * @sizeof_oid: initially holds the size of @oid
2133 * @critical: output variable with critical flag, may be %NULL.
2135 * This function will extract the key purpose OIDs of the Certificate
2136 * specified by the given index. These are stored in the Extended Key
2137 * Usage extension (2.5.29.37). See the GNUTLS_KP_* definitions for
2138 * human readable names.
2140 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2141 * not long enough, and in that case the *@sizeof_oid will be
2142 * updated with the required size. On success 0 is returned.
2144 * Since: 2.8.0
2147 gnutls_x509_crq_get_key_purpose_oid (gnutls_x509_crq_t crq,
2148 int indx, void *oid, size_t * sizeof_oid,
2149 unsigned int *critical)
2151 char tmpstr[ASN1_MAX_NAME_SIZE];
2152 int result, len;
2153 gnutls_datum_t prev = { NULL, 0 };
2154 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2155 size_t prev_size = 0;
2157 if (oid)
2158 memset (oid, 0, *sizeof_oid);
2159 else
2160 *sizeof_oid = 0;
2162 /* Extract extension.
2164 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2165 NULL, &prev_size, critical);
2166 prev.size = prev_size;
2168 if (result < 0)
2170 gnutls_assert ();
2171 return result;
2174 prev.data = gnutls_malloc (prev.size);
2175 if (prev.data == NULL)
2177 gnutls_assert ();
2178 return GNUTLS_E_MEMORY_ERROR;
2181 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2182 prev.data, &prev_size,
2183 critical);
2184 if (result < 0)
2186 gnutls_assert ();
2187 gnutls_free (prev.data);
2188 return result;
2191 result = asn1_create_element
2192 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
2193 if (result != ASN1_SUCCESS)
2195 gnutls_assert ();
2196 gnutls_free (prev.data);
2197 return _gnutls_asn2err (result);
2200 result = asn1_der_decoding (&c2, prev.data, prev.size, NULL);
2201 gnutls_free (prev.data);
2202 if (result != ASN1_SUCCESS)
2204 gnutls_assert ();
2205 asn1_delete_structure (&c2);
2206 return _gnutls_asn2err (result);
2209 indx++;
2210 /* create a string like "?1"
2212 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
2214 len = *sizeof_oid;
2215 result = asn1_read_value (c2, tmpstr, oid, &len);
2217 *sizeof_oid = len;
2218 asn1_delete_structure (&c2);
2220 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
2222 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2225 if (result != ASN1_SUCCESS)
2227 if (result != ASN1_MEM_ERROR)
2228 gnutls_assert ();
2229 return _gnutls_asn2err (result);
2232 return 0;
2236 * gnutls_x509_crq_set_key_purpose_oid:
2237 * @crq: a certificate of type #gnutls_x509_crq_t
2238 * @oid: a pointer to a (0)-terminated string that holds the OID
2239 * @critical: Whether this extension will be critical or not
2241 * This function will set the key purpose OIDs of the Certificate.
2242 * These are stored in the Extended Key Usage extension (2.5.29.37)
2243 * See the GNUTLS_KP_* definitions for human readable names.
2245 * Subsequent calls to this function will append OIDs to the OID list.
2247 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2248 * negative error value.
2250 * Since: 2.8.0
2253 gnutls_x509_crq_set_key_purpose_oid (gnutls_x509_crq_t crq,
2254 const void *oid, unsigned int critical)
2256 int result;
2257 gnutls_datum_t prev = { NULL, 0 }, der_data;
2258 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2259 size_t prev_size = 0;
2261 /* Read existing extension, if there is one.
2263 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2264 NULL, &prev_size, &critical);
2265 prev.size = prev_size;
2267 switch (result)
2269 case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
2270 /* No existing extension, that's fine. */
2271 break;
2273 case GNUTLS_E_SUCCESS:
2274 prev.data = gnutls_malloc (prev.size);
2275 if (prev.data == NULL)
2277 gnutls_assert ();
2278 return GNUTLS_E_MEMORY_ERROR;
2281 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2282 prev.data, &prev_size,
2283 &critical);
2284 if (result < 0)
2286 gnutls_assert ();
2287 gnutls_free (prev.data);
2288 return result;
2290 break;
2292 default:
2293 gnutls_assert ();
2294 return result;
2297 result = asn1_create_element (_gnutls_get_pkix (),
2298 "PKIX1.ExtKeyUsageSyntax", &c2);
2299 if (result != ASN1_SUCCESS)
2301 gnutls_assert ();
2302 gnutls_free (prev.data);
2303 return _gnutls_asn2err (result);
2306 if (prev.data)
2308 /* decode it.
2310 result = asn1_der_decoding (&c2, prev.data, prev.size, NULL);
2311 gnutls_free (prev.data);
2312 if (result != ASN1_SUCCESS)
2314 gnutls_assert ();
2315 asn1_delete_structure (&c2);
2316 return _gnutls_asn2err (result);
2320 /* generate the extension.
2322 /* 1. create a new element.
2324 result = asn1_write_value (c2, "", "NEW", 1);
2325 if (result != ASN1_SUCCESS)
2327 gnutls_assert ();
2328 asn1_delete_structure (&c2);
2329 return _gnutls_asn2err (result);
2332 /* 2. Add the OID.
2334 result = asn1_write_value (c2, "?LAST", oid, 1);
2335 if (result != ASN1_SUCCESS)
2337 gnutls_assert ();
2338 asn1_delete_structure (&c2);
2339 return _gnutls_asn2err (result);
2342 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
2343 asn1_delete_structure (&c2);
2345 if (result != ASN1_SUCCESS)
2347 gnutls_assert ();
2348 return _gnutls_asn2err (result);
2351 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.37",
2352 &der_data, critical);
2353 _gnutls_free_datum (&der_data);
2354 if (result < 0)
2356 gnutls_assert ();
2357 return result;
2360 return 0;
2364 * gnutls_x509_crq_get_key_id:
2365 * @crq: a certificate of type #gnutls_x509_crq_t
2366 * @flags: should be 0 for now
2367 * @output_data: will contain the key ID
2368 * @output_data_size: holds the size of output_data (and will be
2369 * replaced by the actual size of parameters)
2371 * This function will return a unique ID that depends on the public key
2372 * parameters. This ID can be used in checking whether a certificate
2373 * corresponds to the given private key.
2375 * If the buffer provided is not long enough to hold the output, then
2376 * *@output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2377 * be returned. The output will normally be a SHA-1 hash output,
2378 * which is 20 bytes.
2380 * Returns: In case of failure a negative error code will be
2381 * returned, and 0 on success.
2383 * Since: 2.8.0
2386 gnutls_x509_crq_get_key_id (gnutls_x509_crq_t crq, unsigned int flags,
2387 unsigned char *output_data,
2388 size_t * output_data_size)
2390 int pk, ret = 0;
2391 gnutls_pk_params_st params;
2393 if (crq == NULL)
2395 gnutls_assert ();
2396 return GNUTLS_E_INVALID_REQUEST;
2399 pk = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
2400 if (pk < 0)
2402 gnutls_assert ();
2403 return pk;
2406 ret = _gnutls_x509_crq_get_mpis (crq, &params);
2407 if (ret < 0)
2409 gnutls_assert ();
2410 return ret;
2413 ret = _gnutls_get_key_id(pk, &params, output_data, output_data_size);
2415 gnutls_pk_params_release(&params);
2417 return ret;
2421 * gnutls_x509_crq_privkey_sign:
2422 * @crq: should contain a #gnutls_x509_crq_t structure
2423 * @key: holds a private key
2424 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
2425 * @flags: must be 0
2427 * This function will sign the certificate request with a private key.
2428 * This must be the same key as the one used in
2429 * gnutls_x509_crt_set_key() since a certificate request is self
2430 * signed.
2432 * This must be the last step in a certificate request generation
2433 * since all the previously set parameters are now signed.
2435 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2436 * %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
2437 * information in the certificate request (e.g., the version using
2438 * gnutls_x509_crq_set_version()).
2440 * Since: 2.12.0
2443 gnutls_x509_crq_privkey_sign (gnutls_x509_crq_t crq, gnutls_privkey_t key,
2444 gnutls_digest_algorithm_t dig,
2445 unsigned int flags)
2447 int result;
2448 gnutls_datum_t signature;
2449 gnutls_datum_t tbs;
2451 if (crq == NULL)
2453 gnutls_assert ();
2454 return GNUTLS_E_INVALID_REQUEST;
2457 /* Make sure version field is set. */
2458 if (gnutls_x509_crq_get_version (crq) == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
2460 result = gnutls_x509_crq_set_version (crq, 1);
2461 if (result < 0)
2463 gnutls_assert ();
2464 return result;
2468 /* Step 1. Self sign the request.
2470 result = _gnutls_x509_get_tbs (crq->crq, "certificationRequestInfo", &tbs);
2472 if (result < 0)
2474 gnutls_assert ();
2475 return result;
2478 result = gnutls_privkey_sign_data (key, dig, 0, &tbs, &signature);
2479 gnutls_free (tbs.data);
2481 if (result < 0)
2483 gnutls_assert ();
2484 return result;
2487 /* Step 2. write the signature (bits)
2489 result =
2490 asn1_write_value (crq->crq, "signature", signature.data,
2491 signature.size * 8);
2493 _gnutls_free_datum (&signature);
2495 if (result != ASN1_SUCCESS)
2497 gnutls_assert ();
2498 return _gnutls_asn2err (result);
2501 /* Step 3. Write the signatureAlgorithm field.
2503 result = _gnutls_x509_write_sig_params (crq->crq, "signatureAlgorithm",
2504 gnutls_privkey_get_pk_algorithm
2505 (key, NULL), dig);
2506 if (result < 0)
2508 gnutls_assert ();
2509 return result;
2512 return 0;
2517 * gnutls_x509_crq_verify:
2518 * @crq: is the crq to be verified
2519 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
2521 * This function will verify self signature in the certificate
2522 * request and return its status.
2524 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2525 * is returned, and zero or positive code on success.
2527 * Since 2.12.0
2530 gnutls_x509_crq_verify (gnutls_x509_crq_t crq,
2531 unsigned int flags)
2533 gnutls_datum data = { NULL, 0 };
2534 gnutls_datum signature = { NULL, 0 };
2535 gnutls_pk_params_st params;
2536 gnutls_digest_algorithm_t algo;
2537 int ret;
2539 gnutls_pk_params_init(&params);
2541 ret =
2542 _gnutls_x509_get_signed_data (crq->crq, "certificationRequestInfo", &data);
2543 if (ret < 0)
2545 gnutls_assert ();
2546 return ret;
2549 ret = _gnutls_x509_get_signature_algorithm(crq->crq, "signatureAlgorithm.algorithm");
2550 if (ret < 0)
2552 gnutls_assert ();
2553 goto cleanup;
2556 algo = gnutls_sign_get_hash_algorithm(ret);
2558 ret = _gnutls_x509_get_signature (crq->crq, "signature", &signature);
2559 if (ret < 0)
2561 gnutls_assert ();
2562 goto cleanup;
2565 ret =
2566 _gnutls_x509_crq_get_mpis(crq, &params);
2567 if (ret < 0)
2569 gnutls_assert ();
2570 goto cleanup;
2573 ret = pubkey_verify_data(gnutls_x509_crq_get_pk_algorithm (crq, NULL), algo,
2574 &data, &signature, &params);
2575 if (ret < 0)
2577 gnutls_assert ();
2578 goto cleanup;
2581 ret = 0;
2583 cleanup:
2584 _gnutls_free_datum (&data);
2585 _gnutls_free_datum (&signature);
2586 gnutls_pk_params_release(&params);
2588 return ret;
2592 * gnutls_x509_crq_set_private_key_usage_period:
2593 * @crq: a certificate of type #gnutls_x509_crq_t
2594 * @activation: The activation time
2595 * @expiration: The expiration time
2597 * This function will set the private key usage period extension (2.5.29.16).
2599 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2600 * negative error value.
2603 gnutls_x509_crq_set_private_key_usage_period (gnutls_x509_crq_t crq,
2604 time_t activation,
2605 time_t expiration)
2607 int result;
2608 gnutls_datum_t der_data;
2609 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2611 if (crq == NULL)
2613 gnutls_assert ();
2614 return GNUTLS_E_INVALID_REQUEST;
2617 result =
2618 asn1_create_element (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2);
2619 if (result != ASN1_SUCCESS)
2621 gnutls_assert ();
2622 return _gnutls_asn2err (result);
2625 result = _gnutls_x509_set_time (c2,
2626 "notBefore",
2627 activation, 1);
2628 if (result < 0)
2630 gnutls_assert();
2631 goto cleanup;
2634 result = _gnutls_x509_set_time (c2,
2635 "notAfter",
2636 expiration, 1);
2637 if (result < 0)
2639 gnutls_assert();
2640 goto cleanup;
2643 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
2644 if (result < 0)
2646 gnutls_assert();
2647 goto cleanup;
2650 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.16",
2651 &der_data, 0);
2653 _gnutls_free_datum(&der_data);
2655 cleanup:
2656 asn1_delete_structure (&c2);
2658 return result;