diff options
Diffstat (limited to 'src/daemon/https/x509/crq.c')
-rw-r--r-- | src/daemon/https/x509/crq.c | 898 |
1 files changed, 0 insertions, 898 deletions
diff --git a/src/daemon/https/x509/crq.c b/src/daemon/https/x509/crq.c deleted file mode 100644 index 88ac349d..00000000 --- a/src/daemon/https/x509/crq.c +++ /dev/null | |||
@@ -1,898 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2003, 2004, 2005 Free Software Foundation | ||
3 | * | ||
4 | * Author: Nikos Mavrogiannopoulos | ||
5 | * | ||
6 | * This file is part of GNUTLS. | ||
7 | * | ||
8 | * The GNUTLS library 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 2.1 of | ||
11 | * the License, or (at your option) any later version. | ||
12 | * | ||
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. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public | ||
19 | * License along with this library; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | ||
21 | * USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | /* This file contains functions to handle PKCS #10 certificate requests. | ||
26 | */ | ||
27 | |||
28 | #include <gnutls_int.h> | ||
29 | |||
30 | #ifdef ENABLE_PKI | ||
31 | |||
32 | #include <gnutls_datum.h> | ||
33 | #include <gnutls_global.h> | ||
34 | #include <gnutls_errors.h> | ||
35 | #include <common.h> | ||
36 | #include <gnutls_x509.h> | ||
37 | #include <x509_b64.h> | ||
38 | #include <crq.h> | ||
39 | #include <dn.h> | ||
40 | #include <mpi.h> | ||
41 | #include <sign.h> | ||
42 | #include <extensions.h> | ||
43 | #include <libtasn1.h> | ||
44 | |||
45 | /** | ||
46 | * MHD_gnutls_x509_crq_init - This function initializes a MHD_gnutls_x509_crq_t structure | ||
47 | * @crq: The structure to be initialized | ||
48 | * | ||
49 | * This function will initialize a PKCS10 certificate request structure. | ||
50 | * | ||
51 | * Returns 0 on success. | ||
52 | * | ||
53 | **/ | ||
54 | int | ||
55 | MHD_gnutls_x509_crq_init (MHD_gnutls_x509_crq_t * crq) | ||
56 | { | ||
57 | *crq = MHD_gnutls_calloc (1, sizeof (MHD_gnutls_x509_crq_int)); | ||
58 | |||
59 | if (*crq) | ||
60 | { | ||
61 | int result = MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
62 | "PKIX1.pkcs-10-CertificationRequest", | ||
63 | &((*crq)->crq)); | ||
64 | if (result != ASN1_SUCCESS) | ||
65 | { | ||
66 | MHD_gnutls_assert (); | ||
67 | MHD_gnutls_free (*crq); | ||
68 | return MHD_gtls_asn2err (result); | ||
69 | } | ||
70 | return 0; /* success */ | ||
71 | } | ||
72 | return GNUTLS_E_MEMORY_ERROR; | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * MHD_gnutls_x509_crq_deinit - This function deinitializes memory used by a MHD_gnutls_x509_crq_t structure | ||
77 | * @crq: The structure to be initialized | ||
78 | * | ||
79 | * This function will deinitialize a CRL structure. | ||
80 | * | ||
81 | **/ | ||
82 | void | ||
83 | MHD_gnutls_x509_crq_deinit (MHD_gnutls_x509_crq_t crq) | ||
84 | { | ||
85 | if (!crq) | ||
86 | return; | ||
87 | |||
88 | if (crq->crq) | ||
89 | MHD__asn1_delete_structure (&crq->crq); | ||
90 | |||
91 | MHD_gnutls_free (crq); | ||
92 | } | ||
93 | |||
94 | #define PEM_CRQ "NEW CERTIFICATE REQUEST" | ||
95 | #define PEM_CRQ2 "CERTIFICATE REQUEST" | ||
96 | |||
97 | /** | ||
98 | * MHD_gnutls_x509_crq_import - This function will import a DER or PEM encoded Certificate request | ||
99 | * @crq: The structure to store the parsed certificate request. | ||
100 | * @data: The DER or PEM encoded certificate. | ||
101 | * @format: One of DER or PEM | ||
102 | * | ||
103 | * This function will convert the given DER or PEM encoded Certificate | ||
104 | * to the native MHD_gnutls_x509_crq_t format. The output will be stored in @cert. | ||
105 | * | ||
106 | * If the Certificate is PEM encoded it should have a header of "NEW CERTIFICATE REQUEST". | ||
107 | * | ||
108 | * Returns 0 on success. | ||
109 | * | ||
110 | **/ | ||
111 | int | ||
112 | MHD_gnutls_x509_crq_import (MHD_gnutls_x509_crq_t crq, | ||
113 | const MHD_gnutls_datum_t * data, | ||
114 | MHD_gnutls_x509_crt_fmt_t format) | ||
115 | { | ||
116 | int result = 0, need_free = 0; | ||
117 | MHD_gnutls_datum_t _data; | ||
118 | |||
119 | if (crq == NULL) | ||
120 | { | ||
121 | MHD_gnutls_assert (); | ||
122 | return GNUTLS_E_INVALID_REQUEST; | ||
123 | } | ||
124 | |||
125 | _data.data = data->data; | ||
126 | _data.size = data->size; | ||
127 | |||
128 | /* If the Certificate is in PEM format then decode it | ||
129 | */ | ||
130 | if (format == GNUTLS_X509_FMT_PEM) | ||
131 | { | ||
132 | opaque *out; | ||
133 | |||
134 | /* Try the first header */ | ||
135 | result = | ||
136 | MHD__gnutls_fbase64_decode (PEM_CRQ, data->data, data->size, &out); | ||
137 | |||
138 | if (result <= 0) /* Go for the second header */ | ||
139 | result = | ||
140 | MHD__gnutls_fbase64_decode (PEM_CRQ2, data->data, data->size, &out); | ||
141 | |||
142 | if (result <= 0) | ||
143 | { | ||
144 | if (result == 0) | ||
145 | result = GNUTLS_E_INTERNAL_ERROR; | ||
146 | MHD_gnutls_assert (); | ||
147 | return result; | ||
148 | } | ||
149 | |||
150 | _data.data = out; | ||
151 | _data.size = result; | ||
152 | |||
153 | need_free = 1; | ||
154 | } | ||
155 | |||
156 | result = MHD__asn1_der_decoding (&crq->crq, _data.data, _data.size, NULL); | ||
157 | if (result != ASN1_SUCCESS) | ||
158 | { | ||
159 | result = MHD_gtls_asn2err (result); | ||
160 | MHD_gnutls_assert (); | ||
161 | goto cleanup; | ||
162 | } | ||
163 | |||
164 | result = 0; | ||
165 | |||
166 | cleanup: | ||
167 | if (need_free) | ||
168 | MHD__gnutls_free_datum (&_data); | ||
169 | return result; | ||
170 | } | ||
171 | |||
172 | |||
173 | |||
174 | /** | ||
175 | * MHD_gnutls_x509_crq_get_dn - This function returns the Certificate request subject's distinguished name | ||
176 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
177 | * @buf: a pointer to a structure to hold the name (may be null) | ||
178 | * @sizeof_buf: initially holds the size of @buf | ||
179 | * | ||
180 | * This function will copy the name of the Certificate request | ||
181 | * subject in the provided buffer. The name will be in the form | ||
182 | * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string | ||
183 | * will be ASCII or UTF-8 encoded, depending on the certificate data. | ||
184 | * | ||
185 | * If @buf is null then only the size will be filled. | ||
186 | * | ||
187 | * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not | ||
188 | * long enough, and in that case the *sizeof_buf will be updated with | ||
189 | * the required size. On success 0 is returned. | ||
190 | * | ||
191 | **/ | ||
192 | int | ||
193 | MHD_gnutls_x509_crq_get_dn (MHD_gnutls_x509_crq_t crq, char *buf, | ||
194 | size_t * sizeof_buf) | ||
195 | { | ||
196 | if (crq == NULL) | ||
197 | { | ||
198 | MHD_gnutls_assert (); | ||
199 | return GNUTLS_E_INVALID_REQUEST; | ||
200 | } | ||
201 | |||
202 | return MHD__gnutls_x509_parse_dn (crq->crq, | ||
203 | "certificationRequestInfo.subject.rdnSequence", | ||
204 | buf, sizeof_buf); | ||
205 | } | ||
206 | |||
207 | /** | ||
208 | * MHD_gnutls_x509_crq_get_dn_by_oid - This function returns the Certificate request subject's distinguished name | ||
209 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
210 | * @oid: holds an Object Identified in null terminated string | ||
211 | * @indx: In case multiple same OIDs exist in the RDN, this specifies | ||
212 | * which to send. Use zero to get the first one. | ||
213 | * @raw_flag: If non zero returns the raw DER data of the DN part. | ||
214 | * @buf: a pointer to a structure to hold the name (may be null) | ||
215 | * @sizeof_buf: initially holds the size of @buf | ||
216 | * | ||
217 | * This function will extract the part of the name of the Certificate | ||
218 | * request subject, specified by the given OID. The output will be | ||
219 | * encoded as described in RFC2253. The output string will be ASCII | ||
220 | * or UTF-8 encoded, depending on the certificate data. | ||
221 | * | ||
222 | * Some helper macros with popular OIDs can be found in gnutls/x509.h | ||
223 | * If raw flag is zero, this function will only return known OIDs as | ||
224 | * text. Other OIDs will be DER encoded, as described in RFC2253 -- | ||
225 | * in hex format with a '\#' prefix. You can check about known OIDs | ||
226 | * using MHD_gnutls_x509_dn_oid_known(). | ||
227 | * | ||
228 | * If @buf is null then only the size will be filled. | ||
229 | * | ||
230 | * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not | ||
231 | * long enough, and in that case the *sizeof_buf will be updated with | ||
232 | * the required size. On success 0 is returned. | ||
233 | * | ||
234 | **/ | ||
235 | int | ||
236 | MHD_gnutls_x509_crq_get_dn_by_oid (MHD_gnutls_x509_crq_t crq, const char *oid, | ||
237 | int indx, unsigned int raw_flag, | ||
238 | void *buf, size_t * sizeof_buf) | ||
239 | { | ||
240 | if (crq == NULL) | ||
241 | { | ||
242 | MHD_gnutls_assert (); | ||
243 | return GNUTLS_E_INVALID_REQUEST; | ||
244 | } | ||
245 | |||
246 | return MHD__gnutls_x509_parse_dn_oid (crq->crq, | ||
247 | "certificationRequestInfo.subject.rdnSequence", | ||
248 | oid, indx, raw_flag, buf, sizeof_buf); | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * MHD_gnutls_x509_crq_get_dn_oid - This function returns the Certificate request subject's distinguished name OIDs | ||
253 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
254 | * @indx: Specifies which DN OID to send. Use zero to get the first one. | ||
255 | * @oid: a pointer to a structure to hold the name (may be null) | ||
256 | * @sizeof_oid: initially holds the size of @oid | ||
257 | * | ||
258 | * This function will extract the requested OID of the name of the | ||
259 | * Certificate request subject, specified by the given index. | ||
260 | * | ||
261 | * If oid is null then only the size will be filled. | ||
262 | * | ||
263 | * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not | ||
264 | * long enough, and in that case the *sizeof_oid will be updated with | ||
265 | * the required size. On success 0 is returned. | ||
266 | * | ||
267 | **/ | ||
268 | int | ||
269 | MHD_gnutls_x509_crq_get_dn_oid (MHD_gnutls_x509_crq_t crq, | ||
270 | int indx, void *oid, size_t * sizeof_oid) | ||
271 | { | ||
272 | if (crq == NULL) | ||
273 | { | ||
274 | MHD_gnutls_assert (); | ||
275 | return GNUTLS_E_INVALID_REQUEST; | ||
276 | } | ||
277 | |||
278 | return MHD__gnutls_x509_get_dn_oid (crq->crq, | ||
279 | "certificationRequestInfo.subject.rdnSequence", | ||
280 | indx, oid, sizeof_oid); | ||
281 | } | ||
282 | |||
283 | /* Parses an Attribute list in the MHD__asn1_struct, and searches for the | ||
284 | * given OID. The index indicates the attribute value to be returned. | ||
285 | * | ||
286 | * If raw==0 only printable data are returned, or GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE. | ||
287 | * | ||
288 | * MHD__asn1_attr_name must be a string in the form "certificationRequestInfo.attributes" | ||
289 | * | ||
290 | */ | ||
291 | static int | ||
292 | parse_attribute (ASN1_TYPE MHD__asn1_struct, | ||
293 | const char *attr_name, const char *given_oid, int indx, | ||
294 | int raw, char *buf, size_t * sizeof_buf) | ||
295 | { | ||
296 | int k1, result; | ||
297 | char tmpbuffer1[MAX_NAME_SIZE]; | ||
298 | char tmpbuffer3[MAX_NAME_SIZE]; | ||
299 | char value[200]; | ||
300 | char oid[128]; | ||
301 | int len, printable; | ||
302 | |||
303 | if (*sizeof_buf == 0) | ||
304 | { | ||
305 | MHD_gnutls_assert (); | ||
306 | return GNUTLS_E_INVALID_REQUEST; | ||
307 | } | ||
308 | |||
309 | buf[0] = 0; | ||
310 | |||
311 | k1 = 0; | ||
312 | do | ||
313 | { | ||
314 | |||
315 | k1++; | ||
316 | /* create a string like "attribute.?1" | ||
317 | */ | ||
318 | if (attr_name[0] != 0) | ||
319 | snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", attr_name, k1); | ||
320 | else | ||
321 | snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1); | ||
322 | |||
323 | len = sizeof (value) - 1; | ||
324 | result = | ||
325 | MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer1, value, &len); | ||
326 | |||
327 | if (result == ASN1_ELEMENT_NOT_FOUND) | ||
328 | { | ||
329 | MHD_gnutls_assert (); | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | if (result != ASN1_VALUE_NOT_FOUND) | ||
334 | { | ||
335 | MHD_gnutls_assert (); | ||
336 | result = MHD_gtls_asn2err (result); | ||
337 | goto cleanup; | ||
338 | } | ||
339 | |||
340 | /* Move to the attibute type and values | ||
341 | */ | ||
342 | /* Read the OID | ||
343 | */ | ||
344 | MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer1); | ||
345 | MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type"); | ||
346 | |||
347 | len = sizeof (oid) - 1; | ||
348 | result = MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, oid, &len); | ||
349 | |||
350 | if (result == ASN1_ELEMENT_NOT_FOUND) | ||
351 | break; | ||
352 | else if (result != ASN1_SUCCESS) | ||
353 | { | ||
354 | MHD_gnutls_assert (); | ||
355 | result = MHD_gtls_asn2err (result); | ||
356 | goto cleanup; | ||
357 | } | ||
358 | |||
359 | if (strcmp (oid, given_oid) == 0) | ||
360 | { /* Found the OID */ | ||
361 | |||
362 | /* Read the Value | ||
363 | */ | ||
364 | snprintf (tmpbuffer3, sizeof (tmpbuffer3), "%s.values.?%u", | ||
365 | tmpbuffer1, indx + 1); | ||
366 | |||
367 | len = sizeof (value) - 1; | ||
368 | result = | ||
369 | MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, value, &len); | ||
370 | |||
371 | if (result != ASN1_SUCCESS) | ||
372 | { | ||
373 | MHD_gnutls_assert (); | ||
374 | result = MHD_gtls_asn2err (result); | ||
375 | goto cleanup; | ||
376 | } | ||
377 | |||
378 | if (raw == 0) | ||
379 | { | ||
380 | printable = MHD__gnutls_x509_oid_data_printable (oid); | ||
381 | if (printable == 1) | ||
382 | { | ||
383 | if ((result = | ||
384 | MHD__gnutls_x509_oid_data2string | ||
385 | (oid, value, len, buf, sizeof_buf)) < 0) | ||
386 | { | ||
387 | MHD_gnutls_assert (); | ||
388 | goto cleanup; | ||
389 | } | ||
390 | return 0; | ||
391 | } | ||
392 | else | ||
393 | { | ||
394 | MHD_gnutls_assert (); | ||
395 | return GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE; | ||
396 | } | ||
397 | } | ||
398 | else | ||
399 | { /* raw!=0 */ | ||
400 | if (*sizeof_buf > (size_t) len) | ||
401 | { | ||
402 | *sizeof_buf = len; | ||
403 | memcpy (buf, value, len); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | else | ||
408 | { | ||
409 | *sizeof_buf = len; | ||
410 | MHD_gnutls_assert (); | ||
411 | return GNUTLS_E_SHORT_MEMORY_BUFFER; | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | |||
416 | } | ||
417 | while (1); | ||
418 | |||
419 | MHD_gnutls_assert (); | ||
420 | |||
421 | result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; | ||
422 | |||
423 | cleanup: | ||
424 | return result; | ||
425 | } | ||
426 | |||
427 | /** | ||
428 | * MHD_gnutls_x509_crq_get_challenge_password - This function will get the challenge password | ||
429 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
430 | * @pass: will hold a null terminated password | ||
431 | * @sizeof_pass: Initially holds the size of @pass. | ||
432 | * | ||
433 | * This function will return the challenge password in the | ||
434 | * request. | ||
435 | * | ||
436 | * Returns 0 on success. | ||
437 | * | ||
438 | **/ | ||
439 | int | ||
440 | MHD_gnutls_x509_crq_get_challenge_password (MHD_gnutls_x509_crq_t crq, | ||
441 | char *pass, size_t * sizeof_pass) | ||
442 | { | ||
443 | if (crq == NULL) | ||
444 | { | ||
445 | MHD_gnutls_assert (); | ||
446 | return GNUTLS_E_INVALID_REQUEST; | ||
447 | } | ||
448 | |||
449 | return parse_attribute (crq->crq, "certificationRequestInfo.attributes", | ||
450 | "1.2.840.113549.1.9.7", 0, 0, pass, sizeof_pass); | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * MHD_gnutls_x509_crq_set_attribute_by_oid - This function will set an attribute in the request | ||
455 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
456 | * @oid: holds an Object Identified in null terminated string | ||
457 | * @buf: a pointer to a structure that holds the attribute data | ||
458 | * @sizeof_buf: holds the size of @buf | ||
459 | * | ||
460 | * This function will set the attribute in the certificate request specified | ||
461 | * by the given Object ID. The attribute must be be DER encoded. | ||
462 | * | ||
463 | * Returns 0 on success. | ||
464 | * | ||
465 | **/ | ||
466 | int | ||
467 | MHD_gnutls_x509_crq_set_attribute_by_oid (MHD_gnutls_x509_crq_t crq, | ||
468 | const char *oid, void *buf, | ||
469 | size_t sizeof_buf) | ||
470 | { | ||
471 | int result; | ||
472 | |||
473 | if (crq == NULL) | ||
474 | { | ||
475 | MHD_gnutls_assert (); | ||
476 | return GNUTLS_E_INVALID_REQUEST; | ||
477 | } | ||
478 | |||
479 | /* Add the attribute. | ||
480 | */ | ||
481 | result = | ||
482 | MHD__asn1_write_value (crq->crq, "certificationRequestInfo.attributes", | ||
483 | "NEW", 1); | ||
484 | if (result != ASN1_SUCCESS) | ||
485 | { | ||
486 | MHD_gnutls_assert (); | ||
487 | return MHD_gtls_asn2err (result); | ||
488 | } | ||
489 | |||
490 | result = | ||
491 | MHD__gnutls_x509_encode_and_write_attribute (oid, | ||
492 | crq->crq, | ||
493 | "certificationRequestInfo.attributes.?LAST", | ||
494 | buf, sizeof_buf, 1); | ||
495 | |||
496 | if (result < 0) | ||
497 | { | ||
498 | MHD_gnutls_assert (); | ||
499 | return result; | ||
500 | } | ||
501 | |||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | /** | ||
506 | * MHD_gnutls_x509_crq_get_attribute_by_oid - This function will get an attribute of the request | ||
507 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
508 | * @oid: holds an Object Identified in null terminated string | ||
509 | * @indx: In case multiple same OIDs exist in the attribute list, this specifies | ||
510 | * which to send. Use zero to get the first one. | ||
511 | * @buf: a pointer to a structure to hold the attribute data (may be null) | ||
512 | * @sizeof_buf: initially holds the size of @buf | ||
513 | * | ||
514 | * This function will return the attribute in the certificate request specified | ||
515 | * by the given Object ID. The attribute will be DER encoded. | ||
516 | * | ||
517 | * Returns 0 on success. | ||
518 | * | ||
519 | **/ | ||
520 | int | ||
521 | MHD_gnutls_x509_crq_get_attribute_by_oid (MHD_gnutls_x509_crq_t crq, | ||
522 | const char *oid, int indx, | ||
523 | void *buf, size_t * sizeof_buf) | ||
524 | { | ||
525 | if (crq == NULL) | ||
526 | { | ||
527 | MHD_gnutls_assert (); | ||
528 | return GNUTLS_E_INVALID_REQUEST; | ||
529 | } | ||
530 | |||
531 | return parse_attribute (crq->crq, "certificationRequestInfo.attributes", | ||
532 | oid, indx, 1, buf, sizeof_buf); | ||
533 | } | ||
534 | |||
535 | /** | ||
536 | * MHD_gnutls_x509_crq_set_dn_by_oid - This function will set the Certificate request subject's distinguished name | ||
537 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
538 | * @oid: holds an Object Identifier in a null terminated string | ||
539 | * @raw_flag: must be 0, or 1 if the data are DER encoded | ||
540 | * @data: a pointer to the input data | ||
541 | * @sizeof_data: holds the size of @data | ||
542 | * | ||
543 | * This function will set the part of the name of the Certificate request subject, specified | ||
544 | * by the given OID. The input string should be ASCII or UTF-8 encoded. | ||
545 | * | ||
546 | * Some helper macros with popular OIDs can be found in gnutls/x509.h | ||
547 | * With this function you can only set the known OIDs. You can test | ||
548 | * for known OIDs using MHD_gnutls_x509_dn_oid_known(). For OIDs that are | ||
549 | * not known (by gnutls) you should properly DER encode your data, and | ||
550 | * call this function with raw_flag set. | ||
551 | * | ||
552 | * Returns 0 on success. | ||
553 | * | ||
554 | **/ | ||
555 | int | ||
556 | MHD_gnutls_x509_crq_set_dn_by_oid (MHD_gnutls_x509_crq_t crq, const char *oid, | ||
557 | unsigned int raw_flag, const void *data, | ||
558 | unsigned int sizeof_data) | ||
559 | { | ||
560 | if (sizeof_data == 0 || data == NULL || crq == NULL) | ||
561 | { | ||
562 | return GNUTLS_E_INVALID_REQUEST; | ||
563 | } | ||
564 | |||
565 | return MHD__gnutls_x509_set_dn_oid (crq->crq, | ||
566 | "certificationRequestInfo.subject", oid, | ||
567 | raw_flag, data, sizeof_data); | ||
568 | } | ||
569 | |||
570 | /** | ||
571 | * MHD_gnutls_x509_crq_set_version - This function will set the Certificate request version | ||
572 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
573 | * @version: holds the version number. For v1 Requests must be 1. | ||
574 | * | ||
575 | * This function will set the version of the certificate request. For | ||
576 | * version 1 requests this must be one. | ||
577 | * | ||
578 | * Returns 0 on success. | ||
579 | * | ||
580 | **/ | ||
581 | int | ||
582 | MHD_gnutls_x509_crq_set_version (MHD_gnutls_x509_crq_t crq, | ||
583 | unsigned int version) | ||
584 | { | ||
585 | int result; | ||
586 | unsigned char null = version; | ||
587 | |||
588 | if (crq == NULL) | ||
589 | { | ||
590 | MHD_gnutls_assert (); | ||
591 | return GNUTLS_E_INVALID_REQUEST; | ||
592 | } | ||
593 | |||
594 | if (null > 0) | ||
595 | null--; | ||
596 | |||
597 | result = | ||
598 | MHD__asn1_write_value (crq->crq, "certificationRequestInfo.version", | ||
599 | &null, 1); | ||
600 | if (result != ASN1_SUCCESS) | ||
601 | { | ||
602 | MHD_gnutls_assert (); | ||
603 | return MHD_gtls_asn2err (result); | ||
604 | } | ||
605 | |||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | /** | ||
610 | * MHD_gnutls_x509_crq_get_version - This function returns the Certificate request's version number | ||
611 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
612 | * | ||
613 | * This function will return the version of the specified Certificate request. | ||
614 | * | ||
615 | * Returns a negative value on error. | ||
616 | * | ||
617 | **/ | ||
618 | int | ||
619 | MHD_gnutls_x509_crq_get_version (MHD_gnutls_x509_crq_t crq) | ||
620 | { | ||
621 | opaque version[5]; | ||
622 | int len, result; | ||
623 | |||
624 | if (crq == NULL) | ||
625 | { | ||
626 | MHD_gnutls_assert (); | ||
627 | return GNUTLS_E_INVALID_REQUEST; | ||
628 | } | ||
629 | |||
630 | len = sizeof (version); | ||
631 | if ((result = | ||
632 | MHD__asn1_read_value (crq->crq, "certificationRequestInfo.version", | ||
633 | version, &len)) != ASN1_SUCCESS) | ||
634 | { | ||
635 | |||
636 | if (result == ASN1_ELEMENT_NOT_FOUND) | ||
637 | return 1; /* the DEFAULT version */ | ||
638 | MHD_gnutls_assert (); | ||
639 | return MHD_gtls_asn2err (result); | ||
640 | } | ||
641 | |||
642 | return (int) version[0] + 1; | ||
643 | } | ||
644 | |||
645 | /** | ||
646 | * MHD_gnutls_x509_crq_set_key - This function will associate the Certificate request with a key | ||
647 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
648 | * @key: holds a private key | ||
649 | * | ||
650 | * This function will set the public parameters from the given private key to the | ||
651 | * request. Only RSA keys are currently supported. | ||
652 | * | ||
653 | * Returns 0 on success. | ||
654 | * | ||
655 | **/ | ||
656 | int | ||
657 | MHD_gnutls_x509_crq_set_key (MHD_gnutls_x509_crq_t crq, | ||
658 | MHD_gnutls_x509_privkey_t key) | ||
659 | { | ||
660 | int result; | ||
661 | |||
662 | if (crq == NULL) | ||
663 | { | ||
664 | MHD_gnutls_assert (); | ||
665 | return GNUTLS_E_INVALID_REQUEST; | ||
666 | } | ||
667 | |||
668 | result = MHD__gnutls_x509_encode_and_copy_PKI_params (crq->crq, | ||
669 | "certificationRequestInfo.subjectPKInfo", | ||
670 | key->pk_algorithm, | ||
671 | key->params, | ||
672 | key->params_size); | ||
673 | |||
674 | if (result < 0) | ||
675 | { | ||
676 | MHD_gnutls_assert (); | ||
677 | return result; | ||
678 | } | ||
679 | |||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | /** | ||
684 | * MHD_gnutls_x509_crq_set_challenge_password - This function will set a challenge password | ||
685 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
686 | * @pass: holds a null terminated password | ||
687 | * | ||
688 | * This function will set a challenge password to be used when revoking the request. | ||
689 | * | ||
690 | * Returns 0 on success. | ||
691 | * | ||
692 | **/ | ||
693 | int | ||
694 | MHD_gnutls_x509_crq_set_challenge_password (MHD_gnutls_x509_crq_t crq, | ||
695 | const char *pass) | ||
696 | { | ||
697 | int result; | ||
698 | |||
699 | if (crq == NULL) | ||
700 | { | ||
701 | MHD_gnutls_assert (); | ||
702 | return GNUTLS_E_INVALID_REQUEST; | ||
703 | } | ||
704 | |||
705 | /* Add the attribute. | ||
706 | */ | ||
707 | result = | ||
708 | MHD__asn1_write_value (crq->crq, "certificationRequestInfo.attributes", | ||
709 | "NEW", 1); | ||
710 | if (result != ASN1_SUCCESS) | ||
711 | { | ||
712 | MHD_gnutls_assert (); | ||
713 | return MHD_gtls_asn2err (result); | ||
714 | } | ||
715 | |||
716 | result = | ||
717 | MHD__gnutls_x509_encode_and_write_attribute ("1.2.840.113549.1.9.7", | ||
718 | crq->crq, | ||
719 | "certificationRequestInfo.attributes.?LAST", | ||
720 | pass, strlen (pass), 1); | ||
721 | |||
722 | if (result < 0) | ||
723 | { | ||
724 | MHD_gnutls_assert (); | ||
725 | return result; | ||
726 | } | ||
727 | |||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | /** | ||
732 | * MHD_gnutls_x509_crq_sign2 - This function will sign a Certificate request with a key | ||
733 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
734 | * @key: holds a private key | ||
735 | * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing. | ||
736 | * @flags: must be 0 | ||
737 | * | ||
738 | * This function will sign the certificate request with a private key. | ||
739 | * This must be the same key as the one used in MHD_gnutls_x509_crt_set_key() since a | ||
740 | * certificate request is self signed. | ||
741 | * | ||
742 | * This must be the last step in a certificate request generation since all | ||
743 | * the previously set parameters are now signed. | ||
744 | * | ||
745 | * Returns 0 on success. | ||
746 | * | ||
747 | **/ | ||
748 | int | ||
749 | MHD_gnutls_x509_crq_sign2 (MHD_gnutls_x509_crq_t crq, | ||
750 | MHD_gnutls_x509_privkey_t key, | ||
751 | enum MHD_GNUTLS_HashAlgorithm dig, | ||
752 | unsigned int flags) | ||
753 | { | ||
754 | int result; | ||
755 | MHD_gnutls_datum_t signature; | ||
756 | |||
757 | if (crq == NULL) | ||
758 | { | ||
759 | MHD_gnutls_assert (); | ||
760 | return GNUTLS_E_INVALID_REQUEST; | ||
761 | } | ||
762 | |||
763 | /* Step 1. Self sign the request. | ||
764 | */ | ||
765 | result = | ||
766 | MHD__gnutls_x509_sign_tbs (crq->crq, "certificationRequestInfo", | ||
767 | dig, key, &signature); | ||
768 | |||
769 | if (result < 0) | ||
770 | { | ||
771 | MHD_gnutls_assert (); | ||
772 | return result; | ||
773 | } | ||
774 | |||
775 | /* Step 2. write the signature (bits) | ||
776 | */ | ||
777 | result = | ||
778 | MHD__asn1_write_value (crq->crq, "signature", signature.data, | ||
779 | signature.size * 8); | ||
780 | |||
781 | MHD__gnutls_free_datum (&signature); | ||
782 | |||
783 | if (result != ASN1_SUCCESS) | ||
784 | { | ||
785 | MHD_gnutls_assert (); | ||
786 | return MHD_gtls_asn2err (result); | ||
787 | } | ||
788 | |||
789 | /* Step 3. Write the signatureAlgorithm field. | ||
790 | */ | ||
791 | result = MHD__gnutls_x509_write_sig_params (crq->crq, "signatureAlgorithm", | ||
792 | key->pk_algorithm, dig, | ||
793 | key->params, key->params_size); | ||
794 | if (result < 0) | ||
795 | { | ||
796 | MHD_gnutls_assert (); | ||
797 | return result; | ||
798 | } | ||
799 | |||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | /** | ||
804 | * MHD_gnutls_x509_crq_sign - This function will sign a Certificate request with a key | ||
805 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
806 | * @key: holds a private key | ||
807 | * | ||
808 | * This function is the same a MHD_gnutls_x509_crq_sign2() with no flags, and | ||
809 | * SHA1 as the hash algorithm. | ||
810 | * | ||
811 | * Returns 0 on success. | ||
812 | * | ||
813 | **/ | ||
814 | int | ||
815 | MHD_gnutls_x509_crq_sign (MHD_gnutls_x509_crq_t crq, | ||
816 | MHD_gnutls_x509_privkey_t key) | ||
817 | { | ||
818 | return MHD_gnutls_x509_crq_sign2 (crq, key, MHD_GNUTLS_MAC_SHA1, 0); | ||
819 | } | ||
820 | |||
821 | /** | ||
822 | * MHD_gnutls_x509_crq_export - Export the generated certificate request | ||
823 | * @crq: Holds the request | ||
824 | * @format: the format of output params. One of PEM or DER. | ||
825 | * @output_data: will contain a certificate request PEM or DER encoded | ||
826 | * @output_data_size: holds the size of output_data (and will be | ||
827 | * replaced by the actual size of parameters) | ||
828 | * | ||
829 | * This function will export the certificate request to a PKCS10 | ||
830 | * | ||
831 | * If the buffer provided is not long enough to hold the output, then | ||
832 | * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and | ||
833 | * *output_data_size will be updated. | ||
834 | * | ||
835 | * If the structure is PEM encoded, it will have a header of "BEGIN | ||
836 | * NEW CERTIFICATE REQUEST". | ||
837 | * | ||
838 | * Return value: In case of failure a negative value will be | ||
839 | * returned, and 0 on success. | ||
840 | * | ||
841 | **/ | ||
842 | int | ||
843 | MHD_gnutls_x509_crq_export (MHD_gnutls_x509_crq_t crq, | ||
844 | MHD_gnutls_x509_crt_fmt_t format, | ||
845 | void *output_data, size_t * output_data_size) | ||
846 | { | ||
847 | if (crq == NULL) | ||
848 | { | ||
849 | MHD_gnutls_assert (); | ||
850 | return GNUTLS_E_INVALID_REQUEST; | ||
851 | } | ||
852 | |||
853 | return MHD__gnutls_x509_export_int (crq->crq, format, PEM_CRQ, | ||
854 | output_data, output_data_size); | ||
855 | } | ||
856 | |||
857 | /** | ||
858 | * MHD_gnutls_x509_crq_get_pk_algorithm - This function returns the certificate request's PublicKey algorithm | ||
859 | * @crq: should contain a MHD_gnutls_x509_crq_t structure | ||
860 | * @bits: if bits is non null it will hold the size of the parameters' in bits | ||
861 | * | ||
862 | * This function will return the public key algorithm of a PKCS \#10 | ||
863 | * certificate request. | ||
864 | * | ||
865 | * If bits is non null, it should have enough size to hold the parameters | ||
866 | * size in bits. For RSA the bits returned is the modulus. | ||
867 | * For DSA the bits returned are of the public | ||
868 | * exponent. | ||
869 | * | ||
870 | * Returns a member of the enum MHD_GNUTLS_PublicKeyAlgorithm enumeration on success, | ||
871 | * or a negative value on error. | ||
872 | * | ||
873 | **/ | ||
874 | int | ||
875 | MHD_gnutls_x509_crq_get_pk_algorithm (MHD_gnutls_x509_crq_t crq, | ||
876 | unsigned int *bits) | ||
877 | { | ||
878 | int result; | ||
879 | |||
880 | if (crq == NULL) | ||
881 | { | ||
882 | MHD_gnutls_assert (); | ||
883 | return GNUTLS_E_INVALID_REQUEST; | ||
884 | } | ||
885 | |||
886 | result = | ||
887 | MHD__gnutls_x509_get_pk_algorithm (crq->crq, | ||
888 | "certificationRequestInfo.subjectPKInfo", | ||
889 | bits); | ||
890 | if (result < 0) | ||
891 | { | ||
892 | MHD_gnutls_assert (); | ||
893 | } | ||
894 | |||
895 | return result; | ||
896 | } | ||
897 | |||
898 | #endif /* ENABLE_PKI */ | ||