corrected copyright notices
[gnutls.git] / lib / x509 / crq.c
blobe2af23913e077ab5d74ceaed2abfb978ba35a9b4
1 /*
2 * Copyright (C) 2003-2012 Free Software Foundation, Inc.
3 * Copyright (C) 2012 Nikos Mavrogiannopoulos
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 /* This file contains functions to handle PKCS #10 certificate
25 requests, see RFC 2986.
28 #include <gnutls_int.h>
30 #include <gnutls_datum.h>
31 #include <gnutls_global.h>
32 #include <gnutls_errors.h>
33 #include <common.h>
34 #include <gnutls_x509.h>
35 #include <x509_b64.h>
36 #include "x509_int.h"
37 #include <libtasn1.h>
39 /**
40 * gnutls_x509_crq_init:
41 * @crq: The structure to be initialized
43 * This function will initialize a PKCS#10 certificate request
44 * structure.
46 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
47 * negative error value.
48 **/
49 int
50 gnutls_x509_crq_init (gnutls_x509_crq_t * crq)
52 int result;
54 *crq = gnutls_calloc (1, sizeof (gnutls_x509_crq_int));
55 if (!*crq)
56 return GNUTLS_E_MEMORY_ERROR;
58 result = asn1_create_element (_gnutls_get_pkix (),
59 "PKIX1.pkcs-10-CertificationRequest",
60 &((*crq)->crq));
61 if (result != ASN1_SUCCESS)
63 gnutls_assert ();
64 gnutls_free (*crq);
65 return _gnutls_asn2err (result);
68 return 0;
71 /**
72 * gnutls_x509_crq_deinit:
73 * @crq: The structure to be initialized
75 * This function will deinitialize a PKCS#10 certificate request
76 * structure.
77 **/
78 void
79 gnutls_x509_crq_deinit (gnutls_x509_crq_t crq)
81 if (!crq)
82 return;
84 if (crq->crq)
85 asn1_delete_structure (&crq->crq);
87 gnutls_free (crq);
90 #define PEM_CRQ "NEW CERTIFICATE REQUEST"
91 #define PEM_CRQ2 "CERTIFICATE REQUEST"
93 /**
94 * gnutls_x509_crq_import:
95 * @crq: The structure to store the parsed certificate request.
96 * @data: The DER or PEM encoded certificate.
97 * @format: One of DER or PEM
99 * This function will convert the given DER or PEM encoded certificate
100 * request to a #gnutls_x509_crq_t structure. The output will be
101 * stored in @crq.
103 * If the Certificate is PEM encoded it should have a header of "NEW
104 * CERTIFICATE REQUEST".
106 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
107 * negative error value.
110 gnutls_x509_crq_import (gnutls_x509_crq_t crq,
111 const gnutls_datum_t * data,
112 gnutls_x509_crt_fmt_t format)
114 int result = 0, need_free = 0;
115 gnutls_datum_t _data;
117 if (crq == NULL)
119 gnutls_assert ();
120 return GNUTLS_E_INVALID_REQUEST;
123 _data.data = data->data;
124 _data.size = data->size;
126 /* If the Certificate is in PEM format then decode it
128 if (format == GNUTLS_X509_FMT_PEM)
130 /* Try the first header */
131 result = _gnutls_fbase64_decode (PEM_CRQ, data->data, data->size, &_data);
133 if (result < 0) /* Go for the second header */
134 result =
135 _gnutls_fbase64_decode (PEM_CRQ2, data->data, data->size, &_data);
137 if (result < 0)
139 gnutls_assert ();
140 return result;
143 need_free = 1;
146 result = asn1_der_decoding (&crq->crq, _data.data, _data.size, NULL);
147 if (result != ASN1_SUCCESS)
149 result = _gnutls_asn2err (result);
150 gnutls_assert ();
151 goto cleanup;
154 result = 0;
156 cleanup:
157 if (need_free)
158 _gnutls_free_datum (&_data);
159 return result;
163 * gnutls_x509_crq_get_private_key_usage_period:
164 * @cert: should contain a #gnutls_x509_crq_t structure
165 * @activation: The activation time
166 * @expiration: The expiration time
167 * @critical: the extension status
169 * This function will return the expiration and activation
170 * times of the private key of the certificate.
172 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
173 * if the extension is not present, otherwise a negative error value.
176 gnutls_x509_crq_get_private_key_usage_period (gnutls_x509_crq_t crq, time_t* activation, time_t* expiration,
177 unsigned int *critical)
179 int result, ret;
180 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
181 uint8_t buf[128];
182 size_t buf_size = sizeof (buf);
184 if (crq == NULL)
186 gnutls_assert ();
187 return GNUTLS_E_INVALID_REQUEST;
190 ret = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.16", 0,
191 buf, &buf_size, critical);
192 if (ret < 0)
193 return gnutls_assert_val(ret);
195 result = asn1_create_element
196 (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2);
197 if (result != ASN1_SUCCESS)
199 gnutls_assert ();
200 ret = _gnutls_asn2err (result);
201 goto cleanup;
204 result = asn1_der_decoding (&c2, buf, buf_size, NULL);
205 if (result != ASN1_SUCCESS)
207 gnutls_assert ();
208 ret = _gnutls_asn2err (result);
209 goto cleanup;
212 if (activation)
213 *activation = _gnutls_x509_get_time (c2,
214 "notBefore", 1);
216 if (expiration)
217 *expiration = _gnutls_x509_get_time (c2,
218 "notAfter", 1);
220 ret = 0;
222 cleanup:
223 asn1_delete_structure (&c2);
225 return ret;
230 * gnutls_x509_crq_get_dn:
231 * @crq: should contain a #gnutls_x509_crq_t structure
232 * @buf: a pointer to a structure to hold the name (may be %NULL)
233 * @sizeof_buf: initially holds the size of @buf
235 * This function will copy the name of the Certificate request subject
236 * to the provided buffer. The name will be in the form
237 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC 2253. The output string
238 * @buf will be ASCII or UTF-8 encoded, depending on the certificate
239 * data.
241 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
242 * long enough, and in that case the *@sizeof_buf will be updated with
243 * the required size. On success 0 is returned.
246 gnutls_x509_crq_get_dn (gnutls_x509_crq_t crq, char *buf, size_t * sizeof_buf)
248 if (crq == NULL)
250 gnutls_assert ();
251 return GNUTLS_E_INVALID_REQUEST;
254 return _gnutls_x509_parse_dn (crq->crq,
255 "certificationRequestInfo.subject.rdnSequence",
256 buf, sizeof_buf);
260 * gnutls_x509_crq_get_dn_by_oid:
261 * @crq: should contain a gnutls_x509_crq_t structure
262 * @oid: holds an Object Identifier in a null terminated string
263 * @indx: In case multiple same OIDs exist in the RDN, this specifies
264 * which to get. Use (0) to get the first one.
265 * @raw_flag: If non-zero returns the raw DER data of the DN part.
266 * @buf: a pointer to a structure to hold the name (may be %NULL)
267 * @sizeof_buf: initially holds the size of @buf
269 * This function will extract the part of the name of the Certificate
270 * request subject, specified by the given OID. The output will be
271 * encoded as described in RFC2253. The output string will be ASCII
272 * or UTF-8 encoded, depending on the certificate data.
274 * Some helper macros with popular OIDs can be found in gnutls/x509.h
275 * If raw flag is (0), this function will only return known OIDs as
276 * text. Other OIDs will be DER encoded, as described in RFC2253 --
277 * in hex format with a '\#' prefix. You can check about known OIDs
278 * using gnutls_x509_dn_oid_known().
280 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
281 * not long enough, and in that case the *@sizeof_buf will be
282 * updated with the required size. On success 0 is returned.
285 gnutls_x509_crq_get_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
286 int indx, unsigned int raw_flag,
287 void *buf, size_t * sizeof_buf)
289 gnutls_datum_t td;
290 int ret;
292 if (crq == NULL)
294 gnutls_assert ();
295 return GNUTLS_E_INVALID_REQUEST;
298 ret = _gnutls_x509_parse_dn_oid
299 (crq->crq,
300 "certificationRequestInfo.subject.rdnSequence",
301 oid, indx, raw_flag, &td);
302 if (ret < 0)
303 return gnutls_assert_val(ret);
305 return _gnutls_strdatum_to_buf (&td, buf, sizeof_buf);
309 * gnutls_x509_crq_get_dn_oid:
310 * @crq: should contain a gnutls_x509_crq_t structure
311 * @indx: Specifies which DN OID to get. Use (0) to get the first one.
312 * @oid: a pointer to a structure to hold the name (may be %NULL)
313 * @sizeof_oid: initially holds the size of @oid
315 * This function will extract the requested OID of the name of the
316 * certificate request subject, specified by the given index.
318 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
319 * not long enough, and in that case the *@sizeof_oid will be
320 * updated with the required size. On success 0 is returned.
323 gnutls_x509_crq_get_dn_oid (gnutls_x509_crq_t crq,
324 int indx, void *oid, size_t * sizeof_oid)
326 if (crq == NULL)
328 gnutls_assert ();
329 return GNUTLS_E_INVALID_REQUEST;
332 return _gnutls_x509_get_dn_oid (crq->crq,
333 "certificationRequestInfo.subject.rdnSequence",
334 indx, oid, sizeof_oid);
337 /* Parses an Attribute list in the asn1_struct, and searches for the
338 * given OID. The index indicates the attribute value to be returned.
340 * If raw==0 only printable data are returned, or
341 * GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE.
343 * asn1_attr_name must be a string in the form
344 * "certificationRequestInfo.attributes"
347 static int
348 parse_attribute (ASN1_TYPE asn1_struct,
349 const char *attr_name, const char *given_oid, int indx,
350 int raw, gnutls_datum_t * out)
352 int k1, result;
353 char tmpbuffer1[ASN1_MAX_NAME_SIZE];
354 char tmpbuffer3[ASN1_MAX_NAME_SIZE];
355 char value[200];
356 gnutls_datum_t td;
357 char oid[MAX_OID_SIZE];
358 int len;
360 k1 = 0;
364 k1++;
365 /* create a string like "attribute.?1"
367 if (attr_name[0] != 0)
368 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", attr_name, k1);
369 else
370 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
372 len = sizeof (value) - 1;
373 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
375 if (result == ASN1_ELEMENT_NOT_FOUND)
377 gnutls_assert ();
378 break;
381 if (result != ASN1_VALUE_NOT_FOUND)
383 gnutls_assert ();
384 result = _gnutls_asn2err (result);
385 goto cleanup;
388 /* Move to the attibute type and values
390 /* Read the OID
392 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer1);
393 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
395 len = sizeof (oid) - 1;
396 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
398 if (result == ASN1_ELEMENT_NOT_FOUND)
399 break;
400 else if (result != ASN1_SUCCESS)
402 gnutls_assert ();
403 result = _gnutls_asn2err (result);
404 goto cleanup;
407 if (strcmp (oid, given_oid) == 0)
408 { /* Found the OID */
410 /* Read the Value
412 snprintf (tmpbuffer3, sizeof (tmpbuffer3), "%s.values.?%u",
413 tmpbuffer1, indx + 1);
415 len = sizeof (value) - 1;
416 result = _gnutls_x509_read_value (asn1_struct, tmpbuffer3, &td);
418 if (result != ASN1_SUCCESS)
420 gnutls_assert ();
421 result = _gnutls_asn2err (result);
422 goto cleanup;
425 if (raw == 0)
427 result =
428 _gnutls_x509_dn_to_string
429 (oid, td.data, td.size, out);
431 _gnutls_free_datum(&td);
433 if (result < 0)
435 gnutls_assert ();
436 goto cleanup;
438 return 0;
440 else
441 { /* raw!=0 */
442 out->data = td.data;
443 out->size = td.size;
445 return 0;
450 while (1);
452 gnutls_assert ();
454 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
456 cleanup:
457 return result;
461 * gnutls_x509_crq_get_challenge_password:
462 * @crq: should contain a #gnutls_x509_crq_t structure
463 * @buf: will hold a (0)-terminated password string
464 * @sizeof_buf: Initially holds the size of @pass.
466 * This function will return the challenge password in the request.
467 * The challenge password is intended to be used for requesting a
468 * revocation of the certificate.
470 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
471 * negative error value.
474 gnutls_x509_crq_get_challenge_password (gnutls_x509_crq_t crq,
475 char *buf, size_t * sizeof_buf)
477 gnutls_datum_t td;
478 int ret;
480 if (crq == NULL)
482 gnutls_assert ();
483 return GNUTLS_E_INVALID_REQUEST;
486 ret = parse_attribute (crq->crq, "certificationRequestInfo.attributes",
487 "1.2.840.113549.1.9.7", 0, 0, &td);
488 if (ret < 0)
489 return gnutls_assert_val(ret);
491 return _gnutls_strdatum_to_buf (&td, buf, sizeof_buf);
494 /* This function will attempt to set the requested attribute in
495 * the given X509v3 certificate.
497 * Critical will be either 0 or 1.
499 static int
500 add_attribute (ASN1_TYPE asn, const char *root, const char *attribute_id,
501 const gnutls_datum_t * ext_data)
503 int result;
504 char name[ASN1_MAX_NAME_SIZE];
506 snprintf (name, sizeof (name), "%s", root);
508 /* Add a new attribute in the list.
510 result = asn1_write_value (asn, name, "NEW", 1);
511 if (result != ASN1_SUCCESS)
513 gnutls_assert ();
514 return _gnutls_asn2err (result);
517 snprintf (name, sizeof (name), "%s.?LAST.type", root);
519 result = asn1_write_value (asn, name, attribute_id, 1);
520 if (result != ASN1_SUCCESS)
522 gnutls_assert ();
523 return _gnutls_asn2err (result);
526 snprintf (name, sizeof (name), "%s.?LAST.values", root);
528 result = asn1_write_value (asn, name, "NEW", 1);
529 if (result != ASN1_SUCCESS)
531 gnutls_assert ();
532 return _gnutls_asn2err (result);
535 snprintf (name, sizeof (name), "%s.?LAST.values.?LAST", root);
537 result = _gnutls_x509_write_value (asn, name, ext_data);
538 if (result < 0)
540 gnutls_assert ();
541 return result;
544 return 0;
547 /* Overwrite the given attribute (using the index)
548 * index here starts from one.
550 static int
551 overwrite_attribute (ASN1_TYPE asn, const char *root, unsigned int indx,
552 const gnutls_datum_t * ext_data)
554 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
555 int result;
557 snprintf (name, sizeof (name), "%s.?%u", root, indx);
559 _gnutls_str_cpy (name2, sizeof (name2), name);
560 _gnutls_str_cat (name2, sizeof (name2), ".values.?LAST");
562 result = _gnutls_x509_write_value (asn, name2, ext_data);
563 if (result < 0)
565 gnutls_assert ();
566 return result;
570 return 0;
573 static int
574 set_attribute (ASN1_TYPE asn, const char *root,
575 const char *ext_id, const gnutls_datum_t * ext_data)
577 int result;
578 int k, len;
579 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
580 char extnID[MAX_OID_SIZE];
582 /* Find the index of the given attribute.
584 k = 0;
587 k++;
589 snprintf (name, sizeof (name), "%s.?%u", root, k);
591 len = sizeof (extnID) - 1;
592 result = asn1_read_value (asn, name, extnID, &len);
594 /* move to next
597 if (result == ASN1_ELEMENT_NOT_FOUND)
599 break;
605 _gnutls_str_cpy (name2, sizeof (name2), name);
606 _gnutls_str_cat (name2, sizeof (name2), ".type");
608 len = sizeof (extnID) - 1;
609 result = asn1_read_value (asn, name2, extnID, &len);
611 if (result == ASN1_ELEMENT_NOT_FOUND)
613 gnutls_assert ();
614 break;
616 else if (result != ASN1_SUCCESS)
618 gnutls_assert ();
619 return _gnutls_asn2err (result);
622 /* Handle Extension
624 if (strcmp (extnID, ext_id) == 0)
626 /* attribute was found
628 return overwrite_attribute (asn, root, k, ext_data);
633 while (0);
635 while (1);
637 if (result == ASN1_ELEMENT_NOT_FOUND)
639 return add_attribute (asn, root, ext_id, ext_data);
641 else
643 gnutls_assert ();
644 return _gnutls_asn2err (result);
648 return 0;
652 * gnutls_x509_crq_set_attribute_by_oid:
653 * @crq: should contain a #gnutls_x509_crq_t structure
654 * @oid: holds an Object Identifier in a null-terminated string
655 * @buf: a pointer to a structure that holds the attribute data
656 * @sizeof_buf: holds the size of @buf
658 * This function will set the attribute in the certificate request
659 * specified by the given Object ID. The provided attribute must be be DER
660 * encoded.
662 * Attributes in a certificate request is an optional set of data
663 * appended to the request. Their interpretation depends on the CA policy.
665 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
666 * negative error value.
669 gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq,
670 const char *oid, void *buf,
671 size_t sizeof_buf)
673 gnutls_datum_t data;
675 data.data = buf;
676 data.size = sizeof_buf;
678 if (crq == NULL)
680 gnutls_assert ();
681 return GNUTLS_E_INVALID_REQUEST;
684 return set_attribute (crq->crq, "certificationRequestInfo.attributes",
685 oid, &data);
689 * gnutls_x509_crq_get_attribute_by_oid:
690 * @crq: should contain a #gnutls_x509_crq_t structure
691 * @oid: holds an Object Identifier in null-terminated string
692 * @indx: In case multiple same OIDs exist in the attribute list, this
693 * specifies which to get, use (0) to get the first one
694 * @buf: a pointer to a structure to hold the attribute data (may be %NULL)
695 * @sizeof_buf: initially holds the size of @buf
697 * This function will return the attribute in the certificate request
698 * specified by the given Object ID. The attribute will be DER
699 * encoded.
701 * Attributes in a certificate request is an optional set of data
702 * appended to the request. Their interpretation depends on the CA policy.
704 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
705 * negative error value.
708 gnutls_x509_crq_get_attribute_by_oid (gnutls_x509_crq_t crq,
709 const char *oid, int indx, void *buf,
710 size_t * sizeof_buf)
712 int ret;
713 gnutls_datum_t td;
715 if (crq == NULL)
717 gnutls_assert ();
718 return GNUTLS_E_INVALID_REQUEST;
721 ret = parse_attribute (crq->crq, "certificationRequestInfo.attributes",
722 oid, indx, 1, &td);
723 if (ret < 0)
724 return gnutls_assert_val(ret);
726 return _gnutls_strdatum_to_buf (&td, buf, sizeof_buf);
730 * gnutls_x509_crq_set_dn_by_oid:
731 * @crq: should contain a #gnutls_x509_crq_t structure
732 * @oid: holds an Object Identifier in a (0)-terminated string
733 * @raw_flag: must be 0, or 1 if the data are DER encoded
734 * @data: a pointer to the input data
735 * @sizeof_data: holds the size of @data
737 * This function will set the part of the name of the Certificate
738 * request subject, specified by the given OID. The input string
739 * should be ASCII or UTF-8 encoded.
741 * Some helper macros with popular OIDs can be found in gnutls/x509.h
742 * With this function you can only set the known OIDs. You can test
743 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
744 * not known (by gnutls) you should properly DER encode your data, and
745 * call this function with raw_flag set.
747 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
748 * negative error value.
751 gnutls_x509_crq_set_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
752 unsigned int raw_flag, const void *data,
753 unsigned int sizeof_data)
755 if (sizeof_data == 0 || data == NULL || crq == NULL)
757 return GNUTLS_E_INVALID_REQUEST;
760 return _gnutls_x509_set_dn_oid (crq->crq,
761 "certificationRequestInfo.subject", oid,
762 raw_flag, data, sizeof_data);
766 * gnutls_x509_crq_set_version:
767 * @crq: should contain a #gnutls_x509_crq_t structure
768 * @version: holds the version number, for v1 Requests must be 1
770 * This function will set the version of the certificate request. For
771 * version 1 requests this must be one.
773 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
774 * negative error value.
777 gnutls_x509_crq_set_version (gnutls_x509_crq_t crq, unsigned int version)
779 int result;
780 unsigned char null = version;
782 if (crq == NULL)
784 gnutls_assert ();
785 return GNUTLS_E_INVALID_REQUEST;
788 if (null > 0)
789 null--;
791 result =
792 asn1_write_value (crq->crq, "certificationRequestInfo.version", &null, 1);
793 if (result != ASN1_SUCCESS)
795 gnutls_assert ();
796 return _gnutls_asn2err (result);
799 return 0;
803 * gnutls_x509_crq_get_version:
804 * @crq: should contain a #gnutls_x509_crq_t structure
806 * This function will return the version of the specified Certificate
807 * request.
809 * Returns: version of certificate request, or a negative error code on
810 * error.
813 gnutls_x509_crq_get_version (gnutls_x509_crq_t crq)
815 uint8_t version[8];
816 int len, result;
818 if (crq == NULL)
820 gnutls_assert ();
821 return GNUTLS_E_INVALID_REQUEST;
824 len = sizeof (version);
825 if ((result =
826 asn1_read_value (crq->crq, "certificationRequestInfo.version",
827 version, &len)) != ASN1_SUCCESS)
830 if (result == ASN1_ELEMENT_NOT_FOUND)
831 return 1; /* the DEFAULT version */
832 gnutls_assert ();
833 return _gnutls_asn2err (result);
836 return (int) version[0] + 1;
840 * gnutls_x509_crq_set_key:
841 * @crq: should contain a #gnutls_x509_crq_t structure
842 * @key: holds a private key
844 * This function will set the public parameters from the given private
845 * key to the request.
847 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
848 * negative error value.
851 gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
853 int result;
855 if (crq == NULL)
857 gnutls_assert ();
858 return GNUTLS_E_INVALID_REQUEST;
861 result = _gnutls_x509_encode_and_copy_PKI_params
862 (crq->crq,
863 "certificationRequestInfo.subjectPKInfo",
864 key->pk_algorithm, &key->params);
866 if (result < 0)
868 gnutls_assert ();
869 return result;
872 return 0;
876 * gnutls_x509_crq_get_key_rsa_raw:
877 * @crq: Holds the certificate
878 * @m: will hold the modulus
879 * @e: will hold the public exponent
881 * This function will export the RSA public key's parameters found in
882 * the given structure. The new parameters will be allocated using
883 * gnutls_malloc() and will be stored in the appropriate datum.
885 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
886 * negative error value.
888 * Since: 2.8.0
891 gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq,
892 gnutls_datum_t * m, gnutls_datum_t * e)
894 int ret;
895 gnutls_pk_params_st params;
897 gnutls_pk_params_init(&params);
899 if (crq == NULL)
901 gnutls_assert ();
902 return GNUTLS_E_INVALID_REQUEST;
905 ret = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
906 if (ret != GNUTLS_PK_RSA)
908 gnutls_assert ();
909 return GNUTLS_E_INVALID_REQUEST;
912 ret = _gnutls_x509_crq_get_mpis (crq, &params);
913 if (ret < 0)
915 gnutls_assert ();
916 return ret;
919 ret = _gnutls_mpi_dprint (params.params[0], m);
920 if (ret < 0)
922 gnutls_assert ();
923 goto cleanup;
926 ret = _gnutls_mpi_dprint (params.params[1], e);
927 if (ret < 0)
929 gnutls_assert ();
930 _gnutls_free_datum (m);
931 goto cleanup;
934 ret = 0;
936 cleanup:
937 gnutls_pk_params_release(&params);
938 return ret;
942 * gnutls_x509_crq_set_key_rsa_raw:
943 * @crq: should contain a #gnutls_x509_crq_t structure
944 * @m: holds the modulus
945 * @e: holds the public exponent
947 * This function will set the public parameters from the given private
948 * key to the request. Only RSA keys are currently supported.
950 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
951 * negative error value.
953 * Since: 2.6.0
956 gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq,
957 const gnutls_datum_t * m,
958 const gnutls_datum_t * e)
960 int result, ret;
961 size_t siz = 0;
962 gnutls_pk_params_st temp_params;
964 gnutls_pk_params_init(&temp_params);
966 if (crq == NULL)
968 gnutls_assert ();
969 return GNUTLS_E_INVALID_REQUEST;
972 memset (&temp_params, 0, sizeof (temp_params));
974 siz = m->size;
975 if (_gnutls_mpi_scan_nz (&temp_params.params[0], m->data, siz))
977 gnutls_assert ();
978 ret = GNUTLS_E_MPI_SCAN_FAILED;
979 goto error;
982 siz = e->size;
983 if (_gnutls_mpi_scan_nz (&temp_params.params[1], e->data, siz))
985 gnutls_assert ();
986 ret = GNUTLS_E_MPI_SCAN_FAILED;
987 goto error;
990 temp_params.params_nr = RSA_PUBLIC_PARAMS;
992 result = _gnutls_x509_encode_and_copy_PKI_params
993 (crq->crq,
994 "certificationRequestInfo.subjectPKInfo",
995 GNUTLS_PK_RSA, &temp_params);
997 if (result < 0)
999 gnutls_assert ();
1000 ret = result;
1001 goto error;
1004 ret = 0;
1006 error:
1007 gnutls_pk_params_release(&temp_params);
1008 return ret;
1012 * gnutls_x509_crq_set_challenge_password:
1013 * @crq: should contain a #gnutls_x509_crq_t structure
1014 * @pass: holds a (0)-terminated password
1016 * This function will set a challenge password to be used when
1017 * revoking the request.
1019 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1020 * negative error value.
1023 gnutls_x509_crq_set_challenge_password (gnutls_x509_crq_t crq,
1024 const char *pass)
1026 int result;
1028 if (crq == NULL)
1030 gnutls_assert ();
1031 return GNUTLS_E_INVALID_REQUEST;
1034 /* Add the attribute.
1036 result = asn1_write_value (crq->crq, "certificationRequestInfo.attributes",
1037 "NEW", 1);
1038 if (result != ASN1_SUCCESS)
1040 gnutls_assert ();
1041 return _gnutls_asn2err (result);
1044 result = _gnutls_x509_encode_and_write_attribute
1045 ("1.2.840.113549.1.9.7", crq->crq,
1046 "certificationRequestInfo.attributes.?LAST", pass, strlen (pass), 1);
1047 if (result < 0)
1049 gnutls_assert ();
1050 return result;
1053 return 0;
1057 * gnutls_x509_crq_sign2:
1058 * @crq: should contain a #gnutls_x509_crq_t structure
1059 * @key: holds a private key
1060 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
1061 * @flags: must be 0
1063 * This function will sign the certificate request with a private key.
1064 * This must be the same key as the one used in
1065 * gnutls_x509_crt_set_key() since a certificate request is self
1066 * signed.
1068 * This must be the last step in a certificate request generation
1069 * since all the previously set parameters are now signed.
1071 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1072 * %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
1073 * information in the certificate request (e.g., the version using
1074 * gnutls_x509_crq_set_version()).
1078 gnutls_x509_crq_sign2 (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key,
1079 gnutls_digest_algorithm_t dig, unsigned int flags)
1081 int result;
1082 gnutls_privkey_t privkey;
1084 if (crq == NULL)
1086 gnutls_assert ();
1087 return GNUTLS_E_INVALID_REQUEST;
1090 result = gnutls_privkey_init (&privkey);
1091 if (result < 0)
1093 gnutls_assert ();
1094 return result;
1097 result = gnutls_privkey_import_x509 (privkey, key, 0);
1098 if (result < 0)
1100 gnutls_assert ();
1101 goto fail;
1104 result = gnutls_x509_crq_privkey_sign (crq, privkey, dig, flags);
1105 if (result < 0)
1107 gnutls_assert ();
1108 goto fail;
1111 result = 0;
1113 fail:
1114 gnutls_privkey_deinit (privkey);
1116 return result;
1120 * gnutls_x509_crq_sign:
1121 * @crq: should contain a #gnutls_x509_crq_t structure
1122 * @key: holds a private key
1124 * This function is the same a gnutls_x509_crq_sign2() with no flags,
1125 * and SHA1 as the hash algorithm.
1127 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1128 * negative error value.
1130 * Deprecated: Use gnutls_x509_crq_privkey_sign() instead.
1133 gnutls_x509_crq_sign (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
1135 return gnutls_x509_crq_sign2 (crq, key, GNUTLS_DIG_SHA1, 0);
1139 * gnutls_x509_crq_export:
1140 * @crq: should contain a #gnutls_x509_crq_t structure
1141 * @format: the format of output params. One of PEM or DER.
1142 * @output_data: will contain a certificate request PEM or DER encoded
1143 * @output_data_size: holds the size of output_data (and will be
1144 * replaced by the actual size of parameters)
1146 * This function will export the certificate request to a PEM or DER
1147 * encoded PKCS10 structure.
1149 * If the buffer provided is not long enough to hold the output, then
1150 * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
1151 * *@output_data_size will be updated.
1153 * If the structure is PEM encoded, it will have a header of "BEGIN
1154 * NEW CERTIFICATE REQUEST".
1156 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1157 * negative error value.
1160 gnutls_x509_crq_export (gnutls_x509_crq_t crq,
1161 gnutls_x509_crt_fmt_t format, void *output_data,
1162 size_t * output_data_size)
1164 if (crq == NULL)
1166 gnutls_assert ();
1167 return GNUTLS_E_INVALID_REQUEST;
1170 return _gnutls_x509_export_int (crq->crq, format, PEM_CRQ,
1171 output_data, output_data_size);
1175 * gnutls_x509_crq_export2:
1176 * @crq: should contain a #gnutls_x509_crq_t structure
1177 * @format: the format of output params. One of PEM or DER.
1178 * @out: will contain a certificate request PEM or DER encoded
1180 * This function will export the certificate request to a PEM or DER
1181 * encoded PKCS10 structure.
1183 * The output buffer is allocated using gnutls_malloc().
1185 * If the structure is PEM encoded, it will have a header of "BEGIN
1186 * NEW CERTIFICATE REQUEST".
1188 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1189 * negative error value.
1191 * Since 3.1.3
1194 gnutls_x509_crq_export2 (gnutls_x509_crq_t crq,
1195 gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
1197 if (crq == NULL)
1199 gnutls_assert ();
1200 return GNUTLS_E_INVALID_REQUEST;
1203 return _gnutls_x509_export_int2 (crq->crq, format, PEM_CRQ, out);
1207 * gnutls_x509_crq_get_pk_algorithm:
1208 * @crq: should contain a #gnutls_x509_crq_t structure
1209 * @bits: if bits is non-%NULL it will hold the size of the parameters' in bits
1211 * This function will return the public key algorithm of a PKCS#10
1212 * certificate request.
1214 * If bits is non-%NULL, it should have enough size to hold the
1215 * parameters size in bits. For RSA the bits returned is the modulus.
1216 * For DSA the bits returned are of the public exponent.
1218 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1219 * success, or a negative error code on error.
1222 gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits)
1224 int result;
1226 if (crq == NULL)
1228 gnutls_assert ();
1229 return GNUTLS_E_INVALID_REQUEST;
1232 result = _gnutls_x509_get_pk_algorithm
1233 (crq->crq, "certificationRequestInfo.subjectPKInfo", bits);
1234 if (result < 0)
1236 gnutls_assert ();
1239 return result;
1243 * gnutls_x509_crq_get_attribute_info:
1244 * @crq: should contain a #gnutls_x509_crq_t structure
1245 * @indx: Specifies which attribute number to get. Use (0) to get the first one.
1246 * @oid: a pointer to a structure to hold the OID
1247 * @sizeof_oid: initially holds the maximum size of @oid, on return
1248 * holds actual size of @oid.
1250 * This function will return the requested attribute OID in the
1251 * certificate, and the critical flag for it. The attribute OID will
1252 * be stored as a string in the provided buffer. Use
1253 * gnutls_x509_crq_get_attribute_data() to extract the data.
1255 * If the buffer provided is not long enough to hold the output, then
1256 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1257 * returned.
1259 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1260 * negative error code in case of an error. If your have reached the
1261 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1262 * will be returned.
1264 * Since: 2.8.0
1267 gnutls_x509_crq_get_attribute_info (gnutls_x509_crq_t crq, int indx,
1268 void *oid, size_t * sizeof_oid)
1270 int result;
1271 char name[ASN1_MAX_NAME_SIZE];
1272 int len;
1274 if (!crq)
1276 gnutls_assert ();
1277 return GNUTLS_E_INVALID_REQUEST;
1280 snprintf (name, sizeof (name),
1281 "certificationRequestInfo.attributes.?%u.type", indx + 1);
1283 len = *sizeof_oid;
1284 result = asn1_read_value (crq->crq, name, oid, &len);
1285 *sizeof_oid = len;
1287 if (result == ASN1_ELEMENT_NOT_FOUND)
1288 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1289 else if (result < 0)
1291 gnutls_assert ();
1292 return _gnutls_asn2err (result);
1295 return 0;
1300 * gnutls_x509_crq_get_attribute_data:
1301 * @crq: should contain a #gnutls_x509_crq_t structure
1302 * @indx: Specifies which attribute number to get. Use (0) to get the first one.
1303 * @data: a pointer to a structure to hold the data (may be null)
1304 * @sizeof_data: initially holds the size of @oid
1306 * This function will return the requested attribute data in the
1307 * certificate request. The attribute data will be stored as a string in the
1308 * provided buffer.
1310 * Use gnutls_x509_crq_get_attribute_info() to extract the OID.
1311 * Use gnutls_x509_crq_get_attribute_by_oid() instead,
1312 * if you want to get data indexed by the attribute OID rather than
1313 * sequence.
1315 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1316 * negative error code in case of an error. If your have reached the
1317 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1318 * will be returned.
1320 * Since: 2.8.0
1323 gnutls_x509_crq_get_attribute_data (gnutls_x509_crq_t crq, int indx,
1324 void *data, size_t * sizeof_data)
1326 int result, len;
1327 char name[ASN1_MAX_NAME_SIZE];
1329 if (!crq)
1331 gnutls_assert ();
1332 return GNUTLS_E_INVALID_REQUEST;
1335 snprintf (name, sizeof (name),
1336 "certificationRequestInfo.attributes.?%u.values.?1", indx + 1);
1338 len = *sizeof_data;
1339 result = asn1_read_value (crq->crq, name, data, &len);
1340 *sizeof_data = len;
1342 if (result == ASN1_ELEMENT_NOT_FOUND)
1343 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1344 else if (result < 0)
1346 gnutls_assert ();
1347 return _gnutls_asn2err (result);
1350 return 0;
1354 * gnutls_x509_crq_get_extension_info:
1355 * @crq: should contain a #gnutls_x509_crq_t structure
1356 * @indx: Specifies which extension number to get. Use (0) to get the first one.
1357 * @oid: a pointer to a structure to hold the OID
1358 * @sizeof_oid: initially holds the maximum size of @oid, on return
1359 * holds actual size of @oid.
1360 * @critical: output variable with critical flag, may be NULL.
1362 * This function will return the requested extension OID in the
1363 * certificate, and the critical flag for it. The extension OID will
1364 * be stored as a string in the provided buffer. Use
1365 * gnutls_x509_crq_get_extension_data() to extract the data.
1367 * If the buffer provided is not long enough to hold the output, then
1368 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1369 * returned.
1371 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1372 * negative error code in case of an error. If your have reached the
1373 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1374 * will be returned.
1376 * Since: 2.8.0
1379 gnutls_x509_crq_get_extension_info (gnutls_x509_crq_t crq, int indx,
1380 void *oid, size_t * sizeof_oid,
1381 unsigned int *critical)
1383 int result;
1384 char str_critical[10];
1385 char name[ASN1_MAX_NAME_SIZE];
1386 char *extensions = NULL;
1387 size_t extensions_size = 0;
1388 ASN1_TYPE c2;
1389 int len;
1391 if (!crq)
1393 gnutls_assert ();
1394 return GNUTLS_E_INVALID_REQUEST;
1397 /* read extensionRequest */
1398 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1399 0, NULL, &extensions_size);
1400 if (result == GNUTLS_E_SHORT_MEMORY_BUFFER)
1402 extensions = gnutls_malloc (extensions_size);
1403 if (extensions == NULL)
1405 gnutls_assert ();
1406 return GNUTLS_E_MEMORY_ERROR;
1409 result = gnutls_x509_crq_get_attribute_by_oid (crq,
1410 "1.2.840.113549.1.9.14",
1411 0, extensions,
1412 &extensions_size);
1414 if (result < 0)
1416 gnutls_assert ();
1417 goto out;
1420 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
1421 if (result != ASN1_SUCCESS)
1423 gnutls_assert ();
1424 result = _gnutls_asn2err (result);
1425 goto out;
1428 result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
1429 if (result != ASN1_SUCCESS)
1431 gnutls_assert ();
1432 asn1_delete_structure (&c2);
1433 result = _gnutls_asn2err (result);
1434 goto out;
1437 snprintf (name, sizeof (name), "?%u.extnID", indx + 1);
1439 len = *sizeof_oid;
1440 result = asn1_read_value (c2, name, oid, &len);
1441 *sizeof_oid = len;
1443 if (result == ASN1_ELEMENT_NOT_FOUND)
1445 asn1_delete_structure (&c2);
1446 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1447 goto out;
1449 else if (result < 0)
1451 gnutls_assert ();
1452 asn1_delete_structure (&c2);
1453 result = _gnutls_asn2err (result);
1454 goto out;
1457 snprintf (name, sizeof (name), "?%u.critical", indx + 1);
1458 len = sizeof (str_critical);
1459 result = asn1_read_value (c2, name, str_critical, &len);
1461 asn1_delete_structure (&c2);
1463 if (result < 0)
1465 gnutls_assert ();
1466 result = _gnutls_asn2err (result);
1467 goto out;
1470 if (critical)
1472 if (str_critical[0] == 'T')
1473 *critical = 1;
1474 else
1475 *critical = 0;
1478 result = 0;
1480 out:
1481 gnutls_free (extensions);
1482 return result;
1486 * gnutls_x509_crq_get_extension_data:
1487 * @crq: should contain a #gnutls_x509_crq_t structure
1488 * @indx: Specifies which extension number to get. Use (0) to get the first one.
1489 * @data: a pointer to a structure to hold the data (may be null)
1490 * @sizeof_data: initially holds the size of @oid
1492 * This function will return the requested extension data in the
1493 * certificate. The extension data will be stored as a string in the
1494 * provided buffer.
1496 * Use gnutls_x509_crq_get_extension_info() to extract the OID and
1497 * critical flag. Use gnutls_x509_crq_get_extension_by_oid() instead,
1498 * if you want to get data indexed by the extension OID rather than
1499 * sequence.
1501 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1502 * negative error code in case of an error. If your have reached the
1503 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1504 * will be returned.
1506 * Since: 2.8.0
1509 gnutls_x509_crq_get_extension_data (gnutls_x509_crq_t crq, int indx,
1510 void *data, size_t * sizeof_data)
1512 int result, len;
1513 char name[ASN1_MAX_NAME_SIZE];
1514 unsigned char *extensions;
1515 size_t extensions_size = 0;
1516 ASN1_TYPE c2;
1518 if (!crq)
1520 gnutls_assert ();
1521 return GNUTLS_E_INVALID_REQUEST;
1524 /* read extensionRequest */
1525 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1526 0, NULL, &extensions_size);
1527 if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
1529 gnutls_assert ();
1530 if (result == 0)
1531 return GNUTLS_E_INTERNAL_ERROR;
1532 return result;
1535 extensions = gnutls_malloc (extensions_size);
1536 if (extensions == NULL)
1538 gnutls_assert ();
1539 return GNUTLS_E_MEMORY_ERROR;
1542 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1543 0, extensions,
1544 &extensions_size);
1545 if (result < 0)
1547 gnutls_assert ();
1548 return result;
1551 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
1552 if (result != ASN1_SUCCESS)
1554 gnutls_assert ();
1555 gnutls_free (extensions);
1556 return _gnutls_asn2err (result);
1559 result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
1560 gnutls_free (extensions);
1561 if (result != ASN1_SUCCESS)
1563 gnutls_assert ();
1564 asn1_delete_structure (&c2);
1565 return _gnutls_asn2err (result);
1568 snprintf (name, sizeof (name), "?%u.extnValue", indx + 1);
1570 len = *sizeof_data;
1571 result = asn1_read_value (c2, name, data, &len);
1572 *sizeof_data = len;
1574 asn1_delete_structure (&c2);
1576 if (result == ASN1_ELEMENT_NOT_FOUND)
1577 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1578 else if (result < 0)
1580 gnutls_assert ();
1581 return _gnutls_asn2err (result);
1584 return 0;
1588 * gnutls_x509_crq_get_key_usage:
1589 * @crq: should contain a #gnutls_x509_crq_t structure
1590 * @key_usage: where the key usage bits will be stored
1591 * @critical: will be non-zero if the extension is marked as critical
1593 * This function will return certificate's key usage, by reading the
1594 * keyUsage X.509 extension (2.5.29.15). The key usage value will
1595 * ORed values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1596 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1597 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1598 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1599 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1601 * Returns: the certificate key usage, or a negative error code in case of
1602 * parsing error. If the certificate does not contain the keyUsage
1603 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1604 * returned.
1606 * Since: 2.8.0
1609 gnutls_x509_crq_get_key_usage (gnutls_x509_crq_t crq,
1610 unsigned int *key_usage,
1611 unsigned int *critical)
1613 int result;
1614 uint16_t _usage;
1615 uint8_t buf[128];
1616 size_t buf_size = sizeof (buf);
1618 if (crq == NULL)
1620 gnutls_assert ();
1621 return GNUTLS_E_INVALID_REQUEST;
1624 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.15", 0,
1625 buf, &buf_size, critical);
1626 if (result < 0)
1628 gnutls_assert ();
1629 return result;
1632 result = _gnutls_x509_ext_extract_keyUsage (&_usage, buf, buf_size);
1634 *key_usage = _usage;
1636 if (result < 0)
1638 gnutls_assert ();
1639 return result;
1642 return 0;
1646 * gnutls_x509_crq_get_basic_constraints:
1647 * @crq: should contain a #gnutls_x509_crq_t structure
1648 * @critical: will be non-zero if the extension is marked as critical
1649 * @ca: pointer to output integer indicating CA status, may be NULL,
1650 * value is 1 if the certificate CA flag is set, 0 otherwise.
1651 * @pathlen: pointer to output integer indicating path length (may be
1652 * NULL), non-negative error codes indicate a present pathLenConstraint
1653 * field and the actual value, -1 indicate that the field is absent.
1655 * This function will read the certificate's basic constraints, and
1656 * return the certificates CA status. It reads the basicConstraints
1657 * X.509 extension (2.5.29.19).
1659 * Returns: If the certificate is a CA a positive value will be
1660 * returned, or (0) if the certificate does not have CA flag set.
1661 * A negative error code may be returned in case of errors. If the
1662 * certificate does not contain the basicConstraints extension
1663 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1665 * Since: 2.8.0
1668 gnutls_x509_crq_get_basic_constraints (gnutls_x509_crq_t crq,
1669 unsigned int *critical,
1670 unsigned int *ca, int *pathlen)
1672 int result;
1673 unsigned int tmp_ca;
1674 uint8_t buf[256];
1675 size_t buf_size = sizeof (buf);
1677 if (crq == NULL)
1679 gnutls_assert ();
1680 return GNUTLS_E_INVALID_REQUEST;
1683 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.19", 0,
1684 buf, &buf_size, critical);
1685 if (result < 0)
1687 gnutls_assert ();
1688 return result;
1691 result =
1692 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca,
1693 pathlen, buf, buf_size);
1694 if (ca)
1695 *ca = tmp_ca;
1697 if (result < 0)
1699 gnutls_assert ();
1700 return result;
1703 return tmp_ca;
1706 static int
1707 get_subject_alt_name (gnutls_x509_crq_t crq,
1708 unsigned int seq, void *ret,
1709 size_t * ret_size, unsigned int *ret_type,
1710 unsigned int *critical, int othername_oid)
1712 int result;
1713 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1714 gnutls_x509_subject_alt_name_t type;
1715 gnutls_datum_t dnsname = { NULL, 0 };
1716 size_t dns_size = 0;
1718 if (crq == NULL)
1720 gnutls_assert ();
1721 return GNUTLS_E_INVALID_REQUEST;
1724 if (ret)
1725 memset (ret, 0, *ret_size);
1726 else
1727 *ret_size = 0;
1729 /* Extract extension.
1731 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1732 NULL, &dns_size, critical);
1733 if (result < 0)
1735 gnutls_assert ();
1736 return result;
1739 dnsname.size = dns_size;
1740 dnsname.data = gnutls_malloc (dnsname.size);
1741 if (dnsname.data == NULL)
1743 gnutls_assert ();
1744 return GNUTLS_E_MEMORY_ERROR;
1747 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1748 dnsname.data, &dns_size,
1749 critical);
1750 if (result < 0)
1752 gnutls_assert ();
1753 gnutls_free (dnsname.data);
1754 return result;
1757 result = asn1_create_element
1758 (_gnutls_get_pkix (), "PKIX1.SubjectAltName", &c2);
1759 if (result != ASN1_SUCCESS)
1761 gnutls_assert ();
1762 gnutls_free (dnsname.data);
1763 return _gnutls_asn2err (result);
1766 result = asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
1767 gnutls_free (dnsname.data);
1768 if (result != ASN1_SUCCESS)
1770 gnutls_assert ();
1771 asn1_delete_structure (&c2);
1772 return _gnutls_asn2err (result);
1775 result = _gnutls_parse_general_name (c2, "", seq, ret, ret_size,
1776 ret_type, othername_oid);
1777 asn1_delete_structure (&c2);
1778 if (result < 0)
1780 return result;
1783 type = result;
1785 return type;
1789 * gnutls_x509_crq_get_subject_alt_name:
1790 * @crq: should contain a #gnutls_x509_crq_t structure
1791 * @seq: specifies the sequence number of the alt name, 0 for the
1792 * first one, 1 for the second etc.
1793 * @ret: is the place where the alternative name will be copied to
1794 * @ret_size: holds the size of ret.
1795 * @ret_type: holds the #gnutls_x509_subject_alt_name_t name type
1796 * @critical: will be non-zero if the extension is marked as critical
1797 * (may be null)
1799 * This function will return the alternative names, contained in the
1800 * given certificate. It is the same as
1801 * gnutls_x509_crq_get_subject_alt_name() except for the fact that it
1802 * will return the type of the alternative name in @ret_type even if
1803 * the function fails for some reason (i.e. the buffer provided is
1804 * not enough).
1806 * Returns: the alternative subject name type on success, one of the
1807 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1808 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1809 * hold the value. In that case @ret_size will be updated with the
1810 * required size. If the certificate request does not have an
1811 * Alternative name with the specified sequence number then
1812 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1814 * Since: 2.8.0
1817 gnutls_x509_crq_get_subject_alt_name (gnutls_x509_crq_t crq,
1818 unsigned int seq, void *ret,
1819 size_t * ret_size,
1820 unsigned int *ret_type,
1821 unsigned int *critical)
1823 return get_subject_alt_name (crq, seq, ret, ret_size, ret_type, critical,
1828 * gnutls_x509_crq_get_subject_alt_othername_oid:
1829 * @crq: should contain a #gnutls_x509_crq_t structure
1830 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1831 * @ret: is the place where the otherName OID will be copied to
1832 * @ret_size: holds the size of ret.
1834 * This function will extract the type OID of an otherName Subject
1835 * Alternative Name, contained in the given certificate, and return
1836 * the type as an enumerated element.
1838 * This function is only useful if
1839 * gnutls_x509_crq_get_subject_alt_name() returned
1840 * %GNUTLS_SAN_OTHERNAME.
1842 * Returns: the alternative subject name type on success, one of the
1843 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs,
1844 * it will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1845 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1846 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1847 * @ret_size is not large enough to hold the value. In that case
1848 * @ret_size will be updated with the required size. If the
1849 * certificate does not have an Alternative name with the specified
1850 * sequence number and with the otherName type then
1851 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1853 * Since: 2.8.0
1856 gnutls_x509_crq_get_subject_alt_othername_oid (gnutls_x509_crq_t crq,
1857 unsigned int seq,
1858 void *ret, size_t * ret_size)
1860 return get_subject_alt_name (crq, seq, ret, ret_size, NULL, NULL, 1);
1864 * gnutls_x509_crq_get_extension_by_oid:
1865 * @crq: should contain a #gnutls_x509_crq_t structure
1866 * @oid: holds an Object Identifier in a null terminated string
1867 * @indx: In case multiple same OIDs exist in the extensions, this
1868 * specifies which to get. Use (0) to get the first one.
1869 * @buf: a pointer to a structure to hold the name (may be null)
1870 * @sizeof_buf: initially holds the size of @buf
1871 * @critical: will be non-zero if the extension is marked as critical
1873 * This function will return the extension specified by the OID in
1874 * the certificate. The extensions will be returned as binary data
1875 * DER encoded, in the provided buffer.
1877 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1878 * negative error code in case of an error. If the certificate does not
1879 * contain the specified extension
1880 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1882 * Since: 2.8.0
1885 gnutls_x509_crq_get_extension_by_oid (gnutls_x509_crq_t crq,
1886 const char *oid, int indx,
1887 void *buf, size_t * sizeof_buf,
1888 unsigned int *critical)
1890 int result;
1891 unsigned int i;
1892 char _oid[MAX_OID_SIZE];
1893 size_t oid_size;
1895 for (i = 0;; i++)
1897 oid_size = sizeof (_oid);
1898 result =
1899 gnutls_x509_crq_get_extension_info (crq, i, _oid, &oid_size,
1900 critical);
1901 if (result < 0)
1903 gnutls_assert ();
1904 return result;
1907 if (strcmp (oid, _oid) == 0)
1908 { /* found */
1909 if (indx == 0)
1910 return gnutls_x509_crq_get_extension_data (crq, i, buf,
1911 sizeof_buf);
1912 else
1913 indx--;
1918 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1923 * gnutls_x509_crq_set_subject_alt_name:
1924 * @crq: a certificate request of type #gnutls_x509_crq_t
1925 * @nt: is one of the #gnutls_x509_subject_alt_name_t enumerations
1926 * @data: The data to be set
1927 * @data_size: The size of data to be set
1928 * @flags: %GNUTLS_FSAN_SET to clear previous data or
1929 * %GNUTLS_FSAN_APPEND to append.
1931 * This function will set the subject alternative name certificate
1932 * extension. It can set the following types:
1934 * %GNUTLS_SAN_DNSNAME: as a text string
1936 * %GNUTLS_SAN_RFC822NAME: as a text string
1938 * %GNUTLS_SAN_URI: as a text string
1940 * %GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
1942 * Other values can be set as binary values with the proper DER encoding.
1944 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1945 * negative error value.
1947 * Since: 2.8.0
1950 gnutls_x509_crq_set_subject_alt_name (gnutls_x509_crq_t crq,
1951 gnutls_x509_subject_alt_name_t nt,
1952 const void *data,
1953 unsigned int data_size,
1954 unsigned int flags)
1956 int result = 0;
1957 gnutls_datum_t der_data = { NULL, 0 };
1958 gnutls_datum_t prev_der_data = { NULL, 0 };
1959 unsigned int critical = 0;
1960 size_t prev_data_size = 0;
1962 if (crq == NULL)
1964 gnutls_assert ();
1965 return GNUTLS_E_INVALID_REQUEST;
1968 /* Check if the extension already exists.
1970 if (flags == GNUTLS_FSAN_APPEND)
1972 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1973 NULL, &prev_data_size,
1974 &critical);
1975 prev_der_data.size = prev_data_size;
1977 switch (result)
1979 case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
1980 /* Replacing non-existing data means the same as set data. */
1981 break;
1983 case GNUTLS_E_SUCCESS:
1984 prev_der_data.data = gnutls_malloc (prev_der_data.size);
1985 if (prev_der_data.data == NULL)
1987 gnutls_assert ();
1988 return GNUTLS_E_MEMORY_ERROR;
1991 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1992 prev_der_data.data,
1993 &prev_data_size,
1994 &critical);
1995 if (result < 0)
1997 gnutls_assert ();
1998 gnutls_free (prev_der_data.data);
1999 return result;
2001 break;
2003 default:
2004 gnutls_assert ();
2005 return result;
2009 /* generate the extension.
2011 result = _gnutls_x509_ext_gen_subject_alt_name (nt, data, data_size,
2012 &prev_der_data, &der_data);
2013 gnutls_free (prev_der_data.data);
2014 if (result < 0)
2016 gnutls_assert ();
2017 goto finish;
2020 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.17", &der_data,
2021 critical);
2023 _gnutls_free_datum (&der_data);
2025 if (result < 0)
2027 gnutls_assert ();
2028 return result;
2031 return 0;
2033 finish:
2034 return result;
2038 * gnutls_x509_crq_set_basic_constraints:
2039 * @crq: a certificate request of type #gnutls_x509_crq_t
2040 * @ca: true(1) or false(0) depending on the Certificate authority status.
2041 * @pathLenConstraint: non-negative error codes indicate maximum length of path,
2042 * and negative error codes indicate that the pathLenConstraints field should
2043 * not be present.
2045 * This function will set the basicConstraints certificate extension.
2047 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2048 * negative error value.
2050 * Since: 2.8.0
2053 gnutls_x509_crq_set_basic_constraints (gnutls_x509_crq_t crq,
2054 unsigned int ca, int pathLenConstraint)
2056 int result;
2057 gnutls_datum_t der_data;
2059 if (crq == NULL)
2061 gnutls_assert ();
2062 return GNUTLS_E_INVALID_REQUEST;
2065 /* generate the extension.
2067 result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint,
2068 &der_data);
2069 if (result < 0)
2071 gnutls_assert ();
2072 return result;
2075 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.19", &der_data, 1);
2077 _gnutls_free_datum (&der_data);
2079 if (result < 0)
2081 gnutls_assert ();
2082 return result;
2085 return 0;
2089 * gnutls_x509_crq_set_key_usage:
2090 * @crq: a certificate request of type #gnutls_x509_crq_t
2091 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
2093 * This function will set the keyUsage certificate extension.
2095 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2096 * negative error value.
2098 * Since: 2.8.0
2101 gnutls_x509_crq_set_key_usage (gnutls_x509_crq_t crq, unsigned int usage)
2103 int result;
2104 gnutls_datum_t der_data;
2106 if (crq == NULL)
2108 gnutls_assert ();
2109 return GNUTLS_E_INVALID_REQUEST;
2112 /* generate the extension.
2114 result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data);
2115 if (result < 0)
2117 gnutls_assert ();
2118 return result;
2121 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.15", &der_data, 1);
2123 _gnutls_free_datum (&der_data);
2125 if (result < 0)
2127 gnutls_assert ();
2128 return result;
2131 return 0;
2135 * gnutls_x509_crq_get_key_purpose_oid:
2136 * @crq: should contain a #gnutls_x509_crq_t structure
2137 * @indx: This specifies which OID to return, use (0) to get the first one
2138 * @oid: a pointer to a buffer to hold the OID (may be %NULL)
2139 * @sizeof_oid: initially holds the size of @oid
2140 * @critical: output variable with critical flag, may be %NULL.
2142 * This function will extract the key purpose OIDs of the Certificate
2143 * specified by the given index. These are stored in the Extended Key
2144 * Usage extension (2.5.29.37). See the GNUTLS_KP_* definitions for
2145 * human readable names.
2147 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2148 * not long enough, and in that case the *@sizeof_oid will be
2149 * updated with the required size. On success 0 is returned.
2151 * Since: 2.8.0
2154 gnutls_x509_crq_get_key_purpose_oid (gnutls_x509_crq_t crq,
2155 int indx, void *oid, size_t * sizeof_oid,
2156 unsigned int *critical)
2158 char tmpstr[ASN1_MAX_NAME_SIZE];
2159 int result, len;
2160 gnutls_datum_t prev = { NULL, 0 };
2161 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2162 size_t prev_size = 0;
2164 if (oid)
2165 memset (oid, 0, *sizeof_oid);
2166 else
2167 *sizeof_oid = 0;
2169 /* Extract extension.
2171 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2172 NULL, &prev_size, critical);
2173 prev.size = prev_size;
2175 if (result < 0)
2177 gnutls_assert ();
2178 return result;
2181 prev.data = gnutls_malloc (prev.size);
2182 if (prev.data == NULL)
2184 gnutls_assert ();
2185 return GNUTLS_E_MEMORY_ERROR;
2188 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2189 prev.data, &prev_size,
2190 critical);
2191 if (result < 0)
2193 gnutls_assert ();
2194 gnutls_free (prev.data);
2195 return result;
2198 result = asn1_create_element
2199 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
2200 if (result != ASN1_SUCCESS)
2202 gnutls_assert ();
2203 gnutls_free (prev.data);
2204 return _gnutls_asn2err (result);
2207 result = asn1_der_decoding (&c2, prev.data, prev.size, NULL);
2208 gnutls_free (prev.data);
2209 if (result != ASN1_SUCCESS)
2211 gnutls_assert ();
2212 asn1_delete_structure (&c2);
2213 return _gnutls_asn2err (result);
2216 indx++;
2217 /* create a string like "?1"
2219 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
2221 len = *sizeof_oid;
2222 result = asn1_read_value (c2, tmpstr, oid, &len);
2224 *sizeof_oid = len;
2225 asn1_delete_structure (&c2);
2227 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
2229 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2232 if (result != ASN1_SUCCESS)
2234 if (result != ASN1_MEM_ERROR)
2235 gnutls_assert ();
2236 return _gnutls_asn2err (result);
2239 return 0;
2243 * gnutls_x509_crq_set_key_purpose_oid:
2244 * @crq: a certificate of type #gnutls_x509_crq_t
2245 * @oid: a pointer to a (0)-terminated string that holds the OID
2246 * @critical: Whether this extension will be critical or not
2248 * This function will set the key purpose OIDs of the Certificate.
2249 * These are stored in the Extended Key Usage extension (2.5.29.37)
2250 * See the GNUTLS_KP_* definitions for human readable names.
2252 * Subsequent calls to this function will append OIDs to the OID list.
2254 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2255 * negative error value.
2257 * Since: 2.8.0
2260 gnutls_x509_crq_set_key_purpose_oid (gnutls_x509_crq_t crq,
2261 const void *oid, unsigned int critical)
2263 int result;
2264 gnutls_datum_t prev = { NULL, 0 }, der_data;
2265 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2266 size_t prev_size = 0;
2268 /* Read existing extension, if there is one.
2270 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2271 NULL, &prev_size, &critical);
2272 prev.size = prev_size;
2274 switch (result)
2276 case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
2277 /* No existing extension, that's fine. */
2278 break;
2280 case GNUTLS_E_SUCCESS:
2281 prev.data = gnutls_malloc (prev.size);
2282 if (prev.data == NULL)
2284 gnutls_assert ();
2285 return GNUTLS_E_MEMORY_ERROR;
2288 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2289 prev.data, &prev_size,
2290 &critical);
2291 if (result < 0)
2293 gnutls_assert ();
2294 gnutls_free (prev.data);
2295 return result;
2297 break;
2299 default:
2300 gnutls_assert ();
2301 return result;
2304 result = asn1_create_element (_gnutls_get_pkix (),
2305 "PKIX1.ExtKeyUsageSyntax", &c2);
2306 if (result != ASN1_SUCCESS)
2308 gnutls_assert ();
2309 gnutls_free (prev.data);
2310 return _gnutls_asn2err (result);
2313 if (prev.data)
2315 /* decode it.
2317 result = asn1_der_decoding (&c2, prev.data, prev.size, NULL);
2318 gnutls_free (prev.data);
2319 if (result != ASN1_SUCCESS)
2321 gnutls_assert ();
2322 asn1_delete_structure (&c2);
2323 return _gnutls_asn2err (result);
2327 /* generate the extension.
2329 /* 1. create a new element.
2331 result = asn1_write_value (c2, "", "NEW", 1);
2332 if (result != ASN1_SUCCESS)
2334 gnutls_assert ();
2335 asn1_delete_structure (&c2);
2336 return _gnutls_asn2err (result);
2339 /* 2. Add the OID.
2341 result = asn1_write_value (c2, "?LAST", oid, 1);
2342 if (result != ASN1_SUCCESS)
2344 gnutls_assert ();
2345 asn1_delete_structure (&c2);
2346 return _gnutls_asn2err (result);
2349 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
2350 asn1_delete_structure (&c2);
2352 if (result != ASN1_SUCCESS)
2354 gnutls_assert ();
2355 return _gnutls_asn2err (result);
2358 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.37",
2359 &der_data, critical);
2360 _gnutls_free_datum (&der_data);
2361 if (result < 0)
2363 gnutls_assert ();
2364 return result;
2367 return 0;
2371 * gnutls_x509_crq_get_key_id:
2372 * @crq: a certificate of type #gnutls_x509_crq_t
2373 * @flags: should be 0 for now
2374 * @output_data: will contain the key ID
2375 * @output_data_size: holds the size of output_data (and will be
2376 * replaced by the actual size of parameters)
2378 * This function will return a unique ID that depends on the public key
2379 * parameters. This ID can be used in checking whether a certificate
2380 * corresponds to the given private key.
2382 * If the buffer provided is not long enough to hold the output, then
2383 * *@output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2384 * be returned. The output will normally be a SHA-1 hash output,
2385 * which is 20 bytes.
2387 * Returns: In case of failure a negative error code will be
2388 * returned, and 0 on success.
2390 * Since: 2.8.0
2393 gnutls_x509_crq_get_key_id (gnutls_x509_crq_t crq, unsigned int flags,
2394 unsigned char *output_data,
2395 size_t * output_data_size)
2397 int pk, ret = 0;
2398 gnutls_pk_params_st params;
2400 if (crq == NULL)
2402 gnutls_assert ();
2403 return GNUTLS_E_INVALID_REQUEST;
2406 pk = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
2407 if (pk < 0)
2409 gnutls_assert ();
2410 return pk;
2413 ret = _gnutls_x509_crq_get_mpis (crq, &params);
2414 if (ret < 0)
2416 gnutls_assert ();
2417 return ret;
2420 ret = _gnutls_get_key_id(pk, &params, output_data, output_data_size);
2422 gnutls_pk_params_release(&params);
2424 return ret;
2428 * gnutls_x509_crq_privkey_sign:
2429 * @crq: should contain a #gnutls_x509_crq_t structure
2430 * @key: holds a private key
2431 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
2432 * @flags: must be 0
2434 * This function will sign the certificate request with a private key.
2435 * This must be the same key as the one used in
2436 * gnutls_x509_crt_set_key() since a certificate request is self
2437 * signed.
2439 * This must be the last step in a certificate request generation
2440 * since all the previously set parameters are now signed.
2442 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2443 * %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
2444 * information in the certificate request (e.g., the version using
2445 * gnutls_x509_crq_set_version()).
2447 * Since: 2.12.0
2450 gnutls_x509_crq_privkey_sign (gnutls_x509_crq_t crq, gnutls_privkey_t key,
2451 gnutls_digest_algorithm_t dig,
2452 unsigned int flags)
2454 int result;
2455 gnutls_datum_t signature;
2456 gnutls_datum_t tbs;
2458 if (crq == NULL)
2460 gnutls_assert ();
2461 return GNUTLS_E_INVALID_REQUEST;
2464 /* Make sure version field is set. */
2465 if (gnutls_x509_crq_get_version (crq) == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
2467 result = gnutls_x509_crq_set_version (crq, 1);
2468 if (result < 0)
2470 gnutls_assert ();
2471 return result;
2475 /* Step 1. Self sign the request.
2477 result = _gnutls_x509_get_tbs (crq->crq, "certificationRequestInfo", &tbs);
2479 if (result < 0)
2481 gnutls_assert ();
2482 return result;
2485 result = gnutls_privkey_sign_data (key, dig, 0, &tbs, &signature);
2486 gnutls_free (tbs.data);
2488 if (result < 0)
2490 gnutls_assert ();
2491 return result;
2494 /* Step 2. write the signature (bits)
2496 result =
2497 asn1_write_value (crq->crq, "signature", signature.data,
2498 signature.size * 8);
2500 _gnutls_free_datum (&signature);
2502 if (result != ASN1_SUCCESS)
2504 gnutls_assert ();
2505 return _gnutls_asn2err (result);
2508 /* Step 3. Write the signatureAlgorithm field.
2510 result = _gnutls_x509_write_sig_params (crq->crq, "signatureAlgorithm",
2511 gnutls_privkey_get_pk_algorithm
2512 (key, NULL), dig);
2513 if (result < 0)
2515 gnutls_assert ();
2516 return result;
2519 return 0;
2524 * gnutls_x509_crq_verify:
2525 * @crq: is the crq to be verified
2526 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
2528 * This function will verify self signature in the certificate
2529 * request and return its status.
2531 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2532 * is returned, and zero or positive code on success.
2534 * Since 2.12.0
2537 gnutls_x509_crq_verify (gnutls_x509_crq_t crq,
2538 unsigned int flags)
2540 gnutls_datum data = { NULL, 0 };
2541 gnutls_datum signature = { NULL, 0 };
2542 gnutls_pk_params_st params;
2543 gnutls_digest_algorithm_t algo;
2544 int ret;
2546 gnutls_pk_params_init(&params);
2548 ret =
2549 _gnutls_x509_get_signed_data (crq->crq, "certificationRequestInfo", &data);
2550 if (ret < 0)
2552 gnutls_assert ();
2553 return ret;
2556 ret = _gnutls_x509_get_signature_algorithm(crq->crq, "signatureAlgorithm.algorithm");
2557 if (ret < 0)
2559 gnutls_assert ();
2560 goto cleanup;
2563 algo = gnutls_sign_get_hash_algorithm(ret);
2565 ret = _gnutls_x509_get_signature (crq->crq, "signature", &signature);
2566 if (ret < 0)
2568 gnutls_assert ();
2569 goto cleanup;
2572 ret =
2573 _gnutls_x509_crq_get_mpis(crq, &params);
2574 if (ret < 0)
2576 gnutls_assert ();
2577 goto cleanup;
2580 ret = pubkey_verify_data(gnutls_x509_crq_get_pk_algorithm (crq, NULL), algo,
2581 &data, &signature, &params);
2582 if (ret < 0)
2584 gnutls_assert ();
2585 goto cleanup;
2588 ret = 0;
2590 cleanup:
2591 _gnutls_free_datum (&data);
2592 _gnutls_free_datum (&signature);
2593 gnutls_pk_params_release(&params);
2595 return ret;
2599 * gnutls_x509_crq_set_private_key_usage_period:
2600 * @crq: a certificate of type #gnutls_x509_crq_t
2601 * @activation: The activation time
2602 * @expiration: The expiration time
2604 * This function will set the private key usage period extension (2.5.29.16).
2606 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2607 * negative error value.
2610 gnutls_x509_crq_set_private_key_usage_period (gnutls_x509_crq_t crq,
2611 time_t activation,
2612 time_t expiration)
2614 int result;
2615 gnutls_datum_t der_data;
2616 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2618 if (crq == NULL)
2620 gnutls_assert ();
2621 return GNUTLS_E_INVALID_REQUEST;
2624 result =
2625 asn1_create_element (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2);
2626 if (result != ASN1_SUCCESS)
2628 gnutls_assert ();
2629 return _gnutls_asn2err (result);
2632 result = _gnutls_x509_set_time (c2,
2633 "notBefore",
2634 activation, 1);
2635 if (result < 0)
2637 gnutls_assert();
2638 goto cleanup;
2641 result = _gnutls_x509_set_time (c2,
2642 "notAfter",
2643 expiration, 1);
2644 if (result < 0)
2646 gnutls_assert();
2647 goto cleanup;
2650 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
2651 if (result < 0)
2653 gnutls_assert();
2654 goto cleanup;
2657 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.16",
2658 &der_data, 0);
2660 _gnutls_free_datum(&der_data);
2662 cleanup:
2663 asn1_delete_structure (&c2);
2665 return result;