authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-05-03 18:36:20+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-05-28 16:28:27+02:00
log415c574b921a48f6cdcfac40fd3f38f236644f94
tree7fa14e101b06c19146e4b825735d15bb8d90a8f1
parent3086628e7b4d8413fee6b85c886c21c95544d18d

der.Decoder: respect the bounds of the target type on int values


1 files changed, 23 insertions(+), 4 deletions(-)

lib/std/crypto/codecs/asn1/der/Decoder.zig+23-4
......@@ -122,10 +122,20 @@ fn int(comptime T: type, value: []const u8) error{ NonCanonical, LargeValue }!T
122122
123123 const had_sign_byte = value.len >= 2 and value[0] == 0x00;
124124 const bytes = if (had_sign_byte) value[1..] else value;
125 if (bytes.len > @sizeOf(T)) return error.LargeValue;
125 const der_negative = !had_sign_byte and bytes[0] & 0x80 != 0;
126126
127 const sign_extend = info.signedness == .signed and !had_sign_byte and bytes[0] & 0x80 != 0;
128 var buf: [@sizeOf(T)]u8 = @splat(if (sign_extend) 0xff else 0);
127 switch (info.signedness) {
128 .unsigned => {
129 if (der_negative) return error.LargeValue;
130 if (bytes.len > @sizeOf(T)) return error.LargeValue;
131 },
132 .signed => {
133 const max_len: usize = if (had_sign_byte) @sizeOf(T) - 1 else @sizeOf(T);
134 if (bytes.len > max_len) return error.LargeValue;
135 },
136 }
137
138 var buf: [@sizeOf(T)]u8 = @splat(if (der_negative) 0xff else 0);
129139 @memcpy(buf[buf.len - bytes.len ..], bytes);
130140 return std.mem.readInt(T, &buf, .big);
131141}
......@@ -137,7 +147,8 @@ test int {
137147
138148 const big = [_]u8{ 0xef, 0xff };
139149 try expectError(error.LargeValue, int(u8, &big));
140 try expectEqual(0xefff, int(u16, &big));
150 try expectError(error.LargeValue, int(u16, &big));
151 try expectEqual(@as(i16, -4097), try int(i16, &big));
141152
142153 try expectEqual(@as(u16, 255), try int(u16, &.{ 0x00, 0xff }));
143154 try expectEqual(@as(u16, 0x8000), try int(u16, &.{ 0x00, 0x80, 0x00 }));
......@@ -148,6 +159,14 @@ test int {
148159 try expectEqual(@as(i16, -129), try int(i16, &.{ 0xff, 0x7f }));
149160 try expectEqual(@as(i16, 255), try int(i16, &.{ 0x00, 0xff }));
150161 try expectEqual(@as(i32, 0x7fffffff), try int(i32, &.{ 0x7f, 0xff, 0xff, 0xff }));
162
163 try expectError(error.LargeValue, int(i8, &.{ 0x00, 0xff }));
164 try expectError(error.LargeValue, int(i16, &.{ 0x00, 0x80, 0x00 }));
165 try expectError(error.LargeValue, int(i32, &.{ 0x00, 0x80, 0x00, 0x00, 0x00 }));
166
167 try expectError(error.LargeValue, int(u8, &.{0xff}));
168 try expectError(error.LargeValue, int(u16, &.{0x80}));
169 try expectError(error.LargeValue, int(u32, &.{ 0x80, 0x00, 0x00, 0x00 }));
151170}
152171
153172test Decoder {