mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
std.crypto.tls.Certificate: fix parsing missing subsequent fields
Instead of seeing all the attributed types and values, the code was only seeing the first one.
This commit is contained in:
parent
a1f6a08dcb
commit
b24f178029
@ -56,6 +56,8 @@ pub const Attribute = enum {
|
||||
organizationName,
|
||||
organizationalUnitName,
|
||||
organizationIdentifier,
|
||||
subject_alt_name,
|
||||
pkcs9_emailAddress,
|
||||
|
||||
pub const map = std.ComptimeStringMap(Attribute, .{
|
||||
.{ &[_]u8{ 0x55, 0x04, 0x03 }, .commonName },
|
||||
@ -66,6 +68,8 @@ pub const Attribute = enum {
|
||||
.{ &[_]u8{ 0x55, 0x04, 0x0A }, .organizationName },
|
||||
.{ &[_]u8{ 0x55, 0x04, 0x0B }, .organizationalUnitName },
|
||||
.{ &[_]u8{ 0x55, 0x04, 0x61 }, .organizationIdentifier },
|
||||
.{ &[_]u8{ 0x55, 0x1D, 0x11 }, .subject_alt_name },
|
||||
.{ &[_]u8{ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x01 }, .pkcs9_emailAddress },
|
||||
});
|
||||
};
|
||||
|
||||
@ -74,6 +78,7 @@ pub const Parsed = struct {
|
||||
issuer_slice: Slice,
|
||||
subject_slice: Slice,
|
||||
common_name_slice: Slice,
|
||||
subject_alt_name_slice: Slice,
|
||||
signature_slice: Slice,
|
||||
signature_algorithm: Algorithm,
|
||||
pub_key_algo: AlgorithmCategory,
|
||||
@ -104,6 +109,10 @@ pub const Parsed = struct {
|
||||
return p.slice(p.common_name_slice);
|
||||
}
|
||||
|
||||
pub fn subjectAltName(p: Parsed) []const u8 {
|
||||
return p.slice(p.subject_alt_name_slice);
|
||||
}
|
||||
|
||||
pub fn signature(p: Parsed) []const u8 {
|
||||
return p.slice(p.signature_slice);
|
||||
}
|
||||
@ -195,20 +204,33 @@ pub fn parse(cert: Certificate) !Parsed {
|
||||
const pub_key_elem = try der.parseElement(cert_bytes, pub_key_signature_algorithm.slice.end);
|
||||
const pub_key = try parseBitString(cert, pub_key_elem);
|
||||
|
||||
const rdn = try der.parseElement(cert_bytes, subject.slice.start);
|
||||
const atav = try der.parseElement(cert_bytes, rdn.slice.start);
|
||||
|
||||
var common_name = der.Element.Slice.empty;
|
||||
var atav_i = atav.slice.start;
|
||||
while (atav_i < atav.slice.end) {
|
||||
const ty_elem = try der.parseElement(cert_bytes, atav_i);
|
||||
const ty = try parseAttribute(cert_bytes, ty_elem);
|
||||
const val = try der.parseElement(cert_bytes, ty_elem.slice.end);
|
||||
switch (ty) {
|
||||
.commonName => common_name = val.slice,
|
||||
else => {},
|
||||
var subject_alt_name = der.Element.Slice.empty;
|
||||
var name_i = subject.slice.start;
|
||||
//std.debug.print("subject name:\n", .{});
|
||||
while (name_i < subject.slice.end) {
|
||||
const rdn = try der.parseElement(cert_bytes, name_i);
|
||||
var rdn_i = rdn.slice.start;
|
||||
while (rdn_i < rdn.slice.end) {
|
||||
const atav = try der.parseElement(cert_bytes, rdn_i);
|
||||
var atav_i = atav.slice.start;
|
||||
while (atav_i < atav.slice.end) {
|
||||
const ty_elem = try der.parseElement(cert_bytes, atav_i);
|
||||
const ty = try parseAttribute(cert_bytes, ty_elem);
|
||||
const val = try der.parseElement(cert_bytes, ty_elem.slice.end);
|
||||
//std.debug.print(" {s}: '{s}'\n", .{
|
||||
// @tagName(ty), cert_bytes[val.slice.start..val.slice.end],
|
||||
//});
|
||||
switch (ty) {
|
||||
.commonName => common_name = val.slice,
|
||||
.subject_alt_name => subject_alt_name = val.slice,
|
||||
else => {},
|
||||
}
|
||||
atav_i = val.slice.end;
|
||||
}
|
||||
rdn_i = atav.slice.end;
|
||||
}
|
||||
atav_i = val.slice.end;
|
||||
name_i = rdn.slice.end;
|
||||
}
|
||||
|
||||
const sig_algo = try der.parseElement(cert_bytes, tbs_certificate.slice.end);
|
||||
@ -220,6 +242,7 @@ pub fn parse(cert: Certificate) !Parsed {
|
||||
return .{
|
||||
.certificate = cert,
|
||||
.common_name_slice = common_name,
|
||||
.subject_alt_name_slice = subject_alt_name,
|
||||
.issuer_slice = issuer.slice,
|
||||
.subject_slice = subject.slice,
|
||||
.signature_slice = signature,
|
||||
@ -397,8 +420,11 @@ pub fn parseAlgorithmCategory(bytes: []const u8, element: der.Element) !Algorith
|
||||
pub fn parseAttribute(bytes: []const u8, element: der.Element) !Attribute {
|
||||
if (element.identifier.tag != .object_identifier)
|
||||
return error.CertificateFieldHasWrongDataType;
|
||||
return Attribute.map.get(bytes[element.slice.start..element.slice.end]) orelse
|
||||
return error.CertificateHasUnrecognizedAlgorithm;
|
||||
const oid_bytes = bytes[element.slice.start..element.slice.end];
|
||||
return Attribute.map.get(oid_bytes) orelse {
|
||||
//std.debug.print("attr: {}\n", .{std.fmt.fmtSliceHexLower(oid_bytes)});
|
||||
return error.CertificateHasUnrecognizedAttribute;
|
||||
};
|
||||
}
|
||||
|
||||
fn verifyRsa(
|
||||
|
||||
@ -323,8 +323,8 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8)
|
||||
var handshake_state: HandshakeState = .encrypted_extensions;
|
||||
var cleartext_bufs: [2][8000]u8 = undefined;
|
||||
var main_cert_pub_key_algo: Certificate.AlgorithmCategory = undefined;
|
||||
var main_cert_pub_key_buf: [128]u8 = undefined;
|
||||
var main_cert_pub_key_len: u8 = undefined;
|
||||
var main_cert_pub_key_buf: [300]u8 = undefined;
|
||||
var main_cert_pub_key_len: u16 = undefined;
|
||||
|
||||
while (true) {
|
||||
const end_hdr = i + 5;
|
||||
@ -503,7 +503,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8)
|
||||
var verify_buffer =
|
||||
([1]u8{0x20} ** 64) ++
|
||||
"TLS 1.3, server CertificateVerify\x00".* ++
|
||||
([1]u8{undefined} ** max_digest_len);
|
||||
@as([max_digest_len]u8, undefined);
|
||||
|
||||
const verify_bytes = switch (handshake_cipher) {
|
||||
inline else => |*p| v: {
|
||||
@ -524,7 +524,15 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8)
|
||||
const key = try P256.PublicKey.fromSec1(main_cert_pub_key);
|
||||
try sig.verify(verify_bytes, key);
|
||||
},
|
||||
else => return error.TlsBadSignatureAlgorithm,
|
||||
.rsa_pss_rsae_sha256 => {
|
||||
@panic("TODO signature algorithm: rsa_pss_rsae_sha256");
|
||||
},
|
||||
else => {
|
||||
//std.debug.print("signature algorithm: {any}\n", .{
|
||||
// algorithm,
|
||||
//});
|
||||
return error.TlsBadSignatureAlgorithm;
|
||||
},
|
||||
}
|
||||
},
|
||||
@enumToInt(HandshakeType.finished) => {
|
||||
@ -557,7 +565,7 @@ pub fn init(stream: net.Stream, ca_bundle: Certificate.Bundle, host: []const u8)
|
||||
@enumToInt(ContentType.application_data),
|
||||
0x03, 0x03, // legacy protocol version
|
||||
0, wrapped_len, // byte length of encrypted record
|
||||
} ++ ([1]u8{undefined} ** wrapped_len);
|
||||
} ++ @as([wrapped_len]u8, undefined);
|
||||
|
||||
const ad = finished_msg[0..5];
|
||||
const ciphertext = finished_msg[5..][0..out_cleartext.len];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user