forked from TrueCloudLab/certificates
Add initial docs for CAS.
This commit is contained in:
parent
072adc906e
commit
42ce78ed43
1 changed files with 212 additions and 0 deletions
212
docs/cas.md
Normal file
212
docs/cas.md
Normal file
|
@ -0,0 +1,212 @@
|
|||
# Certificate Management Services
|
||||
|
||||
This document describes how to use a certificate management service or CAS to
|
||||
sign X.509 certificates requests.
|
||||
|
||||
A CAS is a system that implements an API to sign certificate requests, the
|
||||
difference between CAS and KMS is that the latter can sign any data, while CAS
|
||||
is intended to sign only X.509 certificates.
|
||||
|
||||
`step-ca` defines an interface that can be implemented to support other
|
||||
services, currently only CloudCAS and the default SoftCAS are implemented.
|
||||
|
||||
The `CertificateAuthorityService` is defined in the package
|
||||
`github.com/smallstep/certificates/cas/apiv1` and it is:
|
||||
|
||||
```go
|
||||
type CertificateAuthorityService interface {
|
||||
CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error)
|
||||
RenewCertificate(req *RenewCertificateRequest) (*RenewCertificateResponse, error)
|
||||
RevokeCertificate(req *RevokeCertificateRequest) (*RevokeCertificateResponse, error)
|
||||
}
|
||||
```
|
||||
|
||||
The same package defines another interface that is used to get the root
|
||||
certificates from the CAS:
|
||||
|
||||
```go
|
||||
type CertificateAuthorityGetter interface {
|
||||
GetCertificateAuthority(req *GetCertificateAuthorityRequest) (*GetCertificateAuthorityResponse, error)
|
||||
}
|
||||
```
|
||||
|
||||
## SoftCAS
|
||||
|
||||
SoftCAS is the default implementation supported by `step-ca`. No special
|
||||
configurations are required to enable it.
|
||||
|
||||
SoftCAS generally uses certificates and keys in the filesystem, but a KMS can
|
||||
also be used instead of a key file for signing certificates. See [KMS](kms.md)
|
||||
for more information.
|
||||
|
||||
## CloudCAS
|
||||
|
||||
CloudCAS is the implementation of the `CertificateAuthorityService` and
|
||||
`CertificateAuthorityGetter` interfaces using [Google's Certificate Authority
|
||||
Service](https://cloud.google.com/certificate-authority-service/).
|
||||
|
||||
Before enabling CloudCAS in `step-ca` you do some steps in Google Cloud Console
|
||||
or using `gcloud` CLI:
|
||||
|
||||
1. Create or define a project to use. Let's say the name is `smallstep-cas-test`.
|
||||
2. Create the KMS keyring and keys for root and intermediate certificates:
|
||||
|
||||
```sh
|
||||
# Create key ring
|
||||
gcloud kms keyrings create kr1 --location us-west1
|
||||
# Create key for Root certificate
|
||||
gcloud kms keys create k1 \
|
||||
--location us-west1 \
|
||||
--keyring kr1 \
|
||||
--purpose asymmetric-signing \
|
||||
--default-algorithm ec-sign-p256-sha256 \
|
||||
--protection-level software
|
||||
# Create key for Intermediate certicate
|
||||
gcloud kms keys create k2 \
|
||||
--location us-west1 \
|
||||
--keyring kr1 \
|
||||
--purpose asymmetric-signing \
|
||||
--default-algorithm ec-sign-p256-sha256 \
|
||||
--protection-level software
|
||||
|
||||
# Put the resource name for version 1 of the new KMS keys into a shell variable.
|
||||
# This will be used in the other instructions below.
|
||||
KMS_ROOT_KEY_VERSION=$(gcloud kms keys versions describe 1 --key k1 --keyring kr1 --location us-west1 --format "value(name)")
|
||||
KMS_INTERMEDIATE_KEY_VERSION=$(gcloud kms keys versions describe 1 --key k2 --keyring kr1 --location us-west1 --format "value(name)")
|
||||
```
|
||||
|
||||
3. Enable the CA service API. You can do it on the console or running:
|
||||
|
||||
```sh
|
||||
gcloud services enable privateca.googleapis.com
|
||||
```
|
||||
|
||||
4. Configure IAM. Create a service account using Google Console or running:
|
||||
|
||||
```sh
|
||||
# Create service account
|
||||
gcloud iam service-accounts create step-ca-sa \
|
||||
--project smallstep-cas-test \
|
||||
--description "Step-CA Service Account" \
|
||||
--display-name "Step-CA Service Account"
|
||||
# Add permissions to use the privateca API
|
||||
gcloud projects add-iam-policy-binding smallstep-cas-test \
|
||||
--member=serviceAccount:step-ca-sa@smallstep-cas-test.iam.gserviceaccount.com \
|
||||
--role=roles/privateca.caManager
|
||||
# Download the credentials.file
|
||||
gcloud iam service-accounts keys create credentials.json \
|
||||
--iam-account step-ca-sa@smallstep-cas-test.iam.gserviceaccount.com
|
||||
```
|
||||
|
||||
5. Create a Root CA. You can do this on the console or running:
|
||||
|
||||
```sh
|
||||
gcloud alpha privateca roots create prod-root-ca \
|
||||
--kms-key-version "$KMS_ROOT_KEY_VERSION" \
|
||||
--subject "CN=Example Root CA, O=Example LLC" \
|
||||
--max-chain-length 2
|
||||
```
|
||||
|
||||
6. Create an Intermediate CA. You can do this on the console or running:
|
||||
|
||||
```sh
|
||||
gcloud alpha privateca subordinates create prod-intermediate-ca \
|
||||
--issuer prod-root-ca --issuer-location us-west1 \
|
||||
--kms-key-version "$KMS_INTERMEDIATE_KEY_VERSION" \
|
||||
--subject "CN=Example Intermediate CA, O=Example LLC" \
|
||||
--reusable-config "subordinate-server-tls-pathlen-0"
|
||||
```
|
||||
|
||||
Not it's time to enable it in `step-ca` adding the new property `"cas"` must be added
|
||||
to the `ca.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"cas": {
|
||||
"type": "cloudCAS",
|
||||
"credentialsFile": "/path/to/credentials.json",
|
||||
"certificateAuthority": "projects/<name>/locations/<loc>/certificateAuthorities/<ca-name>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* **type** defines the name of the CAS to use, _cloudCAS_ must be used to enable it.
|
||||
* **credentialsFile** defines the path to a Google Cloud credential file with
|
||||
access to Google's Certificate AuthorityService. We created this file before
|
||||
in step 4. Instead of setting this property, the environment variable
|
||||
`GOOGLE_APPLICATION_CREDENTIALS` can be pointed to the file to use. Or if the
|
||||
`step-ca` is running in Google Cloud, the default service account in the
|
||||
machine can also be used.
|
||||
* **certificateAuthority** defines the Google Cloud resource to the intermediate
|
||||
(or subordinated) certificate to use. We created this resource in step 6.
|
||||
|
||||
As we said before, the CloudCAS implementation in `step-ca` also defines the
|
||||
interface `CertificateAuthorityGetter`, this allows `step-ca` to automatically
|
||||
download the root certificate from Cloud CAS. In the `ca.json` now you don't
|
||||
need to configure `"root"`, and because the intermediate is in Google Cloud,
|
||||
`"crt"` and `"key"` are no needed. A full `ca.json` can look like:
|
||||
|
||||
```json
|
||||
{
|
||||
"address": ":443",
|
||||
"dnsNames": ["ca.example.com"],
|
||||
"logger": {"format": "text"},
|
||||
"db": {
|
||||
"type": "badger",
|
||||
"dataSource": "/home/jane/.step/db",
|
||||
},
|
||||
"cas": {
|
||||
"type": "cloudCAS",
|
||||
"credentialsFile": "/home/jane/.step/credentials.json",
|
||||
"certificateAuthority": "projects/smallstep-cas-test/locations/us-west1/certificateAuthorities/prod-intermediate-ca"
|
||||
},
|
||||
"authority": {
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "JWK",
|
||||
"name": "jane@example.com",
|
||||
"key": {
|
||||
"use": "sig",
|
||||
"kty": "EC",
|
||||
"kid": "ehFT9BkVOY5k_eIiMax0ZxVZCe2hlDVkMwZ2Y78av4s",
|
||||
"crv": "P-256",
|
||||
"alg": "ES256",
|
||||
"x": "GtEftN0_ED1lNc2SEUJDXV9EMi7JY-kqINPIEQJIkjM",
|
||||
"y": "8HYFdNe1MbWcbclF-hU1L80SCmMcZQI6vZfTOXfPOjg"
|
||||
},
|
||||
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiSjBSWnY5UFZrM3JKRUJkem5RbExzZyJ9.Fiwvo-RIKU5G6v5udeCT1nlX87ElxrocP2FcgNs3AqEz5OH9H4suew.NmzUJR_9xv8ynQC8.dqOveA_G5kn5lxjxnEZoJCystnJMVYLkZ_8CVzfJQhYchbZfNk_-FKdIuQxeWWBzvmomsILFNtLOIUoqSt30qk83lFyGQWN8Ke2bK5DhuwojF7RI_UqkMyiKP0F28Z4ZFhfQP5D2ZT_stoFaMlU8eak0-T8MOiBIfdAJTWM9x2DN-68mtUBuL5z5eU8bqsxELnjGauD_GHTdnduOosmYsw8vp_PmffTTwqUzDFH1RhkeSmRFRZntAizZMGYkxLamquHI3Jvuqiv4eeJ3yLqh3Ppyo_mVQKnxM7P9TyTxcvLkb2dB3K-cItl1fpsz92cy8euKsKG8n5-hKFRyPfY.j7jBN7nUwatoSsIZuNIwHA"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tls": {
|
||||
"cipherSuites": [
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
|
||||
],
|
||||
"minVersion": 1.2,
|
||||
"maxVersion": 1.3,
|
||||
"renegotiation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The we only need to run `step-ca` as usual, but this time, the CA will print the
|
||||
root fingerprint too:
|
||||
|
||||
```sh
|
||||
$ step-ca /home/jane/.step/config/ca.json
|
||||
2020/09/22 13:17:15 Using root fingerprint '3ef16343cf0952eedbe2b843066bb798fa7a7bceb16aa285e8b0399f661b28b7'
|
||||
2020/09/22 13:17:15 Serving HTTPS on :9000 ...
|
||||
```
|
||||
|
||||
We will need to bootstrap once our environment using the printed fingerprint:
|
||||
|
||||
```sh
|
||||
step ca bootstrap --ca-url https://ca.example.com --fingerprint 3ef16343cf0952eedbe2b843066bb798fa7a7bceb16aa285e8b0399f661b28b7
|
||||
```
|
||||
|
||||
And now we can sign sign a certificate as always:
|
||||
|
||||
```sh
|
||||
step ca certificate test.example.com test.crt test.key
|
||||
```
|
Loading…
Reference in a new issue