This reverts a small portion of
8c8629bfd8. The parsers for ANY remain
unchanged, but we inadvertently changed a corner case of ASN1_PRINTABLE
MSTRINGs. This is a huge mess.
utype in these switch cases is usually the type of the ASN1_ITEM, but,
with ANY and MSTRING, it is the tag of the value we found. (An MSTRING
or "multi-string" is a CHOICE of string-like types.)
When parsing ANY, this is moot because the is_supported_universal_type
logic ensures we'll never pass in an invalid type. When encoding ANY,
this only happens if you manually construct such an ASN1_TYPE.
MSTRINGs *should* be similar because of the bitmask they apply on tag
types. However, there is one MSTRING type whose bitmask,
B_ASN1_PRINTABLE, includes B_ASN1_UNKNOWN. ASN1_tag2bit, arbitrarily
maps eight unsupported tags to B_ASN1_UNKNOWN and instead of zero. These
are:
- ObjectDescriptor
- EXTERNAL
- REAL
- EMBEDDED PDV
- RELATIVE-OID
- TIME (note this is not the same as the X.509 Time CHOICE type)
- [UNIVERSAL 15], which is not even a defined type!
- CHARACTER STRING
(ENUMERATED is also mapped to B_ASN1_UNKNOWN, but it's supported.)
These eight tags were previously accepted in d2i_X509_NAME but
8c8629bfd8 inadvertently started rejecting
them. For now, restore the default in the switch/case so that we accept
them again. Per https://crbug.com/boringssl/412, attribute values are
ANY DEFINED BY types, so we actually should be accepting *all* types. We
do not, because B_ASN1_PRINTABLE is completely incoherent. But because
ANY is the correct type, going from the original incoherent set, to
this new, smaller incoherent set is arguably a regression.
This is a minimal fix. Long-term, we should handle that ANY correctly,
and avoid unexpected ASN1_STRING type values, by mapping all unsupported
types to V_ASN1_OTHER. This would allow us to support all types
correctly. A follow-up change will do that.
Update-Note: The X.509 name parser will go back to accepting a handful
of universal tag types that were inadvertently rejected in
8c8629bfd8. It is extremely unlikely that
anyone uses these as they're unsupported, obscure types. This CL also
makes our ASN1_TYPE encoder slightly more permissive again, if the
caller manually constructs an legacy in-memory representation of an
unsupported tag. But the follow-up change will restore the stricter
behavior.
Bug: 412, 561
Change-Id: Ia44a270f12f3021154761a1cd285707416d8787e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58705
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Also unexport PEM_proc_type and PEM_dek_info. They're never called
externally, just private functions within one file. Also, while I'm
here, fix the include guard on asn1/internal.h.
Bug: 516
Change-Id: I6961a65f638e7b464a8c349663898a954d7826b4
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58548
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
I mistakenly thought no one needed X509 as an ASN1_ITEM, but that wasn't
true. wpa_supplicant relies on this. Restore this and add a test for it.
As with the rest of the rewrite, this is currently a little tedious. I'm
hoping that, as the internals are rewritten with CBS and CBB, we can
establish some cleaner patterns and abstractions.
Bug: 547
Change-Id: I761ee058f8ec916b2ec7f4730a764d46d72f1f10
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58285
Commit-Queue: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Now that the preceding CL has isolated the X.509 signature hack, we can
apply the strictness across the legacy parser. This is particularly
important for the TBSCertificate parser, where it is ambiguous which
value one checks the signature over. (Officially, you're supposed to
re-encode as DER. In practice, people don't do this.)
This change means many of our primitive types are actually parsed as
DER. I've removed the bug references in the comment in the documentation
where I believe they're finally correct.
Update-Note: Non-minimal lengths in certificates are no longer accepted,
as required for standards compliance. The one exception is the signature
field, where we still carry an exception. Some of this was already
enforced by libssl's parser.
Bug: 354
Change-Id: I57cfa7df9e1ec5707390e9b32fe1ec6b5d8172f9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58186
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
OpenSSL's ASN1_STRING representation has many cases. There's a grab-bag
V_ASN1_OTHER cases that can represent any element. But it is currently
only used for non-universal tags. Unknown universal tags go into the
type field directly.
This has a few problems:
- Certain high values, V_ASN1_NEG_INTEGER and V_ASN1_NEG_ENUMERATED,
are treated special. This was one of the two causes behind
CVE-2016-2108 and had to be worked around with V_ASN1_MAX_UNIVERSAL.
- OpenSSL can never compatibly support a new universal type in a
non-ASN1_STRING form. Otherwise ASN1_TYPE's union changes its
in-memory representation.
- It is a bit ambiguous when OpenSSL does or doesn't know the type.
- This is broadly implemented by having a default in all the
switch/cases, which is a little awkward.
- It's yet another "unknown tag" case when V_ASN1_OTHER covers such
cases just fine.
Remove this representation and use V_ASN1_OTHER. This more unambiguously
resolves CVE-2016-2108. ASN1_STRING's and ASN1_TYPE's respective type
fields are now a closed set. Update the documenthation accordingly.
Formally allowing universal types in ASN1_STRING also opens the door to
clearing the ASN1_PRINTABLE mess (https://crbug.com/boringssl/412).
BoringSSL currently rejects X.509 names that are actually valid, because
the OpenSSL X509_NAME representation cannot represent them. This allows
us to introduce an ASN1_STRING-based ANY representation, which just
represents all non-ASN1_STRING types in an V_ASN1_OTHER.
The implementation is a little clumsy (the way things tasn_dec.c is
written, I had to introduce yet another check), but I'm hoping that,
when the parser is rewritten with CBS, this can be integrated into a
single type dispatch.
Update-Note: This does not change the set of inputs accepted or rejected
by the ASN.1 parser. It does, however, change the in-memory
representation in edge cases. Unless the application was specifically
inspecting the in-memory representation for these unknown types, we
expect this to have no impact.
Fixed: 561
Change-Id: Ibf9550e285ce50b11c7609d28b139354b9dd41dc
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58148
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Removing object reuse makes it dramatically simpler. Along the way, lift
the OID validity checker into crypto/bytestring, so we can use it more
generally. (Although the difference between invalid OID and unknown OID
is pretty academic, so this check isn't that important.)
For now I've preserved the existing behavior, where the OID validity
checker accepts arbitrarily large OID components. Though this results in
an oddity where the OID to string functions reject inputs that the
parser accepts. (There we only allow up to 2^64-1.)
Update-Note: When we removed object-reuse from all the d2i functions, we
missed one d2i_ASN1_OBJECT. See
https://boringssl-review.googlesource.com/c/boringssl/+/56647.
Otherwise, this CL is not expected to change behavior.
Change-Id: If4d2d83d9f3c96abfdc268e156f2cf3a9a903b0c
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58147
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
These functions already don't go through tasn_*.c. Rewrite them to use
CBS and CBB. This removes some dependencies on ASN1_get_object and
ASN1_put_object.
Update-Note: d2i_ASN1_OBJECT and d2i_ASN1_BOOLEAN will no longer accept
non-minimal length prefixes (forbidden in DER). d2i_ASN1_BOOLEAN will
also no longer accept non-canonical representations of TRUE (also
forbidden in DER). This does not affect certificate parsing, as that
still goes through the old template system, though we will make a
similar change to those functions later.
Bug: 354, 548
Change-Id: I0b7aa96f47aca5c31ec4f702e27108b4106311f2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58145
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
ASN1_TYPE is a union of a bunch of pointer types. Often it takes a
shorthand and accesses a->value.ptr directly. This is allowed in C, but
not C++. Writing the switch/case barely takes more code, so just write
it that way.
Along the way, extract the code for cleaning up an ASN1_TYPE from
tasn_fre.c. This is a small step towards being able to use crypto/asn1's
types without depending on the templates. ASN1_TYPE_free still, for now,
calls into the templates. That will be fixable once tasn_*.c are
rewritten a bit further.
This also removes the weird hack here ASN1_primitive_free (an internal
function) with NULL ASN1_ITEM secretly meant to partially clean up the
ASN1_TYPE. We can just call the function directly now.
Bug: 574
Change-Id: Ie2ba41418801a366ab2f12eccc01e8dadf82c33e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58126
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
An in-progress rewrite of tasn_dec.c accidentally broke this, so add a
regression test.
Bug: 548
Change-Id: Iac6a23acbc08459187c96a2f6471f0aa97d445a1
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58125
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
ASN1_item_ex_i2d() does not take ownership of the memory pointed at by
*out, so it's the caller's responsibility to free it on error.
Change-Id: Id8cb70e50f280944418629a32b53fd4ca248b0bd
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/57805
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
No new tests because they're actually caught by our own tests. I just
forgot to put UBSan on CI! Will fix this shortly.
For BLAKE2, fix this by checking for zero. For c2i_ASN1_INTEGER,
rewrite it with CBS, which has the side effect of avoiding this. (It's
effectively maintaining in->data + start as a temporary, rather than
start itself.)
Bug: fuchsia:46910
Change-Id: I9366f1ba4fd0b0140d64c56e0534d7b060ab90e5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/57687
Commit-Queue: David Benjamin <davidben@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Remove all the other ERR_R_MALLOC_FAILURES from the
codebase.
Also changes cbb to push to the error stack, to correctly
report cbb failures instead of now only reporting
malloc failures. Previously it turned all cbb failures
into a malloc failure
Bug: 564
Change-Id: Ic13208bf9d9aaa470e83b2f15782fc94946bbc7b
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/57046
Auto-Submit: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
The output of ASN1_generate_v3 is *mostly* linear with the input, except
SEQ and SET reference config sections. Sections can be referenced
multiple times, and so the structure grows exponentially.
Cap the total output size to mitigate this. As before, we don't consider
these functions safe to use with untrusted inputs, but unbounded growth
will frustrate fuzzing. This CL sets the limit to 64K, which should be
enough for anyone. (This is the size of a single X.509 extension,
whereas certificates themselves should not get that large.)
While not strictly necessary, this also rearranges the
ASN1_mbstring_copy call to pass in a maximum output. This portion does
scale linearly with the output, so it's fine, but the fuzzer discovered
an input with a 700K-byte input, which, with fuzzer instrumentation and
sanitizers, seems to be a bit slow. This change should help the fuzzer
get past those cases faster.
Update-Note: The stringly-typed API for constructing X.509 extensions
now has a maximum output size. If anyone was constructing an extension
larger than 64K, this will break. This is unlikely and should be caught
by unit tests; if a project hits this outside of tests, that means they
are passing untrusted input into this function, which is a security
vulnerability in itself, and means they especially need this change to
avoid a DoS.
Bug: oss-fuzz:55725
Change-Id: Ibb65854293f44bf48ed5855016ef7cd46d2fae77
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/57125
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
We still keep time_t stuff around for calling time() and
for external interfaces that are meant to give you time_t
values, but we stop using time_t internally. For publicly
exposed and used inputs that rely on time_t, _posix versions are
added to support providing times as an int64_t, and internal
use is changed to use the _posix version.
Several legacy functions which are extensivly used and
and use pointers to time_t are retained for compatibility,
along with posix time versions of them which we use exclusively.
This fixes the tests which were disabled on 32 bit platorms
to always run.
Update-Note: This is a potentially breaking change for things
that bind to the ASN1_[UTC|GENERALIZED]TIME_set and ASN1_TIME_adj
family of functions (and can not type convert a time_t to an
int64).
Bug: 416
Change-Id: Ic4daba5a299d8f35191853742640750a1ecc53d6
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/54765
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
The "object reuse" mode in d2i_FOO is extremely problematic. See bug for
details. When we rewrite d2i_RSAPublicKey, etc., with CBS, we switched
dropped this fragile behavior and replaced it with freeing the old value
and replacing it with the new value. Extend this behavior to all functions
generated by crypto/asn1 templates too.
In particular, tasn_dec.c already frees the original object on error,
which means callers must already be prepared for OpenSSL to free their
reused object. The one caller I found that would be incompatible (via
both running tests and auditing callers) was actually broken due to this
error case, and has been fixed.
Update-Note: This slightly changes the calling convention of the d2i_FOO
functions. The change should be compatible with almost all valid calls.
If something goes wrong, it should hopefully be quite obvious. If
affected (or unaffected), prefer to set the output parameter to NULL
and use the return value instead.
Fixed: 550
Change-Id: Ie54cdf17f8f5a4d76fdbcddeaa27e6afd3fa9d8e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56647
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Instead, move the CRYPTO_BUFFER into ASN1_ENCODING (due to padding,
upgrading the two bitfields do a pointer doesn't increase memory usage),
and instead thread a CRYPTO_BUFFER parameter through tasn_dec.c.
Later, I want to reimplement the X509 and X509_CINF parsers with CBS/CBB
directly (https://crbug.com/boringssl/547), but that will be easier once
the whole crypto/asn1 machinery is rewritten with CBS/CBB
(https://crbug.com/boringssl/548). That, in turn, will be easier with
object reuse gone. But to get rid of object reuse, I need to remove the
one place in the library where we ourselves use it.
Bug: 550
Change-Id: Ia4df3da9280f808b124ac1f4ad58745dfe0f49e2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56646
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Caught by running malloc failure tests on unit tests.
Bug: 563
Change-Id: Ic0167ef346a282dc8b5a26a1cedafced7fef9ed0
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56927
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
and isxdigit.
All of these can be affected by locale, and although we weren't using
them directly (except for isxdigit) we instead had manual versions inline
everywhere.
While I am here add OPENSSL_fromxdigit and deduplicate a bunch of code
in hex decoders pulling out a hex value.
Change-Id: Ie75a4fba0f043208c50b0bb14174516462c89673
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56648
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
This feature is unused and, if I recall, doesn't actually work. (OpenSSL
1.1.0 or so had to rework the feature significantly.) It would actually
be nice to embed some fields, but I think that's better done by just
switching the parsers to imperative CBS/CBB calls.
One less feature to support in the new parsers.
Bug: 548
Change-Id: If10a0d9f1ba5eb09c7e570ab7327fb42fa2bd987
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56189
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Currently, the only EXTERN type is X509_NAME. Implicitly tagging an
X509_NAME didn't work anyway because of the cached encoding. Moreover,
even if it did work, it'd be invalid. Name in RFC 5280 is actually a
one-element CHOICE type, and CHOICE types can never be implicitly
tagged. So just remove support.
One thing of note: I'm thinking EXTERN can be used later to retain
ASN1_ITEM compatibility, once X509 and friends no longer use the
template machinery. That means we're not only assuming X509_NAME is
never implicitly tagged, but also that external callers using
<openssl/asn1t.h> won't implicitly tag a built-in type.
This removes a case we need to handle in the rewritten tasn_enc.c. (In
particular, crypto/asn1 and crypto/bytestring use a different tag
representation and I'd like to minimum the number of conversions we
need.)
Update-Note: IMPLEMENT_EXTERN_ASN1 can no longer be used outside the
library. I found no callers using this machinery, and we're better off
gradually migrating every <openssl/asn1t.h> user to CBS/CBB anyway.
Bug: 548
Change-Id: I0aab531077d25960dd3f16183656f318d78a0806
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56186
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
I didn't quite handle this case correctly in
https://boringssl-review.googlesource.com/c/boringssl/+/49350, which
made it impossible to express an OPTIONAL, doubly-tagged type in
crypto/asn1.
For some background, an ASN1_ITEM is a top-level type, while an
ASN1_TEMPLATE is roughly a field in a SEQUENCE or SET. In ASN.1, types
cannot be OPTIONAL or DEFAULT, only fields, so something like
ASN1_TFLG_OPTIONAL is a flag an ASN1_TEMPLATE.
However, there are many other type-level features that are applied as
ASN1_TEMPLATE flags. SEQUENCE OF T and SET OF T are represented as an
ASN1_TEMPLATE with the ASN1_TFLG_SEQUENCE_OF or ASN1_TFLG_SET_OF flag
and an item of T. Tagging is also a feature of ASN1_TEMPLATE.
But some top-level ASN.1 types may be SEQUENCE OF T or be tagged. So one
of the types of ASN1_ITEM is ASN1_ITEM_TEMPLATE, which is an ASN1_ITEM
that wraps an ASN1_TEMPLATE (which, in turn, wraps an ASN1_ITEM...).
Such an ASN1_ITEM could then be placed in a SEQUENCE or SET, where it is
OPTIONAL.
We didn't correctly handle this case and instead lost the optional bit.
Fix this and add a test. This is a little interesting because it means
asn1_template_ex_i2d may get an optional bit from the caller, or it may
get one from the template itself. (But it will never get both. An
ASN1_ITEM_TEMPLATE cannot wrap an optional template because types are
not optional.)
This case doesn't actually come up, given it doesn't work today. But in
my pending rewrite of tasn_enc.c, it made more sense to just make it
work, so this CL fixes it and adds a test ahead of time.
Bug: 548
Change-Id: I0cf8c25386ddff992bafae029a5a60d026f124d0
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56185
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
ASN1_BOOLEAN has these ASN1_FBOOLEAN and ASN1_TBOOLEAN variants that
behave slightly strangely. Add some tests to ensure we don't break them
in the rewrite.
In doing so, fix a bug: ASN1_BOOLEAN canonically represents TRUE as
0xff, to match DER. But ASN1_TBOOLEAN is initialized with it->size,
which is 1, not 0xff. Fix it to be 0xff. (This shouldn't actually matter
because the encoder is lax and ASN1_TBOOLEAN doesn't encode TRUE
anyway.)
Bug: 548
Change-Id: I4e7fdc2a3bc87603eaf04a7668359006a1480c2e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56187
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
Between the type being sometimes a tri-state and capturing the
underlying DER/BER representation, this type is a bit confusing. Add
constants for these.
I've left a case in ASN1_TBOOLEAN unconverted because it's actually
wrong. It will be fixed in a subsequent CL.
Change-Id: I75d846af14f6b4cd5278c3833b979e89c92c4203
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56487
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
I inadvertently removed it, but set_string(NULL, str) would validate str
without writing an object. OpenSSL's habit of dual-use functions isn't
great (this behavior masked a bug in another project), but I apparently
even documented it in the header, so restore the behavior.
Change-Id: I8b4dbe5a2b21eb59cb20e4c845b17761329b34a1
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55785
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
tag and utype are always accessed as int, so make the structs match.
Boolean ASN1_ITEMs put an ASN1_BOOLEAN in it->size, so add a cast. Also
fix the time set_string functions to call the underlying CBS parser
directly, so they don't need to put a strlen into an int.
Bug: 516
Change-Id: Ie10e7eaf58ec0b0dec59813a0ddcb0197fce1fd1
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55449
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
We currently shift between unsigned long and int.
Bug: 516
Change-Id: I9e3fcc9393e24a352a2c08b9df0650a508d7a60b
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55448
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
I have a use for these in the chrome verifier conversions, we
could choose to make them hidden again after a future move to
boringssl..
Change-Id: If059debbdf482d64577ad04c1ec4f9c82724de1e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55305
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
One less function to make size_t-clean.
Update-Note: All callers of this function since been removed.
Change-Id: I4cd77ede5f58cdbc3cf65365a8fd23967545ecfa
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55269
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
ASN1_ENCODING has a 'modified' bit, but every time it is set, the
contents are both ignored and never filled in again (we don't fill in
the encoding except on parse). That means keeping the underlying buffer
around is just wasting memory. Remove the bit and use the len != 0 to
determine if there's a saved encoding. Replace all the modified bits
with a helper function that drops the encoding.
I don't think we need a separate "present" boolean and can just treat
empty as not saved; a cached value always has a tag and length, so it
cannot be empty. (Even if it could be empty, that would imply the
value's encoding is trivial enough that we probably don't need the saved
encoding to preserve the value.)
Change-Id: I6beda94d33f3799daf85f1397818b9a41e7dd18a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55267
Commit-Queue: Adam Langley <agl@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
We use unsigned, but we actually assume it is 32-bit for the bit-packing
strategy. But also introduce a typedef to hint that callers shouldn't
treat it as an arbitrary 32-bit integer. A typedef would also allow us
to extend to uint64_t in the future, if we ever need to.
Update-Note: Some APIs switch from unsigned * to uint32_t * out
pointers. This is only source-compatible if unsigned and uint32_t are
the exact same type. The CQ suggests this is indeed true. If they are
not, replace unsigned with CBS_ASN1_TAG to fix the build.
Bug: 525
Change-Id: I45cbe127c1aa252f5f6a169dca2e44d1e6e1d669
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/54986
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
We have a number of APIs that cannot migrate to size_t because OpenSSL
used negative numbers as some special indicator. This makes it hard to
become size_t-clean.
However, in reality, the largest buffer size is SSIZE_MAX, or, more
accurately PTRDIFF_MAX. But every platform I've ever seen make ptrdiff_t
and size_t the same size. malloc is just obligated to fail allocations
that don't fit in ssize_t. ssize_t itself is not portable (Windows
doesn't have it), but we can define ossl_ssize_t to be ptrdiff_t.
OpenSSL also has an ossl_ssize_t (though they don't use it much), so
we're also improving compatibility.
Start this out with ASN1_STRING_set. It still internally refuses to
construct a string bigger than INT_MAX; the struct can't hold this and
even if we fix the struct, no other code, inside or outside the library,
can tolerate it. But now code which passes in a size_t (including our
own) can do so without overflow.
Bug: 428, 516
Change-Id: I17aa6971733f34dfda7d971882d0f062e92340e9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/54953
Commit-Queue: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
OpenSSL uses integer parameters for this function, and the
multiplication here ends up being done as an integer. Since we
support values up to year 9999, it is possible for someone to pass
in a number of days to the "adj" function to adjust a base time far
enough to overflow a 32 bit integer.
Change-Id: Iedfc33d8bf90d70049f99897df1d193fb29805d0
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55125
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Should the string be INT_MAX, we cannot actually represent the output
length. i2c_ASN1_INTEGER and ASN1_object_size have checks this, but this
was missing it.
Change-Id: I7cf5debb87568b876f3799308ef4ad6d2b1ff7e6
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55085
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
cbb_add_utf8 is CBB-based, so it is bounds-checked.
Change-Id: Ib30272255894d7d3a35a164a5eefcdce9e8e7991
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/54646
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
https://boringssl-review.googlesource.com/c/boringssl/+/54307 added just
the getters because no one was using the setters yet. But our long
setter *already* implements the int64 version, so just complete the
whole set and deprecate the old long-based APIs.
Change-Id: Ieb793f3cf90d4214c6416ba2f10e641c46403188
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/54526
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
The C11 change has survived for three months now. Let's start freely
using static_assert. In C files, we need to include <assert.h> because
it is a macro. In C++ files, it is a keyword and we can just use it. (In
MSVC C, it is actually also a keyword as in C++, but close enough.)
I moved one assert from ssl3.h to ssl_lib.cc. We haven't yet required
C11 in our public headers, just our internal files.
Change-Id: Ic59978be43b699f2c997858179a9691606784ea5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53665
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
We only care about dates within years 0000 to 9999 for
RFC5280. timegm() is only semi-standard. Some things require the
setting awkward defines to get libc to give it to you. Other things
let you have it but make it stop working at year 3000. Still other
things have 32 bit time_t.....
Let's just make our own that actually works. all the time, does
everything with an int64_t, and fails if you want to send something
out that would overflow a 32 bit time_t.
In the process of doing this, we get rid of the old Julian date stuff
from OpenSSL, which while functional was a bit awkward dealing only
with days, and using the Julian calendar as the reference point instead of potentially something more useful. Julian seconds since Jan 1 1970
00:00:00 UCT are much more useful to us than Julian days since a
Julian epoch.
The OS implementations of timegm() and gmtime() also can be pretty
complex, due to the nature of needing multiple timezone, daylight
saving, day of week, and other stuff we simply do not need for
doing things with certificate times. A small microbenchmark of
10000000 of each operation comparing this implementation to
the system version on my M1 mac gives:
bbe-macbookpro:tmp bbe$ time ./openssl_gmtime
real 0m0.152s
user 0m0.127s
sys 0m0.018s
bbe-macbookpro:tmp bbe$ time ./gmtime
real 0m0.422s
user 0m0.403s
sys 0m0.014s
bbe-macbookpro:tmp bbe$ time ./openssl_timegm
real 0m0.041s
user 0m0.015s
sys 0m0.019s
bbe-macbookpro:tmp bbe$ time ./timegm
real 0m30.432s
user 0m30.383s
sys 0m0.040s
Similarly On a glinux machine:
bbe@bbe-glinux1:~$ time ./openssl_gmtime
real 0m0.157s
user 0m0.152s
sys 0m0.008s
bbe@bbe-glinux1:~$ time ./gmtime
real 0m0.336s
user 0m0.336s
sys 0m0.002s
bbe@bbe-glinux1:~$ time ./openssl_timegm
real 0m0.018s
user 0m0.019s
sys 0m0.002s
bbe@bbe-glinux1:~$ time ./timegm
real 0m0.680s
user 0m0.671s
sys 0m0.011s
bbe@bbe-glinux1:~$
Bug: 501
Change-Id: If445272d365f2c9673b5f3264d082af1a342e0a1
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53245
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
ASN1_STRING_set saves having to manually manage the ASN1_STRING's
buffer. Also size that buffer correctly and align the free_s vs tmps
mismatch.
We can also assume OPENSSL_gmtime writes to the passed-in struct tm.
Every other caller already assumes this, and both POSIX (gmtime_r) and C
(gmtime_s) agree this is valid.
Finally, the cleanup logic is much simpler if we do all the time stuff
before handling the maybe-object-reuse bits.
Change-Id: I25befc8fa93a1a60246c6abcea6e5d58ee563b48
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53227
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Switch to the CBS functions, which do all the checks together. This
resolves a TODO that ASN1_STRING_print_ex was inconsistently checking
for invalid codepoints. It also removes an optimization when
round-tripping UTF-8. This optimization was incorrect if the input was
invalid.
Finally, this removes UTF8_getc, which no longer has any callers.
(I've left UTF8_putc for now because CBB would force a malloc on every
character, even with CBB_init_fixed. We should either decide we don't
care, or make it possible to stack-allocate the cbb_buffer_st.)
Update-Note: This will make ASN1_STRING_print_ex newly fail, but such
inputs should be unreachable from the parser as of an earlier change.
Change-Id: I52d747c500c6f5f9ef659cdee3ef5d241f38ed21
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53226
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
This checks validity for UTF8String, BMPString, and UniversalString.
When we detach the core types from ASN1_ITEM, this will likely also be
reshuffled around, probably into type-specific functions. But for now
just get the checks in place.
Update-Note: Invalid strings in X.509 certificates and other ASN.1
structures will now be rejected. This change is less risky than it seems
because most strings in X.509 are in X509_NAME, which already rejected
invalid instances of these string types (but not other string types)
during canonicalization. See https://crbug.com/boringssl/412 for a
discussion of that mess.
Bug: 427
Change-Id: I0d7e24dfd841703d2a8581ec4e78ed5bc3862d75
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53225
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Our free functions all tolerate NULL.
Change-Id: Ifcb3185c8d2f34afb83f7286c3463136edc926fa
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53125
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
No sense in keeping two around. This does cause the functions to reject
some previously accepted invalid inputs. These were intentionally
accepted by
https://boringssl-review.googlesource.com/c/boringssl/+/13082 for
an old version of M2Crypto, but I belive we no longer need to be
compatible with that.
Update-Note: ASN1_TIME_print, ASN1_UTCTIME_print, and
ASN1_GENERALIZEDTIME_print will no longer accept various invalid inputs.
Change-Id: I4606d0b39585a19eb4b984ac809706e497a3f799
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53090
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
The comment says (in the now outdated orflags terms) that we don't need
to worry about this case because is_first/is_last only affect ASCII
codepoints, but it's easier to just set it correctly.
Change-Id: Ib6db66adb162a555da50f563ffc9af9da4a878ec
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53126
Reviewed-by: Adam Langley <agl@google.com>