parsav  Diff

Differences From Artifact [f5b057e4fa]:

To Artifact [034fdb64c7]:


    10     10   	end;
    11     11   	toobig = -lib.pk.MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
    12     12   }
    13     13   const.maxpemsz = math.floor((const.keybits / 8)*6.4) + 128 -- idk why this formula works but it basically seems to
    14     14   const.maxdersz = const.maxpemsz -- FIXME this is a safe value but obvs not the correct one
    15     15   
    16     16   local ctx = lib.pk.mbedtls_pk_context
           17  +terra ctx:free() lib.pk.mbedtls_pk_free(self) end
    17     18   
    18     19   local struct hashalg { id: uint8 bytes: intptr }
    19     20   local m = {
    20     21   	pemfile = uint8[const.maxpemsz];
    21     22   	const = const;
    22     23   	algsz = {
    23     24   		sha1 =   160/8;
................................................................................
    78     79   	if pub then
    79     80   		return lib.pk.mbedtls_pk_write_pubkey_pem(key, buf, const.maxpemsz) == 0
    80     81   	else
    81     82   		return lib.pk.mbedtls_pk_write_key_pem(key, buf, const.maxpemsz) == 0
    82     83   	end
    83     84   end
    84     85   
    85         -terra m.der(pub: bool, key: &ctx, buf: &uint8): intptr
           86  +local binblob = lib.mem.ptr(uint8)
           87  +terra m.der(pub: bool, key: &ctx, buf: &uint8): binblob
           88  +	var ofs: intptr
    86     89   	if pub then
    87         -		return lib.pk.mbedtls_pk_write_pubkey_der(key, buf, const.maxdersz)
           90  +		ofs = lib.pk.mbedtls_pk_write_pubkey_der(key, buf, const.maxdersz)
    88     91   	else
    89         -		return lib.pk.mbedtls_pk_write_key_der(key, buf, const.maxdersz)
           92  +		ofs = lib.pk.mbedtls_pk_write_key_der(key, buf, const.maxdersz)
    90     93   	end
           94  +	return binblob {
           95  +		ptr = buf + (const.maxdersz - ofs);
           96  +		ct = ofs;
           97  +	}
    91     98   end
    92     99   
    93    100   m.destroy = lib.dispatch {
    94    101   	[ctx] = function(v) return `lib.pk.mbedtls_pk_free(&v) end;
    95    102   
    96    103   	[false] = function(ptr) return `ptr:free() end;
    97    104   }
................................................................................
   104    111   	lib.pk.mbedtls_pk_setup(&pk, lib.pk.mbedtls_pk_info_from_type(lib.pk.MBEDTLS_PK_RSA))
   105    112   	var rsa = [&lib.rsa.mbedtls_rsa_context](pk.pk_ctx)
   106    113   	lib.rsa.mbedtls_rsa_gen_key(rsa, callbacks.randomize, nil, const.keybits, 65537)
   107    114   
   108    115   	return pk
   109    116   end
   110    117   
   111         -terra m.loadpriv(buf: &uint8, len: intptr): ctx
   112         -	lib.dbg('parsing saved keypair')
          118  +terra m.loadpriv(buf: &uint8, len: intptr): lib.stat(ctx)
          119  +	lib.dbg('parsing saved private key')
          120  +
          121  +	var pk: ctx
          122  +	lib.pk.mbedtls_pk_init(&pk)
          123  +	var rt = lib.pk.mbedtls_pk_parse_key(&pk, buf, len + 1, nil, 0)
          124  +	if rt == 0 then
          125  +		return [lib.stat(ctx)] { ok = true, val = pk }
          126  +	else
          127  +		lib.pk.mbedtls_pk_free(&pk)
          128  +		return [lib.stat(ctx)] { ok = false }
          129  +	end
          130  +end
          131  +
          132  +terra m.loadpub(buf: &uint8, len: intptr): lib.stat(ctx)
          133  +	lib.dbg('parsing saved key')
   113    134   
   114    135   	var pk: ctx
   115    136   	lib.pk.mbedtls_pk_init(&pk)
   116         -	lib.pk.mbedtls_pk_parse_key(&pk, buf, len + 1, nil, 0)
   117         -	return pk
          137  +	var rt = lib.pk.mbedtls_pk_parse_public_key(&pk, buf, len)
          138  +	if rt == 0 then
          139  +		return [lib.stat(ctx)] { ok = true, val = pk }
          140  +	else
          141  +		lib.pk.mbedtls_pk_free(&pk)
          142  +		return [lib.stat(ctx)] { ok = false, error = rt }
          143  +	end
   118    144   end
   119    145   
   120    146   terra m.sign(pk: &ctx, txt: rawstring, len: intptr)
   121    147   	lib.dbg('signing message')
   122    148   	var osz: intptr = 0
   123    149   	var sig = lib.mem.heapa(int8, 2048)
   124    150   	var hash: uint8[32]
................................................................................
   133    159   	if ret ~= 0 then lib.bail('could not sign message hash')
   134    160   	else sig:resize(osz) end
   135    161   
   136    162   	return sig
   137    163   end
   138    164   
   139    165   terra m.verify(pk: &ctx, txt: rawstring, len: intptr,
   140         -                        sig: rawstring, siglen: intptr): {bool, uint8}
          166  +                        sig: &uint8, siglen: intptr): {bool, uint8}
   141    167   	lib.dbg('verifying signature')
   142    168   	var osz: intptr = 0
   143    169   	var hash: uint8[64]
   144    170   
   145    171   	-- there does not appear to be any way to extract the hash algorithm
   146    172   	-- from the message, so we just have to try likely algorithms until
   147    173   	-- we find one that fits or give up. a security level is attached
................................................................................
   151    177   		{lib.md.MBEDTLS_MD_SHA256, 'sha256', 2},
   152    178   		{lib.md.MBEDTLS_MD_SHA512, 'sha512', 3},
   153    179   		{lib.md.MBEDTLS_MD_SHA1,   'sha1',   1},
   154    180   		-- uncommon hashes
   155    181   		{lib.md.MBEDTLS_MD_SHA384, 'sha384', 2},
   156    182   		{lib.md.MBEDTLS_MD_SHA224, 'sha224', 2},
   157    183   		-- bad hashes
   158         -		{lib.md.MBEDTLS_MD_MD5,   'md5', 0},
   159         -		{lib.md.MBEDTLS_MD_MD4,   'md4', 0},
   160         -		{lib.md.MBEDTLS_MD_MD2,   'md2', 0}
          184  +		{lib.md.MBEDTLS_MD_MD5,   'md5', 0}
          185  +		--{lib.md.MBEDTLS_MD_MD4,   'md4', 0},
          186  +		--{lib.md.MBEDTLS_MD_MD2,   'md2', 0}
   161    187   	)
   162    188   	
   163    189   	for i = 0, [algs.type.N] do
   164    190   		var hk, aname, secl = algs[i]
   165    191   
   166    192   		lib.dbg('(1/2) trying hash algorithm ',aname)
   167    193   		if lib.md.mbedtls_md(lib.md.mbedtls_md_info_from_type(hk), [&uint8](txt), len, hash) ~= 0 then
................................................................................
   186    212   end
   187    213   
   188    214   terra m.hmaca(alg: hashalg, key: lib.mem.ptr(uint8), txt: lib.mem.ptr(int8))
   189    215   	var buf = lib.mem.heapa(uint8, alg.bytes)
   190    216   	m.hmac(alg, key, txt, buf.ptr)
   191    217   	return buf
   192    218   end
          219  +
          220  +terra m.hmacp(p: &lib.mem.pool, alg: hashalg, key: lib.mem.ptr(uint8), txt: lib.mem.ptr(int8))
          221  +	var buf = p:alloc(uint8, alg.bytes)
          222  +	m.hmac(alg, key, txt, buf.ptr)
          223  +	return buf
          224  +end
   193    225   
   194    226   terra m.hotp(key: &(uint8[10]), counter: uint64)
   195    227   	var hmac: uint8[20]
   196    228   	var ctr = [lib.mem.ptr(int8)]{ptr = [&int8](&counter), ct = 8}
   197    229   	m.hmac(m.alg.sha1,
   198    230   		[lib.mem.ptr(uint8)]{ptr = [&uint8](key), ct = 10},
   199    231   		ctr, hmac)
................................................................................
   200    232   	
   201    233   	var ofs = hmac[19] and 0x0F
   202    234   	var p: uint8[4]
   203    235   	for i=0,4 do p[i] = hmac[ofs + i] end
   204    236   
   205    237   	return (@[&uint32](&p)) and 0x7FFFFFFF -- one hopes it's that easy
   206    238   end
          239  +
          240  +local splitwords = macro(function(str)
          241  +	local words = {}
          242  +	for w in str:asvalue():gmatch('(%g+)') do words[#words + 1] = w end
          243  +	return `arrayof(lib.str.t, [words])
          244  +end)
          245  +
          246  +terra m.cryptogram(a: &lib.str.acc, len: intptr)
          247  +	var words = splitwords [[
          248  +		alpha beta gamma delta epsilon psi eta nu omicron omega
          249  +		red crimson green verdant golden silver blue cyan navy
          250  +		carnelian opal sapphire amethyst ruby jade emerald
          251  +		chalice peacock cabernet windmill saxony tunnel waterspout
          252  +	]]
          253  +	for i = 0, len do
          254  +		a:ppush(words[m.random(intptr,0,[words.type.N])]):lpush '-'
          255  +	end
          256  +	a:ipush(m.random(uint32,0,99999))
          257  +end
   207    258   
   208    259   return m