boringssl/crypto
David Benjamin da7f0c65ef Unwind X509_LU_RETRY and fix a lot of type confusion.
(This change will be sent upstream. Since the legacy X.509 stack is just
kept around for compatibility, if they decide to fix it in a different
way, we may wish to revert this and apply their fix.)

Dating back to SSLeay, X509_LOOKUP_METHOD had this X509_LU_RETRY
machinery. But it's not documented and it appears to have never worked.

Problems with the existing logic:

- X509_LU_* is not sure whether it is a type enum (to be passed into
  X509_LOOKUP_by_*) or a return enum (to be retained by those same
  functions).

- X509_LOOKUP_by_* is not sure whether it returns 0/1 or an X509_LU_*
  value.  Looking at the functions themselves, one might think it's the
  latter, but for X509_LOOKUP_by_subject returning both 0 and
  X509_LU_FAIL. But looking at the call sites, some expect 0/1 (such as
  X509_STORE_get1_certs) while others expect an X509_LU_* enum (such as
  X509_STORE_CTX_get1_issuer). It is very fortunate that FAIL happens to
  be 0 and X509 happens to be 1.

  These functions primarily call to X509_LOOKUP_METHOD hooks. Looking
  through OpenSSL itself and code checked into Google, I found no
  evidence that any hooks have been implemented except for
  get_by_subject in by_dir.c. We take that one as definitive and observe
  it believes it returns 0/1. Notably, it returns 1 on success even if
  asked for a type other than X509_LU_X509. (X509_LU_X509 = 1. Others are
  different.) I found another piece of third-party software which corroborates
  this worldview.

- X509_STORE_get_by_subject's handling of X509_LU_RETRY (it's the j < 0
  check) is broken. It saves j into vs->current_method where it probably
  meant to save i. (This bug has existed since SSLeay.)

  It also returns j (supposedly X509_LU_RETRY) while all callers of
  X509_STORE_get_by_subject expect it to return 0/1 by checking with !
  instead of <= 0. (Note that all other codepaths return 0 and 1 so this
  function did not actually believe it returned X509_LU_* most of the
  time.)

  This, in turn, gives us a free of uninitialized pointers in
  X509_STORE_get1_certs and other functions which expect that *ret is
  filled in if X509_STORE_get_by_subject returns success. GCC 4.9 with
  optimizations from the Android NDK noticed this, which trigged this
  saga.

  (It's only reachable if any X509_LOOKUP_METHOD returned
  X509_LU_RETRY.)

- Although the code which expects X509_STORE_get_by_subject return 0/1
  does not date to SSLeay, the X509_STORE_get_by_subject call in
  X509_STORE_CTX_get1_issuer *does* (though, at the time, it was inline
  in X509_verify_cert. That code believes X509_STORE_get_by_subject
  returns an X509_LU_* enum, but it doesn't work either! It believes
  *ret is filled in on X509_LU_RETRY, thus freeing another uninitialized
  pointer (GCC noticed this too).

Since this "retry" code has clearly never worked, from SSLeay onwards,
unwind it completely rather than attempt to fix it. No
X509_LOOKUP_METHOD can possibly have depended on it.

Matching all non-broken codepaths X509_LOOKUP_by_* now returns 0/1 and
X509_STORE_get_by_subject returns 0/1. X509_LU_* is purely a type enum
with X509_LU_{REJECT,FAIL} being legacy constants to keep old code
compiling. (Upstream is recommended to remove those values altogether
for 1.1.0.)

On the off chance any get_by_* X509_LOOKUP_METHOD implementations did
not return 0/1 (I have found no evidence anywhere of this, and I believe
it wouldn't have worked anyway), the X509_LOOKUP_by_* wrapper functions
will coerce the return values back to 0/1 before passing up to the
callers which want 0/1. This both avoids the error-prone -1/0/1 calling
convention and, more importantly, avoids problems with third-party
callers which expect a X509_LU_* return code. 0/1 collide with FAIL/X509
while -1 will collide with RETRY and might confuse things.

Change-Id: I98ecf6fa7342866b9124dc6f0b422cb9ce4a1ae7
Reviewed-on: https://boringssl-review.googlesource.com/8303
Reviewed-by: Adam Langley <agl@google.com>
2016-06-16 16:24:44 +00:00
..
aes Switch all 'num' parameters in crypto/modes to unsigned. 2016-04-19 17:56:25 +00:00
asn1 Remove ASN.1 BIOs. 2016-06-14 17:39:30 +00:00
base64 Replace base64 decoding. 2016-05-26 17:59:10 +00:00
bio Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
bn Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
buf Add BUF_MEM_reserve. 2016-05-18 19:09:06 +00:00
bytestring Make tls_open_record always in-place. 2016-06-08 18:39:07 +00:00
chacha Revert "Import chacha-x86.pl fix." 2016-06-09 19:49:12 +00:00
cipher Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
cmac Fix some malloc test failures. 2016-03-28 17:17:32 +00:00
conf Add missing internal includes. 2016-03-20 16:38:54 +00:00
curve25519 Add missing copyright header. 2016-06-08 20:13:46 +00:00
des
dh Call |BN_mod_exp_mont_consttime| in crypto/dh. 2016-05-11 22:34:19 +00:00
digest Revert md_len removal from SHA256_CTX and SHA512_CTX. 2016-04-27 19:01:23 +00:00
dsa Fix DSA, preserve BN_FLG_CONSTTIME 2016-06-07 19:29:18 +00:00
ec Use different bit tricks to extend the LSB. 2016-04-25 23:05:20 +00:00
ecdh
ecdsa Drop support for engines-provided signature verification. 2016-04-18 20:40:17 +00:00
engine
err Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
evp Fix the name of OPENSSL_add_all_algorithms_conf. 2016-06-15 21:29:50 +00:00
hkdf Fix HKDF leak. 2016-05-20 15:42:01 +00:00
hmac Reimplement PKCS#12 key derivation. 2016-04-19 18:16:38 +00:00
lhash Use non-deprecated methods on windows. 2016-05-19 20:30:50 +00:00
md4 Revert md_len removal from SHA256_CTX and SHA512_CTX. 2016-04-27 19:01:23 +00:00
md5 Revert md_len removal from SHA256_CTX and SHA512_CTX. 2016-04-27 19:01:23 +00:00
modes Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
newhope Be consistent about 𝑥_tests.txt 2016-06-06 15:57:46 +00:00
obj Split unlock functions into read/write variants. 2016-05-31 21:09:29 +00:00
pem Reject inappropriate private key encryption ciphers. 2016-05-03 16:30:08 +00:00
perlasm perlasm/x86_64-xlate.pl: handle binary constants early. 2016-03-17 18:23:40 +00:00
pkcs8 Add standalone PKCS#8 and SPKI fuzzers. 2016-04-25 21:57:28 +00:00
poly1305 Be consistent about 𝑥_tests.txt 2016-06-06 15:57:46 +00:00
rand Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
rc4 Remove RC4_options from rc4-586.pl. 2016-04-22 21:14:11 +00:00
rsa Split unlock functions into read/write variants. 2016-05-31 21:09:29 +00:00
sha Revert md_len removal from SHA256_CTX and SHA512_CTX. 2016-04-27 19:01:23 +00:00
stack Fix stack macro const-ness. 2016-05-13 18:24:57 +00:00
test Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
x509 Unwind X509_LU_RETRY and fix a lot of type confusion. 2016-06-16 16:24:44 +00:00
x509v3 Remove ASN1_parse and ASN1_parse_dump. 2016-06-14 17:39:17 +00:00
CMakeLists.txt Banish SSL_add_dir_cert_subjects_to_stack and OPENSSL_DIR_CTX to decrepit. 2016-04-27 18:40:25 +00:00
constant_time_test.c Update constant-time operations. 2014-11-10 13:48:30 -08:00
cpu-aarch64-linux.c Rewrite ARM feature detection. 2016-03-26 04:54:44 +00:00
cpu-arm-linux.c Make CRYPTO_is_NEON_capable aware of the buggy CPU. 2016-04-28 16:42:21 +00:00
cpu-arm.c Rewrite ARM feature detection. 2016-03-26 04:54:44 +00:00
cpu-intel.c Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
crypto.c Add CRYPTO_has_asm. 2016-05-17 19:03:31 +00:00
ex_data.c Split unlock functions into read/write variants. 2016-05-31 21:09:29 +00:00
internal.h Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
mem.c Include intrin.h under cover of warning pragmas. 2016-06-16 16:12:32 +00:00
refcount_c11.c
refcount_lock.c Split unlock functions into read/write variants. 2016-05-31 21:09:29 +00:00
refcount_test.c
thread_none.c Split unlock functions into read/write variants. 2016-05-31 21:09:29 +00:00
thread_pthread.c Split unlock functions into read/write variants. 2016-05-31 21:09:29 +00:00
thread_test.c Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
thread_win.c Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
thread.c Wrap MSVC-only warning pragmas in a macro. 2016-06-09 21:29:36 +00:00
time_support.c