Commit 05bad1f42d

Luis Cáceres <lacc97@protonmail.ch>
2023-07-23 22:48:45
std.crypto.Certificate: fix timedate parsing
This commit fixes parsing in parseYear4 and parseTimeDigits by using a wider vector data type such that the intermediate result cannot overflow and the error check remains correct.
1 parent b35874a
Changed files (1)
lib
std
lib/std/crypto/Certificate.zig
@@ -613,13 +613,14 @@ const Date = struct {
     }
 };
 
-pub fn parseTimeDigits(nn: @Vector(2, u8), min: u8, max: u8) !u8 {
-    const zero: @Vector(2, u8) = .{ '0', '0' };
-    const mm: @Vector(2, u8) = .{ 10, 1 };
+pub fn parseTimeDigits(nn_u8: @Vector(2, u8), min: u8, max: u8) !u8 {
+    const nn: @Vector(2, u16) = .{ nn_u8[0], nn_u8[1] };
+    const zero: @Vector(2, u16) = .{ '0', '0' };
+    const mm: @Vector(2, u16) = .{ 10, 1 };
     const result = @reduce(.Add, (nn -% zero) *% mm);
     if (result < min) return error.CertificateTimeInvalid;
     if (result > max) return error.CertificateTimeInvalid;
-    return result;
+    return @truncate(result);
 }
 
 test parseTimeDigits {
@@ -631,15 +632,16 @@ test parseTimeDigits {
     const expectError = std.testing.expectError;
     try expectError(error.CertificateTimeInvalid, parseTimeDigits("13".*, 1, 12));
     try expectError(error.CertificateTimeInvalid, parseTimeDigits("00".*, 1, 12));
+    try expectError(error.CertificateTimeInvalid, parseTimeDigits("Di".*, 0, 99));
 }
 
 pub fn parseYear4(text: *const [4]u8) !u16 {
-    const nnnn: @Vector(4, u16) = .{ text[0], text[1], text[2], text[3] };
-    const zero: @Vector(4, u16) = .{ '0', '0', '0', '0' };
-    const mmmm: @Vector(4, u16) = .{ 1000, 100, 10, 1 };
+    const nnnn: @Vector(4, u32) = .{ text[0], text[1], text[2], text[3] };
+    const zero: @Vector(4, u32) = .{ '0', '0', '0', '0' };
+    const mmmm: @Vector(4, u32) = .{ 1000, 100, 10, 1 };
     const result = @reduce(.Add, (nnnn -% zero) *% mmmm);
     if (result > 9999) return error.CertificateTimeInvalid;
-    return result;
+    return @truncate(result);
 }
 
 test parseYear4 {
@@ -651,6 +653,7 @@ test parseYear4 {
     const expectError = std.testing.expectError;
     try expectError(error.CertificateTimeInvalid, parseYear4("999b"));
     try expectError(error.CertificateTimeInvalid, parseYear4("crap"));
+    try expectError(error.CertificateTimeInvalid, parseYear4("r:bQ"));
 }
 
 pub fn parseAlgorithm(bytes: []const u8, element: der.Element) ParseEnumError!Algorithm {