Sort various X.509 global lists sooner
These functions need a lot more work, documentation, warnings
that using them isn't a good idea, and really we should just remove them
entirely.
But, for now, this is a minimal fix to the most egregious of issues: not
only are the functions themselves not thread-safe (i.e. you must call it
in some program-global initialization), but using them puts you in a
state where future uses of the X.509 library are not thread-safe! Fix
the latter by sorting the list at the point we're already mutating
things.
Re-sorting a list after every addition is not a particularly sensible
implementation, but we can assume these lists will only ever contain
O(1) entries.
(The sort calls date to
https://boringssl-review.googlesource.com/c/boringssl/+/27304, but the
issue was there before. Prior to that CL, sk_FOO_find implicitly sorted
the list. That CL made sk_FOO_find itself a const operation, necessary
for this, and just added explicit sk_FOO_sort calls to preserve the
existing behavior, initially.)
Change-Id: I063b8e708eaf17dfe66c5a3e8d33733adb3297e9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58385
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c
index 1329a9f..553a0ae 100644
--- a/crypto/x509/x509_trs.c
+++ b/crypto/x509/x509_trs.c
@@ -152,7 +152,6 @@
if (!trtable) {
return -1;
}
- sk_X509_TRUST_sort(trtable);
if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) {
return -1;
}
@@ -216,6 +215,10 @@
// If its a new entry manage the dynamic table
if (idx == -1) {
+ // TODO(davidben): This should be locked. Alternatively, remove the dynamic
+ // registration mechanism entirely. The trouble is there no way to pass in
+ // the various parameters into an |X509_VERIFY_PARAM| directly. You can only
+ // register it in the global table and get an ID.
if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
trtable_free(trtmp);
return 0;
@@ -224,6 +227,7 @@
trtable_free(trtmp);
return 0;
}
+ sk_X509_TRUST_sort(trtable);
}
return 1;
}
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index d985cb7..f14a531 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -554,6 +554,8 @@
}
int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) {
+ // TODO(davidben): This should be locked. Alternatively, remove the dynamic
+ // registration mechanism entirely.
X509_VERIFY_PARAM *ptmp;
if (!param_table) {
param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
@@ -562,8 +564,6 @@
}
} else {
size_t idx;
-
- sk_X509_VERIFY_PARAM_sort(param_table);
if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param)) {
ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
X509_VERIFY_PARAM_free(ptmp);
@@ -573,6 +573,7 @@
if (!sk_X509_VERIFY_PARAM_push(param_table, param)) {
return 0;
}
+ sk_X509_VERIFY_PARAM_sort(param_table);
return 1;
}
@@ -599,7 +600,6 @@
pm.name = (char *)name;
if (param_table) {
size_t idx;
- sk_X509_VERIFY_PARAM_sort(param_table);
if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm)) {
return sk_X509_VERIFY_PARAM_value(param_table, idx);
}
diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c
index d006a5e..5a3c3e8 100644
--- a/crypto/x509v3/v3_lib.c
+++ b/crypto/x509v3/v3_lib.c
@@ -78,6 +78,7 @@
}
int X509V3_EXT_add(X509V3_EXT_METHOD *ext) {
+ // TODO(davidben): This should be locked. Also check for duplicates.
if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) {
ext_list_free(ext);
return 0;
@@ -86,6 +87,7 @@
ext_list_free(ext);
return 0;
}
+ sk_X509V3_EXT_METHOD_sort(ext_list);
return 1;
}
@@ -113,7 +115,6 @@
return NULL;
}
- sk_X509V3_EXT_METHOD_sort(ext_list);
if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp)) {
return NULL;
}
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index 71b2c6d..8c254e8 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -201,7 +201,6 @@
return -1;
}
- sk_X509_PURPOSE_sort(xptable);
if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp)) {
return -1;
}
@@ -267,6 +266,10 @@
// If its a new entry manage the dynamic table
if (idx == -1) {
+ // TODO(davidben): This should be locked. Alternatively, remove the dynamic
+ // registration mechanism entirely. The trouble is there no way to pass in
+ // the various parameters into an |X509_VERIFY_PARAM| directly. You can only
+ // register it in the global table and get an ID.
if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
xptable_free(ptmp);
return 0;
@@ -275,6 +278,7 @@
xptable_free(ptmp);
return 0;
}
+ sk_X509_PURPOSE_sort(xptable);
}
return 1;
}