Nothing uses it, and I've never seen an ASN.1 spec use ANY DEFINED BY
with an integer selector. (Although X.680 1997 does seem to allow it.)
Change-Id: Ie1076f58838e4b889c5e6e12e9ca6dd1012472e7
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51636
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Along the way, add ASN1_INTEGER_get_uint64 from upstream, which has much
better error-handling. Also fold the IntegerSetting test into the main
integer test as the test data is largely redundant.
Change-Id: I7ec84629264ebf405bea4bce59a13c4495d81ed7
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51634
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
It's a little simpler to avoid messing around with malloc. It also
allows ASN1_STRING to internally reuse its buffer or realloc.
Change-Id: I12c9f8f7c1a22f3bcc919f5fcc8b00d442cf10f9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51633
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
This fixes several issues around ASN1_INTEGER handling. First, invalid
INTEGERs (not allowed in BER or DER) will no longer be accepted by
d2i_ASN1_INTEGER. This aligns with upstream OpenSSL, which became strict
in 6c5b6cb035666d46495ccbe4a4f3d5e3a659cd40, part of OpenSSL 1.1.0.
In addition to matching the standard, this is needed to avoid
round-tripping issues: ASN1_INTEGER uses a sign-and-magnitude
representation, different from the DER two's complement representation.
That means we cannot represent invalid DER INTEGERs. Attempting to do so
messes up some invariants and causes values to not round-trip correctly
when re-encoded. Thanks to Tavis Ormandy for catching this.
Next, this CL tidies the story around invalid ASN1_INTEGERs (non-minimal
and negative zero). Although we will never produce them in parsing, it
is still possible to manually construct them with ASN1_STRING APIs.
Historically (CVE-2016-2108), it was possible to get them out of the
parser, due to a different bug, *and* i2d_ASN1_INTEGER had a memory
error in doing so. That different bug has since been fixed, but we
should still handle them correctly and test this. (To that end, this CL
adds a test we ought to have added importing upstream's
3661bb4e7934668bd99ca777ea8b30eedfafa871 back in
c4eec0c16b02c97a62a95b6a08656c3a9ddb6baa.)
As the two's complement invariants are subtle as it is, I've opted to
just fix the invalid values before encoding. However, invalid
ASN1_INTEGERs still do not quite work right because ASN1_INTEGER_get,
ASN1_INTEGER_cmp, and ASN1_STRING_cmp will all return surprising values
with them. I've left those alone.
Finally, that leads to the zero value. Almost every function believes
the representation of 0 is a "\0" rather than "". However, a
default-constructed INTEGER, like any other string type, is "". Those do
not compare as equal. crypto/asn1 treats ASN1_INTEGER generically as
ASN1_STRING enough that I think changing the other functions to match is
cleaner than changing default-constructed ASN1_INTEGERs. Thus this CL
removes all the special cases around zero.
Update-Note: Invalid INTEGERs will no longer parse, but they already
would not have parsed in OpenSSL. Additionally, zero is now internally
represented as "" rather than "\0".
Bug: 354
Change-Id: Id4d51a18f32afe90fd4df7455b21e0c8bdbc5389
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51632
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
These functions need some work, but first avoid the duplicate versions.
See also upstream's 6c5b6cb035666d46495ccbe4a4f3d5e3a659cd40.
Update-Note: ASN1_INTEGER_to_BN and ASN1_ENUMERATED_to_BN will now fail
when called on an ASN1_STRING/ASN1_INTEGER/ASN1_ENUMERATED (they're all
the same type) with the wrong runtime type value. Previously, callers
that mixed them up would get the right answer on positive values and
silently misinterpret the input on negative values. This change matches
OpenSSL's 1.1.0's behavior.
Change-Id: Ie01366003f7b2e49477cb73eaf7eaac26d86675d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51631
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
While unlikely, ASN1_STRING_cmp is allowed to return INT_MIN (by way of
memcmp), in which case negating would overflow.
Change-Id: Iec63a6acfad2c662493d22a0acea39ca630881c8
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51630
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
This extends the old ASN1_INTEGER_set tests to cover all integers. There
are a whole bunch of ways to construct and convert ASN1_INTEGERs (DER,
BIGNUM, uint64_t, long, etc.). Rather than maintain one set of test
vectors for small numbers and another for BIGNUMs, this CL makes a
single set of BIGNUM-based test vectors.
Notably, this test now covers:
- Serialization and deserialization
- ASN1_INTEGER_get, not just ASN1_INTEGER_set
- BIGNUM conversions
- ASN1_INTEGER_cmp
Later CLs will add to this or change code covered by it.
Change-Id: I05bd6bc9e70c392927937c2f727cee25092802a1
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51629
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Now we only have one BER/DER TLV parser. Annoyingly, this uses the CBS
BER function, not the DER one. This is because Android sometimes needs
allow a non-minimal length in certificate signature fields (see
b/18228011).
For now, this CL calls CBS_get_any_ber_asn1_element. This is still an
improvement over the old parser because we'll reject non-minimal tags
(which are actually even forbidden in BER). Later, we should move the
special case to just the signature field, and ultimately to a
preprocessing step specific to that part of Android.
Update-Note: Invalid certificates (and the few external structures using
asn1t.h) with incorrectly-encoded tags will now be rejected.
Bug: 354
Change-Id: I56a7faa1ffd51ee38cc315ebaddaef98079fd90e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51626
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Fixes build on NetBSD.
Fixed: 483
Change-Id: I329eb327b67590828a3891f77a2cbbee5ec7affc
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51705
Reviewed-by: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
d2i_ASN1_OBJECT had a similar set of bugs in as in
https://boringssl-review.googlesource.com/c/boringssl/+/49866.
This does not affect any other d2i functions. Those already go through
the ASN1_ITEM machinery.
Update-Note: d2i_ASN1_OBJECT will now notice more incorrect tags. It was
already checking for tag number 6, so it is unlikely anyone was relying
on this as a non-tag-checking parser.
Change-Id: I30f9ad28e3859aeb7a38c0ea299cd2e30002abce
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50290
Reviewed-by: Adam Langley <agl@google.com>
This simplifies the ASN1_get_object calling convention and removes
another significant source of tasn_dec.c complexity. This change does
not affect our PKCS#7 and PKCS#12 parsers.
Update-Note: Invalid certificates (and the few external structures using
asn1t.h) with BER indefinite lengths will now be rejected.
Bug: 354
Change-Id: I723036798fc3254d0a289c77b105fcbdcda309b2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50287
Reviewed-by: Adam Langley <agl@google.com>
Constructed strings are a BER mechanism where a string type can be
represented as a tree of constructed nodes and primitive leaves, that
then have to be concatenated by the parser. This is prohibited in DER
and a significant source of complexity in our parser.
Note this change does not affect our PKCS#7 and PKCS#12 parsers (where
BER is sadly necessary for interop) because those use CBS.
Update-Note: Invalid certificates (and the few external structures using
asn1t.h) with BER constructed strings will now be rejected.
Bug: 354
Change-Id: I5a8ee028ec89ed4f2d5c099a0588f2029b864580
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50286
Reviewed-by: Adam Langley <agl@google.com>
ASN1_ENCODING can be unexported because all types using it are now
hidden. This does mean external uses of <openssl/asn1t.h> can no longer
use ASN1_SEQUENCE_enc, but there do not seem to be any such uses.
ASN1_TLC and ASN1_TEMPLATE typedefs are only necessary for users of
asn1t.h. I'm hopeful we can do away with ASN1_TLC once I get to
reworking tasn_dec.c. ASN1_TEMPLATE is somewhat stuck, though all
references should be hidden behind macros.
ASN1_generate_* appear to only referenced within the library. Remove the
unused one and move the other to x509/internal.h. (asn1_gen.c is
currently in crypto/x509 rather than crypto/asn1, so I put it in
x509/internal.h to match. I'll leave figuring out that file to later.)
Annoyingly, asn1/internal.h now pulls in asn1t.h, but so it goes.
Change-Id: I8b43de3fa9647883103006e27907730d5531fd7d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50106
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
While I'm here, add missing parentheses around the B_ASN1_* bitmasks.
I've tossed ASN1_PRINTABLE into the deprecated bucket, though X509_NAME
relies on it, because it is a mess.
Bug: 407, 426
Change-Id: I287f60e98d6c9f237908011e1a816f4b4fb4433e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50105
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Outside the library, this function is practically useless. It creates an
empty ASN1_OBJECT, which can never be filled in because the struct is
private and there are no mutating setters.
(See https://boringssl-review.googlesource.com/c/boringssl/+/46164 and
https://boringssl-review.googlesource.com/c/boringssl/+/48326 for a
discussion on why it's important ASN1_OBJECTs are immutable.)
Update-Note: ASN1_OBJECT_new is no longer exported. While this function
does remain in OpenSSL, it is extremely unlikely anyone has found a use
for this function.
Bug: 452
Change-Id: I111a9a1ce3ca4d7aa717a3c3a03d34c05af8fdbd
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50025
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
If the header is valid, but the body is truncated, ASN1_get_object
intentionally preserves the indefinite-length and constructed output
bits. This means callers who check for error with == 0x80 may read off
the end of the buffer on accident.
This is unlikely to break callers: 0x80 was already a possible error
value, so callers already needed to handle it. The original function's
aim in returning more information is unlikely to matter because callers
cannot distinguish 0x80 (could not parse header) and 0x80 (header was
valid, definite-length, and primitive, but length was too long).
Update-Note: ASN1_get_object's calling convention is slightly
simplified.
Bug: 451
Change-Id: If2b45c47e6b8864aef9fd5e04f313219639991ed
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50005
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Also fill in docs for some easy ASN1_STRING wrappers while I'm here.
(Not sure why they exist, but removing them is probably more trouble
than is worth it.)
Bug: 407, 426
Change-Id: Id12c5fbc84982728435d105d66a3b63e5f3a1d15
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49945
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Some BIO_write failures weren't handled. Otherwise would successfully
write truncated results. The other i2a functions all report -1 on
truncation, so match. While I'm here, write a test to make sure I didn't
break this.
Change-Id: If17d0209e75c15b3f37bceb1cdfb480fd2c62c4d
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49931
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
They do the same thing, except i2a_ASN1_ENUMERATED has a bug and doesn't
handle negative values.
Change-Id: Ifb22aa4e4d6c441a39cf6b3702cce7f6d12a94ae
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49929
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
The comparison should notice differences in bit count.
Update-Note: ASN1_STRING_cmp no longer incorrectly treats BIT STRINGs
with different padding bits as equal.
Bug: 446
Change-Id: I22b3fcc5d369540d029ca234e9b3b02402cec4c3
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49928
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
ASN1_item_unpack was missing checks for trailing data. ASN1_item_pack's
error handling was all wrong. (Leaking the temporary on error, checking
the the wrong return value for i2d, would-be redundant check for NULL,
were the other check not wrong.)
Update-Note: ASN1_item_unpack now checks for trailing data.
Change-Id: Ibaa19ba2b264fca36dd21109e66f9558d373c58b
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49927
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
In doing so, fix ASN1_item_pack to not use the ASN1_OCTET_STRING
typedef. The function makes an untyped ASN1_STRING.
With all these caveats, one might think that ASN1_BOOLEAN ASN1_ITEMs are
pretty useless. This is about right. They're really only usable embedded
as a field in another struct.
Bug: 426
Change-Id: Id7830b91b2d011038ce79ec848e17ad6241423e1
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49926
Reviewed-by: Adam Langley <agl@google.com>
This is completely unchecked for now, as it all goes through tasn_enc.c.
But the only non-const encoders now are X509_NAME, and the functions
that call into it, so we can fix up the ones at the bottom.
I haven't done the macros that use the "name" or "fname" variants. The
set of macros for const are a little weird. But before expanding the
header macros out, I wanted to change the signatures on the macro side
once, so the compiler checks they're expanded correctly.
Update-Note: The type signature of some i2d functions, such as
i2d_ASN1_OCTET_STRING, is now const-correct.
Bug: 407
Change-Id: I03988f5591191b41ab4e7f014bd8d41cb071b39a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49908
Reviewed-by: Adam Langley <agl@google.com>
d2i_ASN1_BOOLEAN and i2d_ASN1_BOOLEAN don't go through the macros
because ASN1_BOOLEAN is a slightly weird type (int instead of pointer).
Their tag checks were missing a few bits.
This does not affect any other d2i functions. Those already go through
the ASN1_ITEM machinery.
Change-Id: Ic892cd2a8b8f9ceb11e43d931f8aa6df921997d3
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49866
Reviewed-by: Adam Langley <agl@google.com>
This makes it slightly clearer which ints are lengths and which are
substituting for T*. (ASN1_BOOLEAN is weird. It is the one non-pointer
representation in crypto/asn1.)
Change-Id: I93ff87264835e64c9f8613edae63e93731e77548
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49865
Reviewed-by: Adam Langley <agl@google.com>
crypto/asn1 represents an ASN.1 NULL value as a non-null ASN1_NULL*
pointer, (ASN1_NULL*)1. It is a non-null pointer because a null pointer
represents an omitted OPTIONAL NULL. It is an opaque pointer because
there is no sense in allocating anything.
This pointer cannot be dereferenced, yet ASN1_NULL is a typedef for int.
This is confusing and probably undefined behavior. (N1548, 6.3.2.3,
clause 7 requires pointer conversions between two pointer types be
correctly aligned, even if the pointer is never dereferenced. Strangely,
clause 5 above does not impose the same requirement when converting from
integer to pointer, though it mostly punts to the implementation
definition.) Of course, all of tasn_*.c is a giant strict aliasing
violation anyway, but an opaque struct pointer is a slightly better
choice here.
(Note that, although ASN1_BOOLEAN is also a typedef for int, that
situation is different: the ASN1_BOOLEAN representation is a plain
ASN1_BOOLEAN, not ASN1_BOOLEAN*, while the ASN1_NULL representation is a
pointer. ASN1_NULL could have had the same treatment and even used a
little less memory, but changing that would break the API.)
Update-Note: Code that was assuming ASN1_NULL was an int typedef will
fail to compile. Given this was never dereferencable, it is hard to
imagine anything relying on this.
Bug: 438
Change-Id: Ia0c652eed66e76f82a3843af1fc877f06c8d5e8f
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49805
Reviewed-by: Adam Langley <agl@google.com>
This function is a little awkward. It mutates global data, so if two
libraries in the address space both attempt to define a custom OID, they
will conflict. But some existing code uses it so, as long as it does so,
we should make it thread-safe.
Along the way, I've switched it to a hash table and removed the ability
to overwrite existing entries. Previously, overwriting a built-in table
would crash (on platforms where const structures are write-protected).
Overwriting a dynamic table implemented this weird merging algorithm.
The one caller I've seen does not appear to need this feature.
I've also switched ASN1_STRING_TABLE_cleanup to a no-op, matching our
other global cleanup functions. This function is not safe to call
without global knowledge of all other uses of the library.
Update-Note: ASN1_STRING_TABLE_add no longer allows overwrite existing
entries. In most cases, this would crash or trigger a race condition
anyway.
Bug: 426
Change-Id: Ie024cca87feaef3ff10064b452f3a860844544da
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49769
Reviewed-by: Adam Langley <agl@google.com>
Callers may as well use ASN1_mbstring_ncopy directly, but some code uses
this, so test it. I've intentionally not tested updating entries because
it crashes if you use a built-in one, and updating a dynamic one seems
unnecessary.
Change-Id: If760a751fbdcd1a2f14d5dcb08de2b0f2a8d3549
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49768
Reviewed-by: Adam Langley <agl@google.com>
There's a test in the file under ifdef, but that is not wired up into
the build.
Change-Id: Iec09277c7ce948c33303d12c325207de2188d908
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49766
Reviewed-by: Adam Langley <agl@google.com>
The i2d functions internally take a tag/class pair of parameters. If tag
is not -1, we override the tag with (tag, class). Otherwise, class is
ignored. (class is inconsistently called aclass or iclass.)
Historically, the remaning bits of class were repurposed to pass extra
flags down the structure. These had to be preserved in all recursive
calls, so the functions take apart and reassemble the two halves of
aclass/iclass. The only such flag was ASN1_TFLG_NDEF, which on certain
types, caused OpenSSL to encode indefinite-length encoding. We removed
this in https://boringssl-review.googlesource.com/c/boringssl/+/43889.
Due to these flags, if tag == -1, class should default to zero. However,
X509_NAME's callbacks pass -1, -1, instead of -1, 0, effectively setting
all flags. This wasn't noticed because none of the types below X509_NAME
pay attention to ASN1_TFLG_NDEF.
This CL does two things: First, it unwinds the remainder of the flags
machinery. If we ever need flags, we should pass it as a distinct
argument. Second, it fixes the X509_NAME calls and asserts that -1 is
always paired with 0.
Change-Id: I285a73a06ad16980617fe23d5ea7f260fc5dbf16
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49385
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
These are a little odd with the ASN1_ENCODING paths. And there were some
bugs previously around CHOICE types. Nothing defines them, inside or
outside BoringSSL, so remove them.
Change-Id: Id2954fef8ee9637f36f7511b51dc0adc2557e3ba
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49352
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
it->funcs is only an ASN1_AUX for ASN1_ITYPE_SEQUENCE and
ASN1_ITYPE_CHOICE. Fortunately, the other possible types for it->funcs
are larger than ASN1_AUX and we don't touch the result when we
shouldn't, so this is merely a strict aliasing violation.
Change-Id: I29e94249e0b137fe8df0b16254366ae6705c8784
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49351
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
See also 006906cddda37e24a66443199444ef4476697477 from OpenSSL, though
this CL uses a different strategy from upstream. Upstream makes
ASN1_item_ex_i2d continue to allow optionals and checks afterwards at
every non-optional call site. This CL pushes down an optional parameter
and says functions cannot omit items unless explicitly allowed.
I think this is a better default, though it is a larger change. Fields
are only optional when they come from an ASN1_TEMPLATE with the OPTIONAL
flag. Upstream's strategy misses top-level calls.
This CL additionally adds checks for optional ASN1_TEMPLATEs in contexts
where it doesn't make sense. Only fields of SEQUENCEs and SETs may be
OPTIONAL, but the ASN1_ITEM/ASN1_TEMPLATE split doesn't quite match
ASN.1 itself. ASN1_TEMPLATE is additionally responsible for
explicit/implicit tagging, and SEQUENCE/SET OF. That means CHOICE arms
and the occasional top-level type (ASN1_ITEM_TEMPLATE) use ASN1_TEMPLATE
but will get confused if marked optional.
As part of this, i2d_FOO(NULL) now returns -1 rather than "successfully"
writing 0 bytes. If we want to allow NULL at the top-level, that's not
too hard to arrange, but our CBB-based i2d functions do not.
Update-Note: Structures with missing mandatory fields can no longer be
encoded. Note that, apart from the cases already handled by preceding
CLs, tasn_new.c will fill in non-NULL empty objects everywhere. The main
downstream impact I've seen of this particular change is in combination
with other bugs. Consider a caller that does:
GENERAL_NAME *name = GENERAL_NAME_new();
name->type = GEN_DNS;
name->d.dNSName = DoSomethingComplicated(...);
Suppose DoSomethingComplicated() was actually fallible and returned
NULL, but the caller forgot to check. They'd now construct a
GENERAL_NAME with a missing field. Previously, this would silently
serialize some garbage (omitted field) or empty string. Now we fail to
encode, but the true error was the uncaught DoSomethingComplicated()
failure. (Which likely was itself a bug.)
Bug: 429
Change-Id: I37fe618761be64a619be9fdc8d416f24ecbb8c46
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49350
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
See https://github.com/openssl/openssl/issues/16538
Update-Note: A default-constructed object with a required ANY or
string-like CHOICE field cannot be encoded until the field is specified.
Note this affects i2d_X509: notBefore and notAfter are string-like
CHOICEs in OpenSSL.
Bug: 429
Change-Id: I97d971fa588ab72be25a4c1eb7310ed330f16c4f
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49349
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
asn1_ex_i2c actually does have an error condition, it just wasn't being
handled.
628b3c7f2f, 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
later.
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
that.
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
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49348
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
This handles normal CHOICE types. A follow-up CL will handle MSTRING and
ANY types.
Update-Note: An invalid CHOICE object (e.g. GENERAL_NAME) will now fail
when encoded, rather than be silently omitted. In particular, CHOICE
objects are default-initialized by tasn_new.c in an empty -1 state.
Structures containing a required CHOICE field can no longer be encoded
without filling in the CHOICE.
Bug: 429
Change-Id: I7011deadf518ddc344a56b07a0e268ceaae17fe0
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49347
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
tasn_enc.c was missing lots of error checks and mixed up 0 and -1
returns. Document all the internal calling conventions, as best as I can
tell, and fix things up.
There are also error cases it forgets to check (it generally does not
notice missing non-OPTIONAL fields). This CL only addresses errors it
already tries to report. Subsequent CLs will add in the missing error
cases. And then if it all sticks, I'm hoping we can rewrite this with
CBB. Rewriting tsan_dec.c to CBS would also be good, but that will be
more difficult as we need to clear out BER first.
Update-Note: Some error cases which were silently misinterpreted as
missing OPTIONAL elements will now cause encoding to fail.
Bug: 429
Change-Id: Ibbb3eba08eb8f8f878930c9456edc8c74479aade
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49345
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
The old loop read one byte past the length. It also stopped the loop
too early on interior NUL. See also upstream's
https://github.com/openssl/openssl/pull/16433, though I've opted to
rewrite the function entirely rather than use their fix.
Also deduplicate the PrintableString check.
Change-Id: Ia8bd282047c2a2ed1d5e71a68a3947c7c108df95
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49066
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
strchr is interprets the trailing NUL as part of the string, so
is_printable thought NUL was allowed. Just write the code in the obvious
way and let the compiler figure it out. (It seems to make a clever
bitmask or something.)
Update-Note: ASN1_mbstring_ncopy will no longer allow PrintableString
for strings containing NUL.
Change-Id: I3675191ceb44c06f0ac7b430f88272cabf392d35
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/49065
Reviewed-by: Adam Langley <agl@google.com>
I noticed this while I was reading through the encoder. OpenSSL's ASN.1
library is very sloppy when it comes to reusing enums. It has...
- Universal tag numbers. These are just tag numbers from ASN.1
- utype. These are used in the ASN1_TYPE type field, as well as the
ASN1_ITEM utype fields They are the same as universal tag numbers,
except non-universal types map to V_ASN1_OTHER. I believe ASN1_TYPE
types and ASN1_ITEM utypes are the same, but I am not positive.
- ASN1_STRING types. These are the same as utypes, except V_ASN1_OTHER
appears to only be possible when embedded inside ASN1_TYPE, and
negative INTEGER and ENUMERATED values get mapped to
V_ASN1_NEG_INTEGER and V_ASN1_NEG_ENUMERATED. Additionally, some
values like V_ASN1_OBJECT are possible in a utype but not possible in
an ASN1_STRING (and will cause lots of problems if ever placed in
one).
- Sometimes one of these enums is augmented with V_ASN1_UNDEF and/or
V_ASN1_APP_CHOOSE for extra behaviors.
- Probably others I'm missing.
These get mixed up all the time. asn1_ex_i2c's MSTRING path converts
from ASN1_STRING type to utype and forgets to normalize V_ASN1_NEG_*.
This means that negative INTEGERs and ENUMERATEDs in MSTRINGs do not get
encoded right.
The negative INTEGER case is unreachable (unless the caller passes
the wrong ASN1_STRING to an MSTRING i2d function, but mismatching i2d
functions generally does wrong things), but the negative ENUMERATED case
is reachable. Fix this and add a test.
Change-Id: I762d482e72ebf03fd64bba291e751ab0b51af2a9
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48805
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
In writing the tests, I noticed that the documentation was wrong. First,
the maximum lengths are measured in codepoints, not bytes.
Second, the TODO was wrong. We actually do handle this correctly,
*almost*. Rather, the bug is that the function assumes |mask| contains
no extraneous bits. If it does, all extraneous bits are interpreted as
B_ASN1_UTF8STRING. This seems like a bug, so I've gone ahead and fixed
that, with a test.
Change-Id: I7ba8fa700a8e21e6d25cb7ce879dace685eecf7e
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48825
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
ASN1_TFLG_SET_ORDER was used in OpenSSL's CMS and PKCS#7
implementations, which we've removed. Fields that use it not only get
the DER SET sorting but, when serialized, go back and mutate the
original object to match.
This is unused, so remove it. This removes one of the sources of
non-const behavior in i2d functions.
Bug: 407
Change-Id: I6b2bf8d11c30a41b53d14ad475c26a1a30dfd31f
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48786
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
ASN1_STRING and ASN1_TYPE type values almost line up, but not quite.
Negative INTEGERs are not possible in X509_NAME (tag2bit maps INTEGER to
0), but negative ENUMERATEDs are (tag2bit maps ENUMERATED to
B_ASN1_UNKNOWN). See https://crbug.com/boringssl/412 for some notes on
this mess. Either way, the library will freely produce ASN1_STRING
INTEGERs and ENUMERATEDs in non-MSTRING contexts, so get this case
right.
Change-Id: Ica537f4d683e7a6becc96e2eee3cb66e53372124
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48785
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Also use the simpler single-call variant.
Change-Id: I3834a798549f12a9dcdec6a357d2380085baf940
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48777
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
ASN1_STRING_print_ex is extremely complex and attempting to implement
RFC2253, so write some tests for it. Along the way, unexport
CHARTYPE_*, which are internal book-keeping used in
ASN1_STRING_print_ex.
Change-Id: Idb27cd40fb66dc099d1fd6d039a00404608c2063
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48776
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
For some reason, ASN1_STRING_print was not in the same file as
ASN1_STRING_print_ex, but X509_print. Although it also behaves very
differently from ASN1_STRING_print_ex, so that's a little interesting.
Change-Id: I3f88f8943c8e36426eedafa7e350a787881d0c74
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48775
Reviewed-by: Adam Langley <agl@google.com>