From 26de99b77a8b8aeb465a53b987620b79664f6372 Mon Sep 17 00:00:00 2001 From: Calascibetta Romain Date: Thu, 21 Mar 2024 19:55:06 +0100 Subject: [PATCH 01/17] Remove P224 - see mirage/mirage-crypto#209 --- lib/algorithm.ml | 5 +---- lib/key_type.ml | 8 ++++---- lib/private_key.ml | 10 ---------- lib/public_key.ml | 6 ------ lib/signing_request.ml | 1 - lib/x509.mli | 4 +--- tests/priv.ml | 1 - 7 files changed, 6 insertions(+), 29 deletions(-) diff --git a/lib/algorithm.ml b/lib/algorithm.ml index 85bb335f..3654cc37 100644 --- a/lib/algorithm.ml +++ b/lib/algorithm.ml @@ -12,10 +12,9 @@ open Asn_grammars *) type ec_curve = - [ `SECP224R1 | `SECP256R1 | `SECP384R1 | `SECP521R1 ] + [ `SECP256R1 | `SECP384R1 | `SECP521R1 ] let ec_curve_to_string = function - | `SECP224R1 -> "SECP224R1" | `SECP256R1 -> "SECP256R1" | `SECP384R1 -> "SECP384R1" | `SECP521R1 -> "SECP521R1" @@ -218,13 +217,11 @@ let curve_of_oid, curve_to_oid = let open Registry.ANSI_X9_62 in (let default oid = Asn.(S.parse_error "Unknown algorithm %a" OID.pp oid) in case_of_oid ~default [ - (secp224r1, `SECP224R1) ; (secp256r1, `SECP256R1) ; (secp384r1, `SECP384R1) ; (secp521r1, `SECP521R1) ; ]), (function - | `SECP224R1 -> secp224r1 | `SECP256R1 -> secp256r1 | `SECP384R1 -> secp384r1 | `SECP521R1 -> secp521r1) diff --git a/lib/key_type.ml b/lib/key_type.ml index 199a4ef6..07f1a509 100644 --- a/lib/key_type.ml +++ b/lib/key_type.ml @@ -1,7 +1,7 @@ -type t = [ `RSA | `ED25519 | `P224 | `P256 | `P384 | `P521 ] +type t = [ `RSA | `ED25519 | `P256 | `P384 | `P521 ] let strings = - [ ("rsa", `RSA) ; ("ed25519", `ED25519) ; ("p224", `P224) ; + [ ("rsa", `RSA) ; ("ed25519", `ED25519) ; ("p256", `P256) ; ("p384", `P384) ; ("p521", `P521) ] let to_string kt = fst (List.find (fun (_, k) -> kt = k) strings) @@ -29,7 +29,7 @@ let supports_signature_scheme key_typ scheme = match key_typ, scheme with | `RSA, (`RSA_PSS | `RSA_PKCS1) -> true | `ED25519, `ED25519 -> true - | (`P224 | `P256 | `P384 | `P521), `ECDSA -> true + | (`P256 | `P384 | `P521), `ECDSA -> true | _ -> false let opt_signature_scheme ?scheme kt = @@ -38,7 +38,7 @@ let opt_signature_scheme ?scheme kt = | None -> match kt with | `RSA -> `RSA_PSS | `ED25519 -> `ED25519 - | `P224 | `P256 | `P384 | `P521 -> `ECDSA + | `P256 | `P384 | `P521 -> `ECDSA (* the default of RSA keys should be PSS, but most deployed certificates still use PKCS1 (and this library uses pkcs1 by default as well) *) diff --git a/lib/private_key.ml b/lib/private_key.ml index 0bfa783b..d296d77c 100644 --- a/lib/private_key.ml +++ b/lib/private_key.ml @@ -1,7 +1,6 @@ let ( let* ) = Result.bind type ecdsa = [ - | `P224 of Mirage_crypto_ec.P224.Dsa.priv | `P256 of Mirage_crypto_ec.P256.Dsa.priv | `P384 of Mirage_crypto_ec.P384.Dsa.priv | `P521 of Mirage_crypto_ec.P521.Dsa.priv @@ -16,7 +15,6 @@ type t = [ let key_type = function | `RSA _ -> `RSA | `ED25519 _ -> `ED25519 - | `P224 _ -> `P224 | `P256 _ -> `P256 | `P384 _ -> `P384 | `P521 _ -> `P521 @@ -29,7 +27,6 @@ let generate ?seed ?(bits = 4096) typ = match typ with | `RSA -> `RSA (Mirage_crypto_pk.Rsa.generate ?g ~bits ()) | `ED25519 -> `ED25519 (fst (Mirage_crypto_ec.Ed25519.generate ?g ())) - | `P224 -> `P224 (fst (Mirage_crypto_ec.P224.Dsa.generate ?g ())) | `P256 -> `P256 (fst (Mirage_crypto_ec.P256.Dsa.generate ?g ())) | `P384 -> `P384 (fst (Mirage_crypto_ec.P384.Dsa.generate ?g ())) | `P521 -> `P521 (fst (Mirage_crypto_ec.P521.Dsa.generate ?g ())) @@ -46,9 +43,6 @@ let of_cstruct data = | `ED25519 -> let* k = ec_err (Ed25519.priv_of_cstruct data) in Ok (`ED25519 k) - | `P224 -> - let* k = ec_err (P224.Dsa.priv_of_cstruct data) in - Ok (`P224 k) | `P256 -> let* k = ec_err (P256.Dsa.priv_of_cstruct data) in Ok (`P256 k) @@ -77,7 +71,6 @@ let of_string ?seed_or_data ?bits typ data = let public = function | `RSA priv -> `RSA (Mirage_crypto_pk.Rsa.pub_of_priv priv) | `ED25519 priv -> `ED25519 (Mirage_crypto_ec.Ed25519.pub_of_priv priv) - | `P224 priv -> `P224 (Mirage_crypto_ec.P224.Dsa.pub_of_priv priv) | `P256 priv -> `P256 (Mirage_crypto_ec.P256.Dsa.pub_of_priv priv) | `P384 priv -> `P384 (Mirage_crypto_ec.P384.Dsa.pub_of_priv priv) | `P521 priv -> `P521 (Mirage_crypto_ec.P521.Dsa.pub_of_priv priv) @@ -106,7 +99,6 @@ let sign hash ?scheme key data = | #ecdsa as key, `ECDSA -> let* d = hashed () in Ok (ecdsa_to_cs (match key with - | `P224 key -> P224.Dsa.(sign ~key (Public_key.trunc byte_length d)) | `P256 key -> P256.Dsa.(sign ~key (Public_key.trunc byte_length d)) | `P384 key -> P384.Dsa.(sign ~key (Public_key.trunc byte_length d)) | `P521 key -> P521.Dsa.(sign ~key (Public_key.trunc byte_length d)))) @@ -197,7 +189,6 @@ module Asn = struct let reparse_ec_private curve priv = let open Mirage_crypto_ec in match curve with - | `SECP224R1 -> let* p = P224.Dsa.priv_of_cstruct priv in Ok (`P224 p) | `SECP256R1 -> let* p = P256.Dsa.priv_of_cstruct priv in Ok (`P256 p) | `SECP384R1 -> let* p = P384.Dsa.priv_of_cstruct priv in Ok (`P384 p) | `SECP521R1 -> let* p = P521.Dsa.priv_of_cstruct priv in Ok (`P521 p) @@ -243,7 +234,6 @@ module Asn = struct match p with | `RSA pk -> RSA, rsa_priv_to_cs pk | `ED25519 pk -> ED25519, ed25519_to_cs (Ed25519.priv_to_cstruct pk) - | `P224 pk -> EC_pub `SECP224R1, ec_to_cs (P224.Dsa.priv_to_cstruct pk) | `P256 pk -> EC_pub `SECP256R1, ec_to_cs (P256.Dsa.priv_to_cstruct pk) | `P384 pk -> EC_pub `SECP384R1, ec_to_cs (P384.Dsa.priv_to_cstruct pk) | `P521 pk -> EC_pub `SECP521R1, ec_to_cs (P521.Dsa.priv_to_cstruct pk) diff --git a/lib/public_key.ml b/lib/public_key.ml index 82344d56..8748c1ab 100644 --- a/lib/public_key.ml +++ b/lib/public_key.ml @@ -1,7 +1,6 @@ let ( let* ) = Result.bind type ecdsa = [ - | `P224 of Mirage_crypto_ec.P224.Dsa.pub | `P256 of Mirage_crypto_ec.P256.Dsa.pub | `P384 of Mirage_crypto_ec.P384.Dsa.pub | `P521 of Mirage_crypto_ec.P521.Dsa.pub @@ -47,7 +46,6 @@ module Asn = struct function | (RSA , cs) -> `RSA (rsa_pub_of_cs cs) | (ED25519 , cs) -> `ED25519 (to_err (Ed25519.pub_of_cstruct cs)) - | (EC_pub `SECP224R1, cs) -> `P224 (to_err (P224.Dsa.pub_of_cstruct cs)) | (EC_pub `SECP256R1, cs) -> `P256 (to_err (P256.Dsa.pub_of_cstruct cs)) | (EC_pub `SECP384R1, cs) -> `P384 (to_err (P384.Dsa.pub_of_cstruct cs)) | (EC_pub `SECP521R1, cs) -> `P521 (to_err (P521.Dsa.pub_of_cstruct cs)) @@ -59,7 +57,6 @@ module Asn = struct function | `RSA pk -> (RSA, rsa_pub_to_cs pk) | `ED25519 pk -> (ED25519, Ed25519.pub_to_cstruct pk) - | `P224 pk -> (EC_pub `SECP224R1, P224.Dsa.pub_to_cstruct pk) | `P256 pk -> (EC_pub `SECP256R1, P256.Dsa.pub_to_cstruct pk) | `P384 pk -> (EC_pub `SECP384R1, P384.Dsa.pub_to_cstruct pk) | `P521 pk -> (EC_pub `SECP521R1, P521.Dsa.pub_to_cstruct pk) @@ -78,7 +75,6 @@ let id k = let data = match k with | `RSA p -> Asn.rsa_public_to_cstruct p | `ED25519 pk -> Mirage_crypto_ec.Ed25519.pub_to_cstruct pk - | `P224 pk -> Mirage_crypto_ec.P224.Dsa.pub_to_cstruct pk | `P256 pk -> Mirage_crypto_ec.P256.Dsa.pub_to_cstruct pk | `P384 pk -> Mirage_crypto_ec.P384.Dsa.pub_to_cstruct pk | `P521 pk -> Mirage_crypto_ec.P521.Dsa.pub_to_cstruct pk @@ -91,7 +87,6 @@ let fingerprint ?(hash = `SHA256) pub = let key_type = function | `RSA _ -> `RSA | `ED25519 _ -> `ED25519 - | `P224 _ -> `P224 | `P256 _ -> `P256 | `P384 _ -> `P384 | `P521 _ -> `P521 @@ -147,7 +142,6 @@ let verify hash ?scheme ~signature key data = let* s = ecdsa_of_cs signature in ok_if_true (match key with - | `P224 key -> P224.Dsa.verify ~key s (trunc P224.Dsa.byte_length d) | `P256 key -> P256.Dsa.verify ~key s (trunc P256.Dsa.byte_length d) | `P384 key -> P384.Dsa.verify ~key s (trunc P384.Dsa.byte_length d) | `P521 key -> P521.Dsa.verify ~key s (trunc P521.Dsa.byte_length d)) diff --git a/lib/signing_request.ml b/lib/signing_request.ml index 09a05d38..7a0de4dd 100644 --- a/lib/signing_request.ml +++ b/lib/signing_request.ml @@ -164,7 +164,6 @@ let encode_pem v = let digest_of_key = function | `RSA _ -> `SHA256 | `ED25519 _ -> `SHA512 - | `P224 _ -> `SHA224 | `P256 _ -> `SHA256 | `P384 _ -> `SHA384 | `P521 _ -> `SHA512 diff --git a/lib/x509.mli b/lib/x509.mli index 3bdeb612..c6971ea2 100644 --- a/lib/x509.mli +++ b/lib/x509.mli @@ -72,7 +72,7 @@ end (** Types of keys *) module Key_type : sig (** The polymorphic variant of key types. *) - type t = [ `RSA | `ED25519 | `P224 | `P256 | `P384 | `P521 ] + type t = [ `RSA | `ED25519 | `P256 | `P384 | `P521 ] val strings : (string * t) list (** [strings] is an associative list of string and key_type pairs. Useful for @@ -112,7 +112,6 @@ module Public_key : sig type t = [ | `RSA of Mirage_crypto_pk.Rsa.pub | `ED25519 of Mirage_crypto_ec.Ed25519.pub - | `P224 of Mirage_crypto_ec.P224.Dsa.pub | `P256 of Mirage_crypto_ec.P256.Dsa.pub | `P384 of Mirage_crypto_ec.P384.Dsa.pub | `P521 of Mirage_crypto_ec.P521.Dsa.pub @@ -177,7 +176,6 @@ module Private_key : sig type t = [ | `RSA of Mirage_crypto_pk.Rsa.priv | `ED25519 of Mirage_crypto_ec.Ed25519.priv - | `P224 of Mirage_crypto_ec.P224.Dsa.priv | `P256 of Mirage_crypto_ec.P256.Dsa.priv | `P384 of Mirage_crypto_ec.P384.Dsa.priv | `P521 of Mirage_crypto_ec.P521.Dsa.priv diff --git a/tests/priv.ml b/tests/priv.ml index 291383a5..a87e5af4 100644 --- a/tests/priv.ml +++ b/tests/priv.ml @@ -30,7 +30,6 @@ let test_ec (key_type, data) () = let ec_data = [ `ED25519, "W0p4c4tBHtSaTj4zij4oARCjhFbIi8voYg+65bl7wLU=" ; - `P224, "Wjy6Nf4/xJSaaR/eeoQBUxJMA3PDP/c+8VkuPA==" ; `P256, "arvDmHpdTdzbc0uo+KCXoArmrmAs2GAvfk14D8gi6gM=" ; `P384, "UEZz/xVx2f3s7W8/cFy/w38LkjAq0xfMYJiXamdwgW9zwSK18+vrhKzgE23sFnyq" ; `P521, "AVb4DIpMO5hzyfX1n4qi4xtj/JBDCTCwyOLasKnnVS6FHW2hEZbGwd1c2J4rwpNKZqTKNsKu3dVJAmlp3EFhqv5T" ; From bcbf02f00c96c34f4305e57ea39cc3df1c9da31b Mon Sep 17 00:00:00 2001 From: Calascibetta Romain Date: Fri, 22 Mar 2024 11:18:08 +0100 Subject: [PATCH 02/17] Remove cstruct from x509 package --- lib/algorithm.ml | 36 ++++---- lib/asn_grammars.ml | 2 +- lib/authenticator.ml | 4 +- lib/certificate.ml | 40 +++++---- lib/crl.ml | 16 ++-- lib/distinguished_name.ml | 6 +- lib/dune | 4 +- lib/extension.ml | 119 +++++++++++++------------- lib/general_name.ml | 4 +- lib/ocsp.ml | 66 ++++++++------- lib/p12.ml | 101 +++++++++++----------- lib/pem.ml | 37 +++++---- lib/private_key.ml | 79 +++++++++--------- lib/public_key.ml | 73 ++++++++-------- lib/rc2.ml | 27 +++--- lib/signing_request.ml | 22 ++--- lib/validation.ml | 29 ++++--- lib/x509.mli | 170 +++++++++++++++++++------------------- tests/crltests.ml | 18 ++-- tests/dune | 2 +- tests/ocsp.ml | 13 ++- tests/pkcs12.ml | 11 ++- tests/priv.ml | 12 +-- tests/regression.ml | 43 +++++----- tests/x509tests.ml | 11 ++- x509.opam | 10 ++- 26 files changed, 505 insertions(+), 450 deletions(-) diff --git a/lib/algorithm.ml b/lib/algorithm.ml index 3654cc37..7b66fb57 100644 --- a/lib/algorithm.ml +++ b/lib/algorithm.ml @@ -64,19 +64,19 @@ type t = | HMAC_SHA512 (* symmetric block ciphers *) - | AES128_CBC of Cstruct.t - | AES192_CBC of Cstruct.t - | AES256_CBC of Cstruct.t + | AES128_CBC of string + | AES192_CBC of string + | AES256_CBC of string (* PBE encryption algorithms *) - | SHA_RC4_128 of Cstruct.t * int - | SHA_RC4_40 of Cstruct.t * int - | SHA_3DES_CBC of Cstruct.t * int - | SHA_2DES_CBC of Cstruct.t * int - | SHA_RC2_128_CBC of Cstruct.t * int - | SHA_RC2_40_CBC of Cstruct.t * int - - | PBKDF2 of Cstruct.t * int * int option * t + | SHA_RC4_128 of string * int + | SHA_RC4_40 of string * int + | SHA_3DES_CBC of string * int + | SHA_2DES_CBC of string * int + | SHA_RC2_128_CBC of string * int + | SHA_RC2_40_CBC of string * int + + | PBKDF2 of string * int * int option * t | PBES2 of t * t let to_string = function @@ -403,24 +403,22 @@ let identifier = (choice4 null oid pbkdf2_or_pbe_or_pbes2_params octet_string))) let ecdsa_sig = - let f (r, s) = + let f (r', s') = + let r = Mirage_crypto_pk.Z_extra.of_octets_be r' in + let s = Mirage_crypto_pk.Z_extra.of_octets_be s' in if Z.sign r < 0 then Asn.S.parse_error "ECDSA signature: r < 0" else if Z.sign s < 0 then Asn.S.parse_error "ECDSA signature: s < 0" - else - Mirage_crypto_pk.Z_extra.to_cstruct_be r, - Mirage_crypto_pk.Z_extra.to_cstruct_be s - and g (r, s) = - Mirage_crypto_pk.Z_extra.of_cstruct_be r, - Mirage_crypto_pk.Z_extra.of_cstruct_be s + else (r', s') + and g (r, s) = (r, s) in map f g @@ sequence2 (required ~label:"r" integer) (required ~label:"s" integer) -let ecdsa_sig_of_cstruct, ecdsa_sig_to_cstruct = +let ecdsa_sig_of_octets, ecdsa_sig_to_octets = projections_of Asn.der ecdsa_sig let pp fmt x = Fmt.string fmt (to_string x) diff --git a/lib/asn_grammars.ml b/lib/asn_grammars.ml index 629d7fe5..3f3ccd73 100644 --- a/lib/asn_grammars.ml +++ b/lib/asn_grammars.ml @@ -5,7 +5,7 @@ let ( let* ) = Result.bind let decode codec cs = let* a, cs = Asn.decode codec cs in - if Cstruct.length cs = 0 then Ok a else Error (`Parse "Leftover") + if String.length cs = 0 then Ok a else Error (`Parse "Leftover") let projections_of encoding asn = let c = Asn.codec encoding asn in (decode c, Asn.encode c) diff --git a/lib/authenticator.ml b/lib/authenticator.ml index 771d4544..5044b397 100644 --- a/lib/authenticator.ml +++ b/lib/authenticator.ml @@ -37,7 +37,7 @@ let fingerprint_of_string s = `Msg (Fmt.str "Invalid base64 encoding in fingerprint (%s): %S" m s)) (Base64.decode ~pad:false s) in - Ok (Cstruct.of_string d) + Ok d let format = {| @@ -73,7 +73,7 @@ let of_string str = List.fold_left (fun acc s -> let* acc = acc in let* der = Base64.decode ~pad:false s in - let* cert = Certificate.decode_der (Cstruct.of_string der) in + let* cert = Certificate.decode_der der in Ok (cert :: acc)) (Ok []) certs in diff --git a/lib/certificate.ml b/lib/certificate.ml index f988fc6b..b55915b0 100644 --- a/lib/certificate.ml +++ b/lib/certificate.ml @@ -9,20 +9,20 @@ type tBSCertificate = { validity : Ptime.t * Ptime.t ; subject : Distinguished_name.t ; pk_info : Public_key.t ; - issuer_id : Cstruct.t option ; - subject_id : Cstruct.t option ; + issuer_id : string option ; + subject_id : string option ; extensions : Extension.t } type certificate = { tbs_cert : tBSCertificate ; signature_algo : Algorithm.t ; - signature_val : Cstruct.t + signature_val : string } (* - * There are two reasons to carry Cstruct.t around: - * - we still need to hack on the cstruct to get bytes to hash + * There are two reasons to carry octets around: + * - we still need to hack on the octets to get bytes to hash * ( this needs to go ) * - we need a cs to send to the peer * It's a bit ugly to have two levels, and both are better solved by extending @@ -31,7 +31,7 @@ type certificate = { *) type t = { asn : certificate ; - raw : Cstruct.t + raw : string } module Asn = struct @@ -43,7 +43,11 @@ module Asn = struct (function `V3 -> 2 | `V2 -> 1 | `V1 -> 0) int - let certificate_sn = integer + let certificate_sn = + map + Mirage_crypto_pk.Z_extra.of_octets_be + Mirage_crypto_pk.Z_extra.to_octets_be + integer let time = let f = function `C1 t -> t | `C2 t -> t @@ -57,7 +61,7 @@ module Asn = struct (required ~label:"not before" time) (required ~label:"not after" time) - let unique_identifier = bit_string_cs + let unique_identifier = bit_string_octets let tBSCertificate = let f = fun (a, (b, (c, (d, (e, (f, (g, (h, (i, j))))))))) -> @@ -94,7 +98,7 @@ module Asn = struct (* v3 if present *) -@ (optional ~label:"extensions" @@ explicit 3 Extension.Asn.extensions_der) - let (tbs_certificate_of_cstruct, tbs_certificate_to_cstruct) = + let (tbs_certificate_of_octets, tbs_certificate_to_octets) = projections_of Asn.der tBSCertificate let certificate = @@ -108,9 +112,9 @@ module Asn = struct sequence3 (required ~label:"tbsCertificate" tBSCertificate) (required ~label:"signatureAlgorithm" Algorithm.identifier) - (required ~label:"signatureValue" bit_string_cs) + (required ~label:"signatureValue" bit_string_octets) - let (certificate_of_cstruct, certificate_to_cstruct) = + let (certificate_of_octets, certificate_to_octets) = projections_of Asn.der certificate let pkcs1_digest_info = @@ -126,19 +130,19 @@ module Asn = struct (required ~label:"digestAlgorithm" Algorithm.identifier) (required ~label:"digest" octet_string) - let (pkcs1_digest_info_of_cstruct, pkcs1_digest_info_to_cstruct) = + let (pkcs1_digest_info_of_octets, pkcs1_digest_info_to_octets) = projections_of Asn.der pkcs1_digest_info end let decode_pkcs1_digest_info cs = - Asn_grammars.err_to_msg (Asn.pkcs1_digest_info_of_cstruct cs) + Asn_grammars.err_to_msg (Asn.pkcs1_digest_info_of_octets cs) -let encode_pkcs1_digest_info = Asn.pkcs1_digest_info_to_cstruct +let encode_pkcs1_digest_info = Asn.pkcs1_digest_info_to_octets let ( let* ) = Result.bind let decode_der cs = - let* asn = Asn_grammars.err_to_msg (Asn.certificate_of_cstruct cs) in + let* asn = Asn_grammars.err_to_msg (Asn.certificate_of_octets cs) in Ok { asn ; raw = cs } let encode_der { raw ; _ } = raw @@ -158,7 +162,7 @@ let encode_pem v = Pem.unparse ~tag:"CERTIFICATE" (encode_der v) let encode_pem_multiple cs = - Cstruct.concat (List.map encode_pem cs) + String.concat "" (List.map encode_pem cs) let pp_version ppf v = Fmt.string ppf (match v with `V1 -> "1" | `V2 -> "2" | `V3 -> "3") @@ -183,7 +187,9 @@ let pp ppf { asn ; _ } = Distinguished_name.pp tbs.subject Extension.pp tbs.extensions -let fingerprint hash cert = Mirage_crypto.Hash.digest hash cert.raw +let fingerprint hash cert = + let module Hash = (val (Digestif.module_of_hash' hash)) in + Hash.(to_raw_string (digest_string cert.raw)) let issuer { asn ; _ } = asn.tbs_cert.issuer diff --git a/lib/crl.ml b/lib/crl.ml index 4af3381f..584fada3 100644 --- a/lib/crl.ml +++ b/lib/crl.ml @@ -17,7 +17,7 @@ type tBS_CRL = { type crl = { tbs_crl : tBS_CRL ; signature_algo : Algorithm.t ; - signature_val : Cstruct.t + signature_val : string } module Asn = struct @@ -81,17 +81,17 @@ module Asn = struct sequence3 (required ~label:"tbsCertList" @@ tBSCertList) (required ~label:"signatureAlgorithm" @@ Algorithm.identifier) - (required ~label:"signatureValue" @@ bit_string_cs) + (required ~label:"signatureValue" @@ bit_string_octets) - let (crl_of_cstruct, crl_to_cstruct) = + let (crl_of_octets, crl_to_octets) = projections_of Asn.der certificateList - let (tbs_CRL_of_cstruct, tbs_CRL_to_cstruct) = + let (tbs_CRL_of_octets, tbs_CRL_to_octets) = projections_of Asn.der tBSCertList end type t = { - raw : Cstruct.t ; + raw : string ; asn : crl ; } @@ -100,7 +100,7 @@ let guard p e = if p then Ok () else Error e let ( let* ) = Result.bind let decode_der raw = - let* asn = Asn_grammars.err_to_msg (Asn.crl_of_cstruct raw) in + let* asn = Asn_grammars.err_to_msg (Asn.crl_of_octets raw) in Ok { raw ; asn } let encode_der { raw ; _ } = raw @@ -202,14 +202,14 @@ let is_revoked ?allowed_hashes ~issuer:super ~cert (crls : t list) = crls let sign_tbs (tbs : tBS_CRL) key = - let tbs_raw = Asn.tbs_CRL_to_cstruct tbs in + let tbs_raw = Asn.tbs_CRL_to_octets tbs in match Algorithm.to_signature_algorithm tbs.signature with | None -> Error (`Msg "couldn't parse signature algorithm") | Some (_, hash) -> let scheme = Key_type.x509_default_scheme (Private_key.key_type key) in let* signature_val = Private_key.sign hash ~scheme key (`Message tbs_raw) in let asn = { tbs_crl = tbs ; signature_algo = tbs.signature ; signature_val } in - let raw = Asn.crl_to_cstruct asn in + let raw = Asn.crl_to_octets asn in Ok { asn ; raw } let revoke diff --git a/lib/distinguished_name.ml b/lib/distinguished_name.ml index 33ab6ac9..ff337ee8 100644 --- a/lib/distinguished_name.ml +++ b/lib/distinguished_name.ml @@ -246,10 +246,10 @@ module Asn = struct in sequence_of rd_name (* A vacuous choice, in the standard. *) - let (name_of_cstruct, name_to_cstruct) = + let (name_of_octets, name_to_octets) = projections_of Asn.der name end -let decode_der cs = Asn_grammars.err_to_msg (Asn.name_of_cstruct cs) +let decode_der cs = Asn_grammars.err_to_msg (Asn.name_of_octets cs) -let encode_der = Asn.name_to_cstruct +let encode_der = Asn.name_to_octets diff --git a/lib/dune b/lib/dune index ff30d09e..9381c03e 100644 --- a/lib/dune +++ b/lib/dune @@ -5,6 +5,6 @@ public_key private_key crl distinguished_name algorithm extension pem signing_request general_name host rc2 p12 key_type) - (libraries asn1-combinators fmt ptime cstruct mirage-crypto mirage-crypto-pk + (libraries asn1-combinators fmt ptime mirage-crypto mirage-crypto-pk gmap domain-name base64 logs mirage-crypto-ec pbkdf - mirage-crypto-rng ipaddr)) + mirage-crypto-rng ipaddr ohex)) diff --git a/lib/extension.ml b/lib/extension.ml index bc14a31b..e7af11a5 100644 --- a/lib/extension.ml +++ b/lib/extension.ml @@ -51,11 +51,11 @@ let pp_extended_key_usage ppf = function | `Ocsp_signing -> Fmt.string ppf "ocsp signing" | `Other oid -> Asn.OID.pp ppf oid -type authority_key_id = Cstruct.t option * General_name.t * Z.t option +type authority_key_id = string option * General_name.t * Z.t option let pp_authority_key_id ppf (id, issuer, serial) = Fmt.pf ppf "identifier %a@ issuer %a@ serial %s@ " - Fmt.(option ~none:(any "none") Cstruct.hexdump_pp) id + Fmt.(option ~none:(any "none") Ohex.pp) id General_name.pp issuer (match serial with None -> "none" | Some x -> Z.to_string x) @@ -172,10 +172,10 @@ let pp_issuing_distribution_point ppf (name, onlyuser, onlyca, onlysome, indirec type 'a extension = bool * 'a type _ k = - | Unsupported : Asn.oid -> Cstruct.t extension k + | Unsupported : Asn.oid -> string extension k | Subject_alt_name : General_name.t extension k | Authority_key_id : authority_key_id extension k - | Subject_key_id : Cstruct.t extension k + | Subject_key_id : string extension k | Issuer_alt_name : General_name.t extension k | Key_usage : key_usage list extension k | Ext_key_usage : extended_key_usage list extension k @@ -203,7 +203,7 @@ let pp_one : type a. a k -> Format.formatter -> a -> unit = fun k ppf v -> pp_authority_key_id kid | Subject_key_id, (crit, kid) -> Fmt.pf ppf "%ssubjectKeyIdentifier %a" (c_to_str crit) - Cstruct.hexdump_pp kid + Ohex.pp kid | Issuer_alt_name, (crit, alt) -> Fmt.pf ppf "%sissuerAlternativeNames %a" (c_to_str crit) General_name.pp alt @@ -244,9 +244,9 @@ let pp_one : type a. a k -> Format.formatter -> a -> unit = fun k ppf v -> | Policies, (crit, pols) -> Fmt.pf ppf "%spolicies %a" (c_to_str crit) Fmt.(list ~sep:(any "; ") pp_policy) pols - | Unsupported oid, (crit, cs) -> + | Unsupported oid, (crit, str) -> Fmt.pf ppf "%sunsupported %a: %a" (c_to_str crit) Asn.OID.pp oid - Cstruct.hexdump_pp cs + Ohex.pp str module ID = Registry.Cert_extn @@ -352,7 +352,6 @@ let ips exts = | Some xs -> let ips = List.fold_left (fun acc ip -> - let ip = Cstruct.to_string ip in match match String.length ip with | 4 -> Result.map (fun ip -> Ipaddr.V4 ip) (Ipaddr.V4.of_octets ip) @@ -427,8 +426,8 @@ module Asn = struct (optional ~label:"pathLen" int) let authority_key_id = - map (fun (a, b, c) -> (a, def General_name.empty b, c)) - (fun (a, b, c) -> (a, def' General_name.empty b, c)) + map (fun (a, b, c) -> (a, def General_name.empty b, Option.map Mirage_crypto_pk.Z_extra.of_octets_be c)) + (fun (a, b, c) -> (a, def' General_name.empty b, Option.map Mirage_crypto_pk.Z_extra.to_octets_be c)) @@ sequence3 (optional ~label:"keyIdentifier" @@ implicit 0 octet_string) @@ -563,83 +562,83 @@ module Asn = struct let rev = List.map (fun (k, v) -> (v, k)) alist in enumerated (fun i -> List.assoc i alist) (fun k -> List.assoc k rev) - let gen_names_of_cs, gen_names_to_cs = project_exn General_name.Asn.gen_names - and auth_key_id_of_cs, auth_key_id_to_cs = project_exn authority_key_id - and subj_key_id_of_cs, subj_key_id_to_cs = project_exn octet_string - and key_usage_of_cs, key_usage_to_cs = project_exn key_usage - and e_key_usage_of_cs, e_key_usage_to_cs = project_exn ext_key_usage - and basic_constr_of_cs, basic_constr_to_cs = project_exn basic_constraints - and pr_key_peri_of_cs, pr_key_peri_to_cs = project_exn priv_key_usage_period - and name_con_of_cs, name_con_to_cs = project_exn name_constraints - and crl_distrib_of_cs, crl_distrib_to_cs = project_exn crl_distribution_points - and cert_pol_of_cs, cert_pol_to_cs = project_exn cert_policies - and int_of_cs, int_to_cs = project_exn int - and issuing_dp_of_cs, issuing_dp_to_cs = project_exn issuing_distribution_point - and crl_reason_of_cs, crl_reason_to_cs = project_exn crl_reason - and time_of_cs, time_to_cs = project_exn generalized_time_no_frac_s + let gen_names_of_str, gen_names_to_str = project_exn General_name.Asn.gen_names + and auth_key_id_of_str, auth_key_id_to_str = project_exn authority_key_id + and subj_key_id_of_str, subj_key_id_to_str = project_exn octet_string + and key_usage_of_str, key_usage_to_str = project_exn key_usage + and e_key_usage_of_str, e_key_usage_to_str = project_exn ext_key_usage + and basic_constr_of_str, basic_constr_to_str = project_exn basic_constraints + and pr_key_peri_of_str, pr_key_peri_to_str = project_exn priv_key_usage_period + and name_con_of_str, name_con_to_str = project_exn name_constraints + and crl_distrib_of_str, crl_distrib_to_str = project_exn crl_distribution_points + and cert_pol_of_str, cert_pol_to_str = project_exn cert_policies + and int_of_str, int_to_str = project_exn int + and issuing_dp_of_str, issuing_dp_to_str = project_exn issuing_distribution_point + and crl_reason_of_str, crl_reason_to_str = project_exn crl_reason + and time_of_str, time_to_str = project_exn generalized_time_no_frac_s (* XXX 4.2.1.4. - cert policies! ( and other x509 extensions ) *) let reparse_extension_exn crit = case_of_oid_f [ (ID.subject_alternative_name, - fun cs -> B (Subject_alt_name, (crit, gen_names_of_cs cs))) ; + fun cs -> B (Subject_alt_name, (crit, gen_names_of_str cs))) ; (ID.issuer_alternative_name, - fun cs -> B (Issuer_alt_name, (crit, gen_names_of_cs cs))) ; + fun cs -> B (Issuer_alt_name, (crit, gen_names_of_str cs))) ; (ID.authority_key_identifier, - fun cs -> B (Authority_key_id, (crit, auth_key_id_of_cs cs))) ; + fun cs -> B (Authority_key_id, (crit, auth_key_id_of_str cs))) ; (ID.subject_key_identifier, - fun cs -> B (Subject_key_id, (crit, subj_key_id_of_cs cs))) ; + fun cs -> B (Subject_key_id, (crit, subj_key_id_of_str cs))) ; (ID.key_usage, - fun cs -> B (Key_usage, (crit, key_usage_of_cs cs))) ; + fun cs -> B (Key_usage, (crit, key_usage_of_str cs))) ; (ID.basic_constraints, - fun cs -> B (Basic_constraints, (crit, basic_constr_of_cs cs))) ; + fun cs -> B (Basic_constraints, (crit, basic_constr_of_str cs))) ; (ID.crl_number, - fun cs -> B (CRL_number, (crit, int_of_cs cs))) ; + fun cs -> B (CRL_number, (crit, int_of_str cs))) ; (ID.delta_crl_indicator, - fun cs -> B (Delta_CRL_indicator, (crit, int_of_cs cs))) ; + fun cs -> B (Delta_CRL_indicator, (crit, int_of_str cs))) ; (ID.extended_key_usage, - fun cs -> B (Ext_key_usage, (crit, e_key_usage_of_cs cs))) ; + fun cs -> B (Ext_key_usage, (crit, e_key_usage_of_str cs))) ; (ID.private_key_usage_period, - fun cs -> B (Priv_key_period, (crit, pr_key_peri_of_cs cs))) ; + fun cs -> B (Priv_key_period, (crit, pr_key_peri_of_str cs))) ; (ID.name_constraints, - fun cs -> B (Name_constraints, (crit, name_con_of_cs cs))) ; + fun cs -> B (Name_constraints, (crit, name_con_of_str cs))) ; (ID.crl_distribution_points, - fun cs -> B (CRL_distribution_points, (crit, crl_distrib_of_cs cs))) ; + fun cs -> B (CRL_distribution_points, (crit, crl_distrib_of_str cs))) ; (ID.issuing_distribution_point, - fun cs -> B (Issuing_distribution_point, (crit, issuing_dp_of_cs cs))) ; + fun cs -> B (Issuing_distribution_point, (crit, issuing_dp_of_str cs))) ; (ID.freshest_crl, - fun cs -> B (Freshest_CRL, (crit, crl_distrib_of_cs cs))) ; + fun cs -> B (Freshest_CRL, (crit, crl_distrib_of_str cs))) ; (ID.reason_code, - fun cs -> B (Reason, (crit, crl_reason_of_cs cs))) ; + fun cs -> B (Reason, (crit, crl_reason_of_str cs))) ; (ID.invalidity_date, - fun cs -> B (Invalidity_date, (crit, time_of_cs cs))) ; + fun cs -> B (Invalidity_date, (crit, time_of_str cs))) ; (ID.certificate_issuer, - fun cs -> B (Certificate_issuer, (crit, gen_names_of_cs cs))) ; + fun cs -> B (Certificate_issuer, (crit, gen_names_of_str cs))) ; (ID.certificate_policies_2, - fun cs -> B (Policies, (crit, cert_pol_of_cs cs))) + fun cs -> B (Policies, (crit, cert_pol_of_str cs))) ] ~default:(fun oid -> fun cs -> B (Unsupported oid, (crit, cs))) let unparse_extension (B (k, v)) = let v' = match k, v with - | Subject_alt_name, (_, x) -> gen_names_to_cs x - | Issuer_alt_name, (_, x) -> gen_names_to_cs x - | Authority_key_id, (_, x) -> auth_key_id_to_cs x - | Subject_key_id, (_, x) -> subj_key_id_to_cs x - | Key_usage, (_, x) -> key_usage_to_cs x - | Basic_constraints, (_, x) -> basic_constr_to_cs x - | CRL_number, (_, x) -> int_to_cs x - | Delta_CRL_indicator, (_, x) -> int_to_cs x - | Ext_key_usage, (_, x) -> e_key_usage_to_cs x - | Priv_key_period, (_, x) -> pr_key_peri_to_cs x - | Name_constraints, (_, x) -> name_con_to_cs x - | CRL_distribution_points, (_, x) -> crl_distrib_to_cs x - | Issuing_distribution_point, (_, x) -> issuing_dp_to_cs x - | Freshest_CRL, (_, x) -> crl_distrib_to_cs x - | Reason, (_, x) -> crl_reason_to_cs x - | Invalidity_date, (_, x) -> time_to_cs x - | Certificate_issuer, (_, x) -> gen_names_to_cs x - | Policies, (_, x) -> cert_pol_to_cs x + | Subject_alt_name, (_, x) -> gen_names_to_str x + | Issuer_alt_name, (_, x) -> gen_names_to_str x + | Authority_key_id, (_, x) -> auth_key_id_to_str x + | Subject_key_id, (_, x) -> subj_key_id_to_str x + | Key_usage, (_, x) -> key_usage_to_str x + | Basic_constraints, (_, x) -> basic_constr_to_str x + | CRL_number, (_, x) -> int_to_str x + | Delta_CRL_indicator, (_, x) -> int_to_str x + | Ext_key_usage, (_, x) -> e_key_usage_to_str x + | Priv_key_period, (_, x) -> pr_key_peri_to_str x + | Name_constraints, (_, x) -> name_con_to_str x + | CRL_distribution_points, (_, x) -> crl_distrib_to_str x + | Issuing_distribution_point, (_, x) -> issuing_dp_to_str x + | Freshest_CRL, (_, x) -> crl_distrib_to_str x + | Reason, (_, x) -> crl_reason_to_str x + | Invalidity_date, (_, x) -> time_to_str x + | Certificate_issuer, (_, x) -> gen_names_to_str x + | Policies, (_, x) -> cert_pol_to_str x | Unsupported _, (_, x) -> x in to_oid k, critical k v, v' diff --git a/lib/general_name.ml b/lib/general_name.ml index 7049584e..a2841a35 100644 --- a/lib/general_name.ml +++ b/lib/general_name.ml @@ -6,7 +6,7 @@ type _ k = | Directory : Distinguished_name.t list k | EDI_party : (string option * string) list k | URI : string list k - | IP : Cstruct.t list k + | IP : string list k | Registered_id : Asn.oid list k module K = struct @@ -47,7 +47,7 @@ let pp_k : type a. a k -> Format.formatter -> a -> unit = fun k ppf v -> (pair ~sep:(any ", ") (option ~none:(any "") string) string)) xs | URI, x -> Fmt.pf ppf "uri %a" pp_strs x - | IP, x -> Fmt.pf ppf "ip %a" Fmt.(list ~sep:(any ";") Cstruct.hexdump_pp) x + | IP, x -> Fmt.pf ppf "ip %a" Fmt.(list ~sep:(any ";") (fmt "%S")) x | Registered_id, x -> Fmt.pf ppf "registered id %a" Fmt.(list ~sep:(any ";") Asn.OID.pp) x diff --git a/lib/ocsp.ml b/lib/ocsp.ml index 3ebd133b..2fd3e27f 100644 --- a/lib/ocsp.ml +++ b/lib/ocsp.ml @@ -11,17 +11,18 @@ let version_v1 = 0 *) type cert_id = { hashAlgorithm: Algorithm.t; - issuerNameHash: Cstruct.t; - issuerKeyHash: Cstruct.t; + issuerNameHash: string; + issuerKeyHash: string; serialNumber: Z.t; } let create_cert_id ?(hash=`SHA1) issuer serialNumber = let hashAlgorithm = Algorithm.of_hash hash in + let module Hash = (val (Digestif.module_of_hash' (hash :> Digestif.hash'))) in let issuerNameHash = Certificate.subject issuer |> Distinguished_name.encode_der - |> Mirage_crypto.Hash.digest hash + |> Hash.(fun x -> to_raw_string (digest_string x)) in let issuerKeyHash = Public_key.fingerprint ~hash (Certificate.public_key issuer) @@ -33,8 +34,8 @@ let cert_id_serial {serialNumber;_} = serialNumber let pp_cert_id ppf {hashAlgorithm;issuerNameHash;issuerKeyHash;serialNumber} = Fmt.pf ppf "CertID @[<1>{@ algo=%a;@ issuerNameHash=%a;@ issuerKeyHash=%a;@ serialNumber=%a@ }@]" Algorithm.pp hashAlgorithm - Cstruct.hexdump_pp issuerNameHash - Cstruct.hexdump_pp issuerKeyHash + Ohex.pp issuerNameHash + Ohex.pp issuerKeyHash Z.pp_print serialNumber module Asn_common = struct @@ -45,10 +46,11 @@ module Asn_common = struct {hashAlgorithm; issuerNameHash; issuerKeyHash; - serialNumber;} + serialNumber= Mirage_crypto_pk.Z_extra.of_octets_be serialNumber;} in let g {hashAlgorithm;issuerNameHash;issuerKeyHash;serialNumber;} = - (hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber) + (hashAlgorithm, issuerNameHash, issuerKeyHash, + Mirage_crypto_pk.Z_extra.to_octets_be serialNumber) in map f g @@ sequence4 @@ -116,14 +118,14 @@ module Request = struct *) type signature = { signatureAlgorithm: Algorithm.t; - signature: Cstruct.t; + signature: string; certs: Certificate.t list option; } let pp_signature ppf {signatureAlgorithm;signature;certs;} = Fmt.pf ppf "Signature @[<1>{@ signatureAlgorithm=%a;@ signature=%a;@ certs=%a}@]" Algorithm.pp signatureAlgorithm - Cstruct.hexdump_pp signature + Ohex.pp signature (Fmt.option ~none:(Fmt.any "None") @@ Fmt.brackets @@ Fmt.list ~sep:Fmt.semi Certificate.pp) certs @@ -139,7 +141,7 @@ module Request = struct } type t = { - raw : Cstruct.t ; + raw : string ; asn : req ; } @@ -193,7 +195,7 @@ module Request = struct (required ~label:"requestList" @@ sequence_of request) (optional ~label:"requestExtensions" @@ Extension.Asn.extensions_der) - let tbs_request_of_cs,tbs_request_to_cs = + let tbs_request_of_str,tbs_request_to_str = projections_of Asn.der tbs_request let signature = @@ -202,7 +204,7 @@ module Request = struct | None -> None | Some certs -> let encode cert = - let raw = Certificate.Asn.certificate_to_cstruct cert in + let raw = Certificate.Asn.certificate_to_octets cert in Certificate.{raw; asn=cert} in Some (List.map encode certs) @@ -220,7 +222,7 @@ module Request = struct map f g @@ sequence3 (required ~label:"signatureAlgorithm" Algorithm.identifier) - (required ~label:"signature" bit_string_cs) + (required ~label:"signature" bit_string_octets) (optional ~label:"certs" @@ explicit 0 @@ sequence_of Certificate.Asn.certificate) @@ -236,13 +238,13 @@ module Request = struct (required ~label:"tbsRequest" tbs_request) (optional ~label:"optionalSignature" signature) - let (ocsp_request_of_cstruct, ocsp_request_to_cstruct) = + let (ocsp_request_of_octets, ocsp_request_to_octets) = projections_of Asn.der ocsp_request end let decode_der raw = - let* asn = Asn.ocsp_request_of_cstruct raw in + let* asn = Asn.ocsp_request_of_octets raw in Ok { asn ; raw } let encode_der { raw ; _ } = raw @@ -262,12 +264,12 @@ module Request = struct let digest = Signing_request.default_digest digest key in let scheme = Key_type.x509_default_scheme (Private_key.key_type key) in let signatureAlgorithm = Algorithm.of_signature_algorithm scheme digest in - let tbs_der = Asn.tbs_request_to_cs tbsRequest in + let tbs_der = Asn.tbs_request_to_str tbsRequest in let* signature = Private_key.sign digest ~scheme key (`Message tbs_der) in Ok (Some { signature ; signatureAlgorithm ; certs; }) in let asn = { tbsRequest ; optionalSignature } in - let raw = Asn.ocsp_request_to_cstruct asn in + let raw = Asn.ocsp_request_to_octets asn in Ok { raw ; asn } let validate { asn ; raw } ?(allowed_hashes = Validation.sha2) pub = @@ -396,7 +398,7 @@ module Response = struct *) type responder_id = [ | `ByName of Distinguished_name.t - | `ByKey of Cstruct.t + | `ByKey of string ] let create_responder_id pubkey = @@ -405,7 +407,7 @@ module Response = struct let pp_responder_id ppf = function | `ByName dn -> Fmt.pf ppf "ByName %a" Distinguished_name.pp dn - | `ByKey hash -> Fmt.pf ppf "ByKey %a" Cstruct.hexdump_pp hash + | `ByKey hash -> Fmt.pf ppf "ByKey %a" Ohex.pp hash (* ResponseData ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, @@ -435,7 +437,7 @@ module Response = struct type basic_ocsp_response = { tbsResponseData: response_data; signatureAlgorithm: Algorithm.t; - signature: Cstruct.t; + signature: string; certs: Certificate.t list option; } @@ -443,7 +445,7 @@ module Response = struct Fmt.pf ppf "BasicOCSPResponse @[<1>{@ tbsResponseData=%a;@ signatureAlgorithm=%a;@ signature=%a;@ certs=%a@ }@]" pp_response_data tbsResponseData Algorithm.pp signatureAlgorithm - Cstruct.hexdump_pp signature + Ohex.pp signature (Fmt.option ~none:(Fmt.any "None") @@ Fmt.list ~sep:Fmt.semi @@ Certificate.pp) certs @@ -457,7 +459,7 @@ module Response = struct type t = { responseStatus: status; - responseBytes: (Asn.oid * basic_ocsp_response * Cstruct.t) option; + responseBytes: (Asn.oid * basic_ocsp_response * string) option; } let pp ppf {responseStatus;responseBytes;} = @@ -558,7 +560,7 @@ module Response = struct (optional ~label:"responseExtensions" @@ explicit 1 @@ Extension.Asn.extensions_der) - let response_data_of_cs, response_data_to_cs = + let response_data_of_str, response_data_to_str = projections_of Asn.der response_data let basic_ocsp_response = @@ -567,7 +569,7 @@ module Response = struct | None -> None | Some certs -> let encode cert = - let raw = Certificate.Asn.certificate_to_cstruct cert in + let raw = Certificate.Asn.certificate_to_octets cert in Certificate.{raw; asn=cert} in Some (List.map encode certs) @@ -586,11 +588,11 @@ module Response = struct sequence4 (required ~label:"tbsResponseData" response_data) (required ~label:"signatureAlgorithm" Algorithm.identifier) - (required ~label:"signature" bit_string_cs) + (required ~label:"signature" bit_string_octets) (optional ~label:"certs" @@ explicit 0 @@ sequence_of Certificate.Asn.certificate) - let basic_ocsp_response_of_cs,basic_ocsp_response_to_cs = + let basic_ocsp_response_of_str,basic_ocsp_response_to_str = projections_of Asn.der basic_ocsp_response let ocsp_basic_oid = Cert_extn.Private_internet_extensions.ad_ocsp_basic @@ -601,7 +603,7 @@ module Response = struct parse_error "Successful status requires responseBytes" | `Successful, Some (oid, response) -> if Asn.OID.equal ocsp_basic_oid oid then - match basic_ocsp_response_of_cs response with + match basic_ocsp_response_of_str response with | Error e -> error e | Ok basic_response -> {responseStatus=`Successful; @@ -631,13 +633,13 @@ module Response = struct (required ~label:"responseType" oid) (required ~label:"response" octet_string)) - let ocsp_response_of_cs, ocsp_response_to_cs = + let ocsp_response_of_str, ocsp_response_to_str = projections_of Asn.der ocsp_response end - let decode_der = Asn.ocsp_response_of_cs - let encode_der = Asn.ocsp_response_to_cs + let decode_der = Asn.ocsp_response_of_str + let encode_der = Asn.ocsp_response_to_str let create_basic_ocsp_response ?digest ?certs ?response_extensions:responseExtensions key responderID producedAt @@ -651,7 +653,7 @@ module Response = struct responses; responseExtensions; } in - let resp_der = Asn.response_data_to_cs tbsResponseData in + let resp_der = Asn.response_data_to_str tbsResponseData in let* signature = Private_key.sign digest ~scheme key (`Message resp_der) in Ok { tbsResponseData ; signatureAlgorithm ; signature;certs } @@ -662,7 +664,7 @@ module Response = struct ?digest ?certs ?response_extensions private_key responderID producedAt responses in - let raw_resp = Asn.basic_ocsp_response_to_cs response in + let raw_resp = Asn.basic_ocsp_response_to_str response in let responseBytes = Some (Asn.ocsp_basic_oid, response, raw_resp) in Ok { responseStatus = `Successful ; responseBytes } diff --git a/lib/p12.ml b/lib/p12.ml index 7cdd1a5c..6bd1d5ad 100644 --- a/lib/p12.ml +++ b/lib/p12.ml @@ -6,13 +6,13 @@ some definitions from PKCS7 (RFC 2315) are implemented as well, as needed *) -type content_info = Asn.oid * Cstruct.t +type content_info = Asn.oid * string -type digest_info = Algorithm.t * Cstruct.t +type digest_info = Algorithm.t * string -type mac_data = digest_info * Cstruct.t * int +type mac_data = digest_info * string * int -type t = Cstruct.t * mac_data +type t = string * mac_data module Asn = struct open Asn_grammars @@ -189,106 +189,108 @@ end let prepare_pw str = let l = String.length str in - let cs = Cstruct.create ((succ l) * 2) in + let cs = Bytes.make ((succ l) * 2) '\000' in for i = 0 to pred l do - Cstruct.set_char cs (succ (i * 2)) (String.get str i) + Bytes.set cs (succ (i * 2)) (String.get str i) done; - cs + Bytes.unsafe_to_string cs let id len purpose = - let b = Cstruct.create len in let id = match purpose with | `Encryption -> 1 | `Iv -> 2 | `Hmac -> 3 in - Cstruct.memset b id; - b + String.make len (Char.unsafe_chr id) let v = function | `MD5 | `SHA1 | `SHA224 | `SHA256 -> 512 / 8 | `SHA384 | `SHA512 -> 1024 / 8 let fill ~data ~out = - let len = Cstruct.length out - and l = Cstruct.length data + let len = Bytes.length out + and l = String.length data in let rec c off = if off < len then begin - Cstruct.blit data 0 out off (min (len - off) l); + Bytes.blit_string data 0 out off (min (len - off) l); c (off + l) end in c 0 let fill_or_empty size data = - let l = Cstruct.length data in + let l = String.length data in if l = 0 then data else let len = size * ((l + size - 1) / size) in - let buf = Cstruct.create len in + let buf = Bytes.make len '\000' in fill ~data ~out:buf; - buf + Bytes.unsafe_to_string buf let pbes algorithm purpose password salt iterations n = + let module Hash = (val (Digestif.module_of_hash' (algorithm :> Digestif.hash'))) in let pw = prepare_pw password and v = v algorithm - and u = Mirage_crypto.Hash.digest_size algorithm + and u = Hash.digest_size in let diversifier = id v purpose in let salt = fill_or_empty v salt in let pass = fill_or_empty v pw in - let out = Cstruct.create n in + let out = Bytes.make n '\000' in let rec one off i = - let ai = ref (Mirage_crypto.Hash.digest algorithm (Cstruct.append diversifier i)) in + let ai = ref Hash.(to_raw_string (digest_string (diversifier ^ i))) in for _j = 1 to pred iterations do - ai := Mirage_crypto.Hash.digest algorithm !ai; + ai := Hash.(to_raw_string (digest_string !ai)); done; - Cstruct.blit !ai 0 out off (min (n - off) u); + Bytes.blit_string !ai 0 out off (min (n - off) u); if u >= n - off then () else (* 6B *) - let b = Cstruct.create v in + let b = Bytes.make v '\000' in fill ~data:!ai ~out:b; (* 6C *) - let i' = Cstruct.create (Cstruct.length i) in - for j = 0 to pred (Cstruct.length i / v) do + let i' = Bytes.create (String.length i) in + for j = 0 to pred (String.length i / v) do let c = ref 1 in for k = pred v downto 0 do let idx = j * v + k in - c := (!c + Cstruct.get_uint8 i idx + Cstruct.get_uint8 b k) land 0xFFFF; - Cstruct.set_uint8 i' idx (!c land 0xFF); + c := (!c + String.get_uint8 i idx + Bytes.get_uint8 b k) land 0xFFFF; + Bytes.set_uint8 i' idx (!c land 0xFF); c := !c lsr 8; done; done; - one (off + u) i' + one (off + u) (Bytes.to_string i') in - let i = Cstruct.append salt pass in + let i = salt ^ pass in one 0 i; - out + Bytes.unsafe_to_string out + +let split str off = + String.sub str 0 off, + String.sub str off (String.length str - off) (* TODO PKCS5/7 padding is "k - (l mod k)" i.e. always > 0! (and rc4 being a stream cipher has no padding!) *) let unpad x = (* TODO can there be bad padding in this scheme? *) - let l = Cstruct.length x in + let l = String.length x in if l > 0 then - let amount = Cstruct.get_uint8 x (pred l) in + let amount = String.get_uint8 x (pred l) in let split_point = if l > amount then l - amount else l in - let data, pad = Cstruct.split x split_point in + let data, pad = split x split_point in let good = ref true in for i = 0 to pred amount do - if Cstruct.get_uint8 pad i <> amount then good := false + if String.get_uint8 pad i <> amount then good := false done; if !good then data else x else x let pad bs x = - let l = Cstruct.length x in + let l = String.length x in let to_pad = bs - (l mod bs) in - let amount = Cstruct.create to_pad in - Cstruct.memset amount to_pad; - Cstruct.append x amount + let amount = String.make to_pad (Char.unsafe_chr to_pad) in + x ^ amount let ( let* ) = Result.bind @@ -349,13 +351,13 @@ let pkcs5_2_decrypt kdf enc password data = Ok (salt, iterations, prf) | _ -> Error (`Msg "expected kdf being pbkdf2") in - let password = Cstruct.of_string password in let key = Pbkdf.pbkdf2 ~prf ~password ~salt ~count ~dk_len in let key = Mirage_crypto.Cipher_block.AES.CBC.of_secret key in let msg = Mirage_crypto.Cipher_block.AES.CBC.decrypt ~key ~iv data in Ok (unpad msg) let pkcs5_2_encrypt (mac : [ `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ]) count algo password data = + let module Hash = (val (Digestif.module_of_hash' (mac :> Digestif.hash'))) in let bs = Mirage_crypto.Cipher_block.AES.CBC.block_size in let iv = Mirage_crypto_rng.generate bs in let enc, dk_len = @@ -364,9 +366,8 @@ let pkcs5_2_encrypt (mac : [ `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ]) co | `AES192_CBC -> Algorithm.AES192_CBC iv, 24l | `AES256_CBC -> Algorithm.AES256_CBC iv, 32l in - let password = Cstruct.of_string password in - let salt = Mirage_crypto_rng.generate (Mirage_crypto.Hash.digest_size mac) in - let key = Pbkdf.pbkdf2 ~prf:(mac :> Mirage_crypto.Hash.hash) ~password ~salt ~count ~dk_len in + let salt = Mirage_crypto_rng.generate Hash.digest_size in + let key = Pbkdf.pbkdf2 ~prf:(mac :> Digestif.hash') ~password ~salt ~count ~dk_len in let key = Mirage_crypto.Cipher_block.AES.CBC.of_secret key in let padded_data = pad bs data in let enc_data = @@ -395,11 +396,12 @@ let verify password (data, ((algorithm, digest), salt, iterations)) = ~none:(`Msg "unsupported hash algorithm") (Algorithm.to_hash algorithm) in + let module Hash = (val (Digestif.module_of_hash' (hash :> Digestif.hash'))) in let key = - pbes hash `Hmac password salt iterations (Mirage_crypto.Hash.digest_size hash) + pbes hash `Hmac password salt iterations Hash.digest_size in - let computed = Mirage_crypto.Hash.mac hash ~key data in - if Cstruct.equal computed digest then begin + let computed = Hash.(to_raw_string (hmac_string ~key data)) in + if String.equal computed digest then begin let* content = Asn_grammars.err_to_msg (Asn.auth_safe_of_cs data) in let* safe_contents = List.fold_left (fun acc c -> @@ -423,7 +425,7 @@ let verify password (data, ((algorithm, digest), salt, iterations)) = | `Encrypted_private_key (algo, enc_data), _ -> let* data = decrypt algo password enc_data in let* p = - Asn_grammars.err_to_msg (Private_key.Asn.private_of_cstruct data) + Asn_grammars.err_to_msg (Private_key.Asn.private_of_octets data) in Ok (`Decrypted_private_key p :: acc)) (Ok acc) bags) @@ -436,7 +438,7 @@ let create ?(mac = `SHA256) ?(algorithm = `AES256_CBC) ?(iterations = 2048) pass let priv_fp = key_fp (Private_key.public private_key) in let attributes = [ Registry.PKCS9.local_key_id, [ priv_fp ]] in let maybe_attr c = - if Cstruct.equal priv_fp (key_fp (Certificate.public_key c)) then + if String.equal priv_fp (key_fp (Certificate.public_key c)) then Some attributes else None @@ -444,7 +446,7 @@ let create ?(mac = `SHA256) ?(algorithm = `AES256_CBC) ?(iterations = 2048) pass let cert_sc = Asn.safe_contents_to_cs (List.map (fun c -> `Certificate c, maybe_attr c) certificates) and priv_sc = - let data = Private_key.Asn.private_to_cstruct private_key in + let data = Private_key.Asn.private_to_octets private_key in let algo, data = pkcs5_2_encrypt mac iterations algorithm password data in Asn.safe_contents_to_cs [ `Encrypted_private_key (algo, data), Some attributes ] in @@ -455,10 +457,11 @@ let create ?(mac = `SHA256) ?(algorithm = `AES256_CBC) ?(iterations = 2048) pass let auth_data = Asn.auth_safe_to_cs [ `Encrypted cert_sc_enc ; `Data priv_sc ] in - let mac_size = Mirage_crypto.Hash.digest_size mac in + let module Hash = (val (Digestif.module_of_hash' (mac :> Digestif.hash'))) in + let mac_size = Hash.digest_size in let salt = Mirage_crypto_rng.generate mac_size in let key = pbes mac `Hmac password salt iterations mac_size in - let digest = Mirage_crypto.Hash.mac mac ~key auth_data in + let digest = Hash.(to_raw_string (hmac_string ~key auth_data)) in auth_data, ((Algorithm.of_hash mac, digest), salt, iterations) let decode_der cs = Asn_grammars.err_to_msg (Asn.pfx_of_cs cs) diff --git a/lib/pem.ml b/lib/pem.ml index f28450ac..d6fedbd7 100644 --- a/lib/pem.ml +++ b/lib/pem.ml @@ -1,7 +1,13 @@ let ( let* ) = Result.bind module Cs = struct - open Cstruct + open String + + let split str off = + String.sub str 0 off, + String.sub str off (String.length str - off) + + let shift str off = snd (split str off) let begins_with cs target = let l1 = length cs and l2 = length target in @@ -13,19 +19,19 @@ module Cs = struct let null cs = length cs = 0 - let open_begin = of_string "-----BEGIN " - and open_end = of_string "-----END " - and close = of_string "-----" + let open_begin = "-----BEGIN " + and open_end = "-----END " + and close = "-----" let tok_of_line cs = if null cs then `Empty - else if get_char cs 0 = '#' then + else if get cs 0 = '#' then `Empty else if begins_with cs open_begin && ends_with cs close then - `Begin (to_string @@ sub cs 11 (length cs - 16)) + `Begin (sub cs 11 (length cs - 16)) else if begins_with cs open_end && ends_with cs close then - `End (to_string @@ sub cs 9 (length cs - 14)) + `End (sub cs 9 (length cs - 14)) else `Data cs @@ -34,8 +40,8 @@ module Cs = struct let rec lines cs = let rec eol i = - match get_char cs i with - | '\r' when get_char cs (i + 1) = '\n' -> chop cs i 2 + match get cs i with + | '\r' when get cs (i + 1) = '\n' -> chop cs i 2 | '\n' -> chop cs i 1 | _ -> eol (i + 1) in match eol 0 with @@ -48,7 +54,7 @@ module Cs = struct | `Data cs :: tail -> accumulate t (cs :: acc) tail | `End t' :: tail -> if String.equal t t' then - Ok (concat (List.rev acc), tail) + Ok (concat "" (List.rev acc), tail) else Error (`Msg ("invalid end, expected " ^ t ^ ", found " ^ t')) | _ :: _ -> Error (`Msg "invalid line, expected data or end") @@ -58,8 +64,8 @@ module Cs = struct let rec block acc = function | `Begin t :: tail -> let* body, tail = accumulate t [] tail in - let* data = Base64.decode (Cstruct.to_string body) in - block ((t, Cstruct.of_string data) :: acc) tail + let* data = Base64.decode body in + block ((t, data) :: acc) tail | _::xs -> block acc xs | [] -> Ok (List.rev acc) in @@ -73,17 +79,16 @@ module Cs = struct | x -> let here, rest = split x 64 in split_at_64 (here :: acc) rest in - let raw = Cstruct.of_string (Base64.encode_string (Cstruct.to_string value)) in + let raw = Base64.encode_string value in let pieces = split_at_64 [] raw in - let nl = of_string "\n" in + let nl = "\n" in let lines = List.flatten (List.map (fun x -> [ x ; nl ]) pieces) in - let tag = of_string tag in let first = [ open_begin ; tag ; close ; nl ] and last = [ open_end ; tag ; close ; nl ] in - concat (first @ lines @ last) + concat "" (first @ lines @ last) end let parse, unparse = Cs.(parse, unparse) diff --git a/lib/private_key.ml b/lib/private_key.ml index d296d77c..9bb9e104 100644 --- a/lib/private_key.ml +++ b/lib/private_key.ml @@ -31,7 +31,7 @@ let generate ?seed ?(bits = 4096) typ = | `P384 -> `P384 (fst (Mirage_crypto_ec.P384.Dsa.generate ?g ())) | `P521 -> `P521 (fst (Mirage_crypto_ec.P521.Dsa.generate ?g ())) -let of_cstruct data = +let of_octets data = let open Mirage_crypto_ec in let ec_err e = Result.map_error @@ -41,32 +41,32 @@ let of_cstruct data = function | `RSA -> Error (`Msg "cannot decode an RSA key") | `ED25519 -> - let* k = ec_err (Ed25519.priv_of_cstruct data) in + let* k = ec_err (Ed25519.priv_of_octets data) in Ok (`ED25519 k) | `P256 -> - let* k = ec_err (P256.Dsa.priv_of_cstruct data) in + let* k = ec_err (P256.Dsa.priv_of_octets data) in Ok (`P256 k) | `P384 -> - let* k = ec_err (P384.Dsa.priv_of_cstruct data) in + let* k = ec_err (P384.Dsa.priv_of_octets data) in Ok (`P384 k) | `P521 -> - let* k = ec_err (P521.Dsa.priv_of_cstruct data) in + let* k = ec_err (P521.Dsa.priv_of_octets data) in Ok (`P521 k) let of_string ?seed_or_data ?bits typ data = match seed_or_data with | None -> begin match typ with - | `RSA -> Ok (generate ~seed:(Cstruct.of_string data) ?bits `RSA) + | `RSA -> Ok (generate ~seed:data ?bits `RSA) | _ -> let* data = Base64.decode data in - of_cstruct (Cstruct.of_string data) typ + of_octets data typ end | Some `Seed -> - Ok (generate ~seed:(Cstruct.of_string data) ?bits typ) + Ok (generate ~seed:data ?bits typ) | Some `Data -> let* data = Base64.decode data in - of_cstruct (Cstruct.of_string data) typ + of_octets data typ let public = function | `RSA priv -> `RSA (Mirage_crypto_pk.Rsa.pub_of_priv priv) @@ -78,13 +78,13 @@ let public = function let sign hash ?scheme key data = let open Mirage_crypto_ec in let hashed () = Public_key.hashed hash data - and ecdsa_to_cs s = Algorithm.ecdsa_sig_to_cstruct s + and ecdsa_to_str s = Algorithm.ecdsa_sig_to_octets s in let scheme = Key_type.opt_signature_scheme ?scheme (key_type key) in try match key, scheme with | `RSA key, `RSA_PSS -> - let module H = (val (Mirage_crypto.Hash.module_of hash)) in + let module H = (val (Digestif.module_of_hash' hash)) in let module PSS = Mirage_crypto_pk.Rsa.PSS(H) in let* d = hashed () in Ok (PSS.sign ~key (`Digest d)) @@ -98,7 +98,7 @@ let sign hash ?scheme key data = end | #ecdsa as key, `ECDSA -> let* d = hashed () in - Ok (ecdsa_to_cs (match key with + Ok (ecdsa_to_str (match key with | `P256 key -> P256.Dsa.(sign ~key (Public_key.trunc byte_length d)) | `P384 key -> P384.Dsa.(sign ~key (Public_key.trunc byte_length d)) | `P521 key -> P521.Dsa.(sign ~key (Public_key.trunc byte_length d)))) @@ -121,6 +121,7 @@ module Asn = struct (required ~label:"coefficient" integer)) let rsa_private_key = + let integer = map Z_extra.of_octets_be Z_extra.to_octets_be integer in let f (v, (n, (e, (d, (p, (q, (dp, (dq, (q', other))))))))) = match (v, other) with | (0, None) -> @@ -145,18 +146,18 @@ module Asn = struct -@ (optional ~label:"otherPrimeInfos" other_prime_infos) (* For outside uses. *) - let (rsa_private_of_cstruct, rsa_private_to_cstruct) = + let (rsa_private_of_octets, rsa_private_to_octets) = Asn_grammars.projections_of Asn.der rsa_private_key (* PKCS8 *) - let (rsa_priv_of_cs, rsa_priv_to_cs) = + let (rsa_priv_of_str, rsa_priv_to_str) = Asn_grammars.project_exn rsa_private_key let ec_to_err = function | Ok x -> x | Error e -> parse_error "%a" Mirage_crypto_ec.pp_error e - let ed25519_of_cs, ed25519_to_cs = + let ed25519_of_str, ed25519_to_str = Asn_grammars.project_exn octet_string let ec_private_key = @@ -183,18 +184,18 @@ module Asn = struct (optional ~label:"namedCurve" (explicit 0 oid)) (optional ~label:"publicKey" (explicit 1 bit_string)) - let ec_of_cs, ec_to_cs = + let ec_of_str, ec_to_str = Asn_grammars.project_exn ec_private_key let reparse_ec_private curve priv = let open Mirage_crypto_ec in match curve with - | `SECP256R1 -> let* p = P256.Dsa.priv_of_cstruct priv in Ok (`P256 p) - | `SECP384R1 -> let* p = P384.Dsa.priv_of_cstruct priv in Ok (`P384 p) - | `SECP521R1 -> let* p = P521.Dsa.priv_of_cstruct priv in Ok (`P521 p) + | `SECP256R1 -> let* p = P256.Dsa.priv_of_octets priv in Ok (`P256 p) + | `SECP384R1 -> let* p = P384.Dsa.priv_of_octets priv in Ok (`P384 p) + | `SECP521R1 -> let* p = P521.Dsa.priv_of_octets priv in Ok (`P521 p) (* external use (result) *) - let ec_priv_of_cs = + let ec_priv_of_str = let dec, _ = Asn_grammars.projections_of Asn.der ec_private_key in fun cs -> let* priv, curve, _pub = dec cs in @@ -205,8 +206,8 @@ module Asn = struct (fun e -> `Parse (Fmt.to_to_string Mirage_crypto_ec.pp_error e)) (reparse_ec_private c priv) - let ec_of_cs ?curve cs = - let (priv, named_curve, _pub) = ec_of_cs cs in + let ec_of_str ?curve cs = + let (priv, named_curve, _pub) = ec_of_str cs in let nc = match curve, named_curve with | Some c, None -> c @@ -216,15 +217,15 @@ module Asn = struct in ec_to_err (reparse_ec_private nc priv) - let ec_to_cs ?curve ?pub key = ec_to_cs (key, curve, pub) + let ec_to_str ?curve ?pub key = ec_to_str (key, curve, pub) let reparse_private pk = match pk with - | (0, Algorithm.RSA, cs) -> `RSA (rsa_priv_of_cs cs) + | (0, Algorithm.RSA, cs) -> `RSA (rsa_priv_of_str cs) | (0, Algorithm.ED25519, cs) -> - let data = ed25519_of_cs cs in - `ED25519 (ec_to_err (Mirage_crypto_ec.Ed25519.priv_of_cstruct data)) - | (0, Algorithm.EC_pub curve, cs) -> ec_of_cs ~curve cs + let data = ed25519_of_str cs in + `ED25519 (ec_to_err (Mirage_crypto_ec.Ed25519.priv_of_octets data)) + | (0, Algorithm.EC_pub curve, cs) -> ec_of_str ~curve cs | _ -> parse_error "unknown private key info" let unparse_private p = @@ -232,11 +233,11 @@ module Asn = struct let open Algorithm in let alg, cs = match p with - | `RSA pk -> RSA, rsa_priv_to_cs pk - | `ED25519 pk -> ED25519, ed25519_to_cs (Ed25519.priv_to_cstruct pk) - | `P256 pk -> EC_pub `SECP256R1, ec_to_cs (P256.Dsa.priv_to_cstruct pk) - | `P384 pk -> EC_pub `SECP384R1, ec_to_cs (P384.Dsa.priv_to_cstruct pk) - | `P521 pk -> EC_pub `SECP521R1, ec_to_cs (P521.Dsa.priv_to_cstruct pk) + | `RSA pk -> RSA, rsa_priv_to_str pk + | `ED25519 pk -> ED25519, ed25519_to_str (Ed25519.priv_to_octets pk) + | `P256 pk -> EC_pub `SECP256R1, ec_to_str (P256.Dsa.priv_to_octets pk) + | `P384 pk -> EC_pub `SECP384R1, ec_to_str (P384.Dsa.priv_to_octets pk) + | `P521 pk -> EC_pub `SECP521R1, ec_to_str (P521.Dsa.priv_to_octets pk) in (0, alg, cs) @@ -250,14 +251,14 @@ module Asn = struct (optional ~label:"attributes" @@ implicit 0 (SET of Attributes) which are defined in X.501; but nobody seems to use them anyways *) - let (private_of_cstruct, private_to_cstruct) = + let (private_of_octets, private_to_octets) = Asn_grammars.projections_of Asn.der private_key_info end let decode_der cs = - Asn_grammars.err_to_msg (Asn.private_of_cstruct cs) + Asn_grammars.err_to_msg (Asn.private_of_octets cs) -let encode_der = Asn.private_to_cstruct +let encode_der = Asn.private_to_octets let decode_pem cs = let* data = Pem.parse cs in @@ -271,18 +272,18 @@ let decode_pem cs = in let* k = Pem.foldM (fun (_, k) -> - let* k = Asn_grammars.err_to_msg (Asn.rsa_private_of_cstruct k) in + let* k = Asn_grammars.err_to_msg (Asn.rsa_private_of_octets k) in Ok (`RSA k)) r in let* k' = Pem.foldM (fun (_, k) -> - Asn_grammars.err_to_msg (Asn.ec_priv_of_cs k)) ec + Asn_grammars.err_to_msg (Asn.ec_priv_of_str k)) ec in let* k'' = Pem.foldM (fun (_, k) -> - Asn_grammars.err_to_msg (Asn.private_of_cstruct k)) p + Asn_grammars.err_to_msg (Asn.private_of_octets k)) p in Pem.exactly_one ~what:"private key" (k @ k' @ k'') let encode_pem p = - Pem.unparse ~tag:"PRIVATE KEY" (Asn.private_to_cstruct p) + Pem.unparse ~tag:"PRIVATE KEY" (Asn.private_to_octets p) diff --git a/lib/public_key.ml b/lib/public_key.ml index 8748c1ab..080cd853 100644 --- a/lib/public_key.ml +++ b/lib/public_key.ml @@ -20,19 +20,22 @@ module Asn = struct open Mirage_crypto_pk let rsa_public_key = - let f (n, e) = match Rsa.pub ~e ~n with + let f (n, e) = + let n = Z_extra.of_octets_be n + and e = Z_extra.of_octets_be e in + match Rsa.pub ~e ~n with | Ok p -> p | Error (`Msg m) -> parse_error "bad RSA public key %s" m - and g ({ Rsa.n; e } : Rsa.pub) = (n, e) in + and g ({ Rsa.n; e } : Rsa.pub) = (Z_extra.to_octets_be n, Z_extra.to_octets_be e) in map f g @@ sequence2 (required ~label:"modulus" integer) (required ~label:"publicExponent" integer) - let (rsa_public_of_cstruct, rsa_public_to_cstruct) = + let (rsa_public_of_octets, rsa_public_to_octets) = projections_of Asn.der rsa_public_key - let rsa_pub_of_cs, rsa_pub_to_cs = project_exn rsa_public_key + let rsa_pub_of_octets, rsa_pub_to_octets = project_exn rsa_public_key let to_err = function | Ok r -> r @@ -44,45 +47,46 @@ module Asn = struct let open Mirage_crypto_ec in let open Algorithm in function - | (RSA , cs) -> `RSA (rsa_pub_of_cs cs) - | (ED25519 , cs) -> `ED25519 (to_err (Ed25519.pub_of_cstruct cs)) - | (EC_pub `SECP256R1, cs) -> `P256 (to_err (P256.Dsa.pub_of_cstruct cs)) - | (EC_pub `SECP384R1, cs) -> `P384 (to_err (P384.Dsa.pub_of_cstruct cs)) - | (EC_pub `SECP521R1, cs) -> `P521 (to_err (P521.Dsa.pub_of_cstruct cs)) + | (RSA , cs) -> `RSA (rsa_pub_of_octets cs) + | (ED25519 , cs) -> `ED25519 (to_err (Ed25519.pub_of_octets cs)) + | (EC_pub `SECP256R1, cs) -> `P256 (to_err (P256.Dsa.pub_of_octets cs)) + | (EC_pub `SECP384R1, cs) -> `P384 (to_err (P384.Dsa.pub_of_octets cs)) + | (EC_pub `SECP521R1, cs) -> `P521 (to_err (P521.Dsa.pub_of_octets cs)) | _ -> parse_error "unknown public key algorithm" let unparse_pk = let open Mirage_crypto_ec in let open Algorithm in function - | `RSA pk -> (RSA, rsa_pub_to_cs pk) - | `ED25519 pk -> (ED25519, Ed25519.pub_to_cstruct pk) - | `P256 pk -> (EC_pub `SECP256R1, P256.Dsa.pub_to_cstruct pk) - | `P384 pk -> (EC_pub `SECP384R1, P384.Dsa.pub_to_cstruct pk) - | `P521 pk -> (EC_pub `SECP521R1, P521.Dsa.pub_to_cstruct pk) + | `RSA pk -> (RSA, rsa_pub_to_octets pk) + | `ED25519 pk -> (ED25519, Ed25519.pub_to_octets pk) + | `P256 pk -> (EC_pub `SECP256R1, P256.Dsa.pub_to_octets pk) + | `P384 pk -> (EC_pub `SECP384R1, P384.Dsa.pub_to_octets pk) + | `P521 pk -> (EC_pub `SECP521R1, P521.Dsa.pub_to_octets pk) let pk_info_der = map reparse_pk unparse_pk @@ sequence2 (required ~label:"algorithm" Algorithm.identifier) - (required ~label:"subjectPK" bit_string_cs) + (required ~label:"subjectPK" bit_string_octets) - let (pub_info_of_cstruct, pub_info_to_cstruct) = + let (pub_info_of_octets, pub_info_to_octets) = projections_of Asn.der pk_info_der end let id k = let data = match k with - | `RSA p -> Asn.rsa_public_to_cstruct p - | `ED25519 pk -> Mirage_crypto_ec.Ed25519.pub_to_cstruct pk - | `P256 pk -> Mirage_crypto_ec.P256.Dsa.pub_to_cstruct pk - | `P384 pk -> Mirage_crypto_ec.P384.Dsa.pub_to_cstruct pk - | `P521 pk -> Mirage_crypto_ec.P521.Dsa.pub_to_cstruct pk + | `RSA p -> Asn.rsa_public_to_octets p + | `ED25519 pk -> Mirage_crypto_ec.Ed25519.pub_to_octets pk + | `P256 pk -> Mirage_crypto_ec.P256.Dsa.pub_to_octets pk + | `P384 pk -> Mirage_crypto_ec.P384.Dsa.pub_to_octets pk + | `P521 pk -> Mirage_crypto_ec.P521.Dsa.pub_to_octets pk in - Mirage_crypto.Hash.digest `SHA1 data + Digestif.(to_raw_string SHA1 (digest_string SHA1 data)) let fingerprint ?(hash = `SHA256) pub = - Mirage_crypto.Hash.digest hash (Asn.pub_info_to_cstruct pub) + let module Hash = (val (Digestif.module_of_hash' (hash :> Digestif.hash'))) in + Hash.(to_raw_string (digest_string (Asn.pub_info_to_octets pub))) let key_type = function | `RSA _ -> `RSA @@ -99,32 +103,33 @@ let sig_alg = function let pp ppf k = Fmt.string ppf (Key_type.to_string (key_type k)); Fmt.sp ppf (); - Cstruct.hexdump_pp ppf (fingerprint k) + Ohex.pp ppf (fingerprint k) let hashed hash data = + let module Hash = (val (Digestif.module_of_hash' hash)) in match data with - | `Message msg -> Ok (Mirage_crypto.Hash.digest hash msg) + | `Message msg -> Ok Hash.(to_raw_string (digest_string msg)) | `Digest d -> - let n = Cstruct.length d and m = Mirage_crypto.Hash.digest_size hash in + let n = String.length d and m = Hash.digest_size in if n = m then Ok d else Error (`Msg "digested data of invalid size") let trunc len data = - if Cstruct.length data > len then - Cstruct.sub data 0 len + if String.length data > len then + String.sub data 0 len else data let verify hash ?scheme ~signature key data = let open Mirage_crypto_ec in let ok_if_true p = if p then Ok () else Error (`Msg "bad signature") in - let ecdsa_of_cs cs = + let ecdsa_of_str cs = Result.map_error (function `Parse s -> `Msg s) - (Algorithm.ecdsa_sig_of_cstruct cs) + (Algorithm.ecdsa_sig_of_octets cs) in let scheme = Key_type.opt_signature_scheme ?scheme (key_type key) in match key, scheme with | `RSA key, `RSA_PSS -> - let module H = (val (Mirage_crypto.Hash.module_of hash)) in + let module H = (val (Digestif.module_of_hash' hash)) in let module PSS = Mirage_crypto_pk.Rsa.PSS(H) in let* d = hashed hash data in ok_if_true (PSS.verify ~key ~signature (`Digest d)) @@ -139,7 +144,7 @@ let verify hash ?scheme ~signature key data = end | #ecdsa as key, `ECDSA -> let* d = hashed hash data in - let* s = ecdsa_of_cs signature in + let* s = ecdsa_of_str signature in ok_if_true (match key with | `P256 key -> P256.Dsa.verify ~key s (trunc P256.Dsa.byte_length d) @@ -147,9 +152,9 @@ let verify hash ?scheme ~signature key data = | `P521 key -> P521.Dsa.verify ~key s (trunc P521.Dsa.byte_length d)) | _ -> Error (`Msg "invalid key and signature scheme combination") -let encode_der = Asn.pub_info_to_cstruct +let encode_der = Asn.pub_info_to_octets -let decode_der cs = Asn_grammars.err_to_msg (Asn.pub_info_of_cstruct cs) +let decode_der cs = Asn_grammars.err_to_msg (Asn.pub_info_of_octets cs) let decode_pem cs = let* data = Pem.parse cs in diff --git a/lib/rc2.ml b/lib/rc2.ml index 33a670a1..274f71b0 100644 --- a/lib/rc2.ml +++ b/lib/rc2.ml @@ -33,8 +33,8 @@ let tm effective = (* L[i] is the i-th byte of the key; K[i] is the i-th 16-bit-word of the key *) let key_expansion effective key = (* result is a 128 byte key, where we need the words.. *) - let t = Cstruct.length key in - let l = Array.init 128 (fun idx -> if idx < t then Cstruct.get_uint8 key idx else 0) in + let t = String.length key in + let l = Array.init 128 (fun idx -> if idx < t then String.get_uint8 key idx else 0) in let t8, tm = tm effective in for i = t to 127 do l.(i) <- pitable.((l.(i - 1) + l.(i - t)) mod 256) @@ -137,7 +137,7 @@ let r_mash_round r k = r_mash r 0 k let decrypt_one ~key ~data ?(off = 0) dst = - let r = Array.init 4 (fun idx -> Cstruct.LE.get_uint16 data (off + idx * 2)) in + let r = Array.init 4 (fun idx -> String.get_uint16_le data (off + idx * 2)) in let j = 63 in let j = r_mix_round r key j in let j = r_mix_round r key j in @@ -157,19 +157,22 @@ let decrypt_one ~key ~data ?(off = 0) dst = let j = r_mix_round r key j in let j = r_mix_round r key j in let _j = r_mix_round r key j in - Cstruct.LE.set_uint16 dst (off + 0) r.(0); - Cstruct.LE.set_uint16 dst (off + 2) r.(1); - Cstruct.LE.set_uint16 dst (off + 4) r.(2); - Cstruct.LE.set_uint16 dst (off + 6) r.(3) + Bytes.set_uint16_le dst (off + 0) r.(0); + Bytes.set_uint16_le dst (off + 2) r.(1); + Bytes.set_uint16_le dst (off + 4) r.(2); + Bytes.set_uint16_le dst (off + 6) r.(3) + +let shift buf off = + Bytes.sub buf off (Bytes.length buf - off) let decrypt_cbc ?(effective = 128) ~key ~iv data = let block = 8 in let key = key_expansion effective key in - let l = Cstruct.length data in - let dst = Cstruct.create l in + let l = String.length data in + let dst = Bytes.create l in for i = 0 to pred ((l + pred block) / block) do decrypt_one ~key ~data ~off:(i * block) dst done; - Mirage_crypto.Uncommon.Cs.xor_into iv dst block; - Mirage_crypto.Uncommon.Cs.xor_into data (Cstruct.shift dst block) (l - block); - dst + Mirage_crypto.Uncommon.xor_into iv dst block; + Mirage_crypto.Uncommon.xor_into data (shift dst block) (l - block); + Bytes.unsafe_to_string dst diff --git a/lib/signing_request.ml b/lib/signing_request.ml index 7a0de4dd..d4b42050 100644 --- a/lib/signing_request.ml +++ b/lib/signing_request.ml @@ -38,12 +38,12 @@ type request_info = { type request = { info : request_info ; signature_algorithm : Algorithm.t ; - signature : Cstruct.t + signature : string } type t = { asn : request ; - raw : Cstruct.t ; + raw : string ; } module Asn = struct @@ -93,7 +93,7 @@ module Asn = struct (required ~label:"subjectPKInfo" Public_key.Asn.pk_info_der) (required ~label:"attributes" @@ implicit 0 (set_of attributes)) - let request_info_of_cs, request_info_to_cs = + let request_info_of_str, request_info_to_str = projections_of Asn.der request_info let signing_request = @@ -106,9 +106,9 @@ module Asn = struct sequence3 (required ~label:"certificationRequestInfo" request_info) (required ~label:"signatureAlgorithm" Algorithm.identifier) - (required ~label:"signature" bit_string_cs) + (required ~label:"signature" bit_string_octets) - let signing_request_of_cs, signing_request_to_cs = + let signing_request_of_str, signing_request_to_str = projections_of Asn.der signing_request end @@ -139,7 +139,7 @@ let validate_signature allowed_hashes { asn ; raw } = asn.signature_algorithm asn.signature asn.info.public_key let decode_der ?(allowed_hashes = Validation.sha2) cs = - let* csr = Asn_grammars.err_to_msg (Asn.signing_request_of_cs cs) in + let* csr = Asn_grammars.err_to_msg (Asn.signing_request_of_str cs) in let csr = { raw = cs ; asn = csr } in let* () = Result.map_error @@ -175,12 +175,12 @@ let create subject ?digest ?(extensions = Ext.empty) (key : Private_key.t) = let hash = default_digest digest key in let public_key = Private_key.public key in let info : request_info = { subject ; public_key ; extensions } in - let info_cs = Asn.request_info_to_cs info in + let info_str = Asn.request_info_to_str info in let scheme = Key_type.x509_default_scheme (Private_key.key_type key) in - let* signature = Private_key.sign hash ~scheme key (`Message info_cs) in + let* signature = Private_key.sign hash ~scheme key (`Message info_str) in let signature_algorithm = Algorithm.of_signature_algorithm scheme hash in let asn = { info ; signature_algorithm ; signature } in - let raw = Asn.signing_request_to_cs asn in + let raw = Asn.signing_request_to_str asn in Ok { asn ; raw } let sign signing_request @@ -210,7 +210,7 @@ let sign signing_request subject_id = None ; extensions } in - let tbs_raw = Certificate.Asn.tbs_certificate_to_cstruct tbs_cert in + let tbs_raw = Certificate.Asn.tbs_certificate_to_octets tbs_cert in let scheme = Key_type.x509_default_scheme (Private_key.key_type key) in let* signature_val = Private_key.sign hash ~scheme key (`Message tbs_raw) in let asn = { @@ -218,5 +218,5 @@ let sign signing_request signature_algo ; signature_val ; } in - let raw = Certificate.Asn.certificate_to_cstruct asn in + let raw = Certificate.Asn.certificate_to_octets asn in Ok { Certificate.asn ; raw } diff --git a/lib/validation.ml b/lib/validation.ml index ec00f7cc..3cb3cc4b 100644 --- a/lib/validation.ml +++ b/lib/validation.ml @@ -8,8 +8,8 @@ module Log = (val Logs.src_log src : Logs.LOG) type signature_error = [ | `Bad_signature of Distinguished_name.t * string - | `Bad_encoding of Distinguished_name.t * string * Cstruct.t - | `Hash_not_allowed of Distinguished_name.t * Mirage_crypto.Hash.hash + | `Bad_encoding of Distinguished_name.t * string * string + | `Hash_not_allowed of Distinguished_name.t * [ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ] | `Unsupported_keytype of Distinguished_name.t * Public_key.t | `Unsupported_algorithm of Distinguished_name.t * string | `Msg of string @@ -21,7 +21,7 @@ let pp_signature_error ppf = function Distinguished_name.pp subj msg | `Bad_encoding (subj, err, sig_) -> Fmt.pf ppf "bad signature encoding of %a, ASN error %s:@.%a" - Distinguished_name.pp subj err Cstruct.hexdump_pp sig_ + Distinguished_name.pp subj err Ohex.pp sig_ | `Hash_not_allowed (subj, hash) -> Fmt.pf ppf "hash algorithm %a is not allowed, but %a is signed using it" Certificate.pp_hash hash Distinguished_name.pp subj @@ -68,21 +68,24 @@ let validate_raw_signature subject allowed_hashes msg sig_alg signature pk = | None -> Error (`Unsupported_algorithm (subject, Algorithm.to_string sig_alg)) +let shift str off = + String.sub str off (String.length str - off) + (* XXX should return the tbs_cert blob from the parser, this is insane *) let raw_cert_hack raw = (* we only support definite-length *) let loff = 1 in - let snd = Cstruct.get_uint8 raw loff in + let snd = String.get_uint8 raw loff in let lenl = 2 + if 0x80 land snd = 0 then 0 else 0x7F land snd in (* cut away the SEQUENCE and LENGTH from outer sequence (tbs, sigalg, sig) *) - let cert_buf = Cstruct.shift raw lenl in + let cert_buf = shift raw lenl in let rec l acc idx last = if idx = last then acc else - l (acc lsl 8 + Cstruct.get_uint8 cert_buf idx) (succ idx) last + l (acc lsl 8 + String.get_uint8 cert_buf idx) (succ idx) last in - let cert_len_byte = Cstruct.get_uint8 cert_buf loff in + let cert_len_byte = String.get_uint8 cert_buf loff in let cert_len = (* two cases: *) if 0x80 land cert_len_byte = 0 then @@ -94,7 +97,7 @@ let raw_cert_hack raw = let len_len = 2 + 0x7F land cert_len_byte in len_len + (l 0 2 len_len) in - Cstruct.sub cert_buf 0 cert_len + String.sub cert_buf 0 cert_len let validate_signature allowed_hashes { Certificate.asn = trusted ; _ } { Certificate.asn ; raw } = let tbs_raw = raw_cert_hack raw in @@ -201,7 +204,7 @@ let ext_authority_matches_subject trusted cert = find Subject_key_id (Certificate.extensions trusted)) with | (_, None) | (None, _) -> true (* not mandatory *) - | Some (_, (Some auth, _, _)), Some (_, au) -> Cstruct.equal auth au + | Some (_, (Some auth, _, _)), Some (_, au) -> String.equal auth au (* TODO: check exact rules in RFC5280 *) | Some (_, (None, _, _)), _ -> true (* not mandatory *) @@ -257,7 +260,7 @@ let pp_leaf_validation_error ppf = function Fmt.pf ppf "leaf certificate %a expired (now %a)" Certificate.pp c Fmt.(option ~none:(any "no timestamp provided") pp_pt) now | `LeafInvalidIP (c, ip) -> - Fmt.pf ppf "leaf certificate %a does not contain the IP %a (IPs present: %a)" + Fmt.pf ppf "leaf certificate %a does not contain the IP %a (IPs present: %a)String" Certificate.pp c Fmt.(option ~none:(any "none") Ipaddr.pp) ip Fmt.(list ~sep:(any ", ") Ipaddr.pp) (Certificate.ips c |> Ipaddr.Set.elements) | `LeafInvalidName (c, n) -> @@ -317,13 +320,13 @@ let pp_chain_error ppf = function | #chain_validation_error as c -> pp_chain_validation_error ppf c type fingerprint_validation_error = [ - | `InvalidFingerprint of Certificate.t * Cstruct.t * Cstruct.t + | `InvalidFingerprint of Certificate.t * string * string ] let pp_fingerprint_validation_error ppf = function | `InvalidFingerprint (c, c_fp, fp) -> Fmt.pf ppf "fingerprint for %a (computed %a) does not match, expected %a" - Certificate.pp c Cstruct.hexdump_pp c_fp Cstruct.hexdump_pp fp + Certificate.pp c Ohex.pp c_fp Ohex.pp fp type validation_error = [ | signature_error @@ -462,7 +465,7 @@ let fingerprint_verification ?ip host now fingerprint fp = function | [] -> Error `EmptyCertificateChain | server::_ -> let computed_fingerprint = fp server in - if Cstruct.equal computed_fingerprint fingerprint then + if String.equal computed_fingerprint fingerprint then match validate_time now server, maybe_validate_hostname server host, diff --git a/lib/x509.mli b/lib/x509.mli index c6971ea2..8258deaa 100644 --- a/lib/x509.mli +++ b/lib/x509.mli @@ -127,12 +127,12 @@ module Public_key : sig unused bits) for publicKeyInfo of [public_key]. {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.2}RFC 5280, 4.2.1.2, variant (1)} *) - val id : t -> Cstruct.t + val id : t -> string (** [fingerprint ?hash public_key] is [digest], the hash (by default SHA256) of the DER encoded public key (equivalent to [openssl x509 -noout -pubkey | openssl pkey -pubin -outform DER | openssl dgst -HASH]). *) - val fingerprint : ?hash:Mirage_crypto.Hash.hash -> t -> Cstruct.t + val fingerprint : ?hash:Digestif.hash' -> t -> string (** [key_type public_key] is its [key_type]. *) val key_type : t -> Key_type.t @@ -143,25 +143,25 @@ module Public_key : sig on [data] is valid using the [key], or not. The [signature] must be in ASN.1 DER encoding. The [scheme] defaults to [`RSA_PSS] for RSA, [`ED25519] for ED25519, and [`ECDSA] for other EC keys. *) - val verify : Mirage_crypto.Hash.hash -> + val verify : Digestif.hash' -> ?scheme:Key_type.signature_scheme -> - signature:Cstruct.t -> t -> - [ `Message of Cstruct.t | `Digest of Cstruct.t ] -> + signature:string -> t -> + [ `Message of string | `Digest of string ] -> (unit, [> `Msg of string ]) result (** {1 Decoding and encoding in ASN.1 DER and PEM format} *) (** [encode_der pk] is [buffer], the ASN.1 encoding of the given public key. *) - val encode_der : t -> Cstruct.t + val encode_der : t -> string (** [decode_der buffer] is [pubkey], the public key of the ASN.1 encoded buffer. *) - val decode_der : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_der : string -> (t, [> `Msg of string ]) result (** [decode_pem pem] is [t], where the public key of [pem] is extracted *) - val decode_pem : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_pem : string -> (t, [> `Msg of string ]) result (** [encode_pem public_key] is [pem], the pem encoded public key. *) - val encode_pem : t -> Cstruct.t + val encode_pem : t -> string end (** Private keys *) @@ -187,15 +187,15 @@ module Private_key : sig key type. The argument [bits] is only used for the bit length of RSA keys. If [seed] is provided, this is used to seed the random number generator. *) - val generate : ?seed:Cstruct.t -> ?bits:int -> Key_type.t -> t + val generate : ?seed:string -> ?bits:int -> Key_type.t -> t - (** [of_cstruct data type] decodes the buffer as private key. Only supported + (** [of_octets data type] decodes the buffer as private key. Only supported for elliptic curve keys. *) - val of_cstruct : Cstruct.t -> Key_type.t -> (t, [> `Msg of string ]) result + val of_octets : string -> Key_type.t -> (t, [> `Msg of string ]) result (** [of_string ~seed_or_data ~bits type data] attempts to decode the data as a private key. If [seed_or_data] is provided and [`Seed], the [data] is - taken as seed and {!generate} is used. If it is [`Data], {!of_cstruct} is + taken as seed and {!generate} is used. If it is [`Data], {!of_octets} is used with the Base64 decoded [data]. By default, if [type] is RSA, the data is used as seed, otherwise directly as the private key data. *) val of_string : ?seed_or_data:[`Seed | `Data] -> ?bits:int -> Key_type.t -> @@ -215,28 +215,28 @@ module Private_key : sig [scheme]. If [data] is [`Message _], the [hash] will be applied before the signature. The [scheme] defaults to [`RSA_PSS] for RSA keys, [`ED25519] for ED25519, and [`ECDSA] for other EC keys. *) - val sign : Mirage_crypto.Hash.hash -> + val sign : Digestif.hash' -> ?scheme:Key_type.signature_scheme -> - t -> [ `Digest of Cstruct.t | `Message of Cstruct.t ] -> - (Cstruct.t, [> `Msg of string ]) result + t -> [ `Digest of string | `Message of string ] -> + (string, [> `Msg of string ]) result (** {1 Decoding and encoding in ASN.1 DER and PEM format} *) (** [decode_der der] is [t], where the private key of [der] is extracted. It must be in PKCS8 (RFC 5208, Section 5) PrivateKeyInfo structure. *) - val decode_der : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_der : string -> (t, [> `Msg of string ]) result (** [encode_der key] is [der], the encoded private key as PKCS8 (RFC 5208, Section 5) PrivateKeyInfo structure. *) - val encode_der : t -> Cstruct.t + val encode_der : t -> string (** [decode_pem pem] is [t], where the private key of [pem] is extracted. Both RSA PRIVATE KEY and PRIVATE KEY stanzas are supported. *) - val decode_pem : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_pem : string -> (t, [> `Msg of string ]) result (** [encode_pem key] is [pem], the encoded private key (using [PRIVATE KEY]). *) - val encode_pem : t -> Cstruct.t + val encode_pem : t -> string end (** X.500 distinguished name *) @@ -320,11 +320,11 @@ module Distinguished_name : sig val common_name : t -> string option (** [decode_der cs] is [dn], the ASN.1 decoded distinguished name of [cs]. *) - val decode_der : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_der : string -> (t, [> `Msg of string ]) result - (** [encode_der dn] is [cstruct], the ASN.1 encoded representation of the + (** [encode_der dn] is [octets], the ASN.1 encoded representation of the distinguished name [dn]. *) - val encode_der : t -> Cstruct.t + val encode_der : t -> string end (** A list of [general_name]s is the value of both @@ -341,7 +341,7 @@ module General_name : sig | Directory : Distinguished_name.t list k | EDI_party : (string option * string) list k | URI : string list k - | IP : Cstruct.t list k + | IP : string list k | Registered_id : Asn.oid list k include Gmap.S with type 'a key = 'a k @@ -386,7 +386,7 @@ module Extension : sig (** The authority key identifier, as present in the {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.1}Authority Key Identifier} extension. *) - type authority_key_id = Cstruct.t option * General_name.t * Z.t option + type authority_key_id = string option * General_name.t * Z.t option (** The private key usage period, as defined in {{:https://tools.ietf.org/html/rfc3280#section-4.2.1.4}RFC 3280}. *) @@ -441,10 +441,10 @@ module Extension : sig {{:https://tools.ietf.org/html/rfc5280#section-4.2}X509v3} and {{:https://tools.ietf.org/html/rfc5280#section-5.2}CRL} extensions. *) type _ k = - | Unsupported : Asn.oid -> Cstruct.t extension k + | Unsupported : Asn.oid -> string extension k | Subject_alt_name : General_name.t extension k | Authority_key_id : authority_key_id extension k - | Subject_key_id : Cstruct.t extension k + | Subject_key_id : string extension k | Issuer_alt_name : General_name.t extension k | Key_usage : key_usage list extension k | Ext_key_usage : extended_key_usage list extension k @@ -475,12 +475,12 @@ module Certificate : sig (** [decode_pkcs1_digest_info buffer] is [hash, signature], the hash and raw signature of the given [buffer] in ASN.1 DER encoding, or an error. *) - val decode_pkcs1_digest_info : Cstruct.t -> - (Mirage_crypto.Hash.hash * Cstruct.t, [> `Msg of string ]) result + val decode_pkcs1_digest_info : string -> + ([ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ] * string, [> `Msg of string ]) result (** [encode_pkcs1_digest_info (hash, signature)] is [data], the ASN.1 DER encoded hash and signature. *) - val encode_pkcs1_digest_info : Mirage_crypto.Hash.hash * Cstruct.t -> Cstruct.t + val encode_pkcs1_digest_info : [ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ] * string -> string (** {1 Abstract certificate type} *) @@ -492,27 +492,27 @@ module Certificate : sig (** {1 Encoding and decoding in ASN.1 DER and PEM format} *) - (** [decode_der cstruct] is [certificate], the ASN.1 decoded [certificate] + (** [decode_der octets] is [certificate], the ASN.1 decoded [certificate] or an error. *) - val decode_der : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_der : string -> (t, [> `Msg of string ]) result - (** [encode_der certificate] is [cstruct], the ASN.1 encoded representation of + (** [encode_der certificate] is [octets], the ASN.1 encoded representation of the [certificate]. *) - val encode_der : t -> Cstruct.t + val encode_der : t -> string (** [decode_pem_multiple pem] is [t list], where all certificates of the [pem] are extracted *) - val decode_pem_multiple : Cstruct.t -> (t list, [> `Msg of string ]) result + val decode_pem_multiple : string -> (t list, [> `Msg of string ]) result (** [decode_pem pem] is [t], where the single certificate of the [pem] is extracted *) - val decode_pem : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_pem : string -> (t, [> `Msg of string ]) result (** [encode_pem_multiple certificates] is [pem], the pem encoded certificates. *) - val encode_pem_multiple : t list -> Cstruct.t + val encode_pem_multiple : t list -> string (** [encode_pem certificate] is [pem], the pem encoded certificate. *) - val encode_pem : t -> Cstruct.t + val encode_pem : t -> string (** {1 Operations on certificates} *) @@ -525,7 +525,7 @@ module Certificate : sig (** [signature_algorithm certificate] is the algorithm used for the signature. *) val signature_algorithm : t -> - (Key_type.signature_scheme * Mirage_crypto.Hash.hash) option + (Key_type.signature_scheme * Digestif.hash') option (** [hostnames certficate] is the set of domain names this [certificate] is valid for. Currently, these are the DNS names of the @@ -548,7 +548,7 @@ module Certificate : sig (** [fingerprint hash cert] is [digest], the digest of [cert] using the specified [hash] algorithm *) - val fingerprint : Mirage_crypto.Hash.hash -> t -> Cstruct.t + val fingerprint : Digestif.hash' -> t -> string (** [subject certificate] is [dn], the subject as distinguished name of the [certificate]. *) @@ -590,8 +590,8 @@ module Validation : sig (** The type of signature verification errors. *) type signature_error = [ | `Bad_signature of Distinguished_name.t * string - | `Bad_encoding of Distinguished_name.t * string * Cstruct.t - | `Hash_not_allowed of Distinguished_name.t * Mirage_crypto.Hash.hash + | `Bad_encoding of Distinguished_name.t * string * string + | `Hash_not_allowed of Distinguished_name.t * [ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ] | `Unsupported_keytype of Distinguished_name.t * Public_key.t | `Unsupported_algorithm of Distinguished_name.t * string | `Msg of string @@ -621,12 +621,12 @@ module Validation : sig extensions are not present (if X.509 version 1 certificate), or are appropriate for a CA (BasicConstraints is present and true, KeyUsage extension contains keyCertSign). *) - val valid_ca : ?allowed_hashes:Mirage_crypto.Hash.hash list -> ?time:Ptime.t -> + val valid_ca : ?allowed_hashes:Digestif.hash' list -> ?time:Ptime.t -> Certificate.t -> (unit, [> ca_error ]) result (** [valid_cas ~allowed_hashes ~time certificates] is [valid_certificates], only those certificates which pass the {!valid_ca} check. *) - val valid_cas : ?allowed_hashes:Mirage_crypto.Hash.hash list -> ?time:Ptime.t -> + val valid_cas : ?allowed_hashes:Digestif.hash' list -> ?time:Ptime.t -> Certificate.t list -> Certificate.t list (** {1 Chain of trust verification} *) @@ -688,13 +688,13 @@ module Validation : sig val verify_chain : ?ip:Ipaddr.t -> host:[`host] Domain_name.t option -> time:(unit -> Ptime.t option) -> ?revoked:(issuer:Certificate.t -> cert:Certificate.t -> bool) -> - ?allowed_hashes:Mirage_crypto.Hash.hash list -> + ?allowed_hashes:Digestif.hash' list -> anchors:(Certificate.t list) -> Certificate.t list -> (Certificate.t, [> chain_error ]) result (** The polymorphic variant of a fingerprint validation error. *) type fingerprint_validation_error = [ - | `InvalidFingerprint of Certificate.t * Cstruct.t * Cstruct.t + | `InvalidFingerprint of Certificate.t * string * string ] (** The polymorphic variant of validation errors. *) @@ -724,7 +724,7 @@ module Validation : sig ?ip:Ipaddr.t -> host:[`host] Domain_name.t option -> time:(unit -> Ptime.t option) -> ?revoked:(issuer:Certificate.t -> cert:Certificate.t -> bool) -> - ?allowed_hashes:Mirage_crypto.Hash.hash list -> + ?allowed_hashes:Digestif.hash' list -> anchors:(Certificate.t list) -> Certificate.t list -> r (** {1 Fingerprint verification} *) @@ -738,8 +738,8 @@ module Validation : sig checked to include this IP address (using {!Certificate.ips}). *) val trust_key_fingerprint : ?ip:Ipaddr.t -> host:[`host] Domain_name.t option -> - time:(unit -> Ptime.t option) -> hash:Mirage_crypto.Hash.hash -> - fingerprint:Cstruct.t -> Certificate.t list -> r + time:(unit -> Ptime.t option) -> hash:Digestif.hash' -> + fingerprint:string -> Certificate.t list -> r (** [trust_cert_fingerprint host ~time ~hash ~fingerprint certificates] is [result], the first element of [certificates] is verified to match the @@ -754,8 +754,8 @@ module Validation : sig over certificate pinning. *) val trust_cert_fingerprint : ?ip:Ipaddr.t -> host:[`host] Domain_name.t option -> - time:(unit -> Ptime.t option) -> hash:Mirage_crypto.Hash.hash -> - fingerprint:Cstruct.t -> Certificate.t list -> r + time:(unit -> Ptime.t option) -> hash:Digestif.hash' -> + fingerprint:string -> Certificate.t list -> r end (** Certificate Signing request *) @@ -770,21 +770,21 @@ module Signing_request : sig (** {1 Decoding and encoding in ASN.1 DER and PEM format} *) - (** [decode_der ~allowed_hashes cstruct] is [signing_request], the ASN.1 - decoded [cstruct] or an error. The signature on the signing request + (** [decode_der ~allowed_hashes octets] is [signing_request], the ASN.1 + decoded [octets] or an error. The signature on the signing request is validated, and its hash algorithm must be in [allowed_hashes] (by default only SHA-2 is accepted). *) - val decode_der : ?allowed_hashes:Mirage_crypto.Hash.hash list -> Cstruct.t -> + val decode_der : ?allowed_hashes:Digestif.hash' list -> string -> (t, [> `Msg of string ]) result - (** [encode_der sr] is [cstruct], the ASN.1 encoded representation of the [sr]. *) - val encode_der : t -> Cstruct.t + (** [encode_der sr] is [octets], the ASN.1 encoded representation of the [sr]. *) + val encode_der : t -> string (** [decode_pem pem] is [t], where the single signing request of the [pem] is extracted *) - val decode_pem : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_pem : string -> (t, [> `Msg of string ]) result (** [encode_pem signing_request] is [pem], the pem encoded signing request. *) - val encode_pem : t -> Cstruct.t + val encode_pem : t -> string (** {1 Construction of a signing request} *) @@ -815,7 +815,7 @@ module Signing_request : sig (** [signature_algorithm signing_request] is the algorithm used for the signature. *) val signature_algorithm : t -> - (Key_type.signature_scheme * Mirage_crypto.Hash.hash) option + (Key_type.signature_scheme * Digestif.hash') option (** [hostnames signing_request] is the set of domain names this [signing_request] is requesting. This is either the content of the DNS @@ -826,7 +826,7 @@ module Signing_request : sig (** [create subject ~digest ~extensions private] creates [signing_request], a certification request using the given [subject], [digest] (defaults to [`SHA256]) and list of [extensions]. *) - val create : Distinguished_name.t -> ?digest:Mirage_crypto.Hash.hash -> + val create : Distinguished_name.t -> ?digest:Digestif.hash' -> ?extensions:Ext.t -> Private_key.t -> (t, [> `Msg of string ]) result (** {1 Provision a signing request to a certificate} *) @@ -848,8 +848,8 @@ module Signing_request : sig | Error _ -> Extension.empty ]} *) val sign : t -> valid_from:Ptime.t -> valid_until:Ptime.t -> - ?allowed_hashes:Mirage_crypto.Hash.hash list -> - ?digest:Mirage_crypto.Hash.hash -> ?serial:Z.t -> ?extensions:Extension.t -> + ?allowed_hashes:Digestif.hash' list -> + ?digest:Digestif.hash' -> ?serial:Z.t -> ?extensions:Extension.t -> ?subject:Distinguished_name.t -> Private_key.t -> Distinguished_name.t -> (Certificate.t, Validation.signature_error) result @@ -872,11 +872,11 @@ module CRL : sig (** [encode_der crl] is [buffer], the ASN.1 DER encoding of the given certificate revocation list. *) - val encode_der : t -> Cstruct.t + val encode_der : t -> string (** [decode_der buffer] is [crl], the certificate revocation list of the ASN.1 encoded buffer. *) - val decode_der : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_der : string -> (t, [> `Msg of string ]) result (** {1 Operations on CRLs} *) @@ -917,13 +917,13 @@ module CRL : sig (** [signature_algorithm t] is the algorithm used for the signature. *) val signature_algorithm : t -> - (Key_type.signature_scheme * Mirage_crypto.Hash.hash) option + (Key_type.signature_scheme * Digestif.hash') option (** {1 Validation and verification of CRLs} *) (** [validate t ~allowed_hashes pk] validates the digital signature of the revocation list. The [allowed_hashes] defaults to SHA-2. *) - val validate : t -> ?allowed_hashes:Mirage_crypto.Hash.hash list -> + val validate : t -> ?allowed_hashes:Digestif.hash' list -> Public_key.t -> (unit, [> Validation.signature_error ]) result (** The type of CRL verification errors. *) @@ -943,21 +943,21 @@ module CRL : sig revocation list. The used hash algorithm must be in the [allowed_hashes] (defaults to SHA-2). If [time] is provided, it must be after [this_update] and before [next_update] of [t]. *) - val verify : t -> ?allowed_hashes:Mirage_crypto.Hash.hash list -> + val verify : t -> ?allowed_hashes:Digestif.hash' list -> ?time:Ptime.t -> Certificate.t -> (unit, [> verification_error ]) result (** [is_revoked ~allowed_hashes ~issuer ~cert crls] is [true] if there exists a revocation of [cert] in [crls] which is signed by the [issuer]. The subject of [issuer] must match the issuer of the crl. The hash algorithm used for signing must be in the [allowed_hashes] (defaults to SHA-2). *) - val is_revoked : ?allowed_hashes:Mirage_crypto.Hash.hash list -> + val is_revoked : ?allowed_hashes:Digestif.hash' list -> issuer:Certificate.t -> cert:Certificate.t -> t list -> bool (** {1 Construction and signing of CRLs} *) (** [revoked ~digest ~issuer ~this_update ~next_update ~extensions certs priv] constructs a revocation list with the given parameters. *) - val revoke : ?digest:Mirage_crypto.Hash.hash -> + val revoke : ?digest:Digestif.hash' -> issuer:Distinguished_name.t -> this_update:Ptime.t -> ?next_update:Ptime.t -> ?extensions:Extension.t -> @@ -998,14 +998,14 @@ module Authenticator : sig {!Validation.verify_chain_of_trust}. The given trust anchors are not validated, you can filter them with {!Validation.valid_cas} if desired. *) val chain_of_trust : time:(unit -> Ptime.t option) -> ?crls:CRL.t list -> - ?allowed_hashes:Mirage_crypto.Hash.hash list -> Certificate.t list -> t + ?allowed_hashes:Digestif.hash' list -> Certificate.t list -> t (** [server_key_fingerprint ~time hash fingerprint] is an [authenticator] that uses the given [time] and [fingerprint] to verify that the fingerprint of the first element of the certificate chain matches the given fingerprint, using {!Validation.trust_key_fingerprint}. *) val server_key_fingerprint : time:(unit -> Ptime.t option) -> - hash:Mirage_crypto.Hash.hash -> fingerprint:Cstruct.t -> t + hash:Digestif.hash' -> fingerprint:string -> t (** [server_cert_fingerprint ~time hash fingerprint] is an [authenticator] that uses the given [time] and [fingerprint] to verify the first @@ -1015,7 +1015,7 @@ module Authenticator : sig {{:https://www.imperialviolet.org/2011/05/04/pinning.html} advantages} over certificate pinning. *) val server_cert_fingerprint : time:(unit -> Ptime.t option) -> - hash:Mirage_crypto.Hash.hash -> fingerprint:Cstruct.t -> t + hash:Digestif.hash' -> fingerprint:string -> t (** [of_string str] tries to parse the given [str] to an {!type:Authenticator.t}. The format of it is: @@ -1043,10 +1043,10 @@ module PKCS12 : sig type t (** [decode_der buffer] is [t], the PKCS12 archive of [buffer]. *) - val decode_der : Cstruct.t -> (t, [> `Msg of string ]) result + val decode_der : string -> (t, [> `Msg of string ]) result (** [encode_der t] is [buf], the PKCS12 encoded archive of [t]. *) - val encode_der : t -> Cstruct.t + val encode_der : t -> string (** [verify password t] verifies and decrypts the PKCS12 archive [t]. The result is the contents of the archive. *) @@ -1076,7 +1076,7 @@ module OCSP : sig type cert_id (** [create_cert_id issuer serial] creates cert_id for this serial *) - val create_cert_id : ?hash:Mirage_crypto.Hash.hash -> Certificate.t -> Z.t -> + val create_cert_id : ?hash:[ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ] -> Certificate.t -> Z.t -> cert_id (** [cert_id_serial certid] is serial number of this certid *) @@ -1098,13 +1098,13 @@ module OCSP : sig for given [certids] and, if [key] is provided, signs it using [digest]. [requestorName] may be used by responder to distinguish requesters. [certs] may be used by responder to check requestor authority. *) - val create : ?certs:Certificate.t list -> ?digest:Mirage_crypto.Hash.hash -> + val create : ?certs:Certificate.t list -> ?digest:Digestif.hash' -> ?requestor_name:General_name.b -> ?key:Private_key.t -> cert_id list -> (t, [> `Msg of string ]) result (** [validate request key] validates the signature of [request] with the pulic [key]. *) - val validate : t -> ?allowed_hashes:Mirage_crypto.Hash.hash list -> + val validate : t -> ?allowed_hashes:Digestif.hash' list -> Public_key.t -> (unit, [> Validation.signature_error | `No_signature ]) result @@ -1115,10 +1115,10 @@ module OCSP : sig val cert_ids : t -> cert_id list (** [decode_der buffer] decodes request in buffer *) - val decode_der : Cstruct.t -> (t, Asn.error) result + val decode_der : string -> (t, Asn.error) result (** [encode_der request] encodes request into buffer *) - val encode_der : t -> Cstruct.t + val encode_der : t -> string end (** Module for encoding and decoding OCSP responses. *) @@ -1169,12 +1169,12 @@ module OCSP : sig (** type for ResponderID *) type responder_id = [ - | `ByKey of Cstruct.t + | `ByKey of string | `ByName of Distinguished_name.t ] (** [create_responder_id pubkey] creates responderID identified by this key. - Note: Cstruct here contains SHA1 hash of public key, not itself. *) + Note: octets here contains SHA1 hash of public key, not itself. *) val create_responder_id : Public_key.t -> responder_id (** [pp_responder_id ppf responderID] pretty prints [responderID] *) @@ -1187,7 +1187,7 @@ module OCSP : sig responderID producedAt responses] creates response and signs it with [priv_key]. [producedAt] should be current timestamp. *) val create_success : - ?digest:Mirage_crypto.Hash.hash -> + ?digest:Digestif.hash' -> ?certs:Certificate.t list -> ?response_extensions:Extension.t -> Private_key.t -> @@ -1218,14 +1218,14 @@ module OCSP : sig val responses : t -> (single_response list, [> `Msg of string ]) result (** [decode_der buffer] decodes response in buffer *) - val decode_der : Cstruct.t -> (t, Asn.error) result + val decode_der : string -> (t, Asn.error) result (** [encode_der request] encodes response into buffer *) - val encode_der : t -> Cstruct.t + val encode_der : t -> string (** [validate response key] validates the signature of [response] with the pulic [key]. *) - val validate : t -> ?allowed_hashes:Mirage_crypto.Hash.hash list -> + val validate : t -> ?allowed_hashes:Digestif.hash' list -> ?now:Ptime.t -> Public_key.t -> (unit, [> Validation.signature_error | `No_signature | `Time_invalid ]) result end diff --git a/tests/crltests.ml b/tests/crltests.ml index 5074c4d8..7dad9ee1 100644 --- a/tests/crltests.ml +++ b/tests/crltests.ml @@ -1,21 +1,27 @@ open X509 +let of_ic ic = + let ln = in_channel_length ic in + let rs = Bytes.create ln in + really_input ic rs 0 ln; + Bytes.unsafe_to_string rs + let with_loaded_files file ~f = let pre = "./crl/" in let fullpath1 = pre ^ file ^ ".pem" and fullpath2 = pre ^ file ^ ".crl" in - let fd1 = Unix.(openfile fullpath1 [O_RDONLY] 0) - and fd2 = Unix.(openfile fullpath2 [O_RDONLY] 0) + let fd1 = open_in fullpath1 + and fd2 = open_in fullpath2 in - let buf1 = Unix_cstruct.of_fd fd1 - and buf2 = Unix_cstruct.of_fd fd2 + let buf1 = of_ic fd1 + and buf2 = of_ic fd2 in - try let r = f buf1 buf2 in Unix.close fd1 ; Unix.close fd2 ; + try let r = f buf1 buf2 in close_in fd1 ; close_in fd2 ; match r with | Ok x -> x | Error (`Msg e) -> Alcotest.failf "decoding error %s" e - with e -> Unix.close fd1 ; Unix.close fd2 ; + with e -> close_in fd1 ; close_in fd2 ; Alcotest.failf "exception %s" (Printexc.to_string e) let allowed_hashes = [ `SHA1 ; `SHA256 ; `SHA384 ; `SHA512 ] diff --git a/tests/dune b/tests/dune index 1c0105b3..fb10ec7b 100644 --- a/tests/dune +++ b/tests/dune @@ -1,4 +1,4 @@ (test (name tests) (deps (source_tree regression) (source_tree testcertificates) (source_tree crl) (source_tree csr) (source_tree pkcs12) (source_tree ocsp)) - (libraries x509 alcotest cstruct-unix ptime.clock.os mirage-crypto-pk mirage-crypto-ec mirage-crypto-rng.unix)) + (libraries x509 alcotest ptime.clock.os mirage-crypto-pk mirage-crypto-ec mirage-crypto-rng.unix)) diff --git a/tests/ocsp.ml b/tests/ocsp.ml index 6145da48..11d14d91 100644 --- a/tests/ocsp.ml +++ b/tests/ocsp.ml @@ -29,10 +29,15 @@ openssl ocsp -respin response.der -CAfile certificate.pem -text *) -let cs_mmap file = - Unix_cstruct.of_fd Unix.(openfile file [O_RDONLY] 0) - -let data file = cs_mmap ("./ocsp/" ^ file) +let mmap file = + let ic = open_in file in + let ln = in_channel_length ic in + let rs = Bytes.create ln in + really_input ic rs 0 ln; + close_in ic; + Bytes.unsafe_to_string rs + +let data file = mmap ("./ocsp/" ^ file) let responder_cert = match Certificate.decode_pem (data "certificate.pem") with | Ok c -> c diff --git a/tests/pkcs12.ml b/tests/pkcs12.ml index f246c934..51afc4a0 100644 --- a/tests/pkcs12.ml +++ b/tests/pkcs12.ml @@ -1,9 +1,14 @@ open X509 -let cs_mmap file = - Unix_cstruct.of_fd Unix.(openfile file [O_RDONLY] 0) +let mmap file = + let ic = open_in file in + let ln = in_channel_length ic in + let rs = Bytes.create ln in + really_input ic rs 0 ln; + close_in ic; + Bytes.unsafe_to_string rs -let data file = cs_mmap ("./pkcs12/" ^ file) +let data file = mmap ("./ocsp/" ^ file) let cert = match Certificate.decode_pem (data "certificate.pem") with | Ok c -> c diff --git a/tests/priv.ml b/tests/priv.ml index a87e5af4..04a78c0e 100644 --- a/tests/priv.ml +++ b/tests/priv.ml @@ -1,13 +1,13 @@ open X509 let pk_equal a b = - Cstruct.equal - (Mirage_crypto.Hash.SHA256.digest (Private_key.encode_der a)) - (Mirage_crypto.Hash.SHA256.digest (Private_key.encode_der b)) + String.equal + Digestif.SHA256.(to_raw_string (digest_string (Private_key.encode_der a))) + Digestif.SHA256.(to_raw_string (digest_string (Private_key.encode_der b))) let generate_rsa () = let seed = "Test1234" in - let pk = Private_key.generate ~seed:(Cstruct.of_string seed) `RSA in + let pk = Private_key.generate ~seed `RSA in let pk' = Result.get_ok (Private_key.of_string `RSA seed) in let pk'' = Result.get_ok (Private_key.of_string ~seed_or_data:`Seed `RSA seed) in Alcotest.(check bool "generate and of_string" true (pk_equal pk pk')); @@ -16,10 +16,10 @@ let generate_rsa () = | Error _ -> () | Ok _ -> Alcotest.fail "expected failure (of_string `Data `RSA)" -let b64_dec s = Base64.decode_exn s |> Cstruct.of_string +let b64_dec s = Base64.decode_exn s let test_ec (key_type, data) () = - let pk = Result.get_ok (Private_key.of_cstruct (b64_dec data) key_type) in + let pk = Result.get_ok (Private_key.of_octets (b64_dec data) key_type) in let pk' = Result.get_ok (Private_key.of_string key_type data) in let pk'' = Result.get_ok (Private_key.of_string ~seed_or_data:`Data key_type data) in Alcotest.(check bool "generate and of_string" true (pk_equal pk pk')); diff --git a/tests/regression.ml b/tests/regression.ml index b0a19c64..b3740b66 100644 --- a/tests/regression.ml +++ b/tests/regression.ml @@ -1,10 +1,15 @@ open X509 -let cs_mmap file = - Unix_cstruct.of_fd Unix.(openfile file [O_RDONLY] 0) +let mmap file = + let ic = open_in file in + let ln = in_channel_length ic in + let rs = Bytes.create ln in + really_input ic rs 0 ln; + close_in ic; + Bytes.unsafe_to_string rs let regression file = - cs_mmap ("./regression/" ^ file ^ ".pem") + mmap ("./regression/" ^ file ^ ".pem") let cert file = match Certificate.decode_pem (regression file) with @@ -142,7 +147,7 @@ let test_openssl_2048_key () = decode_valid_pem file let ed25519_priv = - Cstruct.of_hex "D4EE72DBF913584AD5B6D8F1F769F8AD3AFE7C28CBF1D4FBE097A88F44755842" + Ohex.decode "D4EE72DBF913584AD5B6D8F1F769F8AD3AFE7C28CBF1D4FBE097A88F44755842" let ed25519_priv_key () = let data = @@ -151,10 +156,10 @@ MC4CAQAwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC -----END PRIVATE KEY----- |} in - match Private_key.decode_pem (Cstruct.of_string data) with - | Ok (`ED25519 k as ke) when Cstruct.equal ed25519_priv (Mirage_crypto_ec.Ed25519.priv_to_cstruct k) -> + match Private_key.decode_pem data with + | Ok (`ED25519 k as ke) when String.equal ed25519_priv (Mirage_crypto_ec.Ed25519.priv_to_octets k) -> let encoded = Private_key.encode_pem ke in - if not (String.equal (Cstruct.to_string encoded) data) then + if not (String.equal encoded data) then Alcotest.failf "ED25519 encoding failed" | Ok (`ED25519 _) -> Alcotest.failf "wrong ED25519 private key" | Ok _ | Error (`Msg _) -> Alcotest.failf "ED25519 private key decode failure" @@ -166,18 +171,18 @@ MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE= -----END PUBLIC KEY----- |} and pub = - match Mirage_crypto_ec.Ed25519.priv_of_cstruct ed25519_priv with + match Mirage_crypto_ec.Ed25519.priv_of_octets ed25519_priv with | Error _ -> Alcotest.fail "couldn't decode private Ed25519 key" | Ok p -> match Private_key.public (`ED25519 p) with | `ED25519 p -> p | _ -> Alcotest.fail "couldn't convert private Ed25519 key to public" in - let to_cs = Mirage_crypto_ec.Ed25519.pub_to_cstruct in - match Public_key.decode_pem (Cstruct.of_string data) with - | Ok (`ED25519 k) when Cstruct.equal (to_cs pub) (to_cs k) -> + let to_cs = Mirage_crypto_ec.Ed25519.pub_to_octets in + match Public_key.decode_pem data with + | Ok (`ED25519 k) when String.equal (to_cs pub) (to_cs k) -> let encoded = Public_key.encode_pem (`ED25519 k) in - if not (String.equal (Cstruct.to_string encoded) data) then + if not (String.equal encoded data) then Alcotest.failf "ED25519 public key encoding failure" | _ -> Alcotest.failf "bad ED25519 public key" @@ -197,22 +202,22 @@ GjfhN8ieupCqSdF3iqDidK006KWs848y |} in match - Private_key.decode_pem (Cstruct.of_string priv_data), - Public_key.decode_pem (Cstruct.of_string pub_data) + Private_key.decode_pem priv_data, + Public_key.decode_pem pub_data with | Ok (`P384 priv), Ok (`P384 pub) -> - let to_cs = Mirage_crypto_ec.P384.Dsa.pub_to_cstruct in + let to_cs = Mirage_crypto_ec.P384.Dsa.pub_to_octets in let pub' = Mirage_crypto_ec.P384.Dsa.pub_of_priv priv in - Alcotest.(check bool __LOC__ true (Cstruct.equal (to_cs pub) (to_cs pub'))); + Alcotest.(check bool __LOC__ true (String.equal (to_cs pub) (to_cs pub'))); let pub_data' = Public_key.encode_pem (`P384 pub) in Alcotest.(check bool __LOC__ true - (Cstruct.equal (Cstruct.of_string pub_data) pub_data')); + (String.equal pub_data pub_data')); let priv_data' = Private_key.encode_pem (`P384 priv) in begin match Private_key.decode_pem priv_data' with | Ok (`P384 priv) -> let pub' = Mirage_crypto_ec.P384.Dsa.pub_of_priv priv in Alcotest.(check bool __LOC__ true - (Cstruct.equal (to_cs pub) (to_cs pub'))) + (String.equal (to_cs pub) (to_cs pub'))) | _ -> Alcotest.failf "cannot decode re-encoded P384 private key" end | _ -> Alcotest.failf "bad P384 key" @@ -319,7 +324,7 @@ let cert_hostnames cert names () = Alcotest.check host_set_test __LOC__ (Certificate.hostnames cert) names let csr file = - let data = cs_mmap ("./csr/" ^ file ^ ".pem") in + let data = mmap ("./csr/" ^ file ^ ".pem") in match Signing_request.decode_pem data with | Ok csr -> csr | Error (`Msg m) -> diff --git a/tests/x509tests.ml b/tests/x509tests.ml index b1893b3b..53095955 100644 --- a/tests/x509tests.ml +++ b/tests/x509tests.ml @@ -4,16 +4,19 @@ let time () = None let with_loaded_file file ~f = let fullpath = "./testcertificates/" ^ file ^ ".pem" in - let fd = Unix.(openfile fullpath [O_RDONLY] 0) in - let buf = Unix_cstruct.of_fd fd in + let fd = open_in fullpath in + let ln = in_channel_length fd in + let buf = Bytes.create ln in + really_input fd buf 0 ln; + let buf = Bytes.unsafe_to_string buf in try let r = f buf in - Unix.close fd; + close_in fd; match r with | Ok data -> data | Error (`Msg m) -> Alcotest.failf "decoding error in %s: %s" fullpath m with e -> - Unix.close fd; + close_in fd; Alcotest.failf "exception in %s: %s" fullpath (Printexc.to_string e) let priv = diff --git a/x509.opam b/x509.opam index 5f2aa3b8..6d415c9a 100644 --- a/x509.opam +++ b/x509.opam @@ -14,7 +14,6 @@ bug-reports: "https://github.com/mirleft/ocaml-x509/issues" depends: [ "ocaml" {>= "4.08.0"} "dune" {>= "1.2"} - "cstruct" {>= "6.0.0"} "asn1-combinators" {>= "0.2.0"} "ptime" "base64" {>= "3.3.0"} @@ -25,7 +24,6 @@ depends: [ "mirage-crypto-rng" {with-test & >= "0.11.0"} "fmt" {>= "0.8.7"} "alcotest" {with-test} - "cstruct-unix" {with-test & >= "3.0.0"} "gmap" {>= "0.3.0"} "domain-name" {>= "0.3.0"} "logs" @@ -49,3 +47,11 @@ The Public Key Cryptography Standards (PKCS) defines encoding and decoding (in ASN.1 DER and PEM format), which is also implemented by this library - namely PKCS 1, PKCS 5, PKCS 7, PKCS 8, PKCS 9, PKCS 10, and PKCS 12. """ + +pin-depends: [ + [ "mirage-crypto.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] + [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] + [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] + [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] + [ "pbkdf.dev" "git+https://github.com/dinosaure/ocaml-pbkdf.git#5af4644b88774c1ed3288df4b43256b9a6767e01" ] +] From bcb9f135c5f929d47082152ce5119da7c9182388 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Wed, 3 Apr 2024 19:14:48 +0200 Subject: [PATCH 03/17] fixes, tests are now passing --- lib/algorithm.ml | 17 +++++++++++------ lib/rc2.ml | 5 +---- tests/pkcs12.ml | 6 +++--- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/algorithm.ml b/lib/algorithm.ml index 7b66fb57..140e4c2d 100644 --- a/lib/algorithm.ml +++ b/lib/algorithm.ml @@ -404,14 +404,19 @@ let identifier = let ecdsa_sig = let f (r', s') = - let r = Mirage_crypto_pk.Z_extra.of_octets_be r' in - let s = Mirage_crypto_pk.Z_extra.of_octets_be s' in - if Z.sign r < 0 then + let r1 = String.get_uint8 r' 0 + and s1 = String.get_uint8 s' 0 + in + if r1 > 0x7F then Asn.S.parse_error "ECDSA signature: r < 0" - else if Z.sign s < 0 then + else if s1 > 0x7F then Asn.S.parse_error "ECDSA signature: s < 0" - else (r', s') - and g (r, s) = (r, s) + else + (if r1 = 0x00 then String.sub r' 1 (String.length r' - 1) else r'), + (if s1 = 0x00 then String.sub s' 1 (String.length s' - 1) else s') + and g (r, s) = + (if String.get_uint8 r 0 > 0x7F then String.make 1 '\x00' ^ r else r), + (if String.get_uint8 s 0 > 0x7F then String.make 1 '\x00' ^ s else s) in map f g @@ sequence2 diff --git a/lib/rc2.ml b/lib/rc2.ml index 274f71b0..417956c8 100644 --- a/lib/rc2.ml +++ b/lib/rc2.ml @@ -162,9 +162,6 @@ let decrypt_one ~key ~data ?(off = 0) dst = Bytes.set_uint16_le dst (off + 4) r.(2); Bytes.set_uint16_le dst (off + 6) r.(3) -let shift buf off = - Bytes.sub buf off (Bytes.length buf - off) - let decrypt_cbc ?(effective = 128) ~key ~iv data = let block = 8 in let key = key_expansion effective key in @@ -174,5 +171,5 @@ let decrypt_cbc ?(effective = 128) ~key ~iv data = decrypt_one ~key ~data ~off:(i * block) dst done; Mirage_crypto.Uncommon.xor_into iv dst block; - Mirage_crypto.Uncommon.xor_into data (shift dst block) (l - block); + Mirage_crypto.Uncommon.xor_into data dst ~dst_off:block (l - block); Bytes.unsafe_to_string dst diff --git a/tests/pkcs12.ml b/tests/pkcs12.ml index 51afc4a0..cd2717f5 100644 --- a/tests/pkcs12.ml +++ b/tests/pkcs12.ml @@ -8,7 +8,7 @@ let mmap file = close_in ic; Bytes.unsafe_to_string rs -let data file = mmap ("./ocsp/" ^ file) +let data file = mmap ("./pkcs12/" ^ file) let cert = match Certificate.decode_pem (data "certificate.pem") with | Ok c -> c @@ -28,11 +28,11 @@ let cert_and_key xs = let openssl1 () = match PKCS12.decode_der (data "ossl.p12") with - | Error _ -> Alcotest.fail "failed to decode ossl.p12" + | Error `Msg m -> Alcotest.fail ("failed to decode ossl.p12: " ^ m) | Ok data -> match PKCS12.verify pass data with | Ok xs -> cert_and_key xs - | Error _ -> Alcotest.fail "failed to verify ossl.p12" + | Error `Msg m -> Alcotest.fail ("failed to verify ossl.p12: " ^ m) let openssl2 () = match PKCS12.decode_der (data "ossl_aes.p12") with From 16ede418a71a258ef887f91885435e1a55ca526d Mon Sep 17 00:00:00 2001 From: Calascibetta Romain Date: Thu, 4 Apr 2024 16:20:40 +0200 Subject: [PATCH 04/17] x509 requires ohex --- x509.opam | 1 + 1 file changed, 1 insertion(+) diff --git a/x509.opam b/x509.opam index 6d415c9a..1714cd6e 100644 --- a/x509.opam +++ b/x509.opam @@ -28,6 +28,7 @@ depends: [ "domain-name" {>= "0.3.0"} "logs" "pbkdf" + "ohex" "ipaddr" {>= "5.2.0"} ] conflicts: [ "result" {< "1.5"} ] From 3dc8b1eecc8f56f8ef12b7681d5795388f5d4351 Mon Sep 17 00:00:00 2001 From: Calascibetta Romain Date: Thu, 4 Apr 2024 17:26:38 +0200 Subject: [PATCH 05/17] Update pin-depends (pbkdf) to fix the CI --- x509.opam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x509.opam b/x509.opam index 1714cd6e..4475763e 100644 --- a/x509.opam +++ b/x509.opam @@ -54,5 +54,5 @@ pin-depends: [ [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] - [ "pbkdf.dev" "git+https://github.com/dinosaure/ocaml-pbkdf.git#5af4644b88774c1ed3288df4b43256b9a6767e01" ] + [ "pbkdf.dev" "git+https://github.com/dinosaure/ocaml-pbkdf.git#0ef32f89cac4091e74d1a0fa34cf417f9b7c70df" ] ] From 099a7ee0d81d8d102dd97bb4791c0bd82ae0aba4 Mon Sep 17 00:00:00 2001 From: Calascibetta Romain Date: Thu, 4 Apr 2024 17:45:18 +0200 Subject: [PATCH 06/17] x509 requires OCaml 4.13 --- x509.opam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x509.opam b/x509.opam index 4475763e..21821a8d 100644 --- a/x509.opam +++ b/x509.opam @@ -12,7 +12,7 @@ homepage: "https://github.com/mirleft/ocaml-x509" doc: "https://mirleft.github.io/ocaml-x509/doc" bug-reports: "https://github.com/mirleft/ocaml-x509/issues" depends: [ - "ocaml" {>= "4.08.0"} + "ocaml" {>= "4.13.0"} "dune" {>= "1.2"} "asn1-combinators" {>= "0.2.0"} "ptime" From 93d267401b377a9b7f814eae397c37d35bd500f5 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Thu, 4 Apr 2024 23:37:48 +0200 Subject: [PATCH 07/17] ecdsa signature encoding: potentially remove superfluous leading 0s --- lib/algorithm.ml | 19 +++++++++++++++++-- tests/ocsp.ml | 8 +++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/algorithm.ml b/lib/algorithm.ml index 140e4c2d..0a7ca79f 100644 --- a/lib/algorithm.ml +++ b/lib/algorithm.ml @@ -415,8 +415,23 @@ let ecdsa_sig = (if r1 = 0x00 then String.sub r' 1 (String.length r' - 1) else r'), (if s1 = 0x00 then String.sub s' 1 (String.length s' - 1) else s') and g (r, s) = - (if String.get_uint8 r 0 > 0x7F then String.make 1 '\x00' ^ r else r), - (if String.get_uint8 s 0 > 0x7F then String.make 1 '\x00' ^ s else s) + let rec strip_leading_0 s off = + if String.length s - off >= 2 then + let s0 = String.get_uint8 s off + and s1 = String.get_uint8 s (off + 1) + in + if s0 = 0x00 && s1 < 0x80 then + strip_leading_0 s (off + 1) + else + String.sub s off (String.length s - off) + else + String.sub s off (String.length s - off) + in + let s = strip_leading_0 s 0 + and r = strip_leading_0 r 0 + in + (if String.get_uint8 r 0 > 0x7F then "\x00" ^ r else r), + (if String.get_uint8 s 0 > 0x7F then "\x00" ^ s else s) in map f g @@ sequence2 diff --git a/tests/ocsp.ml b/tests/ocsp.ml index 11d14d91..499feda8 100644 --- a/tests/ocsp.ml +++ b/tests/ocsp.ml @@ -115,7 +115,13 @@ let test_simple_responder () = | Ok resp -> match OCSP.Response.validate resp (Private_key.public responder_key) with | Ok () -> () - | Error _ -> Alcotest.fail "cannot verify the signature of OCSP response" + | Error e -> + let pp_e ppf = function + | #Validation.signature_error as e -> X509.Validation.pp_signature_error ppf e + | `No_signature -> Fmt.string ppf "no signature" + | `Time_invalid -> Fmt.string ppf "time invalid" + in + Alcotest.failf "cannot verify the signature of OCSP response: %a" pp_e e let tests = [ "OpenSSL request", `Quick, test_request ; From dd49771263758799222887cd0e7c57d6bee72dfa Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Wed, 10 Apr 2024 12:12:31 +0200 Subject: [PATCH 08/17] adapt to recent mirage-crypto API change --- lib/p12.ml | 13 ++++++------- x509.opam | 8 ++++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/p12.ml b/lib/p12.ml index 6bd1d5ad..f180ae2a 100644 --- a/lib/p12.ml +++ b/lib/p12.ml @@ -315,17 +315,16 @@ let pkcs12_decrypt algo password data = let key = pbes hash `Encryption password salt count key_len and iv = pbes hash `Iv password salt count iv_len in + let open Mirage_crypto in let* data = match algo with | SHA_RC2_40_CBC _ | SHA_RC2_128_CBC _ -> Ok (Rc2.decrypt_cbc ~effective:(key_len * 8) ~key ~iv data) | SHA_RC4_40 _ | SHA_RC4_128 _ -> - let open Mirage_crypto.Cipher_stream in let key = ARC4.of_secret key in let { ARC4.message ; _ } = ARC4.decrypt ~key data in Ok message | SHA_3DES_CBC _ -> - let open Mirage_crypto.Cipher_block in let key = DES.CBC.of_secret key in Ok (DES.CBC.decrypt ~key ~iv data) | _ -> Error (`Msg "encryption algorithm not supported") @@ -352,13 +351,13 @@ let pkcs5_2_decrypt kdf enc password data = | _ -> Error (`Msg "expected kdf being pbkdf2") in let key = Pbkdf.pbkdf2 ~prf ~password ~salt ~count ~dk_len in - let key = Mirage_crypto.Cipher_block.AES.CBC.of_secret key in - let msg = Mirage_crypto.Cipher_block.AES.CBC.decrypt ~key ~iv data in + let key = Mirage_crypto.AES.CBC.of_secret key in + let msg = Mirage_crypto.AES.CBC.decrypt ~key ~iv data in Ok (unpad msg) let pkcs5_2_encrypt (mac : [ `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ]) count algo password data = let module Hash = (val (Digestif.module_of_hash' (mac :> Digestif.hash'))) in - let bs = Mirage_crypto.Cipher_block.AES.CBC.block_size in + let bs = Mirage_crypto.AES.CBC.block_size in let iv = Mirage_crypto_rng.generate bs in let enc, dk_len = match algo with @@ -368,10 +367,10 @@ let pkcs5_2_encrypt (mac : [ `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ]) co in let salt = Mirage_crypto_rng.generate Hash.digest_size in let key = Pbkdf.pbkdf2 ~prf:(mac :> Digestif.hash') ~password ~salt ~count ~dk_len in - let key = Mirage_crypto.Cipher_block.AES.CBC.of_secret key in + let key = Mirage_crypto.AES.CBC.of_secret key in let padded_data = pad bs data in let enc_data = - Mirage_crypto.Cipher_block.AES.CBC.encrypt ~key ~iv padded_data + Mirage_crypto.AES.CBC.encrypt ~key ~iv padded_data in let kdf = Algorithm.PBKDF2 (salt, count, None, Algorithm.of_hmac mac) in Algorithm.PBES2 (kdf, enc), enc_data diff --git a/x509.opam b/x509.opam index 21821a8d..99d4de30 100644 --- a/x509.opam +++ b/x509.opam @@ -50,9 +50,9 @@ namely PKCS 1, PKCS 5, PKCS 7, PKCS 8, PKCS 9, PKCS 10, and PKCS 12. """ pin-depends: [ - [ "mirage-crypto.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] - [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] - [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] - [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#918bef0ea7b7b71f02d27205a183ea5a709a7424" ] + [ "mirage-crypto.dev" "git+https://github.com/mirage/mirage-crypto.git#47127ec04403b18216696de5a8a637f7e88ca85e" ] + [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#47127ec04403b18216696de5a8a637f7e88ca85e" ] + [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#47127ec04403b18216696de5a8a637f7e88ca85e" ] + [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#47127ec04403b18216696de5a8a637f7e88ca85e" ] [ "pbkdf.dev" "git+https://github.com/dinosaure/ocaml-pbkdf.git#0ef32f89cac4091e74d1a0fa34cf417f9b7c70df" ] ] From 61ec7d71172ea95da7201a358e2ec729d30e9391 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Tue, 23 Apr 2024 16:19:04 +0100 Subject: [PATCH 09/17] use updated mirage-crypto --- x509.opam | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x509.opam b/x509.opam index 99d4de30..d61be9ed 100644 --- a/x509.opam +++ b/x509.opam @@ -50,9 +50,9 @@ namely PKCS 1, PKCS 5, PKCS 7, PKCS 8, PKCS 9, PKCS 10, and PKCS 12. """ pin-depends: [ - [ "mirage-crypto.dev" "git+https://github.com/mirage/mirage-crypto.git#47127ec04403b18216696de5a8a637f7e88ca85e" ] - [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#47127ec04403b18216696de5a8a637f7e88ca85e" ] - [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#47127ec04403b18216696de5a8a637f7e88ca85e" ] - [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#47127ec04403b18216696de5a8a637f7e88ca85e" ] + [ "mirage-crypto.dev" "git+https://github.com/dinosaure/mirage-crypto.git#81c492efcb8877a383554f2a85bd87fc5e1fa1e1" ] + [ "mirage-crypto-pk.dev" "git+https://github.com/dinosaure/mirage-crypto.git#81c492efcb8877a383554f2a85bd87fc5e1fa1e1" ] + [ "mirage-crypto-ec.dev" "git+https://github.com/dinosaure/mirage-crypto.git#81c492efcb8877a383554f2a85bd87fc5e1fa1e1" ] + [ "mirage-crypto-rng.dev" "git+https://github.com/dinosaure/mirage-crypto.git#81c492efcb8877a383554f2a85bd87fc5e1fa1e1" ] [ "pbkdf.dev" "git+https://github.com/dinosaure/ocaml-pbkdf.git#0ef32f89cac4091e74d1a0fa34cf417f9b7c70df" ] ] From cbe9b610ebc096c42c66c4ae61ba0b5c223e3932 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Tue, 23 Apr 2024 16:31:51 +0100 Subject: [PATCH 10/17] lower asn1 bound is 0.3.0 now --- x509.opam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x509.opam b/x509.opam index d61be9ed..b53ff34f 100644 --- a/x509.opam +++ b/x509.opam @@ -14,7 +14,7 @@ bug-reports: "https://github.com/mirleft/ocaml-x509/issues" depends: [ "ocaml" {>= "4.13.0"} "dune" {>= "1.2"} - "asn1-combinators" {>= "0.2.0"} + "asn1-combinators" {>= "0.3.0"} "ptime" "base64" {>= "3.3.0"} "mirage-crypto" From 22bc5b4c6e87928f940001fdde4500957e905c1a Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Tue, 23 Apr 2024 16:40:32 +0100 Subject: [PATCH 11/17] lower ohex bound --- x509.opam | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x509.opam b/x509.opam index b53ff34f..d984462d 100644 --- a/x509.opam +++ b/x509.opam @@ -28,7 +28,7 @@ depends: [ "domain-name" {>= "0.3.0"} "logs" "pbkdf" - "ohex" + "ohex" {>= "0.2.0"} "ipaddr" {>= "5.2.0"} ] conflicts: [ "result" {< "1.5"} ] From ba89cbf49f5e837c7f7f8ef40c0cffc93690f878 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Tue, 23 Apr 2024 18:12:55 +0100 Subject: [PATCH 12/17] use mirage-crypto at main (since the merge was done) --- x509.opam | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x509.opam b/x509.opam index d984462d..8255cf76 100644 --- a/x509.opam +++ b/x509.opam @@ -50,9 +50,9 @@ namely PKCS 1, PKCS 5, PKCS 7, PKCS 8, PKCS 9, PKCS 10, and PKCS 12. """ pin-depends: [ - [ "mirage-crypto.dev" "git+https://github.com/dinosaure/mirage-crypto.git#81c492efcb8877a383554f2a85bd87fc5e1fa1e1" ] - [ "mirage-crypto-pk.dev" "git+https://github.com/dinosaure/mirage-crypto.git#81c492efcb8877a383554f2a85bd87fc5e1fa1e1" ] - [ "mirage-crypto-ec.dev" "git+https://github.com/dinosaure/mirage-crypto.git#81c492efcb8877a383554f2a85bd87fc5e1fa1e1" ] - [ "mirage-crypto-rng.dev" "git+https://github.com/dinosaure/mirage-crypto.git#81c492efcb8877a383554f2a85bd87fc5e1fa1e1" ] + [ "mirage-crypto.dev" "git+https://github.com/mirage/mirage-crypto.git#38bde3aaaa2faaf07263721139f5ed42bd2f6238" ] + [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#38bde3aaaa2faaf07263721139f5ed42bd2f6238" ] + [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#38bde3aaaa2faaf07263721139f5ed42bd2f6238" ] + [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#38bde3aaaa2faaf07263721139f5ed42bd2f6238" ] [ "pbkdf.dev" "git+https://github.com/dinosaure/ocaml-pbkdf.git#0ef32f89cac4091e74d1a0fa34cf417f9b7c70df" ] ] From 087c0214a2aa669ead6265bd4de0e9f859315606 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Thu, 16 May 2024 15:04:31 +0200 Subject: [PATCH 13/17] algorithm: use unsigned integer, as provided by asn1-combinators 0.3.1 --- lib/algorithm.ml | 35 ++--------------------------------- x509.opam | 2 +- 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/lib/algorithm.ml b/lib/algorithm.ml index 0a7ca79f..ba9bdff9 100644 --- a/lib/algorithm.ml +++ b/lib/algorithm.ml @@ -403,40 +403,9 @@ let identifier = (choice4 null oid pbkdf2_or_pbe_or_pbes2_params octet_string))) let ecdsa_sig = - let f (r', s') = - let r1 = String.get_uint8 r' 0 - and s1 = String.get_uint8 s' 0 - in - if r1 > 0x7F then - Asn.S.parse_error "ECDSA signature: r < 0" - else if s1 > 0x7F then - Asn.S.parse_error "ECDSA signature: s < 0" - else - (if r1 = 0x00 then String.sub r' 1 (String.length r' - 1) else r'), - (if s1 = 0x00 then String.sub s' 1 (String.length s' - 1) else s') - and g (r, s) = - let rec strip_leading_0 s off = - if String.length s - off >= 2 then - let s0 = String.get_uint8 s off - and s1 = String.get_uint8 s (off + 1) - in - if s0 = 0x00 && s1 < 0x80 then - strip_leading_0 s (off + 1) - else - String.sub s off (String.length s - off) - else - String.sub s off (String.length s - off) - in - let s = strip_leading_0 s 0 - and r = strip_leading_0 r 0 - in - (if String.get_uint8 r 0 > 0x7F then "\x00" ^ r else r), - (if String.get_uint8 s 0 > 0x7F then "\x00" ^ s else s) - in - map f g @@ sequence2 - (required ~label:"r" integer) - (required ~label:"s" integer) + (required ~label:"r" unsigned_integer) + (required ~label:"s" unsigned_integer) let ecdsa_sig_of_octets, ecdsa_sig_to_octets = projections_of Asn.der ecdsa_sig diff --git a/x509.opam b/x509.opam index 8255cf76..a949653c 100644 --- a/x509.opam +++ b/x509.opam @@ -14,7 +14,7 @@ bug-reports: "https://github.com/mirleft/ocaml-x509/issues" depends: [ "ocaml" {>= "4.13.0"} "dune" {>= "1.2"} - "asn1-combinators" {>= "0.3.0"} + "asn1-combinators" {>= "0.3.1"} "ptime" "base64" {>= "3.3.0"} "mirage-crypto" From 67562f77e27ad124c476624cab8e6cb95eefc4f5 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Tue, 11 Jun 2024 10:21:20 +0200 Subject: [PATCH 14/17] serial is an unsigned integer now, with a limit of 20 for the octets --- lib/asn_grammars.ml | 12 ++++++++++++ lib/certificate.ml | 18 +++++------------- lib/crl.ml | 6 +++--- lib/extension.ml | 14 ++++++++------ lib/ocsp.ml | 14 +++++--------- lib/rc2.ml | 4 ++-- lib/signing_request.ml | 2 +- lib/x509.mli | 12 ++++++------ tests/ocsp.ml | 10 ++++------ tests/revoke.ml | 14 +++++++------- 10 files changed, 53 insertions(+), 53 deletions(-) diff --git a/lib/asn_grammars.ml b/lib/asn_grammars.ml index 3f3ccd73..8d666cd1 100644 --- a/lib/asn_grammars.ml +++ b/lib/asn_grammars.ml @@ -53,3 +53,15 @@ let generalized_time_no_frac_s = parse_error "generalized time has fractional seconds") (fun y -> Ptime.truncate ~frac_s:0 y) generalized_time) + +(* serial number, as defined in RFC 5280 4.1.2.2: must be > 0 and not be longer than 20 octets + we accept 0. *) +let serial = + Asn.S.(map + (fun x -> + if String.length x > 20 then parse_error "serial exceeds 20 octets"; + x) + (fun y -> + if String.length y > 20 then failwith "serial exceeds 20 octets"; + y) + unsigned_integer) diff --git a/lib/certificate.ml b/lib/certificate.ml index b55915b0..98e8d19c 100644 --- a/lib/certificate.ml +++ b/lib/certificate.ml @@ -3,7 +3,7 @@ *) type tBSCertificate = { version : [ `V1 | `V2 | `V3 ] ; - serial : Z.t ; + serial : string ; signature : Algorithm.t ; issuer : Distinguished_name.t ; validity : Ptime.t * Ptime.t ; @@ -43,12 +43,6 @@ module Asn = struct (function `V3 -> 2 | `V2 -> 1 | `V1 -> 0) int - let certificate_sn = - map - Mirage_crypto_pk.Z_extra.of_octets_be - Mirage_crypto_pk.Z_extra.to_octets_be - integer - let time = let f = function `C1 t -> t | `C2 t -> t and g t = @@ -65,8 +59,7 @@ module Asn = struct let tBSCertificate = let f = fun (a, (b, (c, (d, (e, (f, (g, (h, (i, j))))))))) -> - let extn = match j with None -> Extension.empty | Some xs -> xs - in + let extn = match j with None -> Extension.empty | Some xs -> xs in { version = def `V1 a ; serial = b ; signature = c ; issuer = d ; validity = e ; subject = f ; @@ -78,14 +71,13 @@ module Asn = struct validity = e ; subject = f ; pk_info = g ; issuer_id = h ; subject_id = i ; extensions = j } -> - let extn = if Extension.is_empty j then None else Some j - in + let extn = if Extension.is_empty j then None else Some j in (def' `V1 a, (b, (c, (d, (e, (f, (g, (h, (i, extn))))))))) in map f g @@ sequence @@ (optional ~label:"version" @@ explicit 0 version) (* default v1 *) - @ (required ~label:"serialNumber" @@ certificate_sn) + @ (required ~label:"serialNumber" @@ serial) @ (required ~label:"signature" @@ Algorithm.identifier) @ (required ~label:"issuer" @@ Distinguished_name.Asn.name) @ (required ~label:"validity" @@ validity) @@ -179,7 +171,7 @@ let pp ppf { asn ; _ } = let tbs = asn.tbs_cert in let sigalg = Algorithm.to_signature_algorithm tbs.signature in Fmt.pf ppf "X.509 certificate@.version %a@.serial %a@.algorithm %a@.issuer %a@.valid from %a until %a@.subject %a@.extensions %a" - pp_version tbs.version Z.pp_print tbs.serial + pp_version tbs.version Ohex.pp tbs.serial Fmt.(option ~none:(any "NONE") pp_sigalg) sigalg Distinguished_name.pp tbs.issuer (Ptime.pp_human ~tz_offset_s:0 ()) (fst tbs.validity) diff --git a/lib/crl.ml b/lib/crl.ml index 584fada3..ea14c91c 100644 --- a/lib/crl.ml +++ b/lib/crl.ml @@ -1,5 +1,5 @@ type revoked_cert = { - serial : Z.t ; + serial : string ; date : Ptime.t ; extensions : Extension.t } @@ -34,7 +34,7 @@ module Asn = struct in map f g @@ sequence3 - (required ~label:"userCertificate" @@ Certificate.Asn.certificate_sn) + (required ~label:"userCertificate" @@ serial) (required ~label:"revocationDate" @@ Certificate.Asn.time) (optional ~label:"crlEntryExtensions" @@ Extension.Asn.extensions_der) @@ -187,7 +187,7 @@ let is_revoked ?allowed_hashes ~issuer:super ~cert (crls : t list) = | Ok () -> begin try let entry = List.find - (fun r -> Z.equal (Certificate.serial cert) r.serial) + (fun r -> String.equal (Certificate.serial cert) r.serial) (revoked_certificates crl) in match reason entry with diff --git a/lib/extension.ml b/lib/extension.ml index e7af11a5..d4ee326c 100644 --- a/lib/extension.ml +++ b/lib/extension.ml @@ -51,13 +51,13 @@ let pp_extended_key_usage ppf = function | `Ocsp_signing -> Fmt.string ppf "ocsp signing" | `Other oid -> Asn.OID.pp ppf oid -type authority_key_id = string option * General_name.t * Z.t option +type authority_key_id = string option * General_name.t * string option let pp_authority_key_id ppf (id, issuer, serial) = - Fmt.pf ppf "identifier %a@ issuer %a@ serial %s@ " + Fmt.pf ppf "identifier %a@ issuer %a@ serial %a@ " Fmt.(option ~none:(any "none") Ohex.pp) id General_name.pp issuer - (match serial with None -> "none" | Some x -> Z.to_string x) + Fmt.(option ~none:(any "none") Ohex.pp) serial type priv_key_usage_period = [ | `Interval of Ptime.t * Ptime.t @@ -426,13 +426,15 @@ module Asn = struct (optional ~label:"pathLen" int) let authority_key_id = - map (fun (a, b, c) -> (a, def General_name.empty b, Option.map Mirage_crypto_pk.Z_extra.of_octets_be c)) - (fun (a, b, c) -> (a, def' General_name.empty b, Option.map Mirage_crypto_pk.Z_extra.to_octets_be c)) + map (fun (a, b, c) -> + (a, def General_name.empty b, c)) + (fun (a, b, c) -> + (a, def' General_name.empty b, c)) @@ sequence3 (optional ~label:"keyIdentifier" @@ implicit 0 octet_string) (optional ~label:"authCertIssuer" @@ implicit 1 General_name.Asn.gen_names) - (optional ~label:"authCertSN" @@ implicit 2 integer) + (optional ~label:"authCertSN" @@ implicit 2 serial) let priv_key_usage_period = let f = function diff --git a/lib/ocsp.ml b/lib/ocsp.ml index 2fd3e27f..dbd23894 100644 --- a/lib/ocsp.ml +++ b/lib/ocsp.ml @@ -13,7 +13,7 @@ type cert_id = { hashAlgorithm: Algorithm.t; issuerNameHash: string; issuerKeyHash: string; - serialNumber: Z.t; + serialNumber: string; } let create_cert_id ?(hash=`SHA1) issuer serialNumber = @@ -36,28 +36,24 @@ let pp_cert_id ppf {hashAlgorithm;issuerNameHash;issuerKeyHash;serialNumber} = Algorithm.pp hashAlgorithm Ohex.pp issuerNameHash Ohex.pp issuerKeyHash - Z.pp_print serialNumber + Ohex.pp serialNumber module Asn_common = struct open Asn.S let cert_id = let f (hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber) = - {hashAlgorithm; - issuerNameHash; - issuerKeyHash; - serialNumber= Mirage_crypto_pk.Z_extra.of_octets_be serialNumber;} + {hashAlgorithm; issuerNameHash; issuerKeyHash; serialNumber;} in let g {hashAlgorithm;issuerNameHash;issuerKeyHash;serialNumber;} = - (hashAlgorithm, issuerNameHash, issuerKeyHash, - Mirage_crypto_pk.Z_extra.to_octets_be serialNumber) + (hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber) in map f g @@ sequence4 (required ~label:"hashAlgorithm" Algorithm.identifier) (required ~label:"issuerNameHash" octet_string) (required ~label:"issuerKeyHash" octet_string) - (required ~label:"serialNumber" integer) + (required ~label:"serialNumber" Asn_grammars.serial) end let ( let* ) = Result.bind diff --git a/lib/rc2.ml b/lib/rc2.ml index 417956c8..a6ee183f 100644 --- a/lib/rc2.ml +++ b/lib/rc2.ml @@ -170,6 +170,6 @@ let decrypt_cbc ?(effective = 128) ~key ~iv data = for i = 0 to pred ((l + pred block) / block) do decrypt_one ~key ~data ~off:(i * block) dst done; - Mirage_crypto.Uncommon.xor_into iv dst block; - Mirage_crypto.Uncommon.xor_into data dst ~dst_off:block (l - block); + Mirage_crypto.Uncommon.xor_into iv ~src_off:0 dst ~dst_off:0 block; + Mirage_crypto.Uncommon.xor_into data ~src_off:0 dst ~dst_off:block (l - block); Bytes.unsafe_to_string dst diff --git a/lib/signing_request.ml b/lib/signing_request.ml index d4b42050..7de25fb8 100644 --- a/lib/signing_request.ml +++ b/lib/signing_request.ml @@ -187,7 +187,7 @@ let sign signing_request ~valid_from ~valid_until ?(allowed_hashes = Validation.sha2) ?digest - ?(serial = Mirage_crypto_pk.(Z_extra.gen_r Z.one Z.(one lsl 64))) + ?(serial = Mirage_crypto_rng.generate 10) ?(extensions = Extension.empty) ?(subject = signing_request.asn.info.subject) key issuer = diff --git a/lib/x509.mli b/lib/x509.mli index 8258deaa..057b737c 100644 --- a/lib/x509.mli +++ b/lib/x509.mli @@ -386,7 +386,7 @@ module Extension : sig (** The authority key identifier, as present in the {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.1}Authority Key Identifier} extension. *) - type authority_key_id = string option * General_name.t * Z.t option + type authority_key_id = string option * General_name.t * string option (** The private key usage period, as defined in {{:https://tools.ietf.org/html/rfc3280#section-4.2.1.4}RFC 3280}. *) @@ -559,7 +559,7 @@ module Certificate : sig val issuer : t -> Distinguished_name.t (** [serial certificate] is [sn], the serial number of the [certificate]. *) - val serial : t -> Z.t + val serial : t -> string (** [validity certificate] is [from, until], the validity of the certificate. *) val validity : t -> Ptime.t * Ptime.t @@ -849,7 +849,7 @@ module Signing_request : sig ]} *) val sign : t -> valid_from:Ptime.t -> valid_until:Ptime.t -> ?allowed_hashes:Digestif.hash' list -> - ?digest:Digestif.hash' -> ?serial:Z.t -> ?extensions:Extension.t -> + ?digest:Digestif.hash' -> ?serial:string -> ?extensions:Extension.t -> ?subject:Distinguished_name.t -> Private_key.t -> Distinguished_name.t -> (Certificate.t, Validation.signature_error) result @@ -895,7 +895,7 @@ module CRL : sig {{:https://tools.ietf.org/html/rfc5280#section-5.3}RFC 5280 section 5.3} for allowed extensions (not enforced). *) type revoked_cert = { - serial : Z.t ; + serial : string ; date : Ptime.t ; extensions : Extension.t } @@ -1076,11 +1076,11 @@ module OCSP : sig type cert_id (** [create_cert_id issuer serial] creates cert_id for this serial *) - val create_cert_id : ?hash:[ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ] -> Certificate.t -> Z.t -> + val create_cert_id : ?hash:[ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ] -> Certificate.t -> string -> cert_id (** [cert_id_serial certid] is serial number of this certid *) - val cert_id_serial : cert_id -> Z.t + val cert_id_serial : cert_id -> string (** [pp_cert_id ppf cert_id] pretty prints cert_id *) val pp_cert_id : cert_id Fmt.t diff --git a/tests/ocsp.ml b/tests/ocsp.ml index 499feda8..7c2fe780 100644 --- a/tests/ocsp.ml +++ b/tests/ocsp.ml @@ -43,16 +43,14 @@ let responder_cert = match Certificate.decode_pem (data "certificate.pem") with | Ok c -> c | Error _ -> assert false let responder_dn = Certificate.subject responder_cert -let test1_serial = Z.of_int 0x2710 +let test1_serial = "\x27\x10" let responder_key = match Private_key.decode_pem (data "key.pem") with | Ok k -> k | Error _ -> assert false -let z_testable = Alcotest.testable Z.pp_print Z.equal let cert_dn_testable = Alcotest.testable Distinguished_name.pp Distinguished_name.equal - let test_request () = let open OCSP.Request in match decode_der (data "request.der") with @@ -63,7 +61,7 @@ let test_request () = match cert_ids request with | [certid] -> let serialNumber = OCSP.cert_id_serial certid in - Alcotest.(check z_testable __LOC__ test1_serial serialNumber) + Alcotest.(check string __LOC__ test1_serial serialNumber) | _ -> Alcotest.fail "something wrong with OCSP request" let test_response () = @@ -88,7 +86,7 @@ let test_response () = in let certid = single_response_cert_id response in let serialNumber = OCSP.cert_id_serial certid in - Alcotest.(check z_testable __LOC__ test1_serial serialNumber); + Alcotest.(check string __LOC__ test1_serial serialNumber); Alcotest.(check cert_dn_testable __LOC__ responder responder_dn) let test_simple_responder () = @@ -100,7 +98,7 @@ let test_simple_responder () = let response_logic cert_id = let serial = OCSP.cert_id_serial cert_id in let cert_status = - if Z.equal test1_serial serial then + if String.equal test1_serial serial then `Revoked (now, None) else `Good diff --git a/tests/revoke.ml b/tests/revoke.ml index 538486bd..70287523 100644 --- a/tests/revoke.ml +++ b/tests/revoke.ml @@ -68,7 +68,7 @@ let verify () = let crl () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in - let serial = Z.of_int 42 in + let serial = "\x42" in let issuer = Certificate.subject ca in let cert, _, _ = cert ~serial now false capub capriv issuer in let revoked = { CRL.serial ; date = now ; extensions = Extension.empty } in @@ -85,7 +85,7 @@ let crl () = let verify' () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in - let serial = Z.of_int 42 in + let serial = "\x42" in let issuer = Certificate.subject ca in let ica, ipub, ipriv = cert ~name:"subCA" ~serial now true capub capriv issuer in let cert, _pub, _priv = cert now false ipub ipriv (Certificate.subject ica) in @@ -96,7 +96,7 @@ let verify' () = let crl' () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in - let serial = Z.of_int 42 in + let serial = "\x42" in let issuer = Certificate.subject ca in let ica, ipub, ipriv = cert ~name:"subCA" ~serial now true capub capriv issuer in let cert, _pub, _priv = cert now false ipub ipriv (Certificate.subject ica) in @@ -114,7 +114,7 @@ let crl' () = let crl'leaf () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in - let serial = Z.of_int 42 in + let serial = "\x42" in let ica, ipub, ipriv = cert ~name:"subCA" now true capub capriv (Certificate.subject ca) in let issuer = Certificate.subject ica in let cert, _pub, _priv = cert ~serial now false ipub ipriv issuer in @@ -132,7 +132,7 @@ let crl'leaf () = let crl'leaf'wrong () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in - let serial = Z.of_int 42 in + let serial = "\x42" in let issuer = Certificate.subject ca in let ica, ipub, ipriv = cert ~name:"subCA" now true capub capriv issuer in let cert, _pub, _priv = cert ~serial now false ipub ipriv (Certificate.subject ica) in @@ -149,7 +149,7 @@ let crl'leaf'wrong () = let verify'' () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in - let serial = Z.of_int 42 in + let serial = "\x42" in let issuer = Certificate.subject ca in let ica, ipub, ipriv = cert ~name:"subCA" now true capub capriv issuer in let cert, _pub, _priv = cert now false ipub ipriv (Certificate.subject ica) in @@ -166,7 +166,7 @@ let verify'' () = let crl'' () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in - let serial = Z.of_int 42 in + let serial = "\x42" in let issuer = Certificate.subject ca in let ica, ipub, ipriv = cert ~name:"subCA" ~serial now true capub capriv issuer in let cert, _pub, _priv = cert now false ipub ipriv (Certificate.subject ica) in From 68e7c8a3aabeff3ab94d28d9ec6ad0d51ae4981b Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Tue, 11 Jun 2024 10:36:28 +0200 Subject: [PATCH 15/17] minor changes for mirage-crypto at HEAD --- lib/rc2.ml | 4 ++-- x509.opam | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/rc2.ml b/lib/rc2.ml index a6ee183f..4c02eda1 100644 --- a/lib/rc2.ml +++ b/lib/rc2.ml @@ -170,6 +170,6 @@ let decrypt_cbc ?(effective = 128) ~key ~iv data = for i = 0 to pred ((l + pred block) / block) do decrypt_one ~key ~data ~off:(i * block) dst done; - Mirage_crypto.Uncommon.xor_into iv ~src_off:0 dst ~dst_off:0 block; - Mirage_crypto.Uncommon.xor_into data ~src_off:0 dst ~dst_off:block (l - block); + Mirage_crypto.Uncommon.unsafe_xor_into iv ~src_off:0 dst ~dst_off:0 block; + Mirage_crypto.Uncommon.unsafe_xor_into data ~src_off:0 dst ~dst_off:block (l - block); Bytes.unsafe_to_string dst diff --git a/x509.opam b/x509.opam index a949653c..d8bed3f3 100644 --- a/x509.opam +++ b/x509.opam @@ -50,9 +50,9 @@ namely PKCS 1, PKCS 5, PKCS 7, PKCS 8, PKCS 9, PKCS 10, and PKCS 12. """ pin-depends: [ - [ "mirage-crypto.dev" "git+https://github.com/mirage/mirage-crypto.git#38bde3aaaa2faaf07263721139f5ed42bd2f6238" ] - [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#38bde3aaaa2faaf07263721139f5ed42bd2f6238" ] - [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#38bde3aaaa2faaf07263721139f5ed42bd2f6238" ] - [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#38bde3aaaa2faaf07263721139f5ed42bd2f6238" ] + [ "mirage-crypto.dev" "git+https://github.com/mirage/mirage-crypto.git#98f01b14f5ebf98ba0e7e9c2ba97ec518f90fddc" ] + [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#98f01b14f5ebf98ba0e7e9c2ba97ec518f90fddc" ] + [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#98f01b14f5ebf98ba0e7e9c2ba97ec518f90fddc" ] + [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#98f01b14f5ebf98ba0e7e9c2ba97ec518f90fddc" ] [ "pbkdf.dev" "git+https://github.com/dinosaure/ocaml-pbkdf.git#0ef32f89cac4091e74d1a0fa34cf417f9b7c70df" ] ] From 36fe72e838ec6e46ddbe4770c62b6db83b11a7f0 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Wed, 17 Jul 2024 11:52:20 +0200 Subject: [PATCH 16/17] Remove pin-depends --- x509.opam | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/x509.opam b/x509.opam index d8bed3f3..ab61012a 100644 --- a/x509.opam +++ b/x509.opam @@ -17,7 +17,7 @@ depends: [ "asn1-combinators" {>= "0.3.1"} "ptime" "base64" {>= "3.3.0"} - "mirage-crypto" + "mirage-crypto" {>= "1.0.0"} "mirage-crypto-pk" "mirage-crypto-ec" {>= "0.10.7"} "mirage-crypto-rng" @@ -27,7 +27,7 @@ depends: [ "gmap" {>= "0.3.0"} "domain-name" {>= "0.3.0"} "logs" - "pbkdf" + "pbkdf" {>= "2.0.0"} "ohex" {>= "0.2.0"} "ipaddr" {>= "5.2.0"} ] @@ -48,11 +48,3 @@ The Public Key Cryptography Standards (PKCS) defines encoding and decoding (in ASN.1 DER and PEM format), which is also implemented by this library - namely PKCS 1, PKCS 5, PKCS 7, PKCS 8, PKCS 9, PKCS 10, and PKCS 12. """ - -pin-depends: [ - [ "mirage-crypto.dev" "git+https://github.com/mirage/mirage-crypto.git#98f01b14f5ebf98ba0e7e9c2ba97ec518f90fddc" ] - [ "mirage-crypto-pk.dev" "git+https://github.com/mirage/mirage-crypto.git#98f01b14f5ebf98ba0e7e9c2ba97ec518f90fddc" ] - [ "mirage-crypto-ec.dev" "git+https://github.com/mirage/mirage-crypto.git#98f01b14f5ebf98ba0e7e9c2ba97ec518f90fddc" ] - [ "mirage-crypto-rng.dev" "git+https://github.com/mirage/mirage-crypto.git#98f01b14f5ebf98ba0e7e9c2ba97ec518f90fddc" ] - [ "pbkdf.dev" "git+https://github.com/dinosaure/ocaml-pbkdf.git#0ef32f89cac4091e74d1a0fa34cf417f9b7c70df" ] -] From d280e456c117189cc6e3595a0109dd91dde0f657 Mon Sep 17 00:00:00 2001 From: Calascibetta Romain Date: Wed, 17 Jul 2024 17:11:49 +0200 Subject: [PATCH 17/17] Add a Changes entry about #166 and #167 --- CHANGES.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index e9a01da9..a9fe4cdf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,10 @@ +## v1.0.0 (2024-07-17) + +* **breaking change** Replace `Cstruct.t` by `string` (@dinosaure, @hannesm, #167) +* Remove P224 (@dinosaure, @hannes, #166) +* The serial number of certificates is a `string` and enforced to be a positive + integer of at most 20 bytes in length (@hannesm, #167) + ## v0.16.5 (2023-07-03) * Always embed local_key_id in PKCS12 bags (reported #163 by @NightBlues,