aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/x509/extensions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/x509/extensions.c')
-rw-r--r--src/daemon/https/x509/extensions.c736
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 */
267static int
268set_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 */
323static int
324overwrite_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 */
366int
367MHD__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 */
553int
554MHD__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 */
615int
616MHD__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
653static int
654write_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 */
722int
723MHD__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 */
761int
762MHD__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 */
800int
801MHD__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 */
846int
847MHD__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
943cleanup:
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 */
952int
953MHD__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 */
1032int
1033MHD__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}