Conrad Hoffmann: 1 Adapt to stdlib memio/strio/bufio rewrite 14 files changed, 50 insertions(+), 47 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~apreiml/hare-tls/patches/43428/mbox | git am -3Learn more about email & git
See https://git.sr.ht/~sircmpwn/hare/commit/ed762a2 for context. --- I wanted to play with hare-tls a bit and this was the first thing I ran into. I tried to faithfully convert everything. I still have two broken tests, but I am pretty sure they are unrelated: Failures: crypto::tls::connectself: /home/conrad/hack/hare/hare-tls/crypto/tls/clienthandshake.ha:444:35: slice or array access out of bounds integr::nginx::nginx: /home/conrad/hack/hare/hare-tls/integr/nginx/test.ha:65:38: error occurred All other tests pass. I hope this may spare you the tedious task, even if you need to make a modification or two. I'll investigate the failing tests further, but it might take some time. crypto/tls/+test/message.ha | 6 +++--- crypto/tls/cert.ha | 6 +++--- crypto/tls/clienthandshake.ha | 10 +++++----- crypto/tls/serverhandshake.ha | 6 +++--- crypto/x509/cert.ha | 12 ++++++------ crypto/x509/key.ha | 6 +++--- crypto/x509/store.ha | 6 +++--- encoding/asn1/der+test.ha | 13 ++++++++----- encoding/asn1/dump.ha | 4 ++-- encoding/asn1/oid.ha | 6 +++--- encoding/asn1/types.ha | 6 +++--- format/pkcs/+test.ha | 4 ++-- format/pkcs/rsa.ha | 6 +++--- integr/nginx/test.ha | 6 +++--- 14 files changed, 50 insertions(+), 47 deletions(-) diff --git a/crypto/tls/+test/message.ha b/crypto/tls/+test/message.ha index f74a803..8755bdd 100644 --- a/crypto/tls/+test/message.ha +++ b/crypto/tls/+test/message.ha @@ -1,6 +1,6 @@ // License: MPL-2.0 // (c) 2023 Armin Preiml <apreiml@strohwolke.at> -use bufio; +use memio; use bytes; use crypto::tls::cs; use encoding::hex; @@ -144,10 +144,10 @@ use fmt; let w = newmsgreader(&bufs, buf)!; let lw = io::limitreader(&w, n); - let res = bufio::dynamic(io::mode::WRITE); + let res = memio::dynamic(); io::copy(&res, &lw)!; - let result = bufio::buffer(&res); + let result = memio::buffer(&res); for (let i = 0z; i < n; i += 1) { assert(result[i] == i: u8); }; diff --git a/crypto/tls/cert.ha b/crypto/tls/cert.ha index c2cd0cf..146167c 100644 --- a/crypto/tls/cert.ha +++ b/crypto/tls/cert.ha @@ -1,7 +1,7 @@ // License: MPL-2.0 // (c) 2023 Armin Preiml <apreiml@strohwolke.at> use bytes; -use bufio; +use memio; use crypto::ed25519; use encoding::pem; use errors; @@ -27,9 +27,9 @@ export fn loadcerts(src: io::handle) ([]cert | io::error) = { return errors::invalid; }; - let cbuf = bufio::dynamic(io::mode::WRITE); + let cbuf = memio::dynamic(); io::copy(&cbuf, &csec.1)!; - return alloc([bufio::buffer(&cbuf): cert]); + return alloc([memio::buffer(&cbuf): cert]); }; // Frees certs allocated by [[loadcerts]]. diff --git a/crypto/tls/clienthandshake.ha b/crypto/tls/clienthandshake.ha index b3e6e7f..e139e78 100644 --- a/crypto/tls/clienthandshake.ha +++ b/crypto/tls/clienthandshake.ha @@ -1,6 +1,6 @@ // License: MPL-2.0 // (c) 2023 Armin Preiml <apreiml@strohwolke.at> -use bufio; +use memio; use crypto::random; use crypto::aes; use crypto::cipher; @@ -209,7 +209,7 @@ fn client_inithandshakehash(c: *client, sum: []u8) void = { // hash sum of all handshake messages, which is used for key derivation. let h = &c.thash; - // let h = bufio::dynamic(io::mode::WRITE); + // let h = memio::dynamic(); // TODO fix the hacks const start = c.stream.sbufs.start; @@ -242,7 +242,7 @@ fn client_inithandshakehash(c: *client, sum: []u8) void = { hash::sum(h, sum); log::lprintln(c.log, "first transcript hash:", hex::encodestr(sum)); // fmt::println("hahsshshs")!; - // hex::dump(os::stderr, bufio::buffer(h))!; + // hex::dump(os::stderr, memio::buffer(h))!; }; fn ext_readkeyshare(c: *client, m: *msgstream) (void | error) = { @@ -334,7 +334,7 @@ fn hkdfexpandlabel(dest: []u8, key: []u8, label: []u8, context: []u8) void = { // RFC 8446 7.1 // TODO static let hkdflabel: []u8 = alloc([0...], 2 + 6 + 1 + len(label) + 1 + len(context)); - let w = bufio::dynamic(io::mode::WRITE); + let w = memio::dynamic(); writeu16(&w, len(dest): u16)!; writeu8(&w, len(label): u8 + 6)!; @@ -347,7 +347,7 @@ fn hkdfexpandlabel(dest: []u8, key: []u8, label: []u8, context: []u8) void = { let h = sha512::sha384(); let buf: []u8 = alloc([0...], hash::sz(&h) + hash::bsz(&h)); - hkdf::expand(&h, dest, key, bufio::buffer(&w), buf); + hkdf::expand(&h, dest, key, memio::buffer(&w), buf); }; fn client_parseencext(c: *client, ms: *msgstream) (void | error) = { diff --git a/crypto/tls/serverhandshake.ha b/crypto/tls/serverhandshake.ha index c132c95..0ff5aaf 100644 --- a/crypto/tls/serverhandshake.ha +++ b/crypto/tls/serverhandshake.ha @@ -1,6 +1,6 @@ // License: MPL-2.0 // (c) 2023 Armin Preiml <apreiml@strohwolke.at> -use bufio; +use memio; use encoding::hex; use fmt; use io; @@ -329,7 +329,7 @@ fn srv_sendcertverify(s: *server) (void | error) = { let hh: []u8 = alloc([0...], sha512::SIZE384); hash::sum(&s.thash, hh); - let sigmsg = bufio::dynamic(io::mode::WRITE); + let sigmsg = memio::dynamic(); defer io::close(&sigmsg)!; let prefix: [64]u8 = [0x20...]; io::writeall(&sigmsg, prefix)!; @@ -346,7 +346,7 @@ fn srv_sendcertverify(s: *server) (void | error) = { let cfg = s.cfg as *config; let pk = cfg.privkey as *privkey; edkey[..] = pk.key[..ed25519::PRIVKEYSZ]; - let sig = ed25519::sign(&edkey, bufio::buffer(&sigmsg)); + let sig = ed25519::sign(&edkey, memio::buffer(&sigmsg)); write(&m, sig)?; // TODO diff --git a/crypto/x509/cert.ha b/crypto/x509/cert.ha index c060368..3343165 100644 --- a/crypto/x509/cert.ha +++ b/crypto/x509/cert.ha @@ -1,6 +1,6 @@ // License: MPL-2.0 // (c) 2023 Armin Preiml <apreiml@strohwolke.at> -use bufio; +use memio; use bytes; use crypto::ed25519; use crypto::sha256; @@ -95,7 +95,7 @@ export fn cert_fromder(b: []u8) (cert | error) = { ... }; - let mem = bufio::fixed(b, io::mode::READ); + let mem = memio::fixed(b); let d = asn1::derdecoder(&mem); const h = asn1::peek(&d)?; @@ -343,7 +343,7 @@ fn parseext(c: *cert, d: *asn1::decoder) (void | error) = { fn cert_parseext(c: *cert, d: *asn1::decoder, oid: []u8) (bool | error) = { if (bytes::equal(oidbasicc, oid)) { let sr = asn1::octstrreader(d)?; - let tmp = bufio::dynamic(io::mode::WRITE); + let tmp = memio::dynamic(); let ed = asn1::derdecoder(&sr); asn1::openseq(&ed)?; @@ -480,7 +480,7 @@ fn cert_parsesig(c: *cert, d: *asn1::decoder) (void | error) = { fn cert_rawval(c: *cert, pos: size) []u8 = { let buf = c.raw[pos..]; - let r = bufio::fixed(buf, io::mode::READ); + let r = memio::fixed(buf); let d = asn1::derdecoder(&r); const h = asn1::peek(&d) as asn1::head; return buf[h.data..h.end]; @@ -495,7 +495,7 @@ export fn cert_checksigfrom(c: *cert, p: *cert) (void | error) = { // TODO certpos? const pos = 4z; let buf = c.raw[pos..]; - let r = bufio::fixed(buf, io::mode::READ); + let r = memio::fixed(buf); let d = asn1::derdecoder(&r); const h = asn1::peek(&d) as asn1::head; let cert = buf[..h.end]; @@ -540,7 +540,7 @@ export fn dump(out: io::handle, data: []u8) (void | error) = { fn dumpname(out: io::handle, name: []u8) (void | error) = { // TODO iterator? - let buf = bufio::fixed(name, io::mode::READ); + let buf = memio::fixed(name); let dec = asn1::derdecoder(&buf); let d = &dec; diff --git a/crypto/x509/key.ha b/crypto/x509/key.ha index c10542c..fd207a7 100644 --- a/crypto/x509/key.ha +++ b/crypto/x509/key.ha @@ -1,6 +1,6 @@ // License: MPL-2.0 // (c) 2023 Armin Preiml <apreiml@strohwolke.at> -use bufio; +use memio; use crypto::ec; use crypto::ed25519; use crypto::rsa; @@ -179,7 +179,7 @@ fn rsa_verify( }; fn rsa_parsepub(pubkey: []u8, src: []u8) (void | error) = { - let mem = bufio::fixed(src, io::mode::READ); + let mem = memio::fixed(src); let d = asn1::derdecoder(&mem); asn1::openseq(&d)?; @@ -266,7 +266,7 @@ fn ec_verify( let r: [128]u8 = [0...]; let s: [128]u8 = [0...]; - let mem = bufio::fixed(sig, io::mode::READ); + let mem = memio::fixed(sig); let d = asn1::derdecoder(&mem); // TODO error asn1::openseq(&d)!; diff --git a/crypto/x509/store.ha b/crypto/x509/store.ha index 3902d37..22272b8 100644 --- a/crypto/x509/store.ha +++ b/crypto/x509/store.ha @@ -6,7 +6,7 @@ use os; use fs; use io; use encoding::pem; -use bufio; +use memio; // TODO use a proper data structure for certs with better lookup and // de-duplication @@ -102,13 +102,13 @@ fn store_addfromhandle(s: *store, f: io::handle) (void | fs::error | error) = { yield e.1; }; - let buf = bufio::dynamic(io::mode::WRITE); + let buf = memio::dynamic(); match (io::copy(&buf, &dec)) { case size => yield; case let e: io::error => return e: fs::error; }; - let raw = bufio::buffer(&buf); + let raw = memio::buffer(&buf); append(s, cert_fromder(raw)?); }; }; diff --git a/encoding/asn1/der+test.ha b/encoding/asn1/der+test.ha index 7786ab2..d374575 100644 --- a/encoding/asn1/der+test.ha +++ b/encoding/asn1/der+test.ha @@ -2,31 +2,34 @@ // (c) 2023 Armin Preiml <apreiml@strohwolke.at> use bufio; use io; +use memio; +use os; use types; // XXX: would be nice to just declare this as mem: bufio::memstream. -let mem: nullable *bufio::memstream = null; +let mem: nullable *bufio::stream = null; +let rbuf: [os::BUFSIZ]u8 = [0...]; fn d(i: []u8) decoder = { - let buf = bufio::fixed(i, io::mode::READ); + let buf = bufio::init(&memio::fixed(i), rbuf, []); match (mem) { case null => mem = alloc(buf); - case let m: *bufio::memstream => + case let m: *bufio::stream => *m = buf; }; return derdecoder(mem); }; @init fn newdec() void = { - mem = alloc(bufio::fixed([], io::mode::READ)); + mem = alloc(bufio::init(&memio::fixed([]), rbuf, [])); }; @fini fn freetdec() void = { match (mem) { case null => yield; - case let m: *bufio::memstream => + case let m: *bufio::stream => free(m); mem = null; }; diff --git a/encoding/asn1/dump.ha b/encoding/asn1/dump.ha index 4ee01d8..af75a45 100644 --- a/encoding/asn1/dump.ha +++ b/encoding/asn1/dump.ha @@ -1,6 +1,6 @@ // License: MPL-2.0 // (c) 2023 Armin Preiml <apreiml@strohwolke.at> -use bufio; +use memio; use encoding::hex; use errors; use fmt; @@ -9,7 +9,7 @@ use os; // Dumps der encoded 'data' to 'out'. export fn dump(out: io::handle, data: []u8) (void | error) = { - let s = bufio::fixed(data, io::mode::READ); + let s = memio::fixed(data); let p = derdecoder(&s); match (dumpvar(out, &p, 0)?) { case void => diff --git a/encoding/asn1/oid.ha b/encoding/asn1/oid.ha index a7ce30c..dee31ff 100644 --- a/encoding/asn1/oid.ha +++ b/encoding/asn1/oid.ha @@ -5,7 +5,7 @@ use errors; use fmt; use io; use math::{divu}; -use strio; +use memio; use strings; // estimate @@ -88,7 +88,7 @@ export fn oid_fromder(der: []u8, oid: []u32) (size | errors::invalid | errors::o // Caller must free returned value. export fn oidstr(der: []u8) (str | errors::invalid | errors::overflow) = { - let s = strio::dynamic(); + let s = memio::dynamic(); defer io::close(&s)!; let oid: [OIDMAXLEN]u32 = [0...]; @@ -101,7 +101,7 @@ export fn oidstr(der: []u8) (str | errors::invalid | errors::overflow) = { }; }; - return strings::dup(strio::string(&s)); + return strings::dup(memio::string(&s)!); }; export fn stroid(der: []u8) str = { diff --git a/encoding/asn1/types.ha b/encoding/asn1/types.ha index c76bcca..4174e12 100644 --- a/encoding/asn1/types.ha +++ b/encoding/asn1/types.ha @@ -2,7 +2,7 @@ // (c) 2023 Armin Preiml <apreiml@strohwolke.at> use fmt; use io; -use strio; +use memio; // Invalid encoding. export type invalid = !void; @@ -85,14 +85,14 @@ let tagstrbuf: [64]u8 = [0...]; // String representation of universal tag ids. export fn strtag(dh: head) str = { if (dh.class != class::UNIVERSAL) { - let tagstr = strio::fixed(tagstrbuf); + let tagstr = memio::fixed(tagstrbuf); fmt::fprint(&tagstr, "[")!; if (dh.class != class::CONTEXT_SPECIFIC) { fmt::fprintf(&tagstr, "{} ", strclass(dh.class))!; }; fmt::fprintf(&tagstr, "{:x}]", dh.tagid)!; - return strio::string(&tagstr); + return memio::string(&tagstr)!; }; if (dh.tagid >> 8 != 0) { diff --git a/format/pkcs/+test.ha b/format/pkcs/+test.ha index e61d681..22d8d28 100644 --- a/format/pkcs/+test.ha +++ b/format/pkcs/+test.ha @@ -1,12 +1,12 @@ // License: MPL-2.0 // (c) 2023 Armin Preiml <apreiml@strohwolke.at> -use bufio; +use memio; use fmt; use io; use strings; @test fn rsapem() void = { - let pksrc = bufio::fixed(strings::toutf8(privkeystr), io::mode::READ); + let pksrc = memio::fixed(strings::toutf8(privkeystr)); let buf: [1024]u8 = [0...]; // let pk = match (parsepriv(&pksrc, buf)) { // case let e: error => diff --git a/format/pkcs/rsa.ha b/format/pkcs/rsa.ha index 1d08333..ebaebfe 100644 --- a/format/pkcs/rsa.ha +++ b/format/pkcs/rsa.ha @@ -9,7 +9,7 @@ use errors; use fmt; use io; use os; -use bufio; +use memio; export type error = !(...asn1::error | errors::overflow | errors::invalid | io::error); @@ -45,7 +45,7 @@ export type pkcs1_rsapub = struct { }; fn pkcs1_parsersapriv(src: io::handle, buf: []u8) (pkcs1_rsapriv | error) = { - let kbuf = bufio::dynamic(io::mode::WRITE); + let kbuf = memio::dynamic(); let dec = asn1::derdecoder(src); asn1::openseq(&dec)?; @@ -101,7 +101,7 @@ fn writeint(d: *asn1::decoder, buf: []u8) (([]u8, []u8) | error) = { export type ed25519privkey = []u8; fn parseed25519(src: io::handle, buf: []u8) (ed25519privkey | error) = { - let kbuf = bufio::dynamic(io::mode::WRITE); + let kbuf = memio::dynamic(); let dec = asn1::derdecoder(src); let seed: ed25519::seed = [0...]; diff --git a/integr/nginx/test.ha b/integr/nginx/test.ha index 5b77d75..6cf6100 100644 --- a/integr/nginx/test.ha +++ b/integr/nginx/test.ha @@ -4,7 +4,7 @@ use time; use os::exec; use fmt; use os; -use strio; +use memio; use io; use net; use net::dial; @@ -20,13 +20,13 @@ use unix::signal; const GET = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"; @test fn nginx() void = { - let wd = strio::dynamic(); + let wd = memio::dynamic(); defer io::close(&wd)!; fmt::fprint(&wd, "-p")!; fmt::fprint(&wd, os::getcwd())!; fmt::fprint(&wd, "/integr/nginx")!; - let cmd = exec::cmd("nginx", strio::string(&wd), "-cnginx.conf")!; + let cmd = exec::cmd("nginx", memio::string(&wd)!, "-cnginx.conf")!; exec::nullstd(&cmd); let p = exec::start(&cmd)!; -- 2.41.0
Very Nice! Thanks! The tests are failing because I've started to add certificate validation and the certificates are missing or expired. I didn't bother to update the test certificates yet. Also hostname checking does not work yet and some critical extensions are still ignored.