diff options
author | tb <> | 2022-03-14 21:15:49 +0000 |
---|---|---|
committer | tb <> | 2022-03-14 21:15:49 +0000 |
commit | e4f8fb22773f4dee1da3875ddc02bfcfa39198f4 (patch) | |
tree | cf453def12c05205d1d4cc78cc18a174a34edfe0 /src/lib | |
parent | 07d9625933f5867c4dee9ecde797f4222f5dc516 (diff) | |
download | openbsd-e4f8fb22773f4dee1da3875ddc02bfcfa39198f4.tar.gz openbsd-e4f8fb22773f4dee1da3875ddc02bfcfa39198f4.tar.bz2 openbsd-e4f8fb22773f4dee1da3875ddc02bfcfa39198f4.zip |
Rework ownership handling in x509_constraints_validate()
Instead of having the caller allocate and pass in a new
x509_constraints_name struct, handle allocation inside
x509_constraints_validate(). Also make the error optional.
All this is done to simplify the call sites and to make it
more obvious that there are no leaks.
ok jsing
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/x509/x509_alt.c | 11 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_constraints.c | 72 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_internal.h | 5 |
3 files changed, 49 insertions, 39 deletions
diff --git a/src/lib/libcrypto/x509/x509_alt.c b/src/lib/libcrypto/x509/x509_alt.c index 35aae6f185..845ab1364f 100644 --- a/src/lib/libcrypto/x509/x509_alt.c +++ b/src/lib/libcrypto/x509/x509_alt.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_alt.c,v 1.10 2022/03/13 16:48:49 tb Exp $ */ | 1 | /* $OpenBSD: x509_alt.c,v 1.11 2022/03/14 21:15:49 tb Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project. | 3 | * project. |
4 | */ | 4 | */ |
@@ -657,17 +657,14 @@ v2i_GENERAL_NAME_ex(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, | |||
657 | */ | 657 | */ |
658 | 658 | ||
659 | if (is_nc) { | 659 | if (is_nc) { |
660 | struct x509_constraints_name constraints_name; | 660 | struct x509_constraints_name *constraints_name = NULL; |
661 | int error = 0; | ||
662 | 661 | ||
663 | memset(&constraints_name, 0, sizeof(constraints_name)); | 662 | if (!x509_constraints_validate(ret, &constraints_name, NULL)) { |
664 | type = x509_constraints_validate(ret, &constraints_name, &error); | ||
665 | if (type == 0 || error != 0) { | ||
666 | X509V3error(X509V3_R_BAD_OBJECT); | 663 | X509V3error(X509V3_R_BAD_OBJECT); |
667 | ERR_asprintf_error_data("name=%s", name); | 664 | ERR_asprintf_error_data("name=%s", name); |
668 | goto err; | 665 | goto err; |
669 | } | 666 | } |
670 | x509_constraints_name_clear(&constraints_name); | 667 | x509_constraints_name_free(constraints_name); |
671 | return ret; | 668 | return ret; |
672 | } | 669 | } |
673 | 670 | ||
diff --git a/src/lib/libcrypto/x509/x509_constraints.c b/src/lib/libcrypto/x509/x509_constraints.c index 27d87d4c11..6e88a94189 100644 --- a/src/lib/libcrypto/x509/x509_constraints.c +++ b/src/lib/libcrypto/x509/x509_constraints.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_constraints.c,v 1.23 2022/03/13 17:23:02 tb Exp $ */ | 1 | /* $OpenBSD: x509_constraints.c,v 1.24 2022/03/14 21:15:49 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
4 | * | 4 | * |
@@ -896,21 +896,34 @@ x509_constraints_extract_names(struct x509_constraints_names *names, | |||
896 | */ | 896 | */ |
897 | int | 897 | int |
898 | x509_constraints_validate(GENERAL_NAME *constraint, | 898 | x509_constraints_validate(GENERAL_NAME *constraint, |
899 | struct x509_constraints_name *name, int *error) | 899 | struct x509_constraints_name **out_name, int *out_error) |
900 | { | 900 | { |
901 | uint8_t *bytes = NULL; | 901 | uint8_t *bytes = NULL; |
902 | size_t len = 0; | 902 | size_t len = 0; |
903 | struct x509_constraints_name *name; | ||
904 | int error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; | ||
903 | int name_type; | 905 | int name_type; |
904 | 906 | ||
907 | if (out_name == NULL || *out_name != NULL) | ||
908 | return 0; | ||
909 | |||
910 | if (out_error != NULL) | ||
911 | *out_error = 0; | ||
912 | |||
913 | if ((name = x509_constraints_name_new()) == NULL) { | ||
914 | error = X509_V_ERR_OUT_OF_MEM; | ||
915 | goto err; | ||
916 | } | ||
917 | |||
905 | name_type = x509_constraints_general_to_bytes(constraint, &bytes, &len); | 918 | name_type = x509_constraints_general_to_bytes(constraint, &bytes, &len); |
906 | switch (name_type) { | 919 | switch (name_type) { |
907 | case GEN_DIRNAME: | 920 | case GEN_DIRNAME: |
908 | if (bytes == NULL || (name->der = malloc(len)) == NULL) { | ||
909 | *error = X509_V_ERR_OUT_OF_MEM; | ||
910 | return 0; | ||
911 | } | ||
912 | if (len == 0) | 921 | if (len == 0) |
913 | goto err; /* XXX The RFCs are delightfully vague */ | 922 | goto err; /* XXX The RFCs are delightfully vague */ |
923 | if (bytes == NULL || (name->der = malloc(len)) == NULL) { | ||
924 | error = X509_V_ERR_OUT_OF_MEM; | ||
925 | goto err; | ||
926 | } | ||
914 | memcpy(name->der, bytes, len); | 927 | memcpy(name->der, bytes, len); |
915 | name->der_len = len; | 928 | name->der_len = len; |
916 | name->type = GEN_DIRNAME; | 929 | name->type = GEN_DIRNAME; |
@@ -919,8 +932,8 @@ x509_constraints_validate(GENERAL_NAME *constraint, | |||
919 | if (!x509_constraints_valid_domain_constraint(bytes, len)) | 932 | if (!x509_constraints_valid_domain_constraint(bytes, len)) |
920 | goto err; | 933 | goto err; |
921 | if ((name->name = strdup(bytes)) == NULL) { | 934 | if ((name->name = strdup(bytes)) == NULL) { |
922 | *error = X509_V_ERR_OUT_OF_MEM; | 935 | error = X509_V_ERR_OUT_OF_MEM; |
923 | return 0; | 936 | goto err; |
924 | } | 937 | } |
925 | name->type = GEN_DNS; | 938 | name->type = GEN_DNS; |
926 | break; | 939 | break; |
@@ -933,8 +946,8 @@ x509_constraints_validate(GENERAL_NAME *constraint, | |||
933 | len)) | 946 | len)) |
934 | goto err; | 947 | goto err; |
935 | if ((name->name = strdup(bytes)) == NULL) { | 948 | if ((name->name = strdup(bytes)) == NULL) { |
936 | *error = X509_V_ERR_OUT_OF_MEM; | 949 | error = X509_V_ERR_OUT_OF_MEM; |
937 | return 0; | 950 | goto err; |
938 | } | 951 | } |
939 | } | 952 | } |
940 | name->type = GEN_EMAIL; | 953 | name->type = GEN_EMAIL; |
@@ -954,17 +967,24 @@ x509_constraints_validate(GENERAL_NAME *constraint, | |||
954 | if (!x509_constraints_valid_domain_constraint(bytes, len)) | 967 | if (!x509_constraints_valid_domain_constraint(bytes, len)) |
955 | goto err; | 968 | goto err; |
956 | if ((name->name = strdup(bytes)) == NULL) { | 969 | if ((name->name = strdup(bytes)) == NULL) { |
957 | *error = X509_V_ERR_OUT_OF_MEM; | 970 | error = X509_V_ERR_OUT_OF_MEM; |
958 | return 0; | 971 | goto err; |
959 | } | 972 | } |
960 | name->type = GEN_URI; | 973 | name->type = GEN_URI; |
961 | break; | 974 | break; |
962 | default: | 975 | default: |
963 | break; | 976 | break; |
964 | } | 977 | } |
978 | |||
979 | *out_name = name; | ||
980 | |||
965 | return 1; | 981 | return 1; |
982 | |||
966 | err: | 983 | err: |
967 | *error = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; | 984 | x509_constraints_name_free(name); |
985 | if (out_error != NULL) | ||
986 | *out_error = error; | ||
987 | |||
968 | return 0; | 988 | return 0; |
969 | } | 989 | } |
970 | 990 | ||
@@ -974,7 +994,7 @@ x509_constraints_extract_constraints(X509 *cert, | |||
974 | struct x509_constraints_names *excluded, | 994 | struct x509_constraints_names *excluded, |
975 | int *error) | 995 | int *error) |
976 | { | 996 | { |
977 | struct x509_constraints_name *vname; | 997 | struct x509_constraints_name *vname = NULL; |
978 | NAME_CONSTRAINTS *nc = cert->nc; | 998 | NAME_CONSTRAINTS *nc = cert->nc; |
979 | GENERAL_SUBTREE *subtree; | 999 | GENERAL_SUBTREE *subtree; |
980 | int i; | 1000 | int i; |
@@ -989,24 +1009,20 @@ x509_constraints_extract_constraints(X509 *cert, | |||
989 | *error = X509_V_ERR_SUBTREE_MINMAX; | 1009 | *error = X509_V_ERR_SUBTREE_MINMAX; |
990 | return 0; | 1010 | return 0; |
991 | } | 1011 | } |
992 | if ((vname = x509_constraints_name_new()) == NULL) { | 1012 | if (!x509_constraints_validate(subtree->base, &vname, error)) |
993 | *error = X509_V_ERR_OUT_OF_MEM; | ||
994 | return 0; | ||
995 | } | ||
996 | if (x509_constraints_validate(subtree->base, vname, error) == | ||
997 | 0) { | ||
998 | x509_constraints_name_free(vname); | ||
999 | return 0; | 1013 | return 0; |
1000 | } | ||
1001 | if (vname->type == 0) { | 1014 | if (vname->type == 0) { |
1002 | x509_constraints_name_free(vname); | 1015 | x509_constraints_name_free(vname); |
1016 | vname = NULL; | ||
1003 | continue; | 1017 | continue; |
1004 | } | 1018 | } |
1005 | if (!x509_constraints_names_add(permitted, vname)) { | 1019 | if (!x509_constraints_names_add(permitted, vname)) { |
1006 | x509_constraints_name_free(vname); | 1020 | x509_constraints_name_free(vname); |
1021 | vname = NULL; | ||
1007 | *error = X509_V_ERR_OUT_OF_MEM; | 1022 | *error = X509_V_ERR_OUT_OF_MEM; |
1008 | return 0; | 1023 | return 0; |
1009 | } | 1024 | } |
1025 | vname = NULL; | ||
1010 | } | 1026 | } |
1011 | 1027 | ||
1012 | for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { | 1028 | for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { |
@@ -1015,24 +1031,20 @@ x509_constraints_extract_constraints(X509 *cert, | |||
1015 | *error = X509_V_ERR_SUBTREE_MINMAX; | 1031 | *error = X509_V_ERR_SUBTREE_MINMAX; |
1016 | return 0; | 1032 | return 0; |
1017 | } | 1033 | } |
1018 | if ((vname = x509_constraints_name_new()) == NULL) { | 1034 | if (!x509_constraints_validate(subtree->base, &vname, error)) |
1019 | *error = X509_V_ERR_OUT_OF_MEM; | ||
1020 | return 0; | 1035 | return 0; |
1021 | } | ||
1022 | if (x509_constraints_validate(subtree->base, vname, error) == | ||
1023 | 0) { | ||
1024 | x509_constraints_name_free(vname); | ||
1025 | return 0; | ||
1026 | } | ||
1027 | if (vname->type == 0) { | 1036 | if (vname->type == 0) { |
1028 | x509_constraints_name_free(vname); | 1037 | x509_constraints_name_free(vname); |
1038 | vname = NULL; | ||
1029 | continue; | 1039 | continue; |
1030 | } | 1040 | } |
1031 | if (!x509_constraints_names_add(excluded, vname)) { | 1041 | if (!x509_constraints_names_add(excluded, vname)) { |
1032 | x509_constraints_name_free(vname); | 1042 | x509_constraints_name_free(vname); |
1043 | vname = NULL; | ||
1033 | *error = X509_V_ERR_OUT_OF_MEM; | 1044 | *error = X509_V_ERR_OUT_OF_MEM; |
1034 | return 0; | 1045 | return 0; |
1035 | } | 1046 | } |
1047 | vname = NULL; | ||
1036 | } | 1048 | } |
1037 | 1049 | ||
1038 | return 1; | 1050 | return 1; |
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h index c64992a9ee..c6ce5229ad 100644 --- a/src/lib/libcrypto/x509/x509_internal.h +++ b/src/lib/libcrypto/x509/x509_internal.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_internal.h,v 1.17 2022/03/13 17:08:04 tb Exp $ */ | 1 | /* $OpenBSD: x509_internal.h,v 1.18 2022/03/14 21:15:49 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
4 | * | 4 | * |
@@ -101,6 +101,7 @@ time_t x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notafter); | |||
101 | struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); | 101 | struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); |
102 | 102 | ||
103 | void x509_constraints_name_clear(struct x509_constraints_name *name); | 103 | void x509_constraints_name_clear(struct x509_constraints_name *name); |
104 | void x509_constraints_name_free(struct x509_constraints_name *name); | ||
104 | int x509_constraints_names_add(struct x509_constraints_names *names, | 105 | int x509_constraints_names_add(struct x509_constraints_names *names, |
105 | struct x509_constraints_name *name); | 106 | struct x509_constraints_name *name); |
106 | struct x509_constraints_names *x509_constraints_names_dup( | 107 | struct x509_constraints_names *x509_constraints_names_dup( |
@@ -127,7 +128,7 @@ int x509_constraints_extract_constraints(X509 *cert, | |||
127 | struct x509_constraints_names *permitted, | 128 | struct x509_constraints_names *permitted, |
128 | struct x509_constraints_names *excluded, int *error); | 129 | struct x509_constraints_names *excluded, int *error); |
129 | int x509_constraints_validate(GENERAL_NAME *constraint, | 130 | int x509_constraints_validate(GENERAL_NAME *constraint, |
130 | struct x509_constraints_name *name, int *error); | 131 | struct x509_constraints_name **out_name, int *error); |
131 | int x509_constraints_check(struct x509_constraints_names *names, | 132 | int x509_constraints_check(struct x509_constraints_names *names, |
132 | struct x509_constraints_names *permitted, | 133 | struct x509_constraints_names *permitted, |
133 | struct x509_constraints_names *excluded, int *error); | 134 | struct x509_constraints_names *excluded, int *error); |