Skip to content

permaweb/ssl_cert

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SSL Certificate Library

Hex.pm Hex.pm Hex Docs

A comprehensive SSL certificate management library with Let's Encrypt ACME v2 support for Erlang/OTP applications.

Index

Features

  • Full ACME v2 protocol support
  • Let's Encrypt certificate automation
  • DNS and HTTP-01 challenge support
  • Certificate lifecycle management
  • Cryptographic operations for certificate handling
  • Comprehensive validation and state management
  • Modern HTTP/2 client using gun

Installation

Add this library to your rebar.config dependencies:

{deps, [
    {ssl_cert, {git, "https://github.com/permaweb/ssl_cert.git", {branch, "main"}}}
]}.

Usage

Device Configuration

Configure the SSL certificate device with the required options:

%% Configuration for SSL certificate requests
Opts = #{
    <<"ssl_opts">> => #{
        <<"domains">> => [<<"example.com">>, <<"www.example.com">>],
        <<"email">> => <<"[email protected]">>,
        <<"environment">> => <<"staging">>  % Use "production" for live certificates
    }
}.

Certificate Request Workflow

Step 1: Request Certificate

%% Initiate certificate request - returns DNS challenges
{ok, Response} = dev_ssl_cert:request(undefined, undefined, Opts),
#{<<"body">> := #{
    <<"challenges">> := Challenges,
    <<"message">> := <<"Create DNS TXT records for the following challenges, then call finalize">>
}} = Response.

Step 2: Set DNS TXT Records

Based on the returned challenges, create DNS TXT records:

_acme-challenge.example.com.     TXT "challenge_token_here"
_acme-challenge.www.example.com. TXT "challenge_token_here"

Step 3: Finalize Certificate

%% After DNS records are set, finalize the certificate
{ok, FinalResponse} = dev_ssl_cert:finalize(undefined, undefined, Opts),
#{<<"body">> := #{
    <<"certificate_pem">> := CertPem,
    <<"key_pem">> := KeyPem,
    <<"domains">> := Domains
}} = FinalResponse.

Certificate Management

Renew Certificate

%% Renew existing certificate
RenewOpts = #{
    <<"ssl_opts">> => #{
        <<"domains">> => [<<"example.com">>, <<"www.example.com">>],
        <<"email">> => <<"[email protected]">>,
        <<"environment">> => <<"production">>
    }
},
{ok, RenewResponse} = dev_ssl_cert:renew(undefined, undefined, RenewOpts).

Delete Certificate

%% Delete stored certificate
DeleteOpts = #{
    <<"ssl_opts">> => #{
        <<"domains">> => [<<"example.com">>, <<"www.example.com">>]
    }
},
{ok, DeleteResponse} = dev_ssl_cert:delete(undefined, undefined, DeleteOpts).

Environment Configuration

Staging Environment (for testing)

StagingOpts = #{
    <<"ssl_opts">> => #{
        <<"domains">> => [<<"test.example.com">>],
        <<"email">> => <<"[email protected]">>,
        <<"environment">> => <<"staging">>
    }
}.

Production Environment

ProductionOpts = #{
    <<"ssl_opts">> => #{
        <<"domains">> => [<<"example.com">>],
        <<"email">> => <<"[email protected]">>,
        <<"environment">> => <<"production">>
    }
}.

Direct Module Usage

For advanced use cases, you can call the underlying modules directly:

%% Validate request parameters
{ok, ValidatedParams} = ssl_cert_validation:validate_request_params(
    [<<"example.com">>], <<"[email protected]">>, <<"staging">>),

%% Process certificate request
{ok, ProcessResponse} = ssl_cert_ops:process_certificate_request(ValidatedParams, Wallet),

%% Validate DNS challenges
{ok, ValidationResponse} = ssl_cert_challenge:validate_dns_challenges_state(RequestState, PrivateKey),

%% Generate CSR
{ok, {CsrDer, PrivateKey}} = acme_csr:generate_csr([<<"example.com">>], #{}).

Modules

  • acme_client - Main ACME client API
  • ssl_cert_ops - High-level certificate operations
  • acme_protocol - Core ACME protocol implementation
  • acme_crypto - Cryptographic operations and JWS
  • acme_csr - Certificate Signing Request generation
  • ssl_cert_challenge - Challenge handling and validation
  • ssl_cert_validation - Certificate validation utilities
  • ssl_cert_state - State management utilities
  • ssl_utils - Utility functions and HTTP client

Dependencies

  • gun - Modern HTTP/2 client for ACME communication
  • crypto - Cryptographic operations
  • public_key - Public key operations
  • ssl - SSL/TLS support
  • inets - Additional HTTP utilities

Code Coverage

Current test coverage across all modules:

Module Coverage
Core Modules
acme_client 25%
acme_crypto 65%
acme_csr 81%
acme_http 49%
acme_protocol 26%
acme_url 100%
ssl_cert_challenge 18%
ssl_cert_ops 24%
ssl_cert_state 65%
ssl_cert_validation 95%
ssl_utils 29%
Test Modules
acme_client_tests 91%
acme_crypto_tests 100%
acme_csr_tests 91%
acme_http_tests 100%
acme_protocol_tests 91%
acme_url_tests 100%
ssl_cert_challenge_tests 100%
ssl_cert_integration_tests 100%
ssl_cert_ops_tests 100%
ssl_cert_state_tests 100%
ssl_cert_test_suite 10%
ssl_cert_validation_tests 100%
ssl_utils_tests 100%
Total Coverage 68%

Coverage Analysis

  • High Coverage (80%+): acme_csr, acme_url, ssl_cert_validation
  • Medium Coverage (50-79%): acme_crypto, ssl_cert_state
  • Low Coverage (<50%): acme_client, acme_http, acme_protocol, ssl_cert_challenge, ssl_cert_ops, ssl_utils

Development Commands

Code Quality and Formatting

# Format all Erlang files
rebar3 fmt

# Check if files need formatting (don't modify)
rebar3 fmt --check

# Run linter to check code quality
rebar3 lint

Testing

# Compile and run all tests
rebar3 as test eunit

# Run specific test module
rebar3 as test eunit --module=my_module_tests

Code Coverage

# Run tests with coverage analysis
rebar3 cover

# Generate coverage reports
rebar3 covertool generate

# Full test and coverage workflow
rebar3 as test eunit && rebar3 cover && rebar3 covertool generate

Documentation and Publishing

# Generate HTML documentation
rebar3 ex_doc

# Authenticate with Hex (one-time setup)
rebar3 hex user auth

# Publish to Hex
rebar3 hex publish

Development Workflow

# Complete quality check before commit
rebar3 clean
rebar3 fmt --check
rebar3 lint
rebar3 as test compile
rebar3 as test eunit
rebar3 cover
rebar3 covertool generate

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages