From e89389bfec1142c435848687015b6b8f3a905d62 Mon Sep 17 00:00:00 2001 From: "Kian-Meng, Ang" Date: Sat, 20 Nov 2021 17:17:54 +0800 Subject: [PATCH] Misc doc changes Besides other documentation changes, this commit ensures the generated HTML doc for HexDocs.pm will become the source of truth for this Elixir library and leverage on latest features of ExDoc. --- .formatter.exs | 4 ++++ .gitignore | 11 ++++------- LICENSE => LICENSE.md | 2 +- README.md | 19 +++++++++++++++---- lib/easy_ssl.ex | 23 ++++++++++++++--------- mix.exs | 40 ++++++++++++++++++++++++++++++---------- mix.lock | 11 ++++++----- test/easy_ssl_test.exs | 4 ++-- 8 files changed, 76 insertions(+), 38 deletions(-) create mode 100644 .formatter.exs rename LICENSE => LICENSE.md (98%) diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/.gitignore b/.gitignore index a0c2a26..9afb450 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ # The directory Mix downloads your dependencies sources to. /deps/ -# Where 3rd-party dependencies like ExDoc output generated docs. +# Where third-party dependencies like ExDoc output generated docs. /doc/ # Ignore .fetch files in case you like to edit your project deps locally. @@ -20,10 +20,7 @@ erl_crash.dump *.ez # Ignore package tarball (built via "mix hex.build"). -easy_ssl_elixir-*.tar +easy_ssl-*.tar -*.iml - -.idea/ - -.formatter.exs \ No newline at end of file +# Temporary files, for example, from tests. +/tmp/ diff --git a/LICENSE b/LICENSE.md similarity index 98% rename from LICENSE rename to LICENSE.md index ee59573..8854cc6 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,4 +1,4 @@ -MIT License +# The MIT License Copyright (c) 2019 Cali Dog Security diff --git a/README.md b/README.md index d347465..127cdf4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # EasySSL +[![Module Version](https://img.shields.io/hexpm/v/easy_ssl.svg)](https://hex.pm/packages/easy_ssl) +[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/easy_ssl/) +[![Total Download](https://img.shields.io/hexpm/dt/easy_ssl.svg)](https://hex.pm/packages/easy_ssl) +[![License](https://img.shields.io/hexpm/l/easy_ssl.svg)](https://github.com/CaliDog/EasySSL/blob/master/LICENSE.md) +[![Last Updated](https://img.shields.io/github/last-commit/CaliDog/EasySSL.svg)](https://github.com/CaliDog/EasySSL/commits/master) + Originally this module was part of the [Certstream](https://certstream.calidog.io) project, but we decided that it'd be more useful as a stand-alone module to hopefully de-duplicate the annoyances of figuring out how to use Erlang's `:public_key` module to properly parse X509 certificates and coerce things like extensions and subjects to something that more closely resembles certificate parsing in other languages. As a forewarning, this is by no means an all-inclusive library for parsing X509 certificates, it's just what we needed as part of our project, but pull requests are extremely welcome if you notice some breakage or ways to improve! That being said, it does process millions of certificates per day through Certstream, so we consider it fairly battle tested! @@ -10,7 +16,7 @@ As with most libraries in the Elixir landscape, you can install this by adding t (Current version: ![](http://img.shields.io/hexpm/v/easy_ssl.svg)) -``` +```elixir {:easy_ssl, "~> 1.3.0"} ``` @@ -68,7 +74,7 @@ We aim to make the usage as stupid simple as possible, so there are only 2 expor Parses a DER-encoded X509 certificate ```elixir -iex(1)> File.read!("some_cert.der") |> EasySSL.parse_der +iex> File.read!("some_cert.der") |> EasySSL.parse_der %{ extensions: %{ ...SNIP... @@ -93,7 +99,7 @@ iex(1)> File.read!("some_cert.der") |> EasySSL.parse_der Parses a PEM-encoded X509 certificate ```elixir -iex(1)> File.read!("some_cert.pem") |> EasySSL.parse_pem +iex> File.read!("some_cert.pem") |> EasySSL.parse_pem %{ extensions: %{ ...SNIP... @@ -113,6 +119,11 @@ iex(1)> File.read!("some_cert.pem") |> EasySSL.parse_pem ``` +If you'd like some other functionality or find a bug please open a ticket! +## Copyright and License -If you'd like some other functionality or find a bug please open a ticket! +Copyright (c) 2019 Cali Dog Security + +This work is free. You can redistribute it and/or modify it under the +terms of the MIT License. See the [LICENSE.md](./LICENSE.md) file for more details. diff --git a/lib/easy_ssl.ex b/lib/easy_ssl.ex index 3509236..14cfec7 100644 --- a/lib/easy_ssl.ex +++ b/lib/easy_ssl.ex @@ -1,12 +1,15 @@ -require Logger - defmodule EasySSL do @moduledoc """ - EasySSL is a wrapper around Erlang's `:public_key` module to make it far more friendly. It automatically - processes OIDs for most X509v3 extensions and subject fields. + EasySSL is a wrapper around Erlang's `:public_key` module to make it far more + friendly. It automatically processes OIDs for most X509v3 extensions and + subject fields. - There are really only two functions of note - `parse_der` and `parse_pem`, which should have obvious functions. + There are really only two functions of note - `parse_der` and `parse_pem`, + which should have obvious functions. """ + + require Logger + @pubkey_schema Record.extract_all(from_lib: "public_key/include/OTP-PUB-KEY.hrl") @extended_key_usages %{ @@ -32,7 +35,7 @@ defmodule EasySSL do ## Examples # Pass in a binary (from Base.decode64, or some other source) - iex(1)> EasySSL.parse_der(<<...>>) + iex> EasySSL.parse_der(<<...>>) %{ extensions: %{ authorityInfoAccess: "CA Issuers - URI:http://certificates.godaddy.com/repository/gd_intermediate.crt\\nOCSP - URI:http://ocsp.godaddy.com/\\n", @@ -71,6 +74,7 @@ defmodule EasySSL do emailAddress: nil } } + """ def parse_der(certificate_der, opts \\ [all_domains: false, serialize: false]) when is_binary(certificate_der) do cert = :public_key.pkix_decode_cert(certificate_der, :otp) |> get_field(:tbsCertificate) @@ -132,7 +136,7 @@ defmodule EasySSL do ## Examples # Pass in a binary (from Base.decode64, or some other source) - iex(1)> EasySSL.parse_pem("-----BEGIN CERTIFICATE-----\\nMII...") + iex> EasySSL.parse_pem("-----BEGIN CERTIFICATE-----\\nMII...") %{ extensions: %{ authorityInfoAccess: "CA Issuers - URI:http://certificates.godaddy.com/repository/gd_intermediate.crt\\nOCSP - URI:http://ocsp.godaddy.com/\\n", @@ -171,7 +175,8 @@ defmodule EasySSL do emailAddress: nil } } -""" + + """ def parse_pem(cert_charlist) when is_list(cert_charlist) do parse_pem(cert_charlist |> to_string) end def parse_pem(cert_pem, opts \\ [all_domains: false, return_base64: false]) do cert_regex = ~r/^\-{5}BEGIN\sCERTIFICATE\-{5}\n(?[^\-]+)\-{5}END\sCERTIFICATE\-{5}/ @@ -478,7 +483,7 @@ defmodule EasySSL do |> Enum.reverse() _ -> - Logger.error("Unhandled CRL distrobution point #{inspect distro_point}") + Logger.error("Unhandled CRL distribution point #{inspect distro_point}") output end end) diff --git a/mix.exs b/mix.exs index 0ba916f..d895f13 100644 --- a/mix.exs +++ b/mix.exs @@ -1,18 +1,25 @@ defmodule EasySSL.MixProject do use Mix.Project + @source_url "https://github.com/CaliDog/EasySSL" + @version "1.3.0" + def project do [ app: :easy_ssl, name: "EasySSL", - version: "1.3.0", + version: @version, elixir: "~> 1.6", - description: "SSL/X509 parsing for humans.", deps: deps(), + docs: docs(), + package: package(), test_coverage: [tool: ExCoveralls], - preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test], - source_url: "https://github.com/CaliDog/EasySSL", - package: package() + preferred_cli_env: [ + coveralls: :test, + "coveralls.detail": :test, + "coveralls.post": :test, + "coveralls.html": :test + ] ] end @@ -25,19 +32,32 @@ defmodule EasySSL.MixProject do defp deps do [ {:excoveralls, "~> 0.8", only: :test}, - {:ex_doc, "~> 0.16", only: :dev, runtime: false}, - {:poison, "~> 2.0", only: :test}, + {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, + {:poison, "~> 2.0", only: :test} ] end defp package() do [ name: "easy_ssl", - # These are the default files included in the package - files: ["lib", "mix.exs", "README.md"], + description: "SSL/X509 parsing for humans.", + files: ["lib", "mix.exs", "README.md", "LICENSE.md"], maintainers: ["Ryan Sears"], licenses: ["MIT"], - links: %{"GitHub" => "https://github.com/CaliDog/EasySSL"} + links: %{"GitHub" => @source_url} + ] + end + + defp docs do + [ + extras: [ + "LICENSE.md": [title: "License"], + "README.md": [title: "Overview"] + ], + main: "readme", + source_url: @source_url, + source_ref: "v#{@version}", + formatters: ["html"] ] end end diff --git a/mix.lock b/mix.lock index e8f63f1..c7cb18e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,19 +1,20 @@ %{ "certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"}, "earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm", "1b34655872366414f69dd987cb121c049f76984b6ac69f52fff6d8fd64d29cfd"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"}, - "ex_doc": {:hex, :ex_doc, "0.22.2", "03a2a58bdd2ba0d83d004507c4ee113b9c521956938298eba16e55cc4aba4a6c", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "cf60e1b3e2efe317095b6bb79651f83a2c1b3edcb4d319c421d7fcda8b3aff26"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.17", "6f3c7e94170377ba45241d394389e800fb15adc5de51d0a3cd52ae766aafd63f", [:mix], [], "hexpm", "f93ac89c9feca61c165b264b5837bf82344d13bebc634cd575cb711e2e342023"}, + "ex_doc": {:hex, :ex_doc, "0.25.5", "ac3c5425a80b4b7c4dfecdf51fa9c23a44877124dd8ca34ee45ff608b1c6deb9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "688cfa538cdc146bc4291607764a7f1fcfa4cce8009ecd62de03b27197528350"}, "excoveralls": {:hex, :excoveralls, "0.13.1", "b9f1697f7c9e0cfe15d1a1d737fb169c398803ffcbc57e672aa007e9fd42864c", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "b4bb550e045def1b4d531a37fb766cbbe1307f7628bf8f0414168b3f52021cce"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, "hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"}, "idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"}, "jason": {:hex, :jason, "1.2.1", "12b22825e22f468c02eb3e4b9985f3d0cb8dc40b9bd704730efa11abd2708c44", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b659b8571deedf60f79c5a608e15414085fa141344e2716fbd6988a084b5f993"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"}, - "makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, + "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, - "nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.2.0", "b44d75e2a6542dcb6acf5d71c32c74ca88960421b6874777f79153bbbbd7dccc", [:mix], [], "hexpm", "52b2871a7515a5ac49b00f214e4165a40724cf99798d8e4a65e4fd64ebd002c1"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, "poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], [], "hexpm", "519bc209e4433961284174c497c8524c001e285b79bdf80212b47a1f898084cc"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, diff --git a/test/easy_ssl_test.exs b/test/easy_ssl_test.exs index 5e9cc77..0693749 100644 --- a/test/easy_ssl_test.exs +++ b/test/easy_ssl_test.exs @@ -18,7 +18,7 @@ defmodule EasySSLTest do end) end - test "parses all certifiates in @der_cert_dir directory" do + test "parses all certificates in @der_cert_dir directory" do File.ls!(@der_cert_dir) |> Enum.each(fn cert_filename -> original_cert = File.read!(@der_cert_dir <> cert_filename) @@ -31,7 +31,7 @@ defmodule EasySSLTest do end) end - test "parses all certifiates in @pem_cert_dir directory" do + test "parses all certificates in @pem_cert_dir directory" do File.ls!(@pem_cert_dir) |> Enum.each(fn cert_filename -> original_cert = File.read!(@pem_cert_dir <> cert_filename)