| # CFSSL |
| |
| [![Build Status](https://travis-ci.org/cloudflare/cfssl.svg?branch=master)](https://travis-ci.org/cloudflare/cfssl) |
| [![Coverage Status](http://codecov.io/github/cloudflare/cfssl/coverage.svg?branch=master)](http://codecov.io/github/cloudflare/cfssl?branch=master) |
| [![GoDoc](https://godoc.org/github.com/cloudflare/cfssl?status.svg)](https://godoc.org/github.com/cloudflare/cfssl) |
| |
| ## CloudFlare's PKI/TLS toolkit |
| |
| CFSSL is CloudFlare's PKI/TLS swiss army knife. It is both a command line |
| tool and an HTTP API server for signing, verifying, and bundling TLS |
| certificates. It requires Go 1.8+ to build. |
| |
| Note that certain linux distributions have certain algorithms removed |
| (RHEL-based distributions in particular), so the golang from the |
| official repositories will not work. Users of these distributions should |
| [install go manually](//golang.org/dl) to install CFSSL. |
| |
| CFSSL consists of: |
| |
| * a set of packages useful for building custom TLS PKI tools |
| * the `cfssl` program, which is the canonical command line utility |
| using the CFSSL packages. |
| * the `multirootca` program, which is a certificate authority server |
| that can use multiple signing keys. |
| * the `mkbundle` program is used to build certificate pool bundles. |
| * the `cfssljson` program, which takes the JSON output from the |
| `cfssl` and `multirootca` programs and writes certificates, keys, |
| CSRs, and bundles to disk. |
| |
| ### Building |
| |
| See [BUILDING](BUILDING.md) |
| |
| ### Installation |
| |
| Installation requires a |
| [working Go 1.8+ installation](http://golang.org/doc/install) and a |
| properly set `GOPATH`. |
| |
| ``` |
| $ go get -u github.com/cloudflare/cfssl/cmd/cfssl |
| ``` |
| |
| will download and build the CFSSL tool, installing it in |
| `$GOPATH/bin/cfssl`. |
| |
| To install any of the other utility programs that are |
| in this repo (for instance `cffsljson` in this case): |
| |
| ``` |
| $ go get -u github.com/cloudflare/cfssl/cmd/cfssljson |
| ``` |
| |
| This will download and build the CFSSLJSON tool, installing it in |
| `$GOPATH/bin/`. |
| |
| And to simply install __all__ of the programs in this repo: |
| |
| ``` |
| $ go get -u github.com/cloudflare/cfssl/cmd/... |
| ``` |
| |
| This will download, build, and install all of the utility programs |
| (including `cfssl`, `cfssljson`, and `mkbundle` among others) into the |
| `$GOPATH/bin/` directory. |
| |
| ### Using the Command Line Tool |
| |
| The `cfssl` command line tool takes a command to specify what |
| operation it should carry out: |
| |
| sign signs a certificate |
| bundle build a certificate bundle |
| genkey generate a private key and a certificate request |
| gencert generate a private key and a certificate |
| serve start the API server |
| version prints out the current version |
| selfsign generates a self-signed certificate |
| print-defaults print default configurations |
| |
| Use `cfssl [command] -help` to find out more about a command. |
| The `version` command takes no arguments. |
| |
| #### Signing |
| |
| ``` |
| cfssl sign [-ca cert] [-ca-key key] [-hostname comma,separated,hostnames] csr [subject] |
| ``` |
| |
| The `csr` is the client's certificate request. The `-ca` and `-ca-key` |
| flags are the CA's certificate and private key, respectively. By |
| default, they are `ca.pem` and `ca_key.pem`. The `-hostname` is |
| a comma separated hostname list that overrides the DNS names and |
| IP address in the certificate SAN extension. |
| For example, assuming the CA's private key is in |
| `/etc/ssl/private/cfssl_key.pem` and the CA's certificate is in |
| `/etc/ssl/certs/cfssl.pem`, to sign the `cloudflare.pem` certificate |
| for cloudflare.com: |
| |
| ``` |
| cfssl sign -ca /etc/ssl/certs/cfssl.pem \ |
| -ca-key /etc/ssl/private/cfssl_key.pem \ |
| -hostname cloudflare.com \ |
| ./cloudflare.pem |
| ``` |
| |
| It is also possible to specify CSR with the `-csr` flag. By doing so, |
| flag values take precedence and will overwrite the argument. |
| |
| The subject is an optional file that contains subject information that |
| should be used in place of the information from the CSR. It should be |
| a JSON file as follows: |
| |
| ```json |
| { |
| "CN": "example.com", |
| "names": [ |
| { |
| "C": "US", |
| "L": "San Francisco", |
| "O": "Internet Widgets, Inc.", |
| "OU": "WWW", |
| "ST": "California" |
| } |
| ] |
| } |
| ``` |
| |
| **N.B.** As of Go 1.7, self-signed certificates will not include |
| [the AKI](https://go.googlesource.com/go/+/b623b71509b2d24df915d5bc68602e1c6edf38ca). |
| |
| #### Bundling |
| |
| ``` |
| cfssl bundle [-ca-bundle bundle] [-int-bundle bundle] \ |
| [-metadata metadata_file] [-flavor bundle_flavor] \ |
| -cert certificate_file [-key key_file] |
| ``` |
| |
| The bundles are used for the root and intermediate certificate |
| pools. In addition, platform metadata is specified through `-metadata`. |
| The bundle files, metadata file (and auxiliary files) can be |
| found at: |
| |
| https://github.com/cloudflare/cfssl_trust |
| |
| Specify PEM-encoded client certificate and key through `-cert` and |
| `-key` respectively. If key is specified, the bundle will be built |
| and verified with the key. Otherwise the bundle will be built |
| without a private key. Instead of file path, use `-` for reading |
| certificate PEM from stdin. It is also acceptable that the certificate |
| file should contain a (partial) certificate bundle. |
| |
| Specify bundling flavor through `-flavor`. There are three flavors: |
| `optimal` to generate a bundle of shortest chain and most advanced |
| cryptographic algorithms, `ubiquitous` to generate a bundle of most |
| widely acceptance across different browsers and OS platforms, and |
| `force` to find an acceptable bundle which is identical to the |
| content of the input certificate file. |
| |
| Alternatively, the client certificate can be pulled directly from |
| a domain. It is also possible to connect to the remote address |
| through `-ip`. |
| |
| ``` |
| cfssl bundle [-ca-bundle bundle] [-int-bundle bundle] \ |
| [-metadata metadata_file] [-flavor bundle_flavor] \ |
| -domain domain_name [-ip ip_address] |
| ``` |
| |
| The bundle output form should follow the example: |
| |
| ```json |
| { |
| "bundle": "CERT_BUNDLE_IN_PEM", |
| "crt": "LEAF_CERT_IN_PEM", |
| "crl_support": true, |
| "expires": "2015-12-31T23:59:59Z", |
| "hostnames": ["example.com"], |
| "issuer": "ISSUER CERT SUBJECT", |
| "key": "KEY_IN_PEM", |
| "key_size": 2048, |
| "key_type": "2048-bit RSA", |
| "ocsp": ["http://ocsp.example-ca.com"], |
| "ocsp_support": true, |
| "root": "ROOT_CA_CERT_IN_PEM", |
| "signature": "SHA1WithRSA", |
| "subject": "LEAF CERT SUBJECT", |
| "status": { |
| "rebundled": false, |
| "expiring_SKIs": [], |
| "untrusted_root_stores": [], |
| "messages": [], |
| "code": 0 |
| } |
| } |
| ``` |
| |
| |
| #### Generating certificate signing request and private key |
| |
| ``` |
| cfssl genkey csr.json |
| ``` |
| |
| To generate a private key and corresponding certificate request, specify |
| the key request as a JSON file. This file should follow the form: |
| |
| ```json |
| { |
| "hosts": [ |
| "example.com", |
| "www.example.com" |
| ], |
| "key": { |
| "algo": "rsa", |
| "size": 2048 |
| }, |
| "names": [ |
| { |
| "C": "US", |
| "L": "San Francisco", |
| "O": "Internet Widgets, Inc.", |
| "OU": "WWW", |
| "ST": "California" |
| } |
| ] |
| } |
| ``` |
| |
| #### Generating self-signed root CA certificate and private key |
| |
| ``` |
| cfssl genkey -initca csr.json | cfssljson -bare ca |
| ``` |
| |
| To generate a self-signed root CA certificate, specify the key request as |
| a JSON file in the same format as in 'genkey'. Three PEM-encoded entities |
| will appear in the output: the private key, the csr, and the self-signed |
| certificate. |
| |
| #### Generating a remote-issued certificate and private key. |
| |
| ``` |
| cfssl gencert -remote=remote_server [-hostname=comma,separated,hostnames] csr.json |
| ``` |
| |
| This calls `genkey` but has a remote CFSSL server sign and issue |
| the certificate. You may use `-hostname` to override certificate SANs. |
| |
| #### Generating a local-issued certificate and private key. |
| |
| ``` |
| cfssl gencert -ca cert -ca-key key [-hostname=comma,separated,hostnames] csr.json |
| ``` |
| |
| This generates and issues a certificate and private key from a local CA |
| via a JSON request. You may use `-hostname` to override certificate SANs. |
| |
| |
| #### Updating an OCSP responses file with a newly issued certificate |
| |
| ``` |
| cfssl ocspsign -ca cert -responder key -responder-key key -cert cert \ |
| | cfssljson -bare -stdout >> responses |
| ``` |
| |
| This will generate an OCSP response for the `cert` and add it to the |
| `responses` file. You can then pass `responses` to `ocspserve` to start an |
| OCSP server. |
| |
| ### Starting the API Server |
| |
| CFSSL comes with an HTTP-based API server; the endpoints are |
| documented in `doc/api/intro.txt`. The server is started with the `serve` |
| command: |
| |
| ``` |
| cfssl serve [-address address] [-ca cert] [-ca-bundle bundle] \ |
| [-ca-key key] [-int-bundle bundle] [-int-dir dir] [-port port] \ |
| [-metadata file] [-remote remote_host] [-config config] \ |
| [-responder cert] [-responder-key key] [-db-config db-config] |
| ``` |
| |
| Address and port default to "127.0.0.1:8888". The `-ca` and `-ca-key` |
| arguments should be the PEM-encoded certificate and private key to use |
| for signing; by default, they are `ca.pem` and `ca_key.pem`. The |
| `-ca-bundle` and `-int-bundle` should be the certificate bundles used |
| for the root and intermediate certificate pools, respectively. These |
| default to `ca-bundle.crt` and `int-bundle.crt` respectively. If the |
| `-remote` option is specified, all signature operations will be forwarded |
| to the remote CFSSL. |
| |
| `-int-dir` specifies an intermediates directory. `-metadata` is a file for |
| root certificate presence. The content of the file is a json dictionary |
| (k,v) such that each key k is an SHA-1 digest of a root certificate while value v |
| is a list of key store filenames. `-config` specifies a path to a configuration |
| file. `-responder` and `-responder-key` are the certificate and the |
| private key for the OCSP responder, respectively. |
| |
| The amount of logging can be controlled with the `-loglevel` option. This |
| comes *after* the serve command: |
| |
| ``` |
| cfssl serve -loglevel 2 |
| ``` |
| |
| The levels are: |
| |
| * 0 - DEBUG |
| * 1 - INFO (this is the default level) |
| * 2 - WARNING |
| * 3 - ERROR |
| * 4 - CRITICAL |
| |
| ### The multirootca |
| |
| The `cfssl` program can act as an online certificate authority, but it |
| only uses a single key. If multiple signing keys are needed, the |
| `multirootca` program can be used. It only provides the `sign`, |
| `authsign` and `info` endpoints. The documentation contains instructions |
| for configuring and running the CA. |
| |
| ### The mkbundle Utility |
| |
| `mkbundle` is used to build the root and intermediate bundles used in |
| verifying certificates. It can be installed with |
| |
| ``` |
| go get -u github.com/cloudflare/cfssl/cmd/mkbundle |
| ``` |
| |
| It takes a collection of certificates, checks for CRL revocation (OCSP |
| support is planned for the next release) and expired certificates, and |
| bundles them into one file. It takes directories of certificates and |
| certificate files (which may contain multiple certificates). For example, |
| if the directory `intermediates` contains a number of intermediate |
| certificates: |
| |
| ``` |
| mkbundle -f int-bundle.crt intermediates |
| ``` |
| |
| will check those certificates and combine valid certificates into a single |
| `int-bundle.crt` file. |
| |
| The `-f` flag specifies an output name; `-loglevel` specifies the verbosity |
| of the logging (using the same loglevels as above), and `-nw` controls the |
| number of revocation-checking workers. |
| |
| ### The cfssljson Utility |
| |
| Most of the output from `cfssl` is in JSON. The `cfssljson` utility can take |
| this output and split it out into separate `key`, `certificate`, `CSR`, and |
| `bundle` files as appropriate. The tool takes a single flag, `-f`, that |
| specifies the input file, and an argument that specifies the base name for |
| the files produced. If the input filename is `-` (which is the default), |
| cfssljson reads from standard input. It maps keys in the JSON file to |
| filenames in the following way: |
| |
| * if __cert__ or __certificate__ is specified, __basename.pem__ will be produced. |
| * if __key__ or __private_key__ is specified, __basename-key.pem__ will be produced. |
| * if __csr__ or __certificate_request__ is specified, __basename.csr__ will be produced. |
| * if __bundle__ is specified, __basename-bundle.pem__ will be produced. |
| * if __ocspResponse__ is specified, __basename-response.der__ will be produced. |
| |
| Instead of saving to a file, you can pass `-stdout` to output the encoded |
| contents to standard output. |
| |
| ### Static Builds |
| |
| By default, the web assets are accessed from disk, based on their |
| relative locations. If you wish to distribute a single, |
| statically-linked, `cfssl` binary, you’ll want to embed these resources |
| before building. This can by done with the |
| [go.rice](https://github.com/GeertJohan/go.rice) tool. |
| |
| ``` |
| pushd cli/serve && rice embed-go && popd |
| ``` |
| |
| Then building with `go build` will use the embedded resources. |
| |
| ### Using a PKCS#11 hardware token / HSM |
| |
| For better security, you may wish to store your private key in an HSM or |
| smartcard. The interface to both of these categories of device is described by |
| the PKCS#11 spec. If you need to do approximately one signing operation per |
| second or fewer, the Yubikey NEO and NEO-n are inexpensive smartcard options: |
| |
| https://www.yubico.com/products/yubikey-hardware/yubikey-neo/ |
| |
| In general you should look for a product that supports PIV (personal identity verification). If |
| your signing needs are in the hundreds of signatures per second, you will need |
| to purchase an expensive HSM (in the thousands to many thousands of USD). |
| |
| If you wish to try out the PKCS#11 signing modes without a hardware token, you |
| can use the [SoftHSM](https://github.com/opendnssec/SoftHSMv1#softhsm) |
| implementation. Please note that using SoftHSM simply stores your private key in |
| a file on disk and does not increase security. |
| |
| To get started with your PKCS#11 token you will need to initialize it with a |
| private key, PIN, and token label. The instructions to do this will be specific |
| to each hardware device, and you should follow the instructions provided by your |
| vendor. You will also need to find the path to your `module`, a shared object |
| file (.so). Having initialized your device, you can query it to check your token |
| label with: |
| |
| pkcs11-tool --module <module path> --list-token-slots |
| |
| You'll also want to check the label of the private key you imported (or |
| generated). Run the following command and look for a `Private Key Object`: |
| |
| pkcs11-tool --module <module path> --pin <pin> \ |
| --list-token-slots --login --list-objects |
| |
| You now have all the information you need to use your PKCS#11 token with CFSSL. |
| CFSSL supports PKCS#11 for certificate signing and OCSP signing. To create a |
| Signer (for certificate signing), import `signer/universal` and call NewSigner |
| with a Root object containing the module, pin, token label and private label |
| from above, plus a path to your certificate. The structure of the Root object is |
| documented in `universal.go`. |
| |
| Alternately, you can construct a pkcs11key.Key or pkcs11key.Pool yourself, and |
| pass it to ocsp.NewSigner (for OCSP) or local.NewSigner (for certificate |
| signing). This will be necessary, for example, if you are using a single-session |
| token like the Yubikey and need both OCSP signing and certificate signing at the |
| same time. |
| |
| ### Additional Documentation |
| |
| Additional documentation can be found in the "doc" directory: |
| |
| * `api/intro.txt`: documents the API endpoints |
| * `bootstrap.txt`: a walkthrough from building the package to getting |
| up and running |