pax_global_header00006660000000000000000000000064144506146140014517gustar00rootroot0000000000000052 comment=b00656d2952282323604765d504dfea067b17879 ocaml-x509-0.16.5/000077500000000000000000000000001445061461400134065ustar00rootroot00000000000000ocaml-x509-0.16.5/.gitignore000066400000000000000000000000431445061461400153730ustar00rootroot00000000000000_build/ *.install .merlin random/ ocaml-x509-0.16.5/CHANGES.md000066400000000000000000000330311445061461400150000ustar00rootroot00000000000000## v0.16.5 (2023-07-03) * Always embed local_key_id in PKCS12 bags (reported #163 by @NightBlues, revised and implemented by @hannesm) ## v0.16.4 (2023-02-13) * Adapt to mirage-crypto-rng 0.11.0 API changes (#162 @hannesm) ## v0.16.3 (2023-02-04) * Validation: allow self-signed server certificate with BasicConstraints CA=true (reported by @mbacarella in mirleft/ocaml-tls#446 (https://github.com/lightningnetwork/lnd/issues/5450), fix #161 by @hannesm) ## v0.16.2 (2022-10-05) * Improve parse error message of Authenticator.of_string (mirage/ocaml-git#593 by @dinosaure, mirage/ocaml-git#582 by @reynir) ## v0.16.1 (2022-09-14) * Support ECDSA signatures where the hash algorithm output length exceeds the size of the elliptic curve (by truncating, and using the leftmost bits). Reported as #158 by @torinnd, fixed in #159 by @hannesm ## v0.16.0 (2022-02-15) * Provide X509.Authenticator.of_string to construct an Authenticator.t from a string (@dinosaure #156, reviewed by @hannesm) * Minor documentation fixes (#157 @hannesm) ## v0.15.2 (2021-11-22) * Provide X509.Private_key.of_string (as used by awa and dns-certify). This takes a b64 encoded raw private key or a seed. (@reynir @hannesm #155) ## v0.15.1 (2021-10-26) * avoid usae of deprecated functions of fmt (@hannesm) * remove rresult dependency (@hannesm) ## v0.15.0 (2021-09-27) * FEATURE support validation of an IP address in the leaf certificate (#152 #153 @reynir @hannesm) * FEATURE provide Certificate.ips and Certificate.supports_ip (#152 @reynir @hannesm) * BREAKING revise certificate and public key fingerprint authenticators API: now a single fingerprint is supported, previously a list of pairs of hostname and fingerprint was used (#153 @hannesm) * BREAKING The Authenticator.t type has been extended with ?ip:Ipaddr.t (#153 @hannesm) ## v0.14.1 (2021-08-04) * Use Cstruct.length instead of deprecated Cstruct.len, bump minimum cstruct to 6.0.0 (#151 by @hannesm) ## v0.14.0 (2021-06-17) * FEATURE support Online Certificate Status Protocol (OCSP, RFC 6960) (#148 @NightBlues, #149 @hannesm) ## v0.13.0 (2021-04-22) * FEATURE support for RFC 5915 "BEGIN EC PRIVATE KEY" pem encoded private keys (#147 @hannesm, requested by @ulrikstrid) * BREAKING remove EC_pub _ from Public_key.t and EC _ from Certificate.key_type (#147 by @hannesm) * BREAKING move Certificate.key_type to Key_type.t (#147 @hannesm) * FEATURE some private key utilities (of_cstruct, generate, sign), and Public_key.verify (#report #146, fix #147 @hannesm) * BREAKING rename hash_whitelist to allowed_hashes (#147 @hannesm) * BREAKING provide Key_type.signature_scheme and use across the API (#147 @hannesm) ## v0.12.0 (2021-04-05) * FEATURE PKCS12 support (#114 by @hannesm) * FEATURE ECDSA and EDDSA support via mirage-crypto-ec (#145 by @hannesm) This breaks some clients since the Private_key.t and Public_key.t variants are extended (may result in partial pattern matches of users of this library). * CRL.is_revoked has `crls` as last parameter to avoid warning 16 (4.12 compatibility) (#144 by @hannesm) * Signing_request.sign: add optional labelled argument `~subject` to allow changing the subject when signing a signing request (#139 by @reynir) * BUGFIX Encoding of Distinguished_name components (adhere to specification) DomainComponent and EMail are now serialised using a IA5String; Serialnumber, CountryName and DnQualifier as PrintableString (reported in #69, fixed #140 by @NightBlues) * BREAKING Remove `~sloppy` from Private_key.decode_{pem,der}. The seemingly bad RSA keys were valid and should have been accepted by mirage-crypto. (#142 by @psafont) ## v0.11.2 (2020-05-14) * Private_key.decode_{pem,der} now has a `~sloppy` option to recover from bad keys (where e.g. the private exponent d is wrong). (#135 by @hannesm, reported by @mattjbray in mirage/mirage-crypto#62) ## v0.11.1 (2020-04-27) * open variant for errors to make the composable (#133 by @dinosaure, review by @hannesm) * BUGFIX avoid fractional seconds in generalized_time: truncate on serialising, validate them to be 0 on deserialising, as required in RFC 5280 4.1.2.5.2 (#134 by @hannesm, reported by @ansiwen) ## v0.11.0 (2020-04-07) * BREAKING Validation.validate_raw_signature results in a `(unit, signature_error) result` and logs (Logs.warn) if a weak (non-SHA2) hash algorithm was used. This function is used for verifying signatures on certificates, signing requests, and certificate revocation lists. * The `` `CAInvalidSelfSignature `` constructor (Validation.ca_error) and `` `ChainInvalidSignature `` constructor (Validation.chain_validation_error) have been removed. * BREAKING The polymorphic variant `Validation.chain_error` is now flat (the tags `` `Chain `` and `` `Leaf `` have been removed) * BREAKING Adapted return type of CRL.validate and CRL.verify * The pretty-printer Public_key.pp is now provided * All implemented by @hannesm in #132 based on private conversation with @cfcs (who kindly reviewed the changes) ## v0.10.0 (2020-03-11) * BREAKING #131 use mirage-crypto and mirage-crypto-pk instead of nocrypto raise lower OCaml bound to 4.07.0, test 4.10.0 in CI * BREAKING #131 Certificate.Host_set is now Host.Set, and has pretty-printers * BREAKING #131 Authenticator.null was removed (fixes #130, suggested by @emillon) * BREAKING #131 Authenticator.t now requires (non-optional) ~host and ~time arguments which may return an option. This allows to more easily spot the cases where None is provided. Also, time is (unit -> Ptime.t option) instead of Ptime.t -- thus the timestamp at the time of certificate verification is used instead of the time of Authenticator construction. Similar changes in Validation for verify_chain, verify_chain_of_trust, trust_key_fingerprint, trust_cert_fingerprint. fixes #130, suggested by @emillon ## v0.9.0 (2020-01-22) * BREAKING add a whitelist of hash algorithms used for signatures. The default whitelist is the SHA-2 family (without SHA-224), Validation.valid_ca{,s} use all algorithms as default reported by @emillon in #123, fixed in #128 * BREAKING Certificate.hostnames and Signing_request.hostnames (new) return a set of [`Wildcard|`Strict] * [`host] Domain_name.t (Certificate.Host_set.t) reported by @mmaker in #88, fixed in #127 * BREAKING #127 Signing_request.sign returns a result type now, an error is returned if the signing request was not properly signed * BREAKING #127 Validation.{verify_chain_of_trust, trust_key_fingerprint, trust_cert_fingerptint} and the type Authenticator.t changed, no longer use of a Certificate.host, but instead a [`host] Domain_name.t (previously, it was a pair) * BUGFIX support AlgorithmIdentifier of RSA signature algorithms with parameter not present reported by @Ulrar in #108, fixed in #129 * BUGFIX #127 preserve a signed signing request (Country in a DN sometimes uses a non-utf8 string encoding) * remove deprecation from Validation.trust_cert_fingerprint and Authenticator.server_cert_fingerprint requested by @mben-romdhane in #125, fixed in #126 * Certificate.signature_algorithm, CRL.signature_algorithm, and Signing_request.signature_algorithm are now provided, returning a ([`RSA|`ECDSA] * Nocrypto.Hash.hash) option requested by @psafont in #123, fixed in #128 ## v0.8.1 (2019-10-10) * export Private_key.decode_der and encode_der ## v0.8.0 (2019-10-10) * export X509.Distinguished_name.common_name : t -> string option, which extracts the common name of a distinguished name * Distinguished_name.t is now a Relative_distinguished_name.t list, a Relative_distinguished_name is a Set.S with element type attribute, a variant. It used to be an attribute (expressed as GADT) Gmap.t, but this representation did not conform to RFC 5280, reported by @paurkedal (#117, fixed by #118) * Now using Set.find_first_opt, which bumps lower OCaml bound to 4.05.0 * Improved pretty-printing for DNs including RFC 4514 conformance (@paurkedal, #119). * Extension.pp now outputs extension key and its value (#120) * rename Distinguished_name.SP constructor (stateOrProvince) to ST, as widely used (#121) * support Street and UID in Distinguished_name to satisfy RFC 4514 demands (#121) ## v0.7.1 (2019-08-09) * revert General_name.t (DNS and IP components) to string/Cstruct.t list - NameConstraints uses DNSname with strings with leading dots (.example.com), which are not valid RFC1034 domain names - NameConstraints uses IP with IP/netmask, i.e. using 8 octets for an IPv4 address - X509.Certificate.hostnames still return a Domain_name.Set.t - reported by @reynir * drop ipaddr dependency ## 0.7.0 (2019-07-24) * major restructuring, it is unlikely any pre-0.7.0 users will work with 0.7.0+ * remove sexp de&encoders * provide pretty-printers for validation errors (and types) instead of to_string functions * use result type and Rresult instead of custom result types and control monad * use a GADT map for certificate & csr extensions, distinguished names, general names (avoiding multiple extensions with the same OID, uses the gmap library) * use domain-name library for hostname validation (instead of custom string matching) * use ipaddr library for IPs in SubjectAlternativeName extension * remove Encoding module, provide {en,de}code_{der,pem} in the respective modules (which decoders return (_, [> `Msg of string ]) result, no exceptions raised) * fix DistributionPoint extension: the CRLissuer is a GeneralName, not a DistinguishedName * remove Extension.reason_code (Extension.reason was there before, and is now used) * remove bindings from toplevel, t is now Certificate.t, public_key is now Public_key.t * use alcotest instead of oUnit ## 0.6.3 (2019-04-02) * provide X509.Encoding.distinguished_name_of_cs -- similar to #87 which provided distinguished_name_to_cs * provide X509.Encoding.{public_key_of_cstruct,public_key_to_cstruct}, as requested by @dinosaure * support of cstruct 4.0.0, which split up the sexp de&encoders * removes result dependency (now requires >= 4.04.2) * upgrades opam file to version 2.0 * build system is now dune ## 0.6.2 (2018-08-24) * compatibility with ppx_sexp_conv >v0.11.0 (#109), required for 4.07.0 ## 0.6.1 (2017-12-21) * provide X509.distinguished_name sexp converter (#103) * drop non-exported X509_types module from distinguished_name (#102, @yomimono) ## 0.6.0 (2017-12-13) * Certificate Revocation List (CRL) support (#99) * track asn1-combinators 0.2.0 changes (#97) * provide Extension.subject_alt_names (#95) * compute length of certificate length, instead of hardcoding 4 (#95) * enable safe-string (#89) * use astring instead of custom String_ext.split (#89) * use topkg instead of oasis (#88, #89) * provide Encoding.cs_of_distinguished_name (#87 by @reynir) ## 0.5.3 (2016-09-13) * provide Encoding.parse_signing_request and Encoding.cs_of_signing_request (#81) * provide validity : t -> (Time.t * Time.t) (#86, fixes #85) ## 0.5.2 (2016-04-13) * fix building of certificate paths ## 0.5.1 (2016-03-21) * use ppx_sexp_conv instead of sexplib.syntax * no more Stream syntax, use lists ## 0.5.0 (2015-12-04) * avoid dependency on sexplib.syntax (#55) * document how to combine extensions and a CSR into a certificate (@reynir, #63 #64) * expose `fingerprint : t -> hash -> Cstruct.t`, the hash of the certificate (@cfcs, #66) * trust_fingerprint / server_fingerprint are renamed to trust_cert_fingerprint / server_cert_fingerprint (now deprecated!) * fingerprint public keys (rather than certificates): trust_key_fingerprint / server_key_fingerprint * build certificate paths from the received set (RFC 4158) instead of requiring a strict chain (#74) * the given trust anchors to `Authenticator.chain_of_trust` are not validated (to contain KeyUsage / BasicConstraint extensions) anymore, users can use `valid_ca` and `valid_cas` to filter CAs upfront ## 0.4.0 (2015-07-02) * certificate signing request support (PKCS10) * basic CA functionality (in CA module): create and sign certificate signing requests * PEM encoding of X.509 certificates, RSA public and private keys, and certificate signing requests * new module Extension contains X509v3 extensions as polymorphic variants * expose distinguished_name as polymorphic variant * type pubkey is now public_key * function cert_pubkey is now public_key * functions supports_usage, supports_extended_usage are now in Extension module * types key_usage, extended_key_usage are now in Extension module * Encoding.Pem.Cert has been renamed to Encoding.Pem.Certificate * Encoding.Pem.PK has been renamed to Encoding.Pem.Private_key (now uses type private_key instead of Nocrypto.Rsa.priv) ## 0.3.1 (2015-05-02) * PKCS8 private key info support (only unencrypted keys so far) ## 0.3.0 (2015-03-19) * more detailed error messages (type certificate_failure modified) * no longer Printf.printf debug messages * error reporting: `Ok of certificate option | `Fail of certificate_failure * fingerprint verification can work with None as host (useful for client authentication where host is not known upfront) * API reshape: X509 is the only public module, X509.t is the abstract certificate ## 0.2.1 (2014-12-21) * server_fingerprint authenticator which validates the server certificate based on a hash algorithm and (server_name * fingerprint) list instead of a set of trust anchors * whitelist CAcert certificates (which do not include mandatory X.509v3 KeyUsage extension) ## 0.2.0 (2014-10-30) * expose Certificate.cert_hostnames, wildcard_matches * Certificate.verify_chain_of_trust and X509.authenticate both return now [ `Ok of certificate | `Fail of certificate_failure ], where [certificate] is the trust anchor ## 0.1.0 (2014-07-08) * initial beta release ocaml-x509-0.16.5/LICENSE.md000066400000000000000000000024421445061461400150140ustar00rootroot00000000000000Copyright (c) 2014, David Kaloper and Hannes Mehnert All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.ocaml-x509-0.16.5/README.md000066400000000000000000000016501445061461400146670ustar00rootroot00000000000000## X.509 - Public Key Infrastructure purely in OCaml %%VERSION%% X.509 is a public key infrastructure used mostly on the Internet. It consists of certificates which include public keys and identifiers, signed by an authority. Authorities must be exchanged over a second channel to establish the trust relationship. This library implements most parts of [RFC5280](https://tools.ietf.org/html/rfc5280) and [RFC6125](https://tools.ietf.org/html/rfc6125). The [Public Key Cryptography Standards (PKCS)](https://en.wikipedia.org/wiki/PKCS) defines encoding and decoding in ASN.1 DER and PEM format, which is also implemented by this library - namely PKCS 1, PKCS 7, PKCS 8, PKCS 9 and PKCS 10. Read [further](https://nqsb.io) and our [Usenix Security 2015 paper](https://usenix15.nqsb.io). ## Documentation [API documentation](https://mirleft.github.io/ocaml-x509/doc) ## Installation `opam install x509` will install this library. ocaml-x509-0.16.5/dune-project000066400000000000000000000000341445061461400157250ustar00rootroot00000000000000(lang dune 1.2) (name x509) ocaml-x509-0.16.5/lib/000077500000000000000000000000001445061461400141545ustar00rootroot00000000000000ocaml-x509-0.16.5/lib/algorithm.ml000066400000000000000000000365701445061461400165070ustar00rootroot00000000000000open Asn.S open Asn_grammars (* This type really conflates three things: the set of pk algos that describe * the public key, the set of hashes, and the set of hash+pk algo combinations * that describe digests. The three are conflated because they are generated by * the same ASN grammar, AlgorithmIdentifier, to keep things close to the * standards. * * It's expected that downstream code with pick a subset and add a catch-all * that handles unsupported algos anyway. *) type ec_curve = [ `SECP224R1 | `SECP256R1 | `SECP384R1 | `SECP521R1 ] let ec_curve_to_string = function | `SECP224R1 -> "SECP224R1" | `SECP256R1 -> "SECP256R1" | `SECP384R1 -> "SECP384R1" | `SECP521R1 -> "SECP521R1" type t = (* pk algos *) (* any more? is the universe big enough? ramsey's theorem for pk cyphers? *) | RSA | EC_pub of ec_curve (* sig algos *) | MD2_RSA | MD4_RSA | MD5_RSA | RIPEMD160_RSA | SHA1_RSA | SHA256_RSA | SHA384_RSA | SHA512_RSA | SHA224_RSA | ECDSA_SHA1 | ECDSA_SHA224 | ECDSA_SHA256 | ECDSA_SHA384 | ECDSA_SHA512 | ED25519 (* digest algorithms *) | MD2 | MD4 | MD5 | SHA1 | SHA256 | SHA384 | SHA512 | SHA224 | SHA512_224 | SHA512_256 (* HMAC algorithms *) | HMAC_SHA1 | HMAC_SHA224 | HMAC_SHA256 | HMAC_SHA384 | HMAC_SHA512 (* symmetric block ciphers *) | AES128_CBC of Cstruct.t | AES192_CBC of Cstruct.t | AES256_CBC of Cstruct.t (* 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 | PBES2 of t * t let to_string = function | RSA -> "RSA" | EC_pub curve -> ec_curve_to_string curve | MD2_RSA -> "RSA MD2" | MD4_RSA -> "RSA MD4" | MD5_RSA -> "RSA MD5" | RIPEMD160_RSA -> "RSA RIPEMD160" | SHA1_RSA -> "RSA SHA1" | SHA256_RSA -> "RSA SHA256" | SHA384_RSA -> "RSA SHA384" | SHA512_RSA -> "RSA SHA512" | SHA224_RSA -> "RSA SHA224" | ECDSA_SHA1 -> "ECDSA SHA1" | ECDSA_SHA224 -> "ECDSA SHA224" | ECDSA_SHA256 -> "ECDSA SHA256" | ECDSA_SHA384 -> "ECDSA SHA384" | ECDSA_SHA512 -> "ECDSA SHA512" | ED25519 -> "Ed25519" | MD2 -> "MD2" | MD4 -> "MD4" | MD5 -> "MD5" | SHA1 -> "SHA1" | SHA256 -> "SHA256" | SHA384 -> "SHA384" | SHA512 -> "SHA512" | SHA224 -> "SHA224" | SHA512_224 -> "SHA512/224" | SHA512_256 -> "SHA512/256" | HMAC_SHA1 -> "HMAC SHA1" | HMAC_SHA224 -> "HMAC SHA224" | HMAC_SHA256 -> "HMAC SHA256" | HMAC_SHA384 -> "HMAC SHA384" | HMAC_SHA512 -> "HMAC SHA512" | AES128_CBC _ -> "AES128 CBC" | AES192_CBC _ -> "AES192 CBC" | AES256_CBC _ -> "AES256 CBC" | SHA_RC4_128 (_, _) -> "PBES: SHA RC4 128" | SHA_RC4_40 (_, _) -> "PBES: SHA RC4 40" | SHA_3DES_CBC (_, _) -> "PBES: SHA 3DES CBC" | SHA_2DES_CBC (_, _) -> "PBES: SHA 2DES CBC" | SHA_RC2_128_CBC (_, _) -> "PBES: SHA RC2 128" | SHA_RC2_40_CBC (_, _) -> "PBES: SHA RC2 40" | PBKDF2 (_, _, _, _) -> "PBKDF2" | PBES2 (_, _) -> "PBES2" let to_hash = function | MD5 -> Some `MD5 | SHA1 -> Some `SHA1 | SHA224 -> Some `SHA224 | SHA256 -> Some `SHA256 | SHA384 -> Some `SHA384 | SHA512 -> Some `SHA512 | _ -> None and of_hash = function | `MD5 -> MD5 | `SHA1 -> SHA1 | `SHA224 -> SHA224 | `SHA256 -> SHA256 | `SHA384 -> SHA384 | `SHA512 -> SHA512 and to_hmac = function | HMAC_SHA1 -> Some `SHA1 | HMAC_SHA224 -> Some `SHA224 | HMAC_SHA256 -> Some `SHA256 | HMAC_SHA384 -> Some `SHA384 | HMAC_SHA512 -> Some `SHA512 | _ -> None and of_hmac = function | `SHA1 -> HMAC_SHA1 | `SHA224 -> HMAC_SHA224 | `SHA256 -> HMAC_SHA256 | `SHA384 -> HMAC_SHA384 | `SHA512 -> HMAC_SHA512 and to_key_type = function | RSA -> Some `RSA | EC_pub curve -> Some (`EC curve) | ED25519 -> Some `ED25519 | _ -> None and of_key_type = function | `RSA -> RSA | `EC curve -> EC_pub curve | `ED25519 -> ED25519 (* XXX: No MD2 / MD4 / RIPEMD160 *) and to_signature_algorithm = function | MD5_RSA -> Some (`RSA_PKCS1, `MD5) | SHA1_RSA -> Some (`RSA_PKCS1, `SHA1) | SHA256_RSA -> Some (`RSA_PKCS1, `SHA256) | SHA384_RSA -> Some (`RSA_PKCS1, `SHA384) | SHA512_RSA -> Some (`RSA_PKCS1, `SHA512) | SHA224_RSA -> Some (`RSA_PKCS1, `SHA224) | ECDSA_SHA1 -> Some (`ECDSA, `SHA1) | ECDSA_SHA224 -> Some (`ECDSA, `SHA224) | ECDSA_SHA256 -> Some (`ECDSA, `SHA256) | ECDSA_SHA384 -> Some (`ECDSA, `SHA384) | ECDSA_SHA512 -> Some (`ECDSA, `SHA512) | ED25519 -> Some (`ED25519, `SHA512) | _ -> None and of_signature_algorithm public_key_algorithm digest = match public_key_algorithm, digest with | (`RSA_PKCS1, `MD5) -> MD5_RSA | (`RSA_PKCS1, `SHA1) -> SHA1_RSA | (`RSA_PKCS1, `SHA256) -> SHA256_RSA | (`RSA_PKCS1, `SHA384) -> SHA384_RSA | (`RSA_PKCS1, `SHA512) -> SHA512_RSA | (`RSA_PKCS1, `SHA224) -> SHA224_RSA | (`ECDSA, `SHA1) -> ECDSA_SHA1 | (`ECDSA, `SHA224) -> ECDSA_SHA224 | (`ECDSA, `SHA256) -> ECDSA_SHA256 | (`ECDSA, `SHA384) -> ECDSA_SHA384 | (`ECDSA, `SHA512) -> ECDSA_SHA512 | (`ED25519, _) -> ED25519 | _ -> failwith "unsupported signature scheme and hash" (* XXX * * PKCS1/RFC5280 allows params to be `ANY', depending on the algorithm. I don't * know of one that uses anything other than NULL and OID, however, so we accept * only that. RFC 3279 Section 2.2.1 defines for RSA Signature Algorithms SHALL have null as parameter, but certificates in the wild don't contain the parameter field at all (it is optional). We accept both, and output a null paramter. Section 2.2.2 specifies DSA to have a null parameter, Section 2.2.3 specifies ECDSA to have a null parameter, Section 2.3.1 specifies rsaEncryption (for RSA public keys) requires null. *) 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) let identifier = let open Registry in let f = let none x = function | None -> x | _ -> parse_error "Algorithm: expected no parameters" and null x = function | Some (`C1 ()) -> x | _ -> parse_error "Algorithm: expected null parameters" and null_or_none x = function | None | Some (`C1 ()) -> x | _ -> parse_error "Algorithm: expected null or none parameter" and oid f = function | Some (`C2 id) -> f id | _ -> parse_error "Algorithm: expected parameter OID" and pbe f = function | Some (`C3 `PBE pbe) -> f pbe | _ -> parse_error "Algorithm: expected parameter PBE" and pbkdf2 f = function | Some (`C3 `PBKDF2 params) -> f params | _ -> parse_error "Algorithm: expected parameter PBKDF2" and pbes2 f = function | Some (`C3 `PBES2 params) -> f params | _ -> parse_error "Algorithm: expected parameter PBES2" and octets f = function | Some (`C4 salt) -> f salt | _ -> parse_error "Algorithm: expected parameter octet_string" and default oid = Asn.(S.parse_error "Unknown algorithm %a" OID.pp oid) in case_of_oid_f ~default [ (ANSI_X9_62.ec_pub_key, oid (fun id -> EC_pub (curve_of_oid id))) ; (PKCS1.rsa_encryption , null RSA ) ; (PKCS1.md2_rsa_encryption , null_or_none MD2_RSA ) ; (PKCS1.md4_rsa_encryption , null_or_none MD4_RSA ) ; (PKCS1.md5_rsa_encryption , null_or_none MD5_RSA ) ; (PKCS1.ripemd160_rsa_encryption, null_or_none RIPEMD160_RSA) ; (PKCS1.sha1_rsa_encryption , null_or_none SHA1_RSA ) ; (PKCS1.sha256_rsa_encryption , null_or_none SHA256_RSA ) ; (PKCS1.sha384_rsa_encryption , null_or_none SHA384_RSA ) ; (PKCS1.sha512_rsa_encryption , null_or_none SHA512_RSA ) ; (PKCS1.sha224_rsa_encryption , null_or_none SHA224_RSA ) ; (ANSI_X9_62.ecdsa_sha1 , none ECDSA_SHA1 ) ; (ANSI_X9_62.ecdsa_sha224 , none ECDSA_SHA224 ) ; (ANSI_X9_62.ecdsa_sha256 , none ECDSA_SHA256 ) ; (ANSI_X9_62.ecdsa_sha384 , none ECDSA_SHA384 ) ; (ANSI_X9_62.ecdsa_sha512 , none ECDSA_SHA512 ) ; (RFC8410.ed25519 , none ED25519 ) ; (md2 , null MD2 ) ; (md4 , null MD4 ) ; (md5 , null MD5 ) ; (sha1 , null SHA1 ) ; (sha256 , null SHA256 ) ; (sha384 , null SHA384 ) ; (sha512 , null SHA512 ) ; (sha224 , null SHA224 ) ; (sha512_224 , null SHA512_224 ) ; (sha512_256 , null SHA512_256 ) ; (PKCS2.hmac_sha1 , null HMAC_SHA1 ); (PKCS2.hmac_sha224 , null HMAC_SHA224 ); (PKCS2.hmac_sha256 , null HMAC_SHA256 ); (PKCS2.hmac_sha384 , null HMAC_SHA384 ); (PKCS2.hmac_sha512 , null HMAC_SHA512 ); (PKCS5.aes128_cbc , octets (fun iv -> AES128_CBC iv)); (PKCS5.aes192_cbc , octets (fun iv -> AES192_CBC iv)); (PKCS5.aes256_cbc , octets (fun iv -> AES256_CBC iv)); (PKCS12.pbe_with_SHA_and_128Bit_RC4, pbe (fun (s, i) -> SHA_RC4_128 (s, i))) ; (PKCS12.pbe_with_SHA_and_40Bit_RC4, pbe (fun (s, i) -> SHA_RC4_40 (s, i))) ; (PKCS12.pbe_with_SHA_and_3_KeyTripleDES_CBC, pbe (fun (s, i) -> SHA_3DES_CBC (s, i))) ; (PKCS12.pbe_with_SHA_and_2_KeyTripleDES_CBC, pbe (fun (s, i) -> SHA_2DES_CBC (s, i))) ; (PKCS12.pbe_with_SHA_and_128Bit_RC2_CBC, pbe (fun (s, i) -> SHA_RC2_128_CBC (s, i))) ; (PKCS12.pbe_with_SHA_and_40Bit_RC2_CBC, pbe (fun (s, i) -> SHA_RC2_40_CBC (s, i))) ; (PKCS5.pbkdf2, pbkdf2 (fun (s, i, l, m) -> PBKDF2 (s, i, l, m))) ; (PKCS5.pbes2, pbes2 (fun (oid, oid') -> PBES2 (oid, oid'))) ] and g = let none = None and null = Some (`C1 ()) and oid id = Some (`C2 id) and pbe (s, i) = Some (`C3 (`PBE (s, i))) and pbkdf2 (s, i, k, m) = Some (`C3 (`PBKDF2 (s, i, k, m))) and pbes2 (oid, oid') = Some (`C3 (`PBES2 (oid, oid'))) and octets data = Some (`C4 data) in function | EC_pub id -> (ANSI_X9_62.ec_pub_key , oid (curve_to_oid id)) | RSA -> (PKCS1.rsa_encryption , null) | MD2_RSA -> (PKCS1.md2_rsa_encryption , null) | MD4_RSA -> (PKCS1.md4_rsa_encryption , null) | MD5_RSA -> (PKCS1.md5_rsa_encryption , null) | RIPEMD160_RSA -> (PKCS1.ripemd160_rsa_encryption , null) | SHA1_RSA -> (PKCS1.sha1_rsa_encryption , null) | SHA256_RSA -> (PKCS1.sha256_rsa_encryption , null) | SHA384_RSA -> (PKCS1.sha384_rsa_encryption , null) | SHA512_RSA -> (PKCS1.sha512_rsa_encryption , null) | SHA224_RSA -> (PKCS1.sha224_rsa_encryption , null) | ECDSA_SHA1 -> (ANSI_X9_62.ecdsa_sha1 , none) | ECDSA_SHA224 -> (ANSI_X9_62.ecdsa_sha224 , none) | ECDSA_SHA256 -> (ANSI_X9_62.ecdsa_sha256 , none) | ECDSA_SHA384 -> (ANSI_X9_62.ecdsa_sha384 , none) | ECDSA_SHA512 -> (ANSI_X9_62.ecdsa_sha512 , none) | ED25519 -> (RFC8410.ed25519 , none) | MD2 -> (md2 , null) | MD4 -> (md4 , null) | MD5 -> (md5 , null) | SHA1 -> (sha1 , null) | SHA256 -> (sha256 , null) | SHA384 -> (sha384 , null) | SHA512 -> (sha512 , null) | SHA224 -> (sha224 , null) | SHA512_224 -> (sha512_224 , null) | SHA512_256 -> (sha512_256 , null) | HMAC_SHA1 -> (PKCS2.hmac_sha1 , null) | HMAC_SHA224 -> (PKCS2.hmac_sha224 , null) | HMAC_SHA256 -> (PKCS2.hmac_sha256 , null) | HMAC_SHA384 -> (PKCS2.hmac_sha384 , null) | HMAC_SHA512 -> (PKCS2.hmac_sha512 , null) | AES128_CBC iv -> (PKCS5.aes128_cbc , octets iv) | AES192_CBC iv -> (PKCS5.aes192_cbc , octets iv) | AES256_CBC iv -> (PKCS5.aes256_cbc , octets iv) | SHA_RC4_128 (s, i) -> (PKCS12.pbe_with_SHA_and_128Bit_RC4, pbe (s, i)) | SHA_RC4_40 (s, i) -> (PKCS12.pbe_with_SHA_and_40Bit_RC4, pbe (s, i)) | SHA_3DES_CBC (s, i) -> (PKCS12.pbe_with_SHA_and_3_KeyTripleDES_CBC, pbe (s, i)) | SHA_2DES_CBC (s, i) -> (PKCS12.pbe_with_SHA_and_2_KeyTripleDES_CBC, pbe (s, i)) | SHA_RC2_128_CBC (s, i) -> (PKCS12.pbe_with_SHA_and_128Bit_RC2_CBC, pbe (s, i)) | SHA_RC2_40_CBC (s, i) -> (PKCS12.pbe_with_SHA_and_40Bit_RC2_CBC, pbe (s, i)) | PBKDF2 (s, i, k, m) -> (PKCS5.pbkdf2, pbkdf2 (s, i, k, m)) | PBES2 (oid, oid') -> (PKCS5.pbes2, pbes2 (oid, oid')) in fix (fun id -> let pbkdf2_or_pbe_or_pbes2_params = (* TODO PBKDF2 should support `C2 oid (saltSources) *) let f (salt, count, (* key_len, *) prf) = match salt, count, (* key_len, *) prf with | `C1 salt, Some count, (* None, *) None -> `PBE (salt, count) | `C1 salt, Some count, (* x, *) Some prf -> `PBKDF2 (salt, count, None, prf) | `C2 oid, None, (* None, *) Some oid' -> `PBES2 (oid, oid') | _ -> parse_error "bad parameters" and g = function | `PBE (salt, count) -> (`C1 salt, Some count, (* None, *) None) | `PBKDF2 (salt, count, _key_len, prf) -> (`C1 salt, Some count, (* key_len, *) Some prf) | `PBES2 (oid, oid') -> (`C2 oid, None, (* None, *) Some oid') in map f g @@ sequence3 (required ~label:"salt" (choice2 octet_string id)) (optional ~label:"iteration count" int) (* modified - required for pbkdf2/pbes *) (* (optional ~label:"key length" int) (* should be there and optional *) *) (optional ~label:"prf" id) (* only present in pbkdf2 / pbes2 *) in map f g @@ sequence2 (required ~label:"algorithm" oid) (optional ~label:"params" (choice4 null oid pbkdf2_or_pbe_or_pbes2_params octet_string))) let ecdsa_sig = let f (r, s) = 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 in map f g @@ sequence2 (required ~label:"r" integer) (required ~label:"s" integer) let ecdsa_sig_of_cstruct, ecdsa_sig_to_cstruct = projections_of Asn.der ecdsa_sig let pp fmt x = Fmt.string fmt (to_string x) ocaml-x509-0.16.5/lib/asn_grammars.ml000066400000000000000000000033361445061461400171650ustar00rootroot00000000000000let def x = function None -> x | Some y -> y let def' x = fun y -> if y = x then None else Some y 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") let projections_of encoding asn = let c = Asn.codec encoding asn in (decode c, Asn.encode c) module Hashtbl(T : Hashtbl.HashedType) = struct include Hashtbl.Make (T) let of_assoc xs = let ht = create 16 in List.iter (fun (a, b) -> add ht a b) xs; ht end module OID_H = Hashtbl (struct type t = Asn.oid let (equal, hash) = Asn.OID.(equal, hash) end) let case_of_oid ~default xs = let ht = OID_H.of_assoc xs in fun a -> try OID_H.find ht a with Not_found -> default a let case_of_oid_f ~default xs = let ht = OID_H.of_assoc xs in fun (a, b) -> (try OID_H.find ht a with Not_found -> default a) b (* * A way to parse by propagating (and contributing to) exceptions, so those can * be handles up in a single place. Meant for parsing embedded structures. * * XXX Would be nicer if combinators could handle embedded structures. *) let project_exn asn = let c = Asn.(codec der) asn in let dec cs = match decode c cs with | Ok a -> a | Error err -> Asn.S.error err in (dec, Asn.encode c) let err_to_msg f = Result.map_error (function `Parse msg -> `Msg msg) f (* specified in RFC 5280 4.1.2.5.2 - "MUST NOT include fractional seconds" *) let generalized_time_no_frac_s = Asn.S.(map (fun x -> if Ptime.Span.(equal zero (Ptime.frac_s x)) then x else parse_error "generalized time has fractional seconds") (fun y -> Ptime.truncate ~frac_s:0 y) generalized_time) ocaml-x509-0.16.5/lib/authenticator.ml000066400000000000000000000065441445061461400173710ustar00rootroot00000000000000let ( let* ) = Result.bind type t = ?ip:Ipaddr.t -> host:[`host] Domain_name.t option -> Certificate.t list -> Validation.r (* XXX * Authenticator just hands off a list of certs. Should be indexed. * *) let chain_of_trust ~time ?crls ?(allowed_hashes = Validation.sha2) cas = let revoked = match crls with | None -> None | Some crls -> Some (Crl.is_revoked crls ~allowed_hashes) in fun ?ip ~host certificates -> Validation.verify_chain_of_trust ?ip ~host ~time ?revoked ~allowed_hashes ~anchors:cas certificates let server_key_fingerprint ~time ~hash ~fingerprint = fun ?ip ~host certificates -> Validation.trust_key_fingerprint ?ip ~host ~time ~hash ~fingerprint certificates let server_cert_fingerprint ~time ~hash ~fingerprint = fun ?ip ~host certificates -> Validation.trust_cert_fingerprint ?ip ~host ~time ~hash ~fingerprint certificates let hash_of_string = function | "sha224" -> Ok `SHA224 | "sha256" -> Ok `SHA256 | "sha384" -> Ok `SHA384 | "sha512" -> Ok `SHA512 | hash -> Error (`Msg (Fmt.str "Unknown hash algorithm %S" hash)) let fingerprint_of_string s = let* d = Result.map_error (function `Msg m -> `Msg (Fmt.str "Invalid base64 encoding in fingerprint (%s): %S" m s)) (Base64.decode ~pad:false s) in Ok (Cstruct.of_string d) let format = {| The format of an authenticator is: - [none]: no authentication - [key-fp(:?):]: to authenticate a peer via its key fingerprintf (hash is optional and defaults to SHA256) - [cert-fp(:?):]: to authenticate a peer via its certificate fingerprint (hash is optional and defaults to SHA256) - [trust-anchor(:)+] to authenticate a peer from a list of certificates (certificate must be in PEM format witthout header and footer (----BEGIN CERTIFICATE----) and without newlines). |} let of_string str = begin match String.split_on_char ':' str with | [ "key-fp" ; hash ; tls_key_fingerprint ] -> let* hash = hash_of_string (String.lowercase_ascii hash) in let* fingerprint = fingerprint_of_string tls_key_fingerprint in Ok (fun time -> server_key_fingerprint ~time ~hash ~fingerprint) | [ "key-fp" ; tls_key_fingerprint ] -> let* fingerprint = fingerprint_of_string tls_key_fingerprint in Ok (fun time -> server_key_fingerprint ~time ~hash:`SHA256 ~fingerprint) | [ "cert-fp" ; hash ; tls_cert_fingerprint ] -> let* hash = hash_of_string (String.lowercase_ascii hash) in let* fingerprint = fingerprint_of_string tls_cert_fingerprint in Ok (fun time -> server_cert_fingerprint ~time ~hash ~fingerprint) | [ "cert-fp" ; tls_cert_fingerprint ] -> let* fingerprint = fingerprint_of_string tls_cert_fingerprint in Ok (fun time -> server_cert_fingerprint ~time ~hash:`SHA256 ~fingerprint) | "trust-anchor" :: certs -> let* anchors = 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 Ok (cert :: acc)) (Ok []) certs in Ok (fun time -> chain_of_trust ~time (List.rev anchors)) | [ "none" ] -> Ok (fun _ ?ip:_ ~host:_ _ -> Ok None) | _ -> Error (`Msg (Fmt.str "Invalid TLS authenticator: %S" str)) end |> Result.map_error (function `Msg e -> `Msg (e ^ format)) ocaml-x509-0.16.5/lib/certificate.ml000066400000000000000000000203271445061461400167740ustar00rootroot00000000000000(* * X509 certs *) type tBSCertificate = { version : [ `V1 | `V2 | `V3 ] ; serial : Z.t ; signature : Algorithm.t ; issuer : Distinguished_name.t ; validity : Ptime.t * Ptime.t ; subject : Distinguished_name.t ; pk_info : Public_key.t ; issuer_id : Cstruct.t option ; subject_id : Cstruct.t option ; extensions : Extension.t } type certificate = { tbs_cert : tBSCertificate ; signature_algo : Algorithm.t ; signature_val : Cstruct.t } (* * There are two reasons to carry Cstruct.t around: * - we still need to hack on the cstruct 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 * the asn parser and writer respectively, but until then there needs to be one * place that hides the existence of this pair. *) type t = { asn : certificate ; raw : Cstruct.t } module Asn = struct open Asn.S open Asn_grammars let version = map (function 2 -> `V3 | 1 -> `V2 | 0 -> `V1 | _ -> parse_error "unknown version") (function `V3 -> 2 | `V2 -> 1 | `V1 -> 0) int let certificate_sn = integer let time = let f = function `C1 t -> t | `C2 t -> t and g t = let (y, _, _) = Ptime.to_date t in if y < 2050 then `C1 t else `C2 t in map f g (choice2 utc_time generalized_time_no_frac_s) let validity = sequence2 (required ~label:"not before" time) (required ~label:"not after" time) let unique_identifier = bit_string_cs 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 { version = def `V1 a ; serial = b ; signature = c ; issuer = d ; validity = e ; subject = f ; pk_info = g ; issuer_id = h ; subject_id = i ; extensions = extn } and g = fun { version = a ; serial = b ; signature = c ; issuer = d ; 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 (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:"signature" @@ Algorithm.identifier) @ (required ~label:"issuer" @@ Distinguished_name.Asn.name) @ (required ~label:"validity" @@ validity) @ (required ~label:"subject" @@ Distinguished_name.Asn.name) @ (required ~label:"subjectPKInfo" @@ Public_key.Asn.pk_info_der) (* if present, version is v2 or v3 *) @ (optional ~label:"issuerUID" @@ implicit 1 unique_identifier) (* if present, version is v2 or v3 *) @ (optional ~label:"subjectUID" @@ implicit 2 unique_identifier) (* v3 if present *) -@ (optional ~label:"extensions" @@ explicit 3 Extension.Asn.extensions_der) let (tbs_certificate_of_cstruct, tbs_certificate_to_cstruct) = projections_of Asn.der tBSCertificate let certificate = let f (a, b, c) = if a.signature <> b then parse_error "signatureAlgorithm != tbsCertificate.signature" else { tbs_cert = a; signature_algo = b; signature_val = c } and g { tbs_cert = a; signature_algo = b; signature_val = c } = (a, b, c) in map f g @@ sequence3 (required ~label:"tbsCertificate" tBSCertificate) (required ~label:"signatureAlgorithm" Algorithm.identifier) (required ~label:"signatureValue" bit_string_cs) let (certificate_of_cstruct, certificate_to_cstruct) = projections_of Asn.der certificate let pkcs1_digest_info = let open Algorithm in let f (algo, cs) = match to_hash algo with | Some h -> (h, cs) | None -> parse_error "pkcs1 digest info: unknown hash" and g (h, cs) = (of_hash h, cs) in map f g @@ sequence2 (required ~label:"digestAlgorithm" Algorithm.identifier) (required ~label:"digest" octet_string) let (pkcs1_digest_info_of_cstruct, pkcs1_digest_info_to_cstruct) = 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) let encode_pkcs1_digest_info = Asn.pkcs1_digest_info_to_cstruct let ( let* ) = Result.bind let decode_der cs = let* asn = Asn_grammars.err_to_msg (Asn.certificate_of_cstruct cs) in Ok { asn ; raw = cs } let encode_der { raw ; _ } = raw let decode_pem_multiple cs = let* data = Pem.parse cs in let certs = List.filter (fun (t, _) -> String.equal "CERTIFICATE" t) data in Pem.foldM (fun (_, cs) -> decode_der cs) certs let decode_pem cs = let* certs = decode_pem_multiple cs in Pem.exactly_one ~what:"certificate" certs let encode_pem v = Pem.unparse ~tag:"CERTIFICATE" (encode_der v) let encode_pem_multiple cs = Cstruct.concat (List.map encode_pem cs) let pp_version ppf v = Fmt.string ppf (match v with `V1 -> "1" | `V2 -> "2" | `V3 -> "3") let pp_hash ppf hash = Fmt.string ppf (match hash with | `MD5 -> "MD5" | `SHA1 -> "SHA1" | `SHA224 -> "SHA224" | `SHA256 -> "SHA256" | `SHA384 -> "SHA384" | `SHA512 -> "SHA512") let pp_sigalg ppf (asym, hash) = Fmt.pf ppf "%a-%a" Key_type.pp_signature_scheme asym pp_hash hash 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 Fmt.(option ~none:(any "NONE") pp_sigalg) sigalg Distinguished_name.pp tbs.issuer (Ptime.pp_human ~tz_offset_s:0 ()) (fst tbs.validity) (Ptime.pp_human ~tz_offset_s:0 ()) (snd tbs.validity) Distinguished_name.pp tbs.subject Extension.pp tbs.extensions let fingerprint hash cert = Mirage_crypto.Hash.digest hash cert.raw let issuer { asn ; _ } = asn.tbs_cert.issuer let subject { asn ; _ } = asn.tbs_cert.subject let serial { asn ; _ } = asn.tbs_cert.serial let validity { asn ; _ } = asn.tbs_cert.validity let signature_algorithm { asn ; _ } = Algorithm.to_signature_algorithm asn.signature_algo let public_key { asn = cert ; _ } = cert.tbs_cert.pk_info let supports_keytype c t = match public_key c, t with | (`RSA _), `RSA -> true | _ -> false let extensions { asn = cert ; _ } = cert.tbs_cert.extensions (* RFC 6125, 6.4.4: Therefore, if and only if the presented identifiers do not include a DNS-ID, SRV-ID, URI-ID, or any application-specific identifier types supported by the client, then the client MAY as a last resort check for a string whose form matches that of a fully qualified DNS domain name in a Common Name field of the subject field (i.e., a CN-ID). If the client chooses to compare a reference identifier of type CN-ID against that string, it MUST follow the comparison rules for the DNS domain name portion of an identifier of type DNS-ID, SRV-ID, or URI-ID, as described under Section 6.4.1, Section 6.4.2, and Section 6.4.3. *) let hostnames { asn = cert ; _ } = let subj = match Distinguished_name.common_name cert.tbs_cert.subject with | None -> Host.Set.empty | Some x -> match Host.host x with | Some (wild, d) -> Host.Set.singleton (wild, d) | None -> Host.Set.empty in match Extension.hostnames cert.tbs_cert.extensions with | Some names -> names | None -> subj let supports_hostname cert name = let names = hostnames cert in let wc_name_opt = match Domain_name.drop_label name with | Error _ -> None | Ok name -> match Domain_name.host name with | Ok hostname -> Some hostname | Error _ -> None in Host.Set.mem (`Strict, name) names || (match wc_name_opt with | None -> false | Some wc_name -> Host.Set.mem (`Wildcard, wc_name) names) let ips { asn = cert ; _ } = match Extension.ips cert.tbs_cert.extensions with | None -> Ipaddr.Set.empty | Some ips -> ips let supports_ip cert ip = Ipaddr.Set.mem ip (ips cert) ocaml-x509-0.16.5/lib/crl.ml000066400000000000000000000201531445061461400152670ustar00rootroot00000000000000type revoked_cert = { serial : Z.t ; date : Ptime.t ; extensions : Extension.t } type tBS_CRL = { version : [ `V1 | `V2 ] ; signature : Algorithm.t ; issuer : Distinguished_name.t ; this_update : Ptime.t ; next_update : Ptime.t option ; revoked_certs : revoked_cert list ; extensions : Extension.t } type crl = { tbs_crl : tBS_CRL ; signature_algo : Algorithm.t ; signature_val : Cstruct.t } module Asn = struct open Asn.S open Asn_grammars let revokedCertificate = let f (serial, date, e) = let extensions = match e with None -> Extension.empty | Some xs -> xs in { serial ; date ; extensions } and g { serial ; date ; extensions } = let e = if Extension.is_empty extensions then None else Some extensions in (serial, date, e) in map f g @@ sequence3 (required ~label:"userCertificate" @@ Certificate.Asn.certificate_sn) (required ~label:"revocationDate" @@ Certificate.Asn.time) (optional ~label:"crlEntryExtensions" @@ Extension.Asn.extensions_der) let version = map (function 0 -> `V1 | 1 -> `V2 | _ -> parse_error "unknown version") (function `V2 -> 1 | `V1 -> 0) int let tBSCertList = let f (a, (b, (c, (d, (e, (f, g)))))) = { version = def `V1 a ; signature = b ; issuer = c ; this_update = d ; next_update = e ; revoked_certs = (match f with None -> [] | Some xs -> xs) ; extensions = (match g with None -> Extension.empty | Some xs -> xs) } and g { version = a ; signature = b ; issuer = c ; this_update = d ; next_update = e ; revoked_certs = f ; extensions = g } = let f = match f with [] -> None | xs -> Some xs and g = if Extension.is_empty g then None else Some g in (def' `V1 a, (b, (c, (d, (e, (f, g)))))) in map f g @@ sequence @@ (optional ~label:"version" @@ version) @ (required ~label:"signature" @@ Algorithm.identifier) @ (required ~label:"issuer" @@ Distinguished_name.Asn.name) @ (required ~label:"thisUpdate" @@ Certificate.Asn.time) @ (optional ~label:"nextUpdate" @@ Certificate.Asn.time) @ (optional ~label:"revokedCertificates" @@ sequence_of revokedCertificate) -@ (optional ~label:"crlExtensions" @@ explicit 0 Extension.Asn.extensions_der) let certificateList = let f (cl, sa, sv) = if cl.signature <> sa then parse_error "signatureAlgorithm != tbsCertList.signature" else { tbs_crl = cl ; signature_algo = sa ; signature_val = sv } and g { tbs_crl ; signature_algo ; signature_val } = (tbs_crl, signature_algo, signature_val) in map f g @@ sequence3 (required ~label:"tbsCertList" @@ tBSCertList) (required ~label:"signatureAlgorithm" @@ Algorithm.identifier) (required ~label:"signatureValue" @@ bit_string_cs) let (crl_of_cstruct, crl_to_cstruct) = projections_of Asn.der certificateList let (tbs_CRL_of_cstruct, tbs_CRL_to_cstruct) = projections_of Asn.der tBSCertList end type t = { raw : Cstruct.t ; asn : crl ; } 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 Ok { raw ; asn } let encode_der { raw ; _ } = raw let issuer { asn ; _ } = asn.tbs_crl.issuer let this_update { asn ; _ } = asn.tbs_crl.this_update let next_update { asn ; _ } = asn.tbs_crl.next_update let extensions { asn ; _ } = asn.tbs_crl.extensions let revoked_certificates { asn ; _ } = asn.tbs_crl.revoked_certs let crl_number { asn ; _ } = match Extension.(find CRL_number asn.tbs_crl.extensions) with | None -> None | Some (_, x) -> Some x let signature_algorithm { asn ; _ } = Algorithm.to_signature_algorithm asn.signature_algo let validate { raw ; asn } ?(allowed_hashes = Validation.sha2) pub = let tbs_raw = Validation.raw_cert_hack raw in Validation.validate_raw_signature asn.tbs_crl.issuer allowed_hashes tbs_raw asn.signature_algo asn.signature_val pub type verification_error = [ | Validation.signature_error | `Issuer_subject_mismatch of Distinguished_name.t * Distinguished_name.t | `Not_yet_valid of Distinguished_name.t * Ptime.t * Ptime.t | `Next_update_scheduled of Distinguished_name.t * Ptime.t * Ptime.t ] let pp_verification_error ppf = function | #Validation.signature_error as e -> Validation.pp_signature_error ppf e | `Issuer_subject_mismatch (issuer, subj) -> Fmt.pf ppf "issuer %a does not match subject %a" Distinguished_name.pp issuer Distinguished_name.pp subj | `Not_yet_valid (issuer, now, created) -> Fmt.pf ppf "CRL %a not yet valid, valid from %a, now %a" Distinguished_name.pp issuer (Ptime.pp_human ~tz_offset_s:0 ()) created (Ptime.pp_human ~tz_offset_s:0 ()) now | `Next_update_scheduled (issuer, now, scheduled) -> Fmt.pf ppf "CRL %a next update already scheduled at %a, now %a" Distinguished_name.pp issuer (Ptime.pp_human ~tz_offset_s:0 ()) scheduled (Ptime.pp_human ~tz_offset_s:0 ()) now let verify ({ asn ; _ } as crl) ?allowed_hashes ?time cert = let subj = Certificate.subject cert in let* () = guard (Distinguished_name.equal asn.tbs_crl.issuer subj) (`Issuer_subject_mismatch (asn.tbs_crl.issuer, subj)) in let* () = match time with | None -> Ok () | Some x -> let* () = guard (Ptime.is_later ~than:asn.tbs_crl.this_update x) (`Not_yet_valid (subj, x, asn.tbs_crl.this_update)) in match asn.tbs_crl.next_update with | None -> Ok () | Some y -> guard (Ptime.is_earlier ~than:y x) (`Next_update_scheduled (subj, x, y)) in validate ?allowed_hashes crl (Certificate.public_key cert) let reason (revoked : revoked_cert) = match Extension.(find Reason revoked.extensions) with | Some (_, x) -> Some x | None -> None let is_revoked ?allowed_hashes ~issuer:super ~cert (crls : t list) = List.exists (fun crl -> if Distinguished_name.equal (Certificate.subject super) (issuer crl) then match validate ?allowed_hashes crl (Certificate.public_key super) with | Ok () -> begin try let entry = List.find (fun r -> Z.equal (Certificate.serial cert) r.serial) (revoked_certificates crl) in match reason entry with | None -> true | Some `Remove_from_CRL -> false | Some _ -> true with Not_found -> false end | Error _ -> false else false) crls let sign_tbs (tbs : tBS_CRL) key = let tbs_raw = Asn.tbs_CRL_to_cstruct 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 Ok { asn ; raw } let revoke ?digest ~issuer ~this_update ?next_update ?(extensions = Extension.empty) revoked_certs key = let digest = Signing_request.default_digest digest key in let signature = let scheme = Key_type.x509_default_scheme (Private_key.key_type key) in Algorithm.of_signature_algorithm scheme digest in let tbs_crl = { version = `V2 ; signature ; issuer ; this_update ; next_update ; revoked_certs ; extensions } in sign_tbs tbs_crl key let revoke_certificates (revoked : revoked_cert list) ~this_update ?next_update ({ asn ; _ } as crl) key = let tbs = asn.tbs_crl in let count = match crl_number crl with None -> 0 | Some x -> succ x in let extensions = Extension.(add CRL_number (false, count) tbs.extensions) in let tbs = { tbs with revoked_certs = tbs.revoked_certs @ revoked ; this_update ; next_update ; extensions } in sign_tbs tbs key let revoke_certificate revoked ~this_update ?next_update crl key = revoke_certificates [revoked] ~this_update ?next_update crl key ocaml-x509-0.16.5/lib/distinguished_name.ml000066400000000000000000000216771445061461400203660ustar00rootroot00000000000000type attribute = | CN of string | Serialnumber of string | C of string | L of string | ST of string | O of string | OU of string | T of string | DNQ of string | Mail of string | DC of string | Given_name of string | Surname of string | Initials of string | Pseudonym of string | Generation of string | Street of string | Userid of string | Other of Asn.oid * string (* Escaping is described in RFC4514. Escaing '=' is optional, otherwise the * following is minimal, using the character instead of hex where possible. *) let pp_attribute_value ?(osf = false) () ppf s = let n = String.length s in for i = 0 to n - 1 do match s.[i] with | '#' when i = 0 -> Fmt.string ppf "\\#" | ' ' when i = 0 || i = n - 1 -> Fmt.string ppf "\\ " | ',' when not osf -> Fmt.string ppf "\\," | ';' when not osf -> Fmt.string ppf "\\;" | '/' when osf -> Fmt.string ppf "\\/" | '"' | '+' | '<' | '=' | '>' | '\\' as c -> Fmt.pf ppf "\\%c" c | '\x00' -> Fmt.string ppf "\\00" | c -> Fmt.char ppf c done let pp_string_hex ppf s = for i = 0 to String.length s - 1 do Fmt.pf ppf "%02x" (Char.code s.[i]) done let pp_attribute ?osf ?(ava_equal = Fmt.any "=") () ppf attr = let aux a v = Fmt.pf ppf "%s%a%a" a ava_equal () (pp_attribute_value ?osf ()) v in match attr with | CN s -> aux "CN" s | Serialnumber s -> aux "Serialnumber" s | C s -> aux "C" s | L s -> aux "L" s | ST s -> aux "ST" s | O s -> aux "O" s | OU s -> aux "OU" s | T s -> aux "T" s | DNQ s -> aux "DNQ" s | Mail s -> aux "Mail" s | DC s -> aux "DC" s | Given_name s -> aux "Given_name" s | Surname s -> aux "Surname" s | Initials s -> aux "Initials" s | Pseudonym s -> aux "Pseudonym" s | Generation s -> aux "Generation" s | Street s -> aux "Street" s | Userid s -> aux "UID" s | Other (oid, s) -> Fmt.pf ppf "%a%a#%a" Asn.OID.pp oid ava_equal () pp_string_hex s module K = struct type t = attribute let compare t t' = match t, t' with | CN a, CN b -> String.compare a b | CN _, _ -> -1 | _, CN _ -> 1 | Serialnumber a, Serialnumber b -> String.compare a b | Serialnumber _, _ -> -1 | _, Serialnumber _ -> 1 | C a, C b -> String.compare a b | C _, _ -> -1 | _, C _ -> 1 | L a, L b -> String.compare a b | L _, _ -> -1 | _, L _ -> 1 | ST a, ST b -> String.compare a b | ST _, _ -> -1 | _, ST _ -> 1 | O a, O b -> String.compare a b | O _, _ -> -1 | _, O _ -> 1 | OU a, OU b -> String.compare a b | OU _, _ -> -1 | _, OU _ -> 1 | T a, T b -> String.compare a b | T _, _ -> -1 | _, T _ -> 1 | DNQ a, DNQ b -> String.compare a b | DNQ _, _ -> -1 | _, DNQ _ -> 1 | Mail a, Mail b -> String.compare a b | Mail _, _ -> -1 | _, Mail _ -> 1 | DC a, DC b -> String.compare a b | DC _, _ -> -1 | _, DC _ -> 1 | Given_name a, Given_name b -> String.compare a b | Given_name _, _ -> -1 | _, Given_name _ -> 1 | Surname a, Surname b -> String.compare a b | Surname _, _ -> -1 | _, Surname _ -> 1 | Initials a, Initials b -> String.compare a b | Initials _, _ -> -1 | _, Initials _ -> 1 | Pseudonym a, Pseudonym b -> String.compare a b | Pseudonym _, _ -> -1 | _, Pseudonym _ -> 1 | Generation a, Generation b -> String.compare a b | Generation _, _ -> -1 | _, Generation _ -> 1 | Street a, Street b -> String.compare a b | Street _, _ -> -1 | _, Street _ -> 1 | Userid a, Userid b -> String.compare a b | Userid _, _ -> -1 | _, Userid _ -> 1 | Other (oid_a, v_a), Other (oid_b, v_b) -> match Asn.OID.compare oid_a oid_b with | 0 -> String.compare v_a v_b | x when x < 0 -> -1 | _ -> 1 end module Relative_distinguished_name = Set.Make(K) (* TODO: - each RDN should be a non-empty set - nothing prevents a user from putting Other (base 2 5 <| 4 <| 3, "foo") and Common_name "foo" into the same RDN -- which are identical (i.e. Other should filter the other named constructors) *) type t = Relative_distinguished_name.t list let equal a b = List.length a = List.length b && List.for_all2 Relative_distinguished_name.equal a b let make_pp_rdn ?osf ?(spacing = `Tight) () = let ava_sep, ava_equal = match spacing with | `Tight -> Fmt.(any "+" ++ cut, any "=") | `Medium -> Fmt.(any " +" ++ sp, any "=") | `Loose -> Fmt.(any " +" ++ sp, any " = ") in let pp_ava = pp_attribute ?osf ~ava_equal () in Fmt.(using Relative_distinguished_name.elements @@ list ~sep:ava_sep pp_ava) let make_pp ~format ?spacing () = match format, spacing with | `RFC4514, (None | Some `Tight) -> Fmt.(using List.rev @@ list ~sep:(any "," ++ cut) (make_pp_rdn ())) | `RFC4514, Some (`Medium | `Loose as spacing) -> Fmt.(using List.rev @@ list ~sep:comma (make_pp_rdn ~spacing ())) | `OpenSSL, (None | Some `Loose) -> Fmt.(list ~sep:comma (make_pp_rdn ~spacing:`Loose ())) | `OpenSSL, Some (`Tight | `Medium as spacing) -> Fmt.(list ~sep:(any "," ++ cut) (make_pp_rdn ~spacing ())) | `OSF, _ -> Fmt.(any "/" ++ list ~sep:(any "/") (make_pp_rdn ~osf:true ())) let pp = Fmt.hbox (make_pp ~format:`OSF ()) let common_name t = let is_cn = function CN _ -> true | _ -> false in List.fold_left (fun acc dn -> match Relative_distinguished_name.find_first_opt is_cn dn with | Some CN x -> Some x | _ -> acc) None t module Asn = struct open Asn.S open Asn_grammars (* ASN `Name' fragmet appears all over. *) (* rfc5280 section 4.1.2.4 - name components we "must" handle. *) (* A list of abbreviations: http://pic.dhe.ibm.com/infocenter/wmqv7/v7r1/index.jsp?topic=%2Fcom.ibm.mq.doc%2Fsy10570_.htm *) (* Also rfc4519. *) (* See rfc5280 section 4.1.2.4. *) let directory_name = choice6 utf8_string printable_string ia5_string universal_string teletex_string bmp_string (* We flatten the sequence-of-set-of-tuple here into a single list. * This means that we can't write non-singleton sets back. * Does anyone need that, ever? *) let name = let open Registry in let of_c = function | `C1 x | `C2 x | `C3 x | `C4 x | `C5 x | `C6 x -> x in let a_f = case_of_oid_f [ (domain_component , fun x -> DC (of_c x)) ; (X520.common_name , fun x -> CN (of_c x)) ; (X520.serial_number , fun x -> Serialnumber (of_c x)) ; (X520.country_name , fun x -> C (of_c x)) ; (X520.locality_name , fun x -> L (of_c x)) ; (X520.state_or_province_name , fun x -> ST (of_c x)) ; (X520.organization_name , fun x -> O (of_c x)) ; (X520.organizational_unit_name , fun x -> OU (of_c x)) ; (X520.title , fun x -> T (of_c x)) ; (X520.dn_qualifier , fun x -> DNQ (of_c x)) ; (PKCS9.email , fun x -> Mail (of_c x)) ; (X520.given_name , fun x -> Given_name (of_c x)) ; (X520.surname , fun x -> Surname (of_c x)) ; (X520.initials , fun x -> Initials (of_c x)) ; (X520.pseudonym , fun x -> Pseudonym (of_c x)) ; (X520.generation_qualifier , fun x -> Generation (of_c x)) ; (X520.street_address , fun x -> Street (of_c x)) ; (userid , fun x -> Userid (of_c x))] ~default:(fun oid x -> Other (oid, of_c x)) and a_g = function | DC x -> (domain_component, `C3 x ) | CN x -> (X520.common_name, `C1 x ) | Serialnumber x -> (X520.serial_number, `C2 x ) | C x -> (X520.country_name, `C2 x ) | L x -> (X520.locality_name, `C1 x ) | ST x -> (X520.state_or_province_name, `C1 x ) | O x -> (X520.organization_name, `C1 x ) | OU x -> (X520.organizational_unit_name, `C1 x ) | T x -> (X520.title, `C1 x ) | DNQ x -> (X520.dn_qualifier, `C2 x ) | Mail x -> (PKCS9.email, `C3 x ) | Given_name x -> (X520.given_name, `C1 x ) | Surname x -> (X520.surname, `C1 x ) | Initials x -> (X520.initials, `C1 x ) | Pseudonym x -> (X520.pseudonym, `C1 x ) | Generation x -> (X520.generation_qualifier, `C1 x ) | Street x -> (X520.street_address, `C1 x ) | Userid x -> (userid, `C1 x ) | Other (oid, x) -> (oid, `C1 x ) in let attribute_tv = map a_f a_g @@ sequence2 (required ~label:"attr type" oid) (* This is ANY according to rfc5280. *) (required ~label:"attr value" directory_name) in let rd_name = let f exts = List.fold_left (fun set attr -> Relative_distinguished_name.add attr set) Relative_distinguished_name.empty exts and g map = Relative_distinguished_name.elements map in map f g @@ set_of attribute_tv in sequence_of rd_name (* A vacuous choice, in the standard. *) let (name_of_cstruct, name_to_cstruct) = projections_of Asn.der name end let decode_der cs = Asn_grammars.err_to_msg (Asn.name_of_cstruct cs) let encode_der = Asn.name_to_cstruct ocaml-x509-0.16.5/lib/dune000066400000000000000000000007341445061461400150360ustar00rootroot00000000000000(library (name x509) (public_name x509) (private_modules asn_grammars registry authenticator certificate validation 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 gmap domain-name base64 logs mirage-crypto-ec pbkdf mirage-crypto-rng ipaddr)) ocaml-x509-0.16.5/lib/extension.ml000066400000000000000000000610671445061461400165340ustar00rootroot00000000000000 type key_usage = [ | `Digital_signature | `Content_commitment | `Key_encipherment | `Data_encipherment | `Key_agreement | `Key_cert_sign | `CRL_sign | `Encipher_only | `Decipher_only ] let pp_key_usage ppf ku = Fmt.string ppf (match ku with | `Digital_signature -> "digital signature" | `Content_commitment -> "content commitment" | `Key_encipherment -> "key encipherment" | `Data_encipherment -> "data encipherment" | `Key_agreement -> "key agreement" | `Key_cert_sign -> "key cert sign" | `CRL_sign -> "CRL sign" | `Encipher_only -> "encipher only" | `Decipher_only -> "decipher only") type extended_key_usage = [ | `Any | `Server_auth | `Client_auth | `Code_signing | `Email_protection | `Ipsec_end | `Ipsec_tunnel | `Ipsec_user | `Time_stamping | `Ocsp_signing | `Other of Asn.oid ] let pp_extended_key_usage ppf = function | `Any -> Fmt.string ppf "any" | `Server_auth -> Fmt.string ppf "server authentication" | `Client_auth -> Fmt.string ppf "client authentication" | `Code_signing -> Fmt.string ppf "code signing" | `Email_protection -> Fmt.string ppf "email protection" | `Ipsec_end -> Fmt.string ppf "ipsec end" | `Ipsec_tunnel -> Fmt.string ppf "ipsec tunnel" | `Ipsec_user -> Fmt.string ppf "ipsec user" | `Time_stamping -> Fmt.string ppf "time stamping" | `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 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 General_name.pp issuer (match serial with None -> "none" | Some x -> Z.to_string x) type priv_key_usage_period = [ | `Interval of Ptime.t * Ptime.t | `Not_after of Ptime.t | `Not_before of Ptime.t ] let pp_priv_key_usage_period ppf = let pp_ptime = Ptime.pp_human ~tz_offset_s:0 () in function | `Interval (start, stop) -> Fmt.pf ppf "from %a till %a" pp_ptime start pp_ptime stop | `Not_after after -> Fmt.pf ppf "not after %a" pp_ptime after | `Not_before before -> Fmt.pf ppf "not before %a" pp_ptime before type name_constraint = (General_name.b * int * int option) list let pp_name_constraints ppf (permitted, excluded) = let pp_one ppf (General_name.B (k, base), min, max) = Fmt.pf ppf "base %a min %u max %a" (General_name.pp_k k) base min Fmt.(option ~none:(any "none") int) max in Fmt.pf ppf "permitted %a@ excluded %a" Fmt.(list ~sep:(any ", ") pp_one) permitted Fmt.(list ~sep:(any ", ") pp_one) excluded type policy = [ `Any | `Something of Asn.oid ] let pp_policy ppf = function | `Any -> Fmt.string ppf "any" | `Something oid -> Fmt.pf ppf "some oid %a" Asn.OID.pp oid type reason = [ | `Unspecified | `Key_compromise | `CA_compromise | `Affiliation_changed | `Superseded | `Cessation_of_operation | `Certificate_hold | `Remove_from_CRL | `Privilege_withdrawn | `AA_compromise ] let reason_to_int = function | `Unspecified -> 0 | `Key_compromise -> 1 | `CA_compromise -> 2 | `Affiliation_changed -> 3 | `Superseded -> 4 | `Cessation_of_operation -> 5 | `Certificate_hold -> 6 (* 7 is not used *) | `Remove_from_CRL -> 8 | `Privilege_withdrawn -> 9 | `AA_compromise -> 10 let reason_of_int = function | 0 -> `Unspecified | 1 -> `Key_compromise | 2 -> `CA_compromise | 3 -> `Affiliation_changed | 4 -> `Superseded | 5 -> `Cessation_of_operation | 6 -> `Certificate_hold (* 7 is not used *) | 8 -> `Remove_from_CRL | 9 -> `Privilege_withdrawn | 10 -> `AA_compromise | x -> Asn.S.parse_error "Unknown reason %d" x let pp_reason ppf r = Fmt.string ppf (match r with | `Unspecified -> "unspecified" | `Key_compromise -> "key compromise" | `CA_compromise -> "CA compromise" | `Affiliation_changed -> "affiliation changed" | `Superseded -> "superseded" | `Cessation_of_operation -> "cessation of operation" | `Certificate_hold -> "certificate hold" | `Remove_from_CRL -> "remove from CRL" | `Privilege_withdrawn -> "privilege withdrawn" | `AA_compromise -> "AA compromise") type distribution_point_name = [ `Full of General_name.t | `Relative of Distinguished_name.t ] let pp_distribution_point_name ppf = function | `Full name -> Fmt.pf ppf "full %a" General_name.pp name | `Relative name -> Fmt.pf ppf "relative %a" Distinguished_name.pp name type distribution_point = distribution_point_name option * reason list option * General_name.t option let pp_distribution_point ppf (name, reasons, issuer) = Fmt.pf ppf "name %a reason %a issuer %a" Fmt.(option ~none:(any "none") pp_distribution_point_name) name Fmt.(option ~none:(any "none") (list ~sep:(any ", ") pp_reason)) reasons Fmt.(option ~none:(any "none") General_name.pp) issuer let pp_issuing_distribution_point ppf (name, onlyuser, onlyca, onlysome, indirectcrl, onlyattributes) = Fmt.pf ppf "name %a only user certs %B only CA certs %B only reasons %a indirectcrl %B only attribute certs %B" Fmt.(option ~none:(any "none") pp_distribution_point_name) name onlyuser onlyca Fmt.(option ~none:(any "no") (list ~sep:(any ", ") pp_reason)) onlysome indirectcrl onlyattributes type 'a extension = bool * 'a type _ k = | Unsupported : Asn.oid -> Cstruct.t 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 | Issuer_alt_name : General_name.t extension k | Key_usage : key_usage list extension k | Ext_key_usage : extended_key_usage list extension k | Basic_constraints : (bool * int option) extension k | CRL_number : int extension k | Delta_CRL_indicator : int extension k | Priv_key_period : priv_key_usage_period extension k | Name_constraints : (name_constraint * name_constraint) extension k | CRL_distribution_points : distribution_point list extension k | Issuing_distribution_point : (distribution_point_name option * bool * bool * reason list option * bool * bool) extension k | Freshest_CRL : distribution_point list extension k | Reason : reason extension k | Invalidity_date : Ptime.t extension k | Certificate_issuer : General_name.t extension k | Policies : policy list extension k let pp_one : type a. a k -> Format.formatter -> a -> unit = fun k ppf v -> let c_to_str b = if b then "critical " else "" in match k, v with | Subject_alt_name, (crit, alt) -> Fmt.pf ppf "%ssubjectAlternativeName %a" (c_to_str crit) General_name.pp alt | Authority_key_id, (crit, kid) -> Fmt.pf ppf "%sauthorityKeyIdentifier %a" (c_to_str crit) pp_authority_key_id kid | Subject_key_id, (crit, kid) -> Fmt.pf ppf "%ssubjectKeyIdentifier %a" (c_to_str crit) Cstruct.hexdump_pp kid | Issuer_alt_name, (crit, alt) -> Fmt.pf ppf "%sissuerAlternativeNames %a" (c_to_str crit) General_name.pp alt | Key_usage, (crit, ku) -> Fmt.pf ppf "%skeyUsage %a" (c_to_str crit) Fmt.(list ~sep:(any ", ") pp_key_usage) ku | Ext_key_usage, (crit, eku) -> Fmt.pf ppf "%sextendedKeyUsage %a" (c_to_str crit) Fmt.(list ~sep:(any ", ") pp_extended_key_usage) eku | Basic_constraints, (crit, (ca, depth)) -> Fmt.pf ppf "%sbasicConstraints CA %B depth %a" (c_to_str crit) ca Fmt.(option ~none:(any "none") int) depth | CRL_number, (crit, i) -> Fmt.pf ppf "%scRLNumber %u" (c_to_str crit) i | Delta_CRL_indicator, (crit, indicator) -> Fmt.pf ppf "%sdeltaCRLIndicator %u" (c_to_str crit) indicator | Priv_key_period, (crit, period) -> Fmt.pf ppf "%sprivateKeyUsagePeriod %a" (c_to_str crit) pp_priv_key_usage_period period | Name_constraints, (crit, ncs) -> Fmt.pf ppf "%snameConstraints %a" (c_to_str crit) pp_name_constraints ncs | CRL_distribution_points, (crit, points) -> Fmt.pf ppf "%scRLDistributionPoints %a" (c_to_str crit) Fmt.(list ~sep:(any "; ") pp_distribution_point) points | Issuing_distribution_point, (crit, point) -> Fmt.pf ppf "%sissuingDistributionPoint %a" (c_to_str crit) pp_issuing_distribution_point point | Freshest_CRL, (crit, points) -> Fmt.pf ppf "%sfreshestCRL %a" (c_to_str crit) Fmt.(list ~sep:(any "; ") pp_distribution_point) points | Reason, (crit, reason) -> Fmt.pf ppf "%sreason %a" (c_to_str crit) pp_reason reason | Invalidity_date, (crit, date) -> Fmt.pf ppf "%sinvalidityDate %a" (c_to_str crit) (Ptime.pp_human ~tz_offset_s:0 ()) date | Certificate_issuer, (crit, name) -> Fmt.pf ppf "%scertificateIssuer %a" (c_to_str crit) General_name.pp name | Policies, (crit, pols) -> Fmt.pf ppf "%spolicies %a" (c_to_str crit) Fmt.(list ~sep:(any "; ") pp_policy) pols | Unsupported oid, (crit, cs) -> Fmt.pf ppf "%sunsupported %a: %a" (c_to_str crit) Asn.OID.pp oid Cstruct.hexdump_pp cs module ID = Registry.Cert_extn let to_oid : type a. a k -> Asn.oid = function | Unsupported oid -> oid | Subject_alt_name -> ID.subject_alternative_name | Authority_key_id -> ID.authority_key_identifier | Subject_key_id -> ID.subject_key_identifier | Issuer_alt_name -> ID.issuer_alternative_name | Key_usage -> ID.key_usage | Ext_key_usage -> ID.extended_key_usage | Basic_constraints -> ID.basic_constraints | CRL_number -> ID.crl_number | Delta_CRL_indicator -> ID.delta_crl_indicator | Priv_key_period -> ID.private_key_usage_period | Name_constraints -> ID.name_constraints | CRL_distribution_points -> ID.crl_distribution_points | Issuing_distribution_point -> ID.issuing_distribution_point | Freshest_CRL -> ID.freshest_crl | Reason -> ID.reason_code | Invalidity_date -> ID.invalidity_date | Certificate_issuer -> ID.certificate_issuer | Policies -> ID.certificate_policies_2 let critical : type a. a k -> a -> bool = fun k v -> match k, v with | Unsupported _, (b, _) -> b | Subject_alt_name, (b, _) -> b | Authority_key_id, (b, _) -> b | Subject_key_id, (b, _) -> b | Issuer_alt_name, (b, _) -> b | Key_usage, (b, _) -> b | Ext_key_usage, (b, _) -> b | Basic_constraints, (b, _) -> b | CRL_number, (b, _) -> b | Delta_CRL_indicator, (b, _) -> b | Priv_key_period, (b, _) -> b | Name_constraints, (b, _) -> b | CRL_distribution_points, (b, _) -> b | Issuing_distribution_point, (b, _) -> b | Freshest_CRL, (b, _) -> b | Reason, (b, _) -> b | Invalidity_date, (b, _) -> b | Certificate_issuer, (b, _) -> b | Policies, (b, _) -> b module K = struct type 'a t = 'a k let compare : type a b. a t -> b t -> (a, b) Gmap.Order.t = fun t t' -> let open Gmap.Order in match t, t' with | Subject_alt_name, Subject_alt_name -> Eq | Authority_key_id, Authority_key_id -> Eq | Subject_key_id, Subject_key_id -> Eq | Issuer_alt_name, Issuer_alt_name -> Eq | Key_usage, Key_usage -> Eq | Ext_key_usage, Ext_key_usage -> Eq | Basic_constraints, Basic_constraints -> Eq | CRL_number, CRL_number -> Eq | Delta_CRL_indicator, Delta_CRL_indicator -> Eq | Priv_key_period, Priv_key_period -> Eq | Name_constraints, Name_constraints -> Eq | CRL_distribution_points, CRL_distribution_points -> Eq | Issuing_distribution_point, Issuing_distribution_point -> Eq | Freshest_CRL, Freshest_CRL -> Eq | Reason, Reason -> Eq | Invalidity_date, Invalidity_date -> Eq | Certificate_issuer, Certificate_issuer -> Eq | Policies, Policies -> Eq | Unsupported oid, Unsupported oid' when Asn.OID.equal oid oid' -> Eq | a, b -> let r = Asn.OID.compare (to_oid a) (to_oid b) in if r = 0 then assert false else if r < 0 then Lt else Gt end include Gmap.Make(K) let pp ppf m = iter (fun (B (k, v)) -> pp_one k ppf v ; Fmt.sp ppf ()) m let hostnames exts = match find Subject_alt_name exts with | None -> None | Some (_, names) -> match General_name.find DNS names with | None -> None | Some xs -> let names = List.fold_left (fun acc s -> match Host.host s with | Some (typ, hostname) -> Host.Set.add (typ, hostname) acc | None -> acc) Host.Set.empty xs in if Host.Set.is_empty names then None else Some names let ips exts = match find Subject_alt_name exts with | None -> None | Some (_, names) -> match General_name.find IP names with | None -> None | 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) | 16 -> Result.map (fun ip -> Ipaddr.V6 ip) (Ipaddr.V6.of_octets ip) | _ -> Error (`Msg "unknown IP address kind") with | Ok ip -> Ipaddr.Set.add ip acc | Error _ -> acc) Ipaddr.Set.empty xs in if Ipaddr.Set.is_empty ips then None else Some ips module Asn = struct open Asn.S open Asn_grammars let display_text = map (function `C1 s -> s | `C2 s -> s | `C3 s -> s | `C4 s -> s) (fun s -> `C4 s) @@ choice4 ia5_string visible_string bmp_string utf8_string module ID = Registry.Cert_extn let key_usage : key_usage list Asn.t = bit_string_flags [ 0, `Digital_signature ; 1, `Content_commitment ; 2, `Key_encipherment ; 3, `Data_encipherment ; 4, `Key_agreement ; 5, `Key_cert_sign ; 6, `CRL_sign ; 7, `Encipher_only ; 8, `Decipher_only ] let ext_key_usage = let open ID.Extended_usage in let f = case_of_oid [ (any , `Any ) ; (server_auth , `Server_auth ) ; (client_auth , `Client_auth ) ; (code_signing , `Code_signing ) ; (email_protection , `Email_protection) ; (ipsec_end_system , `Ipsec_end ) ; (ipsec_tunnel , `Ipsec_tunnel ) ; (ipsec_user , `Ipsec_user ) ; (time_stamping , `Time_stamping ) ; (ocsp_signing , `Ocsp_signing ) ] ~default:(fun oid -> `Other oid) and g = function | `Any -> any | `Server_auth -> server_auth | `Client_auth -> client_auth | `Code_signing -> code_signing | `Email_protection -> email_protection | `Ipsec_end -> ipsec_end_system | `Ipsec_tunnel -> ipsec_tunnel | `Ipsec_user -> ipsec_user | `Time_stamping -> time_stamping | `Ocsp_signing -> ocsp_signing | `Other oid -> oid in map (List.map f) (List.map g) @@ sequence_of oid let basic_constraints = map (fun (a, b) -> (def false a, b)) (fun (a, b) -> (def' false a, b)) @@ sequence2 (optional ~label:"cA" bool) (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)) @@ sequence3 (optional ~label:"keyIdentifier" @@ implicit 0 octet_string) (optional ~label:"authCertIssuer" @@ implicit 1 General_name.Asn.gen_names) (optional ~label:"authCertSN" @@ implicit 2 integer) let priv_key_usage_period = let f = function | (Some t1, Some t2) -> `Interval (t1, t2) | (Some t1, None ) -> `Not_before t1 | (None , Some t2) -> `Not_after t2 | _ -> parse_error "empty PrivateKeyUsagePeriod" and g = function | `Interval (t1, t2) -> (Some t1, Some t2) | `Not_before t1 -> (Some t1, None ) | `Not_after t2 -> (None , Some t2) in map f g @@ sequence2 (optional ~label:"notBefore" @@ implicit 0 generalized_time_no_frac_s) (optional ~label:"notAfter" @@ implicit 1 generalized_time_no_frac_s) let name_constraints = let subtree = map (fun (base, min, max) -> (base, def 0 min, max)) (fun (base, min, max) -> (base, def' 0 min, max)) @@ sequence3 (required ~label:"base" General_name.Asn.general_name) (optional ~label:"minimum" @@ implicit 0 int) (optional ~label:"maximum" @@ implicit 1 int) in map (fun (a, b) -> (def [] a, def [] b)) (fun (a, b) -> (def' [] a, def' [] b)) @@ sequence2 (optional ~label:"permittedSubtrees" @@ implicit 0 (sequence_of subtree)) (optional ~label:"excludedSubtrees" @@ implicit 1 (sequence_of subtree)) let cert_policies = let open ID.Cert_policy in let qualifier_info = map (function | (oid, `C1 s) when oid = cps -> s | (oid, `C2 s) when oid = unotice -> s | _ -> parse_error "bad policy qualifier") (function s -> (cps, `C1 s)) @@ sequence2 (required ~label:"qualifierId" oid) (required ~label:"qualifier" (choice2 ia5_string @@ map (function (_, Some s) -> s | _ -> "#(BLAH BLAH)") (fun s -> (None, Some s)) (sequence2 (optional ~label:"noticeRef" (sequence2 (required ~label:"organization" display_text) (required ~label:"numbers" (sequence_of integer)))) (optional ~label:"explicitText" display_text)))) in (* "Optional qualifiers, which MAY be present, are not expected to change * the definition of the policy." * Hence, we just drop them. *) sequence_of @@ map (function | (oid, _) when oid = any_policy -> `Any | (oid, _) -> `Something oid) (function | `Any -> (any_policy, None) | `Something oid -> (oid, None)) @@ sequence2 (required ~label:"policyIdentifier" oid) (optional ~label:"policyQualifiers" (sequence_of qualifier_info)) let reason : reason list Asn.t = bit_string_flags [ 0, `Unspecified ; 1, `Key_compromise ; 2, `CA_compromise ; 3, `Affiliation_changed ; 4, `Superseded ; 5, `Cessation_of_operation ; 6, `Certificate_hold ; 7, `Privilege_withdrawn ; 8, `AA_compromise ] let reason_enumerated : reason Asn.t = enumerated reason_of_int reason_to_int let distribution_point_name = map (function | `C1 s -> `Full s | `C2 s -> `Relative s) (function | `Full s -> `C1 s | `Relative s -> `C2 s) @@ choice2 (implicit 0 General_name.Asn.gen_names) (implicit 1 Distinguished_name.Asn.name) let distribution_point = sequence3 (optional ~label:"distributionPoint" @@ explicit 0 distribution_point_name) (optional ~label:"reasons" @@ implicit 1 reason) (optional ~label:"cRLIssuer" @@ implicit 2 General_name.Asn.gen_names) let crl_distribution_points = sequence_of distribution_point let issuing_distribution_point = map (fun (a, b, c, d, e, f) -> (a, def false b, def false c, d, def false e, def false f)) (fun (a, b, c, d, e, f) -> (a, def' false b, def' false c, d, def' false e, def' false f)) @@ sequence6 (optional ~label:"distributionPoint" @@ explicit 0 distribution_point_name) (optional ~label:"onlyContainsUserCerts" @@ implicit 1 bool) (optional ~label:"onlyContainsCACerts" @@ implicit 2 bool) (optional ~label:"onlySomeReasons" @@ implicit 3 reason) (optional ~label:"indirectCRL" @@ implicit 4 bool) (optional ~label:"onlyContainsAttributeCerts" @@ implicit 5 bool) let crl_reason : reason Asn.t = let alist = [ 0, `Unspecified ; 1, `Key_compromise ; 2, `CA_compromise ; 3, `Affiliation_changed ; 4, `Superseded ; 5, `Cessation_of_operation ; 6, `Certificate_hold ; 8, `Remove_from_CRL ; 9, `Privilege_withdrawn ; 10, `AA_compromise ] in 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 (* 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))) ; (ID.issuer_alternative_name, fun cs -> B (Issuer_alt_name, (crit, gen_names_of_cs cs))) ; (ID.authority_key_identifier, fun cs -> B (Authority_key_id, (crit, auth_key_id_of_cs cs))) ; (ID.subject_key_identifier, fun cs -> B (Subject_key_id, (crit, subj_key_id_of_cs cs))) ; (ID.key_usage, fun cs -> B (Key_usage, (crit, key_usage_of_cs cs))) ; (ID.basic_constraints, fun cs -> B (Basic_constraints, (crit, basic_constr_of_cs cs))) ; (ID.crl_number, fun cs -> B (CRL_number, (crit, int_of_cs cs))) ; (ID.delta_crl_indicator, fun cs -> B (Delta_CRL_indicator, (crit, int_of_cs cs))) ; (ID.extended_key_usage, fun cs -> B (Ext_key_usage, (crit, e_key_usage_of_cs cs))) ; (ID.private_key_usage_period, fun cs -> B (Priv_key_period, (crit, pr_key_peri_of_cs cs))) ; (ID.name_constraints, fun cs -> B (Name_constraints, (crit, name_con_of_cs cs))) ; (ID.crl_distribution_points, fun cs -> B (CRL_distribution_points, (crit, crl_distrib_of_cs cs))) ; (ID.issuing_distribution_point, fun cs -> B (Issuing_distribution_point, (crit, issuing_dp_of_cs cs))) ; (ID.freshest_crl, fun cs -> B (Freshest_CRL, (crit, crl_distrib_of_cs cs))) ; (ID.reason_code, fun cs -> B (Reason, (crit, crl_reason_of_cs cs))) ; (ID.invalidity_date, fun cs -> B (Invalidity_date, (crit, time_of_cs cs))) ; (ID.certificate_issuer, fun cs -> B (Certificate_issuer, (crit, gen_names_of_cs cs))) ; (ID.certificate_policies_2, fun cs -> B (Policies, (crit, cert_pol_of_cs 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 | Unsupported _, (_, x) -> x in to_oid k, critical k v, v' let extensions_der = let extension = let f (oid, crit, cs) = reparse_extension_exn (def false crit) (oid, cs) and g b = let oid, crit, cs = unparse_extension b in (oid, def' false crit, cs) in map f g @@ sequence3 (required ~label:"id" oid) (optional ~label:"critical" bool) (* default false *) (required ~label:"value" octet_string) in let f exts = List.fold_left (fun map (B (k, v)) -> match add_unless_bound k v map with | None -> parse_error "%a already bound" (pp_one k) v | Some b -> b) empty exts and g map = bindings map in map f g @@ sequence_of extension end ocaml-x509-0.16.5/lib/general_name.ml000066400000000000000000000134621445061461400171310ustar00rootroot00000000000000type _ k = | Other : Asn.oid -> string list k | Rfc_822 : string list k | DNS : string list k | X400_address : unit k | Directory : Distinguished_name.t list k | EDI_party : (string option * string) list k | URI : string list k | IP : Cstruct.t list k | Registered_id : Asn.oid list k module K = struct type 'a t = 'a k let compare : type a b. a t -> b t -> (a, b) Gmap.Order.t = fun t t' -> let open Gmap.Order in match t, t' with | Rfc_822, Rfc_822 -> Eq | Rfc_822, _ -> Lt | _, Rfc_822 -> Gt | DNS, DNS -> Eq | DNS, _ -> Lt | _, DNS -> Gt | X400_address, X400_address -> Eq | X400_address, _ -> Lt | _, X400_address -> Gt | Directory, Directory -> Eq | Directory, _ -> Lt | _, Directory -> Gt | EDI_party, EDI_party -> Eq | EDI_party, _ -> Lt | _, EDI_party -> Gt | URI, URI -> Eq | URI, _ -> Lt | _, URI -> Gt | IP, IP -> Eq | IP, _ -> Lt | _, IP -> Gt | Registered_id, Registered_id -> Eq | Registered_id, _ -> Lt | _, Registered_id -> Gt | Other a, Other b -> match Asn.OID.compare a b with | 0 -> Eq | x when x < 0 -> Lt | _ -> Gt end include Gmap.Make(K) let pp_k : type a. a k -> Format.formatter -> a -> unit = fun k ppf v -> let pp_strs = Fmt.(list ~sep:(any "; ") string) in match k, v with | Rfc_822, x -> Fmt.pf ppf "rfc822 %a" pp_strs x | DNS, x -> Fmt.pf ppf "dns %a" Fmt.(list ~sep:(any "; ") string) x | X400_address, () -> Fmt.string ppf "x400 address" | Directory, x -> Fmt.pf ppf "directory %a" Fmt.(list ~sep:(any "; ") Distinguished_name.pp) x | EDI_party, xs -> Fmt.pf ppf "edi party %a" Fmt.(list ~sep:(any "; ") (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 | Registered_id, x -> Fmt.pf ppf "registered id %a" Fmt.(list ~sep:(any ";") Asn.OID.pp) x | Other oid, x -> Fmt.pf ppf "other %a: %a" Asn.OID.pp oid pp_strs x let pp ppf m = iter (fun (B (k, v)) -> pp_k k ppf v ; Fmt.sp ppf ()) m let merge_values : type a. a k -> a -> a -> a = fun k v v' -> match k, v, v' with | Other _, a, b -> a @ b | Registered_id, a, b -> a @ b | IP, a, b -> a @ b | URI, a, b -> a @ b | EDI_party, a, b -> a @ b | Directory, a, b -> a @ b | X400_address, (), () -> () | DNS, a, b -> a @ b | Rfc_822, a, b -> a @ b module Asn = struct open Asn.S (* GeneralName is also pretty pervasive. *) (* OID x ANY. Hunt down the alternatives.... *) (* XXX * Cross-check. NSS seems to accept *all* oids here and just assumes UTF8. * *) let another_name = let open Registry in let f = function | (oid, `C1 n) -> (oid, n) | (oid, `C2 n) -> (oid, n) | (oid, `C3 _) -> (oid, "") and g = function | (oid, "") -> (oid, `C3 ()) | (oid, n ) when Name_extn.is_utf8_id oid -> (oid, `C1 n) | (oid, n ) -> (oid, `C2 n) in map f g @@ sequence2 (required ~label:"type-id" oid) (required ~label:"value" @@ explicit 0 (choice3 utf8_string ia5_string null)) and or_address = null (* Horrible crap, need to fill it. *) let dir_name = let f = function | `C1 s -> s | `C2 s -> s | `C3 s -> s | `C4 s -> s | `C5 s -> s | `C6 s -> s and g s = `C1 s in Asn.S.map f g Distinguished_name.Asn.directory_name let edi_party_name = sequence2 (optional ~label:"nameAssigner" @@ implicit 0 dir_name) (required ~label:"partyName" @@ implicit 1 dir_name) let general_name = let f = function | `C1 (`C1 (oid, x)) -> B (Other oid, [ x ]) | `C1 (`C2 x) -> B (Rfc_822, [ x ]) | `C1 (`C3 x) -> B (DNS, [ x ]) | `C1 (`C4 _x) -> B (X400_address, ()) | `C1 (`C5 x) -> B (Directory, [ x ]) | `C1 (`C6 x) -> B (EDI_party, [ x ]) | `C2 (`C1 x) -> B (URI, [ x ]) | `C2 (`C2 x) -> B (IP, [ x ]) | `C2 (`C3 x) -> B (Registered_id, [ x ]) and g (B (k, v)) = match k, v with | Other oid, [ x ] -> `C1 (`C1 (oid, x)) | Rfc_822, [ x ] -> `C1 (`C2 x) | DNS, [ x ] -> `C1 (`C3 x) | X400_address, () -> `C1 (`C4 ()) | Directory, [ x ] -> `C1 (`C5 x) | EDI_party, [ x ] -> `C1 (`C6 x) | URI, [ x ] -> `C2 (`C1 x) | IP, [ x ] -> `C2 (`C2 x) | Registered_id, [ x ] -> `C2 (`C3 x) | _ -> Asn.S.error (`Parse "bad general name") in map f g @@ choice2 (choice6 (implicit 0 another_name) (implicit 1 ia5_string) (implicit 2 ia5_string) (implicit 3 or_address) (* Everybody uses this as explicit, contrary to x509 (?) *) (explicit 4 Distinguished_name.Asn.name) (implicit 5 edi_party_name)) (choice3 (implicit 6 ia5_string) (implicit 7 octet_string) (implicit 8 oid)) let gen_names = let f exts = List.fold_left (fun map (B (k, v)) -> match find k map with | None -> add k v map | Some b -> add k (merge_values k b v) map) empty exts and g map = List.flatten (List.map (fun (B (k, v)) -> match k, v with | Other oid, xs -> List.map (fun d -> B (Other oid, [ d ])) xs | Registered_id, xs -> List.map (fun d -> B (Registered_id, [ d ])) xs | IP, xs -> List.map (fun d -> B (IP, [ d ])) xs | URI, xs -> List.map (fun d -> B (URI, [ d ])) xs | EDI_party, xs -> List.map (fun d -> B (EDI_party, [ d ])) xs | Directory, xs -> List.map (fun d -> B (Directory, [ d ])) xs | X400_address, () -> [ B (X400_address, ()) ] | DNS, xs -> List.map (fun d -> B (DNS, [ d ])) xs | Rfc_822, xs -> List.map (fun d -> B (Rfc_822, [ d ])) xs) (bindings map)) in map f g @@ sequence_of general_name end ocaml-x509-0.16.5/lib/host.ml000066400000000000000000000020421445061461400154610ustar00rootroot00000000000000type t = [ `Strict | `Wildcard ] * [ `host ] Domain_name.t let pp_typ ppf = function | `Strict -> Fmt.nop ppf () | `Wildcard -> Fmt.string ppf "*." let pp ppf (typ, nam) = Fmt.pf ppf "%a%a" pp_typ typ Domain_name.pp nam module Set = struct include Set.Make(struct type nonrec t = t let compare a b = match a, b with | (`Strict, a), (`Strict, b) | (`Wildcard, a), (`Wildcard, b) -> Domain_name.compare a b | (`Strict, _), (`Wildcard, _) -> -1 | (`Wildcard, _), (`Strict, _) -> 1 end) let pp ppf s = Fmt.(list ~sep:(any ", ") pp) ppf (elements s) end let is_wildcard name = match Domain_name.get_label name 0 with | Ok "*" -> Some (Domain_name.drop_label_exn name) | _ -> None let host name = match Domain_name.of_string name with | Error _ -> None | Ok dn -> let wild, name = match is_wildcard dn with | None -> `Strict, dn | Some dn' -> `Wildcard, dn' in match Domain_name.host name with | Error _ -> None | Ok hostname -> Some (wild, hostname) ocaml-x509-0.16.5/lib/key_type.ml000066400000000000000000000027521445061461400163450ustar00rootroot00000000000000type t = [ `RSA | `ED25519 | `P224 | `P256 | `P384 | `P521 ] let strings = [ ("rsa", `RSA) ; ("ed25519", `ED25519) ; ("p224", `P224) ; ("p256", `P256) ; ("p384", `P384) ; ("p521", `P521) ] let to_string kt = fst (List.find (fun (_, k) -> kt = k) strings) let of_string s = match List.assoc_opt (String.lowercase_ascii s) strings with | Some kt -> Ok kt | None -> Error (`Msg (Fmt.str "unkown key type %s, supported are %a" s Fmt.(list ~sep:(any ", ") string) (List.map fst strings))) let pp ppf t = Fmt.string ppf (to_string t) type signature_scheme = [ `RSA_PSS | `RSA_PKCS1 | `ECDSA | `ED25519 ] let signature_scheme_to_string = function | `RSA_PSS -> "RSA-PSS" | `RSA_PKCS1 -> "RSA-PKCS1" | `ECDSA -> "ECDSA" | `ED25519 -> "ED25519" let pp_signature_scheme ppf s = Fmt.string ppf (signature_scheme_to_string s) 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 | _ -> false let opt_signature_scheme ?scheme kt = match scheme with | Some x -> x | None -> match kt with | `RSA -> `RSA_PSS | `ED25519 -> `ED25519 | `P224 | `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) *) let x509_default_scheme = function | `RSA -> `RSA_PKCS1 | x -> opt_signature_scheme x ocaml-x509-0.16.5/lib/ocsp.ml000066400000000000000000000576211445061461400154650ustar00rootroot00000000000000(* https://tools.ietf.org/html/rfc6960 *) let version_v1 = 0 (* CertID ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, issuerNameHash OCTET STRING, -- Hash of issuer's DN issuerKeyHash OCTET STRING, -- Hash of issuer's public key serialNumber CertificateSerialNumber } *) type cert_id = { hashAlgorithm: Algorithm.t; issuerNameHash: Cstruct.t; issuerKeyHash: Cstruct.t; serialNumber: Z.t; } let create_cert_id ?(hash=`SHA1) issuer serialNumber = let hashAlgorithm = Algorithm.of_hash hash in let issuerNameHash = Certificate.subject issuer |> Distinguished_name.encode_der |> Mirage_crypto.Hash.digest hash in let issuerKeyHash = Public_key.fingerprint ~hash (Certificate.public_key issuer) in {hashAlgorithm;issuerNameHash;issuerKeyHash;serialNumber} 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 Z.pp_print serialNumber module Asn_common = struct open Asn.S let cert_id = let f (hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber) = {hashAlgorithm; issuerNameHash; issuerKeyHash; serialNumber;} in let g {hashAlgorithm;issuerNameHash;issuerKeyHash;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) end let ( let* ) = Result.bind module Request = struct (* Request ::= SEQUENCE { reqCert CertID, singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } *) type request = { reqCert: cert_id; singleRequestExtensions: Extension.t option; } let create_request ?singleRequestExtensions reqCert = {reqCert;singleRequestExtensions} let pp_request ppf {reqCert;singleRequestExtensions;} = Fmt.pf ppf "Request @[<1>{@ reqCert=%a;@ singleRequestExtensions=%a;@ }@]" pp_cert_id reqCert (Fmt.option ~none:(Fmt.any "None") Extension.pp) singleRequestExtensions (* TBSRequest ::= SEQUENCE { version [0] EXPLICIT Version DEFAULT v1, requestorName [1] EXPLICIT GeneralName OPTIONAL, requestList SEQUENCE OF Request, requestExtensions [2] EXPLICIT Extensions OPTIONAL } *) type tbs_request = { requestorName: General_name.b option; requestList: request list; requestExtensions: Extension.t option; } let create_tbs_request ?requestorName ?requestExtensions requests = { requestorName ; requestList=requests ; requestExtensions } let pp_tbs_request ppf { requestorName ; requestList ; requestExtensions } = let pp_general_name ppf x = let open General_name in match x with | B (k, v) -> General_name.pp_k k ppf v in Fmt.pf ppf "TBSRequest @[<1>{@ requestorName=%a;@ requestList=[@ %a@ ];@ requestExtensions=%a@ }@]" (Fmt.option ~none:(Fmt.any "None") pp_general_name) requestorName (Fmt.list ~sep:Fmt.semi pp_request) requestList (Fmt.option ~none:(Fmt.any "None") Extension.pp) requestExtensions (* Signature ::= SEQUENCE { signatureAlgorithm AlgorithmIdentifier, signature BIT STRING, certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL} *) type signature = { signatureAlgorithm: Algorithm.t; signature: Cstruct.t; 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 (Fmt.option ~none:(Fmt.any "None") @@ Fmt.brackets @@ Fmt.list ~sep:Fmt.semi Certificate.pp) certs (* OCSPRequest ::= SEQUENCE { tbsRequest TBSRequest, optionalSignature [0] EXPLICIT Signature OPTIONAL } *) type req = { tbsRequest: tbs_request; optionalSignature: signature option; } type t = { raw : Cstruct.t ; asn : req ; } let pp ppf { asn = { tbsRequest ; optionalSignature } ; _ } = Fmt.pf ppf "OCSPRequest @[<1>{@ tbsRequest=%a;@ optionalSignature=%a@ }@]" pp_tbs_request tbsRequest (Fmt.option ~none:(Fmt.any "None") pp_signature) optionalSignature let cert_ids { asn = { tbsRequest = { requestList ; _ } ; _ } ; _ } = let cert_ids = List.map (fun {reqCert;_} -> reqCert) requestList in cert_ids let requestor_name { asn = { tbsRequest = { requestorName ; _ } ; _ } ; _ } = requestorName module Asn_ = Asn module Asn = struct open Asn_grammars open Asn.S let request = let f (reqCert, singleRequestExtensions) = {reqCert; singleRequestExtensions} in let g {reqCert; singleRequestExtensions} = (reqCert, singleRequestExtensions) in map f g @@ sequence2 (required ~label:"reqCert" Asn_common.cert_id) (optional ~label:"singleRequestExtensions" @@ explicit 0 Extension.Asn.extensions_der) let tbs_request = let f (version, requestorName, requestList, requestExtensions) = match version with | Some v when v <> version_v1 -> Asn.S.parse_error "unsupported version %d" v | _ -> { requestorName ; requestList ; requestExtensions } in let g { requestorName ; requestList ; requestExtensions } = (None, requestorName, requestList, requestExtensions) in map f g @@ sequence4 (optional ~label:"version" @@ explicit 0 int) (optional ~label:"requestorName" @@ explicit 1 General_name.Asn.general_name) (required ~label:"requestList" @@ sequence_of request) (optional ~label:"requestExtensions" @@ Extension.Asn.extensions_der) let tbs_request_of_cs,tbs_request_to_cs = projections_of Asn.der tbs_request let signature = let f (signatureAlgorithm,signature,certs) = let certs = match certs with | None -> None | Some certs -> let encode cert = let raw = Certificate.Asn.certificate_to_cstruct cert in Certificate.{raw; asn=cert} in Some (List.map encode certs) in {signatureAlgorithm;signature;certs} in let g {signatureAlgorithm;signature;certs} = let certs = match certs with | None -> None | Some certs -> Some (List.map (fun Certificate.{asn;_} -> asn) certs) in (signatureAlgorithm,signature,certs) in map f g @@ sequence3 (required ~label:"signatureAlgorithm" Algorithm.identifier) (required ~label:"signature" bit_string_cs) (optional ~label:"certs" @@ explicit 0 @@ sequence_of Certificate.Asn.certificate) let ocsp_request = let f (tbsRequest,optionalSignature) = {tbsRequest;optionalSignature;} in let g {tbsRequest;optionalSignature;} = (tbsRequest,optionalSignature) in map f g @@ sequence2 (required ~label:"tbsRequest" tbs_request) (optional ~label:"optionalSignature" signature) let (ocsp_request_of_cstruct, ocsp_request_to_cstruct) = projections_of Asn.der ocsp_request end let decode_der raw = let* asn = Asn.ocsp_request_of_cstruct raw in Ok { asn ; raw } let encode_der { raw ; _ } = raw let create ?certs ?digest ?requestor_name:requestorName ?key cert_ids = let requestList = List.map create_request cert_ids in let tbsRequest = { requestorName; requestList; requestExtensions=None; } in let* optionalSignature = match key with | None -> Ok None | Some key -> 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* 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 Ok { raw ; asn } let validate { asn ; raw } ?(allowed_hashes = Validation.sha2) pub = match asn.optionalSignature with | None -> Error `No_signature | Some sign -> let tbs_raw = Validation.raw_cert_hack raw in let dn = let cn = "OCSP" in [ Distinguished_name.(Relative_distinguished_name.singleton (CN cn)) ] in Validation.validate_raw_signature dn allowed_hashes tbs_raw sign.signatureAlgorithm sign.signature pub end module Response = struct (* OCSPResponseStatus ::= ENUMERATED { * successful (0), -- Response has valid confirmations * malformedRequest (1), -- Illegal confirmation request * internalError (2), -- Internal error in issuer * tryLater (3), -- Try again later * -- (4) is not used * sigRequired (5), -- Must sign the request * unauthorized (6) -- Request unauthorized * } *) type status = [ | `Successful | `MalformedRequest | `InternalError | `TryLater | `SigRequired | `Unauthorized ] let status_to_int = function | `Successful -> 0 | `MalformedRequest -> 1 | `InternalError -> 2 | `TryLater -> 3 | `SigRequired -> 5 | `Unauthorized -> 6 let status_of_int = function | 0 -> `Successful | 1 -> `MalformedRequest | 2 -> `InternalError | 3 -> `TryLater | 5 -> `SigRequired | 6 -> `Unauthorized | x -> Asn.S.parse_error "Unknown status %d" x let pp_status ppf = function | `Successful -> Fmt.string ppf "Successful" | `MalformedRequest -> Fmt.string ppf "MalformedRequest" | `InternalError -> Fmt.string ppf "InternalError" | `TryLater -> Fmt.string ppf "TryLater" | `SigRequired -> Fmt.string ppf "SigRequired" | `Unauthorized -> Fmt.string ppf "Unauthorized" (* RevokedInfo ::= SEQUENCE { * revocationTime GeneralizedTime, * revocationReason [0] EXPLICIT CRLReason OPTIONAL } *) type revoked_info = Ptime.t * Extension.reason option let pp_revoked_info ppf (revocationTime,revocationReason) = Fmt.pf ppf "RevokedInfo @[<1>{@ revocationTime=%a;@ revocationReason=%a;@ }@]" Ptime.pp revocationTime (Fmt.option ~none:(Fmt.any "None") @@ Extension.pp_reason) revocationReason (* CertStatus ::= CHOICE { * good [0] IMPLICIT NULL, * revoked [1] IMPLICIT RevokedInfo, * unknown [2] IMPLICIT UnknownInfo } *) type cert_status = [ | `Good | `Revoked of revoked_info | `Unknown ] let pp_cert_status ppf = function | `Good -> Fmt.pf ppf "Good" | `Revoked info -> Fmt.pf ppf "Revoked of %a" pp_revoked_info info | `Unknown -> Fmt.pf ppf "Unknown" (* SingleResponse ::= SEQUENCE { * certID CertID, * certStatus CertStatus, * thisUpdate GeneralizedTime, * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, * singleExtensions [1] EXPLICIT Extensions OPTIONAL } *) type single_response = { certID: cert_id; certStatus: cert_status; thisUpdate: Ptime.t; nextUpdate: Ptime.t option; singleExtensions: Extension.t option; } let create_single_response ?next_update:nextUpdate ?single_extensions:singleExtensions certID certStatus thisUpdate = {certID;certStatus;thisUpdate;nextUpdate;singleExtensions;} let pp_single_response ppf {certID;certStatus;thisUpdate;nextUpdate;singleExtensions;} = Fmt.pf ppf "SingleResponse @[<1>{@ certID=%a;@ certStatus=%a;@ thisUpdate=%a;@ nextUpdate=%a;@ singleExtensions=%a;@ }@]" pp_cert_id certID pp_cert_status certStatus Ptime.pp thisUpdate (Fmt.option ~none:(Fmt.any "None") @@ Ptime.pp) nextUpdate (Fmt.option ~none:(Fmt.any "None") @@ Extension.pp) singleExtensions let single_response_cert_id {certID;_} = certID let single_response_status {certStatus;_} = certStatus (* ResponderID ::= CHOICE { * byName [1] Name, * byKey [2] KeyHash } * KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key (excluding the tag and length fields) *) type responder_id = [ | `ByName of Distinguished_name.t | `ByKey of Cstruct.t ] let create_responder_id pubkey = let pubkey_fp = Public_key.fingerprint ~hash:`SHA1 pubkey in `ByKey pubkey_fp 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 (* ResponseData ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, * responderID ResponderID, * producedAt GeneralizedTime, * responses SEQUENCE OF SingleResponse, * responseExtensions [1] EXPLICIT Extensions OPTIONAL } *) type response_data = { responderID: responder_id; producedAt: Ptime.t; responses: single_response list; responseExtensions: Extension.t option; } let pp_response_data ppf { responderID ; producedAt ; responses ; responseExtensions } = Fmt.pf ppf "ResponseData @[<1>{@ responderID=%a;@ producedAt=%a;@ responses=%a;@ responseExtensions=%a@ }@]" pp_responder_id responderID Ptime.pp producedAt (Fmt.list ~sep:Fmt.semi @@ pp_single_response) responses (Fmt.option ~none:(Fmt.any "None") @@ Extension.pp) responseExtensions (* BasicOCSPResponse ::= SEQUENCE { * tbsResponseData ResponseData, * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING, * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } *) type basic_ocsp_response = { tbsResponseData: response_data; signatureAlgorithm: Algorithm.t; signature: Cstruct.t; certs: Certificate.t list option; } let pp_basic_ocsp_response ppf {tbsResponseData;signatureAlgorithm;signature;certs;} = Fmt.pf ppf "BasicOCSPResponse @[<1>{@ tbsResponseData=%a;@ signatureAlgorithm=%a;@ signature=%a;@ certs=%a@ }@]" pp_response_data tbsResponseData Algorithm.pp signatureAlgorithm Cstruct.hexdump_pp signature (Fmt.option ~none:(Fmt.any "None") @@ Fmt.list ~sep:Fmt.semi @@ Certificate.pp) certs (* ResponseBytes ::= SEQUENCE { * responseType OBJECT IDENTIFIER, * response OCTET STRING } *) (* OCSPResponse ::= SEQUENCE { * responseStatus OCSPResponseStatus, * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } *) type t = { responseStatus: status; responseBytes: (Asn.oid * basic_ocsp_response * Cstruct.t) option; } let pp ppf {responseStatus;responseBytes;} = Fmt.pf ppf "OCSPResponse @[<1>{@ responseStatus=%a;@ responseBytes=%a@ }@]" pp_status responseStatus (Fmt.option ~none:(Fmt.any "None") @@ Fmt.pair ~sep:Fmt.comma Asn.OID.pp pp_basic_ocsp_response) (match responseBytes with None -> None | Some (a, b, _) -> Some (a, b)) let status {responseStatus;_} = responseStatus let responder_id = function | {responseBytes=Some (_, {tbsResponseData={responderID;_};_}, _);_} -> Ok responderID | _ -> Error (`Msg "this response has no responseBytes") let responses = function | {responseBytes=Some (_, {tbsResponseData={responses;_};_}, _);_} -> Ok responses | _ -> Error (`Msg "this response has no responseBytes") module Asn = struct open Asn_grammars open Asn.S open Registry let status : status Asn.t = enumerated status_of_int status_to_int let revoked_info = sequence2 (required ~label:"revocationTime" generalized_time_no_frac_s) (optional ~label:"revocationReason" @@ explicit 0 @@ Extension.Asn.reason_enumerated) let cert_status : cert_status Asn.t = let f = function | `C1 () -> `Good | `C2 ri -> `Revoked ri | `C3 () -> `Unknown in let g = function | `Good -> `C1 () | `Revoked ri -> `C2 ri | `Unknown -> `C3 () in map f g @@ choice3 (implicit 0 @@ null) (implicit 1 @@ revoked_info) (implicit 2 @@ null) let single_response = let f (certID,certStatus,thisUpdate,nextUpdate,singleExtensions) = {certID;certStatus;thisUpdate;nextUpdate;singleExtensions;} in let g {certID;certStatus;thisUpdate;nextUpdate;singleExtensions;} = (certID,certStatus,thisUpdate,nextUpdate,singleExtensions) in map f g @@ sequence5 (required ~label:"certID" @@ Asn_common.cert_id) (required ~label:"certStatus" @@ cert_status) (required ~label:"thisUpdate" @@ generalized_time_no_frac_s) (optional ~label:"nextUpdate" @@ explicit 0 @@ generalized_time_no_frac_s) (optional ~label:"singleExtensions" @@ explicit 1 @@ Extension.Asn.extensions_der) let responder_id : responder_id Asn.t = let f = function | `C1 dn -> `ByName dn | `C2 hash -> `ByKey hash in let g = function | `ByName dn -> `C1 dn | `ByKey hash -> `C2 hash in map f g @@ choice2 (explicit 1 Distinguished_name.Asn.name) (explicit 2 octet_string) let response_data = let f (version, responderID, producedAt, responses, responseExtensions) = match version with | Some v when v <> version_v1 -> Asn.S.parse_error "unsupported version %d" v | _ -> { responderID ; producedAt ; responses ; responseExtensions } in let g { responderID ; producedAt ; responses ; responseExtensions } = (None, responderID, producedAt, responses, responseExtensions) in map f g @@ sequence5 (optional ~label:"version" @@ explicit 0 @@ int) (required ~label:"responderID" responder_id) (required ~label:"producedAt" generalized_time_no_frac_s) (required ~label:"responses" @@ sequence_of single_response) (optional ~label:"responseExtensions" @@ explicit 1 @@ Extension.Asn.extensions_der) let response_data_of_cs, response_data_to_cs = projections_of Asn.der response_data let basic_ocsp_response = let f (tbsResponseData,signatureAlgorithm,signature,certs) = let certs = match certs with | None -> None | Some certs -> let encode cert = let raw = Certificate.Asn.certificate_to_cstruct cert in Certificate.{raw; asn=cert} in Some (List.map encode certs) in {tbsResponseData;signatureAlgorithm;signature;certs} in let g {tbsResponseData;signatureAlgorithm;signature;certs} = let certs = match certs with | None -> None | Some certs -> Some (List.map (fun Certificate.{asn;_} -> asn) certs) in (tbsResponseData,signatureAlgorithm,signature,certs) in map f g @@ sequence4 (required ~label:"tbsResponseData" response_data) (required ~label:"signatureAlgorithm" Algorithm.identifier) (required ~label:"signature" bit_string_cs) (optional ~label:"certs" @@ explicit 0 @@ sequence_of Certificate.Asn.certificate) let basic_ocsp_response_of_cs,basic_ocsp_response_to_cs = projections_of Asn.der basic_ocsp_response let ocsp_basic_oid = Cert_extn.Private_internet_extensions.ad_ocsp_basic let ocsp_response = let f = function | `Successful, None -> 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 | Error e -> error e | Ok basic_response -> {responseStatus=`Successful; responseBytes=Some (oid, basic_response, response)} else parse_error "expected OID ad_ocsp_basic" | (`InternalError | `MalformedRequest | `SigRequired | `TryLater |`Unauthorized) as s, None -> {responseStatus=s;responseBytes=None} | _, Some _ -> parse_error "Only Successful status supports non empty responseBytes" in let g {responseStatus;responseBytes} = let responseBytes = match responseBytes with | Some (oid, _basic_response, response) -> Some (oid, response) | None -> None in (responseStatus,responseBytes) in map f g @@ sequence2 (required ~label:"responseStatus" status) (optional ~label:"responseBytes" @@ explicit 0 @@ sequence2 (required ~label:"responseType" oid) (required ~label:"response" octet_string)) let ocsp_response_of_cs, ocsp_response_to_cs = projections_of Asn.der ocsp_response end let decode_der = Asn.ocsp_response_of_cs let encode_der = Asn.ocsp_response_to_cs let create_basic_ocsp_response ?digest ?certs ?response_extensions:responseExtensions key responderID producedAt responses = 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 tbsResponseData = { responderID; producedAt; responses; responseExtensions; } in let resp_der = Asn.response_data_to_cs tbsResponseData in let* signature = Private_key.sign digest ~scheme key (`Message resp_der) in Ok { tbsResponseData ; signatureAlgorithm ; signature;certs } let create_success ?digest ?certs ?response_extensions private_key responderID producedAt responses = let* response = create_basic_ocsp_response ?digest ?certs ?response_extensions private_key responderID producedAt responses in let raw_resp = Asn.basic_ocsp_response_to_cs response in let responseBytes = Some (Asn.ocsp_basic_oid, response, raw_resp) in Ok { responseStatus = `Successful ; responseBytes } let create status = let status = match status with | `MalformedRequest -> `MalformedRequest | `InternalError -> `InternalError | `TryLater -> `TryLater | `SigRequired -> `SigRequired | `Unauthorized -> `Unauthorized in {responseStatus=status;responseBytes=None} let validate t ?(allowed_hashes = Validation.sha2) ?now pub = match t.responseBytes with | None -> Error `No_signature | Some (_oid, response, raw_resp) -> let resp_der = Validation.raw_cert_hack raw_resp in let dn = let cn = "OCSP" in [ Distinguished_name.(Relative_distinguished_name.singleton (CN cn)) ] in let* () = Validation.validate_raw_signature dn allowed_hashes resp_der response.signatureAlgorithm response.signature pub in match now with | None -> Ok () | Some now -> if List.for_all (fun single_resp -> Ptime.is_later ~than:single_resp.thisUpdate now && match single_resp.nextUpdate with | None -> true | Some until -> Ptime.is_earlier ~than:until now) response.tbsResponseData.responses then Ok () else Error `Time_invalid end ocaml-x509-0.16.5/lib/p12.ml000066400000000000000000000402411445061461400151110ustar00rootroot00000000000000(* partial PKCS12 implementation, as defined in RFC 7292 - no public/private key mode, only password privacy and integrity - algorithmidentifier those I need for openssl interop (looking at the p12 I have on my disk) - require version being 3 some definitions from PKCS7 (RFC 2315) are implemented as well, as needed *) type content_info = Asn.oid * Cstruct.t type digest_info = Algorithm.t * Cstruct.t type mac_data = digest_info * Cstruct.t * int type t = Cstruct.t * mac_data module Asn = struct open Asn_grammars open Asn.S open Registry let encrypted_content_info = let f (oid, algo, content) = if Asn.OID.equal PKCS7.data oid then (algo, content) else parse_error "expected OID PKCS7 data" and g (algo, content) = (PKCS7.data, algo, content) in Asn.S.map f g @@ sequence3 (required ~label:"content type" oid) (* here we assume data!? *) (required ~label:"content encryption algorithm" Algorithm.identifier) (optional ~label:"encrypted content" (implicit 0 octet_string)) let encrypted_data = let f (v, eci) = if v = 0 then eci else parse_error "unknown encrypted data version" and g eci = 0, eci in map f g @@ sequence2 (required ~label:"version" int) (required ~label:"encrypted content info" encrypted_content_info) let content_info = let f (oid, data) = match data with | None -> parse_error "found no value for content info" | Some `C1 data when Asn.OID.equal PKCS7.data oid -> `Data data | Some `C2 eci when Asn.OID.equal PKCS7.encrypted_data oid -> `Encrypted eci | _ -> parse_error "couldn't match PKCS7 oid with choice" and g = function | `Data data -> PKCS7.data, Some (`C1 data) | `Encrypted eci -> PKCS7.encrypted_data, Some (`C2 eci) in map f g @@ sequence2 (required ~label:"content type" oid) (optional ~label:"content" (explicit 0 (choice2 octet_string encrypted_data))) let digest_info = sequence2 (required ~label:"digest algorithm" Algorithm.identifier) (required ~label:"digest" octet_string) let mac_data = sequence3 (required ~label:"mac" digest_info) (required ~label:"mac salt" octet_string) (required ~label:"iterations" int) let pfx = let f (version, content_info, mac_data) = if version = 3 then match content_info, mac_data with | `Data data, Some md -> data, md | _, None -> parse_error "missing mac_data" | _, _ -> parse_error "unsupported content_info" else parse_error "unsupported pfx version" and g (content, mac_data) = (3, `Data content, Some mac_data) in map f g @@ sequence3 (required ~label:"version" int) (required ~label:"auth safe" content_info) (* contentType is signedData in public-key integrity mode and data in password integrity mode *) (optional ~label:"mac data" mac_data) (* not present if public keys used *) let pfx_of_cs, pfx_to_cs = projections_of Asn.der pfx (* payload is a sequence of content_info *) let authenticated_safe = sequence_of content_info let auth_safe_of_cs, auth_safe_to_cs = projections_of Asn.der authenticated_safe let pkcs12_attribute = sequence2 (required ~label:"attribute id" oid) (required ~label:"attribute value" (set_of octet_string)) (* here: key_bag = PKCS8 private key pkcs8_shrouded_key_bag = encrypted private key info == sequence2 Algorithm octet_string cert_bag = sequence2 cert_id (PKCS9 cert_types <| 1 (X509) or 2 (SDSI)) expl 0 cert_value (DER-encoded certificate) crl_bag = sequence2 crl_id (PKCS9 crl_types <| 1) (expl 0 crl (DER-encoded)) ^^^---^^^ those we plan to support secret_bag = sequence2 secret_type (expl 0 secret_value) safe_contents_bag = (any of the above) safe_contents (recursive!) *) (* since asn1 does not yet support ANY defined BY, we develop a rather complex grammar covering all supported bags *) let safe_bag = let cert_oid, crl_oid = Asn.OID.(PKCS9.cert_types <| 1, PKCS9.crl_types <| 1) in let f (oid, (a, algo, data), attrs) = match a, algo, data with | `C1 v, Some a, `C1 data when Asn.OID.equal oid PKCS12.key_bag -> let key = Private_key.Asn.reparse_private (v, a, data) in `Private_key key, attrs | `C2 id, None, `C2 data -> if Asn.OID.equal oid PKCS12.cert_bag && Asn.OID.equal id cert_oid then match Certificate.decode_der data with | Error (`Msg e) -> error (`Parse e) | Ok cert -> `Certificate cert, attrs else if Asn.OID.equal oid PKCS12.crl_bag && Asn.OID.equal id crl_oid then match Crl.decode_der data with | Error (`Msg e) -> error (`Parse e) | Ok crl -> `Crl crl, attrs else parse_error "crl bag with non-standard crl" | `C3 algo, None, `C1 data when Asn.OID.equal oid PKCS12.pkcs8_shrouded_key_bag -> `Encrypted_private_key (algo, data), attrs | _ -> parse_error "safe bag OID not supported" and g (v, attrs) = let oid, d = match v with | `Encrypted_private_key (algo, data) -> PKCS12.pkcs8_shrouded_key_bag, (`C3 algo, None, `C1 data) | `Private_key pk -> let v, algo, data = Private_key.Asn.unparse_private pk in PKCS12.key_bag, (`C1 v, Some algo, `C1 data) | `Certificate cert -> PKCS12.cert_bag, (`C2 cert_oid, None, `C2 (Certificate.encode_der cert)) | `Crl crl -> PKCS12.crl_bag, (`C2 crl_oid, None, `C2 (Crl.encode_der crl)) in (oid, d, attrs) in map f g @@ sequence3 (required ~label:"bag id" oid) (required ~label:"bag value" (explicit 0 (sequence3 (required ~label:"fst" (choice3 int oid Algorithm.identifier)) (optional ~label:"algorithm" Algorithm.identifier) (required ~label:"data" (choice2 octet_string (explicit 0 octet_string)))))) (* (explicit 0 (* encrypted private key *) (sequence2 (required ~label:"encryption algorithm" Algorithm.identifier) (required ~label:"encrypted data" octet_string))) *) (* (explicit 0 (* private key ] *) (sequence3 (required ~label:"version" int) (required ~label:"privateKeyAlgorithm" Algorithm.identifier) (required ~label:"privateKey" octet_string))) *) (* (explicit 0 (* cert / crl *) (sequence2 (required ~label:"oid" oid) (required ~label:"data" (explicit 0 octet_string)))) *) (optional ~label:"bag attributes" (set_of pkcs12_attribute)) let safe_contents = sequence_of safe_bag let safe_contents_of_cs, safe_contents_to_cs = projections_of Asn.der safe_contents end let prepare_pw str = let l = String.length str in let cs = Cstruct.create ((succ l) * 2) in for i = 0 to pred l do Cstruct.set_char cs (succ (i * 2)) (String.get str i) done; 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 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 in let rec c off = if off < len then begin Cstruct.blit 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 if l = 0 then data else let len = size * ((l + size - 1) / size) in let buf = Cstruct.create len in fill ~data ~out:buf; buf let pbes algorithm purpose password salt iterations n = let pw = prepare_pw password and v = v algorithm and u = Mirage_crypto.Hash.digest_size algorithm 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 rec one off i = let ai = ref (Mirage_crypto.Hash.digest algorithm (Cstruct.append diversifier i)) in for _j = 1 to pred iterations do ai := Mirage_crypto.Hash.digest algorithm !ai; done; Cstruct.blit !ai 0 out off (min (n - off) u); if u >= n - off then () else (* 6B *) let b = Cstruct.create v 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 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 lsr 8; done; done; one (off + u) i' in let i = Cstruct.append salt pass in one 0 i; out (* 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 if l > 0 then let amount = Cstruct.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 good = ref true in for i = 0 to pred amount do if Cstruct.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 to_pad = bs - (l mod bs) in let amount = Cstruct.create to_pad in Cstruct.memset amount to_pad; Cstruct.append x amount let ( let* ) = Result.bind (* there are 3 possibilities to encrypt / decrypt things: - PKCS12 KDF (see above), with RC2/RC4/DES - PKCS5 v1 (PBES, PBKDF1) -- not (yet?) supported - PKCS5 v2 (PBES2, PBKDF2) *) let pkcs12_decrypt algo password data = let open Algorithm in let hash = `SHA1 in let* salt, count, key_len, iv_len = match algo with | SHA_RC4_128 (s, i) -> Ok (s, i, 16, 0) | SHA_RC4_40 (s, i) -> Ok (s, i, 5, 0) | SHA_3DES_CBC (s, i) -> Ok (s, i, 24, 8) | SHA_2DES_CBC (s, i) -> Ok (s, i, 16, 8) (* TODO 2des -> 3des keys (if relevant)*) | SHA_RC2_128_CBC (s, i) -> Ok (s, i, 16, 8) | SHA_RC2_40_CBC (s, i) -> Ok (s, i, 5, 8) | _ -> Error (`Msg "unsupported algorithm") in let key = pbes hash `Encryption password salt count key_len and iv = pbes hash `Iv password salt count iv_len 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") in Ok (unpad data) let pkcs5_2_decrypt kdf enc password data = let* dk_len, iv = match enc with | Algorithm.AES128_CBC iv -> Ok (16l, iv) | Algorithm.AES192_CBC iv -> Ok (24l, iv) | Algorithm.AES256_CBC iv -> Ok (32l, iv) | _ -> Error (`Msg "unsupported encryption algorithm") in let* salt, count, prf = match kdf with | Algorithm.PBKDF2 (salt, iterations, _ (* todo handle keylength *), prf) -> let* prf = match Algorithm.to_hmac prf with | Some prf -> Ok prf | None -> Error (`Msg "unsupported PRF") in 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 bs = Mirage_crypto.Cipher_block.AES.CBC.block_size in let iv = Mirage_crypto_rng.generate bs in let enc, dk_len = match algo with | `AES128_CBC -> Algorithm.AES128_CBC iv, 16l | `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 key = Mirage_crypto.Cipher_block.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 in let kdf = Algorithm.PBKDF2 (salt, count, None, Algorithm.of_hmac mac) in Algorithm.PBES2 (kdf, enc), enc_data let decrypt algo password data = let open Algorithm in match algo with | SHA_RC4_128 _ | SHA_RC4_40 _ | SHA_3DES_CBC _ | SHA_2DES_CBC _ | SHA_RC2_128_CBC _ | SHA_RC2_40_CBC _ -> pkcs12_decrypt algo password data | PBES2 (kdf, enc) -> pkcs5_2_decrypt kdf enc password data | _ -> Error (`Msg "unsupported encryption algorithm") let password_decrypt password (algo, data) = match data with | None -> Error (`Msg "no data to decrypt") | Some data -> decrypt algo password data let verify password (data, ((algorithm, digest), salt, iterations)) = let* hash = Option.to_result ~none:(`Msg "unsupported hash algorithm") (Algorithm.to_hash algorithm) in let key = pbes hash `Hmac password salt iterations (Mirage_crypto.Hash.digest_size hash) in let computed = Mirage_crypto.Hash.mac hash ~key data in if Cstruct.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 -> let* acc = acc in match c with | `Data data -> Ok (data :: acc) | `Encrypted data -> let* data = password_decrypt password data in Ok (data :: acc)) (Ok []) content in List.fold_left (fun acc cs -> let* acc = acc in let* bags = Asn_grammars.err_to_msg (Asn.safe_contents_of_cs cs) in List.fold_left (fun acc bag -> let* acc = acc in match bag with | `Certificate c, _ -> Ok (`Certificate c :: acc) | `Crl c, _ -> Ok (`Crl c :: acc) | `Private_key p, _ -> Ok (`Private_key p :: acc) | `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) in Ok (`Decrypted_private_key p :: acc)) (Ok acc) bags) (Ok []) safe_contents end else Error (`Msg "invalid signature") let create ?(mac = `SHA256) ?(algorithm = `AES256_CBC) ?(iterations = 2048) password certificates private_key = let key_fp pub = Public_key.fingerprint pub in 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 Some attributes else None in 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 algo, data = pkcs5_2_encrypt mac iterations algorithm password data in Asn.safe_contents_to_cs [ `Encrypted_private_key (algo, data), Some attributes ] in let cert_sc_enc = let algo, data = pkcs5_2_encrypt mac iterations algorithm password cert_sc in algo, Some data in 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 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 auth_data, ((Algorithm.of_hash mac, digest), salt, iterations) let decode_der cs = Asn_grammars.err_to_msg (Asn.pfx_of_cs cs) let encode_der = Asn.pfx_to_cs ocaml-x509-0.16.5/lib/pem.ml000066400000000000000000000057421445061461400152770ustar00rootroot00000000000000let ( let* ) = Result.bind module Cs = struct open Cstruct let begins_with cs target = let l1 = length cs and l2 = length target in l1 >= l2 && equal (sub cs 0 l2) target let ends_with cs target = let l1 = length cs and l2 = length target in l1 >= l2 && equal (sub cs (l1 - l2) l2) target let null cs = length cs = 0 let open_begin = of_string "-----BEGIN " and open_end = of_string "-----END " and close = of_string "-----" let tok_of_line cs = if null cs then `Empty else if get_char 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)) else if begins_with cs open_end && ends_with cs close then `End (to_string @@ sub cs 9 (length cs - 14)) else `Data cs let chop cs off len = let (a, b) = split cs off in (a, shift b len) 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 | '\n' -> chop cs i 1 | _ -> eol (i + 1) in match eol 0 with | exception Invalid_argument _ -> [ tok_of_line cs ] | a, b -> tok_of_line a :: lines b let combine ilines = let rec accumulate t acc = function | `Empty :: tail -> accumulate t acc tail | `Data cs :: tail -> accumulate t (cs :: acc) tail | `End t' :: tail -> if String.equal t t' then Ok (concat (List.rev acc), tail) else Error (`Msg ("invalid end, expected " ^ t ^ ", found " ^ t')) | _ :: _ -> Error (`Msg "invalid line, expected data or end") | [] -> Error (`Msg "end of input") in 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 | _::xs -> block acc xs | [] -> Ok (List.rev acc) in block [] ilines let parse data= combine (lines data) let unparse ~tag value = let rec split_at_64 acc = function | x when length x <= 64 -> List.rev (x :: acc) | 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 pieces = split_at_64 [] raw in let nl = of_string "\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) end let parse, unparse = Cs.(parse, unparse) let exactly_one ~what = function | [] -> Error (`Msg ("No " ^ what)) | [x] -> Ok x | _ -> Error (`Msg ("Multiple " ^ what ^ "s")) let foldM f data = let wrap acc data = let* datas' = acc in let* data = f data in Ok (data :: datas') in let* res = List.fold_left wrap (Ok []) data in Ok (List.rev res) ocaml-x509-0.16.5/lib/private_key.ml000066400000000000000000000243031445061461400170320ustar00rootroot00000000000000let ( 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 ] type t = [ ecdsa | `RSA of Mirage_crypto_pk.Rsa.priv | `ED25519 of Mirage_crypto_ec.Ed25519.priv ] let key_type = function | `RSA _ -> `RSA | `ED25519 _ -> `ED25519 | `P224 _ -> `P224 | `P256 _ -> `P256 | `P384 _ -> `P384 | `P521 _ -> `P521 let generate ?seed ?(bits = 4096) typ = let g = match seed with | None -> None | Some seed -> Some Mirage_crypto_rng.(create ~seed (module Fortuna)) in 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 ())) let of_cstruct data = let open Mirage_crypto_ec in let ec_err e = Result.map_error (fun e -> `Msg (Fmt.to_to_string Mirage_crypto_ec.pp_error e)) e in function | `RSA -> Error (`Msg "cannot decode an RSA key") | `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) | `P384 -> let* k = ec_err (P384.Dsa.priv_of_cstruct data) in Ok (`P384 k) | `P521 -> let* k = ec_err (P521.Dsa.priv_of_cstruct 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) | _ -> let* data = Base64.decode data in of_cstruct (Cstruct.of_string data) typ end | Some `Seed -> Ok (generate ~seed:(Cstruct.of_string data) ?bits typ) | Some `Data -> let* data = Base64.decode data in of_cstruct (Cstruct.of_string data) typ 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) 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 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 PSS = Mirage_crypto_pk.Rsa.PSS(H) in let* d = hashed () in Ok (PSS.sign ~key (`Digest d)) | `RSA key, `RSA_PKCS1 -> let* d = hashed () in Ok (Mirage_crypto_pk.Rsa.PKCS1.sign ~key ~hash (`Digest d)) | `ED25519 key, `ED25519 -> begin match data with | `Message m -> Ok (Ed25519.sign ~key m) | `Digest _ -> Error (`Msg "Ed25519 only suitable with raw message") end | #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)))) | _ -> Error (`Msg "invalid key and signature scheme combination") with | Mirage_crypto_pk.Rsa.Insufficient_key -> Error (`Msg "RSA key of insufficient length") | Message_too_long -> Error (`Msg "message too long") module Asn = struct open Asn.S open Mirage_crypto_pk (* RSA *) let other_prime_infos = sequence_of @@ (sequence3 (required ~label:"prime" integer) (required ~label:"exponent" integer) (required ~label:"coefficient" integer)) let rsa_private_key = let f (v, (n, (e, (d, (p, (q, (dp, (dq, (q', other))))))))) = match (v, other) with | (0, None) -> begin match Rsa.priv ~e ~d ~n ~p ~q ~dp ~dq ~q' with | Ok p -> p | Error (`Msg m) -> parse_error "bad RSA private key %s" m end | _ -> parse_error "multi-prime RSA keys not supported" and g { Rsa.e; d; n; p; q; dp; dq; q' } = (0, (n, (e, (d, (p, (q, (dp, (dq, (q', None))))))))) in map f g @@ sequence @@ (required ~label:"version" int) @ (required ~label:"modulus" integer) (* n *) @ (required ~label:"publicExponent" integer) (* e *) @ (required ~label:"privateExponent" integer) (* d *) @ (required ~label:"prime1" integer) (* p *) @ (required ~label:"prime2" integer) (* q *) @ (required ~label:"exponent1" integer) (* dp *) @ (required ~label:"exponent2" integer) (* dq *) @ (required ~label:"coefficient" integer) (* qinv *) -@ (optional ~label:"otherPrimeInfos" other_prime_infos) (* For outside uses. *) let (rsa_private_of_cstruct, rsa_private_to_cstruct) = Asn_grammars.projections_of Asn.der rsa_private_key (* PKCS8 *) let (rsa_priv_of_cs, rsa_priv_to_cs) = 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 = Asn_grammars.project_exn octet_string let ec_private_key = let f (v, pk, nc, pub) = if v <> 1 then parse_error "bad version for ec Private key" else let curve = match nc with | Some c -> Some (Algorithm.curve_of_oid c) | None -> None in pk, curve, pub and g (pk, curve, pub) = let nc = match curve with | None -> None | Some c -> Some (Algorithm.curve_to_oid c) in (1, pk, nc, pub) in Asn.S.map f g @@ sequence4 (required ~label:"version" int) (* ecPrivkeyVer1(1) *) (required ~label:"privateKey" octet_string) (* from rfc5480: choice3, but only namedCurve is allowed in PKIX *) (optional ~label:"namedCurve" (explicit 0 oid)) (optional ~label:"publicKey" (explicit 1 bit_string)) let ec_of_cs, ec_to_cs = Asn_grammars.project_exn ec_private_key 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) (* external use (result) *) let ec_priv_of_cs = let dec, _ = Asn_grammars.projections_of Asn.der ec_private_key in fun cs -> let* priv, curve, _pub = dec cs in match curve with | None -> Error (`Parse "no curve provided") | Some c -> Result.map_error (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 nc = match curve, named_curve with | Some c, None -> c | None, Some c -> c | Some c, Some c' -> if c = c' then c else parse_error "conflicting curve" | None, None -> parse_error "unknown curve" in ec_to_err (reparse_ec_private nc priv) let ec_to_cs ?curve ?pub key = ec_to_cs (key, curve, pub) let reparse_private pk = match pk with | (0, Algorithm.RSA, cs) -> `RSA (rsa_priv_of_cs 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 | _ -> parse_error "unknown private key info" let unparse_private p = let open Mirage_crypto_ec in 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) | `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) in (0, alg, cs) let private_key_info = map reparse_private unparse_private @@ sequence3 (required ~label:"version" int) (required ~label:"privateKeyAlgorithm" Algorithm.identifier) (required ~label:"privateKey" octet_string) (* TODO: there's an (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) = Asn_grammars.projections_of Asn.der private_key_info end let decode_der cs = Asn_grammars.err_to_msg (Asn.private_of_cstruct cs) let encode_der = Asn.private_to_cstruct let decode_pem cs = let* data = Pem.parse cs in let rsa_p (t, _) = String.equal "RSA PRIVATE KEY" t and ec_p (t, _) = String.equal "EC PRIVATE KEY" t and pk_p (t, _) = String.equal "PRIVATE KEY" t in let r, _ = List.partition rsa_p data and ec, _ = List.partition ec_p data and p, _ = List.partition pk_p data in let* k = Pem.foldM (fun (_, k) -> let* k = Asn_grammars.err_to_msg (Asn.rsa_private_of_cstruct 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 in let* k'' = Pem.foldM (fun (_, k) -> Asn_grammars.err_to_msg (Asn.private_of_cstruct 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) ocaml-x509-0.16.5/lib/public_key.ml000066400000000000000000000126661445061461400166470ustar00rootroot00000000000000let ( 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 ] type t = [ | ecdsa | `RSA of Mirage_crypto_pk.Rsa.pub | `ED25519 of Mirage_crypto_ec.Ed25519.pub ] module Asn_oid = Asn.OID module Asn = struct open Asn_grammars open Asn.S open Mirage_crypto_pk let rsa_public_key = let f (n, e) = 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 map f g @@ sequence2 (required ~label:"modulus" integer) (required ~label:"publicExponent" integer) let (rsa_public_of_cstruct, rsa_public_to_cstruct) = projections_of Asn.der rsa_public_key let rsa_pub_of_cs, rsa_pub_to_cs = project_exn rsa_public_key let to_err = function | Ok r -> r | Error e -> parse_error "failed to decode public EC key %a" Mirage_crypto_ec.pp_error e let reparse_pk = 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 `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)) | _ -> 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) | `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) let pk_info_der = map reparse_pk unparse_pk @@ sequence2 (required ~label:"algorithm" Algorithm.identifier) (required ~label:"subjectPK" bit_string_cs) let (pub_info_of_cstruct, pub_info_to_cstruct) = 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 | `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 in Mirage_crypto.Hash.digest `SHA1 data let fingerprint ?(hash = `SHA256) pub = Mirage_crypto.Hash.digest hash (Asn.pub_info_to_cstruct pub) let key_type = function | `RSA _ -> `RSA | `ED25519 _ -> `ED25519 | `P224 _ -> `P224 | `P256 _ -> `P256 | `P384 _ -> `P384 | `P521 _ -> `P521 let sig_alg = function | #ecdsa -> `ECDSA | `RSA _ -> `RSA | `ED25519 _ -> `ED25519 let pp ppf k = Fmt.string ppf (Key_type.to_string (key_type k)); Fmt.sp ppf (); Cstruct.hexdump_pp ppf (fingerprint k) let hashed hash data = match data with | `Message msg -> Ok (Mirage_crypto.Hash.digest hash msg) | `Digest d -> let n = Cstruct.length d and m = Mirage_crypto.Hash.digest_size hash 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 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 = Result.map_error (function `Parse s -> `Msg s) (Algorithm.ecdsa_sig_of_cstruct 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 PSS = Mirage_crypto_pk.Rsa.PSS(H) in let* d = hashed hash data in ok_if_true (PSS.verify ~key ~signature (`Digest d)) | `RSA key, `RSA_PKCS1 -> let hashp x = x = hash in let* d = hashed hash data in ok_if_true (Mirage_crypto_pk.Rsa.PKCS1.verify ~hashp ~key ~signature (`Digest d)) | `ED25519 key, `ED25519 -> begin match data with | `Message msg -> ok_if_true (Ed25519.verify ~key signature ~msg) | `Digest _ -> Error (`Msg "Ed25519 only suitable with raw message") end | #ecdsa as key, `ECDSA -> let* d = hashed hash data in 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)) | _ -> Error (`Msg "invalid key and signature scheme combination") let encode_der = Asn.pub_info_to_cstruct let decode_der cs = Asn_grammars.err_to_msg (Asn.pub_info_of_cstruct cs) let decode_pem cs = let* data = Pem.parse cs in let pks = List.filter (fun (t, _) -> String.equal "PUBLIC KEY" t) data in let* keys = Pem.foldM (fun (_, k) -> decode_der k) pks in Pem.exactly_one ~what:"public key" keys let encode_pem v = Pem.unparse ~tag:"PUBLIC KEY" (encode_der v) ocaml-x509-0.16.5/lib/rc2.ml000066400000000000000000000140411445061461400151740ustar00rootroot00000000000000 let pitable = [| 0xd9; 0x78; 0xf9; 0xc4; 0x19; 0xdd; 0xb5; 0xed; 0x28; 0xe9; 0xfd; 0x79; 0x4a; 0xa0; 0xd8; 0x9d; 0xc6; 0x7e; 0x37; 0x83; 0x2b; 0x76; 0x53; 0x8e; 0x62; 0x4c; 0x64; 0x88; 0x44; 0x8b; 0xfb; 0xa2; 0x17; 0x9a; 0x59; 0xf5; 0x87; 0xb3; 0x4f; 0x13; 0x61; 0x45; 0x6d; 0x8d; 0x09; 0x81; 0x7d; 0x32; 0xbd; 0x8f; 0x40; 0xeb; 0x86; 0xb7; 0x7b; 0x0b; 0xf0; 0x95; 0x21; 0x22; 0x5c; 0x6b; 0x4e; 0x82; 0x54; 0xd6; 0x65; 0x93; 0xce; 0x60; 0xb2; 0x1c; 0x73; 0x56; 0xc0; 0x14; 0xa7; 0x8c; 0xf1; 0xdc; 0x12; 0x75; 0xca; 0x1f; 0x3b; 0xbe; 0xe4; 0xd1; 0x42; 0x3d; 0xd4; 0x30; 0xa3; 0x3c; 0xb6; 0x26; 0x6f; 0xbf; 0x0e; 0xda; 0x46; 0x69; 0x07; 0x57; 0x27; 0xf2; 0x1d; 0x9b; 0xbc; 0x94; 0x43; 0x03; 0xf8; 0x11; 0xc7; 0xf6; 0x90; 0xef; 0x3e; 0xe7; 0x06; 0xc3; 0xd5; 0x2f; 0xc8; 0x66; 0x1e; 0xd7; 0x08; 0xe8; 0xea; 0xde; 0x80; 0x52; 0xee; 0xf7; 0x84; 0xaa; 0x72; 0xac; 0x35; 0x4d; 0x6a; 0x2a; 0x96; 0x1a; 0xd2; 0x71; 0x5a; 0x15; 0x49; 0x74; 0x4b; 0x9f; 0xd0; 0x5e; 0x04; 0x18; 0xa4; 0xec; 0xc2; 0xe0; 0x41; 0x6e; 0x0f; 0x51; 0xcb; 0xcc; 0x24; 0x91; 0xaf; 0x50; 0xa1; 0xf4; 0x70; 0x39; 0x99; 0x7c; 0x3a; 0x85; 0x23; 0xb8; 0xb4; 0x7a; 0xfc; 0x02; 0x36; 0x5b; 0x25; 0x55; 0x97; 0x31; 0x2d; 0x5d; 0xfa; 0x98; 0xe3; 0x8a; 0x92; 0xae; 0x05; 0xdf; 0x29; 0x10; 0x67; 0x6c; 0xba; 0xc9; 0xd3; 0x00; 0xe6; 0xcf; 0xe1; 0x9e; 0xa8; 0x2c; 0x63; 0x16; 0x01; 0x3f; 0x58; 0xe2; 0x89; 0xa9; 0x0d; 0x38; 0x34; 0x1b; 0xab; 0x33; 0xff; 0xb0; 0xbb; 0x48; 0x0c; 0x5f; 0xb9; 0xb1; 0xcd; 0x2e; 0xc5; 0xf3; 0xdb; 0x47; 0xe5; 0xa5; 0x9c; 0x77; 0x0a; 0xa6; 0x20; 0x68; 0xfe; 0x7f; 0xc1; 0xad |] (* effective is sometimes named t1 *) let tm effective = let t8 = (effective + 7) / 8 in (* RFC says (TM = 255 MOD 2^(8 + effective - 8*T8)) *) let bits = 8 + effective - 8 * t8 in (* likely there's a smarter way to do this *) let rec c acc = function | 0 -> acc | n -> c ((acc lsl 1) + 1) (pred n) in t8, c 0 bits (* 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 t8, tm = tm effective in for i = t to 127 do l.(i) <- pitable.((l.(i - 1) + l.(i - t)) mod 256) done; l.(128 - t8) <- pitable.(l.(128 - t8) land tm); for i = 127 - t8 downto 0 do l.(i) <- pitable.(l.(i + 1) lxor l.(i + t8)); done; Array.init 64 (fun idx -> l.(2 * idx) + 256 * l.(2 * idx + 1)) let mod16 f = 0xFFFF land f let rol16 x k = mod16 ((x lsl k) lor (x lsr (16 - k))) let ror16 x k = mod16 ((x lsr k) lor (x lsl (16 - k))) let not16 x = mod16 (lnot x) let s = Array.init 4 (function 0 -> 1 | 1 -> 2 | 2 -> 3 | 3 -> 5 | _ -> assert false) let pmod a = let b = 4 in let r = a mod b in if r < 0 then (r + b) mod b else r (* only used for encryption which we don't support let mix r i k j = r.(i) <- mod16 (r.(i) + k.(j) + r.(pmod (i - 1)) land r.(pmod (i - 2)) + (not16 r.(pmod (i - 1))) land r.(pmod (i - 3))); let j = succ j in r.(i) <- rol16 r.(i) s.(i); j let mix_round r k j = let j' = mix r 0 k j in let j'' = mix r 1 k j' in let j''' = mix r 2 k j'' in let j'''' = mix r 3 k j''' in j'''' let mash r i k = r.(i) <- mod16 (r.(i) + k.(r.(pmod (i - 1)) land 63)) let mash_round r k = mash r 0 k; mash r 1 k; mash r 2 k; mash r 3 k let encrypt_one ~key ~data = let r = Array.init 4 (fun idx -> Cstruct.LE.get_uint16 data (idx * 2)) in let j = 0 in let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in mash_round r key; let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in mash_round r key; let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in let j = mix_round r key j in let _j = mix_round r key j in let out = Cstruct.create 8 in Cstruct.LE.set_uint16 out 0 r.(0); Cstruct.LE.set_uint16 out 2 r.(1); Cstruct.LE.set_uint16 out 4 r.(2); Cstruct.LE.set_uint16 out 6 r.(3); out *) let r_mix r i k j = r.(i) <- ror16 r.(i) s.(i); r.(i) <- mod16 (r.(i) - k.(j) - (r.(pmod (i - 1)) land r.(pmod (i - 2))) - (not16 r.(pmod (i - 1)) land (r.(pmod (i - 3))))); pred j let r_mix_round r k j = let j' = r_mix r 3 k j in let j'' = r_mix r 2 k j' in let j''' = r_mix r 1 k j'' in let j'''' = r_mix r 0 k j''' in j'''' let r_mash r i k = r.(i) <- mod16 (r.(i) - k.(r.(pmod (i - 1)) land 63)) let r_mash_round r k = r_mash r 3 k; r_mash r 2 k; r_mash r 1 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 j = 63 in 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 let j = r_mix_round r key j in let j = r_mix_round r key j in r_mash_round r key; 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 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 r_mash_round r key; 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 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) 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 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 ocaml-x509-0.16.5/lib/registry.ml000066400000000000000000000244471445061461400163710ustar00rootroot00000000000000 (* * Object Identifiers: magic numbers with a tie. Some OIDs also have an MBA. * * http://www.alvestrand.no/objectid/ * http://oid-info.com/ *) open Asn.OID let pkix = base 1 3 <| 6 <| 1 <| 5 <| 5 <| 7 let usa = base 1 2 <| 840 let rsadsi = usa <| 113549 let pkcs = rsadsi <| 1 let us_govt = base 2 16 <| 840 <| 1 <| 101 let nist_alg = us_govt <| 3 <| 4 let hash_algs = nist_alg <| 2 (* PKCS1 *) let md2 = rsadsi <| 2 <| 2 and md4 = rsadsi <| 2 <| 4 and md5 = rsadsi <| 2 <| 5 and sha1 = base 1 3 <| 14 <| 3 <| 2 <| 26 (* rfc5758 *) let sha256 = hash_algs <| 1 and sha384 = hash_algs <| 2 and sha512 = hash_algs <| 3 and sha224 = hash_algs <| 4 and sha512_224 = hash_algs <| 5 and sha512_256 = hash_algs <| 6 module ANSI_X9_62 = struct let ansi_x9_62 = usa <| 10045 let ecdsa_sha1 = ansi_x9_62 <| 1 let prime_field = ecdsa_sha1 <| 1 and characteristic_2_field = ecdsa_sha1 <| 2 let key_type = ansi_x9_62 <| 2 let ec_pub_key = key_type <| 1 let signatures = ansi_x9_62 <| 4 let field_type = signatures <| 1 and ecdsa_sha2 = signatures <| 3 let ecdsa_sha224 = ecdsa_sha2 <| 1 and ecdsa_sha256 = ecdsa_sha2 <| 2 and ecdsa_sha384 = ecdsa_sha2 <| 3 and ecdsa_sha512 = ecdsa_sha2 <| 4 (* from RFC 5480 *) let certicom = base 1 3 <| 132 <| 0 let curves = ansi_x9_62 <| 3 <| 1 let secp224r1 = certicom <| 33 let secp256r1 = curves <| 7 let secp384r1 = certicom <| 34 let secp521r1 = certicom <| 35 end module PKCS1 = struct let pkcs1 = pkcs <| 1 let rsa_encryption = pkcs1 <| 1 and md2_rsa_encryption = pkcs1 <| 2 and md4_rsa_encryption = pkcs1 <| 3 and md5_rsa_encryption = pkcs1 <| 4 and sha1_rsa_encryption = pkcs1 <| 5 and ripemd160_rsa_encryption = pkcs1 <| 6 and rsaes_oaep = pkcs1 <| 7 and rsassa_pss = pkcs1 <| 10 and sha256_rsa_encryption = pkcs1 <| 11 and sha384_rsa_encryption = pkcs1 <| 12 and sha512_rsa_encryption = pkcs1 <| 13 and sha224_rsa_encryption = pkcs1 <| 14 end module RFC8410 = struct let thawte = base 1 3 <| 101 let x25519 = thawte <| 110 and x448 = thawte <| 111 and ed25519 = thawte <| 112 and ed448 = thawte <| 113 end module PKCS2 = struct let pkcs2 = rsadsi <| 2 let md4 = pkcs2 <| 4 and hmac_sha1 = pkcs2 <| 7 and hmac_sha224 = pkcs2 <| 8 and hmac_sha256 = pkcs2 <| 9 and hmac_sha384 = pkcs2 <| 10 and hmac_sha512 = pkcs2 <| 11 end module PKCS5 = struct let pkcs5 = pkcs <| 5 let pbe_md2_des_cbc = pkcs5 <| 1 and pbe_md5_des_cbc = pkcs5 <| 3 and pbe_md2_rc2_cbc = pkcs5 <| 4 and pbe_md5_rc2_cbc = pkcs5 <| 6 and pbe_md5_xor = pkcs5 <| 9 and pbe_sha1_des_cbc = pkcs5 <| 10 and pbe_sha1_rc2_cbc = pkcs5 <| 11 and pbkdf2 = pkcs5 <| 12 and pbes2 = pkcs5 <| 13 and pbmac1 = pkcs5 <| 14 let aes = nist_alg <| 1 let aes128_cbc = aes <| 2 and aes192_cbc = aes <| 22 and aes256_cbc = aes <| 42 end module PKCS7 = struct let pkcs7 = pkcs <| 7 let data = pkcs7 <| 1 and signed_data = pkcs7 <| 2 and enveloped_data = pkcs7 <| 3 and signed_and_enveloped_data = pkcs7 <| 4 and digested_data = pkcs7 <| 5 and encrypted_data = pkcs7 <| 6 end module PKCS9 = struct let pkcs9 = pkcs <| 9 let email = pkcs9 <| 1 and unstructured_name = pkcs9 <| 2 and content_type = pkcs9 <| 3 and message_digest = pkcs9 <| 4 and signing_time = pkcs9 <| 5 and challenge_password = pkcs9 <| 7 and unstructured_address = pkcs9 <| 8 and signing_description = pkcs9 <| 13 and extension_request = pkcs9 <| 14 and smime_capabilities = pkcs9 <| 15 and smime_oid_registry = pkcs9 <| 16 and friendly_name = pkcs9 <| 20 and local_key_id = pkcs9 <| 21 and cert_types = pkcs9 <| 22 and crl_types = pkcs9 <| 23 end module PKCS12 = struct let pkcs12 = pkcs <| 12 let bagtypes = pkcs12 <| 10 <| 1 let key_bag = bagtypes <| 1 and pkcs8_shrouded_key_bag = bagtypes <| 2 and cert_bag = bagtypes <| 3 and crl_bag = bagtypes <| 4 and secret_bag = bagtypes <| 5 and safe_contents_bag = bagtypes <| 6 let pbe_ids = pkcs12 <| 1 let pbe_with_SHA_and_128Bit_RC4 = pbe_ids <| 1 and pbe_with_SHA_and_40Bit_RC4 = pbe_ids <| 2 and pbe_with_SHA_and_3_KeyTripleDES_CBC = pbe_ids <| 3 and pbe_with_SHA_and_2_KeyTripleDES_CBC = pbe_ids <| 4 and pbe_with_SHA_and_128Bit_RC2_CBC = pbe_ids <| 5 and pbe_with_SHA_and_40Bit_RC2_CBC = pbe_ids <| 6 end module X520 = struct let x520 = base 2 5 <| 4 let object_class = x520 <| 0 and aliased_entry_name = x520 <| 1 and knowldgeinformation = x520 <| 2 and common_name = x520 <| 3 and surname = x520 <| 4 and serial_number = x520 <| 5 and country_name = x520 <| 6 and locality_name = x520 <| 7 and state_or_province_name = x520 <| 8 and street_address = x520 <| 9 and organization_name = x520 <| 10 and organizational_unit_name = x520 <| 11 and title = x520 <| 12 and description = x520 <| 13 and search_guide = x520 <| 14 and business_category = x520 <| 15 and postal_address = x520 <| 16 and postal_code = x520 <| 17 and post_office_box = x520 <| 18 and physical_delivery_office_name = x520 <| 19 and telephone_number = x520 <| 20 and telex_number = x520 <| 21 and teletex_terminal_identifier = x520 <| 22 and facsimile_telephone_number = x520 <| 23 and x121_address = x520 <| 24 and internationa_isdn_number = x520 <| 25 and registered_address = x520 <| 26 and destination_indicator = x520 <| 27 and preferred_delivery_method = x520 <| 28 and presentation_address = x520 <| 29 and supported_application_context = x520 <| 30 and member = x520 <| 31 and owner = x520 <| 32 and role_occupant = x520 <| 33 and see_also = x520 <| 34 and user_password = x520 <| 35 and user_certificate = x520 <| 36 and ca_certificate = x520 <| 37 and authority_revocation_list = x520 <| 38 and certificate_revocation_list = x520 <| 39 and cross_certificate_pair = x520 <| 40 and name = x520 <| 41 and given_name = x520 <| 42 and initials = x520 <| 43 and generation_qualifier = x520 <| 44 and unique_identifier = x520 <| 45 and dn_qualifier = x520 <| 46 and enhanced_search_guide = x520 <| 47 and protocol_information = x520 <| 48 and distinguished_name = x520 <| 49 and unique_member = x520 <| 50 and house_identifier = x520 <| 51 and supported_algorithms = x520 <| 52 and delta_revocation_list = x520 <| 53 and attribute_certificate = x520 <| 58 and pseudonym = x520 <| 65 end let ucl_data_networks = base 0 9 <| 2342 <| 19200300 let directory_pilot = ucl_data_networks <| 100 <| 1 (* The single rfc4519 oid rfc5280 requires us to be aware of.... *) let domain_component = directory_pilot <| 25 (* rfc4514 oid required for compliance *) let userid = directory_pilot <| 1 module Cert_extn = struct let ce = base 2 5 <| 29 let authority_key_identifier_old = ce <| 1 and primary_key_attributes_old = ce <| 2 and certificate_policies_1 = ce <| 3 and primary_key_usage_restriction = ce <| 4 and subject_directory_attributes = ce <| 9 and subject_key_identifier = ce <| 14 and key_usage = ce <| 15 and private_key_usage_period = ce <| 16 and subject_alternative_name = ce <| 17 and issuer_alternative_name = ce <| 18 and basic_constraints = ce <| 19 and crl_number = ce <| 20 and reason_code = ce <| 21 and hold_instruction_code = ce <| 23 and invalidity_date = ce <| 24 and delta_crl_indicator = ce <| 27 and issuing_distribution_point = ce <| 28 and certificate_issuer = ce <| 29 and name_constraints = ce <| 30 and crl_distribution_points = ce <| 31 and certificate_policies_2 = ce <| 32 and policy_mappings = ce <| 33 and authority_key_identifier = ce <| 35 and policy_constraints = ce <| 36 and extended_key_usage = ce <| 37 and freshest_crl = ce <| 46 and inhibit_any_policy = ce <| 54 (* https://tools.ietf.org/html/rfc5280#section-4.2.2.1 *) module Private_internet_extensions = struct let pe = pkix <| 1 let authority_info_access = pe <| 1 let ad = pkix <| 48 let ad_ca_issuer = ad <| 2 let ad_ocsp = ad <| 1 let ad_ocsp_basic = ad_ocsp <| 1 end module Extended_usage = struct let any = extended_key_usage <| 0 let key_purpose = pkix <| 3 let server_auth = key_purpose <| 1 and client_auth = key_purpose <| 2 and code_signing = key_purpose <| 3 and email_protection = key_purpose <| 4 and ipsec_end_system = key_purpose <| 5 and ipsec_tunnel = key_purpose <| 6 and ipsec_user = key_purpose <| 7 and time_stamping = key_purpose <| 8 and ocsp_signing = key_purpose <| 9 end module Cert_policy = struct let qt = pkix <| 2 let cps = qt <| 1 let unotice = qt <| 2 let any_policy = certificate_policies_2 <| 0 end end module Name_extn = struct (* For the rarely-used feature of GeneralName: AnotherName. *) let id_other_name = pkix <| 8 (* rfc6120 *) let xmpp_addr = id_other_name <| 5 (* rfc4985 *) let srv_name = id_other_name <| 7 (* an IA5String _Service.Name *) let venezuela = base 2 16 <| 862 let venezuela_1 = venezuela <| 2 <| 1 and venezuela_2 = venezuela <| 2 <| 2 let is_utf8_id oid = List.mem oid [ xmpp_addr ; venezuela_1 ; venezuela_2 ] end ocaml-x509-0.16.5/lib/signing_request.ml000066400000000000000000000161561445061461400177250ustar00rootroot00000000000000let ( let* ) = Result.bind module Ext = struct type _ k = | Password : string k | Name : string k | Extensions : Extension.t k module K = struct type 'a t = 'a k let compare : type a b . a t -> b t -> (a, b) Gmap.Order.t = fun t t' -> let open Gmap.Order in match t, t' with | Password, Password -> Eq | Password, _ -> Lt | _, Password -> Gt | Name, Name -> Eq | Name, _ -> Lt | _, Name -> Gt | Extensions, Extensions -> Eq end include Gmap.Make(K) let pp_one : type a. a k -> Format.formatter -> a -> unit = fun k ppf v -> match k, v with | Password, pass -> Fmt.pf ppf "password %s" pass | Name, name -> Fmt.pf ppf "name %s" name | Extensions, ext -> Fmt.pf ppf "extensions %a" Extension.pp ext let pp ppf m = iter (fun (B (k, v)) -> pp_one k ppf v ; Fmt.sp ppf ()) m end type request_info = { subject : Distinguished_name.t ; public_key : Public_key.t ; extensions : Ext.t ; } type request = { info : request_info ; signature_algorithm : Algorithm.t ; signature : Cstruct.t } type t = { asn : request ; raw : Cstruct.t ; } module Asn = struct open Asn_grammars open Asn.S open Registry let attributes = let f = function[@ocaml.warning "-8"] | (oid, [`C1 p]) when oid = PKCS9.challenge_password -> Ext.B (Password, p) | (oid, [`C1 n]) when oid = PKCS9.unstructured_name -> Ext.B (Name, n) | (oid, [`C2 es]) when oid = PKCS9.extension_request -> Ext.B (Extensions, es) and g (Ext.B (k, v)) : Asn.oid * [ `C1 of string | `C2 of Extension.t ] list = match k, v with | Ext.Password, v -> (PKCS9.challenge_password, [`C1 v]) | Ext.Name, v -> (PKCS9.unstructured_name, [`C1 v]) | Ext.Extensions, v -> (PKCS9.extension_request, [`C2 v]) in map f g @@ sequence2 (required ~label:"attr type" oid) (required ~label:"attr value" (set_of (choice2 utf8_string Extension.Asn.extensions_der))) let request_info = let f = function | (0, subject, public_key, extensions) -> let extensions = List.fold_left (fun map (Ext.B (k, v)) -> match Ext.add_unless_bound k v map with | None -> parse_error "request extension %a already bound" (Ext.pp_one k) v | Some b -> b) Ext.empty extensions in { subject ; public_key ; extensions } | _ -> parse_error "unknown certificate request info" and g { subject ; public_key ; extensions } = let extensions = Ext.bindings extensions in (0, subject, public_key, extensions) in map f g @@ sequence4 (required ~label:"version" int) (required ~label:"subject" Distinguished_name.Asn.name) (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 = projections_of Asn.der request_info let signing_request = let f = fun (info, signature_algorithm, signature) -> { info ; signature_algorithm ; signature } and g = fun { info ; signature_algorithm ; signature } -> (info, signature_algorithm, signature) in map f g @@ sequence3 (required ~label:"certificationRequestInfo" request_info) (required ~label:"signatureAlgorithm" Algorithm.identifier) (required ~label:"signature" bit_string_cs) let signing_request_of_cs, signing_request_to_cs = projections_of Asn.der signing_request end let info { asn ; _ } = asn.info let signature_algorithm { asn ; _ } = Algorithm.to_signature_algorithm asn.signature_algorithm let hostnames csr = let info = info csr in let subj = match Distinguished_name.common_name info.subject with | None -> Host.Set.empty | Some x -> match Host.host x with | Some (typ, n) -> Host.Set.singleton (typ, n) | None -> Host.Set.empty in match Ext.(find Extensions info.extensions) with | None -> subj | Some exts -> match Extension.hostnames exts with | Some names -> names | None -> subj let validate_signature allowed_hashes { asn ; raw } = let raw_data = Validation.raw_cert_hack raw in Validation.validate_raw_signature asn.info.subject allowed_hashes raw_data 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 = { raw = cs ; asn = csr } in let* () = Result.map_error (fun e -> `Msg (Fmt.to_to_string Validation.pp_signature_error e)) (validate_signature allowed_hashes csr) in Ok csr let encode_der { raw ; _ } = raw let decode_pem cs = let* data = Pem.parse cs in let crs = List.filter (fun (t, _) -> String.equal "CERTIFICATE REQUEST" t) data in let* csrs = Pem.foldM (fun (_, cs) -> decode_der cs) crs in Pem.exactly_one ~what:"certificate request" csrs let encode_pem v = Pem.unparse ~tag:"CERTIFICATE REQUEST" (encode_der v) let digest_of_key = function | `RSA _ -> `SHA256 | `ED25519 _ -> `SHA512 | `P224 _ -> `SHA224 | `P256 _ -> `SHA256 | `P384 _ -> `SHA384 | `P521 _ -> `SHA512 let default_digest digest key = match digest with None -> digest_of_key key | Some x -> x 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 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_algorithm = Algorithm.of_signature_algorithm scheme hash in let asn = { info ; signature_algorithm ; signature } in let raw = Asn.signing_request_to_cs asn in Ok { asn ; raw } 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))) ?(extensions = Extension.empty) ?(subject = signing_request.asn.info.subject) key issuer = let hash = default_digest digest key in let* () = validate_signature allowed_hashes signing_request in let signature_algo = let scheme = Key_type.x509_default_scheme (Private_key.key_type key) in Algorithm.of_signature_algorithm scheme hash and info = signing_request.asn.info in let tbs_cert : Certificate.tBSCertificate = { version = `V3 ; serial ; signature = signature_algo ; issuer = issuer ; validity = (valid_from, valid_until) ; subject ; pk_info = info.public_key ; issuer_id = None ; subject_id = None ; extensions } in let tbs_raw = Certificate.Asn.tbs_certificate_to_cstruct 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 = { Certificate.tbs_cert ; signature_algo ; signature_val ; } in let raw = Certificate.Asn.certificate_to_cstruct asn in Ok { Certificate.asn ; raw } ocaml-x509-0.16.5/lib/validation.ml000066400000000000000000000506661445061461400166550ustar00rootroot00000000000000let ( let* ) = Result.bind let sha2 = [ `SHA256 ; `SHA384 ; `SHA512 ] let all_hashes = [ `MD5 ; `SHA1 ; `SHA224 ] @ sha2 let src = Logs.Src.create "x509" ~doc:"X509 validation" 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 | `Unsupported_keytype of Distinguished_name.t * Public_key.t | `Unsupported_algorithm of Distinguished_name.t * string | `Msg of string ] let pp_signature_error ppf = function | `Bad_signature (subj, msg) -> Fmt.pf ppf "failed to verify signature of %a: %s" 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_ | `Hash_not_allowed (subj, hash) -> Fmt.pf ppf "hash algorithm %a is not allowed, but %a is signed using it" Distinguished_name.pp subj Certificate.pp_hash hash | `Unsupported_keytype (subj, pk) -> Fmt.pf ppf "unsupported key used to sign %a: %a" Distinguished_name.pp subj Public_key.pp pk | `Unsupported_algorithm (subj, alg) -> Fmt.pf ppf "unsupported algorithm used to sign %a: %s" Distinguished_name.pp subj alg | `Msg msg -> Fmt.string ppf msg let maybe_validate_hostname cert = function | None -> true | Some x -> Certificate.supports_hostname cert x let maybe_validate_ip cert = function | None -> true | Some ip -> Certificate.supports_ip cert ip let issuer_matches_subject { Certificate.asn = parent ; _ } { Certificate.asn = cert ; _ } = Distinguished_name.equal parent.tbs_cert.subject cert.tbs_cert.issuer let is_self_signed cert = issuer_matches_subject cert cert let validate_raw_signature subject allowed_hashes msg sig_alg signature pk = match Algorithm.to_signature_algorithm sig_alg with | Some (scheme, siga) -> (* we check that siga is a member of allowed_hashes, to ensure not using a weak one. *) if not (List.mem siga allowed_hashes) then Error (`Hash_not_allowed (subject, siga)) else if not (Key_type.supports_signature_scheme (Public_key.key_type pk) scheme) then Error (`Unsupported_keytype (subject, pk)) else let* () = Result.map_error (function `Msg m -> `Bad_signature (subject, m)) (Public_key.verify siga ~scheme ~signature pk (`Message msg)) in if not (List.mem siga sha2) then Log.warn (fun m -> m "%a signature uses %a, a weak hash algorithm" Distinguished_name.pp subject Certificate.pp_hash siga); Ok () | None -> Error (`Unsupported_algorithm (subject, Algorithm.to_string sig_alg)) (* 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 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 rec l acc idx last = if idx = last then acc else l (acc lsl 8 + Cstruct.get_uint8 cert_buf idx) (succ idx) last in let cert_len_byte = Cstruct.get_uint8 cert_buf loff in let cert_len = (* two cases: *) if 0x80 land cert_len_byte = 0 then (* length < 127: highest bit is zero and lower 7 bits encode the length *) 2 + (0x7F land cert_len_byte) else (* length > 127: highest bit is 1 and lower 7 bits encode the bytes used to encode the length *) 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 let validate_signature allowed_hashes { Certificate.asn = trusted ; _ } { Certificate.asn ; raw } = let tbs_raw = raw_cert_hack raw in validate_raw_signature asn.tbs_cert.subject allowed_hashes tbs_raw asn.signature_algo asn.signature_val trusted.tbs_cert.pk_info let validate_time time { Certificate.asn = cert ; _ } = match time with | None -> true | Some now -> let (not_before, not_after) = cert.tbs_cert.validity in Ptime.(is_later ~than:not_before now && is_earlier ~than:not_after now) let version_matches_extensions { Certificate.asn = cert ; _ } = let tbs = cert.tbs_cert in match tbs.version, Extension.is_empty tbs.extensions with | (`V1 | `V2), true -> true | (`V1 | `V2), _ -> false | `V3, _ -> true let validate_path_len pathlen { Certificate.asn = cert ; _ } = (* X509 V1/V2 certificates do not contain X509v3 extensions! *) (* thus, we cannot check the path length. this will only ever happen for trust anchors: *) (* intermediate CAs are checked by is_cert_valid, which checks that the CA extensions are there *) (* whereas trust anchor are ok with getting V1/2 certificates *) (* TODO: make it configurable whether to accept V1/2 certificates at all *) let exts = cert.tbs_cert.extensions in match cert.tbs_cert.version, Extension.(find Basic_constraints exts) with | (`V1 | `V2), _ -> true | `V3, Some (_ , (true, None)) -> true | `V3, Some (_ , (true, Some n)) -> n >= pathlen | _ -> false let validate_ca_extensions { Certificate.asn = cert ; _ } = let exts = cert.tbs_cert.extensions in (* comments from RFC5280 *) (* 4.2.1.9 Basic Constraints *) (* Conforming CAs MUST include this extension in all CA certificates used *) (* to validate digital signatures on certificates and MUST mark the *) (* extension as critical in such certificates *) (* unfortunately, there are 8 CA certs (including the one which signed google.com) which are _NOT_ marked as critical *) ( match Extension.(find Basic_constraints exts) with | Some (_ , (true, _)) -> true | _ -> false ) && (* 4.2.1.3 Key Usage *) (* Conforming CAs MUST include key usage extension *) (* CA Cert (cacert.org) does not *) ( match Extension.(find Key_usage exts) with (* When present, conforming CAs SHOULD mark this extension as critical *) (* yeah, you wish... *) | Some (_, usage) -> List.mem `Key_cert_sign usage | _ -> false ) && (* if we require this, we cannot talk to github.com (* 4.2.1.12. Extended Key Usage If a certificate contains both a key usage extension and an extended key usage extension, then both extensions MUST be processed independently and the certificate MUST only be used for a purpose consistent with both extensions. If there is no purpose consistent with both extensions, then the certificate MUST NOT be used for any purpose. *) ( match extn_ext_key_usage cert with | Some (_, Ext_key_usage usages) -> List.mem Any usages | _ -> true ) && *) (* Name Constraints - name constraints should match servername *) (* check criticality *) Extension.for_all (fun (Extension.B (k, v)) -> match k with | Extension.Key_usage -> true | Extension.Basic_constraints -> true | _ -> not (Extension.critical k v) ) exts let validate_server_extensions cert = Extension.for_all (fun (Extension.B (k, v)) -> match k, v with | Extension.Basic_constraints, (_, (true, _)) -> if is_self_signed cert then (Log.warn (fun m -> m "allowing self-signed certificate with BasicConstraints CA true"); true) else false | Extension.Basic_constraints, (_, (false, _)) -> true | Extension.Key_usage, _ -> true | Extension.Ext_key_usage, _ -> true | Extension.Subject_alt_name, _ -> true | Extension.Policies, (crit, ps) -> not crit || List.mem `Any ps (* we've to deal with _all_ extensions marked critical! *) | _, _ -> not (Extension.critical k v)) cert.Certificate.asn.tbs_cert.extensions let valid_trust_anchor_extensions cert = match cert.Certificate.asn.tbs_cert.version with | `V1 | `V2 -> true | `V3 -> validate_ca_extensions cert let ext_authority_matches_subject trusted cert = match Extension.(find Authority_key_id (Certificate.extensions cert), find Subject_key_id (Certificate.extensions trusted)) with | (_, None) | (None, _) -> true (* not mandatory *) | Some (_, (Some auth, _, _)), Some (_, au) -> Cstruct.equal auth au (* TODO: check exact rules in RFC5280 *) | Some (_, (None, _, _)), _ -> true (* not mandatory *) (* t -> t list (* set *) -> t list list *) let rec build_paths fst rst = match List.filter (fun x -> Distinguished_name.equal (Certificate.issuer fst) (Certificate.subject x)) rst with | [] -> [[fst]] | xs -> let tails = List.fold_left (fun acc x -> acc @ build_paths x (List.filter (fun y -> x <> y) rst)) [[]] xs in List.map (fun x -> fst :: x) tails type ca_error = [ | signature_error | `CAIssuerSubjectMismatch of Certificate.t | `CAInvalidVersion of Certificate.t | `CACertificateExpired of Certificate.t * Ptime.t option | `CAInvalidExtensions of Certificate.t ] let pp_ca_error ppf = function | #signature_error as e -> pp_signature_error ppf e | `CAIssuerSubjectMismatch c -> Fmt.pf ppf "CA certificate %a: issuer does not match subject" Certificate.pp c | `CAInvalidVersion c -> Fmt.pf ppf "CA certificate %a: version 3 is required for extensions" Certificate.pp c | `CAInvalidExtensions c -> Fmt.pf ppf "CA certificate %a: invalid CA extensions" Certificate.pp c | `CACertificateExpired (c, now) -> let pp_pt = Ptime.pp_human ~tz_offset_s:0 () in Fmt.pf ppf "CA certificate %a: expired (now %a)" Certificate.pp c Fmt.(option ~none:(any "no timestamp provided") pp_pt) now type leaf_validation_error = [ | `LeafCertificateExpired of Certificate.t * Ptime.t option | `LeafInvalidIP of Certificate.t * Ipaddr.t option | `LeafInvalidName of Certificate.t * [`host] Domain_name.t option | `LeafInvalidVersion of Certificate.t | `LeafInvalidExtensions of Certificate.t ] let pp_leaf_validation_error ppf = function | `LeafCertificateExpired (c, now) -> let pp_pt = Ptime.pp_human ~tz_offset_s:0 () in 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)" 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) -> Fmt.pf ppf "leaf certificate %a does not contain the name %a" Certificate.pp c Fmt.(option ~none:(any "none") Domain_name.pp) n | `LeafInvalidVersion c -> Fmt.pf ppf "leaf certificate %a: version 3 is required for extensions" Certificate.pp c | `LeafInvalidExtensions c -> Fmt.pf ppf "leaf certificate %a: invalid server extensions" Certificate.pp c type chain_validation_error = [ | `IntermediateInvalidExtensions of Certificate.t | `IntermediateCertificateExpired of Certificate.t * Ptime.t option | `IntermediateInvalidVersion of Certificate.t | `ChainIssuerSubjectMismatch of Certificate.t * Certificate.t | `ChainAuthorityKeyIdSubjectKeyIdMismatch of Certificate.t * Certificate.t | `ChainInvalidPathlen of Certificate.t * int | `EmptyCertificateChain | `NoTrustAnchor of Certificate.t | `Revoked of Certificate.t ] let pp_chain_validation_error ppf = function | `IntermediateInvalidExtensions c -> Fmt.pf ppf "intermediate certificate %a: invalid extensions" Certificate.pp c | `IntermediateCertificateExpired (c, now) -> let pp_pt = Ptime.pp_human ~tz_offset_s:0 () in Fmt.pf ppf "intermediate certificate %a expired (now %a)" Certificate.pp c Fmt.(option ~none:(any "no timestamp provided") pp_pt) now | `IntermediateInvalidVersion c -> Fmt.pf ppf "intermediate certificate %a: version 3 is required for extensions" Certificate.pp c | `ChainIssuerSubjectMismatch (c, parent) -> Fmt.pf ppf "invalid chain: issuer of %a does not match subject of %a" Certificate.pp c Certificate.pp parent | `ChainAuthorityKeyIdSubjectKeyIdMismatch (c, parent) -> Fmt.pf ppf "invalid chain: authority key id extension of %a does not match subject key id extension of %a" Certificate.pp c Certificate.pp parent | `ChainInvalidPathlen (c, pathlen) -> Fmt.pf ppf "invalid chain: the path length of %a is smaller than the required path length %d" Certificate.pp c pathlen | `EmptyCertificateChain -> Fmt.string ppf "certificate chain is empty" | `NoTrustAnchor c -> Fmt.pf ppf "no trust anchor found for %a" Certificate.pp c | `Revoked c -> Fmt.pf ppf "certificate %a is revoked" Certificate.pp c type chain_error = [ | signature_error | leaf_validation_error | chain_validation_error ] let pp_chain_error ppf = function | #signature_error as e -> pp_signature_error ppf e | #leaf_validation_error as l -> pp_leaf_validation_error ppf l | #chain_validation_error as c -> pp_chain_validation_error ppf c type fingerprint_validation_error = [ | `InvalidFingerprint of Certificate.t * Cstruct.t * Cstruct.t ] 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 type validation_error = [ | signature_error | leaf_validation_error | fingerprint_validation_error | `EmptyCertificateChain | `InvalidChain ] let pp_validation_error ppf = function | #signature_error as e -> pp_signature_error ppf e | #leaf_validation_error as l -> pp_leaf_validation_error ppf l | #fingerprint_validation_error as f -> pp_fingerprint_validation_error ppf f | `EmptyCertificateChain -> Fmt.string ppf "provided certificate chain is empty" | `InvalidChain -> Fmt.string ppf "invalid certificate chain" type r = ((Certificate.t list * Certificate.t) option, validation_error) result (* TODO RFC 5280: A certificate MUST NOT include more than one instance of a particular extension. *) let is_cert_valid now cert = match validate_time now cert, version_matches_extensions cert, validate_ca_extensions cert with | (true, true, true) -> Ok () | (false, _, _) -> Error (`IntermediateCertificateExpired (cert, now)) | (_, false, _) -> Error (`IntermediateInvalidVersion cert) | (_, _, false) -> Error (`IntermediateInvalidExtensions cert) let is_ca_cert_valid allowed_hashes now cert = match is_self_signed cert, version_matches_extensions cert, validate_signature allowed_hashes cert cert, validate_time now cert, valid_trust_anchor_extensions cert with | (true, true, Ok (), true, true) -> Ok () | (false, _, _, _, _) -> Error (`CAIssuerSubjectMismatch cert) | (_, false, _, _, _) -> Error (`CAInvalidVersion cert) | (_, _, Error e, _, _) -> Error e | (_, _, _, false, _) -> Error (`CACertificateExpired (cert, now)) | (_, _, _, _, false) -> Error (`CAInvalidExtensions cert) let valid_ca ?(allowed_hashes = all_hashes) ?time cacert = is_ca_cert_valid allowed_hashes time cacert let is_server_cert_valid ip host now cert = match validate_time now cert, maybe_validate_ip cert ip, maybe_validate_hostname cert host, version_matches_extensions cert, validate_server_extensions cert with | (true, true, true, true, true) -> Ok () | (false, _, _, _, _) -> Error (`LeafCertificateExpired (cert, now)) | (_, false, _, _, _) -> Error (`LeafInvalidIP (cert, ip)) | (_, _, false, _, _) -> Error (`LeafInvalidName (cert, host)) | (_, _, _, false, _) -> Error (`LeafInvalidVersion cert) | (_, _, _, _, false) -> Error (`LeafInvalidExtensions cert) let signs hash pathlen trusted cert = match issuer_matches_subject trusted cert, ext_authority_matches_subject trusted cert, validate_signature hash trusted cert, validate_path_len pathlen trusted with | (true, true, Ok (), true) -> Ok () | (false, _, _, _) -> Error (`ChainIssuerSubjectMismatch (trusted, cert)) | (_, false, _, _) -> Error (`ChainAuthorityKeyIdSubjectKeyIdMismatch (trusted, cert)) | (_, _, Error e, _) -> Error e | (_, _, _, false) -> Error (`ChainInvalidPathlen (trusted, pathlen)) let issuer trusted cert = List.filter (fun p -> issuer_matches_subject p cert) trusted let rec validate_anchors revoked hash pathlen cert = function | [] -> Error (`NoTrustAnchor cert) | x::xs -> match signs hash pathlen x cert with | Ok _ -> if revoked ~issuer:x ~cert then Error (`Revoked cert) else Ok x | Error _ -> validate_anchors revoked hash pathlen cert xs let verify_single_chain now ?(revoked = fun ~issuer:_ ~cert:_ -> false) hash anchors chain = let rec climb pathlen = function | cert :: issuer :: certs -> let* () = is_cert_valid now issuer in let* () = if revoked ~issuer ~cert then Error (`Revoked cert) else Ok () in let* () = signs hash pathlen issuer cert in climb (succ pathlen) (issuer :: certs) | [c] -> let anchors = issuer anchors c in validate_anchors revoked hash pathlen c anchors | [] -> Error `EmptyCertificateChain in climb 0 chain let verify_chain ?ip ~host ~time ?revoked ?(allowed_hashes = sha2) ~anchors = function | [] -> Error `EmptyCertificateChain | server :: certs -> let now = time () in let anchors = List.filter (validate_time now) anchors in let* () = is_server_cert_valid ip host now server in verify_single_chain now ?revoked allowed_hashes anchors (server :: certs) let rec any_m e f = function | [] -> Error e | c::cs -> match f c with | Ok ta -> Ok (Some (c, ta)) | Error _ -> any_m e f cs let verify_chain_of_trust ?ip ~host ~time ?revoked ?(allowed_hashes = sha2) ~anchors = function | [] -> Error `EmptyCertificateChain | server :: certs -> let now = time () in (* verify server! *) let* () = is_server_cert_valid ip host now server in (* build all paths *) let paths = build_paths server certs and anchors = List.filter (validate_time now) anchors in (* exists there one which is good? *) any_m `InvalidChain (verify_single_chain now ?revoked allowed_hashes anchors) paths let valid_cas ?(allowed_hashes = all_hashes) ?time cas = List.filter (fun cert -> Result.is_ok (is_ca_cert_valid allowed_hashes time cert)) cas 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 match validate_time now server, maybe_validate_hostname server host, maybe_validate_ip server ip with | true , true , true -> Ok None | false, _ , _ -> Error (`LeafCertificateExpired (server, now)) | _ , false, _ -> Error (`LeafInvalidName (server, host)) | _ , _ , false -> Error (`LeafInvalidIP (server, ip)) else Error (`InvalidFingerprint (server, computed_fingerprint, fingerprint)) let trust_key_fingerprint ?ip ~host ~time ~hash ~fingerprint = let now = time () in let fp cert = Public_key.fingerprint ~hash (Certificate.public_key cert) in fingerprint_verification ?ip host now fingerprint fp let trust_cert_fingerprint ?ip ~host ~time ~hash ~fingerprint = let now = time () in let fp = Certificate.fingerprint hash in fingerprint_verification ?ip host now fingerprint fp (* RFC5246 says 'root certificate authority MAY be omitted' *) (* TODO: how to deal with 2.16.840.1.113730.1.1 - Netscape certificate type 2.16.840.1.113730.1.12 - SSL server name 2.16.840.1.113730.1.13 - Netscape certificate comment *) (* stuff from 4366 (TLS extensions): - root CAs - client cert url *) (* Future TODO Certificate Revocation Lists and OCSP (RFC6520) 2.16.840.1.113730.1.2 - Base URL 2.16.840.1.113730.1.3 - Revocation URL 2.16.840.1.113730.1.4 - CA Revocation URL 2.16.840.1.113730.1.7 - Renewal URL 2.16.840.1.113730.1.8 - Netscape CA policy URL 2.5.4.38 - id-at-authorityRevocationList 2.5.4.39 - id-at-certificateRevocationList do not forget about 'authority information access' (private internet extension -- 4.2.2 of 5280) *) (* Future TODO: Policies 2.5.29.32 - Certificate Policies 2.5.29.33 - Policy Mappings 2.5.29.36 - Policy Constraints *) (* Future TODO: anything with subject_id and issuer_id ? seems to be not used by anybody *) ocaml-x509-0.16.5/lib/x509.ml000066400000000000000000000006601445061461400152150ustar00rootroot00000000000000module Host = Host module Key_type = Key_type module Public_key = Public_key module Private_key = Private_key module Distinguished_name = Distinguished_name module General_name = General_name module Certificate = Certificate module Validation = Validation module Extension = Extension module Signing_request = Signing_request module CRL = Crl module Authenticator = Authenticator module PKCS12 = P12 module OCSP = Ocsp ocaml-x509-0.16.5/lib/x509.mli000066400000000000000000001442401445061461400153710ustar00rootroot00000000000000(** X509 encoding, generation, and validation. [X509] is a module for handling X.509 certificates and supplementary material (such as public and private RSA or EC keys), as described in {{:https://tools.ietf.org/html/rfc5280}RFC 5280}. X.509 describes a hierarchical public key infrastructure, where all trust is delegated to certificate authorities (CA). The task of a CA is to sign certificate signing requests (CSR), which turns them into certificates, after verification that the requestor is eligible. An X.509 certificate is an authentication token: a public key, a subject (e.g. server name), a validity period, optionally a purpose (usage), and various other optional {{!Extension}Extensions}. The overall approach of this package is to support decoding what is present in the real world, including weak ciphers (various validation functions support an allow list to avoid using weak hashes in chains if needed). The public keys of trusted CAs are distributed with the software, or configured manually. When an endpoint connects, it presents its certificate chain, which are pairwise signed certificates. This chain is verified: the signatures have to be valid, the last certificate must be signed by a trusted CA, the name has to match the expected name, all certificates must be valid at the current time, and the purpose of each certificate must match its usage. An alternative validator checks that the hash of the server certificate matches the given hash. This module uses the [result] type for errors. No provided binging raises an exception. Provided submodules include decoders and encoders (ASN.1 DER and PEM encoding) of X.509v3 {{!Certificate}certificates}, {{!Distinguished_name}distinguished names}, {{!Public_key}public keys} and {{!Private_key}private keys} ({{:http://tools.ietf.org/html/rfc5208}PKCS 8, RFC 5208}), and {{!Signing_request}certificate signing requests} ({{:http://tools.ietf.org/html/rfc2986}PKCS 10, RFC 2986}, both use parts of {{:https://tools.ietf.org/html/rfc2985}PKCS 9, RFC 2985}), {{!Validation} certificate validation} by construction of {{!Authenticator} authenticators}. Name validation, as defined in {{:https://tools.ietf.org/html/rfc6125}RFC 6125}, is also implemented. The archive format for certificates and private keys, {{:https://tools.ietf.org/html/rfc7292}PKCS 12, RFC 7292}, is implemented in the {!PKCS12} submodule. While PKCS 12 decryption supports the weak algorithm used by default by widely used software (RC2!), the encryption path only supports AES. Missing is the handling of online certificate status protocol. Some X.509v3 extensions are not handled, but only parsed, such as name constraints. If any extension is marked as critical in a certificate, but not handled, the validation will fail. {e %%VERSION%% - {{:%%PKG_HOMEPAGE%% }homepage}} *) (** Hostnames (strict, wildcard), used for validation. *) module Host : sig (** The polymorphic variant for hostname validation. *) type t = [ `Strict | `Wildcard ] * [ `host ] Domain_name.t (** [pp ppf host] pretty-prints [host] on [ppf]: if it is a wildcard, "*." is prefixed to the domain name. *) val pp : t Fmt.t (** The module for a set of hostnames. *) module Set : sig include Set.S with type elt = t (** [pp ppf host_set] pretty-prints the [host_set]. *) val pp : t Fmt.t end end (** Types of keys *) module Key_type : sig (** The polymorphic variant of key types. *) type t = [ `RSA | `ED25519 | `P224 | `P256 | `P384 | `P521 ] val strings : (string * t) list (** [strings] is an associative list of string and key_type pairs. Useful for {{:https://erratique.ch/software/cmdliner}cmdliner} (Arg.enum). *) val to_string : t -> string (** [to_string kt] is a string representation of [kt]. *) val of_string : string -> (t, [> `Msg of string ]) result (** [of_string s] is [Ok key_type] if the string could be decoded as [key_type], or an [Error _]. *) val pp : t Fmt.t (** [pp ppf t] is a pretty printer of [t] on [ppf]. *) (** The type of signature schemes. *) type signature_scheme = [ `RSA_PSS | `RSA_PKCS1 | `ECDSA | `ED25519 ] val pp_signature_scheme : signature_scheme Fmt.t (** [pp_signature_scheme ppf s] is a pretty-printer of [s] on [ppf]. *) val supports_signature_scheme : t -> signature_scheme -> bool (** [supports_scheme key_type scheme] is [true] if the signature [scheme] is supported with [key type]. *) end (** Public keys *) module Public_key : sig (** Public keys as specified in {{:http://tools.ietf.org/html/rfc5208}PKCS 8} are supported in this module. *) (** {1 The type for public keys} *) (** The polymorphic variant of public keys, with {{:http://tools.ietf.org/html/rfc5208}PKCS 8} encoding and decoding to PEM. *) 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 ] (** {1 Operations on public keys} *) (** [pp ppf pub] pretty-prints the public key [pub] on [ppf]. *) val pp : t Fmt.t (** [id public_key] is [digest], the 160-bit [`SHA1] hash of the BIT STRING subjectPublicKey (excluding tag, length, and number of 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 (** [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 (** [key_type public_key] is its [key_type]. *) val key_type : t -> Key_type.t (** {1 Cryptographic verify operation} *) (** [verify hash ~scheme ~signature key data] verifies whether the [signature] 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 -> ?scheme:Key_type.signature_scheme -> signature:Cstruct.t -> t -> [ `Message of Cstruct.t | `Digest of Cstruct.t ] -> (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 (** [decode_der buffer] is [pubkey], the public key of the ASN.1 encoded buffer. *) val decode_der : Cstruct.t -> (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 (** [encode_pem public_key] is [pem], the pem encoded public key. *) val encode_pem : t -> Cstruct.t end (** Private keys *) module Private_key : sig (** Private keys as defined in {{:http://tools.ietf.org/html/rfc5208}PKCS 8}: decoding and encoding in PEM format *) (** {1 The type for private keys} *) (** The polymorphic variant of private keys. *) 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 ] (** {1 Constructing private keys} *) (** [generate ~seed ~bits type] generates a private key of the given 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 (** [of_cstruct 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 (** [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 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 -> string -> (t, [> `Msg of string ]) result (** {1 Operations on private keys} *) (** [key_type priv] is the key type of [priv]. *) val key_type : t -> Key_type.t (** [public priv] is the corresponding public key of [priv]. *) val public : t -> Public_key.t (** {1 Cryptographic sign operation} *) (** [sign hash ~scheme key data] signs [data] with [key] using [hash] and [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 -> ?scheme:Key_type.signature_scheme -> t -> [ `Digest of Cstruct.t | `Message of Cstruct.t ] -> (Cstruct.t, [> `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 (** [encode_der key] is [der], the encoded private key as PKCS8 (RFC 5208, Section 5) PrivateKeyInfo structure. *) val encode_der : t -> Cstruct.t (** [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 (** [encode_pem key] is [pem], the encoded private key (using [PRIVATE KEY]). *) val encode_pem : t -> Cstruct.t end (** X.500 distinguished name *) module Distinguished_name : sig (** The variant of a relative distinguished name component, as defined in X.500: an attribute type and value. *) type attribute = | CN of string | Serialnumber of string | C of string | L of string | ST of string | O of string | OU of string | T of string | DNQ of string | Mail of string | DC of string | Given_name of string | Surname of string | Initials of string | Pseudonym of string | Generation of string | Street of string | Userid of string | Other of Asn.oid * string (** Relative_distinguished_name is a set of attributes. *) module Relative_distinguished_name : Set.S with type elt = attribute (** A distinguished name is a list of relative distinguished names, starting with the most significant component. *) type t = Relative_distinguished_name.t list (** [equal a b] is [true] if the distinguished names [a] and [b] are equal. *) val equal : t -> t -> bool (** [make_pp ()] creates a customized pretty-printer for {!t}. @param format Determines RDN order, escaping rules, and the default spacing: - [`RFC4514] produces the {{:https://tools.ietf.org/html/rfc4514}RFC4514}. RDNs are written in reverse order of the ASN.1 representation and spacing defaults to tight. - [`OpenSSL] produces the a format similar to OpenSSL. RDNs are written in the order of the ASN.1 representation, and spacing defaults to loose. - [`OSF] emits RDNs in the order they occur in the ASN.1 representation, each prefixed by a slashes, using tight spacing. This format is designed by analogy to RFC4514, substituting slash for comma an semicolon, and may currently not be fully compliant with the OSF specifications. @param spacing Determines whether to add space around separators: - [`Tight] to not add any redundant space, - [`Medium] to add space after comma and around plus signs, and - [`Loose] to also add space around equality signs. This parameter is currently ignored for the OSF format. The pretty-printer can be wrapped in a box to control line breaking and set it apart, otherwise the RDN components will flow with the surrounding text. *) val make_pp : format: [`RFC4514 | `OpenSSL | `OSF] -> ?spacing: [`Tight | `Medium | `Loose] -> unit -> t Fmt.t (** [pp ppf dn] pretty-prints the distinguished name. This is currently [Fmt.hbox (make_pp ~format:`OSF ())]. If your application relies on the precise format, it is advicable to create a custom formatter with {!make_pp} to guard against future changes to the default format. *) val pp : t Fmt.t (** [common_name t] is [Some x] if the distinguished name [t] contains a [CN x], [None] otherwise. *) 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 (** [encode_der dn] is [cstruct], the ASN.1 encoded representation of the distinguished name [dn]. *) val encode_der : t -> Cstruct.t end (** A list of [general_name]s is the value of both {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.6}subjectAltName} and {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.7}IssuerAltName} extension. *) module General_name : sig type _ k = | Other : Asn.oid -> string list k | Rfc_822 : string list k | DNS : string list k | X400_address : unit k | Directory : Distinguished_name.t list k | EDI_party : (string option * string) list k | URI : string list k | IP : Cstruct.t list k | Registered_id : Asn.oid list k include Gmap.S with type 'a key = 'a k val pp : t Fmt.t end (** X.509v3 extensions *) module Extension : sig (** The polymorphic variant of {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.3}key usages}. *) type key_usage = [ | `Digital_signature | `Content_commitment | `Key_encipherment | `Data_encipherment | `Key_agreement | `Key_cert_sign | `CRL_sign | `Encipher_only | `Decipher_only ] (** The polymorphic variant of {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.12}extended key usages}. *) type extended_key_usage = [ | `Any | `Server_auth | `Client_auth | `Code_signing | `Email_protection | `Ipsec_end | `Ipsec_tunnel | `Ipsec_user | `Time_stamping | `Ocsp_signing | `Other of Asn.oid ] (** 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 (** The private key usage period, as defined in {{:https://tools.ietf.org/html/rfc3280#section-4.2.1.4}RFC 3280}. *) type priv_key_usage_period = [ | `Interval of Ptime.t * Ptime.t | `Not_after of Ptime.t | `Not_before of Ptime.t ] (** Name constraints, as defined in {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.10}RFC 5280}. *) type name_constraint = (General_name.b * int * int option) list (** Certificate policies, the {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.4}policy extension}. *) type policy = [ `Any | `Something of Asn.oid ] (** Type of {{:https://tools.ietf.org/html/rfc5280#section-5.3.1}revocation reasons} for a given distribution point. *) type reason = [ | `Unspecified | `Key_compromise | `CA_compromise | `Affiliation_changed | `Superseded | `Cessation_of_operation | `Certificate_hold | `Remove_from_CRL | `Privilege_withdrawn | `AA_compromise ] (** Distribution point name, either a full one using general names, or a relative one using a distinguished name. *) type distribution_point_name = [ `Full of General_name.t | `Relative of Distinguished_name.t ] (** {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.13}Distribution point}, consisting of an optional name, an optional list of allowed reasons, and an optional issuer. *) type distribution_point = distribution_point_name option * reason list option * General_name.t option (** The type of an extension: the critical flag and the value itself. *) type 'a extension = bool * 'a (** The type of supported {{: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 | Subject_alt_name : General_name.t extension k | Authority_key_id : authority_key_id extension k | Subject_key_id : Cstruct.t 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 | Basic_constraints : (bool * int option) extension k | CRL_number : int extension k | Delta_CRL_indicator : int extension k | Priv_key_period : priv_key_usage_period extension k | Name_constraints : (name_constraint * name_constraint) extension k | CRL_distribution_points : distribution_point list extension k | Issuing_distribution_point : (distribution_point_name option * bool * bool * reason list option * bool * bool) extension k | Freshest_CRL : distribution_point list extension k | Reason : reason extension k | Invalidity_date : Ptime.t extension k | Certificate_issuer : General_name.t extension k | Policies : policy list extension k include Gmap.S with type 'a key = 'a k (** [critical ext_key ext_value] is the critical bit in [ext_value]. *) val critical : 'a key -> 'a -> bool (** [pp ppf ext_map] pretty-prints the extension map. *) val pp : t Fmt.t end (** X509v3 certificate *) 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 (** [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 (** {1 Abstract certificate type} *) (** The abstract type of a certificate. *) type t (** [pp ppf cert] pretty-prints the certificate. *) val pp : t Fmt.t (** {1 Encoding and decoding in ASN.1 DER and PEM format} *) (** [decode_der cstruct] is [certificate], the ASN.1 decoded [certificate] or an error. *) val decode_der : Cstruct.t -> (t, [> `Msg of string ]) result (** [encode_der certificate] is [cstruct], the ASN.1 encoded representation of the [certificate]. *) val encode_der : t -> Cstruct.t (** [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 (** [decode_pem pem] is [t], where the single certificate of the [pem] is extracted *) val decode_pem : Cstruct.t -> (t, [> `Msg of string ]) result (** [encode_pem_multiple certificates] is [pem], the pem encoded certificates. *) val encode_pem_multiple : t list -> Cstruct.t (** [encode_pem certificate] is [pem], the pem encoded certificate. *) val encode_pem : t -> Cstruct.t (** {1 Operations on certificates} *) (** [supports_keytype certificate key_type] is [result], whether public key of the [certificate] matches the given [key_type]. *) val supports_keytype : t -> Key_type.t -> bool (** [public_key certificate] is [pk], the public key of the [certificate]. *) val public_key : t -> Public_key.t (** [signature_algorithm certificate] is the algorithm used for the signature. *) val signature_algorithm : t -> (Key_type.signature_scheme * Mirage_crypto.Hash.hash) option (** [hostnames certficate] is the set of domain names this [certificate] is valid for. Currently, these are the DNS names of the {{:https://tools.ietf.org/html/rfc5280#section-4.2.1.6}Subject Alternative Name} extension, if present, or otherwise the singleton set containing the common name of the certificate subject. *) val hostnames : t -> Host.Set.t (** [supports_hostname certificate hostname] is [result], whether the [certificate] contains the given [hostname], using {!hostnames}. *) val supports_hostname : t -> [`host] Domain_name.t -> bool (** [ips certificate] are the IP addresses the certificate is valid for (as specified in SubjectAlternativeName extensioni). *) val ips : t -> Ipaddr.Set.t (** [supports_ip cert ip] is [true] if the [ip] is mentioned in the SubjectAlternativeName extension, [false] otherwise. *) val supports_ip : t -> Ipaddr.t -> bool (** [fingerprint hash cert] is [digest], the digest of [cert] using the specified [hash] algorithm *) val fingerprint : Mirage_crypto.Hash.hash -> t -> Cstruct.t (** [subject certificate] is [dn], the subject as distinguished name of the [certificate]. *) val subject : t -> Distinguished_name.t (** [issuer certificate] is [dn], the issuer as distinguished name of the [certificate]. *) val issuer : t -> Distinguished_name.t (** [serial certificate] is [sn], the serial number of the [certificate]. *) val serial : t -> Z.t (** [validity certificate] is [from, until], the validity of the certificate. *) val validity : t -> Ptime.t * Ptime.t (** [extensions certificate] is the extension map of [certificate]. *) val extensions : t -> Extension.t end (** Chain Validation. *) module Validation : sig (** A chain of pairwise signed X.509 certificates is sent to the endpoint, which use these to authenticate the other endpoint. Usually a set of trust anchors is configured on the endpoint, and the chain needs to be rooted in one of the trust anchors. In reality, chains may be incomplete or reversed, and there can be multiple paths from the leaf certificate to a trust anchor. RFC 5280 specifies a {{:https://tools.ietf.org/html/rfc5280#section-6}path validation} algorithm for authenticating chains, but this does not handle multiple possible paths. {{:https://tools.ietf.org/html/rfc4158}RFC 4158} describes possible path building strategies. This module provides path building, chain of trust verification, trust anchor (certificate authority) validation, and validation via a fingerprint list (for a trust on first use implementation). *) (** 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 | `Unsupported_keytype of Distinguished_name.t * Public_key.t | `Unsupported_algorithm of Distinguished_name.t * string | `Msg of string ] (** [pp_signature_error ppf sige] pretty-prints the signature error [sige] on [ppf]. *) val pp_signature_error : signature_error Fmt.t (** {1 Certificate Authorities} *) (** The polymorphic variant of possible certificate authorities failures. *) type ca_error = [ | signature_error | `CAIssuerSubjectMismatch of Certificate.t | `CAInvalidVersion of Certificate.t | `CACertificateExpired of Certificate.t * Ptime.t option | `CAInvalidExtensions of Certificate.t ] (** [pp_ca_error ppf ca_error] pretty-prints the CA error [ca_error]. *) val pp_ca_error : ca_error Fmt.t (** [valid_ca ~allowed_hashes ~time certificate] is [result], which is [Ok ()] if the given certificate is self-signed with any hash algorithm of [hash_allowlist] (defaults to any hash), it is valid at [time], its 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 -> 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 -> Certificate.t list -> Certificate.t list (** {1 Chain of trust verification} *) (** The polymorphic variant of a leaf certificate validation error. *) type leaf_validation_error = [ | `LeafCertificateExpired of Certificate.t * Ptime.t option | `LeafInvalidIP of Certificate.t * Ipaddr.t option | `LeafInvalidName of Certificate.t * [`host] Domain_name.t option | `LeafInvalidVersion of Certificate.t | `LeafInvalidExtensions of Certificate.t ] (** The polymorphic variant of a chain validation error. *) type chain_validation_error = [ | `IntermediateInvalidExtensions of Certificate.t | `IntermediateCertificateExpired of Certificate.t * Ptime.t option | `IntermediateInvalidVersion of Certificate.t | `ChainIssuerSubjectMismatch of Certificate.t * Certificate.t | `ChainAuthorityKeyIdSubjectKeyIdMismatch of Certificate.t * Certificate.t | `ChainInvalidPathlen of Certificate.t * int | `EmptyCertificateChain | `NoTrustAnchor of Certificate.t | `Revoked of Certificate.t ] (** [build_paths server rest] is [paths], which are all possible certificate paths starting with [server]. These chains (C1..Cn) fulfill the predicate that each certificate Cn is issued by the next one in the chain (C(n+1)): the issuer of Cn matches the subject of C(n+1). This is as described in {{:https://tools.ietf.org/html/rfc4158}RFC 4158}. *) val build_paths : Certificate.t -> Certificate.t list -> Certificate.t list list (** The polymorphic variant of a chain validation error: either the leaf certificate is problematic, or the chain itself. *) type chain_error = [ | signature_error | leaf_validation_error | chain_validation_error ] (** [pp_chain_error ppf chain_error] pretty-prints the [chain_error]. *) val pp_chain_error : chain_error Fmt.t (** [verify_chain ~ip ~host ~time ~revoked ~allowed_hashes ~anchors chain] is [result], either [Ok] and the trust anchor used to verify the chain, or [Error] and the chain error. RFC 5280 describes the implemented {{:https://tools.ietf.org/html/rfc5280#section-6.1}path validation} algorithm: The validity period of the given certificates is checked against the [time]. The signature algorithm must be present in [allowed_hashes] (defaults to SHA-2). The X509v3 extensions of the [chain] are checked, then a chain of trust from [anchors] to the server certificate is validated. The path length constraints are checked. The server certificate is checked to contain the given [host], using {!Certificate.hostnames}. If [ip] is specified, the certificate is checked to contain the given [ip], using {!Certificate.ips}. The returned certificate is the root of the chain, a member of the given list of [anchors]. *) 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 -> 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 ] (** The polymorphic variant of validation errors. *) type validation_error = [ | signature_error | leaf_validation_error | fingerprint_validation_error | `EmptyCertificateChain | `InvalidChain ] (** [pp_validation_error ppf validation_error] pretty-prints the [validation_error]. *) val pp_validation_error : validation_error Fmt.t type r = ((Certificate.t list * Certificate.t) option, validation_error) result (** [verify_chain_of_trust ~ip ~host ~time ~revoked ~allowed_hashes ~anchors certificates] is [result]. First, all possible paths are constructed using the {!build_paths} function, the first certificate of the chain is verified to be a valid leaf certificate (no BasicConstraints extension) and contains the given [host] (using {!Certificate.hostnames}) or [ip] if specified (using {!Certificate.ips}; if some path is valid, using {!verify_chain}, the result will be [Ok] and contain the actual certificate chain and the trust anchor. *) val verify_chain_of_trust : ?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 -> anchors:(Certificate.t list) -> Certificate.t list -> r (** {1 Fingerprint verification} *) (** [trust_key_fingerprint ~ip ~host ~time ~hash ~fingerprint certificates] is [result], the first element of [certificates] is verified against the given [fingerprint] using {!Public_key.fingerprint}. If [time] is provided, the certificate has to be valid at the given timestamp. If [host] is provided, the certificate is checked for the given [host] (using {!Certificate.hostnames}). If [ip] is provided, the certificate is 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 (** [trust_cert_fingerprint host ~time ~hash ~fingerprint certificates] is [result], the first element of [certificates] is verified to match the given [fingerprint] using {!Certificate.fingerprint}. If [time] is provided, the certificate is checked to be valid in at the given timestamp. If [host] is provided, the certificate is checked for the given [host] (using {!Certificate.hostnames}). If [ip] is provided, the certificate is checked to include this IP address (using {!Certificate.ips}). Note that {{!trust_key_fingerprint}public key pinning} has {{:https://www.imperialviolet.org/2011/05/04/pinning.html} advantages} 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 end (** Certificate Signing request *) (** A certificate authority (CA) deals with {{:https://tools.ietf.org/html/rfc2986}PKCS 10 certificate signing requests}, their construction and encoding, and provisioning using a private key to generate a certificate with a signature thereof. *) module Signing_request : sig (** The abstract type of a (self-signed) certification request. *) type t (** {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 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 -> (t, [> `Msg of string ]) result (** [encode_der sr] is [cstruct], the ASN.1 encoded representation of the [sr]. *) val encode_der : t -> Cstruct.t (** [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 (** [encode_pem signing_request] is [pem], the pem encoded signing request. *) val encode_pem : t -> Cstruct.t (** {1 Construction of a signing request} *) module Ext : sig (** The GADT of certificate request extensions, as defined in {{:http://tools.ietf.org/html/rfc2985}PKCS 9 (RFC 2985)}. *) type _ k = | Password : string k | Name : string k | Extensions : Extension.t k include Gmap.S with type 'a key = 'a k val pp : t Fmt.t end (** The raw request info of a {{:https://tools.ietf.org/html/rfc2986#section-4}PKCS 10 certification request info}. *) type request_info = { subject : Distinguished_name.t ; public_key : Public_key.t ; extensions : Ext.t ; } (** [info signing_request] is {!request_info}, the information inside the signing_request. *) val info : t -> request_info (** [signature_algorithm signing_request] is the algorithm used for the signature. *) val signature_algorithm : t -> (Key_type.signature_scheme * Mirage_crypto.Hash.hash) option (** [hostnames signing_request] is the set of domain names this [signing_request] is requesting. This is either the content of the DNS entries of the SubjectAlternativeName extension, or the common name of the [signing_request]. *) val hostnames : t -> Host.Set.t (** [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 -> ?extensions:Ext.t -> Private_key.t -> (t, [> `Msg of string ]) result (** {1 Provision a signing request to a certificate} *) (** [sign signing_request ~valid_from ~valid_until ~allowed_hashes ~digest ~serial ~extensions ~subject private issuer] creates [certificate], a signed certificate. Signing can fail if the signature on the [signing_request] is invalid, or its hash algorithm does not occur in [allowed_hashes] (default all SHA-2 algorithms). Public key and subject are taken from the [signing_request] unless [subject] is passed, the [extensions] are added to the X.509 certificate. The [private] key is used to sign the certificate, the [issuer] is recorded in the certificate. The digest defaults to [`SHA256]. The [serial] defaults to a random value between 1 and 2^64. Certificate version is always 3. Please note that the extensions in the [signing_request] are ignored, you can pass them using: {[match Ext.find Extensions (info csr).extensions with | Ok ext -> ext | 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 -> ?subject:Distinguished_name.t -> Private_key.t -> Distinguished_name.t -> (Certificate.t, Validation.signature_error) result end (** X.509 Certificate Revocation Lists. *) module CRL : sig (** A certificate revocation list is a signed structure consisting of an issuer, a timestamp, possibly a timestamp when to expect the next update, and a list of revoked certificates (represented by a serial, a revocation date, and extensions (e.g. reason) - see {{:https://tools.ietf.org/html/rfc5280#section-5.2}RFC 5280 section 5.2} for a list of available extensions (not enforced)). It also may contain any extensions, e.g. a CRL number and whether it is partial or complete. *) (** The type of a revocation list, kept abstract. *) type t (** {1 Encoding and decoding in ASN.1 DER format} *) (** [encode_der crl] is [buffer], the ASN.1 DER encoding of the given certificate revocation list. *) val encode_der : t -> Cstruct.t (** [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 (** {1 Operations on CRLs} *) (** [issuer c] is the issuer of the revocation list. *) val issuer : t -> Distinguished_name.t (** [this_update t] is the timestamp of the revocation list. *) val this_update : t -> Ptime.t (** [next_update t] is either [None] or [Some ts], the timestamp of the next update. *) val next_update : t -> Ptime.t option (** The type of a revoked certificate, which consists of a serial number, the revocation date, and possibly extensions. See {{: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 ; date : Ptime.t ; extensions : Extension.t } (** [reason revoked] extracts the [Reason] extension from [revoked] if present. *) val reason : revoked_cert -> Extension.reason option (** [revoked_certificates t] is the list of revoked certificates of the revocation list. *) val revoked_certificates : t -> revoked_cert list (** [extensions t] is the list of extensions, see RFC 5280 section 5.2 for possible values. *) val extensions : t -> Extension.t (** [crl_number t] is the number of the CRL. *) val crl_number : t -> int option (** [signature_algorithm t] is the algorithm used for the signature. *) val signature_algorithm : t -> (Key_type.signature_scheme * Mirage_crypto.Hash.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 -> Public_key.t -> (unit, [> Validation.signature_error ]) result (** The type of CRL verification errors. *) type verification_error = [ | Validation.signature_error | `Issuer_subject_mismatch of Distinguished_name.t * Distinguished_name.t | `Not_yet_valid of Distinguished_name.t * Ptime.t * Ptime.t | `Next_update_scheduled of Distinguished_name.t * Ptime.t * Ptime.t ] (** [pp_verification_error ppf vere] pretty-prints the CRL verification error [vere] on [ppf]. *) val pp_verification_error : verification_error Fmt.t (** [verify t ~allowed_hashes ~time cert] verifies that the issuer of [t] matches the subject of [cert], and validates the digital signature of the 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 -> ?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 -> 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 -> issuer:Distinguished_name.t -> this_update:Ptime.t -> ?next_update:Ptime.t -> ?extensions:Extension.t -> revoked_cert list -> Private_key.t -> (t, [> `Msg of string ]) result (** [revoke_certificate cert ~this_update ~next_update t priv] adds [cert] to the revocation list, increments its counter, adjusts [this_update] and [next_update] timestamps, and digitally signs it using [priv]. *) val revoke_certificate : revoked_cert -> this_update:Ptime.t -> ?next_update:Ptime.t -> t -> Private_key.t -> (t, [> `Msg of string ]) result (** [revoke_certificates certs ~this_update ~next_update t priv] adds [certs] to the revocation list, increments its counter, adjusts [this_update] and [next_update] timestamps, and digitally signs it using [priv]. *) val revoke_certificates : revoked_cert list -> this_update:Ptime.t -> ?next_update:Ptime.t -> t -> Private_key.t -> (t, [> `Msg of string ]) result end (** Certificate chain authenticators *) module Authenticator : sig (** An authenticator [t] is a function type which takes optionally an IP address, a hostname and a certificate stack to an authentication decision {!Validation.r}. If [ip] is specified, it needs to be present in the SubjectAlternativeName extension of the server certificate. *) type t = ?ip:Ipaddr.t -> host:[`host] Domain_name.t option -> Certificate.t list -> Validation.r (** [chain_of_trust ~time ~crls ~allowed_hashes trust_anchors] is [authenticator], which uses the given [time] and list of [trust_anchors] to verify the certificate chain. All signatures must use a hash algorithm specified in [allowed_hashes], defaults to SHA-2. Signatures on revocation lists [crls] must also use a hash algorithm in [allowed_hashes]. This is an implementation of the algorithm described in {{:https://tools.ietf.org/html/rfc5280#section-6.1}RFC 5280}, using {!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 (** [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 (** [server_cert_fingerprint ~time hash fingerprint] is an [authenticator] that uses the given [time] and [fingerprint] to verify the first element of the certificate chain, using {!Validation.trust_cert_fingerprint}. Note that {{!server_key_fingerprint}public key pinning} has {{: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 (** [of_string str] tries to parse the given [str] to an {!type:Authenticator.t}. The format of it is: - [none] no authentication, - [key-fp(:?):] to authenticate a peer via its key fingerprint (hash is optional and defaults to SHA256), - [cert-fp(:?):] to authenticate a peer via its certificate fingerprint (hash is optional and defaults to SHA256), - [trust-anchor(:)+] to authenticate a peer from a list of certificates (certificate must be in PEM format without header and footer (----BEGIN CERTIFICATE-----) and without newlines). If decoding is successful, the returned value expects a function which outputs the current timestamp ([unit -> Ptime.t option]) and is then an authenticator. If decoding fails, and error is returned. *) val of_string : string -> ((unit -> Ptime.t option) -> t, [> `Msg of string ]) result end (** PKCS12 archive files *) module PKCS12 : sig (** A PKCS12 encoded archive file, *) type t (** [decode_der buffer] is [t], the PKCS12 archive of [buffer]. *) val decode_der : Cstruct.t -> (t, [> `Msg of string ]) result (** [encode_der t] is [buf], the PKCS12 encoded archive of [t]. *) val encode_der : t -> Cstruct.t (** [verify password t] verifies and decrypts the PKCS12 archive [t]. The result is the contents of the archive. *) val verify : string -> t -> ([ `Certificate of Certificate.t | `Crl of CRL.t | `Private_key of Private_key.t | `Decrypted_private_key of Private_key.t ] list, [> `Msg of string ]) result (** [create ~mac ~algorithm ~iterations password certificates private_key] constructs a PKCS12 archive with [certificates] and [private_key]. They are encrypted with [algorithm] (using PBES2, PKCS5v2) and integrity protected using [mac]. A [local key id] is always embedded in the private key and matching certificate. *) val create : ?mac:[`SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ] -> ?algorithm:[ `AES128_CBC | `AES192_CBC | `AES256_CBC ] -> ?iterations:int -> string -> Certificate.t list -> Private_key.t -> t end (** OCSP (Online Certificate Status Protocol) as described in {{:https://tools.ietf.org/html/rfc6960}RFC 6960}. *) module OCSP : sig (** type for CertID to distinguish requested certs *) 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 -> cert_id (** [cert_id_serial certid] is serial number of this certid *) val cert_id_serial : cert_id -> Z.t (** [pp_cert_id ppf cert_id] pretty prints cert_id *) val pp_cert_id : cert_id Fmt.t (** Module for encoding and decoding OCSP requests. *) module Request : sig (** type for Request *) type t (** [pp ppf request] pretty prints request *) val pp : t Fmt.t (** [create ~certs ~digest ~requestor_name ~key certids] creates request 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 -> ?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 -> Public_key.t -> (unit, [> Validation.signature_error | `No_signature ]) result (** [requestor_name request] is requestorName from this request *) val requestor_name : t -> General_name.b option (** [cert_ids request] is cert ids from this request *) val cert_ids : t -> cert_id list (** [decode_der buffer] decodes request in buffer *) val decode_der : Cstruct.t -> (t, Asn.error) result (** [encode_der request] encodes request into buffer *) val encode_der : t -> Cstruct.t end (** Module for encoding and decoding OCSP responses. *) module Response : sig (** type for OCSPResponseStatus *) type status = [ | `InternalError | `MalformedRequest | `SigRequired | `Successful | `TryLater | `Unauthorized ] (** [pp_status ppf status] pretty prints status *) val pp_status : status Fmt.t (** type for CertStatus *) type cert_status = [ | `Good | `Revoked of Ptime.t * Extension.reason option | `Unknown ] (** [pp_cert_status ppf status] pretty prints cert status *) val pp_cert_status : cert_status Fmt.t (** type for SingleResponse *) type single_response (** [create_single_response ~next_update ~single_extension cert_id cert_status this_update] creates response info for one cert, [this_update] should be current time. *) val create_single_response : ?next_update:Ptime.t -> ?single_extensions:Extension.t -> cert_id -> cert_status -> Ptime.t -> single_response (** [pp_single_response ppf response] pretty prints single [response] *) val pp_single_response : single_response Fmt.t (** [single_response_cert_id response] is cert_id in this single [response] *) val single_response_cert_id : single_response -> cert_id (** [single_response_cert_id response] is cert_status in this single [response] *) val single_response_status : single_response -> cert_status (** type for ResponderID *) type responder_id = [ | `ByKey of Cstruct.t | `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. *) val create_responder_id : Public_key.t -> responder_id (** [pp_responder_id ppf responderID] pretty prints [responderID] *) val pp_responder_id : responder_id Fmt.t (** type for OCSPResponse *) type t (** [create_success ~digest ~certs ~response_extensions priv_key responderID producedAt responses] creates response and signs it with [priv_key]. [producedAt] should be current timestamp. *) val create_success : ?digest:Mirage_crypto.Hash.hash -> ?certs:Certificate.t list -> ?response_extensions:Extension.t -> Private_key.t -> responder_id -> Ptime.t -> single_response list -> (t, [> `Msg of string ]) result (** [create status] creates error response. Successful status is not allowed here because it requires responseBytes. *) val create : [ | `MalformedRequest | `InternalError | `TryLater | `SigRequired | `Unauthorized ] -> t (** [pp ppf response] pretty prints response *) val pp : t Fmt.t (** [status response] is response status *) val status : t -> status (** [responder_id request] is responder id from response *) val responder_id : t -> (responder_id, [> `Msg of string ]) result (** [responses response] is a list of responses (status per certificate). *) 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 (** [encode_der request] encodes response into buffer *) val encode_der : t -> Cstruct.t (** [validate response key] validates the signature of [response] with the pulic [key]. *) val validate : t -> ?allowed_hashes:Mirage_crypto.Hash.hash list -> ?now:Ptime.t -> Public_key.t -> (unit, [> Validation.signature_error | `No_signature | `Time_invalid ]) result end end ocaml-x509-0.16.5/tests/000077500000000000000000000000001445061461400145505ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/crl/000077500000000000000000000000001445061461400153305ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/crl/1.crl000066400000000000000000000012151445061461400161710ustar00rootroot000000000000000‚‰0‚q0  *†H†÷ 01 0 UEU1'0%U AC Camerfirma SA CIF A827432871#0!U http://www.chambersign.org1"0 UChambers of Commerce Root 170328101019Z 180328101019Z ½0º0«U#£0 €ã”õ±MéÛ¡)[W‹MvváÑ¢Š¡„¤01 0 UEU1'0%U AC Camerfirma SA CIF A827432871#0!U http://www.chambersign.org1"0 UChambers of Commerce Root‚0 U0  *†H†÷ ‚ª³ÔîrÓýÙr¯ùû>RÄ[XAí÷È®ˆ¢?N”»x€µÊ"¥—i˜:ÂÜLé‡Ë’$ך^br1öæA6ÝR‡l­ üÚ#‚-æáJN7þ˼rxP®’¹¸¦ñ&µÀ28Ê,Ø:ÊÇÚ£ê;˲ƒfZ)pgš7Õ4Ùp?æ]–è\ŸVKú€k,Ýb¯òLˆ¹ë$þˆ¥ïJUò…Äzˆ"Ó"ò`_•U¦ªA=å\3Íñ_Æ™3È(0ÖêP  ˆ,lnbïs}  )ûR ¦j1Ÿ•‹\²£á%êóø‡`#óªw›\G]'«‡úñé2K°ÿè €Cocaml-x509-0.16.5/tests/crl/1.pem000066400000000000000000000032511445061461400161740ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq 7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p 26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi 1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu tGWaIZDgqtCYvDi1czyL+Nw= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/10.crl000066400000000000000000000013371445061461400162560ustar00rootroot000000000000000‚Û0‚Ã0  *†H†÷ 0<10UComSign Secured CA10U ComSign1 0 UIL 161218112247Z 201230220000Z0‚ 0I Ö öôB³Î×KÛ 161218105749Z0&0 U 0U20161218105737Z0=y¬ÑmÄt˜at\O{³ 161218111722Z00U20161218111720Z0I\Ÿ)ñ3ÔHpµõ„#- 161218111142Z0&0 U 0U20161218111137Z0I}»}I sÍëµn 161218111034Z0&0 U 0U20161218111027Z /0-0U#0€ÁKíp¶÷>|;Ç>EŸ]ì0 U0  *†H†÷ ‚¨¥æ‘ªN¡²”tŒN½ÂtÚÔØÅfkè&ÀÝ?OçAòxêŠ%òüýIøXǹ™VSÃð5bacùÌ‹˜?O‰÷ß?@úH6n$ZVÝoЋ‹c±íªÛ­ü¾÷Íaiádßr§î3ÙHWà#Ëþ¢OKlöNT¾ï^wÜÏ^E©Ð(~­5$îUfðó! Œ°›£ñ±Ömæ¿“°ÌTòôðOé6á.¹­ºã¤öR¯_˜…‰ÄÈZµ“×§Oíÿ-Z-s Öà Ãbá9¤¬ÙÜ/»L£òÃvʪ‰æAe$àmÂò,¿á¿â´ýáoÈû–’Qocaml-x509-0.16.5/tests/crl/10.pem000066400000000000000000000024671445061461400162640ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr 9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt 6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/11.crl000066400000000000000000000007261445061461400162600ustar00rootroot000000000000000‚Ò0»0  *†H†÷ 0;10U Cybertrust, Inc10UCybertrust Global Root 170620161312Z 170915161312Z0<0 &”4° 160419100000Z0 7Nr© 110111102137Z 0 0 U.0  *†H†÷ ‚!ÕŽvI¼(§á½,íÜ:‰(ß;sÜUêNÒÓa8¥»çMÛýÖºŽßS’®/{KÌÿþ¤ øïÙ 35M–&[餤ØöÇÅY÷ —“êÕ7™¯‘*MÔìTY¸4 —tÃ, ÊL nƨöµŸ>køÂ@aÇyö¹ù¥w}ŒÁ2ß1Féa¼æàÜhùÔ®=C`D™4ob€ˆ"·IL–½d›Y¼.ñc¦CÕh¼y>:IâcÓ9¬™ocaml-x509-0.16.5/tests/crl/11.pem000066400000000000000000000024471445061461400162630ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW WL1WMRJOEcgh4LMRkWXbtKaIOM5V -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/12.crl000066400000000000000000000021411445061461400162520ustar00rootroot000000000000000‚]0‚Æ0  *†H†÷ 0Ã1 0 UUS10U  Entrust.net1;09U 2www.entrust.net/CPS incorp. by ref. (limits liab.)1%0#U (c) 1999 Entrust.net Limited1:08U1Entrust.net Secure Server Certification Authority 170627020538Z 170704020538Z0‚š0#L&S 170322202331Z0 0 U 0#L&R 170322202331Z0 0 U 0#L 161201192455Z0 0 U 0#L 161201192455Z0 0 U 0#LÇ 161128163108Z0 0 U 0#LÆ 161128163108Z0 0 U 0#LE 161123165549Z0 0 U 0#LD 161123165549Z0 0 U 0#LC 161123164917Z0 0 U 0#LB 161123164917Z0 0 U 0#LA 161123162502Z0 0 U 0#L@ 161123162502Z0 0 U 0#L 160824191728Z0 0 U 0#L 160824191728Z0 0 U 0#L 160824190727Z0 0 U 0#L 160824190727Z0 0 U 0#L 160824190020Z0 0 U 0#L 160824190020Z0 0 U  00.0 UMÂ0U#0€ðbU=³ÿ kûP„—óíbÐ0  *†H†÷ KHMDâÇúÏR^Æ ¢±!shÀô‰Ý+„7RÑ~¤Gá» ØÁ¡(Slß³Ïb(èr;Mbw@y0 .nA¬ú‚n3‹™uÎq(”Sò©ZÑŒê-Î8çnU¿=¤•\]nÄjY„úýŸÉðO‹ÆAm5rIr–üjÕ4«´ãÕ£ocaml-x509-0.16.5/tests/crl/12.pem000066400000000000000000000033151445061461400162570ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/13.crl000066400000000000000000000014571445061461400162640ustar00rootroot000000000000000‚+0‚0  *†H†÷  0L1 0U GlobalSign Root CA - R210U  GlobalSign10U GlobalSign 170615000000Z 180615000000Z0‚`0* " <u 141125000000Z0 0 U 0* " <Å 141125000000Z0 0 U 0*  Œ¡ 141125000000Z0 0 U 0* 'û÷g 141125000000Z0 0 U 0* DNðFN 161007000000Z0 0 U 0* V­_² 161007000000Z0 0 U 0* /Ná[c 170407000000Z0 0 U 0* /Ná]Ô 170407000000Z0 0 U  /0-0 U0U#0€›âWgÀjÞY´š-ß܆.0  *†H†÷  ‚ûšb WS~[&8Ù“E˹¸ýªEáĦJHÇ“>g †I«d”dÚ¥ksxÍÕÂ"§hvk®e+-p+eG~²Þx,k=Û¹Ÿà„öXïËþ=]¤Timäù6ÝNr(“‡ÔCP‹¾L… ›‹Ehí­c|Tò¤XT“³'a¨iy>MFìâŸ;ªfè†ÃÔöºZFïön˜™×%3{J`VÈøs“ŽfL'P6"2rÒt¦Cj Ä&&ƒ"wá@©Tƒ‘LG„y}þr€ñw°þÓØ2’ÅHTrƒqšÍW[ >yE¡‚ÜökL;%Û¸0UŽL»áocaml-x509-0.16.5/tests/crl/13.pem000066400000000000000000000025131445061461400162570ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/14.crl000066400000000000000000000012021445061461400162510ustar00rootroot000000000000000‚~0‚f0  *†H†÷ 0r1 0 UHU10UBudapest10U  Microsec Ltd.10U  e-Szigno CA1"0 UMicrosec e-Szigno Root CA 170318110001Z 170417120001Z ¿0¼0¬U#¤0¡€Ç Iua„Û1K„Òñ7@ïNÜ÷¡v¤t0r1 0 UHU10UBudapest10U  Microsec Ltd.10U  e-Szigno CA1"0 UMicrosec e-Szigno Root CA‚̸ç¿N)ý¢Üf¥,0 UÅ0  *†H†÷ ‚_»} /¤ÄU=)KО¼õN¥{³¿¤› ù#:øÏ£|ös?z{ĨÚHûU"ª"ywö͵”•º­$§¹[ÆvÒä‰ÌUxNGËxÚ‚´òx)0¦¼!38t!ØÜžŸ½Òá{ƒ”GS%×¼NÉz™#&kÂIÉ­ŒA%ø7¨N¾$o(>—>ÍýtKznÊr>ñ¥< ï“ù~/Âá5þÓßÏ}÷KYõcZâí¢»Õ*¦ SŠqŽ’¨ oSÉ‹1·:èÀï‹#¶‚ ‰ë&óß@0`Ê:ÒõÁ˜M»kt:2»ŽÇ×ämTÓ9~´Zœ3p‹‡¸J#.ƒocaml-x509-0.16.5/tests/crl/14.pem000066400000000000000000000052341445061461400162630ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4 NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+ LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770 Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx 62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5 ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS 8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl 7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a 86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/ MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/15.crl000066400000000000000000000007411445061461400162610ustar00rootroot000000000000000‚Ý0Æ0  *†H†÷ 0b1 0 UUS1!0U Network Solutions L.L.C.100.U'Network Solutions Certificate Authority 170627164245Z 170701164245Z 00.0U#0€!0Éû×N˜Ú‡ª*Ч.±@1§L0 U…0  *†H†÷ ‚Ó¤Y¨KÔçäyõ“3 ¬LEÄŽeV¶?uËcÎ’q–Ïe‹‚@EVªZˆäî@«–7ÊÀ@]ïO{¼Ù _в` ÿúiŽï•ñ@µÏ>[ŒNøæ#ÉzWó@h‡6ןHµA1 Ç“£0£ŸÐ~MŠ É:~(õsw¶lÞ킸ÌV.B;ýˆRAÑOˆ¢ŒÙ©vwcüÓŽ•£}ÅØ QpT׿'«xð‚ýld•Ç|ɺ&’’<*\ä™÷°ÓDþš±@[uà¼X!¨½ÉR{S9!%\¼Tm³æ#NÊÑa=n¥kÒ<úFocaml-x509-0.16.5/tests/crl/15.pem000066400000000000000000000026041445061461400162620ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH /nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/16.crl000066400000000000000000000007721445061461400162660ustar00rootroot000000000000000‚ö0ß0  *†H†÷ 0J1 0 UUS1 0U SecureTrust Corporation10USecure Global CA 170523174408Z 180522184408Z0.0@' 150812203011Z0M|m 150812203011Z 10/0 U=‘0U#0€¯DÂA~HƒÛN9ìì„zæÎɤ0  *†H†÷ ‚! DRÇ.áqM%ä4±q@€öÙŸÙNŒÓý@z?À¹4Zrˆ_MÖ/鿲  Œ½ÃZ‡ì‘ªßgáXëzž?Î/¸v®­&ƒÂ;J‚Mk&Ïê ¿òf‹c<ÅÁ›zº@þ…|×¶ø ƒd¶žÅ*N“SpQh ʈÄ'£óÅ&>Ñnî_9T€ 6ÞʼnðeÉÔ¨Ž× uBsÉj%Ê&ƒ±ô\{" ]‡Ós—F)â±TF|óŒwÃÏÀì%q¯º®A¿R4r€2¢Zžƽ-Eo}gu¡ïµó<ëÒˆx<äO|°¨ ô_¼ocaml-x509-0.16.5/tests/crl/16.pem000066400000000000000000000025131445061461400162620ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa /FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/17.crl000066400000000000000000000013071445061461400162620ustar00rootroot000000000000000‚Ã0‚«0  *†H†÷ 0H1 0 UUS1 0U SecureTrust Corporation10USecureTrust CA 170523174408Z 180522184408Z0û00IK 150812203013Z00IL 150812203007Z0@Ñ 071210224749Z0@Õ 071115083728Z0G†Ÿä 150812203006Z0Gøö¨ 170125173041Z01eSò¡ 090915201255Z01eSõ` 090915201255Z0 @Ä~þW 080408193354Z0"Ü ¬‹H'jÜ*\’Ü»žÓµ 150812203012Z 10/0 UAÈ0U#0€B2¶úýþ]KzÃý÷L@ZC¯0  *†H†÷ ‚FžºÇÞ“y3þç˜wÁŽ”¿wñ¿ø‰©mçsªÙ„77vÂxX TNéLfô7(«¶HÚü_ÿà‘IÂаӕ‚èÀâa›ï”Ì’QxÑ¿ Ô†YAGæ½ /Ù,{h ¸/ÀJµ@·6 ”?P;œÌÓ>ú…ù¬bË((ÿ… "ÃðW0å³´Ò‡vv·ù«…È£P'Ów‹,Ê “òS]ŠcG Î«›¸Ã°'šdYΑÃÓf-„j5CÈHÛm¿Äý1æÚ»‡ÃäN‰ˆ¤çSWÐûüL_ŸƒÐ¡¯daëšùš]°®§^d‚˜5ž,›m¥-ôÙÒ|ocaml-x509-0.16.5/tests/crl/17.pem000066400000000000000000000025071445061461400162660ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO 0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj 7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS 8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB /zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ 3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/18.crl000066400000000000000000000017111445061461400162620ustar00rootroot000000000000000‚Å0‚­0  *†H†÷  0}1 0 UIL10U  StartCom Ltd.1+0)U "Secure Digital Certificate Signing1)0'U StartCom Certification Authority 170401041447Z 180401041447Z0Ê0/ 110319055235Z00 110319055246Z01 110401065531Z02 110401065546Z0Â…0é;6 170401041200Z0Χö©é 170401041200Z0!NZø¡43#þƒjJ 170401041200Z0!DÑ;ÐñˆPŸs$Ù Ÿ4 170401041200Z /0-0U#0€N ï¤@[¥i‡0Ê4hCÐA®ò0 U0  *†H†÷  ‚®;¬SšÂBr ÑFÀeX{9¨èj0ÂÚˆC9ÉWk·‘u *±)èAÙ=üâç£eC~3Ò5½./5Ò8gáð¶Ä¸—IÉ´RMCS¿åkŽ‚BèLJ‹6ØçM¤WfiIå]¬$YŸ“*%´@Çàz“KCÐv–øw0WÂFjÈ‹¡qZ硯_Oév1¯M?Xƒô¹7à­Á øï‰.–ÜÃøñ+u=3¼ZjèØêGÛÏSàKK¨,íaP3l¯ [6ˆ Úê¬ÿJIù7ÐK~§ÃÔ8ŸÔèFXÁV¡Âï(¬à^ÚÀTþŽB$ýÝÔ"EÅåo8¯¾QÁØÇ„§ÆuE92fÉ6l÷>Å­c=òZog»s‘ëH£u²h7´@ z÷¥õÀ¬CëoÉQ”ñúÉ=ÑGî®þ½øÛsO·öL ©Ãc Ý^wWzµ¤oñ²;^caêÔZÛ•XL•XÀH~ }*që7‚âL ±tºó+ÚÍÄJ’Qc eªCúaæØÇ§0M@@†ÛåOnŸÖcdVXIä&H±ÒÇf@¡Û‹t*ìpk|™Ïa{§ý½’ÑjIa xUPRû×Ì@3n‹„ûâ…žÙ"ÃX6 rpèÈž÷¹·À]%Ìe‚Ùz8g·ocaml-x509-0.16.5/tests/crl/18.pem000066400000000000000000000053111445061461400162630ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w +2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B 26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ 9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/19.crl000066400000000000000000000023631445061461400162670ustar00rootroot000000000000000‚ï0‚×0  *†H†÷ 0v1 0 UDE10U TC TrustCenter GmbH1"0 U TC TrustCenter Class 2 CA1%0#UTC TrustCenter Class 2 CA II 150105113737Z 251231113737Z0‚ù0-››R'bv 141230094333Z0 0 U 0-Mæÿùu3óu 141230095019Z0 0 U 0-(Z1áûjÕ×Añ 141230100151Z0 0 U 0O.~Pg”°o 141105222326Z0 ¼ê|~6jiAV| 141105221925Z0-Aû[·É®­_ 140630142613Z0 0 U 0Àµ)O hPË 141104133931Z0.æ‡Ø_‘í<H 110929095607Z0 0 U 0.’‘ÿ5ª:‘1%Œ 140701090432Z0 0 U 0W¼'º™³.Pcq 141104135227Z0P…CYñó.Í& 150105112510Z0.´Ûx¹ Í*cSØ 141230093751Z0 0 U 0 ›bËÕx¸d»` 141105215928Z0. ÊÐ:™éõKË 141230093932Z0 0 U 0.¶´:çÔë(Œ 141230094153Z0 0 U 0Øí =17I}û 141104133941Z0‡üÁοXfGV 141105215326Z0 »tU~|û5ó‡ 141105214925Z0, íþÈ›¹á 141105225531Z 00.0U#0€ã«TL€¡ÛVC·‘JËó‚z\«0 U ¬0  *†H†÷ ‚©ì§´ åð%ЮxŒÔ[2„y¥Í”k{[kŠYÓö$ˆÜ&¸w×ÚoÝ·ê¿pÞOª?b> ¿¡áÐ½Éøe]üìÎŽ‡ &"×2ùV¶, 3ñÂ?)Ù‰ï\r¨ëü¶®…§l €µÒÉñzUViï§"Ól$6H}GF–ã ^98­‘?=S<ÛSUJèÑqŒŽ> áž¡ú,óÕøkH8 !ù}D^q ®äþ¬FÚ/xÿ}C´£FçΈÀõ¯¼Ù¢ÑÓJ ¶5âÇ>A;ÓuKäHI*ÀÔkÎÅ55Â<ê‘ÜY5Ì{Ñ¿§YÊQˆT#žN(AyJÿj/êßK5Qhðçocaml-x509-0.16.5/tests/crl/19.pem000066400000000000000000000032201445061461400162610ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1 OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK 8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99 5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3 kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6 Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8 au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/2.crl000066400000000000000000000012101445061461400161650ustar00rootroot000000000000000‚„0‚l0  *†H†÷ 0}1 0 UEU1'0%U AC Camerfirma SA CIF A827432871#0!U http://www.chambersign.org1 0UGlobal Chambersign Root 170328101041Z 180328101041Z º0·0¨U# 0€Cœ6Ÿ°ž0MÆÎ_­«å¥ú©¡¤0}1 0 UEU1'0%U AC Camerfirma SA CIF A827432871#0!U http://www.chambersign.org1 0UGlobal Chambersign Root‚0 U0  *†H†÷ ‚h\|R/•Ã7‘¹Ÿ¸R¤Í>d¾…ƒm¾Üæá~‡n²]˜M½•ß3X\—SÁîê•´Ö:ï• }ïw óÅ|Ž …Žøocaml-x509-0.16.5/tests/crl/2.pem000066400000000000000000000032651445061461400162020ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9 MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0 Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795 B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/20.crl000066400000000000000000000016351445061461400162600ustar00rootroot000000000000000‚™0‚0  *†H†÷ 0v1 0 UDE10U TC TrustCenter GmbH1"0 U TC TrustCenter Class 3 CA1%0#UTC TrustCenter Class 3 CA II 170626225959Z 170703225959Z0‚£0.ç"ƒ^UûTÏ 141119134703Z0 0 U 0hœ(ñ¥¯eH 141105224132Z0 Å*ÓôQƒ‰¾ò 141105223128Z0 ôv«i6pùά 141105224122Z0.ë– ùÔ’ñ!¤ 141119151317Z0 0 U 0.ÙPsw<€<Òqž 140701083354Z0 0 U 0-YDÇ—Ý-Š5·4 141119151316Z0 0 U 0-` ü'½~@äbÔ 141119151317Z0 0 U 0-C;êaê' ’ì 141119151316Z0 0 U 0 )EyÀ«¡øë¥ 150115090000Z 00.0 U0U#0€Ô¢üŸ³ÃØÓW\¤Ð$§ÀòÔ0  *†H†÷ ‚•P;Ó]Ó~ùFÓÏQ¥hã:v¼ô€pN-ûêÐg™ÚˆRÁ@«ÛTÍTÓ@]'¸˜'qó7ÎÕ)À§ü9pr©ÿ_2™óþ÷ÇŽäæü>lú¶Ã—Iš6ag§R-%C¿2´aB °|—QjáÈÈbͫΕ•¨8†Ã$ªîƒHx~2öùH[Êðàj¸³ò×l*CSÁƒñ ‚°—\îeÀ&uÂj4{{eÔíP_rÍÂcÄÃq"¥º³œ¿²±û“‹!A Úä€]ä™H˜+ö©4;›a¦Nx %A­ëâùÕqâÈÕ Q4ÉŽT©³ñýk ocaml-x509-0.16.5/tests/crl/20.pem000066400000000000000000000032201445061461400162510ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB 95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/21.crl000066400000000000000000000010711445061461400162530ustar00rootroot000000000000000‚50‚0  *†H†÷ 0“1 0 UUS1 0 UUT10USalt Lake City10U The USERTRUST Network1!0U http://www.usertrust.com10UUTN - DATACorp SGC 170627164245Z 170701164245Z0#0! ^{ÒjíÊ À^é 161004055749Z 00.0U#0€S2ѳÏúàñ ]…N’ÒžE´O0 U0  *†H†÷ ‚ž…ýN¯òfÎõC—qkLkDÐÎ=GÿNÐý)Q{¶öý;£$‹Ày™·AŒ¸Z½P²¾]IÉqŸyÙ ‡¶Öð9^ s¬gPã¿C°Ðñ¢é˜ú´N ÌkpEBCNìÏ‚û cã@´ðb¥%¦œÙNŒ'¿U1îjw·N/ac¼,ÿÏS{ÙS® ™bªßÝ‹_ô Pé»ËÉlŸeýÙ›ð $ˆá¨f:ö §3Âõ`QßÀ­Þö"‡Ô,­ÑÒ·—ÍËDÉq¡Þ:4¥‹KÀYZK-3^‚í J£N™0Ò( Ð:÷ÀßËlJº=;hŠÁ7<ýž­ocaml-x509-0.16.5/tests/crl/21.pem000066400000000000000000000030471445061461400162610ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK 4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv 2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 mfnGV/TJVTl4uix5yaaIK/QI -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/3.crl000066400000000000000000000032711445061461400161770ustar00rootroot000000000000000‚µ0‚0  *†H†÷  0=1 0 UFR10U Certplus10UClass 2 Primary CA 160623000000Z 170723000000Z0‚ù01 2[òWßèY"ž8%]M› 160623000000Z0 0 U 01 Ø\Ðaç^ }sćÀŽ 160623000000Z0 0 U 01 ýbÈì"9>ÍÂ*~Rˆ 160623000000Z0 0 U 01 îÚxe,üßÇâØ‚9Xÿä 160623000000Z0 0 U 01 ‹E[¡qFZ–â !YQ'Ž 160623000000Z0 0 U 01 ȵ~+¹h‹ž¹sÒ¹8ý¹³ 160623000000Z0 0 U 01 r4–yLøàö&r/¦¿‡–q 140520000000Z0 0 U 01 •¢Ÿãó‚×øX™+ÓQ¡ 140520000000Z0 0 U 01 ¢³ž½¢jÛom2É!w÷æ„ 150205000000Z0 0 U 01" tÊw®x­Ë„kÉd 140505000000Z0 0 U 01"f»§ŠÇ®®ƒi­ ÂS 140520000000Z0 0 U 01"¸?ÁÕ¶´í*aÝ!s 150205000000Z0 0 U 01"dÚ|ƒMZŒ9ÿ}$ƒÂ:¦Ç 150303000000Z0 0 U 01"—¯#N†»•…·5rŠä § 160202000000Z0 0 U 01"¦¼IOC5K²9~†b;JT 140328000000Z0 0 U 01"»ª×ÏÐ…hrÄþxWB5¢ 160202000000Z0 0 U 01"¾ˆM4<&Õe_ |nö 151103105212Z0 0 U  /0-0 U0U#0€ãs-ßË( Þݳ¤Êy¸Ž»è0‰0  *†H†÷  ‚˜ #ËœäuK“Í–»&,BàÃS[s‚Œ@j/Þ«6*ÅÒVK%{íç4‰ÓRé; 'ÿµ&T ÿëËöº9<óî—zäX?<8îÊÆeT  ™2i÷U±ÿ¨&,4XÑ…ˆA9Gp[[4~TZ,^×§n ƒð…îp˜×”-+‹&šŽ¹{[h˜…µ$£ŠõpÜ\Ÿî5Me¤¬E¬t!Ç“Á”~Pºµ Õ¸Ãõ2$WÉSÎÒ@œ\ÈØk00xöIfåì†ÖòÒ´Ý&ðˆfN ½) Ca]ˆWá«vøÕ¯,PˆÆ3Äê7:aocaml-x509-0.16.5/tests/crl/3.pem000066400000000000000000000024231445061461400161760ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 l7+ijrRU -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/4.crl000066400000000000000000000007721445061461400162030ustar00rootroot000000000000000‚ö0ß0  *†H†÷ 0{1 0 UGB10U Greater Manchester10U Salford10U Comodo CA Limited1!0U AAA Certificate Services 170624194245Z 170628194245Z 00.0U#0€  #>–ñìâ¯)ï‚¥Ð0¤´0 U?0  *†H†÷ ‚Gæ\`H8ž yòÇ¥0ª„˜zû—R8D¥æ€\öp~Úþ.ö“ ,‹g·ö•Né¸@Æñ‘³-FhîB<¸–lƒáÙ­V¤ó( œ-Eà~ì³J9`„µyIZÿl9e:Ïû }|X\Á¬“k5¤¢Ñ|_BÉqìéò(zÉ%î[æøt4·*$cõ¯)h`%\kX²™§ôd+Z ç^¥¿77¨ Ò{7!ÃDeÑ2ÕºÊØ”(bT²Ò1ÔÝš°ëƒSÃù¯¾¾,•~—YSÿ&„f£˜”*k¢—ýa£j²ÐTùmÒº)Cƒnhv:œä°Úocaml-x509-0.16.5/tests/crl/4.pem000066400000000000000000000027561445061461400162100ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe 3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/5.crl000066400000000000000000000165361445061461400162110ustar00rootroot000000000000000‚Z0‚B0  *†H†÷ 0‚1 0 UUS10U www.xrampsecurity.com1$0"U XRamp Security Services Inc1-0+U$XRamp Global Certification Authority 170523174408Z 180522184408Z0‚V0@8¹ 071025215205Z0@8º 071025215205Z0@8õ 071025215205Z0@8ö 071025215205Z0@8÷ 071025215205Z0@8ø 071025215205Z0@8ù 071025215205Z0@8ú 071025215205Z0@8û 071025215205Z0@8ü 071025215205Z0@8ý 071025215205Z0@8þ 071025215206Z0@8ÿ 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8  071025215206Z0@8  071025215206Z0@8  071025215206Z0@8  071025215206Z0@8  071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8 071025215206Z0@8  071025215206Z0@8! 071025215206Z0@8" 071025215206Z0@8# 071025215206Z0@8$ 071025215206Z0@8% 071025215206Z0@8& 071025215206Z0@8' 071025215206Z0@8( 071025215206Z0@8) 071025215206Z0@8* 071025215206Z0@8+ 071025215206Z0@8, 071025215206Z0@8- 071025215206Z0@8. 071025215206Z0@8/ 071025215206Z0@80 071025215206Z0@81 071025215206Z0@82 071025215206Z0@83 071025215206Z0@84 071025215206Z0@85 071025215206Z0@86 071025215206Z0@87 071025215206Z0@88 071025215206Z0@89 071025215206Z0@8: 071025215206Z0@8; 071025215206Z0@8< 071025215206Z0@8= 071025215206Z0@8> 071025215206Z0@8? 071025215206Z0@8@ 071025215206Z0@8A 071025215206Z0@8B 071025215206Z0@8C 071025215206Z0@8D 071025215206Z0@8E 071025215206Z0@8F 071025215206Z0@8G 071025215206Z0@8H 071025215207Z0@8I 071025215207Z0@8J 071025215207Z0@8K 071025215207Z0@8L 071025215207Z0@8M 071025215207Z0@8N 071025215207Z0@8O 071025215207Z0@8P 071025215207Z0@8Q 071025215207Z0@8R 071025215207Z0@8S 071025215207Z0@8T 071025215207Z0@8U 071025215207Z0@8V 071025215207Z0@8W 071025215207Z0@8X 071025215207Z0@8Y 071025215207Z0@8Z 071025215207Z0@8[ 071025215207Z0@8\ 071025215207Z0@8] 071025215207Z0@8^ 071025215207Z0@8_ 071025215207Z0@8` 071025215207Z0@8a 071025215207Z0@8b 071025215207Z0@8c 071025215207Z0@8d 071025215207Z0@8e 071025215207Z0@8f 071025215207Z0@8g 071025215207Z0@8h 071025215207Z0@8i 071025215207Z0@8j 071025215207Z0@8k 071025215207Z0@8l 071025215207Z0@8m 071025215207Z0@8n 071025215207Z0@8o 071025215207Z0@8p 071025215207Z0@8q 071025215207Z0@8r 071025215207Z0@8s 071025215207Z0@8t 071025215207Z0@8u 071025215207Z0@8v 071025215207Z0@8w 071025215207Z0@8x 071025215207Z0@8y 071025215207Z0@8z 071025215207Z0@8{ 071025215207Z0@8| 071025215207Z0@8} 071025215207Z0@8~ 071025215207Z0@8 071025215207Z0@8€ 071025215207Z0@8 071025215207Z0@8‚ 071025215207Z0@8ƒ 071025215207Z0@8„ 071025215207Z0@8… 071025215207Z0@8† 071025215207Z0@8‡ 071025215207Z0@8ˆ 071025215207Z0@8‰ 071025215207Z0@8Š 071025215207Z0@8‹ 071025215207Z0@8Œ 071025215207Z0@8 071025215207Z0@8Ž 071025215207Z0@8 071025215207Z0@8 071025215207Z0@8‘ 071025215208Z0@8’ 071025215208Z0@8“ 071025215208Z0@8” 071025215208Z0@8• 071025215208Z0@8– 071025215208Z0@8— 071025215208Z0@8˜ 071025215208Z0@8™ 071025215208Z0@8š 071025215208Z0@8› 071025215208Z0@8œ 071025215208Z0@8 071025215208Z0@8ž 071025215208Z0@8Ÿ 071025215208Z0@8  071025215208Z0@8¡ 071025215208Z0@8¢ 071025215208Z0@8£ 071025215208Z0@8¤ 071025215208Z0@8¥ 071025215208Z0@8¦ 071025215208Z0@8§ 071025215208Z0@8¨ 071025215208Z0@8© 071025215208Z0@8ª 071025215208Z0@8« 071025215208Z0@8¬ 071025215208Z0@8­ 071025215208Z0@8® 071025215208Z0@8¯ 071025215208Z0@8° 071025215208Z0@8± 071025215208Z0@8² 071025215208Z0@8³ 071025215208Z0@8´ 071025215208Z0@8µ 071025215208Z0@8¶ 071025215208Z0@8· 071025215208Z0@8¸ 071025215208Z0@8¹ 071025215208Z0@8º 071025215208Z0@8» 071025215208Z0@8¼ 071025215208Z0@8½ 071025215208Z0@8¾ 071025215208Z0@8¿ 071025215208Z0@8À 071025215208Z0@8Á 071025215208Z0@8 071025215208Z0@8à 071025215208Z0@8Ä 071025215208Z0@8Å 071025215208Z0@8Æ 071025215208Z0@8Ç 071025215208Z0@8È 071025215208Z0@8É 071025215208Z0@8Ê 071025215208Z0@8Ë 071025215208Z0@8Ì 071025215208Z0@8Í 071025215208Z0@8Î 071025215208Z0@8Ï 071025215208Z0@8Ð 071025215208Z0@8Ñ 071025215208Z0@8Ò 071025215208Z0@8Ó 071025215208Z0@8Ô 071025215208Z0@8Õ 071025215208Z0@8Ö 071025215208Z0@8× 071025215208Z0@8Ø 071025215209Z0@8Ù 071025215209Z0@8Ú 071025215209Z0@8Û 071025215209Z0@8Ü 071025215209Z0@8Ý 071025215209Z0@8Þ 071025215209Z0@8ß 071025215209Z0@8à 071025215209Z0@8á 071025215209Z0@8â 071025215209Z0@8ã 071025215209Z0@8ä 071025215209Z0@8å 071025215209Z0@8æ 071025215209Z0@8ç 071025215209Z0@8è 071025215209Z0@8é 071025215209Z0@8ê 071025215209Z0@8ë 071025215209Z0@8ì 071025215209Z0@8í 071025215209Z0@8î 071025215209Z0@8ï 071025215209Z0@8ð 071025215209Z0@8ñ 071025215209Z0@8ò 071025215209Z0@8ó 071025215209Z0@8ô 071025215209Z0@8õ 071025215209Z0@8ö 071025215209Z0@8÷ 071025215209Z0@8ø 071025215209Z0@8ù 071025215209Z0@8ú 071025215209Z0@8û 071025215209Z0@8ü 071025215209Z0@8ý 071025215209Z0@8þ 071025215209Z0@8ÿ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘  071025215209Z0@8‘  071025215209Z0@8‘  071025215209Z0@8‘  071025215209Z0@8‘  071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘ 071025215209Z0@8‘  071025215209Z0@8‘! 071025215209Z0@8‘# 071025215209Z0@8‘$ 071025215209Z0@8‘+ 071025215205Z0@8‘, 071025215209Z0@8¹¯ 150812203006Z0@8¹° 150812203008Z0@8¹± 150812203015Z0A«¼ 160622181202Z0A«½ 150812203007Z0 Ú·,2  071115084138Z 10/0 U=Ö0U#0€ÆO¢=c„ œÎbä¬\µé¶0  *†H†÷ ‚sÐ06Å*«lRÇí¡E²fse$(ÓÝ]¹qQj0}˜ØÛ·rlN„ÂtaA¯è¶jDŸ`6ŒqÜ%Ý’ëi{D;,… @ç$1Ýš´ašª-·NQO*…Gæ/3ø›½ÏÐ)Ljôaÿ¥©d' ×q:⮸:™ݵ<œ8b 0MN㟌æDdýÕÄBu+ù½ûæyvhtâ„ÚI «»bªÑȾ=+»ÅÖ´0èCþ0þD)Ú '¡Gç>¢ôQN(©TnÈ|Ei¤í»€fǶ€¶ ]ÝÛŠ@'ш¸ÝDûÎô(#ì‚ôîihBÚç¥ÛvಥÊocaml-x509-0.16.5/tests/crl/5.pem000066400000000000000000000027521445061461400162050ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ O+7ETPTsJ3xCwnR8gooJybQDJbw= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/6.crl000066400000000000000000000010011445061461400161670ustar00rootroot000000000000000‚ý0æ0  *†H†÷ 01 0 UGB10UGreater Manchester10USalford10U COMODO CA Limited1'0%UCOMODO Certification Authority 170624194245Z 170628194245Z 00.0U#0€ X勯L7¤@©0©!¾G6ZVÿ0 U0  *†H†÷ ‚€Ã¯nc£´EÇPoüžlÒûÛ0)wg$Ò-1=<ý6´=ؤ¼ïH×ÝDRAvè³c'®µª Z"éæª‚ük—q–è$ÒÎ^ÍàFåÅçi¥`²êÇœ=PvXõ6Ò{E’8Ów–^‰N,ÉÆ»ÙŸ¼3‘ü2©ÌüïJ‡3HWY°nòSÅPVóÿbÎÀ¿g]7IBpõ4l^¢‰Éa62  ÍU Qâw¢$^‹“Âc𤥄£¼AE>P7‹‚W¤v¢2zñ =Æ ß?0 N¿LB+e×µHè”9)9˜wvZ*/âÙ’ÀÛ"·É’¡Yª¼pã]g¿‘/Ùocaml-x509-0.16.5/tests/crl/6.pem000066400000000000000000000027221445061461400162030ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI 2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp +2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW /zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB ZQ== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/7.crl000066400000000000000000000007751445061461400162110ustar00rootroot000000000000000‚ù0â0  *†H†÷ 0~1 0 UGB10U Greater Manchester10U Salford10U Comodo CA Limited1$0"U Secure Certificate Services 170626174245Z 170630174245Z 00.0U#0€<Ø“ˆÂÀ‚ Ì™“ éžp cO0 U“0  *†H†÷ ‚P.ÓÐ m2÷ëîm;§’mû’ö˜$BEþ"äiÃÖÞçT C}ƒ&±È fÓñgXª‰jcÃ"@:<ù6÷Ý0|lþœ±ßĸ³<BÁ®£Oi$¥6d2,öaáICaûOæh);”8-o«QØ‘š\UÄ›D©—Ç­‘GÚ7há#$dbúdwÞf2$˜R°W¶¢t‰{E4qwÖþFQl`‘B&D0*ÇI~»,×­÷•%óë©Sú¼ÝX «M›QN+BZ%È:«”Ùcz=­ÙÂÉØ,Fí îJ$-°i#Û¿‡ÃÐn¡™¨ù .m z´ocaml-x509-0.16.5/tests/crl/7.pem000066400000000000000000000027761445061461400162150ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk 3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz 6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/8.crl000066400000000000000000000007761445061461400162130ustar00rootroot000000000000000‚ú0ã0  *†H†÷ 01 0 UGB10U Greater Manchester10U Salford10U Comodo CA Limited1%0#U Trusted Certificate Services 170626174245Z 170630174245Z 00.0U#0€Å{X½íÚ%iÒ÷Y¨³2À{'[ô0 U“0  *†H†÷ ‚3ŸY¿ë¬ 5©²¦Åßz…§Â.þ½‚gµ—f­×7_ (h49o§Oƒ¡¹§lIo:v$xL®GAÎÈ>ÓVªµz_á¢Ä4'èw»^«ÚýjÇÒäT÷n6ì‘'«Ð'›sÍÓ‘?˜XÖK¤-\{’åÐŒñO¼Rÿö¾~?p¯çæ3Ë ’“òñê–ÂÒO“¥õLC:`o@=Ç„*.__©W\ìc0†ÿ,ƒE1òEŽM¡~éiÂñ£ê+ {x?Ž^®l9Ô¯lÒè ´øþâÞCº¸7fÃ~Ìu$ÈImq ¨UÝ úì0ÏÖž uocaml-x509-0.16.5/tests/crl/8.pem000066400000000000000000000030021445061461400161750ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW 1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crl/9.crl000066400000000000000000000007771445061461400162150ustar00rootroot000000000000000‚û0ä0  *†H†÷ 0410U ComSign CA10U ComSign1 0 UIL 161218112129Z 201230220000Z0K0IY‰DüKÄczÓ„Åt£I 140114163302Z0&0 U 0U20140114163258Z /0-0U#0€K›>Ve6vË{—ª’î2ç(10 U0  *†H†÷ ‚t²üAàY%Œ³L˜ÔB<;ãï¥ rÚjv5)ñ©Œplg¾¹òSh~õ’Hú+l¤*~O º~{¼Õí´àYŒ™í`þïÈΆ)%5êƒt-h…ϸ/>tÙtfŠR^[:äLú«ìÏåsQ~Ê„ÙÂSñ{Œ£ƒ¬·Z݉ªR +HÙBA2€fF1Æm…yrû ôVB—Ÿ7­n’ÎW!ãäpóT—ø«ÒOQ¥œšr†*­BÀüÖ]w'Cg|¯0‚Uœâ¡…|Á$Ó?|oÒ¹Ö•ehÊk¤+ñ„ÛŠO$Ý®8g“‡­Sª}LŒì¯jc‰Î¬3ˆ ocaml-x509-0.16.5/tests/crl/9.pem000066400000000000000000000024271445061461400162100ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0 MRMwEQYDVQQDEwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQG EwJJTDAeFw0wNDAzMjQxMTMyMThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMT CkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNpZ24xCzAJBgNVBAYTAklMMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49qROR+WCf4C9DklBKK 8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTyP2Q2 98CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb 2CEJKHxNGGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxC ejVb7Us6eva1jsz/D3zkYDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7Kpi Xd3DTKaCQeQzC6zJMw9kglcq/QytNuEMrkvF7zuZ2SOzW120V+x0cAwqTwIDAQAB o4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDovL2Zl ZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0PAQH/BAQD AgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRL AZs+VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWd foPPbrxHbvUanlR2QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0M cXS6hMTXcpuEfDhOZAYnKuGntewImbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq 8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb/627HOkthIDYIb6FUtnUdLlp hbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VGzT2ouvDzuFYk Res3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U AGegcQCCSA== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/crltests.ml000066400000000000000000000035011445061461400167440ustar00rootroot00000000000000open X509 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) in let buf1 = Unix_cstruct.of_fd fd1 and buf2 = Unix_cstruct.of_fd fd2 in try let r = f buf1 buf2 in Unix.close fd1 ; Unix.close fd2 ; match r with | Ok x -> x | Error (`Msg e) -> Alcotest.failf "decoding error %s" e with e -> Unix.close fd1 ; Unix.close fd2 ; Alcotest.failf "exception %s" (Printexc.to_string e) let allowed_hashes = [ `SHA1 ; `SHA256 ; `SHA384 ; `SHA512 ] let one f () = with_loaded_files f ~f:(fun cert crl -> let ( let* ) = Result.bind in let* cert = Certificate.decode_pem cert in let pubkey = Certificate.public_key cert in let* crl = CRL.decode_der crl in Result.map_error (fun e -> `Msg (Fmt.to_to_string Validation.pp_signature_error e)) (CRL.validate crl ~allowed_hashes pubkey)) let crl_tests = [ "CRL 1 is good", `Quick, one "1" ; "CRL 2 is good", `Quick, one "2" ; "CRL 3 is good", `Quick, one "3" ; "CRL 4 is good", `Quick, one "4" ; "CRL 5 is good", `Quick, one "5" ; "CRL 6 is good", `Quick, one "6" ; "CRL 7 is good", `Quick, one "7" ; "CRL 8 is good", `Quick, one "8" ; "CRL 9 is good", `Quick, one "9" ; "CRL 10 is good", `Quick, one "10" ; "CRL 11 is good", `Quick, one "11" ; "CRL 12 is good", `Quick, one "12" ; "CRL 13 is good", `Quick, one "13" ; "CRL 14 is good", `Quick, one "14" ; "CRL 15 is good", `Quick, one "15" ; "CRL 16 is good", `Quick, one "16" ; "CRL 17 is good", `Quick, one "17" ; "CRL 18 is good", `Quick, one "18" ; "CRL 19 is good", `Quick, one "19" ; "CRL 20 is good", `Quick, one "20" ; "CRL 21 is good", `Quick, one "21" ; ] ocaml-x509-0.16.5/tests/csr/000077500000000000000000000000001445061461400153375ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/csr/wild-bar.pem000066400000000000000000000017551445061461400175530ustar00rootroot00000000000000-----BEGIN CERTIFICATE REQUEST----- MIICrDCCAZQCAQAwEjEQMA4GA1UEAwwHZm9vLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAMQibfgxbLeWXHbhy9olGapJd7zUQXWmbMkVUF0BWWaI 2BmdYHJYhupoK3kY5NQL/ghz3TwHU+K8lKMzQt0sX0w44VzHv8hG8wYHEjKvyL81 o97c/eYxT703oGu1h9WwtwtRVOcZB+hHaQej/KYBJ3Npsy/gtMwnkCMIZrNziBR/ 6OHH2DmZ/k02tMdFGkcAuUFpnHQoRUr7xdh204lXbb6vvg7dnntZpW79Q3e2CZSZ Sbb3Q5AD2jQ+qO8A/78hExnpesH8vl9AjGNdM/XUlRwXmkj2SRsKd8RBg75GC8nr xyjCb3EmUAWJaQwDaaj4Wsqtu48D1QLDGfXjdjC2qvMCAwEAAaBVMFMGCSqGSIb3 DQEJDjFGMEQwQgYDVR0RBDswOYITeW91ci1uZXctZG9tYWluLmNvbYIXd3d3Lnlv dXItbmV3LWRvbWFpbi5jb22CCSouYmFyLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA iKYGNYylPp0qMdxYvS1tIlzGSLs8NA2H9vzohlBPaqU0yYrUh7YwDoDtWjkofBax fxJsZlO9wBCGNMaTwNxx3uvJ0mPhlQDJvBFcTeOaUwH7Fys2/DKI5JylXEnGbzzk pw4SqOblw+yGoossvpSWEaXvwX+XiLa3JpMWOT6E+qSqRUUKoJz8tHXBel1T0tL3 SSpSeTBELAkwXV/BWmY8HmsphKGGUKVvdIRrgR7YWMGEU3TR3VhTayc5EO1HpEB7 gZqaVwT29OnQYRfM9EbXRYnqX2guiM/KoouSoLy9NhyVawoOqfAaf6Ysl5JayNL9 QFkrH58zDK3hkOVni7NQ4g== -----END CERTIFICATE REQUEST----- ocaml-x509-0.16.5/tests/csr/wild-foo-cn.pem000066400000000000000000000015731445061461400201660ustar00rootroot00000000000000-----BEGIN CERTIFICATE REQUEST----- MIICWTCCAUECAQAwFDESMBAGA1UEAwwJKi5mb28uY29tMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEA1IoUG5fJRRxiYDxhZa5BPv7SWN9LDVD6DJ3F4cLx rbcXOooeCbbAIbBdmeVDa/kuHdFDb0ug69w+qRehi1NSJE2Q7JDAWg7hxWFnWKjB BD3Dlv6RJ90ClFUXhkJsoZbgOQaMAq4O6sC6YhGTw6L4QrkgZS+1xyERfQqa951q QHbXLFBsi/Ek/DGzphDuuSA7vbIwHKYQ4UXQTcPmCs+i/FxHd3bMkV0iHVD6xS6h la3k4YYi7Kr0QRbRxEvqGbVOqivPP4IFg3ZCItASLTbKGUFCgKvB9gspbFpc0eUH sr+NNoRuRq5mjaGmcHMLfY8KH2nxxKTQFh+cE6z30YQfHwIDAQABoAAwDQYJKoZI hvcNAQELBQADggEBAFHU22XEkexb31Wug07xi/QvNjDapeuhO+pzhSQ5lt3E2arU eQJqaMcl3Kzon93u8Hp5vcc48rBFe69xl/VTlwPTW4wt98MQKu7jgv2QDeH+Sq3+ b1wmMAslc+ORXlRFAk7U9bjHHMP6BN7l2C2ujBw6iK3OmiBfI4M3Si2PxCzVXReJ IMgUZOwa6BBmQ5D1a6njJiJCSMY2T0ttXU4e1/KxURYcvtzLxySxlbyvfwCtqNSY EMIiBxrfjIaLZ8CG4ybF9STqQP9B9s3NdiDJ7RQsXF1xlQrtXH88/YpW8Pf5u9O/ Ajf2IL7UZnriamhlAV3hofWiDJbqmh4n/9u14qs= -----END CERTIFICATE REQUEST----- ocaml-x509-0.16.5/tests/csr/your-new-domain-raw.pem000066400000000000000000000023411445061461400216630ustar00rootroot00000000000000-----BEGIN CERTIFICATE REQUEST----- MIIDYDCCAkgCAQAwgdAxCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhOZXcgWW9yazES MBAGA1UEBwwJUm9jaGVzdGVyMRIwEAYDVQQKDAlFbmQgUG9pbnQxFzAVBgNVBAsM DlRlc3RpbmcgRG9tYWluMUswSQYJKoZIhvcNAQkBFjx5b3VyLWFkbWluaXN0cmF0 aXZlLWFkZHJlc3NAeW91ci1hd2Vzb21lLWV4aXN0aW5nLWRvbWFpbi5jb20xIDAe BgNVBAMMF3d3dy55b3VyLW5ldy1kb21haW4uY29tMIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAzARXVEb2i5eR/bhyFrO34kQ4tdFK72j3hUMTRs2hdvUw LxKQPcRA+XeXdbJHiLXEJHHn0cd+7FQB1DPMCzEZY6eJGDi3iwaeZ/ybiHEcoNqH 5xV4QSNUaDfNzrSOnTRvhfg8Bn/YTCRaDhwxVZt0nU8p4ntrFieCyMD0Js70uFAM KAo4HWjd576jhL3fYROBWiwttP3JPJPzYjsvF7kgYeckfw88ORkrFxxxKaLZCtmr chDKZRQa6qu6Pd9KQFw2W+F9JzbYVTwiR2RmS9kqP7iajpNvKJTWVDM7Ixdw/lTd jOHYzoPFqbgVtjbNRwo1eNvqJbTcV/NCYJvj3s/KfQIDAQABoEowSAYJKoZIhvcN AQkOMTswOTA3BgNVHREEMDAughN5b3VyLW5ldy1kb21haW4uY29tghd3d3cueW91 ci1uZXctZG9tYWluLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAss2p+UK+ZygWtiKm HBKTqjRHwUKO485uNG2XBIQJzKOYjvRj2vA7qCi2Hb1Pr1ReWY29oqMXN1RdMrcb Ic+Wt4Jxipg8Pu5O/+cQNc49D8U2umpY99nO/DMkjKVAhbOOFwTqahcPfrKuTOpb UC7KzVcYi3HFoSdRRJ7Cf3bpxKIJjl2ju/8Tay4+zEYsJgdBEqTcMw4RhaD8T0vB h0n1Bt5cE6Meic2+gaz4sIhAiFH9oH4lJutcWoRxXEAwMorFk7DlzrGzc1XB2oqI KXczg1QAUmAGNq4gyQ1F3czq94XYtNGsUT644lS3Fh8hGIQUI7gYNAGY7Niba1YM KfAccQ== -----END CERTIFICATE REQUEST----- ocaml-x509-0.16.5/tests/csr/your-new-domain.pem000066400000000000000000000017611445061461400211010ustar00rootroot00000000000000-----BEGIN CERTIFICATE REQUEST----- MIICsTCCAZkCAQAwIjEgMB4GA1UEAwwXd3d3LnlvdXItbmV3LWRvbWFpbi5jb20w ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD55xIzpxhQ5Jgz7mc5kZzQ OiRRuOAx392yBlr0T36rYSpOObwmQtdNou4ireQXIQ27U/t4Kiw4n2xStCSOK2EP mxgC0JrlL7w7dRDfy4kChzzxoyRVR55VOejhR5XGLy67BchyMCI+pt/0cWCpECrK UorOgm5eHLDt0djtqaPtdqjwSiiPX/bK3+8vg8NwRvyBekC41znWoTwMNH1FDCHa /mOQT75c3gmIaUVYBD/yEM5EWEgpkQSSsIi6XynbeAZCeDodNJQt2c7z1iYPHw1Q wJqLBKrGsGfKlnfF0THf9hzndBEh+RSF1uvt5NbsPHMD5AZEClOwBoJ34IltR1wV AgMBAAGgSjBIBgkqhkiG9w0BCQ4xOzA5MDcGA1UdEQQwMC6CE3lvdXItbmV3LWRv bWFpbi5jb22CF3d3dy55b3VyLW5ldy1kb21haW4uY29tMA0GCSqGSIb3DQEBCwUA A4IBAQDBaQbBgdtWV2+Xzd6AvfnCl1lE8NNyZBNOmhL5yotJhPqKgByzHjCd1pBV guGd941hVNDqPbrKWbeUf1zgaX/oN2HbbedisH2ntocs4UWsAD2cDzh3P8aE3ixX JgjnqmMKwLQHupFVIFHOY/9UgFcc+fgvQkOGiJWpB1AYds/++Ucn5SmPEIbJmXBN 9+tL2vCH0Dd4rV22SfpENqKf1whFjJEDrrvwwlj9eQjkaqm7APi2ypiTiMDQvzr1 nDszGkTwXQCRto4NSNSexAWQhH00iI/jqssjVVhrwCTfJfEMP8BIf2+ONAWmAoxC ttuCrpcG94ErCLrrCHpMRiy5iLKO -----END CERTIFICATE REQUEST----- ocaml-x509-0.16.5/tests/dune000066400000000000000000000004211445061461400154230ustar00rootroot00000000000000(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)) ocaml-x509-0.16.5/tests/ocsp.ml000066400000000000000000000101561445061461400160510ustar00rootroot00000000000000open X509 (* How files for test1 were generated: key.pem: openssl genpkey -algorithm RSA -out key.pem -outform PEM certificate.pem: openssl req -new -x509 -days 3650 -key key.pem -out certificate.pem -subj '/CN=example.com/' -sha256 test1.pem: openssl req -new -key key.pem -nodes -out test1.csr \ -subj '/CN=test1.example.com/' openssl x509 -req -days 3650 -in test1.csr -CA certificate.pem \ -CAkey key.pem -set_serial 10000 -out test1.pem openssl x509 -in test1.pem -noout -text request.der: openssl ocsp -issuer certificate.pem \ -cert test1.pem \ -no_nonce -reqout request.der openssl ocsp -reqin request.der -text response.der: openssl ocsp -index index.txt -rsigner certificate.pem \ -rkey key.pem -CA certificate.pem \ -reqin request.der -respout response.der 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 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 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 | Error _ -> Alcotest.fail "could not decode OCSP request" | Ok request -> (* Fmt.pr "request=%a" pp request; *) (* TODO: verify *) match cert_ids request with | [certid] -> let serialNumber = OCSP.cert_id_serial certid in Alcotest.(check z_testable __LOC__ test1_serial serialNumber) | _ -> Alcotest.fail "something wrong with OCSP request" let test_response () = let open OCSP.Response in match decode_der (data "response.der") with | Error e -> Alcotest.failf "could not decode OCSP response: %a" Asn.pp_error e | Ok response -> (* Fmt.pr "response=%a" pp response; *) (match validate response (Private_key.public responder_key) with | Ok () -> () | Error _ -> Alcotest.fail "cannot verify the signature of OCSP response"); let responder = match responder_id response with | Ok (`ByName r) -> r | Ok _ -> Alcotest.fail "expected responder identifyed by name" | Error (`Msg e) -> Alcotest.fail e in let response = match responses response with | Ok [r] -> r | Ok _ -> Alcotest.fail "must be exactly one response" | Error (`Msg e) -> Alcotest.fail e 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 cert_dn_testable __LOC__ responder responder_dn) let test_simple_responder () = match OCSP.Request.decode_der (data "request.der") with | Error _ -> Alcotest.fail "could not decode OCSP request" | Ok request -> let certids = OCSP.Request.cert_ids request in let now = Ptime_clock.now () in let response_logic cert_id = let serial = OCSP.cert_id_serial cert_id in let cert_status = if Z.equal test1_serial serial then `Revoked (now, None) else `Good in OCSP.Response.create_single_response cert_id cert_status now in let responses = List.map response_logic certids in let responder_id = `ByName responder_dn in (* Fmt.pr "keytype = %a" Key_type.pp (Private_key.key_type responder_key); *) match OCSP.Response.create_success ~certs:[responder_cert] responder_key responder_id now responses with | Error (`Msg e) -> Alcotest.fail e | Ok resp -> match OCSP.Response.validate resp (Private_key.public responder_key) with | Ok () -> () | Error _ -> Alcotest.fail "cannot verify the signature of OCSP response" let tests = [ "OpenSSL request", `Quick, test_request ; "OpenSSL response", `Quick, test_response ; "Simple OCSP responder", `Quick, test_simple_responder ; ] ocaml-x509-0.16.5/tests/ocsp/000077500000000000000000000000001445061461400155145ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/ocsp/certificate.pem000066400000000000000000000014061445061461400205020ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICDDCCAW+gAwIBAgIIQcOa7kqxp9cwCgYIKoZIzj0EAwQwFjEUMBIGA1UEAwwL ZXhhbXBsZS5jb20wHhcNMjEwNDA0MTcwMTU3WhcNMjIwNDA0MTcwMTU3WjAWMRQw EgYDVQQDDAtleGFtcGxlLmNvbTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAXIK VyKRhKOJjxXQtKJiTX9nM3lZs6qy632NYmG9BwJ74FidW1NYlT0eiN71nMHU9FOH BZ76AH0ISrbo3hjG7uFzAPMplhTwTlA7IcQoR8FOGjrN0w+H5YJZRtkfYU0hFETU F4quomVmbrxtcIgFRWLJdf7qciYYJyYc8ZlTZoHpZY02o2QwYjAdBgNVHQ4EFgQU nku+GxZTewB6/D2bJFQcOkBN4QMwDwYDVR0PAQH/BAUDAwfGADAPBgNVHRMBAf8E BTADAQH/MB8GA1UdIwQYMBaAFJ5LvhsWU3sAevw9myRUHDpATeEDMAoGCCqGSM49 BAMEA4GKADCBhgJBfZBX4o5Df/fJUnzmQKo6KFFWlc70VkO3hXH6lUhVRLcT+Ame 6gJUjgYy65GryW4Tx/pFTI7tdX19UDm+kBvgv1sCQRIgxgt/eJ74VsRgt7Br3Smm px1uULyS4PIGBKT4O4C4bWS1wdzw8ZOlegss1+pkxYYrfJFNJYyBaqY0ScTpvE4F -----END CERTIFICATE----- ---- ocaml-x509-0.16.5/tests/ocsp/index.txt000066400000000000000000000000651445061461400173650ustar00rootroot00000000000000V 260517090452Z 2710 unknown /CN=test1.example.com/ ocaml-x509-0.16.5/tests/ocsp/key.pem000066400000000000000000000002751445061461400170130ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MGACAQAwEAYHKoZIzj0CAQYFK4EEACMESTBHAgEBBEIAtmFgIVel9k9Ivp7S5Mlc adxdv3KvDHc1j787n4avTUpzk+Aj7g0zxen7UsBOk2q/EGbZbtVFsO4zdOvPqP1+ m94= -----END PRIVATE KEY----- ocaml-x509-0.16.5/tests/ocsp/request.der000066400000000000000000000001051445061461400176740ustar00rootroot000000000000000C0A0?0=0;0 +ïøåcós— ,?⡨GÚ­bžK¾S{zü=›$T:@Má'ocaml-x509-0.16.5/tests/ocsp/response.der000066400000000000000000000015251445061461400200510ustar00rootroot000000000000000‚Q  ‚J0‚F +0‚70‚30¡010U example.com20210519144910Z0R0P0;0 +ïøåcós— ,?⡨GÚ­bžK¾S{zü=›$T:@Má'€20210519144910Z0 *†HÎ=‹0‡Bê¦üËú×?ì71'Š$±2vÆ•oå…2Ûž!z93ñ¸n$œn£ ôN”×ïpJ6™;“! ÅáKÙáh,lˆëéA3Á6B-oaN«Ú“m衤º·œÚýܧ?˽—ï}¹ÜI¦¿„P}cc M[ °ÎV|¤3x*q…F ‚0‚0‚ 0‚o AÚîJ±§×0 *†HÎ=010U example.com0 210404170157Z 220404170157Z010U example.com0›0*†HÎ=+#†r W"‘„£‰д¢bMg3yY³ª²ë}ba½{àX[SX•=ˆÞõœÁÔôS‡žú}J¶èÞÆîásó)–ðNP;!Ä(GÁN:ÍÓ‡å‚YFÙaM!DÔŠ®¢efn¼mpˆEbÉuþêr&'&ñ™Sfée6£d0b0UžK¾S{zü=›$T:@Má0UÿÆ0Uÿ0ÿ0U#0€žK¾S{zü=›$T:@Má0 *†HÎ=Š0†A}WâŽC÷ÉR|æ@ª:(QV•ÎôVC·…qú•HUD·ø žêTŽ2ë‘«ÉnÇúELŽíu}}P9¾à¿[A Æ xžøVÄ`·°kÝ)¦§nP¼’àò¤ø;€¸mdµÁÜðñ“¥z ,×êdņ+|‘M%Œj¦4IÄé¼Nocaml-x509-0.16.5/tests/ocsp/test1.pem000066400000000000000000000011631445061461400172600ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIBozCCAQQCAicQMAoGCCqGSM49BAMCMBYxFDASBgNVBAMMC2V4YW1wbGUuY29t MB4XDTIxMDUxOTE0NDIxMFoXDTMxMDUxNzE0NDIxMFowHDEaMBgGA1UEAwwRdGVz dDEuZXhhbXBsZS5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAFyClcikYSj iY8V0LSiYk1/ZzN5WbOqsut9jWJhvQcCe+BYnVtTWJU9Hoje9ZzB1PRThwWe+gB9 CEq26N4Yxu7hcwDzKZYU8E5QOyHEKEfBTho6zdMPh+WCWUbZH2FNIRRE1BeKrqJl Zm68bXCIBUViyXX+6nImGCcmHPGZU2aB6WWNNjAKBggqhkjOPQQDAgOBjAAwgYgC QgCAu0cwvmP9SIfsbv17zFpoEPvBRc6UH4La7iVmq/un8N5qcBnTNsY3CNzXkT68 P9XQhBzqZOvUIkjw0UgVPk8uvwJCAWXwCHa3nw0C/4qrlm3IIRjWAwygXojPHOxu Y+XLaPIpLLja2BzfP4uHWlyJAvZW/1SiMuFFv19ICbGmnRQdQyDY -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/pkcs12.ml000066400000000000000000000033351445061461400162110ustar00rootroot00000000000000open X509 let cs_mmap file = Unix_cstruct.of_fd Unix.(openfile file [O_RDONLY] 0) let data file = cs_mmap ("./pkcs12/" ^ file) let cert = match Certificate.decode_pem (data "certificate.pem") with | Ok c -> c | Error _ -> assert false let key = match Private_key.decode_pem (data "key.pem") with | Ok k -> k | Error _ -> assert false let pass = "1234" let cert_and_key xs = match xs with | [ `Certificate c ; `Decrypted_private_key k ] -> Alcotest.(check bool __LOC__ true (c = cert && k = key)) | _ -> Alcotest.fail "expected certificate and key" let openssl1 () = match PKCS12.decode_der (data "ossl.p12") with | Error _ -> Alcotest.fail "failed to decode ossl.p12" | Ok data -> match PKCS12.verify pass data with | Ok xs -> cert_and_key xs | Error _ -> Alcotest.fail "failed to verify ossl.p12" let openssl2 () = match PKCS12.decode_der (data "ossl_aes.p12") with | Error _ -> Alcotest.fail "failed to decode ossl_aes.p12" | Ok data -> match PKCS12.verify pass data with | Ok xs -> cert_and_key xs | Error _ -> Alcotest.fail "failed to verify ossl_aes.p12" let ours () = match PKCS12.decode_der (data "ours.p12") with | Error _ -> Alcotest.fail "failed to decode ours.p12" | Ok data -> match PKCS12.verify pass data with | Ok xs -> cert_and_key xs | Error _ -> Alcotest.fail "failed to verify ours.p12" let roundtrip () = let p12 = PKCS12.create pass [ cert ] key in match PKCS12.verify pass p12 with | Ok xs -> cert_and_key xs | Error _ -> Alcotest.fail "failed roundtrip" let tests = [ "OpenSSL basic", `Quick, openssl1 ; "OpenSSL AES 256", `Quick, openssl2 ; "OCaml-X509 AES 256", `Quick, ours ; "OCaml-X509 create and verify", `Quick, roundtrip ; ] ocaml-x509-0.16.5/tests/pkcs12/000077500000000000000000000000001445061461400156535ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/pkcs12/certificate.pem000066400000000000000000000014061445061461400206410ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICDDCCAW+gAwIBAgIIQcOa7kqxp9cwCgYIKoZIzj0EAwQwFjEUMBIGA1UEAwwL ZXhhbXBsZS5jb20wHhcNMjEwNDA0MTcwMTU3WhcNMjIwNDA0MTcwMTU3WjAWMRQw EgYDVQQDDAtleGFtcGxlLmNvbTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAXIK VyKRhKOJjxXQtKJiTX9nM3lZs6qy632NYmG9BwJ74FidW1NYlT0eiN71nMHU9FOH BZ76AH0ISrbo3hjG7uFzAPMplhTwTlA7IcQoR8FOGjrN0w+H5YJZRtkfYU0hFETU F4quomVmbrxtcIgFRWLJdf7qciYYJyYc8ZlTZoHpZY02o2QwYjAdBgNVHQ4EFgQU nku+GxZTewB6/D2bJFQcOkBN4QMwDwYDVR0PAQH/BAUDAwfGADAPBgNVHRMBAf8E BTADAQH/MB8GA1UdIwQYMBaAFJ5LvhsWU3sAevw9myRUHDpATeEDMAoGCCqGSM49 BAMEA4GKADCBhgJBfZBX4o5Df/fJUnzmQKo6KFFWlc70VkO3hXH6lUhVRLcT+Ame 6gJUjgYy65GryW4Tx/pFTI7tdX19UDm+kBvgv1sCQRIgxgt/eJ74VsRgt7Br3Smm px1uULyS4PIGBKT4O4C4bWS1wdzw8ZOlegss1+pkxYYrfJFNJYyBaqY0ScTpvE4F -----END CERTIFICATE----- ---- ocaml-x509-0.16.5/tests/pkcs12/key.pem000066400000000000000000000002751445061461400171520ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MGACAQAwEAYHKoZIzj0CAQYFK4EEACMESTBHAgEBBEIAtmFgIVel9k9Ivp7S5Mlc adxdv3KvDHc1j787n4avTUpzk+Aj7g0zxen7UsBOk2q/EGbZbtVFsO4zdOvPqP1+ m94= -----END PRIVATE KEY----- ocaml-x509-0.16.5/tests/pkcs12/ossl.p12000066400000000000000000000017541445061461400171660ustar00rootroot000000000000000‚è0‚® *†H†÷  ‚Ÿ‚›0‚—0‚· *†H†÷  ‚¨0‚¤0‚ *†H†÷ 0 *†H†÷  06‘óCƒ¯³€‚p¬h¡úÊÐÝ/Œí‰¡cW¹êÎ^EJº»%5do¬*€ßk.‘PÙîa@ÌjŸÛÝUD™›¼Ù4nÝe©cØš§óp; sVá¸)jŸpÔ!Ð µÉiw˯þ ¯1Úº4eq¿Ø‹¦•ë•ȆÏÔüÐ5co2›÷öïéÿ‚3òšî‘¼ˆÝ®Vx³`QÅKÿa)—Æ"‘ƒ|áû.Ž@S€ñN`À.&ýoBùeN'ÿ V„ßGÜ啸W(ÖUÌf†öêx˘ø÷ªç…6¸9õ›¹ÿÚ{mÇf: <’œc‘_Ü€àRZ@M±Ä÷ˆzi r7ytÉ7†æ_5áÕªHà((¬‹¸µÕŸ~E&_SŽbÈ%_Œ O¥?eŸ5Ĭ ™CØï‘Pò¹8 ßAÍ€P㟩s“9/ÉÙ•«q>;£{,¼@¹²h^ÅôhÄ1 ‹Ô&>ækh\ü~ 5QØÃ`é“0þÒÄ|¬ºÄ¤tV»ð(Ês§sOíÝuX8bͬǀ¸Z,#`SÁ"ÂßtŽÊ =êo¤#MF4@‹‰¢¸í—¨w…‘ž f½jKsÁ/ífóÄØ‚ºìéž/Ͼ=Л®½‰L“hÔâ~Ô2†ºÌÛe基(ÅÙÊ—æÙòh»Nu/DX¦›³ËKÉuCfzº²a—Ão¸!EÐŒfqîèØm§·œeb½¡…ðFhÉÖþ¶—wÍðˆ¦IqFo†© âsOŒ;õ|.K`‹7+ú .¹¢‘ã6­€›î\Xj7÷Iªx˜þ(A¯˜S8\|io©Ÿõ, »0Ù *†H†÷  ËÈ0Å0 *†H†÷   ‹0ˆ0 *†H†÷  0¶›Zqò]Ïh2¸ ‹'4d[ªÙÕ“å×ìkÁd°>U£®¢+ mœn©3Ôx‘Ù]»Ã\H’Æ8ç¢/‡ÑcÉÐþ¶eÌχо#ûÎfû º ÁÍÝEìýµî>n8‘Ö?¾ ‚ÇïeÜP­Éá1%0# *†H†÷  1>— ÷kB\/ ¸g×,Ç‘010!0 +ý`ry{“Ï`j¸qÞcŽ`ýæáÅØ=¾•–3\\ocaml-x509-0.16.5/tests/pkcs12/ossl_aes.p12000066400000000000000000000022371445061461400200130ustar00rootroot000000000000000‚›0‚1 *†H†÷  ‚"‚0‚0‚ò *†H†÷  ‚ã0‚ß0‚Ø *†H†÷ 0W *†H†÷  0J0) *†H†÷  0çKa*B!ÂM0 *†H†÷  0 `†He*ô,÷tu“ h Y M€‚p›MU3‰üFG:`Æ÷û¦÷@\T…{O¼VEÂ`›;NùN¸@øÙ3~~`§íʤ!V©BC!„nÔÑlÑðKÒ¤ŠÍ&µL~:õ°îí.ˆQ,æ$å¦A„wÔj¶ødC_×ñ÷(÷|¼ï§¯z¿4Ó’´ŠG¥Ww}QàB«ôH£…ª‡·ÓrêÚ±ªé³M¶O`FTeZý†ðñ” 1¬]U+üèí”wı>´  ¼Ž¯¨J %ìö﹋.?é9‡Ë-ƒ’|6K%1hµ"r þéþ<éÏþÕ7ÝÒg`txAwŒr#8ôëwÚ`Ž9Z®0 Ò|oïÀboÐa1ií/Dwi—oí¼¤*ç.G¸P uK„FSÚ9ñækâûJ‡IÚ¾»f¸#Z´ÜÒ|òCe´©ÌMšÀ}ã19»¬é¤ÝÊ2ÜûlÎ\R–ÙSÌ+A0OãÁåèâáæSeÕP„b¶¸é¾qiÂfzÈ:®Ô„êwÉ ‘WL*]±*ñH³(7#B3¥hJûJ„Ò¡‚"oB×»LýÊt²(<6ú±ê¾½«CQîBU“?N«´™>~è¸.Fçt¾n´ù‡»öc“§¾ˆdª´/£c[c·a-8%™ûãù'`”?6,VÑßbz}W" ŒÝßíÄ{0xƒ’+³«NVƒ=¸ÊŸ¬P‡¦&nõÈf,8ˆ¢þE.¯ ¹·’Épu}eË6ø.Ö¡] BuB#ª£~d†ÂegÓQ»ûôæ -±¹E!‚ÜF°)§Ã•ËnØÃÞ0‚  *†H†÷  ‚‚ 0‚ 0‚ *†H†÷   Î0Ë0W *†H†÷  0J0) *†H†÷  0’Újƒ€¯0 *†H†÷  0 `†He*õÂІCÈΣ‡TܯWvp5CÄã ÞŽY÷WO¸¿µâ®kÏ­Ïy·çƒG‡ì¡ÀÓkFrúJËW£qý3•øa=}°¦ÛÚ?ÁõCç¿’ƒ€v΄Ÿ‹²Û^œɈjØcïf»­¼6ªÜ3Ò¤ážr¬1%0# *†H†÷  1>— ÷kB\/ ¸g×,Ç‘0a0Q0  `†He@è«DTý¸M:ÍoØ¥=1dCÚH‘ *,yIoi×ymV£ç–l€§8êáû_œ0yHBª7B68|: ÍaêåÄø M" ÏZ¥c¦í vrïÚ»Û£»\`Pï7HÜÀ&XÛ+yƒ¢âvç2„€›8yÑŠîv .¯ÅŒÍ—­>ëËf§w/wy±)oŠŒÕÜ•{E¬Ã9ng¯- ø_,P?â•R(ù#™XÂBTVdÀã0a½¡µ-WVmziA¤»ûD/¦Ür›¡Úw1šþü³l§c‡šæ?Õê“âÖD8/Ór…=DO›Õ äw×t†Ô‰l+xGOh(·ÐI¶kœ¹UgOfä{‘DiûUŽéÎÅðk縪ˆ»Ã?U§Ô5¸9ð)1}æ¾cN²> ’ž!ýgþmïÚ‘Œ}üQKÙB/¡¶ój†/G¦·{Q™€§ôö˜Cœ¦á½Ÿ’€­T Ìj_‹P\²àÕ3B×<ˆƒYµ-yí¸Ùj›oþPã[+;¤º.9É}ÔΞ»˜·D|– 36ûŠ Ëo}‘*W„ð¥L{ .ÍÞ»¯@Nzt€x¥ÚB~ü7‹¤Ž·hΞj¨9¨­¹-}£Š&³,a¢}ÿßÙ :¾ø÷©V0¯ÐõOm¥TÀ×µÖ´¡L¯ÅRÀ’²pøCTu“Žd?é‰Ñ'’?™dî½Çl¾.lyže;GH±ÄZ‚ŽÝ;¯¶šüª|0‚  *†H†÷  ÿü0ù0ö *†H†÷   æ0ã0o *†H†÷  0b0A *†H†÷  04 ÷ú-.(´?xÚ(¢*åÏw õðD•-;c`¤®±0 *†H†÷  0 `†He*TR%SBEïBÒJ›ÎkhpðáTÔ\jv^c I9­Ð“âúŽ”Tnë‰tÅרx©T­1yø¼Ø vvGôàúw{ýÚ¯™ÉS˜?Moy¼Û52Z çôÁUœãÀžËŽ_%ÍW—˜nh‘BS[yZ©-ñ*Øãƒ¬á+çÔx0Y010  `†He äD¥£KKQÈÝ»)–a@b„SbËçÈÍ4 ¢ÇØZƒ (ú$?=ž:áγcÐ"uú¥ÎäÂȳM|ã+- 3ocaml-x509-0.16.5/tests/priv.ml000066400000000000000000000036461445061461400160730ustar00rootroot00000000000000open 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)) let generate_rsa () = let seed = "Test1234" in let pk = Private_key.generate ~seed:(Cstruct.of_string 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')); Alcotest.(check bool "generate and of_string ~seed" true (pk_equal pk pk'')); match Private_key.of_string ~seed_or_data:`Data `RSA seed with | Error _ -> () | Ok _ -> Alcotest.fail "expected failure (of_string `Data `RSA)" let b64_dec s = Base64.decode_exn s |> Cstruct.of_string 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_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')); Alcotest.(check bool "generate and of_string ~data" true (pk_equal pk pk'')); match Private_key.of_string ~seed_or_data:`Seed key_type data with | Error _ -> Alcotest.fail "expected ok (of_string `Seed)" | Ok pk''' -> Alcotest.(check bool "generate and of_String ~seed" false (pk_equal pk pk''')) let ec_data = [ `ED25519, "W0p4c4tBHtSaTj4zij4oARCjhFbIi8voYg+65bl7wLU=" ; `P224, "Wjy6Nf4/xJSaaR/eeoQBUxJMA3PDP/c+8VkuPA==" ; `P256, "arvDmHpdTdzbc0uo+KCXoArmrmAs2GAvfk14D8gi6gM=" ; `P384, "UEZz/xVx2f3s7W8/cFy/w38LkjAq0xfMYJiXamdwgW9zwSK18+vrhKzgE23sFnyq" ; `P521, "AVb4DIpMO5hzyfX1n4qi4xtj/JBDCTCwyOLasKnnVS6FHW2hEZbGwd1c2J4rwpNKZqTKNsKu3dVJAmlp3EFhqv5T" ; ] let tests = ("Generate RSA", `Quick, generate_rsa) :: List.map (fun d -> Key_type.to_string (fst d), `Quick, test_ec d) ec_data ocaml-x509-0.16.5/tests/regression.ml000066400000000000000000000352251445061461400172710ustar00rootroot00000000000000open X509 let cs_mmap file = Unix_cstruct.of_fd Unix.(openfile file [O_RDONLY] 0) let regression file = cs_mmap ("./regression/" ^ file ^ ".pem") let cert file = match Certificate.decode_pem (regression file) with | Ok cert -> cert | Error (`Msg m) -> Alcotest.failf "certificate %s decoding error %s" file m let jc = cert "jabber.ccc.de" let cacert = cert "cacert" let time () = None let host str = Some (Domain_name.host_exn (Domain_name.of_string_exn str)) let test_jc_jc () = match Validation.verify_chain_of_trust ~host:(host "jabber.ccc.de") ~time ~anchors:[jc] [jc] with | Error `InvalidChain -> () | Error e -> Alcotest.failf "something went wrong with jc_jc (expected invalid_chain, got %a" Validation.pp_validation_error e | Ok _ -> Alcotest.fail "chain validated when it shouldn't" let test_jc_ca_fail () = match Validation.verify_chain_of_trust ~host:(host "jabber.ccc.de") ~time ~anchors:[cacert] [jc ; cacert] with | Error `InvalidChain -> () | _ -> Alcotest.fail "something went wrong with jc_ca" let test_jc_ca_all_hashes () = match Validation.verify_chain_of_trust ~allowed_hashes:[`SHA1] ~host:(host "jabber.ccc.de") ~time ~anchors:[cacert] [jc ; cacert] with | Ok _ -> () | _ -> Alcotest.fail "something went wrong with jc_ca" let telesec = cert "telesec" let jfd = [ cert "jabber.fu-berlin.de" ; cert "fu-berlin" ; cert "dfn" ] let test_jfd_ca () = match Validation.verify_chain_of_trust ~host:(host "jabber.fu-berlin.de") ~time ~anchors:[telesec] (jfd@[telesec]) with | Ok _ -> () | _ -> Alcotest.fail "something went wrong with jfd_ca" let test_jfd_ca' () = match Validation.verify_chain_of_trust ~host:(host "jabber.fu-berlin.de") ~time ~anchors:[telesec] jfd with | Ok _ -> () | _ -> Alcotest.fail "something went wrong with jfd_ca'" let test_izenpe () = let crt = cert "izenpe" in let _, san = Extension.(get Subject_alt_name (Certificate.extensions crt)) in Alcotest.(check int "two SAN (mail + dir)" 2 (General_name.cardinal san)); Alcotest.(check (list string) "mail in SAN is correct" [ "info@izenpe.com" ] General_name.(get Rfc_822 san)); let dir = General_name.(get Directory san) in Alcotest.(check int "directory san len is 1" 1 (List.length dir)); let data = Fmt.to_to_string Distinguished_name.pp (List.hd dir) in let expected = "/O=IZENPE S.A. - CIF A01337260-RMerc.Vitoria-Gasteiz T1055 F62 S8/Street=Avda del Mediterraneo Etorbidea 14 - 01010 Vitoria-Gasteiz" in Alcotest.(check string "directory in SAN is correct" expected data) let test_name_constraints () = ignore (cert "name-constraints") let check_dn = (module Distinguished_name: Alcotest.TESTABLE with type t = Distinguished_name.t) let test_distinguished_name () = let open Distinguished_name in let crt = cert "PostaCARoot" in let expected = [ Relative_distinguished_name.singleton (DC "rs") ; Relative_distinguished_name.singleton (DC "posta") ; Relative_distinguished_name.singleton (DC "ca") ; Relative_distinguished_name.singleton (CN "Configuration") ; Relative_distinguished_name.singleton (CN "Services") ; Relative_distinguished_name.singleton (CN "Public Key Services") ; Relative_distinguished_name.singleton (CN "AIA") ; Relative_distinguished_name.singleton (CN "Posta CA Root") ] in Alcotest.(check check_dn "complex issuer is good" expected (Certificate.issuer crt)) ; Alcotest.(check check_dn "complex subject is good" expected (Certificate.subject crt)) let test_distinguished_name_pp () = let module Dn = struct include Distinguished_name let cn s = Relative_distinguished_name.singleton (CN s) let o s = Relative_distinguished_name.singleton (O s) let initials s = Relative_distinguished_name.singleton (Initials s) let (+) = Relative_distinguished_name.union end in let dn1 = "DN1", Dn.[o "Blanc"; cn "John Doe" + initials "J.D." + initials "N.N."] in let dn2 = "DN2", Dn.[o " Escapist"; cn "# 2"; cn " \"+,;/<>\\ "] in let pp1 = "RFC4514", Fmt.hbox (Dn.make_pp ~format:`RFC4514 ()) in let pp2 = "RFC4514-spacy", Fmt.hbox (Dn.make_pp ~format:`RFC4514 ~spacing:`Loose ()) in let pp3 = "OpenSSL", Fmt.hbox (Dn.make_pp ~format:`OpenSSL ()) in let pp4 = "OSF", Fmt.hbox (Dn.make_pp ~format:`OSF ()) in let pp5 = "RFC4514-vbox", Fmt.vbox (Dn.make_pp ~format:`RFC4514 ()) in let check (pp_desc, pp) (dn_desc, dn) expected = Alcotest.(check string) (Printf.sprintf "%s %s" pp_desc dn_desc) expected (Fmt.to_to_string pp dn) in check pp1 dn1 {|CN=John Doe+Initials=J.D.+Initials=N.N.,O=Blanc|} ; check pp1 dn2 {|CN=\ \"\+\,\;/\<\>\\ \ ,CN=\# 2,O=\ Escapist|} ; check pp2 dn1 {|CN = John Doe + Initials = J.D. + Initials = N.N., O = Blanc|} ; check pp2 dn2 {|CN = \ \"\+\,\;/\<\>\\ \ , CN = \# 2, O = \ Escapist|} ; check pp3 dn1 {|O = Blanc, CN = John Doe + Initials = J.D. + Initials = N.N.|} ; check pp3 dn2 {|O = \ Escapist, CN = \# 2, CN = \ \"\+\,\;/\<\>\\ \ |} ; check pp4 dn1 {|/O=Blanc/CN=John Doe+Initials=J.D.+Initials=N.N.|} ; check pp4 dn2 {|/O=\ Escapist/CN=\# 2/CN=\ \"\+,;\/\<\>\\ \ |} ; check pp5 dn1 "CN=John Doe+\nInitials=J.D.+\nInitials=N.N.,\nO=Blanc" let test_yubico () = ignore (cert "yubico") let test_frac_s () = let file = "until_frac_s" in match Certificate.decode_pem (regression file) with | Ok _ -> Alcotest.failf "certificate %s, expected decoding error" file | Error (`Msg _) -> () let decode_valid_pem file = let data = regression file in match Private_key.decode_pem data with | Ok _ -> () | Error (`Msg _) -> Alcotest.failf "private key %s failed to be verified" file let test_gcloud_key () = (* discussion in https://github.com/mirage/mirage-crypto/issues/62 *) let file = "gcloud" in decode_valid_pem file let test_openssl_2048_key () = (* this key has a d > lcm (p - 1) (q - 1) *) let file = "openssl_2048" in decode_valid_pem file let ed25519_priv = Cstruct.of_hex "D4EE72DBF913584AD5B6D8F1F769F8AD3AFE7C28CBF1D4FBE097A88F44755842" let ed25519_priv_key () = let data = {|-----BEGIN PRIVATE KEY----- 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) -> let encoded = Private_key.encode_pem ke in if not (String.equal (Cstruct.to_string 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" let ed25519_pub_key () = let data = {|-----BEGIN PUBLIC KEY----- MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE= -----END PUBLIC KEY----- |} and pub = match Mirage_crypto_ec.Ed25519.priv_of_cstruct 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 encoded = Public_key.encode_pem (`ED25519 k) in if not (String.equal (Cstruct.to_string encoded) data) then Alcotest.failf "ED25519 public key encoding failure" | _ -> Alcotest.failf "bad ED25519 public key" let p384_key () = let priv_data = {|-----BEGIN PRIVATE KEY----- MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDzBTbwp91ON4CNuDE+ pjKsehNV7I3eTpyKpMlSUqHAguO8hK+t28A/730TP2L0rPyhZANiAATZbEoUICtu yXyN4G6DDHaUHwwe2bfcsTvY9LnlLCPvu24JTuGjf7pT2faiuvjGb49jk8C2KJWt 0DISTEJ945y41DY0cIPl1okaN+E3yJ66kKpJ0XeKoOJ0rTTopazzjzI= -----END PRIVATE KEY----- |} and pub_data = {|-----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE2WxKFCArbsl8jeBugwx2lB8MHtm33LE7 2PS55Swj77tuCU7ho3+6U9n2orr4xm+PY5PAtiiVrdAyEkxCfeOcuNQ2NHCD5daJ GjfhN8ieupCqSdF3iqDidK006KWs848y -----END PUBLIC KEY----- |} in match Private_key.decode_pem (Cstruct.of_string priv_data), Public_key.decode_pem (Cstruct.of_string pub_data) with | Ok (`P384 priv), Ok (`P384 pub) -> let to_cs = Mirage_crypto_ec.P384.Dsa.pub_to_cstruct 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'))); let pub_data' = Public_key.encode_pem (`P384 pub) in Alcotest.(check bool __LOC__ true (Cstruct.equal (Cstruct.of_string 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'))) | _ -> Alcotest.failf "cannot decode re-encoded P384 private key" end | _ -> Alcotest.failf "bad P384 key" let ed25519_cert () = let file = "example-25519" in match Certificate.decode_pem (regression file) with | Error (`Msg msg) -> Alcotest.failf "ED25519 certificate %s, decoding error %s" file msg | Ok cert -> match Validation.valid_ca cert with | Error e -> Alcotest.failf "verifying 25519 ca certificate failed %a" Validation.pp_ca_error e | Ok () -> match Validation.verify_chain ~host:(host "www.example.com") ~time ~anchors:[cert] [cert] with | Ok _ -> () | Error e -> Alcotest.failf "verifying 25519 certificate failed %a" Validation.pp_chain_error e let le_p384_root () = let file = "letsencrypt-root-x2" in match Certificate.decode_pem (regression file) with | Error (`Msg msg) -> Alcotest.failf "let's encrypt P384 certificate %s, decoding error %s" file msg | Ok cert -> match Validation.valid_ca cert with | Error e -> Alcotest.failf "verifying P384 ca certificate failed %a" Validation.pp_ca_error e | Ok () -> () let p256_key () = let file = "priv_p256" in match Private_key.decode_pem (regression file) with | Error (`Msg msg) -> Alcotest.failf "private P256 key %s decoding error %s" file msg | Ok _ -> () let ip_address () = let c = cert "1.1.1.1" in let ta = cert "digicert" in match Validation.verify_chain ~ip:(Ipaddr.of_string_exn "1.1.1.1") ~host:None ~time:(fun () -> None) ~anchors:[ta] [c] with | Ok _ -> () | Error ce -> Alcotest.failf "validation of IP address failed: %a" Validation.pp_chain_error ce let p256_sha384 () = let file = "p256_sha384" in match Certificate.decode_pem (regression file) with | Error (`Msg msg) -> Alcotest.failf "P256 certificate with SHA384 %s, decoding error %s" file msg | Ok cert -> match Validation.valid_ca cert with | Error e -> Alcotest.failf "verifying P256 certificate failed %a" Validation.pp_ca_error e | Ok () -> () let regression_tests = [ "RSA: key too small (jc_jc)", `Quick, test_jc_jc ; "jc_ca", `Quick, test_jc_ca_fail ; "jc_ca", `Quick, test_jc_ca_all_hashes ; "jfd_ca", `Quick, test_jfd_ca ; "jfd_ca'", `Quick, test_jfd_ca' ; "SAN dir explicit or implicit", `Quick, test_izenpe ; "name constraint parsing (DNS: .gr)", `Quick, test_name_constraints ; "complex distinguished name", `Quick, test_distinguished_name ; "distinguished name pp", `Quick, test_distinguished_name_pp ; "algorithm without null", `Quick, test_yubico ; "valid until generalized_time with fractional seconds", `Quick, test_frac_s ; "parse valid key where 1 <> d * e mod (p - 1) * (q - 1)", `Quick, test_gcloud_key ; "parse valid key where d <> e ^ -1 mod lcm ((p - 1) (q - 1))", `Quick, test_openssl_2048_key ; "ed25519 private key", `Quick, ed25519_priv_key ; "ed25519 public key", `Quick, ed25519_pub_key ; "p384 key", `Quick, p384_key ; "ed25519 certificate", `Quick, ed25519_cert ; "p384 certificate", `Quick, le_p384_root ; "p256 key", `Quick, p256_key ; "ip_address", `Quick, ip_address ; "p256 with sha384", `Quick, p256_sha384 ; ] let host_set_test = let module M = struct type t = Host.Set.t let pp ppf hs = let pp_one ppf (typ, name) = Fmt.pf ppf "%s%a" (match typ with `Strict -> "" | `Wildcard -> "*.") Domain_name.pp name in Fmt.(list ~sep:(any ", ") pp_one) ppf (Host.Set.elements hs) let equal = Host.Set.equal end in (module M: Alcotest.TESTABLE with type t = M.t) 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 match Signing_request.decode_pem data with | Ok csr -> csr | Error (`Msg m) -> Alcotest.failf "signing request %s decoding error %s" file m let csr_hostnames cert names () = Alcotest.check host_set_test __LOC__ (Signing_request.hostnames cert) names let host_set xs = Host.Set.of_list (List.map (fun n -> `Strict, Domain_name.(host_exn (of_string_exn n))) xs) let hostname_tests = [ "cacert hostnames", `Quick, cert_hostnames cacert Host.Set.empty; "izenpe hostnames", `Quick, cert_hostnames (cert "izenpe") (host_set ["izenpe.com"]); "jabber.ccc.de hostnames", `Quick, cert_hostnames jc (host_set [ "jabber.ccc.de" ; "conference.jabber.ccc.de" ; "jabberd.jabber.ccc.de" ; "pubsub.jabber.ccc.de" ; "vjud.jabber.ccc.de" ]); "jaber.fu-berlin.de hostnames", `Quick, cert_hostnames (cert "jabber.fu-berlin.de") (host_set [ "jabber.fu-berlin.de" ; "conference.jabber.fu-berlin.de" ; "proxy.jabber.fu-berlin.de" ; "echo.jabber.fu-berlin.de" ; "file.jabber.fu-berlin.de" ; "jitsi-videobridge.jabber.fu-berlin.de" ; "multicast.jabber.fu-berlin.de" ; "pubsub.jabber.fu-berlin.de" ]); "pads.ccc.de hostnames", `Quick, cert_hostnames (cert "pads.ccc.de") (Host.Set.add (`Wildcard, Domain_name.(host_exn (of_string_exn "pads.ccc.de"))) (host_set ["pads.ccc.de"])); "first hostnames", `Quick, cert_hostnames (cert "../testcertificates/first/first") (host_set ["foo.foobar.com"; "foobar.com"]); "CSR your_new_domain hostnames", `Quick, csr_hostnames (csr "your-new-domain") (host_set ["your-new-domain.com" ; "www.your-new-domain.com"]); "CSR your_new_domain_raw hostnames", `Quick, csr_hostnames (csr "your-new-domain-raw") (host_set ["your-new-domain.com" ; "www.your-new-domain.com"]); "CSR bar.com hostnames", `Quick, csr_hostnames (csr "wild-bar") (Host.Set.add (`Wildcard, Domain_name.(host_exn (of_string_exn "bar.com"))) (host_set ["your-new-domain.com" ; "www.your-new-domain.com"])); "CSR foo.com hostnames", `Quick, csr_hostnames (csr "wild-foo-cn") (Host.Set.singleton (`Wildcard, Domain_name.(host_exn (of_string_exn "foo.com")))); ] ocaml-x509-0.16.5/tests/regression/000077500000000000000000000000001445061461400167305ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/regression/1.1.1.1.pem000066400000000000000000000036701445061461400202360ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIFhjCCBQ2gAwIBAgIQBQdvZtEbaSJWzKzVRv/sUzAKBggqhkjOPQQDAzBWMQsw CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMTAwLgYDVQQDEydEaWdp Q2VydCBUTFMgSHlicmlkIEVDQyBTSEEzODQgMjAyMCBDQTEwHhcNMjEwMTExMDAw MDAwWhcNMjIwMTE4MjM1OTU5WjByMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs aWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRm bGFyZSwgSW5jLjEbMBkGA1UEAxMSY2xvdWRmbGFyZS1kbnMuY29tMFkwEwYHKoZI zj0CAQYIKoZIzj0DAQcDQgAEF60f6DWvcNONnJ5k/UceW5cMCtEQqCYyETZmTRKZ w+Exu/UhY3PdpcHBoPBtpMRe4cLb2vkNNIAa97ngOvLVdKOCA58wggObMB8GA1Ud IwQYMBaAFAq8CCkXjKU5bXoOzjPHLrPt+8N6MB0GA1UdDgQWBBThtvwG+bmLBfTB 4kibArkLwbU9eTCBpgYDVR0RBIGeMIGbghJjbG91ZGZsYXJlLWRucy5jb22CFCou Y2xvdWRmbGFyZS1kbnMuY29tgg9vbmUub25lLm9uZS5vbmWHBAEBAQGHBAEAAAGH BKKfJAGHBKKfLgGHECYGRwBHAAAAAAAAAAAAERGHECYGRwBHAAAAAAAAAAAAEAGH ECYGRwBHAAAAAAAAAAAAAGSHECYGRwBHAAAAAAAAAAAAZAAwDgYDVR0PAQH/BAQD AgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCBlwYDVR0fBIGPMIGM MESgQqBAhj5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUTFNIeWJy aWRFQ0NTSEEzODQyMDIwQ0ExLmNybDBEoEKgQIY+aHR0cDovL2NybDQuZGlnaWNl cnQuY29tL0RpZ2lDZXJ0VExTSHlicmlkRUNDU0hBMzg0MjAyMENBMS5jcmwwSwYD VR0gBEQwQjA2BglghkgBhv1sAQEwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5k aWdpY2VydC5jb20vQ1BTMAgGBmeBDAECAjCBgwYIKwYBBQUHAQEEdzB1MCQGCCsG AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTQYIKwYBBQUHMAKGQWh0 dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRMU0h5YnJpZEVDQ1NI QTM4NDIwMjBDQTEuY3J0MAwGA1UdEwEB/wQCMAAwggEEBgorBgEEAdZ5AgQCBIH1 BIHyAPAAdgApeb7wnjk5IfBWc59jpXflvld9nGAK+PlNXSZcJV3HhAAAAXby6BKo AAAEAwBHMEUCIQDRsvaM+FOVneTUUwY0ggKKCuqKp7wnHvtWHtEUZB+uZwIgJbGG 3Rsq548BxED2wxZ4q2G/9jo0/EeIEwdl9GC7NEIAdgAiRUUHWVUkVpY/oS/x922G 4CMmY63AS39dxoNcbuIPAgAAAXby6BMPAAAEAwBHMEUCIQCV3RpnSizsrJ1vi/48 /qT1PoclZYI3N51mveRdD2gkWQIgdWX+MLuAa8ziuKGIlqjoAiaOvs/4IfqthaAN h6HW8TQwCgYIKoZIzj0EAwMDZwAwZAIwJMLPbL32rtHJ1R9KdC48PdHAPtzXG9OU cVv+pYYWJoIBItMKbvyYtdLiueUHaXeWAjBFe2+Cpn22YsMxhdW1NV1PTISIrBoA PQyEQNywp8ocEycVHjf5RsOu2f35uSOLfyo= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/PostaCARoot.pem000066400000000000000000000047411445061461400215770ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIHHzCCBgegAwIBAgIESPx+9TANBgkqhkiG9w0BAQUFADCBrjESMBAGCgmSJomT 8ixkARkWAnJzMRUwEwYKCZImiZPyLGQBGRYFcG9zdGExEjAQBgoJkiaJk/IsZAEZ FgJjYTEWMBQGA1UEAxMNQ29uZmlndXJhdGlvbjERMA8GA1UEAxMIU2VydmljZXMx HDAaBgNVBAMTE1B1YmxpYyBLZXkgU2VydmljZXMxDDAKBgNVBAMTA0FJQTEWMBQG A1UEAxMNUG9zdGEgQ0EgUm9vdDAeFw0wODEwMjAxMjIyMDhaFw0yODEwMjAxMjUy MDhaMIGuMRIwEAYKCZImiZPyLGQBGRYCcnMxFTATBgoJkiaJk/IsZAEZFgVwb3N0 YTESMBAGCgmSJomT8ixkARkWAmNhMRYwFAYDVQQDEw1Db25maWd1cmF0aW9uMREw DwYDVQQDEwhTZXJ2aWNlczEcMBoGA1UEAxMTUHVibGljIEtleSBTZXJ2aWNlczEM MAoGA1UEAxMDQUlBMRYwFAYDVQQDEw1Qb3N0YSBDQSBSb290MIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqPK9iL7Ar0S+m0qiYxzWVqsdKbIcqhUeRdGs naBh1TX55FqDNmND3jhXFfzwlGL0B4BXg1eosxW8+00jeF/a9seBFr6r3+fcg1Nz K7bdY4iNRfMN3X2/6IiwZsFDXTfSbaGcmkbDsz/QwqCKlC6DpjzDYL0szB6LY4J2 QSjkFWtcDGE5VThByshm6Me4l1IQJnC3B7cJHqYTXq6ZWiZvZD3sxNOluVx2ZK1j fYiD4kvMDd7UxtMIQvVbF/Vx4ZEtA5+eHNyLcqToR2QQh2Qwc9jytPFXJpNXy7bH DYiLHc8FMF0E1nY36CAyV78PnDPGCIz2tMKpBrBbMKEeLRK6PwIDAQABo4IDQTCC Az0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgboGA1UdIASBsjCB rzCBrAYLKwYBBAH6OAoKAQEwgZwwMAYIKwYBBQUHAgEWJGh0dHA6Ly93d3cuY2Eu cG9zdGEucnMvZG9rdW1lbnRhY2lqYTBoBggrBgEFBQcCAjBcGlpPdm8gamUgZWxl a3Ryb25za2kgc2VydGlmaWthdCBST09UIENBIHNlcnZlcmEgU2VydGlmaWthY2lv bm9nIHRlbGEgUG9zdGU6ICJQb3N0YSBDQSBSb290Ii4wEQYJYIZIAYb4QgEBBAQD AgAHMIIBvAYDVR0fBIIBszCCAa8wgcmggcaggcOkgcAwgb0xEjAQBgoJkiaJk/Is ZAEZFgJyczEVMBMGCgmSJomT8ixkARkWBXBvc3RhMRIwEAYKCZImiZPyLGQBGRYC Y2ExFjAUBgNVBAMTDUNvbmZpZ3VyYXRpb24xETAPBgNVBAMTCFNlcnZpY2VzMRww GgYDVQQDExNQdWJsaWMgS2V5IFNlcnZpY2VzMQwwCgYDVQQDEwNBSUExFjAUBgNV BAMTDVBvc3RhIENBIFJvb3QxDTALBgNVBAMTBENSTDEwgeCggd2ggdqGgaNsZGFw Oi8vbGRhcC5jYS5wb3N0YS5ycy9jbj1Qb3N0YSUyMENBJTIwUm9vdCxjbj1BSUEs Y249UHVibGljJTIwS2V5JTIwU2VydmljZXMsY249U2VydmljZXMsY249Q29uZmln dXJhdGlvbixkYz1jYSxkYz1wb3N0YSxkYz1ycz9jZXJ0aWZpY2F0ZVJldm9jYXRp b25MaXN0JTNCYmluYXJ5hjJodHRwOi8vc2VydGlmaWthdGkuY2EucG9zdGEucnMv Y3JsL1Bvc3RhQ0FSb290LmNybDArBgNVHRAEJDAigA8yMDA4MTAyMDEyMjIwOFqB DzIwMjgxMDIwMTI1MjA4WjAfBgNVHSMEGDAWgBTyy43iNe8QQ8Tae8r664kDoSKv uDAdBgNVHQ4EFgQU8suN4jXvEEPE2nvK+uuJA6Eir7gwHQYJKoZIhvZ9B0EABBAw DhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBwRqHI5BcFZg+d4kMx SB2SkBnEhQGFFm74ks57rlIWxJeNCih91cts49XlDjJPyGgtNAg9c6iTQikzRgxE Z/HQmpxpAeWR8Q3JaTwzS04Zk2MzBSkhodj/PlSrnvahegLX3P+lPlR4+dPByhKV +YmeFOLyoUSyy+ktdTXMllW7OAuIJtrWrO/TUqILSzpT2ksiU8zKKiSaYqrEMpp+ 3MzBsmzNj9m0wM/1AsCMK4RbG0C8ENBQ4WHWZlaaBJGl49W9oC4igbHZONrkqIdf PEYElt7Jmju/rXhsHUlJtGm5cA8Fkla2/a+u+CAtRyPPthzNxJuATvm/McBUvrsx f/M+ -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/cacert.pem000066400000000000000000000050111445061461400206710ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ 8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6 zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7 w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826 YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0 IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0 dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg 18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/dfn.pem000066400000000000000000000033111445061461400202000ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIE1TCCA72gAwIBAgIIUE7G9T0RtGQwDQYJKoZIhvcNAQELBQAwcTELMAkGA1UE BhMCREUxHDAaBgNVBAoTE0RldXRzY2hlIFRlbGVrb20gQUcxHzAdBgNVBAsTFlQt VGVsZVNlYyBUcnVzdCBDZW50ZXIxIzAhBgNVBAMTGkRldXRzY2hlIFRlbGVrb20g Um9vdCBDQSAyMB4XDTE0MDcyMjEyMDgyNloXDTE5MDcwOTIzNTkwMFowWjELMAkG A1UEBhMCREUxEzARBgNVBAoTCkRGTi1WZXJlaW4xEDAOBgNVBAsTB0RGTi1QS0kx JDAiBgNVBAMTG0RGTi1WZXJlaW4gUENBIEdsb2JhbCAtIEcwMTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAOmbw2eF+Q2u9Y1Uw5ZQNT1i6W5M7ZTXAFuV InTUIOs0j9bswDEEC5mB4qYU0lKgKCOEi3SJBF5b4OJ4wXjLFssoNTl7LZBF0O2g AHp8v0oOGwDDhulcKzERewzzgiRDjBw4i2poAJru3E94q9LGE5t2re7eJujvAa90 D8EJovZrzr3TzRQwT/Xl46TIYpuCGgMnMA0CZWBN7dEJIyqWNVgn03bGcbaQHcTt /zWGfW8zs9sPxRHCioOhlF1Ba9jSEPVM/cpRrNm975KDu9rrixZWVkPP4dUTPaYf JzDNSVTbyRM0mnF1xWzqpwuY+SGdJ68+ozk5SGqMrcmZ+8MS8r0CAwEAAaOCAYYw ggGCMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUSbfGz+g9H3/qRHsTKffxCnA+ 3mQwHwYDVR0jBBgwFoAUMcN5G7r1U9cX4Il6LRdsCrMrnTMwEgYDVR0TAQH/BAgw BgEB/wIBAjBiBgNVHSAEWzBZMBEGDysGAQQBga0hgiwBAQQCAjARBg8rBgEEAYGt IYIsAQEEAwAwEQYPKwYBBAGBrSGCLAEBBAMBMA8GDSsGAQQBga0hgiwBAQQwDQYL KwYBBAGBrSGCLB4wPgYDVR0fBDcwNTAzoDGgL4YtaHR0cDovL3BraTAzMzYudGVs ZXNlYy5kZS9ybC9EVF9ST09UX0NBXzIuY3JsMHgGCCsGAQUFBwEBBGwwajAsBggr BgEFBQcwAYYgaHR0cDovL29jc3AwMzM2LnRlbGVzZWMuZGUvb2NzcHIwOgYIKwYB BQUHMAKGLmh0dHA6Ly9wa2kwMzM2LnRlbGVzZWMuZGUvY3J0L0RUX1JPT1RfQ0Ff Mi5jZXIwDQYJKoZIhvcNAQELBQADggEBAGMgKP2cIYZyvjlGWTkyJbypAZsNzMp9 QZyGbQpuLLMTWXWxM5IbYScW/8Oy1TWC+4QqAUm9ZrtmL7LCBl1uP27jAVpbykNj XJW24TGnH9UHX03mZYJOMvnDfHpLzU1cdO4h8nUC7FI+0slq05AjbklnNb5/TVak 7Mwvz7ehl6hyPsm8QNZapAg91ryCw7e3Mo6xLI5qbbc1AhnP9TlEWGOnJAAQsLv8 Tq9uLzi7pVdJP9huUG8sl5bcHUaaZYnPrszy5dmfU7M+oS+SqdgLxoQfBMbrHuif fbV7pQLxJMUkYxE0zFqTICp5iDolQpCpZTt8htMSFSMp/CzazDlbVBc= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/digicert.pem000066400000000000000000000030011445061461400212170ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIQCidf5wTW7ssj1c1bSxpOBDANBgkqhkiG9w0BAQwFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD QTAeFw0yMDA5MjMwMDAwMDBaFw0zMDA5MjIyMzU5NTlaMFYxCzAJBgNVBAYTAlVT MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMDAuBgNVBAMTJ0RpZ2lDZXJ0IFRMUyBI eWJyaWQgRUNDIFNIQTM4NCAyMDIwIENBMTB2MBAGByqGSM49AgEGBSuBBAAiA2IA BMEbxppbmNmkKaDp1AS12+umsmxVwP/tmMZJLwYnUcu/cMEFesOxnYeJuq20ExfJ qLSDyLiQ0cx0NTY8g3KwtdD3ImnI8YDEe0CPz2iHJlw5ifFNkU3aiYvkA8ND5b8v c6OCAa4wggGqMB0GA1UdDgQWBBQKvAgpF4ylOW16Ds4zxy6z7fvDejAfBgNVHSME GDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0l BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwdgYI KwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j b20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp Q2VydEdsb2JhbFJvb3RDQS5jcnQwewYDVR0fBHQwcjA3oDWgM4YxaHR0cDovL2Ny bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA3oDWgM4Yx aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNy bDAwBgNVHSAEKTAnMAcGBWeBDAEBMAgGBmeBDAECATAIBgZngQwBAgIwCAYGZ4EM AQIDMA0GCSqGSIb3DQEBDAUAA4IBAQDeOpcbhb17jApY4+PwCwYAeq9EYyp/3YFt ERim+vc4YLGwOWK9uHsu8AjJkltz32WQt960V6zALxyZZ02LXvIBoa33llPN1d9R JzcGRvJvPDGJLEoWKRGC5+23QhST4Nlg+j8cZMsywzEXJNmvPlVv/w+AbxsBCMqk BGPI2lNM8hkmxPad31z6n58SXqJdH/bYF462YvgdgbYKOytobPAyTgr3mYI5sUje CzqJx1+NLyc8nAK8Ib2HxnC+IrrWzfRLvVNve8KaN9EtBH7TuMwNW4SpDCmGr6fY 1h3tDjHhkTb9PA36zoaJzu0cIw265vZt6hCmYWJC+/j+fgZwcPwL -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/example-25519.pem000066400000000000000000000006441445061461400215550ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIBCDCBuwIURHJlLlP4SM/dDu22B8MqFTMZ5uAwBQYDK2VwMCcxCzAJBgNVBAYT AkRFMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wHhcNMjAxMTE2MTYwMzAxWhcN MjIxMDE3MTYwMzAxWjAnMQswCQYDVQQGEwJERTEYMBYGA1UEAwwPd3d3LmV4YW1w bGUuY29tMCowBQYDK2VwAyEAygKTwKSBIgaBMrYlbm7ib5HIWVppEazdP+MOPvud gpgwBQYDK2VwA0EArdE+8IE/aN2CCd/QEBCsvIGbf+l2JvctYjZ8GGmbBvSzYOKZ v4USO7H+2weZmbIWqqAVtrEKG0bk2GB4+61fCA== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/fu-berlin.pem000066400000000000000000000037051445061461400213230ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIFjzCCBHegAwIBAgIHF5BgzPm5bjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQG EwJERTETMBEGA1UEChMKREZOLVZlcmVpbjEQMA4GA1UECxMHREZOLVBLSTEkMCIG A1UEAxMbREZOLVZlcmVpbiBQQ0EgR2xvYmFsIC0gRzAxMB4XDTE0MDUxMjE1MDUz MloXDTE5MDcwOTIzNTkwMFowgbUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZCZXJs aW4xDzANBgNVBAcTBkJlcmxpbjEiMCAGA1UEChMZRnJlaWUgVW5pdmVyc2l0YWV0 IEJlcmxpbjEOMAwGA1UECxMFWkVEQVQxMDAuBgNVBAMTJ0ZyZWllIFVuaXZlcnNp dGFldCBCZXJsaW4gLSBGVS1DQSAtIEcwMTEeMBwGCSqGSIb3DQEJARYPY2FARlUt QmVybGluLkRFMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjYUI0048 zDNevkmXipCDjSpIr+sEbhiXPzWnZnCnkmLOrEMFaNDWDX6kcVQ1VP71opEfGuR5 LtW0P6N+JM8E8y5HXdap62bD4Yfg0KQEmlh9vpMQ75BckReW7wRKH/Ntcrg8gwn9 7d17Hs8hgRGk8cpBRAs5v5hcqRZcjR63mKCismsjld6MVdWSNYhZJhpcnb0dVzMa 3A7Rf1OsXHwDXrhusCNph1+Pazuw2XbIKWSCsFS4qlhHOj5QA375qk5IjjsUnw2F qljLiziu9xB4/jhSx1fz6+5RVnTe5Tb9GMbk5RVR+dvPTnzF96T/yW5DqsFIL+xB YQ8juFoBQog3MwIDAQABo4IB/DCCAfgwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNV HQ8BAf8EBAMCAQYwEQYDVR0gBAowCDAGBgRVHSAAMB0GA1UdDgQWBBQG4T30b/Qw t3o7V7AxBYl7DVhabDAfBgNVHSMEGDAWgBRJt8bP6D0ff+pEexMp9/EKcD7eZDAa BgNVHREEEzARgQ9jYUBGVS1CZXJsaW4uREUwgYgGA1UdHwSBgDB+MD2gO6A5hjdo dHRwOi8vY2RwMS5wY2EuZGZuLmRlL2dsb2JhbC1yb290LWNhL3B1Yi9jcmwvY2Fj cmwuY3JsMD2gO6A5hjdodHRwOi8vY2RwMi5wY2EuZGZuLmRlL2dsb2JhbC1yb290 LWNhL3B1Yi9jcmwvY2FjcmwuY3JsMIHXBggrBgEFBQcBAQSByjCBxzAzBggrBgEF BQcwAYYnaHR0cDovL29jc3AucGNhLmRmbi5kZS9PQ1NQLVNlcnZlci9PQ1NQMEcG CCsGAQUFBzAChjtodHRwOi8vY2RwMS5wY2EuZGZuLmRlL2dsb2JhbC1yb290LWNh L3B1Yi9jYWNlcnQvY2FjZXJ0LmNydDBHBggrBgEFBQcwAoY7aHR0cDovL2NkcDIu cGNhLmRmbi5kZS9nbG9iYWwtcm9vdC1jYS9wdWIvY2FjZXJ0L2NhY2VydC5jcnQw DQYJKoZIhvcNAQELBQADggEBADRy38buZjrfDN8mZiukEjlsx+6s/DKj5YYWaAvU B5kqhL2TM58bPyq4sYAVCDWALifAk11Gx4/Rp1PLNFd4tnoRcQsfgN8ywECpWBbg ESOC73tfa6ZSPEY8uZ4yUk0o2nwxkgU0V3/b7/51XLp5TA5gBeL3aYcjYQ17QN14 Mh12MiXFp5VbPBDTHkinUXt316A8Qj09wJnHMOjt5M+ZDn82YYC7vFDzjNkNmw46 PRL3hZOfZb1IS+fhVlR4eW0FBLqmGg+4Y7Y4KKrwBcBK3OzME5jN71LkdNu1lkB4 3OfT+YOMT+pqZp1l0U6DGZa3SZy5xfWY3EL5BYVM8xAfoZg= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/gcloud.pem000066400000000000000000000032501445061461400207100ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0Iuq7GtFgSVnO CG27r4pN5Xsqz7hzomdNLM+hadpbOGZC0fa7bdtXGcKIZs8IZg8ZFjmGvxu3UX8O JCKURbK5UZXKWrsQjwFivr+YJL3zISqwWh3ibIHp/bs/6azYSW9AZaPhRr/BD2M4 V05C+sL0CBSXX3b+Rr23rW57jqkYAP9TpFGZU2VuqBql/kcD32YNRuVE9ak1Gudt Du4O9G0EGuOFXIxcPa6TRzVBPtenRSzbeij4Iqf04jM+FgaFz7cUM1fjvEWIuvEV 1vNwssEPN7sXTYqpWnQOGHI70an5pJ75npo8ZKrwVzAFotSxDPNbBTR0D8vBsFhG TlmwgtJ9AgMBAAECggEAGJ+fQ5VOYqGUN5A6Y8oCl1RTqk37sj7UbR2/ghqEoSyL +f1Wg1dogLcCOwAGs+izjqPVmEA+aygmPIoe+fKvFBr9ZUxSvtg1gch+Sy9WkcoK WlHvPNjFR3WKJ5nrKSOcpApgxPYVVzAhyX1RsuExTgdevTRtASQtYdLAw/4DykZ5 58nbfMLa9cZ0zu+BTIkKhAAEvjMVnzvuDQWhAShLMQISGbcHVApTzSbj7nCR/tn0 2B7znmu/YcHTBsNdee1Ic9/cfLWWueGeYt1z2RUo6h9H4ILJ8Vju/pUqCAUFj2c0 tTLs1pKgxbQv/PEW1OKbeM1MqO6ya0buCJy++up9xwKBgQDbKnzQCRtmSIRSCsHW IYeWwIWvhrQIaQuUtaJ5A/42sKPvIu/HdoScZuZzXsC+WIsmr1XEFUSaxJnAbDhM 73fuUdNlzoQa+dw3x8eoL2KPhHUMgXgGR//eMMegorzSwR7Lmeu2w1G7UZFVfRby 6cqBMMvExoMT017UvdEegwoz3wKBgQDSaTNM2eSIlSHWilaudvjzFyFnoYrNd4ep 52XiSBA/3KMlBv3ZbWmiNlwgKZq77DYnUZGMYdXXbB2edAK5a/ikphNLPRhn1zNq hVEDXuOwkcyGyNol1P2z9G3n9B+rNy+1RYFAKPJ9/eAqtuxj6kgNDPReXk/a+vtj +DMsWzGlIwKBgAieLhQ8F3C5L0LOm3qhDOTXoyoYwOGHx+XMEpxxlMBvx7JyjD0q ouJHhY5JzohtkOMvh87TC0SOsIEJgFk+HVgorYhWS4mIA6nJ2Eb7vgNosPWR7bdJ g30oK+FcJNKgt2ZIIiWonoEgHvfemFVq7gSQd6LAL41LBXKWGC/79R2/AoGACUGN eyz+q697zJdLVuNu8iqrUoa9t2oxspy2U6z94gFPv/o9wonYosUnalbKMsgiXbpt 37ISGSbtaqIJ2KRSTNPtd1rZrv+9iEsTFEXhWEwhpjBBwHZNLtRq3VBU8FA+Lgg/ tlXWzQoVCWwAnCibQM+4FEqr0qNF2dD6V1IvrecCgYEAr8VENgxbQ+mZq6bIfMqC vCj0DNppYs0llOlu/9JZZzEHnas9afg+rNlK/Hd5iMgzJ/0bxlI+u/G3do2QJ8dP z5ewonMpLxmcxWoB/47FdaNhtiMpZkwpi7EOvapzN8jgr8DWeMTl2aA4iMEOk0lj v7+MqvYwLMfQTrTzGu9VjFo= -----END PRIVATE KEY----- ocaml-x509-0.16.5/tests/regression/izenpe.pem000066400000000000000000000041121445061461400207230ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/jabber.ccc.de.pem000066400000000000000000000037211445061461400220010ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIFmTCCA4GgAwIBAgIDDfTyMA0GCSqGSIb3DQEBBQUAMHkxEDAOBgNVBAoTB1Jv b3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEiMCAGA1UEAxMZ Q0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSc3VwcG9y dEBjYWNlcnQub3JnMB4XDTEzMTAxNzIwNTAxOVoXDTE1MTAxNzIwNTAxOVowbDEL MAkGA1UEBhMCREUxEDAOBgNVBAgTB0hhbWJ1cmcxEDAOBgNVBAcTB0hhbWJ1cmcx ITAfBgNVBAoTGENoYW9zIENvbXB1dGVyIENsdWIgZS5WLjEWMBQGA1UEAxMNamFi YmVyLmNjYy5kZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMixz4WE HJn+wfBI6m1d/lITevEBgLXvPS5KdEzuWd/GvPswvXeBVroa1E8f5CjIq9xMS1c5 EvIQ9nPSynzys9YfLgIodWP2SdoaWDXTqj7IYxRgFsbHGhTptG9CMtsIuDxskNxO QCfqT0Ioab/1Q35ZWmFK+7fRH+4Y1wAEjmGlp2ScZgSX5T5lq+M2SP02o+hqoBGd 2BaPz4rUz/3rEEFE8iXz4XwJ8X5NJ6aftqvfjXVQDfSCJmVKqfU6vkhk8AuM77qF Ti6f6IsSQKYJz3wqnWIz61m6gc96+w43KKVFLivCi6ZA3fqqZOOmuahVk43aW8Dx YkbZF6/6T8P5aWkCAwEAAaOCATUwggExMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/ BAQDAgOoMDQGA1UdJQQtMCsGCCsGAQUFBwMCBggrBgEFBQcDAQYJYIZIAYb4QgQB BgorBgEEAYI3CgMDMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDov L29jc3AuY2FjZXJ0Lm9yZy8wMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5j YWNlcnQub3JnL3Jldm9rZS5jcmwwcwYDVR0RBGwwaoINamFiYmVyLmNjYy5kZYIY Y29uZmVyZW5jZS5qYWJiZXIuY2NjLmRlghVqYWJiZXJkLmphYmJlci5jY2MuZGWC FHB1YnN1Yi5qYWJiZXIuY2NjLmRlghJ2anVkLmphYmJlci5jY2MuZGUwDQYJKoZI hvcNAQEFBQADggIBAD94CY3aF3oUqB++4fZrweiT0T2wN4cwK7xrEWBEct7Nc3E7 hOYtec5qbOZ2hQ7l7RcCkwg3TXN1vm8+MJD4hCmFEJYjX/ZQ1K5MhUh9rBx80Xuj zAGiuIa+wGeiohq2lDqRTenPYN1Plq+YV9zPoGNVNZiXzZVzEwKVcacjpMmAX2i0 kfEr0g4AzjnXwjRmzCajRjwuXMsaxzcs+7BNlLCNYyUPVSIXVhSlflVmZ2YweUcW xEjwT/1y8cfADtPJuaLqZyFjilsWrUpzA8Q3IMFrozhHTor9M6GiMCsbCpDrqvFn aW+wPARL2mQGqCpj4QztlcNMFvrTAvuShkJJpNTcJuo6BKvfP5DSvA56LUqWLaM4 cUcXQQ9sKL52rM/6cW1fK2zmwdJ5YPcp43WJYRIbVEYKBjjf81HuS+W5AptuWmhB Z12zaUegpifupWyMMgNgSD5J90JUdPsvsy+8YW2zhYWmllGbd7WSLn0zW/HyWlAt 0O/JJ6FIkRP2uDwQyzxxhMcRu1dIga5XDcVmRH42KRGSQGfw7cbjXV4qB6ijaTF3 wEUhdUe4/8pDfA9llJ+rc9xzQ2ltBhUDBIpUHye0VPAVlgb4+tJsUhDXdlsExRMz 5j8efW3YT5V/vmlYp7kTjRkK+0XYjctcXnWITsexrOruGVFkUnlu1hj8DceV -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/jabber.fu-berlin.de.pem000066400000000000000000000045471445061461400231430ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIGxDCCBaygAwIBAgIHGu0AwHrK3zANBgkqhkiG9w0BAQsFADCBtTELMAkGA1UE BhMCREUxDzANBgNVBAgTBkJlcmxpbjEPMA0GA1UEBxMGQmVybGluMSIwIAYDVQQK ExlGcmVpZSBVbml2ZXJzaXRhZXQgQmVybGluMQ4wDAYDVQQLEwVaRURBVDEwMC4G A1UEAxMnRnJlaWUgVW5pdmVyc2l0YWV0IEJlcmxpbiAtIEZVLUNBIC0gRzAxMR4w HAYJKoZIhvcNAQkBFg9jYUBGVS1CZXJsaW4uREUwHhcNMTYwMjI0MTAxNzIxWhcN MTkwNTIzMTAxNzIxWjCBgTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEP MA0GA1UEBwwGQmVybGluMSIwIAYDVQQKDBlGcmVpZSBVbml2ZXJzaXRhZXQgQmVy bGluMQ4wDAYDVQQLDAVaRURBVDEcMBoGA1UEAwwTamFiYmVyLmZ1LWJlcmxpbi5k ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALt8ASnemyham6bEfR5A Njc/pYErDscO0X+io3duNOxbHqwM8qqEYI8UEnMtafqSEkbdiwPG3vn4GxOLZi+l MJNsAhFizbHVY//doplFSVMULXq9MReSSv4OQQSSeCUqt1dl7SONBYuXdnMxmlgz 3+R/KbaJYNN20X6d51OVxBxD0QZQXQLOFn6q6eNmBnhQHaxvrFwjgUB0brj6iquB G6kJV908Db6abkY+qsWIE3dx4yt5l0fgWZyDao9GQljKeXBfaExmS/mYATJin8gp xFUyPHNRo3TUnYc9n7L+Mt65Apxn6FBoHF11v0Q9pXxC0FSxj9Wylt9vFJuuGNMk OFECAwEAAaOCAwkwggMFMFkGA1UdIARSMFAwEQYPKwYBBAGBrSGCLAEBBAMEMBEG DysGAQQBga0hgiwCAQQDATAPBg0rBgEEAYGtIYIsAQEEMA0GCysGAQQBga0hgiwe MAgGBmeBDAECAjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DAdBgNVHSUEFjAUBggr BgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFMtj5x3aWWTi8IM2pfxzfoSym8Or MB8GA1UdIwQYMBaAFAbhPfRv9DC3ejtXsDEFiXsNWFpsMIHxBgNVHREEgekwgeaC E2phYmJlci5mdS1iZXJsaW4uZGWCHmNvbmZlcmVuY2UuamFiYmVyLmZ1LWJlcmxp bi5kZYIZcHJveHkuamFiYmVyLmZ1LWJlcmxpbi5kZYIYZWNoby5qYWJiZXIuZnUt YmVybGluLmRlghhmaWxlLmphYmJlci5mdS1iZXJsaW4uZGWCJWppdHNpLXZpZGVv YnJpZGdlLmphYmJlci5mdS1iZXJsaW4uZGWCHW11bHRpY2FzdC5qYWJiZXIuZnUt YmVybGluLmRlghpwdWJzdWIuamFiYmVyLmZ1LWJlcmxpbi5kZTB1BgNVHR8EbjBs MDSgMqAwhi5odHRwOi8vY2RwMS5wY2EuZGZuLmRlL2Z1LWNhL3B1Yi9jcmwvY2Fj cmwuY3JsMDSgMqAwhi5odHRwOi8vY2RwMi5wY2EuZGZuLmRlL2Z1LWNhL3B1Yi9j cmwvY2FjcmwuY3JsMIHFBggrBgEFBQcBAQSBuDCBtTAzBggrBgEFBQcwAYYnaHR0 cDovL29jc3AucGNhLmRmbi5kZS9PQ1NQLVNlcnZlci9PQ1NQMD4GCCsGAQUFBzAC hjJodHRwOi8vY2RwMS5wY2EuZGZuLmRlL2Z1LWNhL3B1Yi9jYWNlcnQvY2FjZXJ0 LmNydDA+BggrBgEFBQcwAoYyaHR0cDovL2NkcDIucGNhLmRmbi5kZS9mdS1jYS9w dWIvY2FjZXJ0L2NhY2VydC5jcnQwDQYJKoZIhvcNAQELBQADggEBAHkluh+KgJJO dn+AlTGtM6ArYQCJFky1jN0wZFtgiPKYBZFMMoTzAoxGkOHXukWYaL2EcDPka4dp nfQ5zHZtOi4StpcuipAMcD/wc5GBXLQoKk7Et1g683FzjHotHnpWF+dQEJAIRo+H Z5VUoGz24crKe64EaSZr4m41Kkdmr4EbTEX4jfapbVN3WRkym6GsNDMr3x3zSp+Q Cx4J8Da3yf7hnBuO1/zR0STtvRnfNTaIHhPUuPKLSfmhYY6FPG7HYQHrbT7vUGtS 4AKOsmcPXmlb568ef08c7UNLOYyLKUlX7I42H2s5jdccVu/8dK+9QUKPN935ZxQ/ 2okVaf5AZuI= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/letsencrypt-root-x2.pem000066400000000000000000000014261445061461400233220ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW +1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 /q4AaOeMSQ+2b1tbFfLn -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/name-constraints.pem000066400000000000000000000027511445061461400227250ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD 75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp 5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p 6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI l7WdmplNsDz4SgCbZN2fOUvRJ9e4 -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/openssl_2048.pem000066400000000000000000000032541445061461400215770ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDN/TPIzwalLAgD o5mTsxKSZhKavdF851DBEvteyx/cNd4Apxtt+4qWuI3Mboqeh/llhGLxJ8ZdiQCI bhhHsqXjM640AJq2kLm8f0bEweZknT/KD+ThqObNLmhcgaJpjFjG+Z2ZmC5XDi3C OZKLD/rnuBuDbZqN8n1Tde6S58duI8M2kGvRcVfYPSc+WjMf5yMRMlPOWbYiC+JO 5afjS/FGOG+RBVVDrxq70UoIJdUd9SssfRB79pGED/3hfTT/Mt2AI7rpgsQOYgrd 4eut3UsUGZoLR8hLSaG58WjGqQRgsuih+JHAiWcfhploD0Yx8kR99GzxA/8nGYgg 6RlT389xAgMBAAECggEBAKk+Pkvg/R68fKEwy7/0w2+Refu1tecfztOzmuCZl8XA ZHS41+qXX5jSbX7n2/DA24IzMW/eNDcpl0yA2GYgO/fewGRtkrApXNGo6SZEAd3s 7TpBsNZPhcJTPN+0ixKZg1+IO5q01G4mciZAU0z6hjXYqJJlfTTfZWUrYidFVDAC rIsSAlMAsjzHWugWey8MolMZYBBsEGyXlMc1vf/E2i5lvglEgmgD6Xn86nPS8y9t 2Z3O01OynMa8sE3LVg09HksvfNL+txfZoxbK8z9CHELvI8gVUJcT6EGEiHeDqXjr wThK7WCv2yf/lCYE3zxw1bjLzBlI+20ywEvrIry5xAECgYEA7hAHLi9ip7xG4fRo 1+32d1ZpklyCLJ/lF+UUFfa6wpuXR0muHS+FpOxZO0cNRLE1OMsL7KxeLoBqQfvp nmhTDsCVq9RBnJPqoB1k11I1gNVHZe1aoqYy17A8TfNetR5RwBjo9XYZfrXeHg9s qi8uk1D1d3q1AvDvsoHzv5d9dRECgYEA3YKCmNz8oA08MFqCetxm0XEmqqJwlWGr jX9c1jK6HfamsHS93a2Seb9Zm+fps3PixZZWEEI9n/yJmkM4CkmJBlzUA31gN+gU AAjsxt8YiSdxO0L1BscxqebOoD2CnWXvk9SHr8kE7WfKe98Bf8/CjN+qL3gNkAp4 dqVXY/yfNGECgYEAvQylZxviMGnnsFAzYiZq72ID/GLSTTW87DjSto50yU5d2BK+ 3hZ6/vlh8xz9gGtpZGx6T7yiHjOELloqr80RCEoPkaDBaeJdFEHDbuqt6l10kZDn xPpOrdIaUZzOvO4S5YXimerrXCB4/04ocQ1+4yYLiJI9ZNSIxS1FsARRcMECgYEA 2LJhcovVs/nepOsWdH0DNOe9zPYmr2yiOEWdm4p6mu99uGgsih3QirwQPL4O2ViI Q4XD4hn7UXTrZHdX7nBr1Uagvl078NVgI3yXriH4TczBMBlbvWrHAhBimU4zZimf y34B040S/fEonC/YtqGYENqKEfAfTIeBu4gayx0K3mECgYBmE7Or+YnhIDr3fuDS lspBeejV17mI/kd7xKBbgirMvIzh/6Wi7PooySLrlcu23/lba3FPl6ZobfHAUCLS LDttnjIsDJkxXh3fOwJmad9J/hSDt/QdkIivnEgrvCt7s2Tji3OaPTujtaQT0SOZ ZfOHUpM7RHfGV5KS3qr2C8BjVw== -----END PRIVATE KEY----- ocaml-x509-0.16.5/tests/regression/p256_sha384.pem000066400000000000000000000013611445061461400212220ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICADCCAaagAwIBAgIUHyCUM78QgqYYqanmNGJYTXnAk20wCgYIKoZIzj0EAwMw TzELMAkGA1UEBhMCQVUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 ZDEdMBsGA1UEAwwUcDI1NiBrZXkgd2l0aCBzaGEzODQwHhcNMjIwOTEzMTA1NDQ1 WhcNMjMwOTA4MTA1NDQ1WjBPMQswCQYDVQQGEwJBVTEhMB8GA1UECgwYSW50ZXJu ZXQgV2lkZ2l0cyBQdHkgTHRkMR0wGwYDVQQDDBRwMjU2IGtleSB3aXRoIHNoYTM4 NDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFjrBgci81MwGVNjEtG2gexFcJbK Y2niGcoU2rAmQrB6PyfbhBHFCwmVwPEGyB39bRI+Toy6qFMMSK35EktMmGujYDBe MB0GA1UdDgQWBBRqwn0D+5XJdoUbL0JWG+eYO+xRcDAfBgNVHSMEGDAWgBRqwn0D +5XJdoUbL0JWG+eYO+xRcDAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwICBDAK BggqhkjOPQQDAwNIADBFAiACu3r0M9V45MGoH9Pv2eXPwNfSiEtcEI5VzxbvO24z /AIhAKATujXQk8FiBG0jH2982DzQBIQ03OkoA7MmReOomiY/ -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/pads.ccc.de.pem000066400000000000000000000044021445061461400215000ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIGXTCCBUWgAwIBAgISBDkcRJF02Qx8APXR8rCrg/9eMA0GCSqGSIb3DQEBCwUA MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xOTExMDExNjA3NTVaFw0y MDAxMzAxNjA3NTVaMBYxFDASBgNVBAMTC3BhZHMuY2NjLmRlMIICIjANBgkqhkiG 9w0BAQEFAAOCAg8AMIICCgKCAgEA09UMHZpbLq3EhSaXzjxjLcPpS5B2l6E/rDkd lQGy6Dc2JnvxJKengEvESDuU5ry61bdDNg8RAYKQwGpNeKsca+86rE9lgCWmbIfQ 6+Af9B2EE93hEL2N+EMew6ZbO+PqPdvtRupfiNEWdt4M5OPpM2qAwJVxkdyOxk3c v0JqZ0nKSzIu2pfQ5IEiRtcjEQEJ6BEILY5H1IeiX0y8QDiGjPrqdqQShUd4o0r0 o1Iet1EEVyDZSm6LWvdPQmL+n7GVrKuo40zFh9CqVJo3lZuNgQmzNWefPqUbFq9t WPbWJQOAbrg1w1H9OWl9cs+f0zEUzLCb7ofMx5bxq7wxYw3t2BE1CwndQqBGA0n4 NduZLu9c9tQGkWcfo9S0OkjcoXip9eoT3UM2r5Cb9FgmjXCbRBpKGQj5pZcrYZt6 yp503fiffiDJYC5x8Cx0Kjanrafbwvi1ZozguDC467OYsj9sPqyPtGDdmfx1LdgF JVGyH6VBzLCudCjvAtU/ByHFECmCi+c/bvf0fV1hLnZ+rh5rJRsjPjvaUVdiFTGT /qDVAsvriZdY06ErrbxVIFVF3Z1XzTLCTVH9f0e/4LFS4/xVHAiHsnWyBmEBCBcF iHeuJZB8oli5SgCLPqhRVAopQNFc7J4vcFBgH60NU+L7+29MxuKmGwDo6CsPjwU3 bwh80ucCAwEAAaOCAm8wggJrMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU5oDnFCqI 6EDcML4z3CiQR4TmkTcwHwYDVR0jBBgwFoAUqEpqYwR93brm0Tm3pkVl7/Oo7KEw bwYIKwYBBQUHAQEEYzBhMC4GCCsGAQUFBzABhiJodHRwOi8vb2NzcC5pbnQteDMu bGV0c2VuY3J5cHQub3JnMC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDMu bGV0c2VuY3J5cHQub3JnLzAlBgNVHREEHjAcgg0qLnBhZHMuY2NjLmRlggtwYWRz LmNjYy5kZTBMBgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEEAYLfEwEBATAoMCYG CCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCCAQQGCisGAQQB 1nkCBAIEgfUEgfIA8AB2AF6nc/nfVsDntTZIfdBJ4DJ6kZoMhKESEoQYdZaBcUVY AAABbifwEksAAAQDAEcwRQIhALwTIEEy2IFSWsox04rolhV2u7ZhUu+uhZ8GfqXA /kXiAiBqpoRu5eAGtp/OIGIE5lIxrFvGXulL6qXuA4KgozympQB2AAe3XBvlfWj/ 8bDGHSMVx7rmV3xXlLdq7rxhOhpp06IcAAABbifwEnMAAAQDAEcwRQIgU8vJo3ZO U4LEFh588taYBRL4kyYbgs72ptlP3ZNaDrQCIQCqLVvbuAn0YT4t1BJLHpQjITfX aUlnbi/c0unrKPIm4jANBgkqhkiG9w0BAQsFAAOCAQEABau9X2OKT3SRDwd9/gLt QXHCWirT+OH1K+1A0TPUb2PL0hRvET1Ens8Lf2uN/cbJTjB1M75IXH0wHb+IHRsG Fe9H6qplpEuNxKCn8e/WKm4OpJlVKw+ZmiM/o5oIFCpjMxiFljTpa626CikZZUil wUQ/Upd1O0qWdFR0BPI8xjRU8v0Ck9zNJUgZgyvOOQPIFHqhp4w+tP5DjGsgUJUG qg3mqxDbyPKe+qhuYqKC8T+FhZlsa0860T9n9tjcSwupemNUNAPRM+sFV6bZzWhb GcmpYpdj3v1IxCV2yTx+Lmw2VgSnL0pzFFriu118HGtOs/7D7YNMrf4EnsecBV+L oQ== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/priv_p256.pem000066400000000000000000000003431445061461400211670ustar00rootroot00000000000000-----BEGIN EC PRIVATE KEY----- MHcCAQEEIHE5sa4aN1Qh2oek/0Vsh+AjNW2JvlYClbG5itcElL07oAoGCCqGSM49 AwEHoUQDQgAEGDIcaAYlT2o4IeMoFJtfMj+5ymE7BbwUkT4i3jKMuwPTlbOxcRSy jdqqvzl3XO8wI36oaY54Z/a/W0pegihH5Q== -----END EC PRIVATE KEY----- ocaml-x509-0.16.5/tests/regression/telesec.pem000066400000000000000000000024471445061461400210660ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl 6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU Cm26OWMohpLzGITY+9HPBVZkVw== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/until_frac_s.pem000066400000000000000000000023311445061461400221020ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDZjCCAk6gAwIBAgIJAK8XzYo2Lc2EMA0GCSqGSIb3DQEBCwUAMDIxMDAuBgNV BAMMJ3ZhbGlkX3VudGlsX2NvbnRhaW5zX2ZyYWN0aW9uYWxfc2Vjb25kczAkFw0y MDA0MjcwOTM0NTNaGBM5OTk5MTIzMTIzNTk1OS45OTlaMDIxMDAuBgNVBAMMJ3Zh bGlkX3VudGlsX2NvbnRhaW5zX2ZyYWN0aW9uYWxfc2Vjb25kczCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBALcbxMTFe2X1kKGSd1zK0W7fY2eDzgng1UzN 1oLOFFpPlT88cJADtJIpFvdntLBWphAu/hq53tUYS/TSrTy1f+WH4fFuBiJPO8FW 8xsRhdmx5XwIAyYUhO5onXeBH0nhGS/VxAE/QUj0T1cxgEjJjiwbbF2z3+/4vygM Ob+0eMdJZD7LL4YBDG5Ttm60s6Gcuw2zapfDI8x7E9rmAGHpqD4XJXuPDoXsh5UC lOaXH36MNjBdHWcxNzGm3Uwe3EUrumrKXhIzqL1l+/Ku0gJ7nQD9etyLTaJEsxfz xheAfq/4mnZvYaFq41fp/bCg0etNupFY0Eb4YJVPZrkl/xAh59cCAwEAAaN5MHcw HQYDVR0OBBYEFDhp/reJqyj1UqrTKuKilkA9Q79cMA8GA1UdDwEB/wQFAwMHoAAw DAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQ4af63iaso9VKq0yriopZAPUO/XDAW BgNVHSUBAf8EDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAAdaTDIV4 wR7xrqLWO9Gt+QS1wUfAe014KJ3WF/8IObHGU1mLPP5KqFnR4w7PikJxqHvdQOC3 NA1ApbkqiNOGEciF6Q5wew42GLOr6EdT0/3L3PLkV/MEIkbT2qqLhIkyzi9BmIFq pW6w2r3fzyhWsBZm8+odY8WVLnNR1kczc4RE4pYOn8Nyxdo7la4k0op7jawWfLJK VVXLng0bmXjmVqbzIQQbTyXAC6bPh4iF1uXQ28k4g87xOBYJOkEHqwvJaSuXfPAg rTJaozrqyrzolduRX23yLMyNSU+I1IN8qbi7R1JZMxTlDS2tMmXCU3HC0YdEg/5T /WxH7VMSXkFZuA== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/regression/yubico.pem000066400000000000000000000014251445061461400207270ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICGzCCAQWgAwIBAgIEQMQSJTALBgkqhkiG9w0BAQswLjEsMCoGA1UEAxMjWXVi aWNvIFUyRiBSb290IENBIFNlcmlhbCA0NTcyMDA2MzEwIBcNMTQwODAxMDAwMDAw WhgPMjA1MDA5MDQwMDAwMDBaMCoxKDAmBgNVBAMMH1l1YmljbyBVMkYgRUUgU2Vy aWFsIDEwODY1OTE1MjUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAStoklVeyhj RHTxPqBxr6GzZx1cOmWerwd4zSGAdQuLd9jrnB8zMHh6jOQgDEjAx7X6db7iWGok EpO42+jOPFrXoxIwEDAOBgorBgEEAYLECgEBBAAwCwYJKoZIhvcNAQELA4IBAQFY NAaBBxBKeCyS2D2BQAkRkvFmYl5AgPHK2C4Bp873yl8D8MiiZVM2Mcb+caEa5ec4 5CFF4WeJpx2VbJ4/RGP1Rg7kUcyl+2LcU2aRWZ+3o92m4y4XJE5JEPwIVJJj+1bi tgFi4GLEvHoxlKroIQbCr4f/OLsUwBK+QUvjhoNsou1CI3fFtJzgnOhDfHf/MAoj zo7dmP/kyqSy01yrM5OFJ1jc0XcQU4ZgQaayQWWxdVclUbyZuckSwabYdxvCjL67 eDbtxHKI/0NeeCCaVntQ6dbqQxSzhvZ1gkUJNuWNuuJPQQyEn6rPsB71IyKNog5y peVFaGrk1mk+zOirhMJe -----END CERTIFICATE-----ocaml-x509-0.16.5/tests/revoke.ml000066400000000000000000000210601445061461400163740ustar00rootroot00000000000000open X509 let time () = None (* some revocation scenarios to convince myself *) let ca_exts ?pathlen () = let ku = [ `Key_cert_sign ; `CRL_sign ; `Digital_signature ; `Content_commitment ] in Extension.(add Basic_constraints (true, (true, pathlen)) (singleton Key_usage (true, ku))) let key_ids exts subject_pubkey issuer_pubkey = let subject_key_id = false, Public_key.id subject_pubkey and authority_key_id = let cs = Public_key.id issuer_pubkey in false, (Some cs, General_name.empty, None) in Extension.(add Subject_key_id subject_key_id (add Authority_key_id authority_key_id exts)) let leaf_exts = Extension.(add Key_usage (true, [ `Digital_signature ; `Key_encipherment ]) (add Ext_key_usage (true, [ `Server_auth ]) (singleton Basic_constraints (true, (false, None))))) let validity now = match Ptime.add_span now (Ptime.Span.of_int_s 3600) with | Some fut -> (now, fut) | None -> invalid_arg "couldn't add 3600 seconds to now" let key () = let key = Mirage_crypto_pk.Rsa.generate ~bits:1024 () in (`RSA (Mirage_crypto_pk.Rsa.pub_of_priv key), `RSA key) let selfsigned ?(name = "test") now = let pub, priv = key () in let name = [ Distinguished_name.(Relative_distinguished_name.singleton (CN name)) ] in match Signing_request.create name priv with | Error _ -> assert false | Ok req -> let valid_from, valid_until = validity now in match X509.Signing_request.sign req ~valid_from ~valid_until ~extensions:(ca_exts ()) priv name with | Ok cacert -> (cacert, pub, priv) | Error _ -> assert false let cert ?serial ?(name = "sub") now ca pubca privca issuer = let pub, priv = key () in let name = [ Distinguished_name.(Relative_distinguished_name.singleton (CN name)) ] in match Signing_request.create name priv with | Error _ -> assert false | Ok req -> let valid_from, valid_until = validity now in let extensions = key_ids (if ca then ca_exts () else leaf_exts) pub pubca in match X509.Signing_request.sign req ~valid_from ~valid_until ?serial ~extensions privca issuer with | Ok cert -> (cert, pub, priv) | Error _ -> assert false let verify () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in let cert, _, _ = cert now false capub capriv (Certificate.subject ca) in match Validation.verify_chain ~host:None ~time ~anchors:[ca] [cert] with | Ok _ -> () | Error _ -> Alcotest.fail "expected verification to succeed" let crl () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in let serial = Z.of_int 42 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 let extensions = Extension.(singleton CRL_number (false, 1)) in match CRL.revoke ~issuer ~this_update:now ~extensions [revoked] capriv with | Error _ -> Alcotest.fail "couldn't revoke" | Ok crl -> let revoked = CRL.is_revoked [crl] ?allowed_hashes:None in match Validation.verify_chain ~host:None ~time ~revoked ~anchors:[ca] [cert] with | Ok _ -> Alcotest.fail "expected revocation" | Error (`Revoked _) -> () | Error _ -> Alcotest.fail "expected revoked failure!" let verify' () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in let serial = Z.of_int 42 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 match Validation.verify_chain ~host:None ~time ~anchors:[ca] [cert ; ica] with | Ok _ -> () | Error _ -> Alcotest.fail "expected verification!" let crl' () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in let serial = Z.of_int 42 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 let revoked = { CRL.serial ; date = now ; extensions = Extension.empty } in let extensions = Extension.(singleton CRL_number (false, 1)) in match CRL.revoke ~issuer ~this_update:now ~extensions [revoked] capriv with | Error _ -> Alcotest.fail "couldn't revoke" | Ok crl -> let revoked = CRL.is_revoked [crl] ?allowed_hashes:None in match Validation.verify_chain ~host:None ~time ~revoked ~anchors:[ca] [cert ; ica] with | Ok _ -> Alcotest.fail "expected revocation" | Error (`Revoked _) -> () | Error _ -> Alcotest.fail "expected revoked failure!" let crl'leaf () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in let serial = Z.of_int 42 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 let revoked = { CRL.serial ; date = now ; extensions = Extension.empty } in let extensions = Extension.(singleton CRL_number (false, 1)) in match CRL.revoke ~issuer ~this_update:now ~extensions [revoked] ipriv with | Error _ -> Alcotest.fail "couldn't revoke" | Ok crl -> let revoked = CRL.is_revoked [crl] ?allowed_hashes:None in match Validation.verify_chain ~host:None ~time ~revoked ~anchors:[ca] [cert ; ica] with | Ok _ -> Alcotest.fail "expected revocation" | Error (`Revoked _) -> () | Error _ -> Alcotest.fail "expected revoked failure!" 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 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 let revoked = { CRL.serial ; date = now ; extensions = Extension.empty } in let extensions = Extension.(singleton CRL_number (false, 1)) in match CRL.revoke ~issuer ~this_update:now ~extensions [revoked] ipriv with | Error _ -> Alcotest.fail "couldn't revoke" | Ok crl -> let revoked = CRL.is_revoked [crl] ?allowed_hashes:None in match Validation.verify_chain ~host:None ~time ~revoked ~anchors:[ca] [cert ; ica] with | Ok _ -> () | Error _ -> Alcotest.fail "expected success!" let verify'' () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in let serial = Z.of_int 42 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 let revoked = { CRL.serial ; date = now ; extensions = Extension.empty } in let extensions = Extension.(singleton CRL_number (false, 1)) in match CRL.revoke ~issuer ~this_update:now ~extensions [revoked] capriv with | Error _ -> Alcotest.fail "couldn't revoke" | Ok crl -> let revoked = CRL.is_revoked [crl] ?allowed_hashes:None in match Validation.verify_chain ~host:None ~time ~revoked ~anchors:[ca] [cert ; ica] with | Ok _ -> () | Error _ -> Alcotest.fail "expected verify to succeed!" let crl'' () = let now = Ptime_clock.now () in let ca, capub, capriv = selfsigned now in let serial = Z.of_int 42 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 let extensions = Extension.(singleton Reason (false, `Remove_from_CRL)) in let revoked = { CRL.serial ; date = now ; extensions } in let extensions = Extension.(singleton CRL_number (false, 1)) in match CRL.revoke ~issuer ~this_update:now ~extensions [revoked] capriv with | Error _ -> Alcotest.fail "couldn't revoke" | Ok crl -> let revoked = CRL.is_revoked [crl] ?allowed_hashes:None in match Validation.verify_chain ~host:None ~time ~revoked ~anchors:[ca] [cert ; ica] with | Ok _ -> () | Error _ -> Alcotest.fail "expected proper verification!" let revoke_tests = [ "Verify with a chain works", `Quick, verify ; "Verify with a revoked leaf fails", `Quick, crl ; "Verify with a longer chain works", `Quick, verify' ; "Verify with a revoked intermediate fails", `Quick, crl' ; "Verify with a longer chain works, even if some random serial is revoked", `Quick, verify'' ; "Verify with a revoked `Remove_from_CRL works", `Quick, crl'' ; "Verify with revoked leaf fails", `Quick, crl'leaf ; "Verify with wrongly revoked leaf works", `Quick, crl'leaf'wrong ; ] ocaml-x509-0.16.5/tests/testcertificates/000077500000000000000000000000001445061461400201155ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/testcertificates/cacert-basicconstraint-ca-false.pem000066400000000000000000000015731445061461400267240ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICZTCCAc6gAwIBAgIJAPcD62VeqwKRMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwNjA2MTQ0OTE4WhcNMjQwNjAzMTQ0OTE4WjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN71CgueqD05Ty Hd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPYPW8QrwWgf4pG ALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQABo10wWzAdBgNV HQ4EFgQUn3MQYUIRTYLK8P836RfDIMjbHkowHwYDVR0jBBgwFoAUn3MQYUIRTYLK 8P836RfDIMjbHkowDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCAQYwDQYJKoZIhvcN AQEFBQADgYEArlKvupOurdhs55LfUJsLDtWSNE91uFsMMXBPYEar479oF8dhiZ48 xFmB2kKaFPP6M/IKkAsbfPb9tC1SjeytG7ee/yTKTxyW39p1LIL6VJjeHs6lASfp raJ6S9KiA5p/NYU+FJHIccyjnMSHyIEq59M10udwQEBcNaz/OC6Piag= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/cacert-ext-usage-timestamping.pem000066400000000000000000000016401445061461400264610ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICgDCCAemgAwIBAgIJAKmh6BrU3QWMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwNjA3MTQyOTIyWhcNMjQwNjA0MTQyOTIyWjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN71CgueqD05Ty Hd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPYPW8QrwWgf4pG ALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQABo3gwdjAdBgNV HQ4EFgQUn3MQYUIRTYLK8P836RfDIMjbHkowHwYDVR0jBBgwFoAUn3MQYUIRTYLK 8P836RfDIMjbHkowDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwFgYDVR0l AQH/BAwwCgYIKwYBBQUHAwgwDQYJKoZIhvcNAQEFBQADgYEAjDf6zUCyJkvOsDrk ehK3svOhOorccDBflNO590ToMfWXXF3sU5dpZ2tZ0/UZSlFyc5Uzj/nGpielSMcK zEpQRQS7ZGV7JZ08aNEz7g4n8VxUWW+y2w2R+oX2IEyIdIkSkQK32+TOXkPMHizN pAeW++JBXYY6QmJW499y2z1UquE= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/cacert-ext-usage.pem000066400000000000000000000016341445061461400237650ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICfDCCAeWgAwIBAgIJAIoGsKuY0469MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwNjA3MTQyODUwWhcNMjQwNjA0MTQyODUwWjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN71CgueqD05Ty Hd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPYPW8QrwWgf4pG ALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQABo3QwcjAdBgNV HQ4EFgQUn3MQYUIRTYLK8P836RfDIMjbHkowHwYDVR0jBBgwFoAUn3MQYUIRTYLK 8P836RfDIMjbHkowDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwEgYDVR0l AQH/BAgwBgYEVR0lADANBgkqhkiG9w0BAQUFAAOBgQByiIZb2wNUHIT3WHTJD4lD ExMnKn2BSoP24vCJHi/iDbbsMCoaTDv3e5YxBUMoEFEhT1ozHfpU0u+VfFIy9VFC Ks7Ths7n+7lyzecEJ9eJiq9f8vRCgr4ZhEbK/c7yH707PqOeQ5pSVT9FCM889ZSr 4EkUhWofJr+JGbnSzn/rxQ== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/cacert-keyusage-crlsign.pem000066400000000000000000000015771445061461400253450ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICaDCCAdGgAwIBAgIJAIr4AbIHNEAnMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwNjA2MTQ0ODM1WhcNMjQwNjAzMTQ0ODM1WjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN71CgueqD05Ty Hd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPYPW8QrwWgf4pG ALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQABo2AwXjAdBgNV HQ4EFgQUn3MQYUIRTYLK8P836RfDIMjbHkowHwYDVR0jBBgwFoAUn3MQYUIRTYLK 8P836RfDIMjbHkowDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQIwDQYJKoZI hvcNAQEFBQADgYEALzv9za/FuK9or2E2gNjK3seGlM8L2p8UjrbOBRv1U6SlErA/ smGfRefwtisUkkXTsR6WuGvTZhbjgIh2d/HaUqekQlcTNd3WNESfBek4wjkE6LR3 sZQ5+cAQI9zsENCp+fE7dfgRtRgEYEaHxchNQVmYde8cHL1ye0AKcakvtWY= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/cacert-pathlen-0.pem000066400000000000000000000016031445061461400236470ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICazCCAdSgAwIBAgIJAO2nNZ05JgguMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwNjA2MTQ0NzAyWhcNMjQwNjAzMTQ0NzAyWjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN71CgueqD05Ty Hd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPYPW8QrwWgf4pG ALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQABo2MwYTAdBgNV HQ4EFgQUn3MQYUIRTYLK8P836RfDIMjbHkowHwYDVR0jBBgwFoAUn3MQYUIRTYLK 8P836RfDIMjbHkowEgYDVR0TAQH/BAgwBgEB/wIBADALBgNVHQ8EBAMCAQYwDQYJ KoZIhvcNAQEFBQADgYEAvt+gNpcPebMBYJ3O4346P3ClBfp+jje3GczWqZcWaZMB JLxLAIhBu62+10R6zEFIEsfefQhX+tFXNI6o1c2eHAeXb1DBnx/iMSoZG4P2UY25 trpv9k0FrLhJlXesgZUV8QyISEoGDv9bghwikArxxvu1Lpw2W1v5eedQMTCVWDg= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/cacert-unknown-critical-extension.pem000066400000000000000000000016541445061461400273660ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICijCCAfOgAwIBAgIJAMtobgMI4HeQMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwNjA2MTQ0NjIyWhcNMjQwNjAzMTQ0NjIyWjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN71CgueqD05Ty Hd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPYPW8QrwWgf4pG ALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQABo4GBMH8wHQYD VR0OBBYEFJ9zEGFCEU2CyvD/N+kXwyDI2x5KMB8GA1UdIwQYMBaAFJ9zEGFCEU2C yvD/N+kXwyDI2x5KMBIGA1UdEwEB/wQIMAYBAf8CAWQwCwYDVR0PBAQDAgEGMBwG AyoDBAEB/wQSDBBTb21lIHJhbmRvbSBkYXRhMA0GCSqGSIb3DQEBBQUAA4GBAOaD h3bVjpAdkP6T0D5iVMRS1+cHevvv0HctwxpXwLdqkKU/I2/wR7y99ts9a6ro33Pg dWCT8plnDsUyU86OJ2+j21U94pihBZ/bn8+cfP0WTT112ZnjOzvMftG4b0I+VnHp RVGg7KV/er29BP0LA1iZbbLe45ADJGkQR1Ggm3rF -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/cacert-unknown-extension.pem000066400000000000000000000016441445061461400255750ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICgzCCAeygAwIBAgIJAJtKIRp+wJhvMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwNjA2MTcxODE5WhcNMjQwNjAzMTcxODE5WjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN71CgueqD05Ty Hd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPYPW8QrwWgf4pG ALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQABo3sweTAdBgNV HQ4EFgQUn3MQYUIRTYLK8P836RfDIMjbHkowHwYDVR0jBBgwFoAUn3MQYUIRTYLK 8P836RfDIMjbHkowDwYDVR0TAQH/BAUwAwEB/zAZBgMqAwQEEgwQU29tZSByYW5k b20gZGF0YTALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEFBQADgYEAzri5kJWI1YTQ EHCZIf5BXFxpdFKNmMIidkrynGHHVKluVzbroG23I5elnxP3z97za33NpQlk6p1h TUfFB/+J4FpguXKW6JW3BpY/1jYKKC18NhY3OHubYNdGjqZKPybVm2ZaH3B23q0D 3IpbNRIxzTmSaWAJZ/zibkW5o2sNRAo= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/cacert-v1.pem000066400000000000000000000013651445061461400224120ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICATCCAWoCCQD9ajF8CeIw7jANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 cyBQdHkgTHRkMB4XDTE0MDYwNzEzNTE1MVoXDTI0MDYwNDEzNTE1MVowRTELMAkG A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA52G0 B+6RZhjuqk4+LKQFmco3bf5WCf/McuKAj5SmpsTpEf3Ize9QoLnqg9OU8h3d49Ik 9qr8c1OCMDyJT6KivfoMxcm59LvK4z+FKLkanBkvcPmT2D1vEK8FoH+KRgC4FpW0 pvFZGEumdUAEJja2AL3uqbojZF79zZsGtVYiOwECAwEAATANBgkqhkiG9w0BAQUF AAOBgQDj8fzfzrhaLooJV+6IGwPbmsL0448vt/0QUY5Q82FfLo1KHNp5j/axSmw3 b90T8OUq6EAAJyW+KLed0Q0YGcz/OcOTh68ellTpeSei3AxNdKxV6ucK70QdR0Wk mp6jOTmLFTTBoqCRxlbrwgN/nmx77/j002yXcXiGe1Tos9zUKQ== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/cacert.pem000066400000000000000000000016031445061461400220610ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICazCCAdSgAwIBAgIJAM7c1BlUjOksMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwNjA2MTI1NjI1WhcNMjQwNjAzMTI1NjI1WjBF MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN71CgueqD05Ty Hd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPYPW8QrwWgf4pG ALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQABo2MwYTAdBgNV HQ4EFgQUn3MQYUIRTYLK8P836RfDIMjbHkowHwYDVR0jBBgwFoAUn3MQYUIRTYLK 8P836RfDIMjbHkowEgYDVR0TAQH/BAgwBgEB/wIBZDALBgNVHQ8EBAMCAQYwDQYJ KoZIhvcNAQEFBQADgYEAX0qcQDr2Dw6qJkMVZZUmdrnGZ0npmYG7mPH4IN45h1IS NhpsLAxY0kfPF/gcwGmRzzifUnAZ4huDudUrOWVvVg7Wi5OE1JF2g8nFUzV/z0Cs 1tUEcSFgWnP8a8CNfXOXq1CSd9IctfoLJ7C/e9vOqw+n5MT85TCbHr/Ib2eYzaQ= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/000077500000000000000000000000001445061461400212445ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/testcertificates/first/first-basicconstraint-true.pem000066400000000000000000000057031445061461400272440ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 6 (0x6) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 6 17:23:19 2014 GMT Not After : Jun 3 17:23:19 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=ca.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:TRUE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A Signature Algorithm: sha1WithRSAEncryption 45:b6:bc:bb:49:8b:12:ce:07:14:68:4f:d1:d1:e5:60:a6:9b: 9a:b0:8e:40:d0:9c:9d:63:3d:5e:ef:5c:1c:80:4b:2d:ba:45: d5:46:2a:08:06:d1:4f:ce:20:7c:3f:04:c2:69:fe:29:6e:be: e9:27:fe:7a:7a:6c:75:7f:b1:8f:c8:97:52:85:c3:35:53:b4: e8:69:f7:ce:fa:a1:48:aa:36:41:37:c3:7d:9f:3f:dc:b3:dd: 7e:ba:73:b5:94:89:6c:b1:b1:15:c7:48:d1:2f:a7:28:d5:6d: c3:de:a2:93:da:80:d5:8b:5d:0f:10:47:36:70:a2:10:38:3e: 57:8e -----BEGIN CERTIFICATE----- MIICdTCCAd6gAwIBAgIBBjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNjE3MjMxOVoXDTI0MDYwMzE3MjMxOVowXTELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDEWMBQGA1UEAwwNY2EuZm9vYmFyLmNvbTCBnzANBgkqhkiG 9w0BAQEFAAOBjQAwgYkCgYEA5BPn8JeHYl/izHmyVXfXwri501G5cm8VE7WU51SO wRg3bNgLkFqkXaUOQnROfq3pNDenbeUwxkF7+IXpYYTM2IDyf69uIrwszicfSv02 vByd9V/ptJYPiDGPp204VKh+LBwccowvCwpxb9LVxqzp4Ol+ckZDoABgM2LXev8e f3cCAwEAAaNdMFswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCBeAwHQYDVR0OBBYE FEr36OtXG6tJQSPoAmQjgyMXDsoFMB8GA1UdIwQYMBaAFJ9zEGFCEU2CyvD/N+kX wyDI2x5KMA0GCSqGSIb3DQEBBQUAA4GBAEW2vLtJixLOBxRoT9HR5WCmm5qwjkDQ nJ1jPV7vXByASy26RdVGKggG0U/OIHw/BMJp/iluvukn/np6bHV/sY/Il1KFwzVT tOhp9876oUiqNkE3w32fP9yz3X66c7WUiWyxsRXHSNEvpyjVbcPeopPagNWLXQ8Q RzZwohA4PleO -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/first-keyusage-and-timestamping.pem000066400000000000000000000060641445061461400301560ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 14 (0xe) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 14:36:13 2014 GMT Not After : Jun 4 14:36:13 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=ext.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Extended Key Usage: Time Stamping X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A Signature Algorithm: sha1WithRSAEncryption aa:94:49:20:a4:23:a8:ff:c1:0f:0c:18:e4:23:c9:04:ed:b6: 2f:f5:6f:8a:89:4b:37:ca:18:e7:8b:27:d9:7a:fa:9b:fe:d9: 5f:f1:00:2b:bc:f7:cd:32:b8:00:8b:37:4d:c1:6f:20:08:b7: 68:76:fe:39:d8:cd:e1:3c:cb:fe:c6:e8:6e:e2:39:08:d9:fa: 47:01:82:ab:84:56:fa:48:a8:f6:dc:a5:dd:18:34:35:d4:60: b0:50:22:3a:da:38:64:bd:9b:c5:55:e2:75:41:82:13:bd:5f: b8:36:dc:21:d6:1c:a1:63:c0:c6:2f:c5:4c:4f:18:6d:6e:36: 3b:5b -----BEGIN CERTIFICATE----- MIICizCCAfSgAwIBAgIBDjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzE0MzYxM1oXDTI0MDYwNDE0MzYxM1owXjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAwwOZXh0LmZvb2Jhci5jb20wgZ8wDQYJKoZI hvcNAQEBBQADgY0AMIGJAoGBAOQT5/CXh2Jf4sx5slV318K4udNRuXJvFRO1lOdU jsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23lMMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9 NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKMLwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/ Hn93AgMBAAGjcjBwMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMBMGA1UdJQQM MAoGCCsGAQUFBwMIMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7KBTAfBgNV HSMEGDAWgBSfcxBhQhFNgsrw/zfpF8MgyNseSjANBgkqhkiG9w0BAQUFAAOBgQCq lEkgpCOo/8EPDBjkI8kE7bYv9W+KiUs3yhjniyfZevqb/tlf8QArvPfNMrgAizdN wW8gCLdodv452M3hPMv+xuhu4jkI2fpHAYKrhFb6SKj23KXdGDQ11GCwUCI62jhk vZvFVeJ1QYITvV+4Ntwh1hyhY8DGL8VMTxhtbjY7Ww== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/first-keyusage-any.pem000066400000000000000000000061241445061461400255010ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 15 (0xf) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 14:38:14 2014 GMT Not After : Jun 4 14:38:14 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=any.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Extended Key Usage: Any Extended Key Usage, Time Stamping X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A Signature Algorithm: sha1WithRSAEncryption 91:08:7d:2c:a4:b7:85:af:62:c8:21:96:8a:1d:1f:81:fa:a4: 67:d4:2b:78:62:44:e6:83:c8:a4:3c:fd:64:f0:b9:fa:bd:c4: 99:a4:dd:82:f0:8a:75:8f:d1:4b:dd:f7:d3:1b:79:4f:d4:2d: 16:b1:86:23:54:93:7f:3e:99:b5:4f:f3:e4:fe:6a:76:21:d4: b0:d5:62:2d:de:63:a2:3a:c7:ae:f3:6d:68:c6:fe:a9:2f:e4: ef:36:85:42:85:f3:d3:0e:61:44:53:70:93:d0:b2:d4:06:f2: d7:96:e8:e1:b4:8d:9f:46:a5:a4:0b:08:20:41:8a:ee:04:c8: 63:4d -----BEGIN CERTIFICATE----- MIICkTCCAfqgAwIBAgIBDzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzE0MzgxNFoXDTI0MDYwNDE0MzgxNFowXjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAwwOYW55LmZvb2Jhci5jb20wgZ8wDQYJKoZI hvcNAQEBBQADgY0AMIGJAoGBAOQT5/CXh2Jf4sx5slV318K4udNRuXJvFRO1lOdU jsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23lMMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9 NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKMLwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/ Hn93AgMBAAGjeDB2MAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgXgMBkGA1UdJQQS MBAGBFUdJQAGCCsGAQUFBwMIMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7K BTAfBgNVHSMEGDAWgBSfcxBhQhFNgsrw/zfpF8MgyNseSjANBgkqhkiG9w0BAQUF AAOBgQCRCH0spLeFr2LIIZaKHR+B+qRn1Ct4YkTmg8ikPP1k8Ln6vcSZpN2C8Ip1 j9FL3ffTG3lP1C0WsYYjVJN/Ppm1T/Pk/mp2IdSw1WIt3mOiOseu821oxv6pL+Tv NoVChfPTDmFEU3CT0LLUBvLXlujhtI2fRqWkCwggQYruBMhjTQ== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/first-keyusage-nonrep.pem000066400000000000000000000056401445061461400262150ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 7 (0x7) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 6 17:24:10 2014 GMT Not After : Jun 3 17:24:10 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=key.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Non Repudiation X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A Signature Algorithm: sha1WithRSAEncryption 7b:67:67:33:93:3a:16:9b:1b:93:71:3c:0b:90:0c:ba:37:cd: 53:c7:84:94:6b:c8:ea:6c:3a:c8:da:70:e8:1f:ec:ab:9e:fe: 4f:f4:69:8d:e4:c0:82:fc:48:9e:f3:a3:a0:91:d7:ef:a0:ac: 80:38:f5:84:b9:5f:29:9a:57:9c:e3:be:ba:6e:3a:fa:59:89: cc:c2:36:5f:5a:c0:83:3d:48:3c:3f:51:55:f3:ae:2e:64:40: 06:8d:de:87:a0:08:33:4f:85:f3:ec:92:f2:eb:a8:0a:5b:94: 56:a6:23:9a:5f:02:4c:01:9a:d7:f3:5c:67:2c:81:4a:2c:ca: ae:14 -----BEGIN CERTIFICATE----- MIICczCCAdygAwIBAgIBBzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNjE3MjQxMFoXDTI0MDYwMzE3MjQxMFowXjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAwwOa2V5LmZvb2Jhci5jb20wgZ8wDQYJKoZI hvcNAQEBBQADgY0AMIGJAoGBAOQT5/CXh2Jf4sx5slV318K4udNRuXJvFRO1lOdU jsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23lMMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9 NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKMLwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/ Hn93AgMBAAGjWjBYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgZAMB0GA1UdDgQWBBRK 9+jrVxurSUEj6AJkI4MjFw7KBTAfBgNVHSMEGDAWgBSfcxBhQhFNgsrw/zfpF8Mg yNseSjANBgkqhkiG9w0BAQUFAAOBgQB7Z2czkzoWmxuTcTwLkAy6N81Tx4SUa8jq bDrI2nDoH+yrnv5P9GmN5MCC/Eie86OgkdfvoKyAOPWEuV8pmlec4766bjr6WYnM wjZfWsCDPUg8P1FV864uZEAGjd6HoAgzT4Xz7JLy66gKW5RWpiOaXwJMAZrX81xn LIFKLMquFA== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/first-unknown-critical-extension.pem000066400000000000000000000063021445061461400303760ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 2 (0x2) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 6 17:16:32 2014 GMT Not After : Jun 3 17:16:32 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=blafasel.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Subject Alternative Name: DNS:foo.foobar.com, DNS:foobar.com 1.2.3.4: critical ..Some random data Signature Algorithm: sha1WithRSAEncryption 59:43:8c:77:b5:d8:ad:98:b3:2c:e3:47:60:5b:b0:a6:b4:b5: 1a:22:b2:16:15:d0:2d:6f:9a:a0:2b:f3:45:c8:77:9c:dd:e1: 82:1d:55:9d:be:ff:53:45:2b:82:d1:ca:fd:a8:7f:6a:2d:47: b2:79:bc:70:e8:48:8e:48:3a:5f:0b:d9:ee:40:be:87:77:5e: 0e:69:45:ff:8e:06:b1:b5:87:eb:da:ea:26:d7:7d:e5:b3:d6: e3:4d:db:53:53:dd:5d:3f:7e:6b:98:a6:bd:db:79:35:f1:13: b4:1b:e1:8a:9c:84:f9:32:20:31:60:27:8d:e4:1c:c3:f9:dd: 6d:56 -----BEGIN CERTIFICATE----- MIICuDCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNjE3MTYzMloXDTI0MDYwMzE3MTYzMlowXDELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDEVMBMGA1UEAwwMYmxhZmFzZWwuY29tMIGfMA0GCSqGSIb3 DQEBAQUAA4GNADCBiQKBgQDkE+fwl4diX+LMebJVd9fCuLnTUblybxUTtZTnVI7B GDds2AuQWqRdpQ5CdE5+rek0N6dt5TDGQXv4helhhMzYgPJ/r24ivCzOJx9K/Ta8 HJ31X+m0lg+IMY+nbThUqH4sHBxyjC8LCnFv0tXGrOng6X5yRkOgAGAzYtd6/x5/ dwIDAQABo4GgMIGdMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK 9+jrVxurSUEj6AJkI4MjFw7KBTAfBgNVHSMEGDAWgBSfcxBhQhFNgsrw/zfpF8Mg yNseSjAlBgNVHREEHjAcgg5mb28uZm9vYmFyLmNvbYIKZm9vYmFyLmNvbTAcBgMq AwQBAf8EEgwQU29tZSByYW5kb20gZGF0YTANBgkqhkiG9w0BAQUFAAOBgQBZQ4x3 tditmLMs40dgW7CmtLUaIrIWFdAtb5qgK/NFyHec3eGCHVWdvv9TRSuC0cr9qH9q LUeyebxw6EiOSDpfC9nuQL6Hd14OaUX/jgaxtYfr2uom133ls9bjTdtTU91dP35r mKa923k18RO0G+GKnIT5MiAxYCeN5BzD+d1tVg== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/first-unknown-extension.pem000066400000000000000000000060261445061461400266110ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 3 (0x3) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 6 17:20:25 2014 GMT Not After : Jun 3 17:20:25 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A 1.2.3.4: ..Some random data Signature Algorithm: sha1WithRSAEncryption b7:2d:23:88:43:67:46:46:61:df:b8:04:cc:db:54:71:2a:56: 37:47:13:78:9e:c6:7f:ee:4a:3e:be:41:c9:74:ac:ea:14:e7: ff:20:4e:92:72:96:e7:72:a2:65:af:ee:6c:d0:d3:d6:f4:24: 38:e7:e9:b2:ff:40:3e:a1:9b:51:41:b2:2a:55:66:56:c0:fb: 43:cf:94:7f:b7:d4:0f:9b:61:8b:48:31:f5:49:11:c0:77:af: a0:6e:57:5c:43:fb:e4:15:90:f2:e3:83:9b:e3:fb:7b:5f:8d: 88:bc:ce:ab:f3:8f:a6:c6:d8:57:04:65:04:2b:cc:8c:98:9d: a1:9a -----BEGIN CERTIFICATE----- MIICijCCAfOgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNjE3MjAyNVoXDTI0MDYwMzE3MjAyNVowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKZm9vYmFyLmNvbTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEA5BPn8JeHYl/izHmyVXfXwri501G5cm8VE7WU51SOwRg3 bNgLkFqkXaUOQnROfq3pNDenbeUwxkF7+IXpYYTM2IDyf69uIrwszicfSv02vByd 9V/ptJYPiDGPp204VKh+LBwccowvCwpxb9LVxqzp4Ol+ckZDoABgM2LXev8ef3cC AwEAAaN1MHMwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFEr36OtX G6tJQSPoAmQjgyMXDsoFMB8GA1UdIwQYMBaAFJ9zEGFCEU2CyvD/N+kXwyDI2x5K MBkGAyoDBAQSDBBTb21lIHJhbmRvbSBkYXRhMA0GCSqGSIb3DQEBBQUAA4GBALct I4hDZ0ZGYd+4BMzbVHEqVjdHE3iexn/uSj6+Qcl0rOoU5/8gTpJyludyomWv7mzQ 09b0JDjn6bL/QD6hm1FBsipVZlbA+0PPlH+31A+bYYtIMfVJEcB3r6BuV1xD++QV kPLjg5vj+3tfjYi8zqvzj6bG2FcEZQQrzIyYnaGa -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/first-wildcard-subjaltname.pem000066400000000000000000000060641445061461400271760ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 5 (0x5) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 6 17:21:48 2014 GMT Not After : Jun 3 17:21:48 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=www.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Subject Alternative Name: DNS:*.foobar.com Signature Algorithm: sha1WithRSAEncryption be:5b:6d:d0:3d:c6:8c:1c:9f:ae:dc:2e:ca:78:8a:55:dd:01: 34:62:2d:9c:2b:ae:ac:68:5d:97:2d:8c:5e:f8:44:2d:89:f9: 84:79:94:67:75:13:f1:b4:fa:f2:21:ab:e3:59:15:a4:1c:0e: 9b:17:51:e4:b0:98:22:d9:33:c1:ef:06:88:f5:f4:78:76:92: c2:e0:99:ff:d7:24:ef:26:a7:33:8c:1e:7c:56:8b:b5:3a:93: 6c:3e:00:cb:b6:db:4c:51:5d:9c:0d:94:7f:0f:79:e6:d0:dc: 1b:18:ab:b1:74:6d:b1:72:76:fb:e8:89:00:d1:f7:99:cb:e3: d8:77 -----BEGIN CERTIFICATE----- MIICjDCCAfWgAwIBAgIBBTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNjE3MjE0OFoXDTI0MDYwMzE3MjE0OFowXjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAwwOd3d3LmZvb2Jhci5jb20wgZ8wDQYJKoZI hvcNAQEBBQADgY0AMIGJAoGBAOQT5/CXh2Jf4sx5slV318K4udNRuXJvFRO1lOdU jsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23lMMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9 NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKMLwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/ Hn93AgMBAAGjczBxMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK 9+jrVxurSUEj6AJkI4MjFw7KBTAfBgNVHSMEGDAWgBSfcxBhQhFNgsrw/zfpF8Mg yNseSjAXBgNVHREEEDAOggwqLmZvb2Jhci5jb20wDQYJKoZIhvcNAQEFBQADgYEA vltt0D3GjByfrtwuyniKVd0BNGItnCuurGhdly2MXvhELYn5hHmUZ3UT8bT68iGr 41kVpBwOmxdR5LCYItkzwe8GiPX0eHaSwuCZ/9ck7yanM4wefFaLtTqTbD4Ay7bb TFFdnA2Ufw955tDcGxirsXRtsXJ2++iJANH3mcvj2Hc= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/first-wildcard.pem000066400000000000000000000056771445061461400247040ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 4 (0x4) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 6 17:21:03 2014 GMT Not After : Jun 3 17:21:03 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=*.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A Signature Algorithm: sha1WithRSAEncryption 68:c1:17:fa:0c:e4:04:cd:2b:19:ea:e7:a6:02:27:73:f2:e2: 54:b9:6c:8d:2f:06:be:a5:82:83:41:37:ae:f2:5c:cf:62:a0: 2a:79:37:7c:79:6c:cc:9f:f0:64:a9:8a:1b:93:62:f9:c2:08: 88:e2:73:77:77:73:f7:3f:9e:d6:b1:2c:56:65:a7:cb:10:b9: 79:7b:c6:4b:56:8e:08:d7:51:59:f0:47:6f:fd:b9:32:b0:b8: 69:f1:74:97:a9:9b:11:5a:86:03:14:2a:3b:a7:11:cb:0c:02: 67:dd:45:db:5d:a3:d0:8a:41:2c:13:3f:7f:37:24:2f:49:d4: 07:c1 -----BEGIN CERTIFICATE----- MIICcTCCAdqgAwIBAgIBBDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNjE3MjEwM1oXDTI0MDYwMzE3MjEwM1owXDELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDEVMBMGA1UEAwwMKi5mb29iYXIuY29tMIGfMA0GCSqGSIb3 DQEBAQUAA4GNADCBiQKBgQDkE+fwl4diX+LMebJVd9fCuLnTUblybxUTtZTnVI7B GDds2AuQWqRdpQ5CdE5+rek0N6dt5TDGQXv4helhhMzYgPJ/r24ivCzOJx9K/Ta8 HJ31X+m0lg+IMY+nbThUqH4sHBxyjC8LCnFv0tXGrOng6X5yRkOgAGAzYtd6/x5/ dwIDAQABo1owWDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHQ4EFgQUSvfo 61cbq0lBI+gCZCODIxcOygUwHwYDVR0jBBgwFoAUn3MQYUIRTYLK8P836RfDIMjb HkowDQYJKoZIhvcNAQEFBQADgYEAaMEX+gzkBM0rGernpgInc/LiVLlsjS8GvqWC g0E3rvJcz2KgKnk3fHlszJ/wZKmKG5Ni+cIIiOJzd3dz9z+e1rEsVmWnyxC5eXvG S1aOCNdRWfBHb/25MrC4afF0l6mbEVqGAxQqO6cRywwCZ91F212j0IpBLBM/fzck L0nUB8E= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/first/first.pem000066400000000000000000000061321445061461400231000ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 6 17:11:44 2014 GMT Not After : Jun 3 17:11:44 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=bar.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Subject Alternative Name: DNS:foo.foobar.com, DNS:foobar.com Signature Algorithm: sha1WithRSAEncryption 9c:93:69:c4:94:ac:a3:c5:29:38:48:2f:bb:95:83:a2:62:81: 30:b7:a0:d1:dd:f2:c7:8c:b7:3e:27:54:1e:a7:43:da:18:90: 05:d0:ce:08:7e:26:c9:f9:65:7b:65:ce:33:55:95:47:c8:1d: 4e:bf:0f:64:e9:ae:b1:b8:4a:23:0a:84:15:c2:8d:aa:65:9b: fa:1c:9c:cb:d8:2d:0a:9c:ee:a6:a0:91:1b:0b:a3:61:48:05: 45:e1:1e:22:2e:52:0a:9c:0c:9a:80:cc:d4:8f:20:d2:60:2b: ed:60:7b:51:1c:3d:bc:75:b2:eb:45:67:51:6e:53:24:51:b8: 6f:8e -----BEGIN CERTIFICATE----- MIICmzCCAgSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNjE3MTE0NFoXDTI0MDYwMzE3MTE0NFowXjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAwwOYmFyLmZvb2Jhci5jb20wgZ8wDQYJKoZI hvcNAQEBBQADgY0AMIGJAoGBAOQT5/CXh2Jf4sx5slV318K4udNRuXJvFRO1lOdU jsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23lMMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9 NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKMLwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/ Hn93AgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAdBgNVHQ4EFgQU Svfo61cbq0lBI+gCZCODIxcOygUwHwYDVR0jBBgwFoAUn3MQYUIRTYLK8P836RfD IMjbHkowJQYDVR0RBB4wHIIOZm9vLmZvb2Jhci5jb22CCmZvb2Jhci5jb20wDQYJ KoZIhvcNAQEFBQADgYEAnJNpxJSso8UpOEgvu5WDomKBMLeg0d3yx4y3PidUHqdD 2hiQBdDOCH4myflle2XOM1WVR8gdTr8PZOmusbhKIwqEFcKNqmWb+hycy9gtCpzu pqCRGwujYUgFReEeIi5SCpwMmoDM1I8g0mAr7WB7URw9vHWy60VnUW5TJFG4b44= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/000077500000000000000000000000001445061461400225675ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert-any-ext.pem000066400000000000000000000060271445061461400261230ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 19 (0x13) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 15:06:35 2014 GMT Not After : Jun 4 15:06:35 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: Certificate Sign, CRL Sign X509v3 Extended Key Usage: Any Extended Key Usage Signature Algorithm: sha1WithRSAEncryption 5b:69:22:ab:5a:ae:15:d8:a3:35:ff:66:fc:c8:44:25:a3:c2: 32:26:b2:b8:68:29:30:97:52:a1:31:1f:86:e0:97:6c:00:98: 75:1f:e8:3d:66:bd:9f:7f:51:e8:3f:d0:28:10:1c:0a:0b:3b: 8a:69:a8:30:c9:14:22:92:fa:09:bb:04:ab:15:6b:6e:89:14: 63:26:7b:e3:6d:3d:f3:94:f3:16:9d:25:7f:d6:70:af:fa:99: f4:a4:38:1e:47:69:87:e1:5c:80:b7:0f:34:36:e2:ba:35:c3: f0:c3:02:90:16:b5:be:22:84:6e:1e:83:8c:91:55:62:40:23: 71:c5 -----BEGIN CERTIFICATE----- MIIChjCCAe+gAwIBAgIBEzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzE1MDYzNVoXDTI0MDYwNDE1MDYzNVowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAAaNxMG8wHQYDVR0OBBYEFHBGSRvCcS7AUNNLGFiKxBAcrrNZMB8GA1UdIwQY MBaAFJ9zEGFCEU2CyvD/N+kXwyDI2x5KMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0P BAQDAgEGMA8GA1UdJQQIMAYGBFUdJQAwDQYJKoZIhvcNAQEFBQADgYEAW2kiq1qu FdijNf9m/MhEJaPCMiayuGgpMJdSoTEfhuCXbACYdR/oPWa9n39R6D/QKBAcCgs7 immoMMkUIpL6CbsEqxVrbokUYyZ7420985TzFp0lf9Zwr/qZ9KQ4Hkdph+FcgLcP NDbiujXD8MMCkBa1viKEbh6DjJFVYkAjccU= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert-ba-false.pem000066400000000000000000000056551445061461400262160ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 16 (0x10) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 15:04:42 2014 GMT Not After : Jun 4 15:04:42 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Certificate Sign, CRL Sign Signature Algorithm: sha1WithRSAEncryption 5a:fb:c5:0a:22:3d:76:de:b6:3a:85:06:9f:dc:97:e7:44:2c: 88:c5:4f:6f:3e:f9:31:8f:55:25:28:d0:0f:0c:5d:f9:08:b6: 3e:50:be:5d:ee:d7:bb:47:87:02:d0:a3:73:f4:95:ee:99:d0: 89:07:f7:a7:89:0a:7d:07:3b:a3:75:8a:af:22:23:30:33:2b: 96:b1:8d:59:1b:32:63:e4:6c:99:ef:9c:66:30:9b:e7:36:31: 5d:1e:d8:7e:1b:fa:65:cd:e3:25:28:aa:d6:6a:35:a2:a7:77: 9b:ca:4d:12:0a:91:3a:5b:74:05:7d:57:9c:4d:d0:a0:74:e5: 12:73 -----BEGIN CERTIFICATE----- MIICcjCCAdugAwIBAgIBEDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzE1MDQ0MloXDTI0MDYwNDE1MDQ0MlowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAAaNdMFswHQYDVR0OBBYEFHBGSRvCcS7AUNNLGFiKxBAcrrNZMB8GA1UdIwQY MBaAFJ9zEGFCEU2CyvD/N+kXwyDI2x5KMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQD AgEGMA0GCSqGSIb3DQEBBQUAA4GBAFr7xQoiPXbetjqFBp/cl+dELIjFT28++TGP VSUo0A8MXfkItj5Qvl3u17tHhwLQo3P0le6Z0IkH96eJCn0HO6N1iq8iIzAzK5ax jVkbMmPkbJnvnGYwm+c2MV0e2H4b+mXN4yUoqtZqNaKnd5vKTRIKkTpbdAV9V5xN 0KB05RJz -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert-ku-critical.pem000066400000000000000000000056741445061461400267540ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 22 (0x16) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 20:30:46 2014 GMT Not After : Jun 4 20:30:46 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: critical Certificate Sign, CRL Sign Signature Algorithm: sha1WithRSAEncryption 16:a1:47:40:d9:71:b8:ab:84:8f:f7:da:f3:53:cd:ad:a6:4d: d9:39:32:e9:d5:5c:6d:e3:45:05:00:1e:a3:45:28:c9:a1:c1: 07:0e:3f:52:ba:70:18:4d:ee:89:5a:80:05:af:dd:24:d6:4a: b2:c2:2f:a4:2c:4d:2e:60:86:01:6b:07:8f:70:d8:6a:07:a6: 4a:ce:b0:d0:4b:13:b5:a4:87:ac:ba:45:25:0a:8a:a2:a2:2f: 59:dd:9c:94:d7:0d:1d:e1:23:44:99:d5:63:5b:46:35:e0:87: bb:cb:53:24:89:48:e1:5f:0c:d7:02:e2:15:97:37:b1:dd:0d: 4e:bd -----BEGIN CERTIFICATE----- MIICeDCCAeGgAwIBAgIBFjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzIwMzA0NloXDTI0MDYwNDIwMzA0NlowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAAaNjMGEwHQYDVR0OBBYEFHBGSRvCcS7AUNNLGFiKxBAcrrNZMB8GA1UdIwQY MBaAFJ9zEGFCEU2CyvD/N+kXwyDI2x5KMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4GBABahR0DZcbirhI/32vNTza2mTdk5 MunVXG3jRQUAHqNFKMmhwQcOP1K6cBhN7olagAWv3STWSrLCL6QsTS5ghgFrB49w 2GoHpkrOsNBLE7Wkh6y6RSUKiqKiL1ndnJTXDR3hI0SZ1WNbRjXgh7vLUySJSOFf DNcC4hWXN7HdDU69 -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert-no-bc.pem000066400000000000000000000055241445061461400255350ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 21 (0x15) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 20:17:41 2014 GMT Not After : Jun 4 20:17:41 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Key Usage: Certificate Sign, CRL Sign Signature Algorithm: sha1WithRSAEncryption 32:a8:c9:7d:d8:a5:3c:da:f3:58:07:bb:e7:04:e2:fa:db:a3: 85:bd:06:49:fc:ca:a3:87:cb:5b:43:de:b2:8e:fd:c5:3e:35: ea:d7:ab:36:d2:f4:b2:05:41:4b:12:6d:82:9f:98:81:49:ad: 53:a1:d1:72:2e:4e:f3:87:13:c0:b7:4e:1c:a3:b6:66:a1:0d: 36:8a:58:3c:7f:29:46:a8:88:8a:f9:f8:d2:3d:de:31:00:f3: 2c:8e:cd:7b:58:11:39:b9:74:10:38:95:d2:84:71:f5:ee:6f: e4:ed:cd:c6:9a:67:4f:42:d7:ae:4f:9a:ac:22:6c:d3:80:76: 1f:79 -----BEGIN CERTIFICATE----- MIICZDCCAc2gAwIBAgIBFTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzIwMTc0MVoXDTI0MDYwNDIwMTc0MVowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAAaNPME0wHQYDVR0OBBYEFHBGSRvCcS7AUNNLGFiKxBAcrrNZMB8GA1UdIwQY MBaAFJ9zEGFCEU2CyvD/N+kXwyDI2x5KMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B AQUFAAOBgQAyqMl92KU82vNYB7vnBOL626OFvQZJ/Mqjh8tbQ96yjv3FPjXq16s2 0vSyBUFLEm2Cn5iBSa1TodFyLk7zhxPAt04co7ZmoQ02ilg8fylGqIiK+fjSPd4x APMsjs17WBE5uXQQOJXShHH17m/k7c3GmmdPQteuT5qsImzTgHYfeQ== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert-no-keyusage.pem000066400000000000000000000055251445061461400267670ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 18 (0x12) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 15:05:29 2014 GMT Not After : Jun 4 15:05:29 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha1WithRSAEncryption 6e:6c:e2:73:b6:77:9a:a4:14:34:2d:f9:93:3a:4e:0b:26:f7: f0:63:c7:8f:1e:2b:cf:fb:f3:db:6d:e1:13:eb:ec:c6:62:f5: 87:d7:f7:9e:db:55:d2:3f:79:b0:b8:61:5a:2a:c1:2f:e8:b4: f5:7d:55:fa:9b:d9:cd:09:62:d8:84:d7:86:e1:82:a1:c8:da: 41:92:5f:aa:f8:6e:59:b2:7d:d0:0a:f0:44:f6:c8:44:91:7d: 2d:71:59:27:6f:e7:22:0e:65:d5:62:bf:f0:98:53:34:76:16: 1a:61:46:4a:13:a0:db:71:b6:ca:8e:8e:d6:2a:4e:88:e1:8c: 99:8b -----BEGIN CERTIFICATE----- MIICaDCCAdGgAwIBAgIBEjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzE1MDUyOVoXDTI0MDYwNDE1MDUyOVowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAAaNTMFEwHQYDVR0OBBYEFHBGSRvCcS7AUNNLGFiKxBAcrrNZMB8GA1UdIwQY MBaAFJ9zEGFCEU2CyvD/N+kXwyDI2x5KMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI hvcNAQEFBQADgYEAbmzic7Z3mqQUNC35kzpOCyb38GPHjx4rz/vz223hE+vsxmL1 h9f3nttV0j95sLhhWirBL+i09X1V+pvZzQli2ITXhuGCocjaQZJfqvhuWbJ90Arw RPbIRJF9LXFZJ2/nIg5l1WK/8JhTNHYWGmFGShOg23G2yo6O1ipOiOGMmYs= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert-timestamp.pem000066400000000000000000000060221445061461400265340ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 17 (0x11) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 15:05:04 2014 GMT Not After : Jun 4 15:05:04 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: Certificate Sign, CRL Sign X509v3 Extended Key Usage: Time Stamping Signature Algorithm: sha1WithRSAEncryption a4:df:66:b2:ac:06:4d:0a:2d:68:77:8e:a0:cd:10:cb:de:f5: 38:46:99:b8:ee:2e:cb:e0:56:c7:67:4a:8b:a9:28:1b:9d:50: bc:c9:c2:7f:98:45:17:2a:cf:f1:be:2b:bc:e9:03:e8:b7:97: d6:d5:15:d2:87:1f:03:8b:02:b3:8f:62:5d:55:7e:27:4c:c9: a7:bd:ed:5d:e2:c6:fc:d5:d9:88:cc:b0:71:c9:36:61:d7:d8: 28:95:e7:45:e3:7e:e9:d5:5f:af:1f:a0:51:02:34:b9:21:19: b0:7b:d5:c5:8e:72:97:33:cc:96:14:93:ef:b3:95:db:c0:d0: 57:0b -----BEGIN CERTIFICATE----- MIICijCCAfOgAwIBAgIBETANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzE1MDUwNFoXDTI0MDYwNDE1MDUwNFowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAAaN1MHMwHQYDVR0OBBYEFHBGSRvCcS7AUNNLGFiKxBAcrrNZMB8GA1UdIwQY MBaAFJ9zEGFCEU2CyvD/N+kXwyDI2x5KMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0P BAQDAgEGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBBQUAA4GBAKTf ZrKsBk0KLWh3jqDNEMve9ThGmbjuLsvgVsdnSoupKBudULzJwn+YRRcqz/G+K7zp A+i3l9bVFdKHHwOLArOPYl1VfidMyae97V3ixvzV2YjMsHHJNmHX2CiV50XjfunV X68foFECNLkhGbB71cWOcpczzJYUk++zldvA0FcL -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert-unknown.pem000066400000000000000000000060311445061461400262300ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 20 (0x14) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 15:07:08 2014 GMT Not After : Jun 4 15:07:08 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: Certificate Sign, CRL Sign 1.2.3.4: critical ..Some random data Signature Algorithm: sha1WithRSAEncryption 8f:f1:30:c0:f0:33:18:2f:09:bc:cc:70:4b:f5:9a:e5:7c:33: d7:39:5a:af:bc:10:f9:b4:bf:ce:b5:07:67:26:87:b3:31:67: ce:41:a3:23:ba:51:85:10:dd:41:2d:e0:16:a0:a3:d0:0c:89: 92:d0:a8:bc:a9:b2:73:ca:7e:0a:4b:2c:ff:66:f7:61:75:43: f1:07:32:6b:ec:61:76:35:8c:4d:08:e8:18:d4:ce:75:3e:25: 1f:cc:0f:66:a0:c4:25:cb:6a:f1:04:da:ad:e6:e7:0a:62:f4: a5:88:de:ca:70:12:a1:33:05:85:e2:ea:27:97:ac:7d:ef:f8: 0b:9c -----BEGIN CERTIFICATE----- MIICkzCCAfygAwIBAgIBFDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzE1MDcwOFoXDTI0MDYwNDE1MDcwOFowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAAaN+MHwwHQYDVR0OBBYEFHBGSRvCcS7AUNNLGFiKxBAcrrNZMB8GA1UdIwQY MBaAFJ9zEGFCEU2CyvD/N+kXwyDI2x5KMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0P BAQDAgEGMBwGAyoDBAEB/wQSDBBTb21lIHJhbmRvbSBkYXRhMA0GCSqGSIb3DQEB BQUAA4GBAI/xMMDwMxgvCbzMcEv1muV8M9c5Wq+8EPm0v861B2cmh7MxZ85BoyO6 UYUQ3UEt4Bago9AMiZLQqLypsnPKfgpLLP9m92F1Q/EHMmvsYXY1jE0I6BjUznU+ JR/MD2agxCXLavEE2q3m5wpi9KWI3spwEqEzBYXi6ieXrH3v+Auc -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert-v1.pem000066400000000000000000000046111445061461400250610ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 23 (0x17) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 8 07:10:36 2014 GMT Not After : Jun 5 07:10:36 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) Signature Algorithm: sha1WithRSAEncryption ae:5a:77:70:95:f8:37:1e:38:90:3d:ad:ed:23:d9:27:0f:f6: 22:0d:7f:77:59:2d:62:84:97:12:88:10:48:2d:3e:35:1a:00: 65:32:1d:b6:fb:90:3b:f8:01:88:8b:d1:8c:1b:da:d8:19:7a: a3:f2:29:28:c1:a2:f2:2b:a8:42:75:58:d5:4a:69:f0:3f:d4: 70:49:73:6e:3f:6d:3f:ff:c1:dc:0c:90:1c:c4:08:f0:88:4b: 6d:25:ab:db:b8:d4:6b:55:cf:23:28:79:11:c0:31:c9:a6:e9: 85:61:5d:b5:cb:e2:fc:3c:aa:d5:6f:b1:bc:b4:17:7b:89:3f: 9b:48 -----BEGIN CERTIFICATE----- MIICEzCCAXygAwIBAgIBFzANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwODA3MTAzNloXDTI0MDYwNTA3MTAzNlowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAATANBgkqhkiG9w0BAQUFAAOBgQCuWndwlfg3HjiQPa3tI9knD/YiDX93WS1i hJcSiBBILT41GgBlMh22+5A7+AGIi9GMG9rYGXqj8ikowaLyK6hCdVjVSmnwP9Rw SXNuP20//8HcDJAcxAjwiEttJavbuNRrVc8jKHkRwDHJpumFYV21y+L8PKrVb7G8 tBd7iT+bSA== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/cacert.pem000066400000000000000000000056441445061461400245440ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 8 (0x8) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Validity Not Before: Jun 7 14:06:12 2014 GMT Not After : Jun 4 14:06:12 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:ca:53:26:f9:ea:f4:1b:8a:70:c0:8c:17:17:c4: af:69:61:7a:62:8f:79:81:9e:16:9c:22:5c:64:25: fa:b3:be:bd:d1:84:98:7b:06:18:35:92:3a:c6:4b: 77:b4:90:61:6d:e1:6e:e9:bd:0a:72:a7:fb:27:51: ac:c6:43:5f:b9:60:41:a7:af:28:ff:6b:62:6a:ff: 54:16:06:84:48:94:4e:26:fe:bb:2b:f3:b2:8a:be: a2:a1:88:d1:4c:89:8e:29:60:41:9f:16:55:31:55: 86:c0:90:f4:b0:5e:63:7d:18:d8:d9:fb:0a:f3:df: 92:90:b1:78:e6:2e:c8:09:15 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: Certificate Sign X509v3 Subject Key Identifier: 70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Authority Key Identifier: keyid:9F:73:10:61:42:11:4D:82:CA:F0:FF:37:E9:17:C3:20:C8:DB:1E:4A Signature Algorithm: sha1WithRSAEncryption 1d:9e:fa:5f:8f:1e:15:e9:d9:c7:9c:1c:30:0e:78:3c:ac:01: 4b:5c:42:03:e8:01:c3:1c:22:04:f4:ef:6f:f1:55:cc:fc:70: a3:75:ae:98:ea:f2:b6:77:a5:46:14:49:56:85:e7:dd:d7:57: a2:32:12:86:ec:7b:19:4c:d5:76:0b:7c:f5:64:3a:4c:52:b4: 6b:49:15:58:73:f9:21:23:de:dc:1c:6f:fa:d5:0a:93:1b:7d: 68:70:a8:47:2d:41:5f:ea:94:a5:6f:69:8d:f8:2f:40:b1:a5: d2:33:af:6e:32:fe:43:7b:70:73:3e:2b:fa:d7:fa:c7:1e:73: 10:23 -----BEGIN CERTIFICATE----- MIICdTCCAd6gAwIBAgIBCDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMB4XDTE0MDYwNzE0MDYxMloXDTI0MDYwNDE0MDYxMlowWjELMAkGA1UE BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp ZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKc2lnbmluZyBDQTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAylMm+er0G4pwwIwXF8SvaWF6Yo95gZ4WnCJcZCX6s769 0YSYewYYNZI6xkt3tJBhbeFu6b0Kcqf7J1GsxkNfuWBBp68o/2tiav9UFgaESJRO Jv67K/Oyir6ioYjRTImOKWBBnxZVMVWGwJD0sF5jfRjY2fsK89+SkLF45i7ICRUC AwEAAaNgMF4wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQwHQYDVR0OBBYE FHBGSRvCcS7AUNNLGFiKxBAcrrNZMB8GA1UdIwQYMBaAFJ9zEGFCEU2CyvD/N+kX wyDI2x5KMA0GCSqGSIb3DQEBBQUAA4GBAB2e+l+PHhXp2cecHDAOeDysAUtcQgPo AcMcIgT072/xVcz8cKN1rpjq8rZ3pUYUSVaF593XV6IyEobsexlM1XYLfPVkOkxS tGtJFVhz+SEj3twcb/rVCpMbfWhwqEctQV/qlKVvaY34L0CxpdIzr24y/kN7cHM+ K/rX+scecxAj -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/private/000077500000000000000000000000001445061461400242415ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/testcertificates/intermediate/private/cakey.pem000066400000000000000000000015671445061461400260510ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDKUyb56vQbinDAjBcXxK9pYXpij3mBnhacIlxkJfqzvr3RhJh7 Bhg1kjrGS3e0kGFt4W7pvQpyp/snUazGQ1+5YEGnryj/a2Jq/1QWBoRIlE4m/rsr 87KKvqKhiNFMiY4pYEGfFlUxVYbAkPSwXmN9GNjZ+wrz35KQsXjmLsgJFQIDAQAB AoGAJnKix39UoB8wygZVJRklVFtHzI8DQhRuq4EEGav19k5a+APAjjBcTWHadXBF 8TQ2r5DVaOmZoKw3WAN3V73Z5KNy8qG7BUi/c7uMkJAnDfXVRGZU58b+K/ga8AeZ bQ+agYmyo18//EtxHrrcG/bmz/5DEN796npmaDMICrY4X0ECQQD68e9bB93w5/Qk OwCyT1AaJeblVzDfxvMZfG31UPaZLGS9F12yUAiXy/B+6KGKuLcItHz2Rr5MCD7S 1/EtkeEpAkEAzmZ+eJouwxtdLow71eE5fzrT8ZFoEOEMUDHVTAUckUzmtuUVkYCg LmL+2wXf0NsFGw5N7fmAGsc8Ao4XnXQKDQJAL+XP1uM4hIvxeJzedCpZUrRbTvkG diAGNJ4gasuKVhA4JjN4idlm2nptq/uBIfZB0WKJ24QDPIXyX9Ih0Z3fiQJAQ4gv i0BPWpEifO9vSHyntmRGIn0EArnPsJGNi5EEltoFhwQPeYsPXf4QCxOx9oEi+4ZD o0CGVLypeuCJA4CLJQJBAPp2SyfdblsIez+wzzt3e/W6lhBX1BiRgg9pZ7GUwhTN IQ1FKqflqank2Gk/7mcgHDDtNGgQ+ewxjsdAWX/veX0= -----END RSA PRIVATE KEY----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/000077500000000000000000000000001445061461400240425ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-any.pem000066400000000000000000000061471445061461400266150ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 4 (0x4) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 15:12:00 2014 GMT Not After : Jun 4 15:12:00 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Extended Key Usage: Any Extended Key Usage Signature Algorithm: sha1WithRSAEncryption 5f:3b:4b:a3:70:1a:82:3e:9c:bb:cb:16:95:f3:b2:ef:3a:a6: 09:1d:1c:b9:cb:ce:56:82:29:98:41:b8:c5:58:cb:35:27:45: 9d:2e:f5:41:e1:a0:7c:5f:ee:2d:0c:9c:9b:42:31:61:27:fb: 5f:d6:ce:a6:dc:c6:9b:b2:d1:3b:72:1e:b3:f1:20:73:7f:86: 8a:1d:44:c8:d7:bc:f2:92:4a:2c:48:97:b5:12:63:99:f3:90: e5:79:bf:68:fe:11:34:1d:ac:75:80:d2:22:7f:53:2d:70:50: d2:a0:fc:7b:b9:8f:b3:5e:6c:70:b8:55:0b:52:d5:84:b7:7c: 84:9b -----BEGIN CERTIFICATE----- MIICnzCCAgigAwIBAgIBBDANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE1MTIwMFoXDTI0 MDYwNDE1MTIwMFowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjbjBsMAwGA1UdEwEB/wQC MAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7KBTAf BgNVHSMEGDAWgBRwRkkbwnEuwFDTSxhYisQQHK6zWTAPBgNVHSUECDAGBgRVHSUA MA0GCSqGSIb3DQEBBQUAA4GBAF87S6NwGoI+nLvLFpXzsu86pgkdHLnLzlaCKZhB uMVYyzUnRZ0u9UHhoHxf7i0MnJtCMWEn+1/Wzqbcxpuy0TtyHrPxIHN/hoodRMjX vPKSSixIl7USY5nzkOV5v2j+ETQdrHWA0iJ/Uy1wUNKg/Hu5j7NebHC4VQtS1YS3 fISb -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-bc-true.pem000066400000000000000000000060061445061461400273610ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 2 (0x2) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 15:09:33 2014 GMT Not After : Jun 4 15:09:33 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 Signature Algorithm: sha1WithRSAEncryption 5d:9d:36:2b:33:c8:43:c8:78:13:10:c7:a8:7f:ac:60:f6:19: 46:36:24:8b:8e:db:20:00:b5:f8:c7:a5:ac:49:56:a6:e1:e6: dd:fd:07:10:44:2b:aa:42:f5:76:56:81:86:3d:74:53:03:24: e0:9a:6e:d7:e6:3c:d7:31:87:82:2a:72:fc:67:8f:0e:5a:3b: 05:c9:5c:52:61:6d:a0:4d:78:ba:8d:97:a5:4c:e1:a6:07:43: 61:81:c5:94:84:37:47:91:aa:13:b6:57:19:af:57:8d:82:8a: 50:eb:cc:07:76:cb:1b:35:c3:db:98:2d:ab:d6:cf:d2:c3:a8: e5:1b -----BEGIN CERTIFICATE----- MIICkTCCAfqgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE1MDkzM1oXDTI0 MDYwNDE1MDkzM1owYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjYDBeMA8GA1UdEwEB/wQF MAMBAf8wCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7K BTAfBgNVHSMEGDAWgBRwRkkbwnEuwFDTSxhYisQQHK6zWTANBgkqhkiG9w0BAQUF AAOBgQBdnTYrM8hDyHgTEMeof6xg9hlGNiSLjtsgALX4x6WsSVam4ebd/QcQRCuq QvV2VoGGPXRTAyTgmm7X5jzXMYeCKnL8Z48OWjsFyVxSYW2gTXi6jZelTOGmB0Nh gcWUhDdHkaoTtlcZr1eNgopQ68wHdssbNcPbmC2r1s/Sw6jlGw== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-no-cn.pem000066400000000000000000000057061445061461400270400ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 10 (0xa) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 20:19:45 2014 GMT Not After : Jun 4 20:19:45 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 Signature Algorithm: sha1WithRSAEncryption 86:ff:aa:35:31:07:ab:76:8d:44:3a:a6:63:40:ce:ac:13:56: c0:90:12:e1:23:af:0d:b9:16:88:48:7b:a1:00:85:6c:b8:32: 4d:ed:04:dc:32:05:e9:27:77:e1:1b:16:0b:8e:dc:23:fb:cd: fc:c7:63:27:35:bd:69:4d:45:ae:ab:b9:06:bb:a1:5e:b5:7e: 89:72:cc:fe:3e:90:3c:09:bc:e1:1c:b0:bf:c6:d2:40:61:a7: d6:20:9b:cd:e9:f5:d6:09:f3:1e:ee:6b:6e:d2:31:6e:0d:15: 8d:dd:9d:f7:8e:d9:96:df:42:7e:e2:0f:0d:37:f4:a8:ef:79: c1:88 -----BEGIN CERTIFICATE----- MIICcjCCAdugAwIBAgIBCjANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzIwMTk0NVoXDTI0 MDYwNDIwMTk0NVowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEA5BPn8JeHYl/izHmyVXfXwri501G5cm8VE7WU51SOwRg3 bNgLkFqkXaUOQnROfq3pNDenbeUwxkF7+IXpYYTM2IDyf69uIrwszicfSv02vByd 9V/ptJYPiDGPp204VKh+LBwccowvCwpxb9LVxqzp4Ol+ckZDoABgM2LXev8ef3cC AwEAAaNdMFswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFEr3 6OtXG6tJQSPoAmQjgyMXDsoFMB8GA1UdIwQYMBaAFHBGSRvCcS7AUNNLGFiKxBAc rrNZMA0GCSqGSIb3DQEBBQUAA4GBAIb/qjUxB6t2jUQ6pmNAzqwTVsCQEuEjrw25 FohIe6EAhWy4Mk3tBNwyBeknd+EbFguO3CP7zfzHYyc1vWlNRa6ruQa7oV61foly zP4+kDwJvOEcsL/G0kBhp9Ygm83p9dYJ8x7ua27SMW4NFY3dnfeO2ZbfQn7iDw03 9KjvecGI -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-nonrepud.pem000066400000000000000000000057361445061461400276630ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 5 (0x5) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 15:12:35 2014 GMT Not After : Jun 4 15:12:35 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Non Repudiation X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 Signature Algorithm: sha1WithRSAEncryption a4:9d:d9:79:78:68:e8:e3:2f:ac:3b:25:6c:f3:05:8d:ab:08: 3a:ff:a9:85:4e:c2:77:df:38:56:50:d3:7a:77:1f:fd:53:f6: eb:f0:43:2f:39:61:d0:f6:1b:c8:3b:30:a4:53:c2:a4:eb:02: 02:ec:11:ee:d6:4c:e9:d5:25:2e:15:ce:e3:c5:9a:04:e3:00: 45:34:c5:26:69:b4:89:51:fa:41:f5:0a:5e:60:23:b7:ef:f7: 3e:c9:7a:94:57:31:b1:86:58:31:34:df:25:56:03:a2:3e:c9: 3f:db:43:58:39:c7:1a:a5:1f:d8:49:cc:09:96:da:0b:e7:21: b6:06 -----BEGIN CERTIFICATE----- MIICjjCCAfegAwIBAgIBBTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE1MTIzNVoXDTI0 MDYwNDE1MTIzNVowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjXTBbMAwGA1UdEwEB/wQC MAAwCwYDVR0PBAQDAgZAMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7KBTAf BgNVHSMEGDAWgBRwRkkbwnEuwFDTSxhYisQQHK6zWTANBgkqhkiG9w0BAQUFAAOB gQCkndl5eGjo4y+sOyVs8wWNqwg6/6mFTsJ33zhWUNN6dx/9U/br8EMvOWHQ9hvI OzCkU8Kk6wIC7BHu1kzp1SUuFc7jxZoE4wBFNMUmabSJUfpB9QpeYCO37/c+yXqU VzGxhlgxNN8lVgOiPsk/20NYOccapR/YScwJltoL5yG2Bg== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-subj-wild.pem000066400000000000000000000062371445061461400277260ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 9 (0x9) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 15:15:26 2014 GMT Not After : Jun 4 15:15:26 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Subject Alternative Name: DNS:*.foobar.com, DNS:foo.foobar.com Signature Algorithm: sha1WithRSAEncryption c8:c4:d0:4a:98:c8:d1:92:54:da:e0:a8:71:05:4e:76:e0:51: 5f:5f:c0:3f:38:9d:d4:d2:ea:68:c1:61:4c:67:74:22:19:54: a1:1d:cf:2a:41:69:2a:2b:82:e8:f6:ca:54:4f:c2:bd:5a:0e: f0:e1:c8:12:5f:9a:75:c0:d2:23:66:ea:dd:a7:2f:a6:7e:ae: 38:7e:14:2a:f4:d1:90:26:91:cb:0a:9a:5d:de:d6:25:bd:97: 34:c0:4f:8e:3b:3c:fc:7b:ee:c7:6c:6f:80:e6:a9:4f:6d:87: 94:d8:6d:cf:be:92:5b:7e:23:e5:eb:55:cb:5c:9b:27:bf:78: ce:0d -----BEGIN CERTIFICATE----- MIICuTCCAiKgAwIBAgIBCTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE1MTUyNloXDTI0 MDYwNDE1MTUyNlowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjgYcwgYQwDAYDVR0TAQH/ BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFEr36OtXG6tJQSPoAmQjgyMXDsoF MB8GA1UdIwQYMBaAFHBGSRvCcS7AUNNLGFiKxBAcrrNZMCcGA1UdEQQgMB6CDCou Zm9vYmFyLmNvbYIOZm9vLmZvb2Jhci5jb20wDQYJKoZIhvcNAQEFBQADgYEAyMTQ SpjI0ZJU2uCocQVOduBRX1/APzid1NLqaMFhTGd0IhlUoR3PKkFpKiuC6PbKVE/C vVoO8OHIEl+adcDSI2bq3acvpn6uOH4UKvTRkCaRywqaXd7WJb2XNMBPjjs8/Hvu x2xvgOapT22HlNhtz76SW34j5etVy1ybJ794zg0= -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-subj.pem000066400000000000000000000062311445061461400267630ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 8 (0x8) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 15:15:01 2014 GMT Not After : Jun 4 15:15:01 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Subject Alternative Name: DNS:foobar.com, DNS:foo.foobar.com Signature Algorithm: sha1WithRSAEncryption 77:a1:83:7f:ed:4f:5c:a5:86:55:11:2a:6e:89:0c:07:be:0e: 1e:5a:b8:94:7f:0d:74:ef:e1:b4:e4:72:68:96:95:2b:00:a2: 29:a2:4e:16:cd:e8:04:fc:e7:ac:73:04:9a:fc:2a:5d:c2:59: aa:92:0f:7c:fb:25:39:f9:b9:ed:d2:1a:04:93:8f:e0:d2:41: eb:81:8d:c6:89:b0:54:de:1d:24:e6:6d:3b:a7:e2:80:61:32: 98:22:4d:a1:fb:61:5c:ed:15:87:ba:26:5e:91:53:54:47:a9: 76:b8:4b:bb:00:53:5b:c6:3c:8c:a4:80:d0:13:fa:b0:3c:d4: 0f:44 -----BEGIN CERTIFICATE----- MIICtzCCAiCgAwIBAgIBCDANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE1MTUwMVoXDTI0 MDYwNDE1MTUwMVowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjgYUwgYIwDAYDVR0TAQH/ BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0OBBYEFEr36OtXG6tJQSPoAmQjgyMXDsoF MB8GA1UdIwQYMBaAFHBGSRvCcS7AUNNLGFiKxBAcrrNZMCUGA1UdEQQeMByCCmZv b2Jhci5jb22CDmZvby5mb29iYXIuY29tMA0GCSqGSIb3DQEBBQUAA4GBAHehg3/t T1ylhlURKm6JDAe+Dh5auJR/DXTv4bTkcmiWlSsAoimiThbN6AT856xzBJr8Kl3C WaqSD3z7JTn5ue3SGgSTj+DSQeuBjcaJsFTeHSTmbTun4oBhMpgiTaH7YVztFYe6 Jl6RU1RHqXa4S7sAU1vGPIykgNAT+rA81A9E -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-subjaltemail.pem000066400000000000000000000061601445061461400304750ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 11 (0xb) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 20:27:58 2014 GMT Not After : Jun 4 20:27:58 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Subject Alternative Name: email:foobar.com Signature Algorithm: sha1WithRSAEncryption 37:e6:be:0f:75:4a:b8:c2:e1:7f:e2:70:31:41:12:41:cc:05: 72:8f:ce:8c:2c:c2:1e:78:03:bb:61:f5:9a:76:cf:36:bb:66: cf:4c:f1:33:ba:9d:a7:7e:20:92:7c:bb:9c:01:53:ba:c9:13: 2c:6e:c4:bf:04:ee:76:bc:eb:d3:87:e8:05:5c:62:f1:0e:7c: 51:12:25:c8:4f:e6:8e:46:c1:15:2a:55:fb:e4:8a:e3:04:7f: 9f:86:1d:03:e1:25:b4:6b:9a:bd:b6:02:ba:07:d4:82:04:06: fb:fd:7d:9b:7b:37:96:f2:04:0e:a4:f3:43:6c:9a:f1:fb:1f: 4b:bc -----BEGIN CERTIFICATE----- MIICpTCCAg6gAwIBAgIBCzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzIwMjc1OFoXDTI0 MDYwNDIwMjc1OFowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjdDByMAwGA1UdEwEB/wQC MAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7KBTAf BgNVHSMEGDAWgBRwRkkbwnEuwFDTSxhYisQQHK6zWTAVBgNVHREEDjAMgQpmb29i YXIuY29tMA0GCSqGSIb3DQEBBQUAA4GBADfmvg91SrjC4X/icDFBEkHMBXKPzows wh54A7th9Zp2zza7Zs9M8TO6nad+IJJ8u5wBU7rJEyxuxL8E7na869OH6AVcYvEO fFESJchP5o5GwRUqVfvkiuMEf5+GHQPhJbRrmr22AroH1IIEBvv9fZt7N5byBA6k 80NsmvH7H0u8 -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-time.pem000066400000000000000000000061461445061461400267630ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 3 (0x3) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 15:11:22 2014 GMT Not After : Jun 4 15:11:22 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 X509v3 Extended Key Usage: Time Stamping Signature Algorithm: sha1WithRSAEncryption 2e:95:20:c3:be:29:0f:f7:3c:eb:e3:02:e1:11:18:21:88:6f: 16:d8:e1:04:4b:d8:56:80:4f:e2:78:c0:35:10:b4:0f:11:0d: 3d:96:0a:77:aa:56:be:27:7c:53:4c:c4:e7:f2:42:9a:3f:c0: e5:8c:5e:9b:ff:c9:c2:13:d1:57:4a:9c:53:86:c2:c7:04:fa: 0b:8d:ac:52:0a:d8:e3:5d:d5:a6:f3:c0:67:db:de:43:0b:fd: 21:2a:7d:67:bd:de:f5:48:5a:f3:a5:d4:ed:18:4a:37:f9:c4: 6f:6e:7c:ff:b4:4e:db:5a:7b:6d:92:79:68:5d:ce:74:a0:b9: 96:38 -----BEGIN CERTIFICATE----- MIICozCCAgygAwIBAgIBAzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE1MTEyMloXDTI0 MDYwNDE1MTEyMlowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjcjBwMAwGA1UdEwEB/wQC MAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7KBTAf BgNVHSMEGDAWgBRwRkkbwnEuwFDTSxhYisQQHK6zWTATBgNVHSUEDDAKBggrBgEF BQcDCDANBgkqhkiG9w0BAQUFAAOBgQAulSDDvikP9zzr4wLhERghiG8W2OEES9hW gE/ieMA1ELQPEQ09lgp3qla+J3xTTMTn8kKaP8DljF6b/8nCE9FXSpxThsLHBPoL jaxSCtjjXdWm88Bn295DC/0hKn1nvd71SFrzpdTtGEo3+cRvbnz/tE7bWnttknlo Xc50oLmWOA== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-unknown-noncrit.pem000066400000000000000000000061411445061461400311710ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 7 (0x7) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 15:14:08 2014 GMT Not After : Jun 4 15:14:08 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 1.2.3.4: ..Some random data Signature Algorithm: sha1WithRSAEncryption ad:f0:9c:da:6a:61:bd:5f:bd:bb:43:4c:c9:31:ca:07:6c:b0: 49:1f:9d:f0:72:b7:58:f8:91:a3:c5:d3:9a:46:c7:c7:ad:50: 7f:2c:05:c0:e2:ba:82:a7:22:2b:33:3a:60:87:dd:c7:18:01: 52:13:c4:da:63:88:65:cf:a2:a2:db:7f:83:85:11:94:12:82: d2:d5:91:01:40:7c:9b:8a:a7:33:e7:e0:ab:39:de:b6:ee:56: 49:50:f8:b5:e7:f0:50:3e:96:e1:ea:5d:5b:00:26:c3:1b:13: bc:12:da:35:b7:33:f0:cc:bc:ca:b1:1a:79:69:b3:34:22:35: 31:7f -----BEGIN CERTIFICATE----- MIICqTCCAhKgAwIBAgIBBzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE1MTQwOFoXDTI0 MDYwNDE1MTQwOFowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjeDB2MAwGA1UdEwEB/wQC MAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7KBTAf BgNVHSMEGDAWgBRwRkkbwnEuwFDTSxhYisQQHK6zWTAZBgMqAwQEEgwQU29tZSBy YW5kb20gZGF0YTANBgkqhkiG9w0BAQUFAAOBgQCt8JzaamG9X727Q0zJMcoHbLBJ H53wcrdY+JGjxdOaRsfHrVB/LAXA4rqCpyIrMzpgh93HGAFSE8TaY4hlz6Ki23+D hRGUEoLS1ZEBQHybiqcz5+CrOd627lZJUPi15/BQPpbh6l1bACbDGxO8Eto1tzPw zLzKsRp5abM0IjUxfw== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second-unknown.pem000066400000000000000000000061551445061461400275240ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 6 (0x6) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 15:13:35 2014 GMT Not After : Jun 4 15:13:35 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 1.2.3.4: critical ..Some random data Signature Algorithm: sha1WithRSAEncryption 22:43:ed:d2:8f:20:da:b4:31:1d:54:54:80:d4:b7:3b:c8:db: 81:30:1b:29:c3:e7:76:6c:7c:c1:1d:86:97:d7:98:99:e7:99: 87:25:11:30:9e:63:e2:4e:b2:a3:c9:97:aa:b0:a6:9c:73:76: c3:a0:15:b2:05:3e:3f:92:38:aa:62:26:78:56:85:c0:bb:1e: 39:fa:f7:c8:40:25:9c:f9:c0:ce:70:b9:8a:b0:56:35:f7:54: 91:b5:b6:33:85:f2:18:ae:f4:ca:a4:d9:a8:41:34:4a:7b:23: 5d:41:77:87:6d:f9:65:07:62:6d:50:5a:f1:14:13:a3:c8:2f: 7a:3d -----BEGIN CERTIFICATE----- MIICrDCCAhWgAwIBAgIBBjANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE1MTMzNVoXDTI0 MDYwNDE1MTMzNVowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjezB5MAwGA1UdEwEB/wQC MAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7KBTAf BgNVHSMEGDAWgBRwRkkbwnEuwFDTSxhYisQQHK6zWTAcBgMqAwQBAf8EEgwQU29t ZSByYW5kb20gZGF0YTANBgkqhkiG9w0BAQUFAAOBgQAiQ+3SjyDatDEdVFSA1Lc7 yNuBMBspw+d2bHzBHYaX15iZ55mHJREwnmPiTrKjyZeqsKacc3bDoBWyBT4/kjiq YiZ4VoXAux45+vfIQCWc+cDOcLmKsFY191SRtbYzhfIYrvTKpNmoQTRKeyNdQXeH bfllB2JtUFrxFBOjyC96PQ== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second.key000066400000000000000000000016241445061461400260320ustar00rootroot00000000000000-----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOQT5/CXh2Jf4sx5 slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23lMMZBe/iF 6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKMLwsKcW/S 1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAECgYB4qOtIhfGSoqWKhUtKGfekRTPR zudr2cZtwd9/rmVDVDtmMrmTadCQ1hRAJeWs8PZxsIu8AMcX62bZaIa6F5aCZ7IU Jwwd9rt6o9pbBh2lcBO+iy+oCwFv7BImP6jFH7ODC7DYrwich2iEWIqNbhoLD8+7 0B9klyIlpc39fbL+2QJBAPH+cGq330uE8GVWyw3A8GVnkMrrcKKG+EAXMp0cCdSe YhoGPURk/Uww78GKfCmRFAVkNRQj4fJ+sIc16+nTf4sCQQDxR0Zk5T7sH2A9N2da Al6q/523sA5AkF/wJ9xmcT5HfZ/xFx0R96TSHR6SplbvXALUeQTWTmbuHkInraxi Sz1FAkEAk34I9oJrTpQQETP9PrzByIx+667kT6sD08xPxQI526VNFZ+H6A/FcpLB Dq1hT9Rk54RT9ZqJNEuTPFXZHAMUUQJAXe5rn1gIORC1/N8W41nM1TGSizKFOel7 EBnUmiU4I8jqfYeMD7SjfBFOF7WeXq0phOJgWbZIKCerhZr9Y377KQJAdYo+p8B8 uwp+Yq/9S+JrXtwLYOFYDm5lPykGp1rHZKzJdU6hYMednsSZ0FWZn2M5l0lhgPPs mPVCW2CSvF+p9Q== -----END PRIVATE KEY----- ocaml-x509-0.16.5/tests/testcertificates/intermediate/second/second.pem000066400000000000000000000060031445061461400260170ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha1WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=signing CA Validity Not Before: Jun 7 14:46:24 2014 GMT Not After : Jun 4 14:46:24 2024 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=second.foobar.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (1024 bit) Modulus: 00:e4:13:e7:f0:97:87:62:5f:e2:cc:79:b2:55:77: d7:c2:b8:b9:d3:51:b9:72:6f:15:13:b5:94:e7:54: 8e:c1:18:37:6c:d8:0b:90:5a:a4:5d:a5:0e:42:74: 4e:7e:ad:e9:34:37:a7:6d:e5:30:c6:41:7b:f8:85: e9:61:84:cc:d8:80:f2:7f:af:6e:22:bc:2c:ce:27: 1f:4a:fd:36:bc:1c:9d:f5:5f:e9:b4:96:0f:88:31: 8f:a7:6d:38:54:a8:7e:2c:1c:1c:72:8c:2f:0b:0a: 71:6f:d2:d5:c6:ac:e9:e0:e9:7e:72:46:43:a0:00: 60:33:62:d7:7a:ff:1e:7f:77 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Key Identifier: 4A:F7:E8:EB:57:1B:AB:49:41:23:E8:02:64:23:83:23:17:0E:CA:05 X509v3 Authority Key Identifier: keyid:70:46:49:1B:C2:71:2E:C0:50:D3:4B:18:58:8A:C4:10:1C:AE:B3:59 Signature Algorithm: sha1WithRSAEncryption ba:87:d8:55:8c:17:44:eb:c3:5b:9e:9a:d2:c7:78:d9:b0:00: 6e:a0:be:68:ed:a6:70:06:46:5b:79:f6:39:1b:d2:be:2d:d1: 22:4b:28:a7:4d:f5:53:f1:e1:10:c0:fd:11:47:cd:b0:0f:57: c0:4f:dc:c8:09:0d:77:01:2c:21:e4:37:99:69:81:cb:87:d1: 64:60:9e:92:56:9b:27:36:e9:e4:d8:5f:86:60:a8:d9:8f:0e: 75:b1:1a:ef:d7:3a:9b:59:04:2c:e4:7f:16:73:09:b1:86:91: 03:23:37:25:f3:4c:0a:77:3d:e1:f7:0e:29:35:c1:64:4d:e2: 62:bb -----BEGIN CERTIFICATE----- MIICjjCCAfegAwIBAgIBATANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJBVTET MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ dHkgTHRkMRMwEQYDVQQDDApzaWduaW5nIENBMB4XDTE0MDYwNzE0NDYyNFoXDTI0 MDYwNDE0NDYyNFowYTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEaMBgGA1UEAwwRc2Vj b25kLmZvb2Jhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQT5/CX h2Jf4sx5slV318K4udNRuXJvFRO1lOdUjsEYN2zYC5BapF2lDkJ0Tn6t6TQ3p23l MMZBe/iF6WGEzNiA8n+vbiK8LM4nH0r9NrwcnfVf6bSWD4gxj6dtOFSofiwcHHKM LwsKcW/S1cas6eDpfnJGQ6AAYDNi13r/Hn93AgMBAAGjXTBbMAwGA1UdEwEB/wQC MAAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBRK9+jrVxurSUEj6AJkI4MjFw7KBTAf BgNVHSMEGDAWgBRwRkkbwnEuwFDTSxhYisQQHK6zWTANBgkqhkiG9w0BAQUFAAOB gQC6h9hVjBdE68NbnprSx3jZsABuoL5o7aZwBkZbefY5G9K+LdEiSyinTfVT8eEQ wP0RR82wD1fAT9zICQ13ASwh5DeZaYHLh9FkYJ6SVpsnNunk2F+GYKjZjw51sRrv 1zqbWQQs5H8WcwmxhpEDIzcl80wKdz3h9w4pNcFkTeJiuw== -----END CERTIFICATE----- ocaml-x509-0.16.5/tests/testcertificates/openssl.cnf000066400000000000000000000205411445061461400222720ustar00rootroot00000000000000# This definition stops the following lines choking if HOME isn't # defined. HOME = . RANDFILE = $ENV::HOME/.rnd # Extra OBJECT IDENTIFIER info: #oid_file = $ENV::HOME/.oid oid_section = new_oids # To use this configuration file with the "-extfile" option of the # "openssl x509" utility, name here the section containing the # X.509v3 extensions to use: # extensions = # (Alternatively, use a configuration file that has only # X.509v3 extensions in its main [= default] section.) [ new_oids ] #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] dir = . # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. unique_subject = no # Set to 'no' to allow creation of # several ctificates with same subject. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key RANDFILE = $dir/private/.rand # private random number file x509_extensions = usr_cert # The extentions to add to the cert # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options # Extension copying option: use with caution. # copy_extensions = copy # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs # so this is commented out by default to leave a V1 CRL. # crlnumber must also be commented out to leave a V1 CRL. # crl_extensions = crl_ext default_days = 3650 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = default # use public key default MD preserve = no # keep passed DN ordering # A few difference way of specifying how similar the request should look # For type CA, the listed attributes must be the same, and the optional # and supplied fields are just that :-) policy = policy_match # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional # For the 'anything' policy # At this point in time, you must list all acceptable 'object' # types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ req ] default_bits = 1024 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes #x509_extensions = v3_ca # The extentions to add to the self signed cert # Passwords for private keys if not present they will be prompted for # input_password = secret # output_password = secret # This sets a mask for permitted string types. There are several options. # default: PrintableString, T61String, BMPString. # pkix : PrintableString, BMPString (PKIX recommendation before 2004) # utf8only: only UTF8Strings (PKIX recommendation after 2004). # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). # MASK:XXXX a literal mask value. # WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. string_mask = utf8only # req_extensions = v3_req # The extensions to add to a certificate request [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = AU countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Some-State localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Internet Widgits Pty Ltd # we can do this but it is not needed normally :-) #1.organizationName = Second Organization Name (eg, company) #1.organizationName_default = World Wide Web Pty Ltd organizationalUnitName = Organizational Unit Name (eg, section) #organizationalUnitName_default = commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 # SET-ex3 = SET extension number 3 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ usr_cert ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer #keyUsage = cRLSign, keyCertSign #extendedKeyUsage = 2.5.29.37.0,timeStamping # This stuff is for subjectAltName and issuerAltname. # Import the email address. #subjectAltName=DNS:*.foobar.com [ usr_bc_true ] basicConstraints=critical,CA:TRUE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer [ usr_time ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer extendedKeyUsage = timeStamping [ usr_any ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer extendedKeyUsage = 2.5.29.37.0 [ usr_nonrepud ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer [ usr_unknown ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer 1.2.3.4 = critical,ASN1:UTF8String:Some random data [ usr_unknown_noncrit ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer 1.2.3.4 = ASN1:UTF8String:Some random data [ usr_subj ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer subjectAltName=DNS:foobar.com,DNS:foo.foobar.com [ usr_subj_xx ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer subjectAltName=email:foobar.com [ usr_subj_wild ] basicConstraints=critical,CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer subjectAltName=DNS:*.foobar.com,DNS:foo.foobar.com [ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName=DNS:foobar.com,DNS:foo.foobar.com [ v3_ca ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true keyUsage = cRLSign, keyCertSign [ v3_ca_int_ca_no_bc ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer keyUsage = cRLSign, keyCertSign [ v3_int_ca_ba_false ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:false keyUsage = cRLSign, keyCertSign [ v3_int_ca_time ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true keyUsage = cRLSign, keyCertSign extendedKeyUsage = timeStamping [ v3_int_ca_no_ku ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true [ v3_int_ca_any ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true keyUsage = cRLSign, keyCertSign extendedKeyUsage = 2.5.29.37.0 [ v3_int_ca_ku_crit ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true keyUsage = critical, cRLSign, keyCertSign [ v3_int_ca_unknown ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true keyUsage = cRLSign, keyCertSign 1.2.3.4 = critical,ASN1:UTF8String:Some random data [ none ]ocaml-x509-0.16.5/tests/testcertificates/private/000077500000000000000000000000001445061461400215675ustar00rootroot00000000000000ocaml-x509-0.16.5/tests/testcertificates/private/cakey.pem000066400000000000000000000015671445061461400233770ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDnYbQH7pFmGO6qTj4spAWZyjdt/lYJ/8xy4oCPlKamxOkR/cjN 71CgueqD05TyHd3j0iT2qvxzU4IwPIlPoqK9+gzFybn0u8rjP4UouRqcGS9w+ZPY PW8QrwWgf4pGALgWlbSm8VkYS6Z1QAQmNrYAve6puiNkXv3Nmwa1ViI7AQIDAQAB AoGAHDLREQJnH+078O92LlSTBioZ1ULg03kkPoASMO1p3fszeGjYdxiKV/wwc35u sY8oQqKStKkj+R4dSKmoBleIw6kJivVOnYOakHJcO5MYevXNi0B0Ban3ODi/AMye zJBS6TXeqaK0/SFGma79SrCVViIlFYP883oRdUX7DEw/NBECQQD1oML+/DNUCuLy VzwrGYgD1+BsSgQyeXjVNTDqP4Z1IEJc7w6pRBDOUrJcPNKZ5+qVUhwNlHl22ptn VxuI/MbdAkEA8SbwVbNgWDPFjWwLBpUX2z9dE4u5P2Z5f6T84X4fL0zHJstxtghn 7QFbT4Gn2XJc0WxDBb6IN8HHY+n9olc4dQJBAKYJdubAer3r4f9pQq3rw0q9yeHJ os6v2CNfomImcPCJzvJdUq7O6QFfW1wIbWBGKgeoCniPjg/utDAF7QILxS0CQQCu QaH3e6gJ9FczizgoaIIVpyLd5eBVxPnU1+b4Fof4SPW7vdUMYeSfKZTOzfT5Nx+F IUMJGpYaHEe1ljb2ISqlAkA4qD6bweRPfRVC3FIH/l0//5yPZ5KpUadtmyF427Pf 8gbIdJsMLE37Ah0NHz3nS4eWYPoHBjcd4Hc8aJxvpK4s -----END RSA PRIVATE KEY----- ocaml-x509-0.16.5/tests/tests.ml000066400000000000000000000006741445061461400162530ustar00rootroot00000000000000let suites = X509tests.x509_tests @ [ "Regression", Regression.regression_tests ; "Host names", Regression.hostname_tests ; "Revoke", Revoke.revoke_tests ; "CRL", Crltests.crl_tests ; "PKCS12", Pkcs12.tests ; "OCSP", Ocsp.tests ; "Private Key", Priv.tests ; ] let () = Printexc.record_backtrace true; Mirage_crypto_rng_unix.initialize (module Mirage_crypto_rng.Fortuna); Alcotest.run "X509 tests" suites ocaml-x509-0.16.5/tests/x509tests.ml000066400000000000000000000342001445061461400166710ustar00rootroot00000000000000open X509 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 try let r = f buf in Unix.close fd; match r with | Ok data -> data | Error (`Msg m) -> Alcotest.failf "decoding error in %s: %s" fullpath m with e -> Unix.close fd; Alcotest.failf "exception in %s: %s" fullpath (Printexc.to_string e) let priv = match with_loaded_file "private/cakey" ~f:Private_key.decode_pem with | `RSA x -> x | _ -> assert false let cert name = with_loaded_file name ~f:Certificate.decode_pem let host name = Domain_name.host_exn (Domain_name.of_string_exn name) let invalid_cas = [ "cacert-basicconstraint-ca-false"; "cacert-unknown-critical-extension" ; "cacert-keyusage-crlsign" ; "cacert-ext-usage-timestamping" ] let cert_public_is_pub cert = let pub = Mirage_crypto_pk.Rsa.pub_of_priv priv in ( match Certificate.public_key cert with | `RSA pub' when pub = pub' -> () | _ -> Alcotest.fail "public / private key doesn't match" ) let test_invalid_ca name () = let c = cert name in cert_public_is_pub c ; Alcotest.(check int "CA list is empty" 0 (List.length (Validation.valid_cas [c]))) let invalid_ca_tests = List.mapi (fun i args -> "invalid CA " ^ string_of_int i, `Quick, test_invalid_ca args) invalid_cas let cacert = cert "cacert" let cacert_pathlen0 = cert "cacert-pathlen-0" let cacert_ext = cert "cacert-unknown-extension" let cacert_ext_ku = cert "cacert-ext-usage" let cacert_v1 = cert "cacert-v1" let test_valid_ca c () = cert_public_is_pub c ; Alcotest.(check int "CA is valid" 1 (List.length (Validation.valid_cas [c]))) let valid_ca_tests = [ "valid CA cacert", `Quick, test_valid_ca cacert ; "valid CA cacert_pathlen0", `Quick, test_valid_ca cacert_pathlen0 ; "valid CA cacert_ext", `Quick, test_valid_ca cacert_ext ; "valid CA cacert_v1", `Quick, test_valid_ca cacert_v1 ] let first_cert name = with_loaded_file ("first/" ^ name) ~f:Certificate.decode_pem (* ok, now some real certificates *) let first_certs = [ ( "first", true, [ "foo.foobar.com" ; "foobar.com" ], (* commonName: "bar.foobar.com" *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ( "first-basicconstraint-true" , false, [ "ca.foobar.com" ], (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ( "first-keyusage-and-timestamping", true, [ "ext.foobar.com" ], (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], Some [`Time_stamping] ) ; ( "first-keyusage-any", true, [ "any.foobar.com" ], (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], Some [`Time_stamping; `Any] ) ; ( "first-keyusage-nonrep", true, [ "key.foobar.com" ], (* no subjAltName *) [ `Content_commitment ], None ) ; ( "first-unknown-critical-extension", false, (* commonName: "blafasel.com" *) [ "foo.foobar.com" ; "foobar.com" ], [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ( "first-unknown-extension", true, [ "foobar.com" ], (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ] let allowed_hashes = [ `MD5 ; `SHA1 ; `SHA224 ; `SHA256 ; `SHA384 ; `SHA512 ] let test_valid_ca_cert ?(allowed_hashes = allowed_hashes) server chain valid name ca () = let anchors = ca and host = Some (host name) and full_chain = server :: chain in match valid, Validation.verify_chain_of_trust ~time ~allowed_hashes ~host ~anchors full_chain with | false, Ok _ -> Alcotest.fail "expected to fail, but didn't" | false, Error _ -> () | true , Ok _ -> () | true , Error c -> Alcotest.failf "valid certificate %a" Validation.pp_validation_error c let test_cert c usages extusage () = let ku, eku = let exts = Certificate.extensions c in let ku = match Extension.(find Key_usage exts) with | None -> [] | Some (_crit, ku) -> ku and eku = match Extension.(find Ext_key_usage exts) with | None -> [] | Some (_crit, eku) -> eku in ku, eku in ( if List.for_all (fun u -> List.mem u ku) usages then () else Alcotest.fail "key usage is different" ) ; ( match extusage with | None -> () | Some x when List.for_all (fun u -> List.mem u eku) x -> () | _ -> Alcotest.fail "extended key usage is broken" ) let first_cert_tests = List.mapi (fun i (name, _, _, us, eus) -> "certificate property testing " ^ string_of_int i, `Quick, test_cert (first_cert name) us eus) first_certs let first_cert_ca_test (ca, x) = List.flatten (List.map (fun (name, valid, cns, _, _) -> let c = first_cert name in ("verification CA " ^ x ^ " cn blablbalbala", `Quick, test_valid_ca_cert c [] false "blablabalbal" [ca]) :: List.mapi (fun i cn -> "certificate verification testing using CA " ^ x ^ " and CN " ^ cn ^ " " ^ string_of_int i, `Quick, test_valid_ca_cert c [] valid cn [ca]) cns) first_certs) let ca_tests f = List.flatten (List.map f [ (cacert, "cacert") ; (cacert_pathlen0, "cacert_pathlen0") ; (cacert_ext, "cacert_ext") ; (cacert_ext_ku, "cacert_ext_ku") ; (cacert_v1, "cacert_v1") ]) let first_wildcard_certs = [ ( "first-wildcard-subjaltname", [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ( "first-wildcard", [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ] let first_wildcard_cert_tests = List.mapi (fun i (name, us, eus) -> "wildcard certificate property testing " ^ string_of_int i, `Quick, test_cert (first_cert name) us eus) first_wildcard_certs let first_wildcard_cert_ca_test (ca, x) = List.flatten (List.map (fun (name, _, _) -> let c = first_cert name in ("verification CA " ^ x ^ " cn blablbalbala", `Quick, test_valid_ca_cert c [] false "blablabalbal" [ca]) :: List.mapi (fun i cn -> "wildcard certificate CA " ^ x ^ " and CN " ^ cn ^ " " ^ string_of_int i, `Quick, test_valid_ca_cert c [] true cn [ca]) [ "foo.foobar.com" ; "bar.foobar.com" ; "www.foobar.com" ] @ List.mapi (fun i cn -> "wildcard certificate CA " ^ x ^ " and CN " ^ cn ^ " " ^ string_of_int i, `Quick, test_valid_ca_cert c [] false cn [ca]) [ "foo.foo.foobar.com" ; "bar.fbar.com" ; "foobar.com" ; "com" ; "foobar.com.bla" ] ) first_wildcard_certs) let intermediate_cas = [ (true, "cacert") ; (true, "cacert-any-ext") ; (false, "cacert-ba-false") ; (false, "cacert-no-bc") ; (false, "cacert-no-keyusage") ; (true, "cacert-ku-critical") ; (true, "cacert-timestamp") ; (* if we require CAs to have ext_key_usage any, github.com doesn't talk to us *) (false, "cacert-unknown") ; (false, "cacert-v1") ] let im_cert name = with_loaded_file ("intermediate/" ^ name) ~f:Certificate.decode_pem let second_certs = [ ("second", [ "second.foobar.com" ], true, (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ("second-any", [ "second.foobar.com" ], true, (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], Some [ `Any ] ) ; ("second-subj", [ "foobar.com" ; "foo.foobar.com" ], true, (* commonName: "second.foobar.com" *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ("second-unknown-noncrit", [ "second.foobar.com" ], true, (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ("second-nonrepud", [ "second.foobar.com" ], true, (* no subjAltName *) [ `Content_commitment ], None ) ; ("second-time", [ "second.foobar.com" ], true, (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], Some [ `Time_stamping ]) ; ("second-subj-wild", [ "foo.foobar.com" ], true, (* commonName: "second.foobar.com" *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ("second-bc-true", [ "second.foobar.com" ], false, (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ("second-unknown", [ "second.foobar.com" ], false, (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ("second-no-cn", [ ], false, (* no subjAltName *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ("second-subjaltemail", [ ], false, (* email in subjAltName, do not use CN *) [ `Digital_signature ; `Content_commitment ; `Key_encipherment ], None ) ; ] let second_cert name = with_loaded_file ("intermediate/second/" ^ name) ~f:Certificate.decode_pem let second_cert_tests = List.mapi (fun i (name, _, _, us, eus) -> "second certificate property testing " ^ string_of_int i, `Quick, test_cert (second_cert name) us eus) second_certs let second_cert_ca_test (cavalid, ca, x) = List.flatten (List.flatten (List.map (fun (imvalid, im) -> let chain = [im_cert im] in List.map (fun (name, cns, valid, _, _) -> let c = second_cert name in ("verification CA " ^ x ^ " cn blablbalbala", `Quick, test_valid_ca_cert c chain false "blablabalbal" [ca]) :: List.mapi (fun i cn -> "strict certificate verification testing using CA " ^ x ^ " and CN " ^ cn ^ " " ^ string_of_int i, `Quick, test_valid_ca_cert c chain (cavalid && imvalid && valid) cn [ca]) cns) second_certs) intermediate_cas)) let im_ca_tests f = List.flatten (List.map f [ (true, cacert, "cacert") ; (true, cacert_ext, "cacert_ext") ; (true, cacert_ext_ku, "cacert_ext_ku") ; (true, cacert_v1, "cacert_v1") ; (false, cacert_pathlen0, "cacert_pathlen0") ]) let second_wildcard_cert_ca_test (cavalid, ca, x) = List.flatten (List.map (fun (imvalid, im) -> let chain = [im_cert im] in let c = second_cert "second-subj-wild" in ("verification CA " ^ x ^ " cn blablbalbala", `Quick, test_valid_ca_cert c chain false "blablabalbal" [ca]) :: List.mapi (fun i cn -> "wildcard certificate verification CA " ^ x ^ " and CN " ^ cn ^ " " ^ string_of_int i, `Quick, test_valid_ca_cert c chain (cavalid && imvalid) cn [ca]) [ "a.foobar.com" ; "foo.foobar.com" ; "foobar.foobar.com" ; "www.foobar.com" ] @ List.mapi (fun i cn -> "wildcard certificate verification CA " ^ x ^ " and CN " ^ cn ^ " " ^ string_of_int i, `Quick, test_valid_ca_cert c chain false cn [ca]) [ "a.b.foobar.com" ; "f.foobar.com.com" ; "f.f.f." ; "foobar.com.uk" ; "foooo.bar.com" ; "foobar.com" ]) intermediate_cas) let second_no_cn_cert_ca_test (_, ca, x) = List.flatten (List.map (fun (_, im) -> let chain = [im_cert im] in let c = second_cert "second-no-cn" in ("verification CA " ^ x ^ " cn blablbalbala", `Quick, test_valid_ca_cert c chain false "blablabalbal" [ca]) :: List.mapi (fun i cn -> "certificate verification CA " ^ x ^ " and CN " ^ cn ^ " " ^ string_of_int i, `Quick, test_valid_ca_cert c chain false cn [ca]) [ "a.foobar.com" ; "foo.foobar.com" ; "foobar.foobar.com" ; "foobar.com" ; "www.foobar.com" ] @ List.mapi (fun i cn -> "certificate verification CA " ^ x ^ " and CN " ^ cn ^ " " ^ string_of_int i, `Quick, test_valid_ca_cert c chain false cn [ca]) [ "a.b.foobar.com" ; "f.foobar.com.com" ; "f.f.f." ; "foobar.com.uk" ; "foooo.bar.com" ]) intermediate_cas) let invalid_tests = let c = second_cert "second" in let h = "second.foobar.com" in let allowed_hashes = [ `SHA256 ; `SHA384 ; `SHA512 ] in [ "invalid chain", `Quick, test_valid_ca_cert c [] false h [cacert] ; "broken chain", `Quick, test_valid_ca_cert c [cacert] false h [cacert] ; "no trust anchor", `Quick, test_valid_ca_cert c [im_cert "cacert"] false h [] ; "2chain invalid", `Quick, test_valid_ca_cert ~allowed_hashes c [im_cert "cacert" ; cacert] false h [cacert] ; "2chain valid", `Quick, test_valid_ca_cert c [im_cert "cacert" ; cacert] true h [cacert] ; "3chain invalid", `Quick, test_valid_ca_cert ~allowed_hashes c [im_cert "cacert" ; cacert ; cacert] false h [cacert] ; "3chain valid", `Quick, test_valid_ca_cert c [im_cert "cacert" ; cacert ; cacert] true h [cacert] ; "chain-order invalid", `Quick, test_valid_ca_cert ~allowed_hashes c [im_cert "cacert" ; im_cert "cacert" ; cacert] false h [cacert] ; "chain-order valid", `Quick, test_valid_ca_cert c [im_cert "cacert" ; im_cert "cacert" ; cacert] true h [cacert] ; "not a CA", `Quick, (fun _ -> Alcotest.(check int "is not a CA" 0 (List.length (Validation.valid_cas [im_cert "cacert"])))) ; "not a CA", `Quick, (fun _ -> Alcotest.(check int "is also not a CA" 0 (List.length (Validation.valid_cas [c])))) ; ] let x509_tests = [ "Invalid CA", invalid_ca_tests ; "Valid CA", valid_ca_tests ; "Certificate", first_cert_tests ; "CA tests with certificate", ca_tests first_cert_ca_test ; "Wildcard certificate", first_wildcard_cert_tests ; "CA tests with wildcard certificate", ca_tests first_wildcard_cert_ca_test ; "Second certificate test", second_cert_tests ; "Intermediate CA with second certificate", im_ca_tests second_cert_ca_test ; "Intermediate CA with CA and second", im_ca_tests second_wildcard_cert_ca_test ; "Intermediate CA with second no common name", im_ca_tests second_no_cn_cert_ca_test ; "Tests with invalid data", invalid_tests ] ocaml-x509-0.16.5/x509.opam000066400000000000000000000032231445061461400147710ustar00rootroot00000000000000opam-version: "2.0" maintainer: [ "Hannes Mehnert " ] authors: [ "Hannes Mehnert " "David Kaloper " ] license: "BSD-2-Clause" tags: "org:mirage" 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"} "dune" {>= "1.2"} "cstruct" {>= "6.0.0"} "asn1-combinators" {>= "0.2.0"} "ptime" "base64" {>= "3.3.0"} "mirage-crypto" "mirage-crypto-pk" "mirage-crypto-ec" {>= "0.10.7"} "mirage-crypto-rng" "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" "pbkdf" "ipaddr" {>= "5.2.0"} ] conflicts: [ "result" {< "1.5"} ] build: [ ["dune" "subst"] {dev} ["dune" "build" "-p" name "-j" jobs] ["dune" "runtest" "-p" name "-j" jobs] {with-test} ] dev-repo: "git+https://github.com/mirleft/ocaml-x509.git" synopsis: "Public Key Infrastructure (RFC 5280, PKCS) purely in OCaml" description: """ X.509 is a public key infrastructure used mostly on the Internet. It consists of certificates which include public keys and identifiers, signed by an authority. Authorities must be exchanged over a second channel to establish the trust relationship. This library implements most parts of RFC5280 and RFC6125. 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. """