From 58ea88f6cfbaa7a96236a53e26c86ead1ce7c9c2 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 20 Apr 2026 21:54:04 +0200 Subject: [PATCH] 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 Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31983 Reviewed-by: Andrew Kelley Co-authored-by: Frank Denis Co-committed-by: Frank Denis --- lib/std/crypto/codecs/asn1/Oid.zig | 13 ++++++++++++- 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 index be5bc7e7ff..6ec52d9abc 100644 --- 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 {