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 | |
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
-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); |