parsav  Check-in [e7e16156a6]

Overview
Comment:begin steps to port parsav to mbedtls3 and modern nix. also? fuck mbedtls with a fucking jackhammer i am never using it again holy fuck
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e7e16156a6023585c11c86749c3558437a308e730fb5e55fb4a20b53e4027749
User & Date: lexi on 2022-11-04 12:45:06
Other Links: manifest | tags
Context
2022-11-04
16:49
fix privilege bugs, make visible and shout actually do things check-in: 611a321026 user: lexi tags: trunk
12:45
begin steps to port parsav to mbedtls3 and modern nix. also? fuck mbedtls with a fucking jackhammer i am never using it again holy fuck check-in: e7e16156a6 user: lexi tags: trunk
04:27
fixes to make parsav build on modern nix check-in: 8648683aba user: lexi tags: trunk
Changes

Modified crypt.t from [530b761d29] to [2e175d9d09].

     1      1   -- vim: ft=terra
     2      2   local const = {
     3      3   	keybits = 2048;
     4         -	sighash = lib.md.MBEDTLS_MD_SHA256;
            4  +	sighash = constant(uint32, lib.md.MBEDTLS_MD_SHA256);
     5      5   }
            6  +const.keybits_c = constant(uint32,const.keybits);
     6      7   local err = {
     7      8   	rawcode = terra(code: int)
     8      9   		if code < 0 then code = -code end
     9     10   		return code and 0xFF80
    10     11   	end;
    11     12   	toobig = -lib.pk.MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
    12     13   }
................................................................................
    88     89   terra m.der(pub: bool, key: &ctx, buf: &uint8): binblob
    89     90   	var ofs: ptrdiff
    90     91   	if pub then
    91     92   		ofs = lib.pk.mbedtls_pk_write_pubkey_der(key, buf, const.maxdersz)
    92     93   	else
    93     94   		ofs = lib.pk.mbedtls_pk_write_key_der(key, buf, const.maxdersz)
    94     95   	end
    95         -	if ofs < 0 then return binblob.null() end
           96  +
           97  +	if ofs == lib.asn1.MBEDTLS_ERR_ASN1_BUF_TOO_SMALL then
           98  +		lib.warn("BUG: bad buffer size for lib.crypt.der")
           99  +		return binblob.null()
          100  +	elseif ofs == lib.pk.MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE then
          101  +		lib.warn("mbedtls broken! asymmetric-key crypto unsupported")
          102  +		return binblob.null()
          103  +	elseif ofs == lib.pk.MBEDTLS_ERR_RSA_BAD_INPUT_DATA then
          104  +		lib.warn("bad RSA input to lib.crypt.der")
          105  +		return binblob.null()
          106  +	elseif ofs < 0 then
          107  +		var num: int8[21]
          108  +		var sz = lib.str.bfmt(num, "%lld", ofs)
          109  +		lib.warn("unknown MBEDTLS error ", {&num[0], sz});
          110  +		return binblob.null()
          111  +	end
          112  +
    96    113   	return binblob {
    97    114   		ptr = buf + (const.maxdersz - ofs);
    98    115   		ct = ofs;
    99    116   	}
   100    117   end
   101    118   
   102    119   m.destroy = lib.dispatch {
   103    120   	[ctx] = function(v) return `lib.pk.mbedtls_pk_free(&v) end;
   104    121   
   105    122   	[false] = function(ptr) return `ptr:free() end;
   106    123   }
          124  +
          125  +terra m.pk_genrsa(pk: &ctx)
          126  +-- fuck you arm for making requiring this inane pipe-through-cat
          127  +-- what is wrong with you demented bastards
          128  +	var noise: uint8[2048]
          129  +	m.spray(noise,2048)
          130  +	var rng: lib.drbg.mbedtls_ctr_drbg_context
          131  +	var entropy: lib.entropy.mbedtls_entropy_context
          132  +	lib.drbg.mbedtls_ctr_drbg_init(&rng)
          133  +	lib.entropy.mbedtls_entropy_init(&entropy)
          134  +	lib.drbg.mbedtls_ctr_drbg_seed(&rng, lib.entropy.mbedtls_entropy_func, &entropy, &noise[0], 2048)
          135  +	var rsa = lib.pk.pk2rsa(@pk)
          136  +	lib.rsa.mbedtls_rsa_init(rsa)
          137  +	var e = lib.rsa.mbedtls_rsa_gen_key(rsa, lib.drbg.mbedtls_ctr_drbg_random, &rng, const.keybits_c, 3)
          138  +	if e < 0 then
          139  +		var buf: int8[22]
          140  +		lib.bail("BUG: could not buf-generate RSA keypair; mbedtls reports error ",
          141  +			lib.math.decstrs(e, &buf[21]))
          142  +	end
          143  +	if lib.rsa.mbedtls_rsa_check_privkey(rsa) < 0 then
          144  +		lib.bail("BUG: generated bad RSA keypair")
          145  +	end
          146  +end
   107    147   
   108    148   terra m.genkp(): lib.pk.mbedtls_pk_context
   109    149   	lib.dbg('generating new keypair')
   110    150   
   111    151   	var pk: ctx
   112    152   	lib.pk.mbedtls_pk_init(&pk)
   113         -	lib.pk.mbedtls_pk_setup(&pk, lib.pk.mbedtls_pk_info_from_type(lib.pk.MBEDTLS_PK_RSA))
   114         -	var rsa = [&lib.rsa.mbedtls_rsa_context](pk.pk_ctx)
   115         -	lib.rsa.mbedtls_rsa_gen_key(rsa, callbacks.randomize, nil, const.keybits, 65537)
   116         -
          153  +	if lib.pk.mbedtls_pk_setup(&pk, lib.pk.mbedtls_pk_info_from_type(lib.pk.MBEDTLS_PK_RSA)) < 0 then
          154  +		lib.bail 'pk context setup failed'
          155  +	end
          156  +	m.pk_genrsa(&pk)
   117    157   	return pk
   118    158   end
          159  +
   119    160   
   120    161   local binblob = lib.mem.ptr(uint8)
   121    162   terra m.loadpriv(buf: binblob): lib.stat(ctx)
   122    163   	lib.dbg('parsing saved private key')
   123    164   
   124    165   	var pk: ctx
   125    166   	lib.pk.mbedtls_pk_init(&pk)
   126         -	var rt = lib.pk.mbedtls_pk_parse_key(&pk, buf.ptr, buf.ct, nil, 0)
          167  +	var rt = lib.pk.mbedtls_pk_parse_key(&pk,
          168  +		[&uint8](buf.ptr), [intptr](buf.ct),
          169  +		nil, 0,
          170  +		callbacks.randomize, nil)
   127    171   	if rt == 0 then
   128    172   		return [lib.stat(ctx)] { ok = true, val = pk }
   129    173   	else
   130    174   		lib.pk.mbedtls_pk_free(&pk)
   131    175   		return [lib.stat(ctx)] { ok = false, error = rt }
   132    176   	end
   133    177   end
................................................................................
   154    198   	
   155    199   	lib.dbg('(1/2) hashing message')
   156    200   	if lib.md.mbedtls_md(lib.md.mbedtls_md_info_from_type(const.sighash), [&uint8](txt), len, hash) ~= 0 then
   157    201   		lib.bail('could not hash message')
   158    202   	end
   159    203   
   160    204   	lib.dbg('(2/2) signing hash')
   161         -	var ret = lib.pk.mbedtls_pk_sign(pk, const.sighash, hash, 0, [&uint8](sig.ptr), &osz, callbacks.randomize, nil)
          205  +	var ret = lib.pk.mbedtls_pk_sign(pk, const.sighash,
          206  +		hash, sizeof([hash.type]),
          207  +		[&uint8](sig.ptr), 2048, &osz,
          208  +		callbacks.randomize, nil)
   162    209   	if ret ~= 0 then lib.bail('could not sign message hash')
   163    210   	else sig:resize(osz) end
   164    211   
   165    212   	return sig
   166    213   end
          214  +
   167    215   
   168    216   terra m.verify(pk: &ctx, txt: rawstring, len: intptr,
   169    217                           sig: &uint8, siglen: intptr): {bool, uint8}
   170    218   	lib.dbg('verifying signature')
   171    219   	var osz: intptr = 0
   172    220   	var hash: uint8[64]
   173    221   
................................................................................
   201    249   		if lib.pk.mbedtls_pk_verify(pk, hk, hash, 0, [&uint8](sig), siglen) == 0 then
   202    250   			return true, secl
   203    251   		end
   204    252   	end
   205    253   	lib.dbg('all hash algorithms failed')
   206    254   	return false, 0
   207    255   end
   208         -
   209    256   terra m.hmac(alg: hashalg, key: lib.mem.ptr(uint8), txt: lib.mem.ptr(int8), buf: &uint8)
   210    257   	lib.md.mbedtls_md_hmac(
   211    258   			lib.md.mbedtls_md_info_from_type(alg.id), 
   212    259   			key.ptr, key.ct,
   213    260   			[&uint8](txt.ptr), txt.ct,
   214    261   			buf) -- sz(buf) >= hash output size
   215    262   end
................................................................................
   256    303   	for i = 0, len do
   257    304   		a:ppush(words[m.random(intptr,0,[words.type.N])]):lpush '-'
   258    305   	end
   259    306   	a:ipush(m.random(uint32,0,99999))
   260    307   end
   261    308   
   262    309   return m
          310  +

Modified default.nix from [e620433c36] to [552f41e3b4].

     1      1   let pkg = import <nixpkgs> {};
     2      2   in {stdenv          ? pkg.stdenv,
     3      3   	fetchFromGitHub ? pkg.fetchFromGitHub,
     4      4   	terra           ? pkg.terra,
     5      5   	pkgconfig       ? pkg.pkgconfig,
     6      6   	json_c          ? pkg.json_c,
     7      7   	postgresql      ? pkg.postgresql.lib,
     8         -	mbedtls         ? pkg.mbedtls,
            8  +	mbedtlsLegacy   ? pkg.mbedtls,
     9      9   	glibc           ? pkg.glibc,
    10     10   	cmark           ? pkg.cmark,
    11     11   	inkscape        ? pkg.inkscape,
    12     12   	mongoose        ? null,
    13         -	lib             ? pkg.lib
           13  +	lib             ? pkg.lib,
           14  +	pypkgs			? pkg.python310Packages,
           15  +	debug           ? true
    14     16   }:
    15     17   let mgsrc = if mongoose != null then mongoose
    16     18   			else fetchFromGitHub {
    17     19   				owner = "cesanta";
    18     20   				repo = "mongoose";
    19     21   				rev = "369f44adfa38e0d8fa9667e9d6bafd7e0e3c6231";
    20     22   				sha256 = "17rkd7ydic39cw9sfh11mcil02vmi6jjyj2ncbxan6psak09xbrc";
    21     23   			};
    22     24   	pkv = val: p: "parsav_pkg_${p}_${val}";
    23     25   	pkp = pkv "prefix";
           26  +	mbedtls = mbedtlsLegacy.overrideAttrs(o: rec{
           27  +		version = "3.0-dev";
           28  +		nativeBuildInputs = o.nativeBuildInputs ++ [pypkgs.jinja2];
           29  +		src = fetchFromGitHub {
           30  +			owner = "ARMmbed"; repo = "mbedtls";
           31  +			rev = "49e9fbd6bc7c970c221be6e35f6872762ddde0bc";
           32  +			sha256 = "1ips4mx8rr0kcqn7vdapx2m9xh4cayb7isbwvr98qp2ybi4pi4ai";
           33  +		};
           34  +	});
    24     35   in stdenv.mkDerivation {
    25     36   	name = "parsav";
    26     37   	version = "dev";
    27     38   	nativeBuildInputs = [terra json_c pkgconfig mbedtls];
    28     39   	buildInputs = [cmark inkscape postgresql postgresql.lib];
    29     40   	src = ./.;
    30     41   
           42  +	dontStrip = debug;
           43  +	dbg = if debug then 1 else null;
           44  +
    31     45   	${pkp "json-c"} = "${json_c}";
    32     46   	${pkp "mbedtls"} = "${mbedtls}";
    33     47   	${pkp "libc"} = "${glibc.out}";
    34     48   	${pkp "cmark"} = "${cmark}";
    35     49   	${pkp "inkscape"} = "${inkscape}";
    36     50   	${pkv "incdir" "libpq"} = "${postgresql.out}/include";
    37     51   	${pkv "libdir" "libpq"} = "${postgresql.lib}/lib";

Modified math.t from [60b64e2aea] to [cdf2deb1fe].

   160    160   end
   161    161   
   162    162   terra m.decstr(val: intptr, buf: &int8): rawstring
   163    163   -- works backwards to avoid copies. log10(2^64) ≈ 19.2 and we
   164    164   -- need a byte for NUL so buf MUST point to THE END OF a buffer
   165    165   -- at least 21 bytes long
   166    166   	@buf = 0
   167         -	if val > 0 then while val > 0 do
          167  +	if val ~= 0 then
          168  +		while val > 0 do
          169  +			buf = buf - 1
          170  +			var dgt = val % 10
          171  +			val = val / 10
          172  +			@buf = 0x30 + dgt
          173  +		end
          174  +	else
   168    175   		buf = buf - 1
   169         -		var dgt = val % 10
   170         -		val = val / 10
   171         -		@buf = 0x30 + dgt
   172         -	end else
          176  +		@buf = 0x30
          177  +	end
          178  +	return buf
          179  +end
          180  +
          181  +terra m.decstrs(inval: ptrdiff, buf: &int8): rawstring
          182  +-- works backwards to avoid copies. log10(2^64) ≈ 19.2 and we
          183  +-- need a byte for NUL so buf MUST point to THE END OF a buffer
          184  +-- at least 22 bytes long
          185  +	@buf = 0
          186  +	var val = inval
          187  +	if val ~= 0 then
          188  +		if val < 0 then
          189  +			val = -val
          190  +		end
          191  +		while val > 0 do
          192  +			buf = buf - 1
          193  +			var dgt = val % 10
          194  +			val = val / 10
          195  +			@buf = 0x30 + dgt
          196  +		end
          197  +		if inval < 0 then
          198  +			buf = buf - 1
          199  +			@buf = @"-"
          200  +		end
          201  +	else
   173    202   		buf = buf - 1
   174    203   		@buf = 0x30
   175    204   	end
   176    205   	return buf
   177    206   end
   178    207   
   179    208   terra m.decstr_friendly(val: intptr, buf: &int8): rawstring

Modified mgtool.t from [36fb1b8ec6] to [ca08eb5d7e].

   300    300   					srv:conprep(lib.store.prepmode.conf)
   301    301   
   302    302   					do var newkp = lib.crypt.genkp()
   303    303   					 -- generate server privkey
   304    304   						var kbuf: uint8[lib.crypt.const.maxdersz]
   305    305   						var derkey = lib.crypt.der(false,&newkp, &kbuf[0])
   306    306   						if not derkey then
   307         -							lib.bail('could not write out DER form of server pubkey!')
          307  +							lib.bail('could not write out DER form of server privkey!')
   308    308   						end
   309    309   						dlg:server_setup_self(dbmode.arglist(1), derkey)
   310    310   					end
   311    311   
   312    312   					dlg:conf_set('instance-name', dbmode.arglist(1))
   313    313   					dlg:conf_set('domain', dbmode.arglist(1))
   314    314   					do var sec: int8[65] gensec(&sec[0])

Modified parsav.t from [9e243d4979] to [04815ba40d].

   429    429   		end
   430    430   	end
   431    431   	return set
   432    432   end
   433    433   
   434    434   lib.err = lib.loadlib('mbedtls','mbedtls/error.h')
   435    435   lib.rsa = lib.loadlib('mbedtls','mbedtls/rsa.h')
   436         -lib.pk = lib.loadlib('mbedtls','mbedtls/pk.h')
          436  +lib.asn1 = lib.loadlib('mbedtls','mbedtls/asn1.h')
          437  +-- lib.pk = lib.loadlib('mbedtls','mbedtls/pk.h')
          438  +--sigh
          439  +lib.pk = terralib.includecstring [[
          440  +	#include <mbedtls/pk.h>
          441  +	mbedtls_rsa_context* pk2rsa(const mbedtls_pk_context pk) {
          442  +		return mbedtls_pk_rsa(pk);
          443  +	}
          444  +]]
   437    445   lib.md = lib.loadlib('mbedtls','mbedtls/md.h')
          446  +lib.drbg = lib.loadlib('mbedtls','mbedtls/ctr_drbg.h')
          447  +lib.entropy = lib.loadlib('mbedtls','mbedtls/entropy.h')
   438    448   lib.b64 = lib.loadlib('mbedtls','mbedtls/base64.h')
   439    449   lib.net = lib.loadlib('mongoose','mongoose.h')
   440    450   lib.pq = lib.loadlib('libpq','libpq-fe.h')
   441    451   lib.jc = lib.loadlib('mjson','mjson.h')
   442    452   
   443    453   lib.load {
   444    454   	'mem', 'math', 'str', 'file', 'crypt', 'ipc';