Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds cert-utility. #1870

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

ianhundere
Copy link

@ianhundere ianhundere commented Nov 21, 2024

closes #1869

Summary

currently, there is no standard method for creating cert chains for fulcio or tsa. the community has used an assortment of open source scripts/tools, but i thought it would be nice to have a small cloud agnostic go app to create/sign (via awskms, gcpkms, or azurekms) certificates. the smallstep crypto library is fairly comprehensive in its kms/cert capabilities.

@haydentherapper / @bobcallaway gave the go ahead in proceeding w/ this work.

Release Note

  • Adds certificate utility to create and sign certificates via AWS KMS, Google Cloud KMS, or Azure Key Vault.

Documentation

Overview

This tool creates root, intermediate (optional), and leaf certificates for Fulcio (compliant to Fulcio's certificate requirements):

  • Two-level chain (root -> leaf)
  • Three-level chain (root -> intermediate -> leaf)

Requirements

  • Access to one of the supported KMS providers (AWS, Google Cloud, Azure)
  • Pre-existing KMS keys (the tool uses existing keys and does not create new ones)

Local Development

Clone and build the project locally:

# Clone the repository
git clone https://github.com/sigstore/fulcio

# Change to project directory
cd fulcio

# Build the binary
go build -o fulcio-certificate-maker ./cmd/certificate_maker

Usage

The tool can be configured using either command-line flags or environment variables.

Command-Line Interface

Available flags:

  • --kms-type: KMS provider type (awskms, gcpkms, azurekms)

  • --root-key-id: KMS key identifier for root certificate

  • --leaf-key-id: KMS key identifier for leaf certificate

  • --aws-region: AWS region (required for AWS KMS)

  • --azure-tenant-id: Azure KMS tenant ID

  • --gcp-credentials-file: Path to credentials file (for Google Cloud KMS)

  • --root-template: Path to root certificate template

  • --leaf-template: Path to leaf certificate template

  • --root-cert: Output path for root certificate (default: root.pem)

  • --leaf-cert: Output path for leaf certificate (default: leaf.pem)

  • --intermediate-key-id: KMS key identifier for intermediate certificate

  • --intermediate-template: Path to intermediate certificate template

  • --intermediate-cert: Output path for intermediate certificate

Environment Variables

  • KMS_TYPE: KMS provider type ("awskms", "gcpkms", "azurekms")

  • ROOT_KEY_ID: Key identifier for root certificate

  • KMS_INTERMEDIATE_KEY_ID: Key identifier for intermediate certificate

  • LEAF_KEY_ID: Key identifier for leaf certificate

  • AWS_REGION: AWS Region (required for AWS KMS)

  • AZURE_TENANT_ID: Azure tenant ID

  • GCP_CREDENTIALS_FILE: Path to credentials file (for Google Cloud KMS)

Certificate Templates

The tool uses JSON templates to define certificate properties:

  • root-template.json: Defines root CA certificate properties
  • intermediate-template.json: Defines intermediate CA certificate properties (when using --intermediate-key-id)
  • leaf-template.json: Defines leaf certificate properties

Templates are located in pkg/certmaker/templates/.

Note: Templates use standard JSON format with code signing extensions.

Provider-Specific Configuration Examples

AWS KMS

export KMS_TYPE=awskms
export AWS_REGION=us-east-1
export ROOT_KEY_ID=alias/root-key
export KMS_INTERMEDIATE_KEY_ID=alias/intermediate-key
export LEAF_KEY_ID=alias/leaf-key

Google Cloud KMS

export KMS_TYPE=gcpkms
export ROOT_KEY_ID=projects/PROJECT_ID/locations/LOCATION/keyRings/KEYRING/cryptoKeys/KEY_NAME/cryptoKeyVersions/VERSION
export LEAF_KEY_ID=projects/PROJECT_ID/locations/LOCATION/keyRings/KEYRING/cryptoKeys/KEY_NAME/cryptoKeyVersions/VERSION
export KMS_INTERMEDIATE_KEY_ID=projects/PROJECT_ID/locations/LOCATION/keyRings/KEYRING/cryptoKeys/KEY_NAME/cryptoKeyVersions/VERSION

Azure KMS

export KMS_TYPE=azurekms
export ROOT_KEY_ID=azurekms:name=root-key;vault=fulcio-keys
export KMS_INTERMEDIATE_KEY_ID=azurekms:name=leaf-key;vault=fulcio-keys
export LEAF_KEY_ID=azurekms:name=leaf-key;vault=fulcio-keys
export AZURE_TENANT_ID=83j229-83j229-83j229-83j229-83j229

Example Certificate Outputs

Fulcio Leaf Certificate

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1733012039 (0x674baa47)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, O=Sigstore, OU=Fulcio Intermediate CA, CN=https://fulcio.com
        Validity
            Not Before: Jan  1 00:00:00 2024 GMT
            Not After : Jan  1 00:00:00 2034 GMT
        Subject: C=US, O=Sigstore, OU=Fulcio Leaf CA, CN=https://fulcio.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:f8:ca:84:0d:9d:31:da:d0:94:1f:2a:53:ff:3f:
                    f2:39:ca:90:5b:8c:26:29:28:02:a7:e2:10:80:92:
                    1b:9f:3a:03:c7:cd:36:7a:2c:2b:1c:0c:95:bc:86:
                    73:b4:55:46:0e:50:29:34:1e:07:a6:64:41:13:ca:
                    36:5d:d4:71:dd
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                Code Signing
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                0D:1B:3F:95:18:04:65:60:AD:E3:28:D0:B7:43:45:BD:FE:63:5A:DF
            X509v3 Authority Key Identifier:
                0D:1B:3F:95:18:04:65:60:AD:E3:28:D0:B7:43:45:BD:FE:63:5A:DF
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:46:02:21:00:e5:98:16:cd:93:2c:20:73:e3:b6:62:4a:25:
        40:c0:e0:68:fb:4a:70:ce:89:09:6c:cd:b6:c6:2c:ee:66:40:
        6f:02:21:00:eb:b7:53:99:60:2a:92:d2:90:39:73:f8:98:18:
        96:2c:fe:cb:ac:5b:63:36:fe:5d:75:9b:da:69:b9:9b:c6:fb

Fulcio Intermediate CA Certificate

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1733012039 (0x674baa47)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, O=Sigstore, OU=Fulcio Root CA, CN=https://fulcio.com
        Validity
            Not Before: Jan  1 00:00:00 2024 GMT
            Not After : Jan  1 00:00:00 2034 GMT
        Subject: C=US, O=Sigstore, OU=Fulcio Intermediate CA, CN=https://fulcio.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:f8:ca:84:0d:9d:31:da:d0:94:1f:2a:53:ff:3f:
                    f2:39:ca:90:5b:8c:26:29:28:02:a7:e2:10:80:92:
                    1b:9f:3a:03:c7:cd:36:7a:2c:2b:1c:0c:95:bc:86:
                    73:b4:55:46:0e:50:29:34:1e:07:a6:64:41:13:ca:
                    36:5d:d4:71:dd
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Extended Key Usage:
                Code Signing
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:0
            X509v3 Subject Key Identifier:
                0D:1B:3F:95:18:04:65:60:AD:E3:28:D0:B7:43:45:BD:FE:63:5A:DF
            X509v3 Authority Key Identifier:
                BB:84:41:46:F0:A6:90:38:C0:73:1E:11:F4:58:7C:44:9B:C6:45:89
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:46:02:21:00:88:2b:2a:68:f1:61:34:4b:e5:f2:24:26:3c:
        64:1c:80:94:94:02:e1:78:a1:ea:6c:1b:92:a7:54:b2:88:52:
        90:02:21:00:a6:7d:ef:04:ba:2a:5b:a9:f6:b7:c8:02:1e:9f:
        78:2c:15:09:bd:b3:93:d9:6b:b2:ba:43:6e:b9:61:61:ea:8a

Fulcio Root CA Certificate

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1733012038 (0x674baa46)
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, O=Sigstore, OU=Fulcio Root CA, CN=https://fulcio.com
        Validity
            Not Before: Jan  1 00:00:00 2024 GMT
            Not After : Jan  1 00:00:00 2034 GMT
        Subject: C=US, O=Sigstore, OU=Fulcio Root CA, CN=https://fulcio.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:73:77:29:2b:48:de:da:82:53:60:36:ac:9e:b7:
                    e1:78:3e:e1:d6:58:f1:7e:fa:b2:2a:28:c5:c8:d4:
                    25:c6:e8:5c:d1:63:a8:22:3e:a6:7b:bb:3b:d7:f3:
                    98:c8:25:52:12:2a:c1:fb:9b:56:af:97:77:a4:48:
                    89:be:49:bc:63
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE, pathlen:1
            X509v3 Subject Key Identifier:
                BB:84:41:46:F0:A6:90:38:C0:73:1E:11:F4:58:7C:44:9B:C6:45:89
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        30:45:02:21:00:d5:82:3b:01:64:9f:f3:f3:b1:d6:44:43:1f:
        78:2d:7f:b8:c9:e9:0e:7e:34:9f:8c:55:33:09:14:2a:16:c5:
        b2:02:20:04:a5:a2:49:ee:3b:22:4c:f5:5b:b3:9b:ff:b4:40:
        dc:f6:a3:11:00:05:a3:14:d5:77:72:f6:f9:44:f1:e9:27

Running the Tool

Example with AWS KMS:

fulcio-certificate-maker  create \
  --kms-type awskms \
  --aws-region us-east-1 \
  --root-key-id alias/fulcio-root \
  --leaf-key-id alias/fulcio-leaf \
  --root-template pkg/certmaker/templates/root-template.json \
  --leaf-template pkg/certmaker/templates/leaf-template.json

Example with Azure KMS:

fulcio-certificate-maker create \
  --kms-type azurekms \
  --azure-tenant-id 1b4a4fed-fed8-4823-a8a0-3d5cea83d122 \
  --root-key-id "azurekms:name=sigstore-key;vault=sigstore-key" \
  --leaf-key-id "azurekms:name=sigstore-key-intermediate;vault=sigstore-key" \
  --intermediate-key-id "azurekms:name=sigstore-key-intermediate;vault=sigstore-key” \
  --root-cert root.pem \
  --leaf-cert leaf.pem \
  --intermediate-cert intermediate.pem

@ianhundere ianhundere changed the title feat: adds cert templates. feat: adds cert-utility. Nov 22, 2024
Copy link

codecov bot commented Nov 22, 2024

Codecov Report

Attention: Patch coverage is 73.95349% with 112 lines in your changes missing coverage. Please review.

Project coverage is 51.02%. Comparing base (cf238ac) to head (49b38dc).
Report is 253 commits behind head on main.

Files with missing lines Patch % Lines
pkg/certmaker/certmaker.go 62.83% 64 Missing and 20 partials ⚠️
pkg/certmaker/template.go 86.76% 12 Missing and 6 partials ⚠️
cmd/certificate_maker/certificate_maker.go 85.29% 8 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1870      +/-   ##
==========================================
- Coverage   57.93%   51.02%   -6.91%     
==========================================
  Files          50       73      +23     
  Lines        3119     5634    +2515     
==========================================
+ Hits         1807     2875    +1068     
- Misses       1154     2497    +1343     
- Partials      158      262     +104     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ianhundere ianhundere force-pushed the feat/adds-cert-maker branch 5 times, most recently from 2fbc59f to aa6d7aa Compare November 25, 2024 20:03
@ianhundere ianhundere marked this pull request as ready for review November 25, 2024 20:18
@ianhundere ianhundere force-pushed the feat/adds-cert-maker branch 16 times, most recently from 61d9f68 to 8193f47 Compare December 1, 2024 06:39
@ianhundere
Copy link
Author

ianhundere commented Dec 1, 2024

i think this is ready for 👀 now. just a couple of notes.

  1. the following use-cases are now covered:
  • root ca -> leaf
  • root ca -> intermediate ca -> leaf
  1. all kms providers are working; awskms, azurekms, and gcpkms both awskms and azurekms have been tested / work, but cloudkms (e.g. gcp), has not been tested.

i think that about covers it, i have some basic readme/documentation above as well.

cc @haydentherapper

@haydentherapper
Copy link
Contributor

Thanks @ianhundere, I’ll take a look at this later this week.

@ianhundere ianhundere force-pushed the feat/adds-cert-maker branch 2 times, most recently from 563de59 to 78b06b6 Compare December 4, 2024 09:14
@ianhundere ianhundere force-pushed the feat/adds-cert-maker branch 4 times, most recently from 2cbf902 to 49b38dc Compare December 9, 2024 15:56
@ianhundere
Copy link
Author

a nudge for 👀

cc @haydentherapper / @bobcallaway

Comment on lines 31 to 33
"go.step.sm/crypto/kms/awskms"
"go.step.sm/crypto/kms/azurekms"
"go.step.sm/crypto/kms/cloudkms"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing you use these deps b/c we don't expose enough of them in sigstore/sigstore?

Copy link
Author

@ianhundere ianhundere Dec 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doh, you're right / i'll implement the sigstore library for kms signing, but continue to use smallstep/crypto for certificate generation (e.g. feeding it cert templates etc).

@ianhundere
Copy link
Author

ianhundere commented Dec 12, 2024

@bobcallaway thanks for the fb especially w/ the gcpkms callout / i totally missed that one. below is a summary of the fb/changes implemented:

  1. now using gcpkms instead of cloudkms to keep consistent w/ naming schemes used elsewhere in fulcio and sigstore etc:
createCmd.Flags().StringVar(&kmsType, "kms-type", "", "KMS provider type (awskms, gcpkms, azurekms)")
  1. cli flags are now more specific to the kms svc used (e.g. gcp / azure / aws):
createCmd.Flags().StringVar(&kmsTenantID, "azure-tenant-id", "", "Azure KMS tenant ID")
createCmd.Flags().StringVar(&kmsCredsFile, "gcp-credentials-file", "", "Path to credentials file for GCP KMS")
createCmd.Flags().StringVar(&kmsRegion, "aws-region", "", "AWS KMS region")
  1. made env vars more specific/consistent to the kms svc/flag used (e.g. gcp / azure / aws)
AWS_REGION
AZURE_TENANT_ID
GCP_CREDENTIALS_FILE
  1. added better error handling for gcp credentials file
  2. updated tests

i'll implement the same fb w/ tsa.

cc @haydentherapper

ps also updated the readme/docs above. let me know if i should include that in some shape way or form in the repo itself.

@ianhundere ianhundere force-pushed the feat/adds-cert-maker branch 2 times, most recently from 96b69b9 to c76001a Compare December 16, 2024 15:59
@ianhundere ianhundere force-pushed the feat/adds-cert-maker branch 2 times, most recently from a73d460 to 2d28296 Compare December 18, 2024 14:12
… support, and adds testify back.

Signed-off-by: ianhundere <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

light tool to create/sign (via kms) certs (ca, leaf etc)
3 participants