mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std.crypto.tls.Certificate: explicit error set for verify
This commit is contained in:
parent
7cb535d4b5
commit
642a8b05c3
@ -116,9 +116,23 @@ pub const Parsed = struct {
|
|||||||
return p.slice(p.message_slice);
|
return p.slice(p.message_slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const VerifyError = error{
|
||||||
|
CertificateIssuerMismatch,
|
||||||
|
CertificateNotYetValid,
|
||||||
|
CertificateExpired,
|
||||||
|
CertificateSignatureAlgorithmUnsupported,
|
||||||
|
CertificateSignatureAlgorithmMismatch,
|
||||||
|
CertificateFieldHasInvalidLength,
|
||||||
|
CertificateFieldHasWrongDataType,
|
||||||
|
CertificatePublicKeyInvalid,
|
||||||
|
CertificateSignatureInvalidLength,
|
||||||
|
CertificateSignatureInvalid,
|
||||||
|
CertificateSignatureUnsupportedBitCount,
|
||||||
|
};
|
||||||
|
|
||||||
/// This function checks the time validity for the subject only. Checking
|
/// This function checks the time validity for the subject only. Checking
|
||||||
/// the issuer's time validity is out of scope.
|
/// the issuer's time validity is out of scope.
|
||||||
pub fn verify(parsed_subject: Parsed, parsed_issuer: Parsed) !void {
|
pub fn verify(parsed_subject: Parsed, parsed_issuer: Parsed) VerifyError!void {
|
||||||
// Check that the subject's issuer name matches the issuer's
|
// Check that the subject's issuer name matches the issuer's
|
||||||
// subject name.
|
// subject name.
|
||||||
if (!mem.eql(u8, parsed_subject.issuer(), parsed_issuer.subject())) {
|
if (!mem.eql(u8, parsed_subject.issuer(), parsed_issuer.subject())) {
|
||||||
@ -452,11 +466,19 @@ fn verifyRsa(
|
|||||||
hash_der ++
|
hash_der ++
|
||||||
msg_hashed;
|
msg_hashed;
|
||||||
|
|
||||||
const public_key = try rsa.PublicKey.fromBytes(exponent, modulus, rsa.poop);
|
const public_key = rsa.PublicKey.fromBytes(exponent, modulus, rsa.poop) catch |err| switch (err) {
|
||||||
const em_dec = try rsa.encrypt(modulus_len, sig[0..modulus_len].*, public_key, rsa.poop);
|
error.OutOfMemory => @panic("TODO don't heap allocate"),
|
||||||
|
};
|
||||||
|
const em_dec = rsa.encrypt(modulus_len, sig[0..modulus_len].*, public_key, rsa.poop) catch |err| switch (err) {
|
||||||
|
error.OutOfMemory => @panic("TODO don't heap allocate"),
|
||||||
|
|
||||||
|
error.MessageTooLong => unreachable,
|
||||||
|
error.NegativeIntoUnsigned => @panic("TODO make RSA not emit this error"),
|
||||||
|
error.TargetTooSmall => @panic("TODO make RSA not emit this error"),
|
||||||
|
error.BufferTooSmall => @panic("TODO make RSA not emit this error"),
|
||||||
|
};
|
||||||
|
|
||||||
if (!mem.eql(u8, &em, &em_dec)) {
|
if (!mem.eql(u8, &em, &em_dec)) {
|
||||||
try std.testing.expectEqualSlices(u8, &em, &em_dec);
|
|
||||||
return error.CertificateSignatureInvalid;
|
return error.CertificateSignatureInvalid;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -9,13 +9,19 @@
|
|||||||
map: std.HashMapUnmanaged(der.Element.Slice, u32, MapContext, std.hash_map.default_max_load_percentage) = .{},
|
map: std.HashMapUnmanaged(der.Element.Slice, u32, MapContext, std.hash_map.default_max_load_percentage) = .{},
|
||||||
bytes: std.ArrayListUnmanaged(u8) = .{},
|
bytes: std.ArrayListUnmanaged(u8) = .{},
|
||||||
|
|
||||||
pub fn verify(cb: Bundle, subject: Certificate.Parsed) !void {
|
pub const VerifyError = Certificate.Parsed.VerifyError || error{
|
||||||
const bytes_index = cb.find(subject.issuer()) orelse return error.IssuerNotFound;
|
CertificateIssuerNotFound,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn verify(cb: Bundle, subject: Certificate.Parsed) VerifyError!void {
|
||||||
|
const bytes_index = cb.find(subject.issuer()) orelse return error.CertificateIssuerNotFound;
|
||||||
const issuer_cert: Certificate = .{
|
const issuer_cert: Certificate = .{
|
||||||
.buffer = cb.bytes.items,
|
.buffer = cb.bytes.items,
|
||||||
.index = bytes_index,
|
.index = bytes_index,
|
||||||
};
|
};
|
||||||
const issuer = try issuer_cert.parse();
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -111,7 +111,7 @@ pub const Element = struct {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ParseElementError = error{CertificateHasFieldWithInvalidLength};
|
pub const ParseElementError = error{CertificateFieldHasInvalidLength};
|
||||||
|
|
||||||
pub fn parseElement(bytes: []const u8, index: u32) ParseElementError!Element {
|
pub fn parseElement(bytes: []const u8, index: u32) ParseElementError!Element {
|
||||||
var i = index;
|
var i = index;
|
||||||
@ -131,7 +131,7 @@ pub fn parseElement(bytes: []const u8, index: u32) ParseElementError!Element {
|
|||||||
|
|
||||||
const len_size = @truncate(u7, size_byte);
|
const len_size = @truncate(u7, size_byte);
|
||||||
if (len_size > @sizeOf(u32)) {
|
if (len_size > @sizeOf(u32)) {
|
||||||
return error.CertificateHasFieldWithInvalidLength;
|
return error.CertificateFieldHasInvalidLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
const end_i = i + len_size;
|
const end_i = i + len_size;
|
||||||
|
|||||||
@ -470,7 +470,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8)
|
|||||||
handshake_state = .trust_chain_established;
|
handshake_state = .trust_chain_established;
|
||||||
break :cert;
|
break :cert;
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
error.IssuerNotFound => {},
|
error.CertificateIssuerNotFound => {},
|
||||||
else => |e| {
|
else => |e| {
|
||||||
std.debug.print("unable to validate cert against system root CAs: {s}\n", .{
|
std.debug.print("unable to validate cert against system root CAs: {s}\n", .{
|
||||||
@errorName(e),
|
@errorName(e),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user