Rewrite tasn_enc and tasn_dec with CBS/CBB

OpenSSL's ASN.1 parser is a marvel. It is a pile of undocumented macros,
which build tables of struct fields and pointer offers. Those tables are
evaluated in the tasn_* files, in a sort of home-grown reflection in C.
All throughout, it is permeated with unchecked integer overflows and one
of the most error-prone calling conventions (d2i and i2d) I've ever
seen.

ASN.1 is actually quite easy to parse, if you don't do it this way.
Ideally we would remove this system entirely, but there are external
users of <openssl/asn1t.h>, and it will take time to rewrite all our
parsers. Replace the machinery with CBS/CBB under the hood. This fixes
the mess of integer overflows, etc., which we were previously mitigating
by capping the input length.  The calling conventions outside CBS/CBB
remain the messy d2i/i2d convention. The type-safety risks also remain.
Those can only be fixed by migrating individual types off of this
parser.

Beyond fixing the bad calling convention, this rewrite fixes a few bugs
in table evaluator:

- If a type with an explicit tag (an ASN1_ITEM_TEMPLATE) is then wrapped
  in an implicit tag, the old parser would reject it, but this is valid
  and easy to support.

- A type with an explicit tag could not be optional, but this is easy to
  support.

- An ASN1_ITEM_TEMPLATE cannot point to an optional ASN1_TEMPLATE.

The tagging issues are captured in the updated tests.

Now that tasn_enc is based on CBB, this also switches the EXTERN hook to
CBB-style instead of i2d-style.

There is still some work in tasn_* that it would be nice to do later:

- The ADB (ANY DEFINED BY) stuff pulls in a dependency on the big OID
  table and it's only used by one type. If we detach that dependency,
  tasn_* will no longer pull in the table.

- We should remove string types that we don't actually use, to reduce
  the number of string types we need to write checkers for.

- It's made of strict aliasing violations.

- As we move types off of this framework, we should be able to trim more
  unused features. The few external users are much more limited. "enc"
  and "cb" are potential candidates.

- It accepts invalid DER. In general, any type that needs invalid DER
  should move off this framework (really all types should move off) and
  instead manually activate the parsing bug. Then the general parser can
  be strict and deviations are limited to known fields.

Bug: 42290418
Change-Id: I8a4ce577ac09ea52063c83832fbd9f11f3261fd7
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/97159
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
9 files changed
tree: 1e2d9a8b8bdc3a5cd746d5b794913f20e1d4a966
  1. .bcr/
  2. .github/
  3. bench/
  4. cmake/
  5. crypto/
  6. decrepit/
  7. docs/
  8. fuzz/
  9. gen/
  10. include/
  11. infra/
  12. pki/
  13. rust/
  14. ssl/
  15. third_party/
  16. tool/
  17. util/
  18. .bazelignore
  19. .bazelrc
  20. .bazelversion
  21. .clang-format
  22. .clang-format-ignore
  23. .clangd
  24. .gitattributes
  25. .gitignore
  26. API-CONVENTIONS.md
  27. AUTHORS
  28. BREAKING-CHANGES.md
  29. BUILD.bazel
  30. build.json
  31. BUILDING.md
  32. CMakeLists.txt
  33. codereview.settings
  34. CONTRIBUTING.md
  35. FUZZING.md
  36. go.mod
  37. go.sum
  38. INCORPORATING.md
  39. LICENSE
  40. MODULE.bazel
  41. MODULE.bazel.lock
  42. PORTING.md
  43. PRESUBMIT.py
  44. PrivacyInfo.xcprivacy
  45. README.md
  46. SANDBOXING.md
  47. SECURITY.md
  48. STYLE.md
README.md

BoringSSL

BoringSSL is a fork of OpenSSL that is designed to meet Google's needs.

Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing so is likely to be frustrating because there are no guarantees of API or ABI stability.

Programs ship their own copies of BoringSSL when they use it and we update everything as needed when deciding to make API changes. This allows us to mostly avoid compromises in the name of compatibility. It works for us, but it may not work for you.

BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved in maintaining all these patches in multiple places was growing steadily.

Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the NDK) and a number of other apps/programs.

Project links:

To file a security issue, use the Chromium process and mention in the report this is for BoringSSL. You can ignore the parts of the process that are specific to Chromium/Chrome.

There are other files in this directory which might be helpful: