Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc doc changes #14

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]
11 changes: 4 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
# Temporary files, for example, from tests.
/tmp/
2 changes: 1 addition & 1 deletion LICENSE → LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
MIT License
# The MIT License

Copyright (c) 2019 Cali Dog Security

Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -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!
Expand All @@ -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"}
```

Expand Down Expand Up @@ -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...
Expand All @@ -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...
Expand All @@ -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.
23 changes: 14 additions & 9 deletions lib/easy_ssl.ex
Original file line number Diff line number Diff line change
@@ -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 %{
Expand All @@ -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",
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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(?<certificate>[^\-]+)\-{5}END\sCERTIFICATE\-{5}/
Expand Down Expand Up @@ -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)
Expand Down
40 changes: 30 additions & 10 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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
11 changes: 6 additions & 5 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -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"},
Expand Down
4 changes: 2 additions & 2 deletions test/easy_ssl_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down