authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-24 10:56:38-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-07-24 10:56:38-07:00
logf8666d748d57c5a71cfb2ae2a9eb1209fcee6e81
tree6a62d721c45390af95146aa9c08a28723873ba00
parentddd27db362ccfa9877e2cbf6025d88c553ab34eb
parentdf5f6836c474a689469e01554997bbf3108e2cb9
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #16516 from lacc97/std-crypto-certificate-parse-datetime

std.crypto.Certificate: fix timedate parsing

1 files changed, 27 insertions(+), 24 deletions(-)

lib/std/crypto/Certificate.zig+27-24
...@@ -538,12 +538,12 @@ pub fn parseTime(cert: Certificate, elem: der.Element) ParseTimeError!u64 {...@@ -538,12 +538,12 @@ pub fn parseTime(cert: Certificate, elem: der.Element) ParseTimeError!u64 {
538 return error.CertificateTimeInvalid;538 return error.CertificateTimeInvalid;
539539
540 return Date.toSeconds(.{540 return Date.toSeconds(.{
541 .year = @as(u16, 2000) + try parseTimeDigits(bytes[0..2].*, 0, 99),541 .year = @as(u16, 2000) + try parseTimeDigits(bytes[0..2], 0, 99),
542 .month = try parseTimeDigits(bytes[2..4].*, 1, 12),542 .month = try parseTimeDigits(bytes[2..4], 1, 12),
543 .day = try parseTimeDigits(bytes[4..6].*, 1, 31),543 .day = try parseTimeDigits(bytes[4..6], 1, 31),
544 .hour = try parseTimeDigits(bytes[6..8].*, 0, 23),544 .hour = try parseTimeDigits(bytes[6..8], 0, 23),
545 .minute = try parseTimeDigits(bytes[8..10].*, 0, 59),545 .minute = try parseTimeDigits(bytes[8..10], 0, 59),
546 .second = try parseTimeDigits(bytes[10..12].*, 0, 59),546 .second = try parseTimeDigits(bytes[10..12], 0, 59),
547 });547 });
548 },548 },
549 .generalized_time => {549 .generalized_time => {
...@@ -555,11 +555,11 @@ pub fn parseTime(cert: Certificate, elem: der.Element) ParseTimeError!u64 {...@@ -555,11 +555,11 @@ pub fn parseTime(cert: Certificate, elem: der.Element) ParseTimeError!u64 {
555 return error.CertificateTimeInvalid;555 return error.CertificateTimeInvalid;
556 return Date.toSeconds(.{556 return Date.toSeconds(.{
557 .year = try parseYear4(bytes[0..4]),557 .year = try parseYear4(bytes[0..4]),
558 .month = try parseTimeDigits(bytes[4..6].*, 1, 12),558 .month = try parseTimeDigits(bytes[4..6], 1, 12),
559 .day = try parseTimeDigits(bytes[6..8].*, 1, 31),559 .day = try parseTimeDigits(bytes[6..8], 1, 31),
560 .hour = try parseTimeDigits(bytes[8..10].*, 0, 23),560 .hour = try parseTimeDigits(bytes[8..10], 0, 23),
561 .minute = try parseTimeDigits(bytes[10..12].*, 0, 59),561 .minute = try parseTimeDigits(bytes[10..12], 0, 59),
562 .second = try parseTimeDigits(bytes[12..14].*, 0, 59),562 .second = try parseTimeDigits(bytes[12..14], 0, 59),
563 });563 });
564 },564 },
565 else => return error.CertificateFieldHasWrongDataType,565 else => return error.CertificateFieldHasWrongDataType,
...@@ -613,33 +613,35 @@ const Date = struct {...@@ -613,33 +613,35 @@ const Date = struct {
613 }613 }
614};614};
615615
616pub fn parseTimeDigits(nn: @Vector(2, u8), min: u8, max: u8) !u8 {616pub fn parseTimeDigits(text: *const [2]u8, min: u8, max: u8) !u8 {
617 const zero: @Vector(2, u8) = .{ '0', '0' };617 const nn: @Vector(2, u16) = .{ text[0], text[1] };
618 const mm: @Vector(2, u8) = .{ 10, 1 };618 const zero: @Vector(2, u16) = .{ '0', '0' };
619 const mm: @Vector(2, u16) = .{ 10, 1 };
619 const result = @reduce(.Add, (nn -% zero) *% mm);620 const result = @reduce(.Add, (nn -% zero) *% mm);
620 if (result < min) return error.CertificateTimeInvalid;621 if (result < min) return error.CertificateTimeInvalid;
621 if (result > max) return error.CertificateTimeInvalid;622 if (result > max) return error.CertificateTimeInvalid;
622 return result;623 return @truncate(result);
623}624}
624625
625test parseTimeDigits {626test parseTimeDigits {
626 const expectEqual = std.testing.expectEqual;627 const expectEqual = std.testing.expectEqual;
627 try expectEqual(@as(u8, 0), try parseTimeDigits("00".*, 0, 99));628 try expectEqual(@as(u8, 0), try parseTimeDigits("00", 0, 99));
628 try expectEqual(@as(u8, 99), try parseTimeDigits("99".*, 0, 99));629 try expectEqual(@as(u8, 99), try parseTimeDigits("99", 0, 99));
629 try expectEqual(@as(u8, 42), try parseTimeDigits("42".*, 0, 99));630 try expectEqual(@as(u8, 42), try parseTimeDigits("42", 0, 99));
630631
631 const expectError = std.testing.expectError;632 const expectError = std.testing.expectError;
632 try expectError(error.CertificateTimeInvalid, parseTimeDigits("13".*, 1, 12));633 try expectError(error.CertificateTimeInvalid, parseTimeDigits("13", 1, 12));
633 try expectError(error.CertificateTimeInvalid, parseTimeDigits("00".*, 1, 12));634 try expectError(error.CertificateTimeInvalid, parseTimeDigits("00", 1, 12));
635 try expectError(error.CertificateTimeInvalid, parseTimeDigits("Di", 0, 99));
634}636}
635637
636pub fn parseYear4(text: *const [4]u8) !u16 {638pub fn parseYear4(text: *const [4]u8) !u16 {
637 const nnnn: @Vector(4, u16) = .{ text[0], text[1], text[2], text[3] };639 const nnnn: @Vector(4, u32) = .{ text[0], text[1], text[2], text[3] };
638 const zero: @Vector(4, u16) = .{ '0', '0', '0', '0' };640 const zero: @Vector(4, u32) = .{ '0', '0', '0', '0' };
639 const mmmm: @Vector(4, u16) = .{ 1000, 100, 10, 1 };641 const mmmm: @Vector(4, u32) = .{ 1000, 100, 10, 1 };
640 const result = @reduce(.Add, (nnnn -% zero) *% mmmm);642 const result = @reduce(.Add, (nnnn -% zero) *% mmmm);
641 if (result > 9999) return error.CertificateTimeInvalid;643 if (result > 9999) return error.CertificateTimeInvalid;
642 return result;644 return @truncate(result);
643}645}
644646
645test parseYear4 {647test parseYear4 {
...@@ -651,6 +653,7 @@ test parseYear4 {...@@ -651,6 +653,7 @@ test parseYear4 {
651 const expectError = std.testing.expectError;653 const expectError = std.testing.expectError;
652 try expectError(error.CertificateTimeInvalid, parseYear4("999b"));654 try expectError(error.CertificateTimeInvalid, parseYear4("999b"));
653 try expectError(error.CertificateTimeInvalid, parseYear4("crap"));655 try expectError(error.CertificateTimeInvalid, parseYear4("crap"));
656 try expectError(error.CertificateTimeInvalid, parseYear4("r:bQ"));
654}657}
655658
656pub fn parseAlgorithm(bytes: []const u8, element: der.Element) ParseEnumError!Algorithm {659pub fn parseAlgorithm(bytes: []const u8, element: der.Element) ParseEnumError!Algorithm {