1 /*
2 * Copyright (C) 2003-2014 Free Software Foundation, Inc.
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GnuTLS.
7 *
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 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 License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>
20 *
21 */
22
23 /* Functions that relate to the X.509 extension parsing.
24 */
25
26 #include "gnutls_int.h"
27 #include "errors.h"
28 #include <global.h>
29 #include <libtasn1.h>
30 #include <common.h>
31 #include <gnutls/x509-ext.h>
32 #include <gnutls/x509.h>
33 #include <x509_int.h>
34 #include <datum.h>
35
36 int
_gnutls_get_extension(ASN1_TYPE asn,const char * root,const char * extension_id,int indx,gnutls_datum_t * ret,unsigned int * _critical)37 _gnutls_get_extension(ASN1_TYPE asn, const char *root,
38 const char *extension_id, int indx,
39 gnutls_datum_t * ret, unsigned int *_critical)
40 {
41 int k, result, len;
42 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
43 char str_critical[10];
44 int critical = 0;
45 char extnID[MAX_OID_SIZE];
46 gnutls_datum_t value;
47 int indx_counter = 0;
48
49 ret->data = NULL;
50 ret->size = 0;
51
52 k = 0;
53 do {
54 k++;
55
56 snprintf(name, sizeof(name), "%s.?%u", root, k);
57
58 _gnutls_str_cpy(name2, sizeof(name2), name);
59 _gnutls_str_cat(name2, sizeof(name2), ".extnID");
60
61 len = sizeof(extnID) - 1;
62 result = asn1_read_value(asn, name2, extnID, &len);
63
64 if (result == ASN1_ELEMENT_NOT_FOUND) {
65 break;
66 } else if (result != ASN1_SUCCESS) {
67 gnutls_assert();
68 return _gnutls_asn2err(result);
69 }
70
71 /* Handle Extension
72 */
73 if (strcmp(extnID, extension_id) == 0
74 && indx == indx_counter++) {
75 /* extension was found
76 */
77
78 /* read the critical status.
79 */
80 _gnutls_str_cpy(name2, sizeof(name2), name);
81 _gnutls_str_cat(name2, sizeof(name2), ".critical");
82
83 len = sizeof(str_critical);
84 result =
85 asn1_read_value(asn, name2,
86 str_critical, &len);
87
88 if (result == ASN1_ELEMENT_NOT_FOUND) {
89 gnutls_assert();
90 break;
91 } else if (result != ASN1_SUCCESS) {
92 gnutls_assert();
93 return _gnutls_asn2err(result);
94 }
95
96 if (str_critical[0] == 'T')
97 critical = 1;
98 else
99 critical = 0;
100
101 /* read the value.
102 */
103 _gnutls_str_cpy(name2, sizeof(name2), name);
104 _gnutls_str_cat(name2, sizeof(name2),
105 ".extnValue");
106
107 result =
108 _gnutls_x509_read_value(asn, name2, &value);
109 if (result < 0) {
110 gnutls_assert();
111 return result;
112 }
113
114 ret->data = value.data;
115 ret->size = value.size;
116
117 if (_critical)
118 *_critical = critical;
119
120 return 0;
121 }
122 }
123 while (1);
124
125 if (result == ASN1_ELEMENT_NOT_FOUND) {
126 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
127 } else {
128 gnutls_assert();
129 return _gnutls_asn2err(result);
130 }
131 }
132
133 static int
get_indx_extension(ASN1_TYPE asn,const char * root,int indx,gnutls_datum_t * out)134 get_indx_extension(ASN1_TYPE asn, const char *root,
135 int indx, gnutls_datum_t * out)
136 {
137 char name[MAX_NAME_SIZE];
138 int ret;
139
140 out->data = NULL;
141 out->size = 0;
142
143 snprintf(name, sizeof(name), "%s.?%u.extnValue", root, indx+1);
144
145 ret = _gnutls_x509_read_value(asn, name, out);
146 if (ret < 0)
147 return gnutls_assert_val(ret);
148
149 return 0;
150 }
151
152 int
_gnutls_x509_crt_get_extension(gnutls_x509_crt_t cert,const char * extension_id,int indx,gnutls_datum_t * data,unsigned int * critical)153 _gnutls_x509_crt_get_extension(gnutls_x509_crt_t cert,
154 const char *extension_id, int indx,
155 gnutls_datum_t * data, unsigned int *critical)
156 {
157 return _gnutls_get_extension(cert->cert, "tbsCertificate.extensions",
158 extension_id, indx, data, critical);
159 }
160
161 /**
162 * gnutls_x509_crt_get_extension_data2:
163 * @cert: should contain a #gnutls_x509_crt_t type
164 * @indx: Specifies which extension OID to read. Use (0) to get the first one.
165 * @data: will contain the extension DER-encoded data
166 *
167 * This function will return the requested by the index extension data in the
168 * certificate. The extension data will be allocated using
169 * gnutls_malloc().
170 *
171 * Use gnutls_x509_crt_get_extension_info() to extract the OID.
172 *
173 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
174 * otherwise a negative error code is returned. If you have reached the
175 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
176 * will be returned.
177 **/
178 int
gnutls_x509_crt_get_extension_data2(gnutls_x509_crt_t cert,unsigned indx,gnutls_datum_t * data)179 gnutls_x509_crt_get_extension_data2(gnutls_x509_crt_t cert,
180 unsigned indx,
181 gnutls_datum_t * data)
182 {
183 return get_indx_extension(cert->cert, "tbsCertificate.extensions",
184 indx, data);
185 }
186
187 int
_gnutls_x509_crl_get_extension(gnutls_x509_crl_t crl,const char * extension_id,int indx,gnutls_datum_t * data,unsigned int * critical)188 _gnutls_x509_crl_get_extension(gnutls_x509_crl_t crl,
189 const char *extension_id, int indx,
190 gnutls_datum_t * data,
191 unsigned int *critical)
192 {
193 return _gnutls_get_extension(crl->crl, "tbsCertList.crlExtensions",
194 extension_id, indx, data, critical);
195 }
196
197 /**
198 * gnutls_x509_crl_get_extension_data2:
199 * @crl: should contain a #gnutls_x509_crl_t type
200 * @indx: Specifies which extension OID to read. Use (0) to get the first one.
201 * @data: will contain the extension DER-encoded data
202 *
203 * This function will return the requested by the index extension data in the
204 * certificate revocation list. The extension data will be allocated using
205 * gnutls_malloc().
206 *
207 * Use gnutls_x509_crt_get_extension_info() to extract the OID.
208 *
209 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
210 * otherwise a negative error code is returned. If you have reached the
211 * last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
212 * will be returned.
213 **/
214 int
gnutls_x509_crl_get_extension_data2(gnutls_x509_crl_t crl,unsigned indx,gnutls_datum_t * data)215 gnutls_x509_crl_get_extension_data2(gnutls_x509_crl_t crl,
216 unsigned indx,
217 gnutls_datum_t * data)
218 {
219 return get_indx_extension(crl->crl, "tbsCertList.crlExtensions",
220 indx, data);
221 }
222
223 /* This function will attempt to return the requested extension OID found in
224 * the given X509v3 certificate.
225 *
226 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
227 * be returned.
228 */
get_extension_oid(ASN1_TYPE asn,const char * root,unsigned indx,void * oid,size_t * sizeof_oid)229 static int get_extension_oid(ASN1_TYPE asn, const char *root,
230 unsigned indx, void *oid, size_t * sizeof_oid)
231 {
232 int k, result, len;
233 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
234 char extnID[MAX_OID_SIZE];
235 unsigned indx_counter = 0;
236
237 k = 0;
238 do {
239 k++;
240
241 snprintf(name, sizeof(name), "%s.?%u", root, k);
242
243 _gnutls_str_cpy(name2, sizeof(name2), name);
244 _gnutls_str_cat(name2, sizeof(name2), ".extnID");
245
246 len = sizeof(extnID) - 1;
247 result = asn1_read_value(asn, name2, extnID, &len);
248
249 if (result == ASN1_ELEMENT_NOT_FOUND) {
250 gnutls_assert();
251 break;
252 } else if (result != ASN1_SUCCESS) {
253 gnutls_assert();
254 return _gnutls_asn2err(result);
255 }
256
257 /* Handle Extension
258 */
259 if (indx == indx_counter++) {
260 len = strlen(extnID) + 1;
261
262 if (*sizeof_oid < (unsigned) len) {
263 *sizeof_oid = len;
264 gnutls_assert();
265 return GNUTLS_E_SHORT_MEMORY_BUFFER;
266 }
267
268 memcpy(oid, extnID, len);
269 *sizeof_oid = len - 1;
270
271 return 0;
272 }
273
274
275 }
276 while (1);
277
278 if (result == ASN1_ELEMENT_NOT_FOUND) {
279 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
280 } else {
281 gnutls_assert();
282 return _gnutls_asn2err(result);
283 }
284 }
285
286 /* This function will attempt to return the requested extension OID found in
287 * the given X509v3 certificate.
288 *
289 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
290 * be returned.
291 */
292 int
_gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert,int indx,void * oid,size_t * sizeof_oid)293 _gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert,
294 int indx, void *oid,
295 size_t * sizeof_oid)
296 {
297 return get_extension_oid(cert->cert, "tbsCertificate.extensions",
298 indx, oid, sizeof_oid);
299 }
300
301 int
_gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl,int indx,void * oid,size_t * sizeof_oid)302 _gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl,
303 int indx, void *oid,
304 size_t * sizeof_oid)
305 {
306 return get_extension_oid(crl->crl, "tbsCertList.crlExtensions",
307 indx, oid, sizeof_oid);
308 }
309
310 /* This function will attempt to set the requested extension in
311 * the given X509v3 certificate.
312 *
313 * Critical will be either 0 or 1.
314 */
315 static int
add_extension(ASN1_TYPE asn,const char * root,const char * extension_id,const gnutls_datum_t * ext_data,unsigned int critical)316 add_extension(ASN1_TYPE asn, const char *root, const char *extension_id,
317 const gnutls_datum_t * ext_data, unsigned int critical)
318 {
319 int result;
320 const char *str;
321 char name[MAX_NAME_SIZE];
322
323 snprintf(name, sizeof(name), "%s", root);
324
325 /* Add a new extension in the list.
326 */
327 result = asn1_write_value(asn, name, "NEW", 1);
328 if (result != ASN1_SUCCESS) {
329 gnutls_assert();
330 return _gnutls_asn2err(result);
331 }
332
333 if (root[0] != 0)
334 snprintf(name, sizeof(name), "%s.?LAST.extnID", root);
335 else
336 snprintf(name, sizeof(name), "?LAST.extnID");
337
338 result = asn1_write_value(asn, name, extension_id, 1);
339 if (result != ASN1_SUCCESS) {
340 gnutls_assert();
341 return _gnutls_asn2err(result);
342 }
343
344 if (critical == 0)
345 str = "FALSE";
346 else
347 str = "TRUE";
348
349 if (root[0] != 0)
350 snprintf(name, sizeof(name), "%s.?LAST.critical", root);
351 else
352 snprintf(name, sizeof(name), "?LAST.critical");
353
354 result = asn1_write_value(asn, name, str, 1);
355 if (result != ASN1_SUCCESS) {
356 gnutls_assert();
357 return _gnutls_asn2err(result);
358 }
359
360 if (root[0] != 0)
361 snprintf(name, sizeof(name), "%s.?LAST.extnValue", root);
362 else
363 snprintf(name, sizeof(name), "?LAST.extnValue");
364
365 result = _gnutls_x509_write_value(asn, name, ext_data);
366 if (result < 0) {
367 gnutls_assert();
368 return result;
369 }
370
371 return 0;
372 }
373
374 /* Overwrite the given extension (using the index)
375 * index here starts from one.
376 */
377 static int
overwrite_extension(ASN1_TYPE asn,const char * root,unsigned int indx,const gnutls_datum_t * ext_data,unsigned int critical)378 overwrite_extension(ASN1_TYPE asn, const char *root, unsigned int indx,
379 const gnutls_datum_t * ext_data, unsigned int critical)
380 {
381 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
382 const char *str;
383 int result;
384
385 if (root[0] != 0)
386 snprintf(name, sizeof(name), "%s.?%u", root, indx);
387 else
388 snprintf(name, sizeof(name), "?%u", indx);
389
390 if (critical == 0)
391 str = "FALSE";
392 else
393 str = "TRUE";
394
395 _gnutls_str_cpy(name2, sizeof(name2), name);
396 _gnutls_str_cat(name2, sizeof(name2), ".critical");
397
398 result = asn1_write_value(asn, name2, str, 1);
399 if (result != ASN1_SUCCESS) {
400 gnutls_assert();
401 return _gnutls_asn2err(result);
402 }
403
404 _gnutls_str_cpy(name2, sizeof(name2), name);
405 _gnutls_str_cat(name2, sizeof(name2), ".extnValue");
406
407 result = _gnutls_x509_write_value(asn, name2, ext_data);
408 if (result < 0) {
409 gnutls_assert();
410 return result;
411 }
412
413 return 0;
414 }
415
416 int
_gnutls_set_extension(ASN1_TYPE asn,const char * root,const char * ext_id,const gnutls_datum_t * ext_data,unsigned int critical)417 _gnutls_set_extension(ASN1_TYPE asn, const char *root,
418 const char *ext_id,
419 const gnutls_datum_t * ext_data, unsigned int critical)
420 {
421 int result = 0;
422 int k, len;
423 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
424 char extnID[MAX_OID_SIZE];
425
426 /* Find the index of the given extension.
427 */
428 k = 0;
429 do {
430 k++;
431
432 if (root[0] != 0)
433 snprintf(name, sizeof(name), "%s.?%u", root, k);
434 else
435 snprintf(name, sizeof(name), "?%u", k);
436
437 len = sizeof(extnID) - 1;
438 result = asn1_read_value(asn, name, extnID, &len);
439
440 /* move to next
441 */
442
443 if (result == ASN1_ELEMENT_NOT_FOUND) {
444 break;
445 }
446
447 do {
448
449 _gnutls_str_cpy(name2, sizeof(name2), name);
450 _gnutls_str_cat(name2, sizeof(name2), ".extnID");
451
452 len = sizeof(extnID) - 1;
453 result = asn1_read_value(asn, name2, extnID, &len);
454
455 if (result == ASN1_ELEMENT_NOT_FOUND) {
456 gnutls_assert();
457 break;
458 } else if (result != ASN1_SUCCESS) {
459 gnutls_assert();
460 return _gnutls_asn2err(result);
461 }
462
463 /* Handle Extension
464 */
465 if (strcmp(extnID, ext_id) == 0) {
466 /* extension was found
467 */
468 return overwrite_extension(asn, root, k,
469 ext_data,
470 critical);
471 }
472
473
474 }
475 while (0);
476 }
477 while (1);
478
479 if (result == ASN1_ELEMENT_NOT_FOUND) {
480 return add_extension(asn, root, ext_id, ext_data,
481 critical);
482 } else {
483 gnutls_assert();
484 return _gnutls_asn2err(result);
485 }
486
487
488 return 0;
489 }
490
491 /* This function will attempt to overwrite the requested extension with
492 * the given one.
493 *
494 * Critical will be either 0 or 1.
495 */
496 int
_gnutls_x509_crt_set_extension(gnutls_x509_crt_t cert,const char * ext_id,const gnutls_datum_t * ext_data,unsigned int critical)497 _gnutls_x509_crt_set_extension(gnutls_x509_crt_t cert,
498 const char *ext_id,
499 const gnutls_datum_t * ext_data,
500 unsigned int critical)
501 {
502 MODIFIED(cert);
503 cert->use_extensions = 1;
504
505 return _gnutls_set_extension(cert->cert, "tbsCertificate.extensions",
506 ext_id, ext_data, critical);
507 }
508
509 int
_gnutls_x509_crl_set_extension(gnutls_x509_crl_t crl,const char * ext_id,const gnutls_datum_t * ext_data,unsigned int critical)510 _gnutls_x509_crl_set_extension(gnutls_x509_crl_t crl,
511 const char *ext_id,
512 const gnutls_datum_t * ext_data,
513 unsigned int critical)
514 {
515 return _gnutls_set_extension(crl->crl, "tbsCertList.crlExtensions", ext_id,
516 ext_data, critical);
517 }
518
519 int
_gnutls_x509_crq_set_extension(gnutls_x509_crq_t crq,const char * ext_id,const gnutls_datum_t * ext_data,unsigned int critical)520 _gnutls_x509_crq_set_extension(gnutls_x509_crq_t crq,
521 const char *ext_id,
522 const gnutls_datum_t * ext_data,
523 unsigned int critical)
524 {
525 unsigned char *extensions = NULL;
526 size_t extensions_size = 0;
527 gnutls_datum_t der;
528 ASN1_TYPE c2;
529 int result;
530
531 result =
532 gnutls_x509_crq_get_attribute_by_oid(crq,
533 "1.2.840.113549.1.9.14",
534 0, NULL,
535 &extensions_size);
536 if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
537 extensions = gnutls_malloc(extensions_size);
538 if (extensions == NULL) {
539 gnutls_assert();
540 return GNUTLS_E_MEMORY_ERROR;
541 }
542
543 result = gnutls_x509_crq_get_attribute_by_oid(crq,
544 "1.2.840.113549.1.9.14",
545 0,
546 extensions,
547 &extensions_size);
548 }
549 if (result < 0) {
550 if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
551 extensions_size = 0;
552 } else {
553 gnutls_assert();
554 gnutls_free(extensions);
555 return result;
556 }
557 }
558
559 result =
560 asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extensions",
561 &c2);
562 if (result != ASN1_SUCCESS) {
563 gnutls_assert();
564 gnutls_free(extensions);
565 return _gnutls_asn2err(result);
566 }
567
568 if (extensions_size > 0) {
569 result =
570 _asn1_strict_der_decode(&c2, extensions, extensions_size,
571 NULL);
572 gnutls_free(extensions);
573 if (result != ASN1_SUCCESS) {
574 gnutls_assert();
575 asn1_delete_structure(&c2);
576 return _gnutls_asn2err(result);
577 }
578 }
579
580 result = _gnutls_set_extension(c2, "", ext_id, ext_data, critical);
581 if (result < 0) {
582 gnutls_assert();
583 asn1_delete_structure(&c2);
584 return result;
585 }
586
587 result = _gnutls_x509_der_encode(c2, "", &der, 0);
588
589 asn1_delete_structure(&c2);
590
591 if (result < 0) {
592 gnutls_assert();
593 return result;
594 }
595
596 result =
597 gnutls_x509_crq_set_attribute_by_oid(crq,
598 "1.2.840.113549.1.9.14",
599 der.data, der.size);
600 gnutls_free(der.data);
601 if (result < 0) {
602 gnutls_assert();
603 return result;
604 }
605
606
607 return 0;
608 }
609
610 /* extract an INTEGER from the DER encoded extension
611 */
612 int
_gnutls_x509_ext_extract_number(uint8_t * number,size_t * _nr_size,uint8_t * extnValue,int extnValueLen)613 _gnutls_x509_ext_extract_number(uint8_t * number,
614 size_t * _nr_size,
615 uint8_t * extnValue, int extnValueLen)
616 {
617 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
618 int result;
619 int nr_size = *_nr_size;
620
621 /* here it doesn't matter so much that we use CertificateSerialNumber. It is equal
622 * to using INTEGER.
623 */
624 if ((result = asn1_create_element
625 (_gnutls_get_pkix(), "PKIX1.CertificateSerialNumber",
626 &ext)) != ASN1_SUCCESS) {
627 gnutls_assert();
628 return _gnutls_asn2err(result);
629 }
630
631 result = _asn1_strict_der_decode(&ext, extnValue, extnValueLen, NULL);
632 if (result != ASN1_SUCCESS) {
633 gnutls_assert();
634 asn1_delete_structure(&ext);
635 return _gnutls_asn2err(result);
636 }
637
638 /* the default value of cA is false.
639 */
640 result = asn1_read_value(ext, "", number, &nr_size);
641 if (result != ASN1_SUCCESS)
642 result = _gnutls_asn2err(result);
643 else
644 result = 0;
645
646 *_nr_size = nr_size;
647
648 asn1_delete_structure(&ext);
649
650 return result;
651 }
652
653 /* generate an INTEGER in a DER encoded extension
654 */
655 int
_gnutls_x509_ext_gen_number(const uint8_t * number,size_t nr_size,gnutls_datum_t * der_ext)656 _gnutls_x509_ext_gen_number(const uint8_t * number, size_t nr_size,
657 gnutls_datum_t * der_ext)
658 {
659 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
660 int result;
661
662 result =
663 asn1_create_element(_gnutls_get_pkix(),
664 "PKIX1.CertificateSerialNumber", &ext);
665 if (result != ASN1_SUCCESS) {
666 gnutls_assert();
667 return _gnutls_asn2err(result);
668 }
669
670 result = asn1_write_value(ext, "", number, nr_size);
671 if (result != ASN1_SUCCESS) {
672 gnutls_assert();
673 asn1_delete_structure(&ext);
674 return _gnutls_asn2err(result);
675 }
676
677 result = _gnutls_x509_der_encode(ext, "", der_ext, 0);
678
679 asn1_delete_structure(&ext);
680
681 if (result < 0) {
682 gnutls_assert();
683 return result;
684 }
685
686 return 0;
687 }
688
689 int
_gnutls_write_general_name(ASN1_TYPE ext,const char * ext_name,gnutls_x509_subject_alt_name_t type,const void * data,unsigned int data_size)690 _gnutls_write_general_name(ASN1_TYPE ext, const char *ext_name,
691 gnutls_x509_subject_alt_name_t type,
692 const void *data, unsigned int data_size)
693 {
694 const char *str;
695 int result;
696 char name[128];
697
698 if (data == NULL) {
699 if (data_size == 0)
700 data = (void*)"";
701 else
702 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
703 }
704
705 switch (type) {
706 case GNUTLS_SAN_DNSNAME:
707 str = "dNSName";
708 break;
709 case GNUTLS_SAN_RFC822NAME:
710 str = "rfc822Name";
711 break;
712 case GNUTLS_SAN_URI:
713 str = "uniformResourceIdentifier";
714 break;
715 case GNUTLS_SAN_IPADDRESS:
716 str = "iPAddress";
717 break;
718 case GNUTLS_SAN_REGISTERED_ID:
719 str = "registeredID";
720 break;
721 default:
722 gnutls_assert();
723 return GNUTLS_E_INTERNAL_ERROR;
724 }
725
726 result = asn1_write_value(ext, ext_name, str, 1);
727 if (result != ASN1_SUCCESS) {
728 gnutls_assert();
729 return _gnutls_asn2err(result);
730 }
731
732 snprintf(name, sizeof(name), "%s.%s", ext_name, str);
733
734 result = asn1_write_value(ext, name, data, data_size);
735 if (result != ASN1_SUCCESS) {
736 gnutls_assert();
737 asn1_delete_structure(&ext);
738 return _gnutls_asn2err(result);
739 }
740
741 return 0;
742 }
743
744 int
_gnutls_write_new_general_name(ASN1_TYPE ext,const char * ext_name,gnutls_x509_subject_alt_name_t type,const void * data,unsigned int data_size)745 _gnutls_write_new_general_name(ASN1_TYPE ext, const char *ext_name,
746 gnutls_x509_subject_alt_name_t type,
747 const void *data, unsigned int data_size)
748 {
749 int result;
750 char name[128];
751
752 result = asn1_write_value(ext, ext_name, "NEW", 1);
753 if (result != ASN1_SUCCESS) {
754 gnutls_assert();
755 return _gnutls_asn2err(result);
756 }
757
758 if (ext_name[0] == 0) { /* no dot */
759 _gnutls_str_cpy(name, sizeof(name), "?LAST");
760 } else {
761 _gnutls_str_cpy(name, sizeof(name), ext_name);
762 _gnutls_str_cat(name, sizeof(name), ".?LAST");
763 }
764
765 result = _gnutls_write_general_name(ext, name, type,
766 data, data_size);
767 if (result < 0) {
768 gnutls_assert();
769 return result;
770 }
771
772 return 0;
773 }
774
775 int
_gnutls_write_new_othername(ASN1_TYPE ext,const char * ext_name,const char * oid,const void * data,unsigned int data_size)776 _gnutls_write_new_othername(ASN1_TYPE ext, const char *ext_name,
777 const char *oid,
778 const void *data, unsigned int data_size)
779 {
780 int result;
781 char name[128];
782 char name2[128];
783
784 result = asn1_write_value(ext, ext_name, "NEW", 1);
785 if (result != ASN1_SUCCESS) {
786 gnutls_assert();
787 return _gnutls_asn2err(result);
788 }
789
790 if (ext_name[0] == 0) { /* no dot */
791 _gnutls_str_cpy(name, sizeof(name), "?LAST");
792 } else {
793 _gnutls_str_cpy(name, sizeof(name), ext_name);
794 _gnutls_str_cat(name, sizeof(name), ".?LAST");
795 }
796
797 result = asn1_write_value(ext, name, "otherName", 1);
798 if (result != ASN1_SUCCESS) {
799 gnutls_assert();
800 return _gnutls_asn2err(result);
801 }
802
803 snprintf(name2, sizeof(name2), "%s.otherName.type-id", name);
804
805 result = asn1_write_value(ext, name2, oid, 1);
806 if (result != ASN1_SUCCESS) {
807 gnutls_assert();
808 asn1_delete_structure(&ext);
809 return _gnutls_asn2err(result);
810 }
811
812 snprintf(name2, sizeof(name2), "%s.otherName.value", name);
813
814 result = asn1_write_value(ext, name2, data, data_size);
815 if (result != ASN1_SUCCESS) {
816 gnutls_assert();
817 asn1_delete_structure(&ext);
818 return _gnutls_asn2err(result);
819 }
820
821 return 0;
822 }
823
824 /* Convert the given name to GeneralNames in a DER encoded extension.
825 * This is the same as subject alternative name.
826 */
827 int
_gnutls_x509_ext_gen_subject_alt_name(gnutls_x509_subject_alt_name_t type,const char * othername_oid,const void * data,unsigned int data_size,const gnutls_datum_t * prev_der_ext,gnutls_datum_t * der_ext)828 _gnutls_x509_ext_gen_subject_alt_name(gnutls_x509_subject_alt_name_t
829 type,
830 const char *othername_oid,
831 const void *data,
832 unsigned int data_size,
833 const gnutls_datum_t * prev_der_ext,
834 gnutls_datum_t * der_ext)
835 {
836 int ret;
837 gnutls_subject_alt_names_t sans = NULL;
838 gnutls_datum_t name;
839
840 ret = gnutls_subject_alt_names_init(&sans);
841 if (ret < 0) {
842 gnutls_assert();
843 return ret;
844 }
845
846 if (prev_der_ext && prev_der_ext->data != NULL &&
847 prev_der_ext->size != 0) {
848
849 ret = gnutls_x509_ext_import_subject_alt_names(prev_der_ext, sans, 0);
850 if (ret < 0) {
851 gnutls_assert();
852 goto cleanup;
853 }
854 }
855
856 name.data = (void*)data;
857 name.size = data_size;
858 ret = gnutls_subject_alt_names_set(sans, type, &name, othername_oid);
859 if (ret < 0) {
860 gnutls_assert();
861 goto cleanup;
862 }
863
864 ret = gnutls_x509_ext_export_subject_alt_names(sans, der_ext);
865 if (ret < 0) {
866 gnutls_assert();
867 goto cleanup;
868 }
869
870 ret = 0;
871 cleanup:
872 if (sans != NULL)
873 gnutls_subject_alt_names_deinit(sans);
874
875 return ret;
876 }
877
878 /* generate the AuthorityKeyID in a DER encoded extension
879 */
880 int
_gnutls_x509_ext_gen_auth_key_id(const void * id,size_t id_size,gnutls_datum_t * der_ext)881 _gnutls_x509_ext_gen_auth_key_id(const void *id, size_t id_size,
882 gnutls_datum_t * der_ext)
883 {
884 gnutls_x509_aki_t aki;
885 int ret;
886 gnutls_datum_t l_id;
887
888 ret = gnutls_x509_aki_init(&aki);
889 if (ret < 0)
890 return gnutls_assert_val(ret);
891
892 l_id.data = (void*)id;
893 l_id.size = id_size;
894 ret = gnutls_x509_aki_set_id(aki, &l_id);
895 if (ret < 0) {
896 gnutls_assert();
897 goto cleanup;
898 }
899
900 ret = gnutls_x509_ext_export_authority_key_id(aki, der_ext);
901 if (ret < 0) {
902 gnutls_assert();
903 goto cleanup;
904 }
905
906 ret = 0;
907
908 cleanup:
909 gnutls_x509_aki_deinit(aki);
910 return ret;
911 }
912