GithubHelp home page GithubHelp logo

ryankurte / pki Goto Github PK

View Code? Open in Web Editor NEW
70.0 6.0 8.0 69 KB

Scripts to bootstrap internal Certificate Authorities (CAs) using Yubikeys

License: MIT License

Shell 80.00% Batchfile 20.00%
pki ca certificate-authority yubikey

pki's Introduction

Bootstraping PKI with Yubikeys

Helper scripts to build and manage internal Certificate Authorities (CAs) with yubikey devices, because everybody needs a little bit of PKI, and we can definitely make it cheaper and easier to achieve.

This project is intended to be used as a template for the creation and management of certificate infrastructure, with CA information stored in git, and consists of a set of helper utilities to support the creation of root certificates, intermediate and end (client and certificate) Certificate Signing Requests (CSRs), as well as to load certificates and keys on to yubikeys and to use yubikeys to sign CSRs to create certificates.

This requires as many yubikeys as you would like to store certificates on, as well as an offline machine to generate the root keys and intermediate certificates. In future it may be possible to generate all keys on devices to aleviate this need for a trusted / airgapped machine.

Introduction

What is PKI?

PKI is Public Key Infrastructure, a method using cryptographic certificates to validate or authenticate services or devices. This works using a trust chain, whereby devices can trust a root Certificate Authority (CA), then any certificates issued by that authority can be validated against that root.

Why would you need it?

This is commonly used for HTTPS/TLS on the web, where certificate authorities are distributed as part of your operating system or browser, allowing transparent validation and secure connections through the web. Sometimes it is useful to have an internal certificate authority (or a few), for use between micro-services, or in manufacturing to ensure security with physical devices.

Why would we want to use yubikeys?

TODO

Status

Working on OSX, Linux, Some features supported on Windows (and PRs are welcome).

Dependencies

  • Git - to clone and manage the repository
  • OpenSSL - for key and certificate generation and signing
  • OpenSC - smartcard to pkcs11 adaptor
  • engine_pks11 - openssl pkcs11 engine
  • Yubico Manager for managing and interacting with keys

OSX: install with brew install openssl engine_pkcs11 opensc yubico-piv-tool. Linux: install with sudo apt install openssl opensc-pkcs11 libengine-pkcs11-openssl Windows: install with choco install openssl opensc, compile libp11 or grab a pre-compiled (win10, x64) libp11.dll from here, copy config from scripts/engine-win.conf to C:\Program Files\OpenSSL-Win64\openssl.cfg and update opensc-pkcs11.dll and pkcs11.dll locations to match installed.

Usage

First, create your own PKI git repository using this as a template, then use the following steps to create a Root / CA, Intermediate certificates, and Client or Server certificates.

Note that when deploying yubikeys you may wish to configure management and PIV pins to ensure that certificates are not mistakenly overwritten, and are only used by authorized parties. We recommend you read this getting started guide for PIV on yubikeys before getting underway.

Creating a new Certificate Authority (Root Certificate)

  1. Run mkdir CA_NAME to create a new directory for your CA
  2. Run cp example-ca/config CA_NAME/config to copy the example config to your new CA directory
  3. Edit CA_NAME/config to configure your CA
  4. Run ./scripts/new-ca.sh CA_NAME "Human Description" to create the root certificate
  5. Run ./scripts/yk-load CA_NAME CA_NAME to load the root certificate onto a connected yubikey
  6. Run rm CA_NAME/CA_NAME.key to remove CA key from the system
  7. Run git add CA_NAME/ to add your new CA to version control

Creating a new Intermediate Certificate

  1. Run ./scripts/new-int.sh CA_NAME INT_NAME "Human Description" to create a new intermediate CSR under the provided CA
  2. Run ./scripts/yk-sign-int.sh CA_NAME INT_NAME to sign the intermediate CSR using the root yubikey
  • You will need to enter the device pin and press the button on the yubikey when the light flashes to authorize the signing
  1. Disconnect the attached root yubikey and replace it with a new intermediate yubikey
  2. Run ./scripts/yk-load CA_NAME INT_NAME to load the CA onto a connected yubikey
  3. Run rm CA_NAME/INT_NAME.key to remove intermediate key from the system
  4. Run git add CA_NAME/INT_NAME.* to add your new intermediate to version control

Note that steps 4-6 can be elided if you need to do something else with your intermediate certificate

Creating a new End Certificate

  1. Run ./scripts/new-client.sh CA_NAME CLIENT_NAME or ./scripts/new-server.sh CA_NAME SERVER_NAME to create a new client or server cerficiate respectively
    • Note that server names are checked when making tls connections, so the server name must match the domain name
  2. Run ./scripts/yk-sign-end.sh CA_NAME END_NAME to sign the client or server CSR using an intermediate yubikey
  • You will need to enter the device pin and press the button on the yubikey when the light flashes to authorize the signing
  1. Run git add CA_NAME/END_NAME.crt to add your new certificate to version control
  2. Do whatever you choose with the created certificate

Creating a new End (Client) Certificate (Windows)

  1. Copy ./templates/client.cfg.tmpl to CA_NAME/CLIENT_NAME.cfg
  2. Run ./scripts/new-client.cmd CA_NAME INT_NAME CLIENT_NAME to generate and sign the new client certificate with the provided intermediate (on the yubikey)

Resources


If you have any questions, comments, or suggestions, feel free to open an issue or a pull request.

pki's People

Contributors

nopdotcom avatar ryankurte avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pki's Issues

Intermediate CA build issues

When building the Intermediate CA with the build-int.sh there are a couple of errors.

  1. Your instructions indicate passing in 3 variables but the code on build-int.sh (line 9) only expects 2
    if [ "$#" -ne 2 ]; then
    this obviously generates an error and the code quits

  2. If i omit the key name and just pass the intermediate CA cert name i get as far as
    yk_sign_ca $DIR/yk-ca.crt $DIR/$FILE.csr $DIR/$FILE.conf $DIR/$FILE.crt
    cat $DIR/roots.crt $DIR/$FILE.crt > $DIR/$FILE-chain.crt
    before receiving these errors ........
    PKCS11 library:PKCS11_rsa_sign:User not logged in:p11_ops.c:131:
    asn1 encoding routines:ASN1_item_sign_ctx:EVP lib:a_sign.c:306:

Windows certificate generation

Client certificate generation using windows is required for production-line deployment.

OpenSC provide a minidriver and pkcs#11 module for windows, providers can be listed using certutil -csplist

Request information specified using INF files:

[NewRequest] 
; At least one value must be set in this section 
Subject = "CN=test-client-cert,[email protected],OU=TestOrg_UNIT,0=TestOrg,S=TestCity,c=CN"

HashAlgorithm = Sha512
KeyAlgorithm = RSA
KeyLength = 2048
KeyUsage = "CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_KEY_ENCIPHERMENT_KEY_USAGE | CERT_KEY_AGREEMENT_KEY_USAGE"
RequestType=PKCS10

Create a CSR using certreq -new client.inf client.req

Signing via certutil -sign .\client.req client.crt locates the correct certificate, but, fails with:

CertUtil: -sign command FAILED: 0x80090014 (-2146893804 NTE_BAD_PROV_TYPE)
CertUtil: Invalid provider type specified.

And I don't know how to get the private key in this instance either...

Possibly should try using openssl with opensc-pkcs#11 :-/

Get CRLs working

Revocation / CRL generation is working, but the CRLs aren't matching up with issued certs which is a bit of a problem...

On device keys with certificate generation

Related to PR #1, behaviour of OpenSSL / Libp11 appears to preclude generation of a self signed root certificates using engine_pks11 as the modulus used in the CSR is that of the existing certificate in the slot, not the key on the device.

Existing (previous) modulus (for externally generated key + cert presigned then loaded onto device)
screen shot 2017-01-18 at 3 08 21 pm

Replaced key, modulus output from onboard key generation with yubico-piv-tool -s 9c -A RSA2048 -a generate -o $DIR/ca1-root.pem --touch-policy=never

screen shot 2017-01-18 at 3 11 53 pm

Generated certificate using req -engine pkcs11 -keyform engine -key slot_0-id_2 -passin pass:$PIN -x509 -new -nodes -$HASH -days 36500 -verify -config $1 -out $2 with engine_pks11 as in on-device-keys/common.sh

screen shot 2017-01-18 at 3 12 54 pm

Generated certificate modulus is that of the previously installed cert, not the locally created keypair.

Removing the certificate from the slot in use (9c) with yubico-piv-tool -a delete-certificate -s causes locating the private key to fail, confirming that it is loading the key based on the modulus of the existing certificate.

screen shot 2017-01-18 at 3 21 09 pm

The openssh command uses the slot id to fetch the key, maybe there is another way of specifying this?
screen shot 2017-01-18 at 3 32 14 pm

The yubico-piv-tool does manage to create / sign certificates on device, so it has to be possible. May need to look into PIV tool extensions, passing full certificate configs to the tool would mitigate the need for raw OpenSSL calls when generating root CAs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.