NAME
    App::sslmaker - Be your own SSL certificate authority

VERSION
    0.02

DESCRIPTION
    App::sslmaker 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/blog/category/CA/>.

    This module is used by the "sslmaker" command line application, but can
    also act as a standalone toolkit.

    From
    <https://jamielinux.com/articles/2013/08/act-as-your-own-certificate-aut
    hority/>:

      Most websites, such as shopping, banking or email websites, need to let their
      customers know that the connection is secure. Thus, they need to pay a
      well-known and internationally trusted CA (eg, VeriSign) to issue an SSL
      certificate. However, this isn't always necessary. For example, if you're
      setting up a virtual private network (VPN) or an intranet website, it might
      make more sense to issue your own certificates.

      Being a CA means dealing with cryptographic pairs of private keys and public
      certificates. Ideally the cryptographic pairs should be generated in a secure
      environment, which means a personal laptop or computer that is disconnected
      from the Internet. It is not recommended to generate any certificates
      directly on your server.

DISCLAIMER
    This module is based on tips and tricks from online resources, and has
    been reviewed by security experts. Even so, the "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.

COMMAND LINE USAGE
      $ sslmaker [options] {action} {arg1,...}

      # Generate root CA key and certificate
      $ sslmaker --home /path/to/pki/CA root

      # Generate intermediate CA key and certificate
      $ sslmaker --root-home /path/to/pki/CA --home /path/to/pki/intermediate intermediate

      # Generate client or server key and certificate signing request
      $ sslmaker --home /path/to/pki/intermediate generate <commonName>
      $ sslmaker --home /path/to/pki/intermediate generate www.example.com
      $ sslmaker --home /path/to/pki/intermediate nginx www.example.com

      # Sign a certificate signing request
      $ sslmaker --home /path/to/pki/intermediate sign www.example.com.csr.pem [outfile]

SYNOPSIS
      my $sslmaker = App::sslmaker->new;

      my $asset = $sslmaker->make_csr({
                    key => "/path/to/private/input.key.pem",
                    passphrase => "/path/to/passphrase.txt",
                    subject => '/C=NO/ST=Oslo',
                  });

      # the content of the csr
      print $asset->slurp;

      # move to a non-temp location
      $asset->move("/path/to/certs/output.csr.pem");

    All methods will throw an exception on error, unless otherwise noted.

ATTRIBUTES
  subject
      $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 certificates.

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". "passphrase" should match the argument given to "make_key".
    An optional "subject" can be provided. The subject string will be merged
    with the "subject" attribute. "days" can be used to set how many days
    the certificate should be valid.

    The returned $asset is a Path::Tiny 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". "passphrase" should match the argument
    given to "make_key".

    The returned $asset is a Path::Tiny 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".

  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". "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"
    attribute.

    The returned $asset is a Path::Tiny 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.

      $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 object which holds the generated
    key. It is possible to specify the location of this object by passing on
    "key" to this method.

    From
    <https://jamielinux.com/articles/2013/08/act-as-your-own-certificate-aut
    hority/>:

      The very first cryptographic pair we generate includes what is known as a
      root certificate. The root key (ca.key.pem) generated in this step should be
      kept extremely secure, otherwise an attacker can issue valid certificates for
      themselves. We'll therefore protect it with AES 256-bit encryption and a
      strong password just in case it falls into the wrong hands.

  new
      $self = App::sslmaker->new(%args);
      $self = App::sslmaker->new(\%args);

    Object constructor.

  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" 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".

  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". "ca_key" and
    "passphrase" is the same values as you would provide "make_key" and
    "ca_cert" is the output from "make_cert".

    The returned $asset is a Path::Tiny object which holds the generated
    certificate. It is possible to specify the location of this object by
    passing on "cert" to this method.

  with_config
      $any = $self->with_config($method => \%args);

    Used to call a method with a temp "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" 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) 2014, 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/>.

AUTHOR
    Jan Henning Thorsen - "jhthorsen@cpan.org"

