commit 98cc059622cd5cad3eef1bbc851437358d259033 (tree)
parent 98ddebc380fd12b91c00b90c049435117d03274b
Author: Frank Denis <jedisct1@noreply.codeberg.org>
Date: Mon, 20 Apr 2026 21:54:04 +0200
crypto.asn1.Oid: Reject empty OID encodings (#31983)
The DER decoder accepted zero-length OID payloads producing an Oid value that would panic later.
Co-authored-by: Frank Denis <github@pureftpd.org>
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31983
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Co-authored-by: Frank Denis <jedisct1@noreply.codeberg.org>
Co-committed-by: Frank Denis <jedisct1@noreply.codeberg.org>
Diffstat:
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/lib/std/crypto/codecs/asn1/Oid.zig b/lib/std/crypto/codecs/asn1/Oid.zig
@@ -85,6 +85,14 @@ test toDot {
}
}
+test "malformed OID" {
+ var empty: der.Decoder = .{ .bytes = &.{ 0x06, 0x00 } };
+ try std.testing.expectError(error.EndOfStream, decodeDer(&empty));
+
+ var truncated: der.Decoder = .{ .bytes = &.{ 0x06, 0x02, 0x2a, 0x80 } };
+ try std.testing.expectError(error.InvalidEncoding, decodeDer(&truncated));
+}
+
const TestCase = struct {
encoded: []const u8,
dot_notation: []const u8,
@@ -109,7 +117,10 @@ pub const asn1_tag = asn1.Tag.init(.oid, false, .universal);
pub fn decodeDer(decoder: *der.Decoder) !Oid {
const ele = try decoder.element(asn1_tag.toExpected());
- return Oid{ .encoded = decoder.view(ele) };
+ const encoded = decoder.view(ele);
+ if (encoded.len == 0) return error.EndOfStream;
+ if (encoded[encoded.len - 1] & 0x80 != 0) return error.InvalidEncoding;
+ return Oid{ .encoded = encoded };
}
pub fn encodeDer(self: Oid, encoder: *der.Encoder) !void {