diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig index f81676a977..fe211c6146 100644 --- a/lib/std/crypto/Certificate.zig +++ b/lib/std/crypto/Certificate.zig @@ -198,14 +198,13 @@ pub const Parsed = struct { /// * That the subject's issuer is indeed the provided issuer. /// * The time validity of the subject. /// * The signature. - pub fn verify(parsed_subject: Parsed, parsed_issuer: Parsed) VerifyError!void { + pub fn verify(parsed_subject: Parsed, parsed_issuer: Parsed, now_sec: i64) VerifyError!void { // Check that the subject's issuer name matches the issuer's // subject name. if (!mem.eql(u8, parsed_subject.issuer(), parsed_issuer.subject())) { return error.CertificateIssuerMismatch; } - const now_sec = std.time.timestamp(); if (now_sec < parsed_subject.validity.not_before) return error.CertificateNotYetValid; if (now_sec > parsed_subject.validity.not_after) @@ -419,10 +418,10 @@ pub fn parse(cert: Certificate) !Parsed { }; } -pub fn verify(subject: Certificate, issuer: Certificate) !void { +pub fn verify(subject: Certificate, issuer: Certificate, now_sec: i64) !void { const parsed_subject = try subject.parse(); const parsed_issuer = try issuer.parse(); - return parsed_subject.verify(parsed_issuer); + return parsed_subject.verify(parsed_issuer, now_sec); } pub fn contents(cert: Certificate, elem: der.Element) []const u8 { diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index b30fa531ec..a1684fda73 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -13,7 +13,7 @@ pub const VerifyError = Certificate.Parsed.VerifyError || error{ CertificateIssuerNotFound, }; -pub fn verify(cb: Bundle, subject: Certificate.Parsed) VerifyError!void { +pub fn verify(cb: Bundle, subject: Certificate.Parsed, now_sec: i64) VerifyError!void { const bytes_index = cb.find(subject.issuer()) orelse return error.CertificateIssuerNotFound; const issuer_cert: Certificate = .{ .buffer = cb.bytes.items, @@ -22,7 +22,7 @@ pub fn verify(cb: Bundle, subject: Certificate.Parsed) VerifyError!void { // Every certificate in the bundle is pre-parsed before adding it, ensuring // that parsing will succeed here. const issuer = issuer_cert.parse() catch unreachable; - try subject.verify(issuer); + try subject.verify(issuer, now_sec); } /// The returned bytes become invalid after calling any of the rescan functions diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig index 0251350dad..877ad33bb4 100644 --- a/lib/std/crypto/tls/Client.zig +++ b/lib/std/crypto/tls/Client.zig @@ -351,6 +351,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) !C var main_cert_pub_key_algo: Certificate.AlgorithmCategory = undefined; var main_cert_pub_key_buf: [300]u8 = undefined; var main_cert_pub_key_len: u16 = undefined; + const now_sec = std.time.timestamp(); while (true) { try d.readAtLeastOurAmt(stream, tls.record_header_len); @@ -458,10 +459,10 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) !C @memcpy(&main_cert_pub_key_buf, pub_key.ptr, pub_key.len); main_cert_pub_key_len = @intCast(@TypeOf(main_cert_pub_key_len), pub_key.len); } else { - try prev_cert.verify(subject); + try prev_cert.verify(subject, now_sec); } - if (ca_bundle.verify(subject)) |_| { + if (ca_bundle.verify(subject, now_sec)) |_| { handshake_state = .trust_chain_established; break :cert; } else |err| switch (err) {