Correctly handle invalid ASN1_OBJECTs when encoding.

asn1_ex_i2c actually does have an error condition, it just wasn't being

628b3c7f2fdf68519c27dc087c400ca616616f4e, imported from upstream's
f3f8e72f494b36d05e0d04fe418f92b692fbb261, tried to check for OID-less
ASN1_OBJECTs and return an error. But it and the upstream change didn't
actually work. -1 in this function means to omit the object, so OpenSSL
was silently misinterpreting the input structure.

This changes the calling convention for asn1_ex_i2c to support this. It
is, unfortunately, a little messy because:

1. One cannot check for object presense without walking the
   ASN1_ITEM/ASN1_TEMPLATE structures. You can *almost* check if *pval
   is NULL, but ASN1_BOOLEAN is an int with -1 to indicate an omitted
   optional. There are also FBOOLEAN/TBOOLEAN types that omit FALSE/TRUE
   for DEFAULT. Thus, without more invasive changes, asn1_ex_i2c must be
   able to report an omitted element.

2. While the i2d functions report an omitted element by successfully
   writing zero bytes, i2c only writes the contents. It thus must
   distinguish between an omitted element and an element with
   zero-length contents.

3. i2c_ASN1_INTEGER and i2c_ASN1_BIT_STRING return zero on error rather
   than -1. Those error paths are not actually reachable because they
   only check for NULL. In fact, OpenSSL has even unexported them. But I
   found a few callers. Rather than unwind all this and change the
   calling convention, I've just made it handle 0 and map to -1 for now.
   It's all a no-op anyway, and hopefully we can redo all this with CBB

I've just added an output parameter for now.

In writing tests, I also noticed that the hand-written i2d_ASN1_OBJECT
and i2d_ASN1_BOOLEAN return the wrong value for errors, so I've fixed

Update-Note: A default-constructed object with a required ASN1_OBJECT
field can no longer be encoded without initializing the ASN1_OBJECT.
Note this affects X509: the signature algorithm is an ASN1_OBJECT. Tests
that try to serialize an X509_new() must fill in all required fields.
(Production code is unlikely to be affected because the output was
unparsable anyway, while tests sometimes wouldn't notice.)

Bug: 429
Change-Id: I04417f5ad6b994cc5ccca540c8a7714b9b3af33d
Commit-Queue: David Benjamin <>
Reviewed-by: Adam Langley <>
4 files changed
tree: 3ec5cef25e8f8d1e6f488d62c7b0a1b591c29937
  1. .github/
  2. crypto/
  3. decrepit/
  4. fuzz/
  5. include/
  6. ssl/
  7. third_party/
  8. tool/
  9. util/
  10. .clang-format
  11. .gitignore
  15. CMakeLists.txt
  16. codereview.settings
  19. go.mod
  20. go.sum
  26. sources.cmake


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:

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