Harden browser FFI and secure store parsing
ober
873da2789f9879b497e961214d1273cfa271360e
--- a/scheme/browser/secure-store.ss +++ b/scheme/browser/secure-store.ss @@ -87,6 +87,12 @@ (* 256 (bytevector-u8-ref b (+ o 2))) (bytevector-u8-ref b (+ o 3)))) + (def (require-bytes who b off len) + (unless (and (>= off 0) + (>= len 0) + (<= (+ off len) (bytevector-length b))) + (error who "truncated payload"))) + ;; --- bookmark (de)serialization --- ;; pairs :: list of (url-string . title-string) (def (serialize-pairs pairs) @@ -98,17 +104,29 @@ pairs))) (def (deserialize-pairs b) - (let ([n (u32-ref b 0)]) + (require-bytes 'deserialize-pairs b 0 4) + (let ([n (u32-ref b 0)] + [blen (bytevector-length b)]) (let loop ([i 0] [off 4] [acc '()]) - (if (= i n) (reverse acc) - (let* ([ulen (u16-ref b off)] - [u (sub b (+ off 2) (+ off 2 ulen))] - [off2 (+ off 2 ulen)] - [tlen (u16-ref b off2)] - [t (sub b (+ off2 2) (+ off2 2 tlen))] - [off3 (+ off2 2 tlen)]) - (loop (+ i 1) off3 - (cons (cons (utf8->string u) (utf8->string t)) acc))))))) + (if (= i n) + (if (= off blen) + (reverse acc) + (error 'deserialize-pairs "trailing payload bytes")) + (begin + (require-bytes 'deserialize-pairs b off 2) + (let* ([ulen (u16-ref b off)] + [uoff (+ off 2)]) + (require-bytes 'deserialize-pairs b uoff ulen) + (let* ([u (sub b uoff (+ uoff ulen))] + [off2 (+ uoff ulen)]) + (require-bytes 'deserialize-pairs b off2 2) + (let* ([tlen (u16-ref b off2)] + [toff (+ off2 2)]) + (require-bytes 'deserialize-pairs b toff tlen) + (let* ([t (sub b toff (+ toff tlen))] + [off3 (+ toff tlen)]) + (loop (+ i 1) off3 + (cons (cons (utf8->string u) (utf8->string t)) acc))))))))))) ;; --- RSA-OAEP (SHA-256, empty label) --- ;; lHash is computed lazily: merely loading this module then needs no native