From a712a342ee06c0a34bec1dd300df82306c0592e8 Mon Sep 17 00:00:00 2001 From: Armin Preiml Date: Fri, 27 Sep 2024 16:40:57 +0200 Subject: [PATCH] x509: avoid error on empty subject --- cmd/limbo/main.ha | 3 +++ crypto/x509/cert.ha | 16 +++++++++++----- debug/debug.ha | 12 ++++++------ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/cmd/limbo/main.ha b/cmd/limbo/main.ha index 8923dcd..8d172b7 100644 --- a/cmd/limbo/main.ha +++ b/cmd/limbo/main.ha @@ -80,6 +80,9 @@ export fn main() void = { match (selecttc) { case void => void; case let stc: str => + if (stats.total == 1) { + break; + }; if (stc != tc.id) { continue; }; diff --git a/crypto/x509/cert.ha b/crypto/x509/cert.ha index d39d15b..cabeb54 100644 --- a/crypto/x509/cert.ha +++ b/crypto/x509/cert.ha @@ -69,6 +69,7 @@ export type cert = struct { issuerpos: io::off, subjecthash: [DNHASHSZ]u8, subjectpos: io::off, + subjectempty: bool, issueruidpos: (void | io::off), subjectuidpos: (void | io::off), @@ -275,7 +276,10 @@ fn parse_cert(c: *cert, d: *asn1::decoder) (void | _error) = { c.issuerpos = io::tell(c.h)!; const h = asn1::peek(d)?; - hashdn(d, &c.issuerhash)?; + if (!hashdn(d, &c.issuerhash)?) { + // must have non empty issuer + return badformat; + }; asn1::open_seq(d)?; c.validfrom = read_date(d)?; @@ -284,7 +288,8 @@ fn parse_cert(c: *cert, d: *asn1::decoder) (void | _error) = { c.subjectpos = io::tell(c.h)!; const h = asn1::peek(d)?; - hashdn(d, &c.subjecthash)?; + c.subjectempty = !hashdn(d, &c.subjecthash)?; + // TODO consider subject empty (rfc 5280 4.1.2.6) parse_pubkey(d, &c.pubkey)?; @@ -463,7 +468,7 @@ fn close_dn(d: *asn1::decoder) (void | _error) = { // Creates a hash sum that can be used to compare subject and issuer // distinguished names. -fn hashdn(d: *asn1::decoder, sum: *[sha256::SZ]u8) (void | _error) = { +fn hashdn(d: *asn1::decoder, sum: *[sha256::SZ]u8) (bool | _error) = { // Distinguished names are compared using the process described in // RFC 4518. // TODO implement rfc 4518 @@ -475,8 +480,8 @@ fn hashdn(d: *asn1::decoder, sum: *[sha256::SZ]u8) (void | _error) = { asn1::open_seq(d)?; if (asn1::trypeek(d)? is io::EOF) { - // must have at least one. - return badformat; + asn1::close_seq(d)?; + return false; }; // TODO max? @@ -496,6 +501,7 @@ fn hashdn(d: *asn1::decoder, sum: *[sha256::SZ]u8) (void | _error) = { asn1::close_seq(d)?; hash::sum(&h, sum); + return true; }; type tag = enum u32 { diff --git a/debug/debug.ha b/debug/debug.ha index fcb61fc..f40b94c 100644 --- a/debug/debug.ha +++ b/debug/debug.ha @@ -5,26 +5,26 @@ use memio; use io; export fn print(args: fmt::formattable...) void = { - fmt::println(args...)!; + fmt::errorln(args...)!; }; export fn printf(fmt: str, args: fmt::field...) void = { - fmt::printfln(fmt: str, args...)!; + fmt::errorfln(fmt: str, args...)!; }; export fn hexdump(b: ([]u8 | *memio::stream | io::handle)) void = { match (b) { case let b: []u8 => - hex::dump(os::stdout, b)!; + hex::dump(os::stderr, b)!; case let s: *memio::stream => - hex::dump(os::stdout, memio::buffer(s))!; + hex::dump(os::stderr, memio::buffer(s))!; case let s: io::handle => let buf = io::drain(s)!; defer free(buf); - hex::dump(os::stdout, buf)!; + hex::dump(os::stderr, buf)!; }; }; export fn hexsdump(b: []u8) void = { - fmt::println(hex::encodestr(b))!; + print(hex::encodestr(b)); }; -- 2.45.2