diff options
Diffstat (limited to 'src/daemon/https/x509/extensions.c')
-rw-r--r-- | src/daemon/https/x509/extensions.c | 736 |
1 files changed, 1 insertions, 735 deletions
diff --git a/src/daemon/https/x509/extensions.c b/src/daemon/https/x509/extensions.c index f22fac36..8bf36000 100644 --- a/src/daemon/https/x509/extensions.c +++ b/src/daemon/https/x509/extensions.c | |||
@@ -259,191 +259,6 @@ MHD__gnutls_x509_crt_get_extension_oid (MHD_gnutls_x509_crt_t cert, | |||
259 | } | 259 | } |
260 | } | 260 | } |
261 | 261 | ||
262 | /* This function will attempt to set the requested extension in | ||
263 | * the given X509v3 certificate. | ||
264 | * | ||
265 | * Critical will be either 0 or 1. | ||
266 | */ | ||
267 | static int | ||
268 | set_extension (ASN1_TYPE asn, const char *extension_id, | ||
269 | const MHD_gnutls_datum_t * ext_data, unsigned int critical) | ||
270 | { | ||
271 | int result; | ||
272 | const char *str; | ||
273 | |||
274 | /* Add a new extension in the list. | ||
275 | */ | ||
276 | result = MHD__asn1_write_value (asn, "tbsCertificate.extensions", "NEW", 1); | ||
277 | if (result != ASN1_SUCCESS) | ||
278 | { | ||
279 | MHD_gnutls_assert (); | ||
280 | return MHD_gtls_asn2err (result); | ||
281 | } | ||
282 | |||
283 | result = | ||
284 | MHD__asn1_write_value (asn, "tbsCertificate.extensions.?LAST.extnID", | ||
285 | extension_id, 1); | ||
286 | if (result != ASN1_SUCCESS) | ||
287 | { | ||
288 | MHD_gnutls_assert (); | ||
289 | return MHD_gtls_asn2err (result); | ||
290 | } | ||
291 | |||
292 | if (critical == 0) | ||
293 | str = "FALSE"; | ||
294 | else | ||
295 | str = "TRUE"; | ||
296 | |||
297 | |||
298 | result = | ||
299 | MHD__asn1_write_value (asn, "tbsCertificate.extensions.?LAST.critical", | ||
300 | str, 1); | ||
301 | if (result != ASN1_SUCCESS) | ||
302 | { | ||
303 | MHD_gnutls_assert (); | ||
304 | return MHD_gtls_asn2err (result); | ||
305 | } | ||
306 | |||
307 | result = | ||
308 | MHD__gnutls_x509_write_value (asn, | ||
309 | "tbsCertificate.extensions.?LAST.extnValue", | ||
310 | ext_data, 0); | ||
311 | if (result < 0) | ||
312 | { | ||
313 | MHD_gnutls_assert (); | ||
314 | return result; | ||
315 | } | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | /* Overwrite the given extension (using the index) | ||
321 | * index here starts from one. | ||
322 | */ | ||
323 | static int | ||
324 | overwrite_extension (ASN1_TYPE asn, unsigned int indx, | ||
325 | const MHD_gnutls_datum_t * ext_data, unsigned int critical) | ||
326 | { | ||
327 | char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE]; | ||
328 | const char *str; | ||
329 | int result; | ||
330 | |||
331 | snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", indx); | ||
332 | |||
333 | if (critical == 0) | ||
334 | str = "FALSE"; | ||
335 | else | ||
336 | str = "TRUE"; | ||
337 | |||
338 | MHD_gtls_str_cpy (name2, sizeof (name2), name); | ||
339 | MHD_gtls_str_cat (name2, sizeof (name2), ".critical"); | ||
340 | |||
341 | result = MHD__asn1_write_value (asn, name2, str, 1); | ||
342 | if (result != ASN1_SUCCESS) | ||
343 | { | ||
344 | MHD_gnutls_assert (); | ||
345 | return MHD_gtls_asn2err (result); | ||
346 | } | ||
347 | |||
348 | MHD_gtls_str_cpy (name2, sizeof (name2), name); | ||
349 | MHD_gtls_str_cat (name2, sizeof (name2), ".extnValue"); | ||
350 | |||
351 | result = MHD__gnutls_x509_write_value (asn, name2, ext_data, 0); | ||
352 | if (result < 0) | ||
353 | { | ||
354 | MHD_gnutls_assert (); | ||
355 | return result; | ||
356 | } | ||
357 | |||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | /* This function will attempt to overwrite the requested extension with | ||
362 | * the given one. | ||
363 | * | ||
364 | * Critical will be either 0 or 1. | ||
365 | */ | ||
366 | int | ||
367 | MHD__gnutls_x509_crt_set_extension (MHD_gnutls_x509_crt_t cert, | ||
368 | const char *ext_id, | ||
369 | const MHD_gnutls_datum_t * ext_data, | ||
370 | unsigned int critical) | ||
371 | { | ||
372 | int result; | ||
373 | int k, len; | ||
374 | char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE]; | ||
375 | char extnID[128]; | ||
376 | |||
377 | /* Find the index of the given extension. | ||
378 | */ | ||
379 | k = 0; | ||
380 | do | ||
381 | { | ||
382 | k++; | ||
383 | |||
384 | snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k); | ||
385 | |||
386 | len = sizeof (extnID) - 1; | ||
387 | result = MHD__asn1_read_value (cert->cert, name, extnID, &len); | ||
388 | |||
389 | /* move to next | ||
390 | */ | ||
391 | |||
392 | if (result == ASN1_ELEMENT_NOT_FOUND) | ||
393 | { | ||
394 | break; | ||
395 | } | ||
396 | |||
397 | do | ||
398 | { | ||
399 | |||
400 | MHD_gtls_str_cpy (name2, sizeof (name2), name); | ||
401 | MHD_gtls_str_cat (name2, sizeof (name2), ".extnID"); | ||
402 | |||
403 | len = sizeof (extnID) - 1; | ||
404 | result = MHD__asn1_read_value (cert->cert, name2, extnID, &len); | ||
405 | |||
406 | if (result == ASN1_ELEMENT_NOT_FOUND) | ||
407 | { | ||
408 | MHD_gnutls_assert (); | ||
409 | break; | ||
410 | } | ||
411 | else if (result != ASN1_SUCCESS) | ||
412 | { | ||
413 | MHD_gnutls_assert (); | ||
414 | return MHD_gtls_asn2err (result); | ||
415 | } | ||
416 | |||
417 | /* Handle Extension | ||
418 | */ | ||
419 | if (strcmp (extnID, ext_id) == 0) | ||
420 | { | ||
421 | /* extension was found | ||
422 | */ | ||
423 | return overwrite_extension (cert->cert, k, ext_data, critical); | ||
424 | } | ||
425 | |||
426 | |||
427 | } | ||
428 | while (0); | ||
429 | } | ||
430 | while (1); | ||
431 | |||
432 | if (result == ASN1_ELEMENT_NOT_FOUND) | ||
433 | { | ||
434 | return set_extension (cert->cert, ext_id, ext_data, critical); | ||
435 | } | ||
436 | else | ||
437 | { | ||
438 | MHD_gnutls_assert (); | ||
439 | return MHD_gtls_asn2err (result); | ||
440 | } | ||
441 | |||
442 | |||
443 | return 0; | ||
444 | } | ||
445 | |||
446 | |||
447 | /* Here we only extract the KeyUsage field, from the DER encoded | 262 | /* Here we only extract the KeyUsage field, from the DER encoded |
448 | * extension. | 263 | * extension. |
449 | */ | 264 | */ |
@@ -520,7 +335,7 @@ MHD__gnutls_x509_ext_extract_basicConstraints (int *CA, | |||
520 | if (pathLenConstraint) | 335 | if (pathLenConstraint) |
521 | { | 336 | { |
522 | result = MHD__gnutls_x509_read_uint (ext, "pathLenConstraint", | 337 | result = MHD__gnutls_x509_read_uint (ext, "pathLenConstraint", |
523 | pathLenConstraint); | 338 | (unsigned int*) pathLenConstraint); |
524 | if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) | 339 | if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) |
525 | *pathLenConstraint = -1; | 340 | *pathLenConstraint = -1; |
526 | else if (result != GNUTLS_E_SUCCESS) | 341 | else if (result != GNUTLS_E_SUCCESS) |
@@ -544,552 +359,3 @@ MHD__gnutls_x509_ext_extract_basicConstraints (int *CA, | |||
544 | 359 | ||
545 | return 0; | 360 | return 0; |
546 | } | 361 | } |
547 | |||
548 | /* generate the basicConstraints in a DER encoded extension | ||
549 | * Use 0 or 1 (TRUE) for CA. | ||
550 | * Use negative values for pathLenConstraint to indicate that the field | ||
551 | * should not be present, >= 0 to indicate set values. | ||
552 | */ | ||
553 | int | ||
554 | MHD__gnutls_x509_ext_gen_basicConstraints (int CA, | ||
555 | int pathLenConstraint, | ||
556 | MHD_gnutls_datum_t * der_ext) | ||
557 | { | ||
558 | ASN1_TYPE ext = ASN1_TYPE_EMPTY; | ||
559 | const char *str; | ||
560 | int result; | ||
561 | |||
562 | if (CA == 0) | ||
563 | str = "FALSE"; | ||
564 | else | ||
565 | str = "TRUE"; | ||
566 | |||
567 | result = | ||
568 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext); | ||
569 | if (result != ASN1_SUCCESS) | ||
570 | { | ||
571 | MHD_gnutls_assert (); | ||
572 | return MHD_gtls_asn2err (result); | ||
573 | } | ||
574 | |||
575 | result = MHD__asn1_write_value (ext, "cA", str, 1); | ||
576 | if (result != ASN1_SUCCESS) | ||
577 | { | ||
578 | MHD_gnutls_assert (); | ||
579 | MHD__asn1_delete_structure (&ext); | ||
580 | return MHD_gtls_asn2err (result); | ||
581 | } | ||
582 | |||
583 | if (pathLenConstraint < 0) | ||
584 | { | ||
585 | result = MHD__asn1_write_value (ext, "pathLenConstraint", NULL, 0); | ||
586 | if (result < 0) | ||
587 | result = MHD_gtls_asn2err (result); | ||
588 | } | ||
589 | else | ||
590 | result = MHD__gnutls_x509_write_uint32 (ext, "pathLenConstraint", | ||
591 | pathLenConstraint); | ||
592 | if (result < 0) | ||
593 | { | ||
594 | MHD_gnutls_assert (); | ||
595 | MHD__asn1_delete_structure (&ext); | ||
596 | return result; | ||
597 | } | ||
598 | |||
599 | result = MHD__gnutls_x509_der_encode (ext, "", der_ext, 0); | ||
600 | |||
601 | MHD__asn1_delete_structure (&ext); | ||
602 | |||
603 | if (result < 0) | ||
604 | { | ||
605 | MHD_gnutls_assert (); | ||
606 | return result; | ||
607 | } | ||
608 | |||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | /* generate the keyUsage in a DER encoded extension | ||
613 | * Use an ORed SEQUENCE of GNUTLS_KEY_* for usage. | ||
614 | */ | ||
615 | int | ||
616 | MHD__gnutls_x509_ext_gen_keyUsage (uint16_t usage, MHD_gnutls_datum_t * der_ext) | ||
617 | { | ||
618 | ASN1_TYPE ext = ASN1_TYPE_EMPTY; | ||
619 | int result; | ||
620 | uint8_t str[2]; | ||
621 | |||
622 | result = MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.KeyUsage", &ext); | ||
623 | if (result != ASN1_SUCCESS) | ||
624 | { | ||
625 | MHD_gnutls_assert (); | ||
626 | return MHD_gtls_asn2err (result); | ||
627 | } | ||
628 | |||
629 | str[0] = usage & 0xff; | ||
630 | str[1] = usage >> 8; | ||
631 | |||
632 | result = MHD__asn1_write_value (ext, "", str, 9); | ||
633 | if (result != ASN1_SUCCESS) | ||
634 | { | ||
635 | MHD_gnutls_assert (); | ||
636 | MHD__asn1_delete_structure (&ext); | ||
637 | return MHD_gtls_asn2err (result); | ||
638 | } | ||
639 | |||
640 | result = MHD__gnutls_x509_der_encode (ext, "", der_ext, 0); | ||
641 | |||
642 | MHD__asn1_delete_structure (&ext); | ||
643 | |||
644 | if (result < 0) | ||
645 | { | ||
646 | MHD_gnutls_assert (); | ||
647 | return result; | ||
648 | } | ||
649 | |||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static int | ||
654 | write_new_general_name (ASN1_TYPE ext, const char *ext_name, | ||
655 | MHD_gnutls_x509_subject_alt_name_t type, | ||
656 | const char *data_string) | ||
657 | { | ||
658 | const char *str; | ||
659 | int result; | ||
660 | char name[128]; | ||
661 | |||
662 | result = MHD__asn1_write_value (ext, ext_name, "NEW", 1); | ||
663 | if (result != ASN1_SUCCESS) | ||
664 | { | ||
665 | MHD_gnutls_assert (); | ||
666 | return MHD_gtls_asn2err (result); | ||
667 | } | ||
668 | |||
669 | switch (type) | ||
670 | { | ||
671 | case GNUTLS_SAN_DNSNAME: | ||
672 | str = "dNSName"; | ||
673 | break; | ||
674 | case GNUTLS_SAN_RFC822NAME: | ||
675 | str = "rfc822Name"; | ||
676 | break; | ||
677 | case GNUTLS_SAN_URI: | ||
678 | str = "uniformResourceIdentifier"; | ||
679 | break; | ||
680 | case GNUTLS_SAN_IPADDRESS: | ||
681 | str = "iPAddress"; | ||
682 | break; | ||
683 | default: | ||
684 | MHD_gnutls_assert (); | ||
685 | return GNUTLS_E_INTERNAL_ERROR; | ||
686 | } | ||
687 | |||
688 | if (ext_name[0] == 0) | ||
689 | { /* no dot */ | ||
690 | MHD_gtls_str_cpy (name, sizeof (name), "?LAST"); | ||
691 | } | ||
692 | else | ||
693 | { | ||
694 | MHD_gtls_str_cpy (name, sizeof (name), ext_name); | ||
695 | MHD_gtls_str_cat (name, sizeof (name), ".?LAST"); | ||
696 | } | ||
697 | |||
698 | result = MHD__asn1_write_value (ext, name, str, 1); | ||
699 | if (result != ASN1_SUCCESS) | ||
700 | { | ||
701 | MHD_gnutls_assert (); | ||
702 | return MHD_gtls_asn2err (result); | ||
703 | } | ||
704 | |||
705 | MHD_gtls_str_cat (name, sizeof (name), "."); | ||
706 | MHD_gtls_str_cat (name, sizeof (name), str); | ||
707 | |||
708 | result = MHD__asn1_write_value (ext, name, data_string, strlen (data_string)); | ||
709 | if (result != ASN1_SUCCESS) | ||
710 | { | ||
711 | MHD_gnutls_assert (); | ||
712 | MHD__asn1_delete_structure (&ext); | ||
713 | return MHD_gtls_asn2err (result); | ||
714 | } | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | /* Convert the given name to GeneralNames in a DER encoded extension. | ||
720 | * This is the same as subject alternative name. | ||
721 | */ | ||
722 | int | ||
723 | MHD__gnutls_x509_ext_gen_subject_alt_name (MHD_gnutls_x509_subject_alt_name_t | ||
724 | type, const char *data_string, | ||
725 | MHD_gnutls_datum_t * der_ext) | ||
726 | { | ||
727 | ASN1_TYPE ext = ASN1_TYPE_EMPTY; | ||
728 | int result; | ||
729 | |||
730 | result = | ||
731 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.GeneralNames", &ext); | ||
732 | if (result != ASN1_SUCCESS) | ||
733 | { | ||
734 | MHD_gnutls_assert (); | ||
735 | return MHD_gtls_asn2err (result); | ||
736 | } | ||
737 | |||
738 | result = write_new_general_name (ext, "", type, data_string); | ||
739 | if (result < 0) | ||
740 | { | ||
741 | MHD_gnutls_assert (); | ||
742 | MHD__asn1_delete_structure (&ext); | ||
743 | return result; | ||
744 | } | ||
745 | |||
746 | result = MHD__gnutls_x509_der_encode (ext, "", der_ext, 0); | ||
747 | |||
748 | MHD__asn1_delete_structure (&ext); | ||
749 | |||
750 | if (result < 0) | ||
751 | { | ||
752 | MHD_gnutls_assert (); | ||
753 | return result; | ||
754 | } | ||
755 | |||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | /* generate the SubjectKeyID in a DER encoded extension | ||
760 | */ | ||
761 | int | ||
762 | MHD__gnutls_x509_ext_gen_key_id (const void *id, size_t id_size, | ||
763 | MHD_gnutls_datum_t * der_ext) | ||
764 | { | ||
765 | ASN1_TYPE ext = ASN1_TYPE_EMPTY; | ||
766 | int result; | ||
767 | |||
768 | result = | ||
769 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
770 | "PKIX1.SubjectKeyIdentifier", &ext); | ||
771 | if (result != ASN1_SUCCESS) | ||
772 | { | ||
773 | MHD_gnutls_assert (); | ||
774 | return MHD_gtls_asn2err (result); | ||
775 | } | ||
776 | |||
777 | result = MHD__asn1_write_value (ext, "", id, id_size); | ||
778 | if (result != ASN1_SUCCESS) | ||
779 | { | ||
780 | MHD_gnutls_assert (); | ||
781 | MHD__asn1_delete_structure (&ext); | ||
782 | return MHD_gtls_asn2err (result); | ||
783 | } | ||
784 | |||
785 | result = MHD__gnutls_x509_der_encode (ext, "", der_ext, 0); | ||
786 | |||
787 | MHD__asn1_delete_structure (&ext); | ||
788 | |||
789 | if (result < 0) | ||
790 | { | ||
791 | MHD_gnutls_assert (); | ||
792 | return result; | ||
793 | } | ||
794 | |||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | /* generate the AuthorityKeyID in a DER encoded extension | ||
799 | */ | ||
800 | int | ||
801 | MHD__gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size, | ||
802 | MHD_gnutls_datum_t * der_ext) | ||
803 | { | ||
804 | ASN1_TYPE ext = ASN1_TYPE_EMPTY; | ||
805 | int result; | ||
806 | |||
807 | result = | ||
808 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
809 | "PKIX1.AuthorityKeyIdentifier", &ext); | ||
810 | if (result != ASN1_SUCCESS) | ||
811 | { | ||
812 | MHD_gnutls_assert (); | ||
813 | return MHD_gtls_asn2err (result); | ||
814 | } | ||
815 | |||
816 | result = MHD__asn1_write_value (ext, "keyIdentifier", id, id_size); | ||
817 | if (result != ASN1_SUCCESS) | ||
818 | { | ||
819 | MHD_gnutls_assert (); | ||
820 | MHD__asn1_delete_structure (&ext); | ||
821 | return MHD_gtls_asn2err (result); | ||
822 | } | ||
823 | |||
824 | MHD__asn1_write_value (ext, "authorityCertIssuer", NULL, 0); | ||
825 | MHD__asn1_write_value (ext, "authorityCertSerialNumber", NULL, 0); | ||
826 | |||
827 | result = MHD__gnutls_x509_der_encode (ext, "", der_ext, 0); | ||
828 | |||
829 | MHD__asn1_delete_structure (&ext); | ||
830 | |||
831 | if (result < 0) | ||
832 | { | ||
833 | MHD_gnutls_assert (); | ||
834 | return result; | ||
835 | } | ||
836 | |||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | |||
841 | /* Creates and encodes the CRL Distribution points. data_string should be a name | ||
842 | * and type holds the type of the name. | ||
843 | * reason_flags should be an or'ed sequence of GNUTLS_CRL_REASON_*. | ||
844 | * | ||
845 | */ | ||
846 | int | ||
847 | MHD__gnutls_x509_ext_gen_crl_dist_points (MHD_gnutls_x509_subject_alt_name_t | ||
848 | type, const void *data_string, | ||
849 | unsigned int reason_flags, | ||
850 | MHD_gnutls_datum_t * der_ext) | ||
851 | { | ||
852 | ASN1_TYPE ext = ASN1_TYPE_EMPTY; | ||
853 | MHD_gnutls_datum_t gnames = { NULL, 0 }; | ||
854 | int result; | ||
855 | uint8_t reasons[2]; | ||
856 | |||
857 | reasons[0] = reason_flags & 0xff; | ||
858 | reasons[1] = reason_flags >> 8; | ||
859 | |||
860 | result = | ||
861 | MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
862 | "PKIX1.CRLDistributionPoints", &ext); | ||
863 | if (result != ASN1_SUCCESS) | ||
864 | { | ||
865 | MHD_gnutls_assert (); | ||
866 | result = MHD_gtls_asn2err (result); | ||
867 | goto cleanup; | ||
868 | } | ||
869 | |||
870 | result = MHD__asn1_write_value (ext, "", "NEW", 1); | ||
871 | if (result != ASN1_SUCCESS) | ||
872 | { | ||
873 | MHD_gnutls_assert (); | ||
874 | result = MHD_gtls_asn2err (result); | ||
875 | goto cleanup; | ||
876 | } | ||
877 | |||
878 | if (reason_flags) | ||
879 | { | ||
880 | result = MHD__asn1_write_value (ext, "?LAST.reasons", reasons, 9); | ||
881 | if (result != ASN1_SUCCESS) | ||
882 | { | ||
883 | MHD_gnutls_assert (); | ||
884 | result = MHD_gtls_asn2err (result); | ||
885 | goto cleanup; | ||
886 | } | ||
887 | } | ||
888 | else | ||
889 | { | ||
890 | result = MHD__asn1_write_value (ext, "?LAST.reasons", NULL, 0); | ||
891 | if (result != ASN1_SUCCESS) | ||
892 | { | ||
893 | MHD_gnutls_assert (); | ||
894 | result = MHD_gtls_asn2err (result); | ||
895 | goto cleanup; | ||
896 | } | ||
897 | } | ||
898 | |||
899 | result = MHD__asn1_write_value (ext, "?LAST.cRLIssuer", NULL, 0); | ||
900 | if (result != ASN1_SUCCESS) | ||
901 | { | ||
902 | MHD_gnutls_assert (); | ||
903 | result = MHD_gtls_asn2err (result); | ||
904 | goto cleanup; | ||
905 | } | ||
906 | |||
907 | /* When used as type CHOICE. | ||
908 | */ | ||
909 | result = MHD__asn1_write_value (ext, "?LAST.distributionPoint", "fullName", 1); | ||
910 | if (result != ASN1_SUCCESS) | ||
911 | { | ||
912 | MHD_gnutls_assert (); | ||
913 | result = MHD_gtls_asn2err (result); | ||
914 | goto cleanup; | ||
915 | } | ||
916 | |||
917 | #if 0 | ||
918 | /* only needed in old code (where defined as SEQUENCE OF) */ | ||
919 | MHD__asn1_write_value (ext, | ||
920 | "?LAST.distributionPoint.nameRelativeToCRLIssuer", | ||
921 | NULL, 0); | ||
922 | #endif | ||
923 | |||
924 | result = | ||
925 | write_new_general_name (ext, "?LAST.distributionPoint.fullName", | ||
926 | type, data_string); | ||
927 | if (result < 0) | ||
928 | { | ||
929 | MHD_gnutls_assert (); | ||
930 | goto cleanup; | ||
931 | } | ||
932 | |||
933 | result = MHD__gnutls_x509_der_encode (ext, "", der_ext, 0); | ||
934 | |||
935 | if (result < 0) | ||
936 | { | ||
937 | MHD_gnutls_assert (); | ||
938 | goto cleanup; | ||
939 | } | ||
940 | |||
941 | result = 0; | ||
942 | |||
943 | cleanup: | ||
944 | MHD__gnutls_free_datum (&gnames); | ||
945 | MHD__asn1_delete_structure (&ext); | ||
946 | |||
947 | return result; | ||
948 | } | ||
949 | |||
950 | /* extract the proxyCertInfo from the DER encoded extension | ||
951 | */ | ||
952 | int | ||
953 | MHD__gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint, | ||
954 | char **policyLanguage, | ||
955 | char **policy, | ||
956 | size_t * sizeof_policy, | ||
957 | opaque * extnValue, int extnValueLen) | ||
958 | { | ||
959 | ASN1_TYPE ext = ASN1_TYPE_EMPTY; | ||
960 | int result; | ||
961 | MHD_gnutls_datum_t value; | ||
962 | |||
963 | if ((result = MHD__asn1_create_element | ||
964 | (MHD__gnutls_get_pkix (), "PKIX1.ProxyCertInfo", &ext)) != ASN1_SUCCESS) | ||
965 | { | ||
966 | MHD_gnutls_assert (); | ||
967 | return MHD_gtls_asn2err (result); | ||
968 | } | ||
969 | |||
970 | result = MHD__asn1_der_decoding (&ext, extnValue, extnValueLen, NULL); | ||
971 | if (result != ASN1_SUCCESS) | ||
972 | { | ||
973 | MHD_gnutls_assert (); | ||
974 | MHD__asn1_delete_structure (&ext); | ||
975 | return MHD_gtls_asn2err (result); | ||
976 | } | ||
977 | |||
978 | if (pathLenConstraint) | ||
979 | { | ||
980 | result = MHD__gnutls_x509_read_uint (ext, "pCPathLenConstraint", | ||
981 | pathLenConstraint); | ||
982 | if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) | ||
983 | *pathLenConstraint = -1; | ||
984 | else if (result != GNUTLS_E_SUCCESS) | ||
985 | { | ||
986 | MHD__asn1_delete_structure (&ext); | ||
987 | return MHD_gtls_asn2err (result); | ||
988 | } | ||
989 | } | ||
990 | |||
991 | result = MHD__gnutls_x509_read_value (ext, "proxyPolicy.policyLanguage", | ||
992 | &value, 0); | ||
993 | if (result < 0) | ||
994 | { | ||
995 | MHD_gnutls_assert (); | ||
996 | MHD__asn1_delete_structure (&ext); | ||
997 | return result; | ||
998 | } | ||
999 | |||
1000 | if (policyLanguage) | ||
1001 | *policyLanguage = MHD_gnutls_strdup (value.data); | ||
1002 | |||
1003 | result = MHD__gnutls_x509_read_value (ext, "proxyPolicy.policy", &value, 0); | ||
1004 | if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) | ||
1005 | { | ||
1006 | if (policy) | ||
1007 | *policy = NULL; | ||
1008 | if (sizeof_policy) | ||
1009 | *sizeof_policy = 0; | ||
1010 | } | ||
1011 | else if (result < 0) | ||
1012 | { | ||
1013 | MHD_gnutls_assert (); | ||
1014 | MHD__asn1_delete_structure (&ext); | ||
1015 | return result; | ||
1016 | } | ||
1017 | else | ||
1018 | { | ||
1019 | if (policy) | ||
1020 | *policy = value.data; | ||
1021 | if (sizeof_policy) | ||
1022 | *sizeof_policy = value.size; | ||
1023 | } | ||
1024 | |||
1025 | MHD__asn1_delete_structure (&ext); | ||
1026 | |||
1027 | return 0; | ||
1028 | } | ||
1029 | |||
1030 | /* generate the proxyCertInfo in a DER encoded extension | ||
1031 | */ | ||
1032 | int | ||
1033 | MHD__gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint, | ||
1034 | const char *policyLanguage, | ||
1035 | const char *policy, | ||
1036 | size_t sizeof_policy, | ||
1037 | MHD_gnutls_datum_t * der_ext) | ||
1038 | { | ||
1039 | ASN1_TYPE ext = ASN1_TYPE_EMPTY; | ||
1040 | int result; | ||
1041 | |||
1042 | result = MHD__asn1_create_element (MHD__gnutls_get_pkix (), | ||
1043 | "PKIX1.ProxyCertInfo", &ext); | ||
1044 | if (result != ASN1_SUCCESS) | ||
1045 | { | ||
1046 | MHD_gnutls_assert (); | ||
1047 | return MHD_gtls_asn2err (result); | ||
1048 | } | ||
1049 | |||
1050 | if (pathLenConstraint < 0) | ||
1051 | { | ||
1052 | result = MHD__asn1_write_value (ext, "pCPathLenConstraint", NULL, 0); | ||
1053 | if (result < 0) | ||
1054 | result = MHD_gtls_asn2err (result); | ||
1055 | } | ||
1056 | else | ||
1057 | result = MHD__gnutls_x509_write_uint32 (ext, "pCPathLenConstraint", | ||
1058 | pathLenConstraint); | ||
1059 | if (result < 0) | ||
1060 | { | ||
1061 | MHD_gnutls_assert (); | ||
1062 | MHD__asn1_delete_structure (&ext); | ||
1063 | return result; | ||
1064 | } | ||
1065 | |||
1066 | result = MHD__asn1_write_value (ext, "proxyPolicy.policyLanguage", | ||
1067 | policyLanguage, 1); | ||
1068 | if (result < 0) | ||
1069 | { | ||
1070 | MHD_gnutls_assert (); | ||
1071 | MHD__asn1_delete_structure (&ext); | ||
1072 | return MHD_gtls_asn2err (result); | ||
1073 | } | ||
1074 | |||
1075 | result = MHD__asn1_write_value (ext, "proxyPolicy.policy", | ||
1076 | policy, sizeof_policy); | ||
1077 | if (result < 0) | ||
1078 | { | ||
1079 | MHD_gnutls_assert (); | ||
1080 | MHD__asn1_delete_structure (&ext); | ||
1081 | return MHD_gtls_asn2err (result); | ||
1082 | } | ||
1083 | |||
1084 | result = MHD__gnutls_x509_der_encode (ext, "", der_ext, 0); | ||
1085 | |||
1086 | MHD__asn1_delete_structure (&ext); | ||
1087 | |||
1088 | if (result < 0) | ||
1089 | { | ||
1090 | MHD_gnutls_assert (); | ||
1091 | return result; | ||
1092 | } | ||
1093 | |||
1094 | return 0; | ||
1095 | } | ||