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>
33 #include <gnutls_x509.h>
39 * gnutls_x509_crq_init:
40 * @crq: The structure to be initialized
42 * This function will initialize a PKCS#10 certificate request
45 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
46 * negative error value.
49 gnutls_x509_crq_init (gnutls_x509_crq_t
* crq
)
53 *crq
= gnutls_calloc (1, sizeof (gnutls_x509_crq_int
));
55 return GNUTLS_E_MEMORY_ERROR
;
57 result
= asn1_create_element (_gnutls_get_pkix (),
58 "PKIX1.pkcs-10-CertificationRequest",
60 if (result
!= ASN1_SUCCESS
)
64 return _gnutls_asn2err (result
);
71 * gnutls_x509_crq_deinit:
72 * @crq: The structure to be initialized
74 * This function will deinitialize a PKCS#10 certificate request
78 gnutls_x509_crq_deinit (gnutls_x509_crq_t crq
)
84 asn1_delete_structure (&crq
->crq
);
89 #define PEM_CRQ "NEW CERTIFICATE REQUEST"
90 #define PEM_CRQ2 "CERTIFICATE REQUEST"
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
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
;
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 */
134 _gnutls_fbase64_decode (PEM_CRQ2
, data
->data
, data
->size
, &_data
);
145 result
= asn1_der_decoding (&crq
->crq
, _data
.data
, _data
.size
, NULL
);
146 if (result
!= ASN1_SUCCESS
)
148 result
= _gnutls_asn2err (result
);
157 _gnutls_free_datum (&_data
);
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
)
179 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
181 size_t buf_size
= sizeof (buf
);
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
);
192 return gnutls_assert_val(ret
);
194 result
= asn1_create_element
195 (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2
);
196 if (result
!= ASN1_SUCCESS
)
199 ret
= _gnutls_asn2err (result
);
203 result
= asn1_der_decoding (&c2
, buf
, buf_size
, NULL
);
204 if (result
!= ASN1_SUCCESS
)
207 ret
= _gnutls_asn2err (result
);
212 *activation
= _gnutls_x509_get_time (c2
,
216 *expiration
= _gnutls_x509_get_time (c2
,
222 asn1_delete_structure (&c2
);
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
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
)
250 return GNUTLS_E_INVALID_REQUEST
;
253 return _gnutls_x509_parse_dn (crq
->crq
,
254 "certificationRequestInfo.subject.rdnSequence",
259 * gnutls_x509_crq_get_dn_by_oid:
260 * @crq: should contain a gnutls_x509_crq_t structure
261 * @oid: holds an Object Identified in null terminated string
262 * @indx: In case multiple same OIDs exist in the RDN, this specifies
263 * which to send. Use (0) to get the first one.
264 * @raw_flag: If non-zero returns the raw DER data of the DN part.
265 * @buf: a pointer to a structure to hold the name (may be %NULL)
266 * @sizeof_buf: initially holds the size of @buf
268 * This function will extract the part of the name of the Certificate
269 * request subject, specified by the given OID. The output will be
270 * encoded as described in RFC2253. The output string will be ASCII
271 * or UTF-8 encoded, depending on the certificate data.
273 * Some helper macros with popular OIDs can be found in gnutls/x509.h
274 * If raw flag is (0), this function will only return known OIDs as
275 * text. Other OIDs will be DER encoded, as described in RFC2253 --
276 * in hex format with a '\#' prefix. You can check about known OIDs
277 * using gnutls_x509_dn_oid_known().
279 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
280 * not long enough, and in that case the *@sizeof_buf will be
281 * updated with the required size. On success 0 is returned.
284 gnutls_x509_crq_get_dn_by_oid (gnutls_x509_crq_t crq
, const char *oid
,
285 int indx
, unsigned int raw_flag
,
286 void *buf
, size_t * sizeof_buf
)
291 return GNUTLS_E_INVALID_REQUEST
;
294 return _gnutls_x509_parse_dn_oid
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
)
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"
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
)
345 char tmpbuffer1
[ASN1_MAX_NAME_SIZE
];
346 char tmpbuffer3
[ASN1_MAX_NAME_SIZE
];
348 char oid
[MAX_OID_SIZE
];
356 /* create a string like "attribute.?1"
358 if (attr_name
[0] != 0)
359 snprintf (tmpbuffer1
, sizeof (tmpbuffer1
), "%s.?%u", attr_name
, k1
);
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
)
372 if (result
!= ASN1_VALUE_NOT_FOUND
)
375 result
= _gnutls_asn2err (result
);
379 /* Move to the attibute type and values
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
)
391 else if (result
!= ASN1_SUCCESS
)
394 result
= _gnutls_asn2err (result
);
398 if (strcmp (oid
, given_oid
) == 0)
399 { /* Found the OID */
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
)
412 result
= _gnutls_asn2err (result
);
418 printable
= _gnutls_x509_oid_data_printable (oid
);
422 _gnutls_x509_oid_data2string
423 (oid
, value
, len
, buf
, sizeof_buf
)) < 0)
433 return GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE
;
438 if (*sizeof_buf
>= (size_t) len
&& buf
!= NULL
)
441 memcpy (buf
, value
, len
);
448 return GNUTLS_E_SHORT_MEMORY_BUFFER
;
458 result
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
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
)
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.
497 add_attribute (ASN1_TYPE asn
, const char *root
, const char *attribute_id
,
498 const gnutls_datum_t
* ext_data
)
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
)
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
)
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
)
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);
544 /* Overwrite the given attribute (using the index)
545 * index here starts from one.
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
];
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);
571 set_attribute (ASN1_TYPE asn
, const char *root
,
572 const char *ext_id
, const gnutls_datum_t
* ext_data
)
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.
586 snprintf (name
, sizeof (name
), "%s.?%u", root
, k
);
588 len
= sizeof (extnID
) - 1;
589 result
= asn1_read_value (asn
, name
, extnID
, &len
);
594 if (result
== ASN1_ELEMENT_NOT_FOUND
)
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
)
613 else if (result
!= ASN1_SUCCESS
)
616 return _gnutls_asn2err (result
);
621 if (strcmp (extnID
, ext_id
) == 0)
623 /* attribute was found
625 return overwrite_attribute (asn
, root
, k
, ext_data
);
634 if (result
== ASN1_ELEMENT_NOT_FOUND
)
636 return add_attribute (asn
, root
, ext_id
, ext_data
);
641 return _gnutls_asn2err (result
);
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
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
,
670 data
.size
= sizeof_buf
;
675 return GNUTLS_E_INVALID_REQUEST
;
678 return set_attribute (crq
->crq
, "certificationRequestInfo.attributes",
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
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
,
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
)
764 unsigned char null
= version
;
769 return GNUTLS_E_INVALID_REQUEST
;
776 asn1_write_value (crq
->crq
, "certificationRequestInfo.version", &null
, 1);
777 if (result
!= ASN1_SUCCESS
)
780 return _gnutls_asn2err (result
);
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
793 * Returns: version of certificate request, or a negative error code on
797 gnutls_x509_crq_get_version (gnutls_x509_crq_t crq
)
805 return GNUTLS_E_INVALID_REQUEST
;
808 len
= sizeof (version
);
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 */
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
)
842 return GNUTLS_E_INVALID_REQUEST
;
845 result
= _gnutls_x509_encode_and_copy_PKI_params
847 "certificationRequestInfo.subjectPKInfo",
848 key
->pk_algorithm
, &key
->params
);
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.
875 gnutls_x509_crq_get_key_rsa_raw (gnutls_x509_crq_t crq
,
876 gnutls_datum_t
* m
, gnutls_datum_t
* e
)
879 gnutls_pk_params_st params
;
881 gnutls_pk_params_init(¶ms
);
886 return GNUTLS_E_INVALID_REQUEST
;
889 ret
= gnutls_x509_crq_get_pk_algorithm (crq
, NULL
);
890 if (ret
!= GNUTLS_PK_RSA
)
893 return GNUTLS_E_INVALID_REQUEST
;
896 ret
= _gnutls_x509_crq_get_mpis (crq
, ¶ms
);
903 ret
= _gnutls_mpi_dprint (params
.params
[0], m
);
910 ret
= _gnutls_mpi_dprint (params
.params
[1], e
);
914 _gnutls_free_datum (m
);
921 gnutls_pk_params_release(¶ms
);
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.
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
)
946 gnutls_pk_params_st temp_params
;
948 gnutls_pk_params_init(&temp_params
);
953 return GNUTLS_E_INVALID_REQUEST
;
956 memset (&temp_params
, 0, sizeof (temp_params
));
959 if (_gnutls_mpi_scan_nz (&temp_params
.params
[0], m
->data
, siz
))
962 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
967 if (_gnutls_mpi_scan_nz (&temp_params
.params
[1], e
->data
, siz
))
970 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
974 temp_params
.params_nr
= RSA_PUBLIC_PARAMS
;
976 result
= _gnutls_x509_encode_and_copy_PKI_params
978 "certificationRequestInfo.subjectPKInfo",
979 GNUTLS_PK_RSA
, &temp_params
);
991 gnutls_pk_params_release(&temp_params
);
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
,
1015 return GNUTLS_E_INVALID_REQUEST
;
1018 /* Add the attribute.
1020 result
= asn1_write_value (crq
->crq
, "certificationRequestInfo.attributes",
1022 if (result
!= ASN1_SUCCESS
)
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);
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
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
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
)
1066 gnutls_privkey_t privkey
;
1071 return GNUTLS_E_INVALID_REQUEST
;
1074 result
= gnutls_privkey_init (&privkey
);
1081 result
= gnutls_privkey_import_x509 (privkey
, key
, 0);
1088 result
= gnutls_x509_crq_privkey_sign (crq
, privkey
, dig
, flags
);
1098 gnutls_privkey_deinit (privkey
);
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
)
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_export2:
1160 * @crq: should contain a #gnutls_x509_crq_t structure
1161 * @format: the format of output params. One of PEM or DER.
1162 * @out: will contain a certificate request PEM or DER encoded
1164 * This function will export the certificate request to a PEM or DER
1165 * encoded PKCS10 structure.
1167 * The output buffer is allocated using gnutls_malloc().
1169 * If the structure is PEM encoded, it will have a header of "BEGIN
1170 * NEW CERTIFICATE REQUEST".
1172 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1173 * negative error value.
1178 gnutls_x509_crq_export2 (gnutls_x509_crq_t crq
,
1179 gnutls_x509_crt_fmt_t format
, gnutls_datum_t
*out
)
1184 return GNUTLS_E_INVALID_REQUEST
;
1187 return _gnutls_x509_export_int2 (crq
->crq
, format
, PEM_CRQ
, out
);
1191 * gnutls_x509_crq_get_pk_algorithm:
1192 * @crq: should contain a #gnutls_x509_crq_t structure
1193 * @bits: if bits is non-%NULL it will hold the size of the parameters' in bits
1195 * This function will return the public key algorithm of a PKCS#10
1196 * certificate request.
1198 * If bits is non-%NULL, it should have enough size to hold the
1199 * parameters size in bits. For RSA the bits returned is the modulus.
1200 * For DSA the bits returned are of the public exponent.
1202 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1203 * success, or a negative error code on error.
1206 gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq
, unsigned int *bits
)
1213 return GNUTLS_E_INVALID_REQUEST
;
1216 result
= _gnutls_x509_get_pk_algorithm
1217 (crq
->crq
, "certificationRequestInfo.subjectPKInfo", bits
);
1227 * gnutls_x509_crq_get_attribute_info:
1228 * @crq: should contain a #gnutls_x509_crq_t structure
1229 * @indx: Specifies which attribute OID to send. Use (0) to get the first one.
1230 * @oid: a pointer to a structure to hold the OID
1231 * @sizeof_oid: initially holds the maximum size of @oid, on return
1232 * holds actual size of @oid.
1234 * This function will return the requested attribute OID in the
1235 * certificate, and the critical flag for it. The attribute OID will
1236 * be stored as a string in the provided buffer. Use
1237 * gnutls_x509_crq_get_attribute_data() to extract the data.
1239 * If the buffer provided is not long enough to hold the output, then
1240 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1243 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1244 * negative error code in case of an error. If your have reached the
1245 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1251 gnutls_x509_crq_get_attribute_info (gnutls_x509_crq_t crq
, int indx
,
1252 void *oid
, size_t * sizeof_oid
)
1255 char name
[ASN1_MAX_NAME_SIZE
];
1261 return GNUTLS_E_INVALID_REQUEST
;
1264 snprintf (name
, sizeof (name
),
1265 "certificationRequestInfo.attributes.?%u.type", indx
+ 1);
1268 result
= asn1_read_value (crq
->crq
, name
, oid
, &len
);
1271 if (result
== ASN1_ELEMENT_NOT_FOUND
)
1272 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1273 else if (result
< 0)
1276 return _gnutls_asn2err (result
);
1284 * gnutls_x509_crq_get_attribute_data:
1285 * @crq: should contain a #gnutls_x509_crq_t structure
1286 * @indx: Specifies which attribute OID to send. Use (0) to get the first one.
1287 * @data: a pointer to a structure to hold the data (may be null)
1288 * @sizeof_data: initially holds the size of @oid
1290 * This function will return the requested attribute data in the
1291 * certificate request. The attribute data will be stored as a string in the
1294 * Use gnutls_x509_crq_get_attribute_info() to extract the OID.
1295 * Use gnutls_x509_crq_get_attribute_by_oid() instead,
1296 * if you want to get data indexed by the attribute OID rather than
1299 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1300 * negative error code in case of an error. If your have reached the
1301 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1307 gnutls_x509_crq_get_attribute_data (gnutls_x509_crq_t crq
, int indx
,
1308 void *data
, size_t * sizeof_data
)
1311 char name
[ASN1_MAX_NAME_SIZE
];
1316 return GNUTLS_E_INVALID_REQUEST
;
1319 snprintf (name
, sizeof (name
),
1320 "certificationRequestInfo.attributes.?%u.values.?1", indx
+ 1);
1323 result
= asn1_read_value (crq
->crq
, name
, data
, &len
);
1326 if (result
== ASN1_ELEMENT_NOT_FOUND
)
1327 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1328 else if (result
< 0)
1331 return _gnutls_asn2err (result
);
1338 * gnutls_x509_crq_get_extension_info:
1339 * @crq: should contain a #gnutls_x509_crq_t structure
1340 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1341 * @oid: a pointer to a structure to hold the OID
1342 * @sizeof_oid: initially holds the maximum size of @oid, on return
1343 * holds actual size of @oid.
1344 * @critical: output variable with critical flag, may be NULL.
1346 * This function will return the requested extension OID in the
1347 * certificate, and the critical flag for it. The extension OID will
1348 * be stored as a string in the provided buffer. Use
1349 * gnutls_x509_crq_get_extension_data() to extract the data.
1351 * If the buffer provided is not long enough to hold the output, then
1352 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1355 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1356 * negative error code in case of an error. If your have reached the
1357 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1363 gnutls_x509_crq_get_extension_info (gnutls_x509_crq_t crq
, int indx
,
1364 void *oid
, size_t * sizeof_oid
,
1365 unsigned int *critical
)
1368 char str_critical
[10];
1369 char name
[ASN1_MAX_NAME_SIZE
];
1370 char *extensions
= NULL
;
1371 size_t extensions_size
= 0;
1378 return GNUTLS_E_INVALID_REQUEST
;
1381 /* read extensionRequest */
1382 result
= gnutls_x509_crq_get_attribute_by_oid (crq
, "1.2.840.113549.1.9.14",
1383 0, NULL
, &extensions_size
);
1384 if (result
== GNUTLS_E_SHORT_MEMORY_BUFFER
)
1386 extensions
= gnutls_malloc (extensions_size
);
1387 if (extensions
== NULL
)
1390 return GNUTLS_E_MEMORY_ERROR
;
1393 result
= gnutls_x509_crq_get_attribute_by_oid (crq
,
1394 "1.2.840.113549.1.9.14",
1404 result
= asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2
);
1405 if (result
!= ASN1_SUCCESS
)
1408 result
= _gnutls_asn2err (result
);
1412 result
= asn1_der_decoding (&c2
, extensions
, extensions_size
, NULL
);
1413 if (result
!= ASN1_SUCCESS
)
1416 asn1_delete_structure (&c2
);
1417 result
= _gnutls_asn2err (result
);
1421 snprintf (name
, sizeof (name
), "?%u.extnID", indx
+ 1);
1424 result
= asn1_read_value (c2
, name
, oid
, &len
);
1427 if (result
== ASN1_ELEMENT_NOT_FOUND
)
1429 asn1_delete_structure (&c2
);
1430 result
= GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1433 else if (result
< 0)
1436 asn1_delete_structure (&c2
);
1437 result
= _gnutls_asn2err (result
);
1441 snprintf (name
, sizeof (name
), "?%u.critical", indx
+ 1);
1442 len
= sizeof (str_critical
);
1443 result
= asn1_read_value (c2
, name
, str_critical
, &len
);
1445 asn1_delete_structure (&c2
);
1450 result
= _gnutls_asn2err (result
);
1456 if (str_critical
[0] == 'T')
1465 gnutls_free (extensions
);
1470 * gnutls_x509_crq_get_extension_data:
1471 * @crq: should contain a #gnutls_x509_crq_t structure
1472 * @indx: Specifies which extension OID to send. Use (0) to get the first one.
1473 * @data: a pointer to a structure to hold the data (may be null)
1474 * @sizeof_data: initially holds the size of @oid
1476 * This function will return the requested extension data in the
1477 * certificate. The extension data will be stored as a string in the
1480 * Use gnutls_x509_crq_get_extension_info() to extract the OID and
1481 * critical flag. Use gnutls_x509_crq_get_extension_by_oid() instead,
1482 * if you want to get data indexed by the extension OID rather than
1485 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1486 * negative error code in case of an error. If your have reached the
1487 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1493 gnutls_x509_crq_get_extension_data (gnutls_x509_crq_t crq
, int indx
,
1494 void *data
, size_t * sizeof_data
)
1497 char name
[ASN1_MAX_NAME_SIZE
];
1498 unsigned char *extensions
;
1499 size_t extensions_size
= 0;
1505 return GNUTLS_E_INVALID_REQUEST
;
1508 /* read extensionRequest */
1509 result
= gnutls_x509_crq_get_attribute_by_oid (crq
, "1.2.840.113549.1.9.14",
1510 0, NULL
, &extensions_size
);
1511 if (result
!= GNUTLS_E_SHORT_MEMORY_BUFFER
)
1515 return GNUTLS_E_INTERNAL_ERROR
;
1519 extensions
= gnutls_malloc (extensions_size
);
1520 if (extensions
== NULL
)
1523 return GNUTLS_E_MEMORY_ERROR
;
1526 result
= gnutls_x509_crq_get_attribute_by_oid (crq
, "1.2.840.113549.1.9.14",
1535 result
= asn1_create_element (_gnutls_get_pkix (), "PKIX1.Extensions", &c2
);
1536 if (result
!= ASN1_SUCCESS
)
1539 gnutls_free (extensions
);
1540 return _gnutls_asn2err (result
);
1543 result
= asn1_der_decoding (&c2
, extensions
, extensions_size
, NULL
);
1544 gnutls_free (extensions
);
1545 if (result
!= ASN1_SUCCESS
)
1548 asn1_delete_structure (&c2
);
1549 return _gnutls_asn2err (result
);
1552 snprintf (name
, sizeof (name
), "?%u.extnValue", indx
+ 1);
1555 result
= asn1_read_value (c2
, name
, data
, &len
);
1558 asn1_delete_structure (&c2
);
1560 if (result
== ASN1_ELEMENT_NOT_FOUND
)
1561 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1562 else if (result
< 0)
1565 return _gnutls_asn2err (result
);
1572 * gnutls_x509_crq_get_key_usage:
1573 * @crq: should contain a #gnutls_x509_crq_t structure
1574 * @key_usage: where the key usage bits will be stored
1575 * @critical: will be non-zero if the extension is marked as critical
1577 * This function will return certificate's key usage, by reading the
1578 * keyUsage X.509 extension (2.5.29.15). The key usage value will
1579 * ORed values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1580 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1581 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1582 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1583 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1585 * Returns: the certificate key usage, or a negative error code in case of
1586 * parsing error. If the certificate does not contain the keyUsage
1587 * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1593 gnutls_x509_crq_get_key_usage (gnutls_x509_crq_t crq
,
1594 unsigned int *key_usage
,
1595 unsigned int *critical
)
1600 size_t buf_size
= sizeof (buf
);
1605 return GNUTLS_E_INVALID_REQUEST
;
1608 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.15", 0,
1609 buf
, &buf_size
, critical
);
1616 result
= _gnutls_x509_ext_extract_keyUsage (&_usage
, buf
, buf_size
);
1618 *key_usage
= _usage
;
1630 * gnutls_x509_crq_get_basic_constraints:
1631 * @crq: should contain a #gnutls_x509_crq_t structure
1632 * @critical: will be non-zero if the extension is marked as critical
1633 * @ca: pointer to output integer indicating CA status, may be NULL,
1634 * value is 1 if the certificate CA flag is set, 0 otherwise.
1635 * @pathlen: pointer to output integer indicating path length (may be
1636 * NULL), non-negative error codes indicate a present pathLenConstraint
1637 * field and the actual value, -1 indicate that the field is absent.
1639 * This function will read the certificate's basic constraints, and
1640 * return the certificates CA status. It reads the basicConstraints
1641 * X.509 extension (2.5.29.19).
1643 * Returns: If the certificate is a CA a positive value will be
1644 * returned, or (0) if the certificate does not have CA flag set.
1645 * A negative error code may be returned in case of errors. If the
1646 * certificate does not contain the basicConstraints extension
1647 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1652 gnutls_x509_crq_get_basic_constraints (gnutls_x509_crq_t crq
,
1653 unsigned int *critical
,
1654 unsigned int *ca
, int *pathlen
)
1657 unsigned int tmp_ca
;
1659 size_t buf_size
= sizeof (buf
);
1664 return GNUTLS_E_INVALID_REQUEST
;
1667 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.19", 0,
1668 buf
, &buf_size
, critical
);
1676 _gnutls_x509_ext_extract_basicConstraints (&tmp_ca
,
1677 pathlen
, buf
, buf_size
);
1691 get_subject_alt_name (gnutls_x509_crq_t crq
,
1692 unsigned int seq
, void *ret
,
1693 size_t * ret_size
, unsigned int *ret_type
,
1694 unsigned int *critical
, int othername_oid
)
1697 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
1698 gnutls_x509_subject_alt_name_t type
;
1699 gnutls_datum_t dnsname
= { NULL
, 0 };
1700 size_t dns_size
= 0;
1705 return GNUTLS_E_INVALID_REQUEST
;
1709 memset (ret
, 0, *ret_size
);
1713 /* Extract extension.
1715 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.17", 0,
1716 NULL
, &dns_size
, critical
);
1723 dnsname
.size
= dns_size
;
1724 dnsname
.data
= gnutls_malloc (dnsname
.size
);
1725 if (dnsname
.data
== NULL
)
1728 return GNUTLS_E_MEMORY_ERROR
;
1731 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.17", 0,
1732 dnsname
.data
, &dns_size
,
1737 gnutls_free (dnsname
.data
);
1741 result
= asn1_create_element
1742 (_gnutls_get_pkix (), "PKIX1.SubjectAltName", &c2
);
1743 if (result
!= ASN1_SUCCESS
)
1746 gnutls_free (dnsname
.data
);
1747 return _gnutls_asn2err (result
);
1750 result
= asn1_der_decoding (&c2
, dnsname
.data
, dnsname
.size
, NULL
);
1751 gnutls_free (dnsname
.data
);
1752 if (result
!= ASN1_SUCCESS
)
1755 asn1_delete_structure (&c2
);
1756 return _gnutls_asn2err (result
);
1759 result
= _gnutls_parse_general_name (c2
, "", seq
, ret
, ret_size
,
1760 ret_type
, othername_oid
);
1761 asn1_delete_structure (&c2
);
1773 * gnutls_x509_crq_get_subject_alt_name:
1774 * @crq: should contain a #gnutls_x509_crq_t structure
1775 * @seq: specifies the sequence number of the alt name, 0 for the
1776 * first one, 1 for the second etc.
1777 * @ret: is the place where the alternative name will be copied to
1778 * @ret_size: holds the size of ret.
1779 * @ret_type: holds the #gnutls_x509_subject_alt_name_t name type
1780 * @critical: will be non-zero if the extension is marked as critical
1783 * This function will return the alternative names, contained in the
1784 * given certificate. It is the same as
1785 * gnutls_x509_crq_get_subject_alt_name() except for the fact that it
1786 * will return the type of the alternative name in @ret_type even if
1787 * the function fails for some reason (i.e. the buffer provided is
1790 * Returns: the alternative subject name type on success, one of the
1791 * enumerated #gnutls_x509_subject_alt_name_t. It will return
1792 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1793 * hold the value. In that case @ret_size will be updated with the
1794 * required size. If the certificate request does not have an
1795 * Alternative name with the specified sequence number then
1796 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1801 gnutls_x509_crq_get_subject_alt_name (gnutls_x509_crq_t crq
,
1802 unsigned int seq
, void *ret
,
1804 unsigned int *ret_type
,
1805 unsigned int *critical
)
1807 return get_subject_alt_name (crq
, seq
, ret
, ret_size
, ret_type
, critical
,
1812 * gnutls_x509_crq_get_subject_alt_othername_oid:
1813 * @crq: should contain a #gnutls_x509_crq_t structure
1814 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1815 * @ret: is the place where the otherName OID will be copied to
1816 * @ret_size: holds the size of ret.
1818 * This function will extract the type OID of an otherName Subject
1819 * Alternative Name, contained in the given certificate, and return
1820 * the type as an enumerated element.
1822 * This function is only useful if
1823 * gnutls_x509_crq_get_subject_alt_name() returned
1824 * %GNUTLS_SAN_OTHERNAME.
1826 * Returns: the alternative subject name type on success, one of the
1827 * enumerated gnutls_x509_subject_alt_name_t. For supported OIDs,
1828 * it will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1829 * e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1830 * unknown OIDs. It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1831 * @ret_size is not large enough to hold the value. In that case
1832 * @ret_size will be updated with the required size. If the
1833 * certificate does not have an Alternative name with the specified
1834 * sequence number and with the otherName type then
1835 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1840 gnutls_x509_crq_get_subject_alt_othername_oid (gnutls_x509_crq_t crq
,
1842 void *ret
, size_t * ret_size
)
1844 return get_subject_alt_name (crq
, seq
, ret
, ret_size
, NULL
, NULL
, 1);
1848 * gnutls_x509_crq_get_extension_by_oid:
1849 * @crq: should contain a #gnutls_x509_crq_t structure
1850 * @oid: holds an Object Identified in null terminated string
1851 * @indx: In case multiple same OIDs exist in the extensions, this
1852 * specifies which to send. Use (0) to get the first one.
1853 * @buf: a pointer to a structure to hold the name (may be null)
1854 * @sizeof_buf: initially holds the size of @buf
1855 * @critical: will be non-zero if the extension is marked as critical
1857 * This function will return the extension specified by the OID in
1858 * the certificate. The extensions will be returned as binary data
1859 * DER encoded, in the provided buffer.
1861 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1862 * negative error code in case of an error. If the certificate does not
1863 * contain the specified extension
1864 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1869 gnutls_x509_crq_get_extension_by_oid (gnutls_x509_crq_t crq
,
1870 const char *oid
, int indx
,
1871 void *buf
, size_t * sizeof_buf
,
1872 unsigned int *critical
)
1876 char _oid
[MAX_OID_SIZE
];
1881 oid_size
= sizeof (_oid
);
1883 gnutls_x509_crq_get_extension_info (crq
, i
, _oid
, &oid_size
,
1891 if (strcmp (oid
, _oid
) == 0)
1894 return gnutls_x509_crq_get_extension_data (crq
, i
, buf
,
1902 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
1907 * gnutls_x509_crq_set_subject_alt_name:
1908 * @crq: a certificate request of type #gnutls_x509_crq_t
1909 * @nt: is one of the #gnutls_x509_subject_alt_name_t enumerations
1910 * @data: The data to be set
1911 * @data_size: The size of data to be set
1912 * @flags: %GNUTLS_FSAN_SET to clear previous data or
1913 * %GNUTLS_FSAN_APPEND to append.
1915 * This function will set the subject alternative name certificate
1916 * extension. It can set the following types:
1918 * %GNUTLS_SAN_DNSNAME: as a text string
1920 * %GNUTLS_SAN_RFC822NAME: as a text string
1922 * %GNUTLS_SAN_URI: as a text string
1924 * %GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
1926 * Other values can be set as binary values with the proper DER encoding.
1928 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1929 * negative error value.
1934 gnutls_x509_crq_set_subject_alt_name (gnutls_x509_crq_t crq
,
1935 gnutls_x509_subject_alt_name_t nt
,
1937 unsigned int data_size
,
1941 gnutls_datum_t der_data
= { NULL
, 0 };
1942 gnutls_datum_t prev_der_data
= { NULL
, 0 };
1943 unsigned int critical
= 0;
1944 size_t prev_data_size
= 0;
1949 return GNUTLS_E_INVALID_REQUEST
;
1952 /* Check if the extension already exists.
1954 if (flags
== GNUTLS_FSAN_APPEND
)
1956 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.17", 0,
1957 NULL
, &prev_data_size
,
1959 prev_der_data
.size
= prev_data_size
;
1963 case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
:
1964 /* Replacing non-existing data means the same as set data. */
1967 case GNUTLS_E_SUCCESS
:
1968 prev_der_data
.data
= gnutls_malloc (prev_der_data
.size
);
1969 if (prev_der_data
.data
== NULL
)
1972 return GNUTLS_E_MEMORY_ERROR
;
1975 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.17", 0,
1982 gnutls_free (prev_der_data
.data
);
1993 /* generate the extension.
1995 result
= _gnutls_x509_ext_gen_subject_alt_name (nt
, data
, data_size
,
1996 &prev_der_data
, &der_data
);
1997 gnutls_free (prev_der_data
.data
);
2004 result
= _gnutls_x509_crq_set_extension (crq
, "2.5.29.17", &der_data
,
2007 _gnutls_free_datum (&der_data
);
2022 * gnutls_x509_crq_set_basic_constraints:
2023 * @crq: a certificate request of type #gnutls_x509_crq_t
2024 * @ca: true(1) or false(0) depending on the Certificate authority status.
2025 * @pathLenConstraint: non-negative error codes indicate maximum length of path,
2026 * and negative error codes indicate that the pathLenConstraints field should
2029 * This function will set the basicConstraints certificate extension.
2031 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2032 * negative error value.
2037 gnutls_x509_crq_set_basic_constraints (gnutls_x509_crq_t crq
,
2038 unsigned int ca
, int pathLenConstraint
)
2041 gnutls_datum_t der_data
;
2046 return GNUTLS_E_INVALID_REQUEST
;
2049 /* generate the extension.
2051 result
= _gnutls_x509_ext_gen_basicConstraints (ca
, pathLenConstraint
,
2059 result
= _gnutls_x509_crq_set_extension (crq
, "2.5.29.19", &der_data
, 1);
2061 _gnutls_free_datum (&der_data
);
2073 * gnutls_x509_crq_set_key_usage:
2074 * @crq: a certificate request of type #gnutls_x509_crq_t
2075 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
2077 * This function will set the keyUsage certificate extension.
2079 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2080 * negative error value.
2085 gnutls_x509_crq_set_key_usage (gnutls_x509_crq_t crq
, unsigned int usage
)
2088 gnutls_datum_t der_data
;
2093 return GNUTLS_E_INVALID_REQUEST
;
2096 /* generate the extension.
2098 result
= _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage
, &der_data
);
2105 result
= _gnutls_x509_crq_set_extension (crq
, "2.5.29.15", &der_data
, 1);
2107 _gnutls_free_datum (&der_data
);
2119 * gnutls_x509_crq_get_key_purpose_oid:
2120 * @crq: should contain a #gnutls_x509_crq_t structure
2121 * @indx: This specifies which OID to return, use (0) to get the first one
2122 * @oid: a pointer to a buffer to hold the OID (may be %NULL)
2123 * @sizeof_oid: initially holds the size of @oid
2124 * @critical: output variable with critical flag, may be %NULL.
2126 * This function will extract the key purpose OIDs of the Certificate
2127 * specified by the given index. These are stored in the Extended Key
2128 * Usage extension (2.5.29.37). See the GNUTLS_KP_* definitions for
2129 * human readable names.
2131 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2132 * not long enough, and in that case the *@sizeof_oid will be
2133 * updated with the required size. On success 0 is returned.
2138 gnutls_x509_crq_get_key_purpose_oid (gnutls_x509_crq_t crq
,
2139 int indx
, void *oid
, size_t * sizeof_oid
,
2140 unsigned int *critical
)
2142 char tmpstr
[ASN1_MAX_NAME_SIZE
];
2144 gnutls_datum_t prev
= { NULL
, 0 };
2145 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
2146 size_t prev_size
= 0;
2149 memset (oid
, 0, *sizeof_oid
);
2153 /* Extract extension.
2155 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.37", 0,
2156 NULL
, &prev_size
, critical
);
2157 prev
.size
= prev_size
;
2165 prev
.data
= gnutls_malloc (prev
.size
);
2166 if (prev
.data
== NULL
)
2169 return GNUTLS_E_MEMORY_ERROR
;
2172 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.37", 0,
2173 prev
.data
, &prev_size
,
2178 gnutls_free (prev
.data
);
2182 result
= asn1_create_element
2183 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2
);
2184 if (result
!= ASN1_SUCCESS
)
2187 gnutls_free (prev
.data
);
2188 return _gnutls_asn2err (result
);
2191 result
= asn1_der_decoding (&c2
, prev
.data
, prev
.size
, NULL
);
2192 gnutls_free (prev
.data
);
2193 if (result
!= ASN1_SUCCESS
)
2196 asn1_delete_structure (&c2
);
2197 return _gnutls_asn2err (result
);
2201 /* create a string like "?1"
2203 snprintf (tmpstr
, sizeof (tmpstr
), "?%u", indx
);
2206 result
= asn1_read_value (c2
, tmpstr
, oid
, &len
);
2209 asn1_delete_structure (&c2
);
2211 if (result
== ASN1_VALUE_NOT_FOUND
|| result
== ASN1_ELEMENT_NOT_FOUND
)
2213 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
;
2216 if (result
!= ASN1_SUCCESS
)
2218 if (result
!= ASN1_MEM_ERROR
)
2220 return _gnutls_asn2err (result
);
2227 * gnutls_x509_crq_set_key_purpose_oid:
2228 * @crq: a certificate of type #gnutls_x509_crq_t
2229 * @oid: a pointer to a (0)-terminated string that holds the OID
2230 * @critical: Whether this extension will be critical or not
2232 * This function will set the key purpose OIDs of the Certificate.
2233 * These are stored in the Extended Key Usage extension (2.5.29.37)
2234 * See the GNUTLS_KP_* definitions for human readable names.
2236 * Subsequent calls to this function will append OIDs to the OID list.
2238 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2239 * negative error value.
2244 gnutls_x509_crq_set_key_purpose_oid (gnutls_x509_crq_t crq
,
2245 const void *oid
, unsigned int critical
)
2248 gnutls_datum_t prev
= { NULL
, 0 }, der_data
;
2249 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
2250 size_t prev_size
= 0;
2252 /* Read existing extension, if there is one.
2254 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.37", 0,
2255 NULL
, &prev_size
, &critical
);
2256 prev
.size
= prev_size
;
2260 case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
:
2261 /* No existing extension, that's fine. */
2264 case GNUTLS_E_SUCCESS
:
2265 prev
.data
= gnutls_malloc (prev
.size
);
2266 if (prev
.data
== NULL
)
2269 return GNUTLS_E_MEMORY_ERROR
;
2272 result
= gnutls_x509_crq_get_extension_by_oid (crq
, "2.5.29.37", 0,
2273 prev
.data
, &prev_size
,
2278 gnutls_free (prev
.data
);
2288 result
= asn1_create_element (_gnutls_get_pkix (),
2289 "PKIX1.ExtKeyUsageSyntax", &c2
);
2290 if (result
!= ASN1_SUCCESS
)
2293 gnutls_free (prev
.data
);
2294 return _gnutls_asn2err (result
);
2301 result
= asn1_der_decoding (&c2
, prev
.data
, prev
.size
, NULL
);
2302 gnutls_free (prev
.data
);
2303 if (result
!= ASN1_SUCCESS
)
2306 asn1_delete_structure (&c2
);
2307 return _gnutls_asn2err (result
);
2311 /* generate the extension.
2313 /* 1. create a new element.
2315 result
= asn1_write_value (c2
, "", "NEW", 1);
2316 if (result
!= ASN1_SUCCESS
)
2319 asn1_delete_structure (&c2
);
2320 return _gnutls_asn2err (result
);
2325 result
= asn1_write_value (c2
, "?LAST", oid
, 1);
2326 if (result
!= ASN1_SUCCESS
)
2329 asn1_delete_structure (&c2
);
2330 return _gnutls_asn2err (result
);
2333 result
= _gnutls_x509_der_encode (c2
, "", &der_data
, 0);
2334 asn1_delete_structure (&c2
);
2336 if (result
!= ASN1_SUCCESS
)
2339 return _gnutls_asn2err (result
);
2342 result
= _gnutls_x509_crq_set_extension (crq
, "2.5.29.37",
2343 &der_data
, critical
);
2344 _gnutls_free_datum (&der_data
);
2355 * gnutls_x509_crq_get_key_id:
2356 * @crq: a certificate of type #gnutls_x509_crq_t
2357 * @flags: should be 0 for now
2358 * @output_data: will contain the key ID
2359 * @output_data_size: holds the size of output_data (and will be
2360 * replaced by the actual size of parameters)
2362 * This function will return a unique ID that depends on the public key
2363 * parameters. This ID can be used in checking whether a certificate
2364 * corresponds to the given private key.
2366 * If the buffer provided is not long enough to hold the output, then
2367 * *@output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2368 * be returned. The output will normally be a SHA-1 hash output,
2369 * which is 20 bytes.
2371 * Returns: In case of failure a negative error code will be
2372 * returned, and 0 on success.
2377 gnutls_x509_crq_get_key_id (gnutls_x509_crq_t crq
, unsigned int flags
,
2378 unsigned char *output_data
,
2379 size_t * output_data_size
)
2382 gnutls_pk_params_st params
;
2387 return GNUTLS_E_INVALID_REQUEST
;
2390 pk
= gnutls_x509_crq_get_pk_algorithm (crq
, NULL
);
2397 ret
= _gnutls_x509_crq_get_mpis (crq
, ¶ms
);
2404 ret
= _gnutls_get_key_id(pk
, ¶ms
, output_data
, output_data_size
);
2406 gnutls_pk_params_release(¶ms
);
2412 * gnutls_x509_crq_privkey_sign:
2413 * @crq: should contain a #gnutls_x509_crq_t structure
2414 * @key: holds a private key
2415 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
2418 * This function will sign the certificate request with a private key.
2419 * This must be the same key as the one used in
2420 * gnutls_x509_crt_set_key() since a certificate request is self
2423 * This must be the last step in a certificate request generation
2424 * since all the previously set parameters are now signed.
2426 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2427 * %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
2428 * information in the certificate request (e.g., the version using
2429 * gnutls_x509_crq_set_version()).
2434 gnutls_x509_crq_privkey_sign (gnutls_x509_crq_t crq
, gnutls_privkey_t key
,
2435 gnutls_digest_algorithm_t dig
,
2439 gnutls_datum_t signature
;
2445 return GNUTLS_E_INVALID_REQUEST
;
2448 /* Make sure version field is set. */
2449 if (gnutls_x509_crq_get_version (crq
) == GNUTLS_E_ASN1_VALUE_NOT_FOUND
)
2451 result
= gnutls_x509_crq_set_version (crq
, 1);
2459 /* Step 1. Self sign the request.
2461 result
= _gnutls_x509_get_tbs (crq
->crq
, "certificationRequestInfo", &tbs
);
2469 result
= gnutls_privkey_sign_data (key
, dig
, 0, &tbs
, &signature
);
2470 gnutls_free (tbs
.data
);
2478 /* Step 2. write the signature (bits)
2481 asn1_write_value (crq
->crq
, "signature", signature
.data
,
2482 signature
.size
* 8);
2484 _gnutls_free_datum (&signature
);
2486 if (result
!= ASN1_SUCCESS
)
2489 return _gnutls_asn2err (result
);
2492 /* Step 3. Write the signatureAlgorithm field.
2494 result
= _gnutls_x509_write_sig_params (crq
->crq
, "signatureAlgorithm",
2495 gnutls_privkey_get_pk_algorithm
2508 * gnutls_x509_crq_verify:
2509 * @crq: is the crq to be verified
2510 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
2512 * This function will verify self signature in the certificate
2513 * request and return its status.
2515 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED
2516 * is returned, and zero or positive code on success.
2521 gnutls_x509_crq_verify (gnutls_x509_crq_t crq
,
2524 gnutls_datum data
= { NULL
, 0 };
2525 gnutls_datum signature
= { NULL
, 0 };
2526 gnutls_pk_params_st params
;
2527 gnutls_digest_algorithm_t algo
;
2530 gnutls_pk_params_init(¶ms
);
2533 _gnutls_x509_get_signed_data (crq
->crq
, "certificationRequestInfo", &data
);
2540 ret
= _gnutls_x509_get_signature_algorithm(crq
->crq
, "signatureAlgorithm.algorithm");
2547 algo
= gnutls_sign_get_hash_algorithm(ret
);
2549 ret
= _gnutls_x509_get_signature (crq
->crq
, "signature", &signature
);
2557 _gnutls_x509_crq_get_mpis(crq
, ¶ms
);
2564 ret
= pubkey_verify_data(gnutls_x509_crq_get_pk_algorithm (crq
, NULL
), algo
,
2565 &data
, &signature
, ¶ms
);
2575 _gnutls_free_datum (&data
);
2576 _gnutls_free_datum (&signature
);
2577 gnutls_pk_params_release(¶ms
);
2583 * gnutls_x509_crq_set_private_key_usage_period:
2584 * @crq: a certificate of type #gnutls_x509_crq_t
2585 * @activation: The activation time
2586 * @expiration: The expiration time
2588 * This function will set the private key usage period extension (2.5.29.16).
2590 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2591 * negative error value.
2594 gnutls_x509_crq_set_private_key_usage_period (gnutls_x509_crq_t crq
,
2599 gnutls_datum_t der_data
;
2600 ASN1_TYPE c2
= ASN1_TYPE_EMPTY
;
2605 return GNUTLS_E_INVALID_REQUEST
;
2609 asn1_create_element (_gnutls_get_pkix (), "PKIX1.PrivateKeyUsagePeriod", &c2
);
2610 if (result
!= ASN1_SUCCESS
)
2613 return _gnutls_asn2err (result
);
2616 result
= _gnutls_x509_set_time (c2
,
2625 result
= _gnutls_x509_set_time (c2
,
2634 result
= _gnutls_x509_der_encode (c2
, "", &der_data
, 0);
2641 result
= _gnutls_x509_crq_set_extension (crq
, "2.5.29.16",
2644 _gnutls_free_datum(&der_data
);
2647 asn1_delete_structure (&c2
);