# NAME App::sslmaker - Be your own SSL certificate authority # VERSION 0.16 # DESCRIPTION [App::sslmaker](https://metacpan.org/pod/App%3A%3Asslmaker) is a module that provide methods for acting as your own [CA](http://en.wikipedia.org/wiki/Certificate_authority) (certificate authority). It can creating SSL keys, certificates and signing requests. The methods should have good defaults and "just work", so you don't have to worry about the details. "Just work" depends on safe defaults, which will change when new and more secure standards come along. The openssl commands are based on the instructions from [https://jamielinux.com/docs/openssl-certificate-authority/](https://jamielinux.com/docs/openssl-certificate-authority/). This module is used by the `sslmaker` command line application, but can also act as a standalone toolkit. # DISCLAIMER This module is based on tips and tricks from online resources, and has been reviewed by security experts. Even so, the ["AUTHOR"](#author) of this application or any parts involved cannot be held responsible for the security of your server, application or other parts that use the files generated by this library. # SYNOPSIS $ sslmaker [options] # 1. Initial CA setup # 1a. The CA admin generates root CA key and certificate $ sslmaker root --subject "/C=US/ST=Texas/L=Dallas/O=Company/OU=Department/CN=superduper" # 1b. The CA admin generates intermediate CA key and certificate # Uses the --subject from root CA by default $ sslmaker intermediate # 2. Client certificate setup # 2a. The client generates a server key and certificate signing request # Can be done on any other server # Uses the --subject from intermediate CA if available $ sslmaker generate $ sslmaker generate www.example.com # 2b. The client sends the signing request file to the CA admin # 3. CA sign and revoke process # 3a. The CA admin signs the certificate request $ sslmaker sign www.example.com.csr.pem $ sslmaker sign www.example.com.csr.pem [outfile] # 3b. The CA admin sends back the signed certificate which the client can use # 3c. The CA can revoke a certificate $ sslmaker revoke $ sslmaker revoke /etc/ssl/sslmaker/newcerts/1000.pem # 4. Utility commands # 4a. Create dhparam file $ sslmaker dhparam $ sslmaker dhparam /etc/ssl/sslmaker/dhparam.pem 2048 # 4b. Show the manual for App::sslmaker $ sslmaker man # ENVIRONMENT VARIABLES - SSLMAKER\_BITS Default bits for a generated certificate. Default is 4096. - SSLMAKER\_DAYS Default days before expiring a generated certificate. Default is 365. - SSLMAKER\_DEBUG Setting this to "0" will output less debug information from `sslmaker`. - SSLMAKER\_HOME Used by the `sslmaker` script as default home directory. Default is either "/etc/pki/sslmaker" or "/etc/ssl/sslmaker". Directory structure is: # generated by "sslmaker root" $SSLMAKER_HOME/root/ca.cert.pem $SSLMAKER_HOME/root/ca.key.pem $SSLMAKER_HOME/root/crlnumber $SSLMAKER_HOME/root/index.txt $SSLMAKER_HOME/root/index.txt.attr $SSLMAKER_HOME/root/passphrase $SSLMAKER_HOME/root/serial # generated by "sslmaker intermediate" $SSLMAKER_HOME/certs/ca-chain.cert.pem $SSLMAKER_HOME/certs/ca.cert.pem $SSLMAKER_HOME/certs/ca.csr.pem $SSLMAKER_HOME/private/ca.key.pem $SSLMAKER_HOME/private/passphrase $SSLMAKER_HOME/root/newcerts/1000.pem $SSLMAKER_HOME/crlnumber $SSLMAKER_HOME/index.txt $SSLMAKER_HOME/index.txt.attr $SSLMAKER_HOME/serial # generated by "sslmaker sign" $SSLMAKER_HOME/newcerts/1000.pem # generated by "sslmaker dhparam" $SSLMAKER_HOME/dhparam.pem NOTE! After running "sslmaker intermediate", then it is highly suggested to move "$SSLMAKER\_HOME/root/" to a safe location, such as a memory stick. You can revoke any of the child certificates if they are compromised, but if you loose the root key, then all is lost. - SSLMAKER\_OPENSSL Default to "openssl". Can be set to a custom path if "openssl" is not in `PATH`. - SSLMAKER\_SUBJECT Used as default subject, unless specified. ## SEE ALSO - [https://jamielinux.com/docs/openssl-certificate-authority/](https://jamielinux.com/docs/openssl-certificate-authority/) - [https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs](https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs) - [http://en.wikipedia.org/wiki/Certificate\_authority](http://en.wikipedia.org/wiki/Certificate_authority) - [Easy RSA](https://github.com/OpenVPN/easy-rsa) # METHODS ## make\_cert $asset = $self->make_cert({ key => "/path/to/private/input.key.pem", passphrase => "/path/to/passphrase.txt", days => $number_of_days, # default: 365 subject => '/C=NO/ST=Oslo', # optional }); This method will generate a SSL certificate using a `key` generated by ["make\_key"](#make_key). `passphrase` should match the argument given to ["make\_key"](#make_key). An optional `subject` can be provided. The subject string will be merged with the ["subject"](#subject) attribute. `days` can be used to set how many days the certificate should be valid. The returned `$asset` is a [Path::Tiny](https://metacpan.org/pod/Path%3A%3ATiny) object which holds the generated certificate file. It is possible to specify the location of this object by passing on `cert` to this method. ## make\_crl $asset = $self->make_crl({ key => "/path/to/private/input.key.pem", cert => "/path/to/cefrt/input.cert.pem", passphrase => "/path/to/passphrase.txt", # optional }); This method will generate a certificate revocation list (CRL) using a `key` generated by ["make\_key"](#make_key). `passphrase` should match the argument given to ["make\_key"](#make_key). The returned `$asset` is a [Path::Tiny](https://metacpan.org/pod/Path%3A%3ATiny) object which holds the generated certificate file. It is possible to specify the location of this object by passing on `crl` to this method. You can inspect the generated asset using the command `openssl crl -in $crl_asset -text`. See also ["revoke\_cert"](#revoke_cert). ## make\_csr $asset = $self->make_csr({ key => "/path/to/private/input.key.pem", passphrase => "/path/to/passphrase.txt", subject => '/C=NO/ST=Oslo', days => $number_of_days, # default: 365 }); This method will generate a SSL certificate signing request using a `key` generated by ["make\_key"](#make_key). `passphrase` is only required if the `key` was generated with a `passphrase`. An optional `subject` can be provided. The subject string will be merged with the ["subject"](#subject) attribute. The returned `$asset` is a [Path::Tiny](https://metacpan.org/pod/Path%3A%3ATiny) object which holds the generated signing request file. It is possible to specify the location of this object by passing on `csr` to this method. ## make\_directories $self->make_directories({ home => "/path/to/pki", templates => 1, # default: false }); Used to generate a suitable file structure, which reflect what `openssl.cnf` expects. Set `$emplates` to a true value to generate [files](#render_to_file). $home/ # need to be writable by current user $home/certs/ $home/crl/ $home/newcerts/ $home/private/ # will have mode 700 # optional templates $home/index.txt $home/serial ## make\_key $asset = $self->make_key({ passphrase => "/path/to/passphrase.txt", # optional bits => 8192, # default: 4096 }); This method will generate a SSL key. The key will be protected with `passphrase` if given as input. In addition if `passphrase` does not exist, it will be created with a random passphrase. The returned `$asset` is a [Path::Tiny](https://metacpan.org/pod/Path%3A%3ATiny) object which holds the generated key. It is possible to specify the location of this object by passing on `key` to this method. ## new $self = App::sslmaker->new(%args); $self = App::sslmaker->new(\%args); Object constructor. ## openssl $self->openssl(@args); $self->openssl(@args, sub { ... }); App::sslmaker::openssl(@args); App::sslmaker::openssl(@args, sub { ... }); Used to run the application `openssl`. The callback defined at the end is optional, but will be called with the complete output from the openssl command. `$?` is also available for inspection. The `openssl` application must exist in path or defined by setting the `SSLMAKER_OPENSSL` environment variable before loading this module. ## render\_to\_file $asset = $self->render_to_file($template, \%stash); $asset = $self->render_to_file($template, $out_file, \%args); This method can render a `$template` to either a temp file or `$out_file`. The `$template` will have access to `%stash` and `$self`. See ["TEMPLATES"](#templates) for list of valid templates. ## revoke\_cert $self->with_config( revoke_cert => { key => "/path/to/private/ca.key.pem", cert => "/path/to/certs/ca.cert.pem", crl => "/path/to/crl.pem", revoke => "/path/to/newcerts/1000.pem", }, ); This method can revoke a certificate. It need to be run either with `OPENSSL_CONF` or inside ["with\_config"](#with_config). ## sign\_csr $asset = $self->sign_csr({ csr => "/path/to/certs/input.csr.pem", ca_key => "/path/to/private/ca.key.pem", ca_cert => "/path/to/certs/ca.cert.pem", passphrase => "/path/to/passphrase.txt", extensions => "v3_ca", # default: usr_cert }); This method will sign a `csr` file generated by ["make\_csr"](#make_csr). `ca_key` and `passphrase` is the same values as you would provide ["make\_key"](#make_key) and `ca_cert` is the output from ["make\_cert"](#make_cert). The returned `$asset` is a [Path::Tiny](https://metacpan.org/pod/Path%3A%3ATiny) object which holds the generated certificate. It is possible to specify the location of this object by passing on `cert` to this method. ## subject $self = $self->subject(@subjects); $self = $self->subject("/C=NO/ST=Oslo/L=Oslo/O=Example/OU=Prime/emailAddress=admin@example.com", ...); $str = $self->subject; Holds the default subject field for the certificate. Can be set by passing in a list of subject strings, hashes or paths to certificate files. The list will get merged, soo the last one overrides the one before. ## with\_config $any = $self->with_config($method => \%args); Used to call a [method](#methods) with a temp ["openssl.cnf"](#openssl-cnf) file. The `%stash` in the template will be constructed from the `%args`, which is also passed on to the next `$method`. Example: $asset = $self->with_config(make_key => { home => "/path/to/pki", passphrase => "/path/to/pki/private/passphrase.txt", bits => 8192, }); The config file will be removed when `$self` go out of scope. An alternative to this method is to set the `OPENSSL_CONF` environment variable before calling `$method`: local $ENV{OPENSSL_CONF} = "/path/to/openssl.cnf"; $asset = $self->make_key({...}); # TEMPLATES ["render\_to\_file"](#render_to_file) can render these templates, which is bundled with this module: - crlnumber Creates a file which stores the SSL CRL number. If `n` is present in `%stash`, it will be used as the start number, which defaults to 1000. - index.txt This is currently just an empty file. - nginx.config Used to render an example nginx config. `%stash` should contain `cert`, `client_certificate`, `crl`, `key`, `server_name` and `verify_client`. - openssl.cnf Creates a config file for openssl. TODO: Descrive stash values. - serial Creates a file which stores the SSL serial number. If `n` is present in `%stash`, it will be used as the start number, which defaults to 1000. # COPYRIGHT AND LICENCE ## Code Copyright (C) Jan Henning Thorsen The code is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. ## Documentation Documentation is licensed under the terms of Creative Commons Attribution-ShareAlike 3.0 Unported license. The documentation is put together by Jan Henning Thorsen, with citations from Jamie Nguyen's website [https://jamielinux.com/](https://jamielinux.com/). # AUTHOR Jan Henning Thorsen - `jhthorsen@cpan.org`