···1515let hex = Alcotest.testable Wycheproof.pp_hex Wycheproof.equal_hex
16161717module Asn = struct
1818- (* This is a handcrafted asn1 parser, sufficient for the wycheproof tests.
1919- The underlying reason is to avoid a dependency on asn1-grammars and
2020- mirage-crypto-pk (which depends on gmp and zarith, and are cumbersome to
2121- build on windows with CL.EXE). *)
2222-2323- let guard p e = if p then Ok () else Error e
2424-2525- let decode_len start_off buf =
2626- let len = string_get_uint8 buf start_off in
2727- if len >= 0x80 then
2828- let bytes = len - 0x80 in
2929- let rec g acc off =
3030- if off = bytes then
3131- Ok (acc, bytes + start_off + 1)
3232- else
3333- let this = string_get_uint8 buf (start_off + 1 + off) in
3434- let* () = guard (off = 0 && this >= 0x80) "badly encoded length" in
3535- let acc' = acc lsl 8 + this in
3636- let* () = guard (acc <= acc') "decode_len overflow in acc" in
3737- g (acc lsl 8 + string_get_uint8 buf (start_off + 1 + off)) (succ off)
3838- in
3939- g 0 0
4040- else
4141- Ok (len, start_off + 1)
4242-4343- let decode_seq data =
4444- let* () = guard (String.length data > 2) "decode_seq: data too short" in
4545- let tag = string_get_uint8 data 0 in
4646- let* () = guard (tag = 0x30) "decode_seq: bad tag (should be 0x30)" in
4747- let* len, off = decode_len 1 data in
4848- let* () = guard (String.length data - off >= len) "decode_seq: too short" in
4949- Ok (String.sub data off len,
5050- if String.length data - off > len then
5151- Some (String.sub data (off + len) (String.length data - len - off))
5252- else
5353- None)
5454-5555- let decode_2_oid data =
5656- let decode_one off =
5757- let tag = string_get_uint8 data off in
5858- let* () = guard (tag = 0x06) "decode_oid: bad tag (should be 0x06)" in
5959- let len = string_get_uint8 data (off + 1) in
6060- let* () = guard (String.length data - 2 - off >= len) "decode_oid: data too short" in
6161- Ok (String.sub data (off + 2) len, off + 2 + len)
6262- in
6363- let* first, off = decode_one 0 in
6464- let* second, off = decode_one off in
6565- let* () = guard (off = String.length data) "decode_oid: leftover data" in
6666- Ok (first, second)
6767-6868- let decode_bit_string data =
6969- let tag = string_get_uint8 data 0 in
7070- let* () = guard (tag = 0x03) "decode_bit_string: bad tag (expected 0x03)" in
7171- let* len, off = decode_len 1 data in
7272- let* () = guard (String.length data - off = len) "decode_bit_string: leftover or too short data" in
7373- let unused = string_get_uint8 data off in
7474- let* () = guard (unused = 0) "unused is not 0" in
7575- Ok (String.sub data (off + 1) (len - 1))
7676-7777- let decode_int_pair data =
7878- let decode_int off =
7979- let* () = guard (String.length data - off > 2) "decode_int: data too short" in
8080- let tag = string_get_uint8 data off in
8181- let* () = guard (tag = 0x02) "decode_int: bad tag (should be 0x02)" in
8282- let len = string_get_uint8 data (off + 1) in
8383- let* () = guard (String.length data - off - 2 >= len) "decode_int: too short" in
8484- let fix_one = if string_get_uint8 data (off + 2) = 0x00 then 1 else 0 in
8585- let* () = guard (string_get_uint8 data (off + 2) land 0x80 = 0) "decode_int: negative number" in
8686- let* () =
8787- if String.length data > off + 3 && fix_one = 1 then
8888- guard (string_get_uint8 data (off + 3) <> 0x00) "decode_int: leading extra 0 byte"
8989- else
9090- Ok ()
9191- in
9292- Ok (String.sub data (fix_one + off + 2) (len - fix_one), off + len + 2)
9393- in
9494- let* first, off = decode_int 0 in
9595- let* second, off = decode_int off in
9696- let* () = guard (off = String.length data) "decode_int: leftover data" in
9797- Ok (first, second)
9898-9999- let encode_oid = function
100100- | first :: second :: rt ->
101101- let oct1 = 40 * first + second in
102102- let octs = concat_map (fun x ->
103103- let fst = x / 16384
104104- and snd = x / 128
105105- and thr = x mod 128
106106- in
107107- assert (fst < 128);
108108- (if fst > 0 then [ 128 (* set high bit *) + fst ] else []) @
109109- (if snd > 0 then [ 128 + snd ] else []) @
110110- [ thr ])
111111- rt
112112- in
113113- String.init (1 + List.length octs) (function
114114- | 0 -> char_of_int oct1
115115- | n -> char_of_int (List.nth octs (pred n)))
116116- | _ -> assert false
117117-11818 let parse_point curve s =
119119- let ec_public_key = encode_oid [ 1 ; 2 ; 840; 10045; 2; 1 ] in
120120- let prime_oid = encode_oid (match curve with
121121- | "secp256r1" -> [ 1 ; 2 ; 840; 10045; 3; 1; 7 ]
122122- | "secp384r1" -> [ 1 ; 3 ; 132; 0; 34 ]
123123- | "secp521r1" -> [ 1 ; 3 ; 132; 0; 35 ]
124124- | _ -> assert false)
1919+ let seq2 a b = Asn.S.(sequence2 (required a) (required b)) in
2020+ let term = Asn.S.(seq2 (seq2 oid oid) bit_string_octets) in
2121+ let ec_public_key = Asn.OID.(base 1 2 <|| [ 840; 10045; 2; 1 ]) in
2222+ let prime_oid = match curve with
2323+ | "secp256r1" -> Asn.OID.(base 1 2 <|| [ 840; 10045; 3; 1; 7 ])
2424+ | "secp384r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 34 ])
2525+ | "secp521r1" -> Asn.OID.(base 1 3 <|| [ 132; 0; 35 ])
2626+ | _ -> assert false
12527 in
126126- let* r = decode_seq s in
127127- match r with
128128- | _data, Some _ -> Error "expected no leftover"
129129- | data, None ->
130130- let* r = decode_seq data in
131131- match r with
132132- | _oids, None -> Error "expected some data"
133133- | oids, Some data ->
134134- let* oid1, oid2 = decode_2_oid oids in
135135- let* data = decode_bit_string data in
136136- if not (String.equal oid1 ec_public_key) then
137137- Error "ASN1: wrong oid 1"
138138- else if not (String.equal oid2 prime_oid) then
139139- Error "ASN1: wrong oid 2"
140140- else
141141- Ok data
2828+ match Asn.decode (Asn.codec Asn.ber term) s with
2929+ | Error _ -> Error "ASN1 parse error"
3030+ | Ok (((oid1, oid2), data), rest) ->
3131+ if String.length rest <> 0 then Error "ASN1 leftover"
3232+ else if not (Asn.OID.equal oid1 ec_public_key) then
3333+ Error "ASN1: wrong oid 1"
3434+ else if not (Asn.OID.equal oid2 prime_oid) then Error "ASN1: wrong oid 2"
3535+ else Ok data
14236143143- let parse_signature s =
144144- let* r = decode_seq s in
145145- match r with
146146- | _data, Some _ -> Error "expected no leftover"
147147- | data, None ->
148148- let* r, s = decode_int_pair data in
149149- Ok (r, s)
3737+ let parse_signature cs =
3838+ let asn = Asn.S.(sequence2 (required unsigned_integer) (required unsigned_integer)) in
3939+ match Asn.(decode (codec der asn) cs) with
4040+ | Error _ -> Error "ASN1 parse error"
4141+ | Ok (r_s, rest) ->
4242+ if String.length rest <> 0 then Error "ASN1 leftover"
4343+ else
4444+ Ok r_s
15045end
1514615247let to_string_result ~pp_error = function