summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2022-03-14 21:15:49 +0000
committertb <>2022-03-14 21:15:49 +0000
commite4f8fb22773f4dee1da3875ddc02bfcfa39198f4 (patch)
treecf453def12c05205d1d4cc78cc18a174a34edfe0
parent07d9625933f5867c4dee9ecde797f4222f5dc516 (diff)
downloadopenbsd-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.c11
-rw-r--r--src/lib/libcrypto/x509/x509_constraints.c72
-rw-r--r--src/lib/libcrypto/x509/x509_internal.h5
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 */
897int 897int
898x509_constraints_validate(GENERAL_NAME *constraint, 898x509_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);
101struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc); 101struct x509_verify_ctx *x509_verify_ctx_new_from_xsc(X509_STORE_CTX *xsc);
102 102
103void x509_constraints_name_clear(struct x509_constraints_name *name); 103void x509_constraints_name_clear(struct x509_constraints_name *name);
104void x509_constraints_name_free(struct x509_constraints_name *name);
104int x509_constraints_names_add(struct x509_constraints_names *names, 105int x509_constraints_names_add(struct x509_constraints_names *names,
105 struct x509_constraints_name *name); 106 struct x509_constraints_name *name);
106struct x509_constraints_names *x509_constraints_names_dup( 107struct 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);
129int x509_constraints_validate(GENERAL_NAME *constraint, 130int x509_constraints_validate(GENERAL_NAME *constraint,
130 struct x509_constraints_name *name, int *error); 131 struct x509_constraints_name **out_name, int *error);
131int x509_constraints_check(struct x509_constraints_names *names, 132int 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);