Differences From
Artifact [f5b057e4fa]:
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