simplified base64 encoding/decoding functions by using a datum.
[gnutls.git] / lib / x509 / crq.c
blob956229ba97ef7cb9b47afedd714363031c04ba56
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 (0) 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 if (crq == NULL)
290 gnutls_assert ();
291 return GNUTLS_E_INVALID_REQUEST;
294 return _gnutls_x509_parse_dn_oid
295 (crq->crq,
296 "certificationRequestInfo.subject.rdnSequence",
297 oid, indx, raw_flag, buf, sizeof_buf);
301 * gnutls_x509_crq_get_dn_oid:
302 * @crq: should contain a gnutls_x509_crq_t structure
303 * @indx: Specifies which DN OID to send. Use (0) to get the first one.
304 * @oid: a pointer to a structure to hold the name (may be %NULL)
305 * @sizeof_oid: initially holds the size of @oid
307 * This function will extract the requested OID of the name of the
308 * certificate request subject, specified by the given index.
310 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
311 * not long enough, and in that case the *@sizeof_oid will be
312 * updated with the required size. On success 0 is returned.
315 gnutls_x509_crq_get_dn_oid (gnutls_x509_crq_t crq,
316 int indx, void *oid, size_t * sizeof_oid)
318 if (crq == NULL)
320 gnutls_assert ();
321 return GNUTLS_E_INVALID_REQUEST;
324 return _gnutls_x509_get_dn_oid (crq->crq,
325 "certificationRequestInfo.subject.rdnSequence",
326 indx, oid, sizeof_oid);
329 /* Parses an Attribute list in the asn1_struct, and searches for the
330 * given OID. The index indicates the attribute value to be returned.
332 * If raw==0 only printable data are returned, or
333 * GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE.
335 * asn1_attr_name must be a string in the form
336 * "certificationRequestInfo.attributes"
339 static int
340 parse_attribute (ASN1_TYPE asn1_struct,
341 const char *attr_name, const char *given_oid, int indx,
342 int raw, char *buf, size_t * sizeof_buf)
344 int k1, result;
345 char tmpbuffer1[ASN1_MAX_NAME_SIZE];
346 char tmpbuffer3[ASN1_MAX_NAME_SIZE];
347 char value[200];
348 char oid[MAX_OID_SIZE];
349 int len, printable;
351 k1 = 0;
355 k1++;
356 /* create a string like "attribute.?1"
358 if (attr_name[0] != 0)
359 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", attr_name, k1);
360 else
361 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
363 len = sizeof (value) - 1;
364 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
366 if (result == ASN1_ELEMENT_NOT_FOUND)
368 gnutls_assert ();
369 break;
372 if (result != ASN1_VALUE_NOT_FOUND)
374 gnutls_assert ();
375 result = _gnutls_asn2err (result);
376 goto cleanup;
379 /* Move to the attibute type and values
381 /* Read the OID
383 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer1);
384 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
386 len = sizeof (oid) - 1;
387 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
389 if (result == ASN1_ELEMENT_NOT_FOUND)
390 break;
391 else if (result != ASN1_SUCCESS)
393 gnutls_assert ();
394 result = _gnutls_asn2err (result);
395 goto cleanup;
398 if (strcmp (oid, given_oid) == 0)
399 { /* Found the OID */
401 /* Read the Value
403 snprintf (tmpbuffer3, sizeof (tmpbuffer3), "%s.values.?%u",
404 tmpbuffer1, indx + 1);
406 len = sizeof (value) - 1;
407 result = asn1_read_value (asn1_struct, tmpbuffer3, value, &len);
409 if (result != ASN1_SUCCESS)
411 gnutls_assert ();
412 result = _gnutls_asn2err (result);
413 goto cleanup;
416 if (raw == 0)
418 printable = _gnutls_x509_oid_data_printable (oid);
419 if (printable == 1)
421 if ((result =
422 _gnutls_x509_oid_data2string
423 (oid, value, len, buf, sizeof_buf)) < 0)
425 gnutls_assert ();
426 goto cleanup;
428 return 0;
430 else
432 gnutls_assert ();
433 return GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE;
436 else
437 { /* raw!=0 */
438 if (*sizeof_buf >= (size_t) len && buf != NULL)
440 *sizeof_buf = len;
441 memcpy (buf, value, len);
443 return 0;
445 else
447 *sizeof_buf = len;
448 return GNUTLS_E_SHORT_MEMORY_BUFFER;
454 while (1);
456 gnutls_assert ();
458 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
460 cleanup:
461 return result;
465 * gnutls_x509_crq_get_challenge_password:
466 * @crq: should contain a #gnutls_x509_crq_t structure
467 * @pass: will hold a (0)-terminated password string
468 * @sizeof_pass: Initially holds the size of @pass.
470 * This function will return the challenge password in the request.
471 * The challenge password is intended to be used for requesting a
472 * revocation of the certificate.
474 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
475 * negative error value.
478 gnutls_x509_crq_get_challenge_password (gnutls_x509_crq_t crq,
479 char *pass, size_t * sizeof_pass)
481 if (crq == NULL)
483 gnutls_assert ();
484 return GNUTLS_E_INVALID_REQUEST;
487 return parse_attribute (crq->crq, "certificationRequestInfo.attributes",
488 "1.2.840.113549.1.9.7", 0, 0, pass, sizeof_pass);
491 /* This function will attempt to set the requested attribute in
492 * the given X509v3 certificate.
494 * Critical will be either 0 or 1.
496 static int
497 add_attribute (ASN1_TYPE asn, const char *root, const char *attribute_id,
498 const gnutls_datum_t * ext_data)
500 int result;
501 char name[ASN1_MAX_NAME_SIZE];
503 snprintf (name, sizeof (name), "%s", root);
505 /* Add a new attribute in the list.
507 result = asn1_write_value (asn, name, "NEW", 1);
508 if (result != ASN1_SUCCESS)
510 gnutls_assert ();
511 return _gnutls_asn2err (result);
514 snprintf (name, sizeof (name), "%s.?LAST.type", root);
516 result = asn1_write_value (asn, name, attribute_id, 1);
517 if (result != ASN1_SUCCESS)
519 gnutls_assert ();
520 return _gnutls_asn2err (result);
523 snprintf (name, sizeof (name), "%s.?LAST.values", root);
525 result = asn1_write_value (asn, name, "NEW", 1);
526 if (result != ASN1_SUCCESS)
528 gnutls_assert ();
529 return _gnutls_asn2err (result);
532 snprintf (name, sizeof (name), "%s.?LAST.values.?LAST", root);
534 result = _gnutls_x509_write_value (asn, name, ext_data, 0);
535 if (result < 0)
537 gnutls_assert ();
538 return result;
541 return 0;
544 /* Overwrite the given attribute (using the index)
545 * index here starts from one.
547 static int
548 overwrite_attribute (ASN1_TYPE asn, const char *root, unsigned int indx,
549 const gnutls_datum_t * ext_data)
551 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
552 int result;
554 snprintf (name, sizeof (name), "%s.?%u", root, indx);
556 _gnutls_str_cpy (name2, sizeof (name2), name);
557 _gnutls_str_cat (name2, sizeof (name2), ".values.?LAST");
559 result = _gnutls_x509_write_value (asn, name2, ext_data, 0);
560 if (result < 0)
562 gnutls_assert ();
563 return result;
567 return 0;
570 static int
571 set_attribute (ASN1_TYPE asn, const char *root,
572 const char *ext_id, const gnutls_datum_t * ext_data)
574 int result;
575 int k, len;
576 char name[ASN1_MAX_NAME_SIZE], name2[ASN1_MAX_NAME_SIZE];
577 char extnID[MAX_OID_SIZE];
579 /* Find the index of the given attribute.
581 k = 0;
584 k++;
586 snprintf (name, sizeof (name), "%s.?%u", root, k);
588 len = sizeof (extnID) - 1;
589 result = asn1_read_value (asn, name, extnID, &len);
591 /* move to next
594 if (result == ASN1_ELEMENT_NOT_FOUND)
596 break;
602 _gnutls_str_cpy (name2, sizeof (name2), name);
603 _gnutls_str_cat (name2, sizeof (name2), ".type");
605 len = sizeof (extnID) - 1;
606 result = asn1_read_value (asn, name2, extnID, &len);
608 if (result == ASN1_ELEMENT_NOT_FOUND)
610 gnutls_assert ();
611 break;
613 else if (result != ASN1_SUCCESS)
615 gnutls_assert ();
616 return _gnutls_asn2err (result);
619 /* Handle Extension
621 if (strcmp (extnID, ext_id) == 0)
623 /* attribute was found
625 return overwrite_attribute (asn, root, k, ext_data);
630 while (0);
632 while (1);
634 if (result == ASN1_ELEMENT_NOT_FOUND)
636 return add_attribute (asn, root, ext_id, ext_data);
638 else
640 gnutls_assert ();
641 return _gnutls_asn2err (result);
645 return 0;
649 * gnutls_x509_crq_set_attribute_by_oid:
650 * @crq: should contain a #gnutls_x509_crq_t structure
651 * @oid: holds an Object Identified in (0)-terminated string
652 * @buf: a pointer to a structure that holds the attribute data
653 * @sizeof_buf: holds the size of @buf
655 * This function will set the attribute in the certificate request
656 * specified by the given Object ID. The attribute must be be DER
657 * encoded.
659 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
660 * negative error value.
663 gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq,
664 const char *oid, void *buf,
665 size_t sizeof_buf)
667 gnutls_datum_t data;
669 data.data = buf;
670 data.size = sizeof_buf;
672 if (crq == NULL)
674 gnutls_assert ();
675 return GNUTLS_E_INVALID_REQUEST;
678 return set_attribute (crq->crq, "certificationRequestInfo.attributes",
679 oid, &data);
683 * gnutls_x509_crq_get_attribute_by_oid:
684 * @crq: should contain a #gnutls_x509_crq_t structure
685 * @oid: holds an Object Identified in (0)-terminated string
686 * @indx: In case multiple same OIDs exist in the attribute list, this
687 * specifies which to send, use (0) to get the first one
688 * @buf: a pointer to a structure to hold the attribute data (may be %NULL)
689 * @sizeof_buf: initially holds the size of @buf
691 * This function will return the attribute in the certificate request
692 * specified by the given Object ID. The attribute will be DER
693 * encoded.
695 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
696 * negative error value.
699 gnutls_x509_crq_get_attribute_by_oid (gnutls_x509_crq_t crq,
700 const char *oid, int indx, void *buf,
701 size_t * sizeof_buf)
703 if (crq == NULL)
705 gnutls_assert ();
706 return GNUTLS_E_INVALID_REQUEST;
709 return parse_attribute (crq->crq, "certificationRequestInfo.attributes",
710 oid, indx, 1, buf, sizeof_buf);
714 * gnutls_x509_crq_set_dn_by_oid:
715 * @crq: should contain a #gnutls_x509_crq_t structure
716 * @oid: holds an Object Identifier in a (0)-terminated string
717 * @raw_flag: must be 0, or 1 if the data are DER encoded
718 * @data: a pointer to the input data
719 * @sizeof_data: holds the size of @data
721 * This function will set the part of the name of the Certificate
722 * request subject, specified by the given OID. The input string
723 * should be ASCII or UTF-8 encoded.
725 * Some helper macros with popular OIDs can be found in gnutls/x509.h
726 * With this function you can only set the known OIDs. You can test
727 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
728 * not known (by gnutls) you should properly DER encode your data, and
729 * call this function with raw_flag set.
731 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
732 * negative error value.
735 gnutls_x509_crq_set_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
736 unsigned int raw_flag, const void *data,
737 unsigned int sizeof_data)
739 if (sizeof_data == 0 || data == NULL || crq == NULL)
741 return GNUTLS_E_INVALID_REQUEST;
744 return _gnutls_x509_set_dn_oid (crq->crq,
745 "certificationRequestInfo.subject", oid,
746 raw_flag, data, sizeof_data);
750 * gnutls_x509_crq_set_version:
751 * @crq: should contain a #gnutls_x509_crq_t structure
752 * @version: holds the version number, for v1 Requests must be 1
754 * This function will set the version of the certificate request. For
755 * version 1 requests this must be one.
757 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
758 * negative error value.
761 gnutls_x509_crq_set_version (gnutls_x509_crq_t crq, unsigned int version)
763 int result;
764 unsigned char null = version;
766 if (crq == NULL)
768 gnutls_assert ();
769 return GNUTLS_E_INVALID_REQUEST;
772 if (null > 0)
773 null--;
775 result =
776 asn1_write_value (crq->crq, "certificationRequestInfo.version", &null, 1);
777 if (result != ASN1_SUCCESS)
779 gnutls_assert ();
780 return _gnutls_asn2err (result);
783 return 0;
787 * gnutls_x509_crq_get_version:
788 * @crq: should contain a #gnutls_x509_crq_t structure
790 * This function will return the version of the specified Certificate
791 * request.
793 * Returns: version of certificate request, or a negative error code on
794 * error.
797 gnutls_x509_crq_get_version (gnutls_x509_crq_t crq)
799 uint8_t version[8];
800 int len, result;
802 if (crq == NULL)
804 gnutls_assert ();
805 return GNUTLS_E_INVALID_REQUEST;
808 len = sizeof (version);
809 if ((result =
810 asn1_read_value (crq->crq, "certificationRequestInfo.version",
811 version, &len)) != ASN1_SUCCESS)
814 if (result == ASN1_ELEMENT_NOT_FOUND)
815 return 1; /* the DEFAULT version */
816 gnutls_assert ();
817 return _gnutls_asn2err (result);
820 return (int) version[0] + 1;
824 * gnutls_x509_crq_set_key:
825 * @crq: should contain a #gnutls_x509_crq_t structure
826 * @key: holds a private key
828 * This function will set the public parameters from the given private
829 * key to the request.
831 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
832 * negative error value.
835 gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
837 int result;
839 if (crq == NULL)
841 gnutls_assert ();
842 return GNUTLS_E_INVALID_REQUEST;
845 result = _gnutls_x509_encode_and_copy_PKI_params
846 (crq->crq,
847 "certificationRequestInfo.subjectPKInfo",
848 key->pk_algorithm, &key->params);
850 if (result < 0)
852 gnutls_assert ();
853 return result;
856 return 0;
860 * gnutls_x509_crq_get_key_rsa_raw:
861 * @crq: Holds the certificate
862 * @m: will hold the modulus
863 * @e: will hold the public exponent
865 * This function will export the RSA public key's parameters found in
866 * the given structure. The new parameters will be allocated using
867 * gnutls_malloc() and will be stored in the appropriate datum.
869 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
870 * negative error value.
872 * Since: 2.8.0
875 gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq,
876 gnutls_datum_t * m, gnutls_datum_t * e)
878 int ret;
879 gnutls_pk_params_st params;
881 gnutls_pk_params_init(&params);
883 if (crq == NULL)
885 gnutls_assert ();
886 return GNUTLS_E_INVALID_REQUEST;
889 ret = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
890 if (ret != GNUTLS_PK_RSA)
892 gnutls_assert ();
893 return GNUTLS_E_INVALID_REQUEST;
896 ret = _gnutls_x509_crq_get_mpis (crq, &params);
897 if (ret < 0)
899 gnutls_assert ();
900 return ret;
903 ret = _gnutls_mpi_dprint (params.params[0], m);
904 if (ret < 0)
906 gnutls_assert ();
907 goto cleanup;
910 ret = _gnutls_mpi_dprint (params.params[1], e);
911 if (ret < 0)
913 gnutls_assert ();
914 _gnutls_free_datum (m);
915 goto cleanup;
918 ret = 0;
920 cleanup:
921 gnutls_pk_params_release(&params);
922 return ret;
926 * gnutls_x509_crq_set_key_rsa_raw:
927 * @crq: should contain a #gnutls_x509_crq_t structure
928 * @m: holds the modulus
929 * @e: holds the public exponent
931 * This function will set the public parameters from the given private
932 * key to the request. Only RSA keys are currently supported.
934 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
935 * negative error value.
937 * Since: 2.6.0
940 gnutls_x509_crq_set_key_rsa_raw (gnutls_x509_crq_t crq,
941 const gnutls_datum_t * m,
942 const gnutls_datum_t * e)
944 int result, ret;
945 size_t siz = 0;
946 gnutls_pk_params_st temp_params;
948 gnutls_pk_params_init(&temp_params);
950 if (crq == NULL)
952 gnutls_assert ();
953 return GNUTLS_E_INVALID_REQUEST;
956 memset (&temp_params, 0, sizeof (temp_params));
958 siz = m->size;
959 if (_gnutls_mpi_scan_nz (&temp_params.params[0], m->data, siz))
961 gnutls_assert ();
962 ret = GNUTLS_E_MPI_SCAN_FAILED;
963 goto error;
966 siz = e->size;
967 if (_gnutls_mpi_scan_nz (&temp_params.params[1], e->data, siz))
969 gnutls_assert ();
970 ret = GNUTLS_E_MPI_SCAN_FAILED;
971 goto error;
974 temp_params.params_nr = RSA_PUBLIC_PARAMS;
976 result = _gnutls_x509_encode_and_copy_PKI_params
977 (crq->crq,
978 "certificationRequestInfo.subjectPKInfo",
979 GNUTLS_PK_RSA, &temp_params);
981 if (result < 0)
983 gnutls_assert ();
984 ret = result;
985 goto error;
988 ret = 0;
990 error:
991 gnutls_pk_params_release(&temp_params);
992 return ret;
996 * gnutls_x509_crq_set_challenge_password:
997 * @crq: should contain a #gnutls_x509_crq_t structure
998 * @pass: holds a (0)-terminated password
1000 * This function will set a challenge password to be used when
1001 * revoking the request.
1003 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1004 * negative error value.
1007 gnutls_x509_crq_set_challenge_password (gnutls_x509_crq_t crq,
1008 const char *pass)
1010 int result;
1012 if (crq == NULL)
1014 gnutls_assert ();
1015 return GNUTLS_E_INVALID_REQUEST;
1018 /* Add the attribute.
1020 result = asn1_write_value (crq->crq, "certificationRequestInfo.attributes",
1021 "NEW", 1);
1022 if (result != ASN1_SUCCESS)
1024 gnutls_assert ();
1025 return _gnutls_asn2err (result);
1028 result = _gnutls_x509_encode_and_write_attribute
1029 ("1.2.840.113549.1.9.7", crq->crq,
1030 "certificationRequestInfo.attributes.?LAST", pass, strlen (pass), 1);
1031 if (result < 0)
1033 gnutls_assert ();
1034 return result;
1037 return 0;
1041 * gnutls_x509_crq_sign2:
1042 * @crq: should contain a #gnutls_x509_crq_t structure
1043 * @key: holds a private key
1044 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
1045 * @flags: must be 0
1047 * This function will sign the certificate request with a private key.
1048 * This must be the same key as the one used in
1049 * gnutls_x509_crt_set_key() since a certificate request is self
1050 * signed.
1052 * This must be the last step in a certificate request generation
1053 * since all the previously set parameters are now signed.
1055 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
1056 * %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
1057 * information in the certificate request (e.g., the version using
1058 * gnutls_x509_crq_set_version()).
1062 gnutls_x509_crq_sign2 (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key,
1063 gnutls_digest_algorithm_t dig, unsigned int flags)
1065 int result;
1066 gnutls_privkey_t privkey;
1068 if (crq == NULL)
1070 gnutls_assert ();
1071 return GNUTLS_E_INVALID_REQUEST;
1074 result = gnutls_privkey_init (&privkey);
1075 if (result < 0)
1077 gnutls_assert ();
1078 return result;
1081 result = gnutls_privkey_import_x509 (privkey, key, 0);
1082 if (result < 0)
1084 gnutls_assert ();
1085 goto fail;
1088 result = gnutls_x509_crq_privkey_sign (crq, privkey, dig, flags);
1089 if (result < 0)
1091 gnutls_assert ();
1092 goto fail;
1095 result = 0;
1097 fail:
1098 gnutls_privkey_deinit (privkey);
1100 return result;
1104 * gnutls_x509_crq_sign:
1105 * @crq: should contain a #gnutls_x509_crq_t structure
1106 * @key: holds a private key
1108 * This function is the same a gnutls_x509_crq_sign2() with no flags,
1109 * and SHA1 as the hash algorithm.
1111 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1112 * negative error value.
1114 * Deprecated: Use gnutls_x509_crq_privkey_sign() instead.
1117 gnutls_x509_crq_sign (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
1119 return gnutls_x509_crq_sign2 (crq, key, GNUTLS_DIG_SHA1, 0);
1123 * gnutls_x509_crq_export:
1124 * @crq: should contain a #gnutls_x509_crq_t structure
1125 * @format: the format of output params. One of PEM or DER.
1126 * @output_data: will contain a certificate request PEM or DER encoded
1127 * @output_data_size: holds the size of output_data (and will be
1128 * replaced by the actual size of parameters)
1130 * This function will export the certificate request to a PEM or DER
1131 * encoded PKCS10 structure.
1133 * If the buffer provided is not long enough to hold the output, then
1134 * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
1135 * *@output_data_size will be updated.
1137 * If the structure is PEM encoded, it will have a header of "BEGIN
1138 * NEW CERTIFICATE REQUEST".
1140 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1141 * negative error value.
1144 gnutls_x509_crq_export (gnutls_x509_crq_t crq,
1145 gnutls_x509_crt_fmt_t format, void *output_data,
1146 size_t * output_data_size)
1148 if (crq == NULL)
1150 gnutls_assert ();
1151 return GNUTLS_E_INVALID_REQUEST;
1154 return _gnutls_x509_export_int (crq->crq, format, PEM_CRQ,
1155 output_data, output_data_size);
1159 * gnutls_x509_crq_get_pk_algorithm:
1160 * @crq: should contain a #gnutls_x509_crq_t structure
1161 * @bits: if bits is non-%NULL it will hold the size of the parameters' in bits
1163 * This function will return the public key algorithm of a PKCS#10
1164 * certificate request.
1166 * If bits is non-%NULL, it should have enough size to hold the
1167 * parameters size in bits. For RSA the bits returned is the modulus.
1168 * For DSA the bits returned are of the public exponent.
1170 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1171 * success, or a negative error code on error.
1174 gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits)
1176 int result;
1178 if (crq == NULL)
1180 gnutls_assert ();
1181 return GNUTLS_E_INVALID_REQUEST;
1184 result = _gnutls_x509_get_pk_algorithm
1185 (crq->crq, "certificationRequestInfo.subjectPKInfo", bits);
1186 if (result < 0)
1188 gnutls_assert ();
1191 return result;
1195 * gnutls_x509_crq_get_attribute_info:
1196 * @crq: should contain a #gnutls_x509_crq_t structure
1197 * @indx: Specifies which attribute OID to send. Use (0) to get the first one.
1198 * @oid: a pointer to a structure to hold the OID
1199 * @sizeof_oid: initially holds the maximum size of @oid, on return
1200 * holds actual size of @oid.
1202 * This function will return the requested attribute OID in the
1203 * certificate, and the critical flag for it. The attribute OID will
1204 * be stored as a string in the provided buffer. Use
1205 * gnutls_x509_crq_get_attribute_data() to extract the data.
1207 * If the buffer provided is not long enough to hold the output, then
1208 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1209 * returned.
1211 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1212 * negative error code in case of an error. If your have reached the
1213 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1214 * will be returned.
1216 * Since: 2.8.0
1219 gnutls_x509_crq_get_attribute_info (gnutls_x509_crq_t crq, int indx,
1220 void *oid, size_t * sizeof_oid)
1222 int result;
1223 char name[ASN1_MAX_NAME_SIZE];
1224 int len;
1226 if (!crq)
1228 gnutls_assert ();
1229 return GNUTLS_E_INVALID_REQUEST;
1232 snprintf (name, sizeof (name),
1233 "certificationRequestInfo.attributes.?%u.type", indx + 1);
1235 len = *sizeof_oid;
1236 result = asn1_read_value (crq->crq, name, oid, &len);
1237 *sizeof_oid = len;
1239 if (result == ASN1_ELEMENT_NOT_FOUND)
1240 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1241 else if (result < 0)
1243 gnutls_assert ();
1244 return _gnutls_asn2err (result);
1247 return 0;
1252 * gnutls_x509_crq_get_attribute_data:
1253 * @crq: should contain a #gnutls_x509_crq_t structure
1254 * @indx: Specifies which attribute OID to send. Use (0) to get the first one.
1255 * @data: a pointer to a structure to hold the data (may be null)
1256 * @sizeof_data: initially holds the size of @oid
1258 * This function will return the requested attribute data in the
1259 * certificate request. The attribute data will be stored as a string in the
1260 * provided buffer.
1262 * Use gnutls_x509_crq_get_attribute_info() to extract the OID.
1263 * Use gnutls_x509_crq_get_attribute_by_oid() instead,
1264 * if you want to get data indexed by the attribute OID rather than
1265 * sequence.
1267 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1268 * negative error code in case of an error. If your have reached the
1269 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1270 * will be returned.
1272 * Since: 2.8.0
1275 gnutls_x509_crq_get_attribute_data (gnutls_x509_crq_t crq, int indx,
1276 void *data, size_t * sizeof_data)
1278 int result, len;
1279 char name[ASN1_MAX_NAME_SIZE];
1281 if (!crq)
1283 gnutls_assert ();
1284 return GNUTLS_E_INVALID_REQUEST;
1287 snprintf (name, sizeof (name),
1288 "certificationRequestInfo.attributes.?%u.values.?1", indx + 1);
1290 len = *sizeof_data;
1291 result = asn1_read_value (crq->crq, name, data, &len);
1292 *sizeof_data = len;
1294 if (result == ASN1_ELEMENT_NOT_FOUND)
1295 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1296 else if (result < 0)
1298 gnutls_assert ();
1299 return _gnutls_asn2err (result);
1302 return 0;
1306 * gnutls_x509_crq_get_extension_info:
1307 * @crq: should contain a #gnutls_x509_crq_t structure
1308 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1309 * @oid: a pointer to a structure to hold the OID
1310 * @sizeof_oid: initially holds the maximum size of @oid, on return
1311 * holds actual size of @oid.
1312 * @critical: output variable with critical flag, may be NULL.
1314 * This function will return the requested extension OID in the
1315 * certificate, and the critical flag for it. The extension OID will
1316 * be stored as a string in the provided buffer. Use
1317 * gnutls_x509_crq_get_extension_data() to extract the data.
1319 * If the buffer provided is not long enough to hold the output, then
1320 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1321 * returned.
1323 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1324 * negative error code in case of an error. If your have reached the
1325 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1326 * will be returned.
1328 * Since: 2.8.0
1331 gnutls_x509_crq_get_extension_info (gnutls_x509_crq_t crq, int indx,
1332 void *oid, size_t * sizeof_oid,
1333 unsigned int *critical)
1335 int result;
1336 char str_critical[10];
1337 char name[ASN1_MAX_NAME_SIZE];
1338 char *extensions = NULL;
1339 size_t extensions_size = 0;
1340 ASN1_TYPE c2;
1341 int len;
1343 if (!crq)
1345 gnutls_assert ();
1346 return GNUTLS_E_INVALID_REQUEST;
1349 /* read extensionRequest */
1350 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1351 0, NULL, &extensions_size);
1352 if (result == GNUTLS_E_SHORT_MEMORY_BUFFER)
1354 extensions = gnutls_malloc (extensions_size);
1355 if (extensions == NULL)
1357 gnutls_assert ();
1358 return GNUTLS_E_MEMORY_ERROR;
1361 result = gnutls_x509_crq_get_attribute_by_oid (crq,
1362 "1.2.840.113549.1.9.14",
1363 0, extensions,
1364 &extensions_size);
1366 if (result < 0)
1368 gnutls_assert ();
1369 goto out;
1372 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
1373 if (result != ASN1_SUCCESS)
1375 gnutls_assert ();
1376 result = _gnutls_asn2err (result);
1377 goto out;
1380 result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
1381 if (result != ASN1_SUCCESS)
1383 gnutls_assert ();
1384 asn1_delete_structure (&c2);
1385 result = _gnutls_asn2err (result);
1386 goto out;
1389 snprintf (name, sizeof (name), "?%u.extnID", indx + 1);
1391 len = *sizeof_oid;
1392 result = asn1_read_value (c2, name, oid, &len);
1393 *sizeof_oid = len;
1395 if (result == ASN1_ELEMENT_NOT_FOUND)
1397 asn1_delete_structure (&c2);
1398 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1399 goto out;
1401 else if (result < 0)
1403 gnutls_assert ();
1404 asn1_delete_structure (&c2);
1405 result = _gnutls_asn2err (result);
1406 goto out;
1409 snprintf (name, sizeof (name), "?%u.critical", indx + 1);
1410 len = sizeof (str_critical);
1411 result = asn1_read_value (c2, name, str_critical, &len);
1413 asn1_delete_structure (&c2);
1415 if (result < 0)
1417 gnutls_assert ();
1418 result = _gnutls_asn2err (result);
1419 goto out;
1422 if (critical)
1424 if (str_critical[0] == 'T')
1425 *critical = 1;
1426 else
1427 *critical = 0;
1430 result = 0;
1432 out:
1433 gnutls_free (extensions);
1434 return result;
1438 * gnutls_x509_crq_get_extension_data:
1439 * @crq: should contain a #gnutls_x509_crq_t structure
1440 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1441 * @data: a pointer to a structure to hold the data (may be null)
1442 * @sizeof_data: initially holds the size of @oid
1444 * This function will return the requested extension data in the
1445 * certificate. The extension data will be stored as a string in the
1446 * provided buffer.
1448 * Use gnutls_x509_crq_get_extension_info() to extract the OID and
1449 * critical flag. Use gnutls_x509_crq_get_extension_by_oid() instead,
1450 * if you want to get data indexed by the extension OID rather than
1451 * sequence.
1453 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1454 * negative error code in case of an error. If your have reached the
1455 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1456 * will be returned.
1458 * Since: 2.8.0
1461 gnutls_x509_crq_get_extension_data (gnutls_x509_crq_t crq, int indx,
1462 void *data, size_t * sizeof_data)
1464 int result, len;
1465 char name[ASN1_MAX_NAME_SIZE];
1466 unsigned char *extensions;
1467 size_t extensions_size = 0;
1468 ASN1_TYPE c2;
1470 if (!crq)
1472 gnutls_assert ();
1473 return GNUTLS_E_INVALID_REQUEST;
1476 /* read extensionRequest */
1477 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1478 0, NULL, &extensions_size);
1479 if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
1481 gnutls_assert ();
1482 if (result == 0)
1483 return GNUTLS_E_INTERNAL_ERROR;
1484 return result;
1487 extensions = gnutls_malloc (extensions_size);
1488 if (extensions == NULL)
1490 gnutls_assert ();
1491 return GNUTLS_E_MEMORY_ERROR;
1494 result = gnutls_x509_crq_get_attribute_by_oid (crq, "1.2.840.113549.1.9.14",
1495 0, extensions,
1496 &extensions_size);
1497 if (result < 0)
1499 gnutls_assert ();
1500 return result;
1503 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2);
1504 if (result != ASN1_SUCCESS)
1506 gnutls_assert ();
1507 gnutls_free (extensions);
1508 return _gnutls_asn2err (result);
1511 result = asn1_der_decoding (&c2, extensions, extensions_size, NULL);
1512 gnutls_free (extensions);
1513 if (result != ASN1_SUCCESS)
1515 gnutls_assert ();
1516 asn1_delete_structure (&c2);
1517 return _gnutls_asn2err (result);
1520 snprintf (name, sizeof (name), "?%u.extnValue", indx + 1);
1522 len = *sizeof_data;
1523 result = asn1_read_value (c2, name, data, &len);
1524 *sizeof_data = len;
1526 asn1_delete_structure (&c2);
1528 if (result == ASN1_ELEMENT_NOT_FOUND)
1529 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1530 else if (result < 0)
1532 gnutls_assert ();
1533 return _gnutls_asn2err (result);
1536 return 0;
1540 * gnutls_x509_crq_get_key_usage:
1541 * @crq: should contain a #gnutls_x509_crq_t structure
1542 * @key_usage: where the key usage bits will be stored
1543 * @critical: will be non (0) if the extension is marked as critical
1545 * This function will return certificate's key usage, by reading the
1546 * keyUsage X.509 extension (2.5.29.15). The key usage value will
1547 * ORed values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1548 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1549 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1550 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1551 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1553 * Returns: the certificate key usage, or a negative error code in case of
1554 * parsing error. If the certificate does not contain the keyUsage
1555 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1556 * returned.
1558 * Since: 2.8.0
1561 gnutls_x509_crq_get_key_usage (gnutls_x509_crq_t crq,
1562 unsigned int *key_usage,
1563 unsigned int *critical)
1565 int result;
1566 uint16_t _usage;
1567 uint8_t buf[128];
1568 size_t buf_size = sizeof (buf);
1570 if (crq == NULL)
1572 gnutls_assert ();
1573 return GNUTLS_E_INVALID_REQUEST;
1576 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.15", 0,
1577 buf, &buf_size, critical);
1578 if (result < 0)
1580 gnutls_assert ();
1581 return result;
1584 result = _gnutls_x509_ext_extract_keyUsage (&_usage, buf, buf_size);
1586 *key_usage = _usage;
1588 if (result < 0)
1590 gnutls_assert ();
1591 return result;
1594 return 0;
1598 * gnutls_x509_crq_get_basic_constraints:
1599 * @crq: should contain a #gnutls_x509_crq_t structure
1600 * @critical: will be non (0) if the extension is marked as critical
1601 * @ca: pointer to output integer indicating CA status, may be NULL,
1602 * value is 1 if the certificate CA flag is set, 0 otherwise.
1603 * @pathlen: pointer to output integer indicating path length (may be
1604 * NULL), non-negative error codes indicate a present pathLenConstraint
1605 * field and the actual value, -1 indicate that the field is absent.
1607 * This function will read the certificate's basic constraints, and
1608 * return the certificates CA status. It reads the basicConstraints
1609 * X.509 extension (2.5.29.19).
1611 * Returns: If the certificate is a CA a positive value will be
1612 * returned, or (0) if the certificate does not have CA flag set.
1613 * A negative error code may be returned in case of errors. If the
1614 * certificate does not contain the basicConstraints extension
1615 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1617 * Since: 2.8.0
1620 gnutls_x509_crq_get_basic_constraints (gnutls_x509_crq_t crq,
1621 unsigned int *critical,
1622 unsigned int *ca, int *pathlen)
1624 int result;
1625 unsigned int tmp_ca;
1626 uint8_t buf[256];
1627 size_t buf_size = sizeof (buf);
1629 if (crq == NULL)
1631 gnutls_assert ();
1632 return GNUTLS_E_INVALID_REQUEST;
1635 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.19", 0,
1636 buf, &buf_size, critical);
1637 if (result < 0)
1639 gnutls_assert ();
1640 return result;
1643 result =
1644 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca,
1645 pathlen, buf, buf_size);
1646 if (ca)
1647 *ca = tmp_ca;
1649 if (result < 0)
1651 gnutls_assert ();
1652 return result;
1655 return tmp_ca;
1658 static int
1659 get_subject_alt_name (gnutls_x509_crq_t crq,
1660 unsigned int seq, void *ret,
1661 size_t * ret_size, unsigned int *ret_type,
1662 unsigned int *critical, int othername_oid)
1664 int result;
1665 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1666 gnutls_x509_subject_alt_name_t type;
1667 gnutls_datum_t dnsname = { NULL, 0 };
1668 size_t dns_size = 0;
1670 if (crq == NULL)
1672 gnutls_assert ();
1673 return GNUTLS_E_INVALID_REQUEST;
1676 if (ret)
1677 memset (ret, 0, *ret_size);
1678 else
1679 *ret_size = 0;
1681 /* Extract extension.
1683 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1684 NULL, &dns_size, critical);
1685 if (result < 0)
1687 gnutls_assert ();
1688 return result;
1691 dnsname.size = dns_size;
1692 dnsname.data = gnutls_malloc (dnsname.size);
1693 if (dnsname.data == NULL)
1695 gnutls_assert ();
1696 return GNUTLS_E_MEMORY_ERROR;
1699 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1700 dnsname.data, &dns_size,
1701 critical);
1702 if (result < 0)
1704 gnutls_assert ();
1705 gnutls_free (dnsname.data);
1706 return result;
1709 result = asn1_create_element
1710 (_gnutls_get_pkix (), "PKIX1.SubjectAltName", &c2);
1711 if (result != ASN1_SUCCESS)
1713 gnutls_assert ();
1714 gnutls_free (dnsname.data);
1715 return _gnutls_asn2err (result);
1718 result = asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
1719 gnutls_free (dnsname.data);
1720 if (result != ASN1_SUCCESS)
1722 gnutls_assert ();
1723 asn1_delete_structure (&c2);
1724 return _gnutls_asn2err (result);
1727 result = _gnutls_parse_general_name (c2, "", seq, ret, ret_size,
1728 ret_type, othername_oid);
1729 asn1_delete_structure (&c2);
1730 if (result < 0)
1732 return result;
1735 type = result;
1737 return type;
1741 * gnutls_x509_crq_get_subject_alt_name:
1742 * @crq: should contain a #gnutls_x509_crq_t structure
1743 * @seq: specifies the sequence number of the alt name, 0 for the
1744 * first one, 1 for the second etc.
1745 * @ret: is the place where the alternative name will be copied to
1746 * @ret_size: holds the size of ret.
1747 * @ret_type: holds the #gnutls_x509_subject_alt_name_t name type
1748 * @critical: will be non (0) if the extension is marked as critical
1749 * (may be null)
1751 * This function will return the alternative names, contained in the
1752 * given certificate. It is the same as
1753 * gnutls_x509_crq_get_subject_alt_name() except for the fact that it
1754 * will return the type of the alternative name in @ret_type even if
1755 * the function fails for some reason (i.e. the buffer provided is
1756 * not enough).
1758 * Returns: the alternative subject name type on success, one of the
1759 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1760 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1761 * hold the value. In that case @ret_size will be updated with the
1762 * required size. If the certificate request does not have an
1763 * Alternative name with the specified sequence number then
1764 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1766 * Since: 2.8.0
1769 gnutls_x509_crq_get_subject_alt_name (gnutls_x509_crq_t crq,
1770 unsigned int seq, void *ret,
1771 size_t * ret_size,
1772 unsigned int *ret_type,
1773 unsigned int *critical)
1775 return get_subject_alt_name (crq, seq, ret, ret_size, ret_type, critical,
1780 * gnutls_x509_crq_get_subject_alt_othername_oid:
1781 * @crq: should contain a #gnutls_x509_crq_t structure
1782 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1783 * @ret: is the place where the otherName OID will be copied to
1784 * @ret_size: holds the size of ret.
1786 * This function will extract the type OID of an otherName Subject
1787 * Alternative Name, contained in the given certificate, and return
1788 * the type as an enumerated element.
1790 * This function is only useful if
1791 * gnutls_x509_crq_get_subject_alt_name() returned
1792 * %GNUTLS_SAN_OTHERNAME.
1794 * Returns: the alternative subject name type on success, one of the
1795 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs,
1796 * it will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1797 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1798 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1799 * @ret_size is not large enough to hold the value. In that case
1800 * @ret_size will be updated with the required size. If the
1801 * certificate does not have an Alternative name with the specified
1802 * sequence number and with the otherName type then
1803 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1805 * Since: 2.8.0
1808 gnutls_x509_crq_get_subject_alt_othername_oid (gnutls_x509_crq_t crq,
1809 unsigned int seq,
1810 void *ret, size_t * ret_size)
1812 return get_subject_alt_name (crq, seq, ret, ret_size, NULL, NULL, 1);
1816 * gnutls_x509_crq_get_extension_by_oid:
1817 * @crq: should contain a #gnutls_x509_crq_t structure
1818 * @oid: holds an Object Identified in null terminated string
1819 * @indx: In case multiple same OIDs exist in the extensions, this
1820 * specifies which to send. Use (0) to get the first one.
1821 * @buf: a pointer to a structure to hold the name (may be null)
1822 * @sizeof_buf: initially holds the size of @buf
1823 * @critical: will be non (0) if the extension is marked as critical
1825 * This function will return the extension specified by the OID in
1826 * the certificate. The extensions will be returned as binary data
1827 * DER encoded, in the provided buffer.
1829 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1830 * negative error code in case of an error. If the certificate does not
1831 * contain the specified extension
1832 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1834 * Since: 2.8.0
1837 gnutls_x509_crq_get_extension_by_oid (gnutls_x509_crq_t crq,
1838 const char *oid, int indx,
1839 void *buf, size_t * sizeof_buf,
1840 unsigned int *critical)
1842 int result;
1843 unsigned int i;
1844 char _oid[MAX_OID_SIZE];
1845 size_t oid_size;
1847 for (i = 0;; i++)
1849 oid_size = sizeof (_oid);
1850 result =
1851 gnutls_x509_crq_get_extension_info (crq, i, _oid, &oid_size,
1852 critical);
1853 if (result < 0)
1855 gnutls_assert ();
1856 return result;
1859 if (strcmp (oid, _oid) == 0)
1860 { /* found */
1861 if (indx == 0)
1862 return gnutls_x509_crq_get_extension_data (crq, i, buf,
1863 sizeof_buf);
1864 else
1865 indx--;
1870 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1875 * gnutls_x509_crq_set_subject_alt_name:
1876 * @crq: a certificate request of type #gnutls_x509_crq_t
1877 * @nt: is one of the #gnutls_x509_subject_alt_name_t enumerations
1878 * @data: The data to be set
1879 * @data_size: The size of data to be set
1880 * @flags: %GNUTLS_FSAN_SET to clear previous data or
1881 * %GNUTLS_FSAN_APPEND to append.
1883 * This function will set the subject alternative name certificate
1884 * extension. It can set the following types:
1886 * %GNUTLS_SAN_DNSNAME: as a text string
1888 * %GNUTLS_SAN_RFC822NAME: as a text string
1890 * %GNUTLS_SAN_URI: as a text string
1892 * %GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
1894 * Other values can be set as binary values with the proper DER encoding.
1896 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1897 * negative error value.
1899 * Since: 2.8.0
1902 gnutls_x509_crq_set_subject_alt_name (gnutls_x509_crq_t crq,
1903 gnutls_x509_subject_alt_name_t nt,
1904 const void *data,
1905 unsigned int data_size,
1906 unsigned int flags)
1908 int result = 0;
1909 gnutls_datum_t der_data = { NULL, 0 };
1910 gnutls_datum_t prev_der_data = { NULL, 0 };
1911 unsigned int critical = 0;
1912 size_t prev_data_size = 0;
1914 if (crq == NULL)
1916 gnutls_assert ();
1917 return GNUTLS_E_INVALID_REQUEST;
1920 /* Check if the extension already exists.
1922 if (flags == GNUTLS_FSAN_APPEND)
1924 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1925 NULL, &prev_data_size,
1926 &critical);
1927 prev_der_data.size = prev_data_size;
1929 switch (result)
1931 case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
1932 /* Replacing non-existing data means the same as set data. */
1933 break;
1935 case GNUTLS_E_SUCCESS:
1936 prev_der_data.data = gnutls_malloc (prev_der_data.size);
1937 if (prev_der_data.data == NULL)
1939 gnutls_assert ();
1940 return GNUTLS_E_MEMORY_ERROR;
1943 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.17", 0,
1944 prev_der_data.data,
1945 &prev_data_size,
1946 &critical);
1947 if (result < 0)
1949 gnutls_assert ();
1950 gnutls_free (prev_der_data.data);
1951 return result;
1953 break;
1955 default:
1956 gnutls_assert ();
1957 return result;
1961 /* generate the extension.
1963 result = _gnutls_x509_ext_gen_subject_alt_name (nt, data, data_size,
1964 &prev_der_data, &der_data);
1965 gnutls_free (prev_der_data.data);
1966 if (result < 0)
1968 gnutls_assert ();
1969 goto finish;
1972 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.17", &der_data,
1973 critical);
1975 _gnutls_free_datum (&der_data);
1977 if (result < 0)
1979 gnutls_assert ();
1980 return result;
1983 return 0;
1985 finish:
1986 return result;
1990 * gnutls_x509_crq_set_basic_constraints:
1991 * @crq: a certificate request of type #gnutls_x509_crq_t
1992 * @ca: true(1) or false(0) depending on the Certificate authority status.
1993 * @pathLenConstraint: non-negative error codes indicate maximum length of path,
1994 * and negative error codes indicate that the pathLenConstraints field should
1995 * not be present.
1997 * This function will set the basicConstraints certificate extension.
1999 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2000 * negative error value.
2002 * Since: 2.8.0
2005 gnutls_x509_crq_set_basic_constraints (gnutls_x509_crq_t crq,
2006 unsigned int ca, int pathLenConstraint)
2008 int result;
2009 gnutls_datum_t der_data;
2011 if (crq == NULL)
2013 gnutls_assert ();
2014 return GNUTLS_E_INVALID_REQUEST;
2017 /* generate the extension.
2019 result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint,
2020 &der_data);
2021 if (result < 0)
2023 gnutls_assert ();
2024 return result;
2027 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.19", &der_data, 1);
2029 _gnutls_free_datum (&der_data);
2031 if (result < 0)
2033 gnutls_assert ();
2034 return result;
2037 return 0;
2041 * gnutls_x509_crq_set_key_usage:
2042 * @crq: a certificate request of type #gnutls_x509_crq_t
2043 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
2045 * This function will set the keyUsage 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_key_usage (gnutls_x509_crq_t crq, unsigned int usage)
2055 int result;
2056 gnutls_datum_t der_data;
2058 if (crq == NULL)
2060 gnutls_assert ();
2061 return GNUTLS_E_INVALID_REQUEST;
2064 /* generate the extension.
2066 result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data);
2067 if (result < 0)
2069 gnutls_assert ();
2070 return result;
2073 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.15", &der_data, 1);
2075 _gnutls_free_datum (&der_data);
2077 if (result < 0)
2079 gnutls_assert ();
2080 return result;
2083 return 0;
2087 * gnutls_x509_crq_get_key_purpose_oid:
2088 * @crq: should contain a #gnutls_x509_crq_t structure
2089 * @indx: This specifies which OID to return, use (0) to get the first one
2090 * @oid: a pointer to a buffer to hold the OID (may be %NULL)
2091 * @sizeof_oid: initially holds the size of @oid
2092 * @critical: output variable with critical flag, may be %NULL.
2094 * This function will extract the key purpose OIDs of the Certificate
2095 * specified by the given index. These are stored in the Extended Key
2096 * Usage extension (2.5.29.37). See the GNUTLS_KP_* definitions for
2097 * human readable names.
2099 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2100 * not long enough, and in that case the *@sizeof_oid will be
2101 * updated with the required size. On success 0 is returned.
2103 * Since: 2.8.0
2106 gnutls_x509_crq_get_key_purpose_oid (gnutls_x509_crq_t crq,
2107 int indx, void *oid, size_t * sizeof_oid,
2108 unsigned int *critical)
2110 char tmpstr[ASN1_MAX_NAME_SIZE];
2111 int result, len;
2112 gnutls_datum_t prev = { NULL, 0 };
2113 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2114 size_t prev_size = 0;
2116 if (oid)
2117 memset (oid, 0, *sizeof_oid);
2118 else
2119 *sizeof_oid = 0;
2121 /* Extract extension.
2123 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2124 NULL, &prev_size, critical);
2125 prev.size = prev_size;
2127 if (result < 0)
2129 gnutls_assert ();
2130 return result;
2133 prev.data = gnutls_malloc (prev.size);
2134 if (prev.data == NULL)
2136 gnutls_assert ();
2137 return GNUTLS_E_MEMORY_ERROR;
2140 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2141 prev.data, &prev_size,
2142 critical);
2143 if (result < 0)
2145 gnutls_assert ();
2146 gnutls_free (prev.data);
2147 return result;
2150 result = asn1_create_element
2151 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
2152 if (result != ASN1_SUCCESS)
2154 gnutls_assert ();
2155 gnutls_free (prev.data);
2156 return _gnutls_asn2err (result);
2159 result = asn1_der_decoding (&c2, prev.data, prev.size, NULL);
2160 gnutls_free (prev.data);
2161 if (result != ASN1_SUCCESS)
2163 gnutls_assert ();
2164 asn1_delete_structure (&c2);
2165 return _gnutls_asn2err (result);
2168 indx++;
2169 /* create a string like "?1"
2171 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
2173 len = *sizeof_oid;
2174 result = asn1_read_value (c2, tmpstr, oid, &len);
2176 *sizeof_oid = len;
2177 asn1_delete_structure (&c2);
2179 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
2181 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2184 if (result != ASN1_SUCCESS)
2186 if (result != ASN1_MEM_ERROR)
2187 gnutls_assert ();
2188 return _gnutls_asn2err (result);
2191 return 0;
2195 * gnutls_x509_crq_set_key_purpose_oid:
2196 * @crq: a certificate of type #gnutls_x509_crq_t
2197 * @oid: a pointer to a (0)-terminated string that holds the OID
2198 * @critical: Whether this extension will be critical or not
2200 * This function will set the key purpose OIDs of the Certificate.
2201 * These are stored in the Extended Key Usage extension (2.5.29.37)
2202 * See the GNUTLS_KP_* definitions for human readable names.
2204 * Subsequent calls to this function will append OIDs to the OID list.
2206 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2207 * negative error value.
2209 * Since: 2.8.0
2212 gnutls_x509_crq_set_key_purpose_oid (gnutls_x509_crq_t crq,
2213 const void *oid, unsigned int critical)
2215 int result;
2216 gnutls_datum_t prev = { NULL, 0 }, der_data;
2217 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2218 size_t prev_size = 0;
2220 /* Read existing extension, if there is one.
2222 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2223 NULL, &prev_size, &critical);
2224 prev.size = prev_size;
2226 switch (result)
2228 case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
2229 /* No existing extension, that's fine. */
2230 break;
2232 case GNUTLS_E_SUCCESS:
2233 prev.data = gnutls_malloc (prev.size);
2234 if (prev.data == NULL)
2236 gnutls_assert ();
2237 return GNUTLS_E_MEMORY_ERROR;
2240 result = gnutls_x509_crq_get_extension_by_oid (crq, "2.5.29.37", 0,
2241 prev.data, &prev_size,
2242 &critical);
2243 if (result < 0)
2245 gnutls_assert ();
2246 gnutls_free (prev.data);
2247 return result;
2249 break;
2251 default:
2252 gnutls_assert ();
2253 return result;
2256 result = asn1_create_element (_gnutls_get_pkix (),
2257 "PKIX1.ExtKeyUsageSyntax", &c2);
2258 if (result != ASN1_SUCCESS)
2260 gnutls_assert ();
2261 gnutls_free (prev.data);
2262 return _gnutls_asn2err (result);
2265 if (prev.data)
2267 /* decode it.
2269 result = asn1_der_decoding (&c2, prev.data, prev.size, NULL);
2270 gnutls_free (prev.data);
2271 if (result != ASN1_SUCCESS)
2273 gnutls_assert ();
2274 asn1_delete_structure (&c2);
2275 return _gnutls_asn2err (result);
2279 /* generate the extension.
2281 /* 1. create a new element.
2283 result = asn1_write_value (c2, "", "NEW", 1);
2284 if (result != ASN1_SUCCESS)
2286 gnutls_assert ();
2287 asn1_delete_structure (&c2);
2288 return _gnutls_asn2err (result);
2291 /* 2. Add the OID.
2293 result = asn1_write_value (c2, "?LAST", oid, 1);
2294 if (result != ASN1_SUCCESS)
2296 gnutls_assert ();
2297 asn1_delete_structure (&c2);
2298 return _gnutls_asn2err (result);
2301 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
2302 asn1_delete_structure (&c2);
2304 if (result != ASN1_SUCCESS)
2306 gnutls_assert ();
2307 return _gnutls_asn2err (result);
2310 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.37",
2311 &der_data, critical);
2312 _gnutls_free_datum (&der_data);
2313 if (result < 0)
2315 gnutls_assert ();
2316 return result;
2319 return 0;
2323 * gnutls_x509_crq_get_key_id:
2324 * @crq: a certificate of type #gnutls_x509_crq_t
2325 * @flags: should be 0 for now
2326 * @output_data: will contain the key ID
2327 * @output_data_size: holds the size of output_data (and will be
2328 * replaced by the actual size of parameters)
2330 * This function will return a unique ID the depends on the public key
2331 * parameters. This ID can be used in checking whether a certificate
2332 * corresponds to the given private key.
2334 * If the buffer provided is not long enough to hold the output, then
2335 * *@output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2336 * be returned. The output will normally be a SHA-1 hash output,
2337 * which is 20 bytes.
2339 * Returns: In case of failure a negative error code will be
2340 * returned, and 0 on success.
2342 * Since: 2.8.0
2345 gnutls_x509_crq_get_key_id (gnutls_x509_crq_t crq, unsigned int flags,
2346 unsigned char *output_data,
2347 size_t * output_data_size)
2349 int pk, ret = 0;
2350 gnutls_pk_params_st params;
2352 if (crq == NULL)
2354 gnutls_assert ();
2355 return GNUTLS_E_INVALID_REQUEST;
2358 pk = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
2359 if (pk < 0)
2361 gnutls_assert ();
2362 return pk;
2365 ret = _gnutls_x509_crq_get_mpis (crq, &params);
2366 if (ret < 0)
2368 gnutls_assert ();
2369 return ret;
2372 ret = _gnutls_get_key_id(pk, &params, output_data, output_data_size);
2374 gnutls_pk_params_release(&params);
2376 return ret;
2380 * gnutls_x509_crq_privkey_sign:
2381 * @crq: should contain a #gnutls_x509_crq_t structure
2382 * @key: holds a private key
2383 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
2384 * @flags: must be 0
2386 * This function will sign the certificate request with a private key.
2387 * This must be the same key as the one used in
2388 * gnutls_x509_crt_set_key() since a certificate request is self
2389 * signed.
2391 * This must be the last step in a certificate request generation
2392 * since all the previously set parameters are now signed.
2394 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2395 * %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
2396 * information in the certificate request (e.g., the version using
2397 * gnutls_x509_crq_set_version()).
2399 * Since: 2.12.0
2402 gnutls_x509_crq_privkey_sign (gnutls_x509_crq_t crq, gnutls_privkey_t key,
2403 gnutls_digest_algorithm_t dig,
2404 unsigned int flags)
2406 int result;
2407 gnutls_datum_t signature;
2408 gnutls_datum_t tbs;
2410 if (crq == NULL)
2412 gnutls_assert ();
2413 return GNUTLS_E_INVALID_REQUEST;
2416 /* Make sure version field is set. */
2417 if (gnutls_x509_crq_get_version (crq) == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
2419 result = gnutls_x509_crq_set_version (crq, 1);
2420 if (result < 0)
2422 gnutls_assert ();
2423 return result;
2427 /* Step 1. Self sign the request.
2429 result = _gnutls_x509_get_tbs (crq->crq, "certificationRequestInfo", &tbs);
2431 if (result < 0)
2433 gnutls_assert ();
2434 return result;
2437 result = gnutls_privkey_sign_data (key, dig, 0, &tbs, &signature);
2438 gnutls_free (tbs.data);
2440 if (result < 0)
2442 gnutls_assert ();
2443 return result;
2446 /* Step 2. write the signature (bits)
2448 result =
2449 asn1_write_value (crq->crq, "signature", signature.data,
2450 signature.size * 8);
2452 _gnutls_free_datum (&signature);
2454 if (result != ASN1_SUCCESS)
2456 gnutls_assert ();
2457 return _gnutls_asn2err (result);
2460 /* Step 3. Write the signatureAlgorithm field.
2462 result = _gnutls_x509_write_sig_params (crq->crq, "signatureAlgorithm",
2463 gnutls_privkey_get_pk_algorithm
2464 (key, NULL), dig);
2465 if (result < 0)
2467 gnutls_assert ();
2468 return result;
2471 return 0;
2476 * gnutls_x509_crq_verify:
2477 * @crq: is the crq to be verified
2478 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
2480 * This function will verify self signature in the certificate
2481 * request and return its status.
2483 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2484 * is returned, and zero or positive code on success.
2486 * Since 2.12.0
2489 gnutls_x509_crq_verify (gnutls_x509_crq_t crq,
2490 unsigned int flags)
2492 gnutls_datum data = { NULL, 0 };
2493 gnutls_datum signature = { NULL, 0 };
2494 gnutls_pk_params_st params;
2495 gnutls_digest_algorithm_t algo;
2496 int ret;
2498 gnutls_pk_params_init(&params);
2500 ret =
2501 _gnutls_x509_get_signed_data (crq->crq, "certificationRequestInfo", &data);
2502 if (ret < 0)
2504 gnutls_assert ();
2505 return ret;
2508 ret = _gnutls_x509_get_signature_algorithm(crq->crq, "signatureAlgorithm.algorithm");
2509 if (ret < 0)
2511 gnutls_assert ();
2512 goto cleanup;
2515 algo = _gnutls_sign_get_hash_algorithm(ret);
2517 ret = _gnutls_x509_get_signature (crq->crq, "signature", &signature);
2518 if (ret < 0)
2520 gnutls_assert ();
2521 goto cleanup;
2524 ret =
2525 _gnutls_x509_crq_get_mpis(crq, &params);
2526 if (ret < 0)
2528 gnutls_assert ();
2529 goto cleanup;
2532 ret = pubkey_verify_data(gnutls_x509_crq_get_pk_algorithm (crq, NULL), algo,
2533 &data, &signature, &params);
2534 if (ret < 0)
2536 gnutls_assert ();
2537 goto cleanup;
2540 ret = 0;
2542 cleanup:
2543 _gnutls_free_datum (&data);
2544 _gnutls_free_datum (&signature);
2545 gnutls_pk_params_release(&params);
2547 return ret;
2551 * gnutls_x509_crq_set_private_key_usage_period:
2552 * @crq: a certificate of type #gnutls_x509_crq_t
2553 * @activation: The activation time
2554 * @expiration: The expiration time
2556 * This function will set the private key usage period extension (2.5.29.16).
2558 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2559 * negative error value.
2562 gnutls_x509_crq_set_private_key_usage_period (gnutls_x509_crq_t crq,
2563 time_t activation,
2564 time_t expiration)
2566 int result;
2567 gnutls_datum_t der_data;
2568 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2570 if (crq == NULL)
2572 gnutls_assert ();
2573 return GNUTLS_E_INVALID_REQUEST;
2576 result =
2577 asn1_create_element (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2);
2578 if (result != ASN1_SUCCESS)
2580 gnutls_assert ();
2581 return _gnutls_asn2err (result);
2584 result = _gnutls_x509_set_time (c2,
2585 "notBefore",
2586 activation, 1);
2587 if (result < 0)
2589 gnutls_assert();
2590 goto cleanup;
2593 result = _gnutls_x509_set_time (c2,
2594 "notAfter",
2595 expiration, 1);
2596 if (result < 0)
2598 gnutls_assert();
2599 goto cleanup;
2602 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
2603 if (result < 0)
2605 gnutls_assert();
2606 goto cleanup;
2609 result = _gnutls_x509_crq_set_extension (crq, "2.5.29.16",
2610 &der_data, 0);
2612 _gnutls_free_datum(&der_data);
2614 cleanup:
2615 asn1_delete_structure (&c2);
2617 return result;