Skip to content

Commit

Permalink
Add HAB CA hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
AlCutter committed Jan 31, 2024
1 parent f02cad5 commit 37e0b56
Show file tree
Hide file tree
Showing 3 changed files with 319 additions and 3 deletions.
295 changes: 294 additions & 1 deletion deployment/build_and_release/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ resource "google_project_service" "storage_component_googleapis_com" {
resource "google_project_service" "storage_googleapis_com" {
service = "storage.googleapis.com"
}
resource "google_project_service" "privateca_api" {
service = "privateca.googleapis.com"
disable_on_destroy = false
}


# GCS buckets

Expand Down Expand Up @@ -114,7 +119,7 @@ resource "google_storage_bucket" "armored_witness_firmware_log_ci_1" {
uniform_bucket_level_access = true
}

# KMS key rings
# KMS key rings & data sources
resource "google_kms_key_ring" "firmware_release_ci" {
location = var.signing_keyring_location
name = "firmware-release-ci"
Expand All @@ -123,6 +128,14 @@ resource "google_kms_key_ring" "firmware_release_prod" {
location = var.signing_keyring_location
name = "firmware-release-prod"
}
resource "google_kms_key_ring" "hab_ci" {
location = var.signing_keyring_location
name = "hab-ci"
}
data "google_kms_key_ring" "hab_ci" {
location = google_kms_key_ring.hab_ci.location
name = google_kms_key_ring.hab_ci.name
}

# TODO(jayhou): This configuration cannot be applied right now because of the
# algorithm. Uncomment again when it is supported.
Expand Down Expand Up @@ -227,6 +240,286 @@ resource "google_kms_key_ring" "firmware_release_prod" {
# }
#}

# CI HAB CSF key & data sources for each of the SRK intermediates below.
#
# The resource creates the key within the keyring, and the data sections below
# ultimately provide a mechanism for getting the public key out from the HSM
# so that it can be certified by the leaf certificates of the HAB PKI below.
resource "google_kms_crypto_key" "hab_csf_ci" {
for_each = toset(local.hab_intermediates)

key_ring = google_kms_key_ring.hab_ci.id
name = format("hab-csf%d-rev%d-ci", each.value, var.hab_ci_srk_revision)
purpose = "ASYMMETRIC_SIGN"
version_template {
algorithm = format("RSA_SIGN_PKCS1_%d_SHA256", var.hab_keylength)
protection_level = "HSM"
}
}
data "google_kms_crypto_key" "hab_csf_ci" {
for_each = toset(local.hab_intermediates)

name = format("hab-csf%s-rev%d-ci", each.value, var.hab_ci_srk_revision)
key_ring = data.google_kms_key_ring.hab_ci.id

depends_on = [
google_kms_crypto_key.hab_csf_ci
]
}
data "google_kms_crypto_key_version" "hab_csf_ci" {
for_each = toset(local.hab_intermediates)

crypto_key = data.google_kms_crypto_key.hab_csf_ci[each.key].id
}
# CI HAB IMG key & data sources for each of the SRK intermediates below.
resource "google_kms_crypto_key" "hab_img_ci" {
for_each = toset(local.hab_intermediates)

key_ring = google_kms_key_ring.hab_ci.id
name = format("hab-img%d-rev%d-ci", each.value, var.hab_ci_srk_revision)
purpose = "ASYMMETRIC_SIGN"
version_template {
algorithm = format("RSA_SIGN_PKCS1_%d_SHA256", var.hab_keylength)
protection_level = "HSM"
}
}
data "google_kms_crypto_key" "hab_img_ci" {
for_each = toset(local.hab_intermediates)

name = format("hab-img%s-rev%d-ci", each.value, var.hab_ci_srk_revision)
key_ring = data.google_kms_key_ring.hab_ci.id

depends_on = [
google_kms_crypto_key.hab_img_ci
]
}
data "google_kms_crypto_key_version" "hab_img_ci" {
for_each = toset(local.hab_intermediates)

crypto_key = data.google_kms_crypto_key.hab_img_ci[each.key].id
}

###########################################################################
## CI HAB Certificate Authority config.
##
## This should construct a CA hierarchy as below for use with HAB signing:
## .--------.
## | Root |
## `--------'
## |
## ---------------------------------------------------
## | | | |
## .--------. .--------. .--------. .--------.
## | SRK1 | | SRK2 | | SRK3 | | SRK4 |
## `--------' `--------' `--------' `--------'
## / \ / \ / \ / \
## .----. .----. .----. .----. .----. .----. .----. .----.
## |CSF1| |IMG1| |CSF2| |IMG2| |CSF3| |IMG3| |CSF4| |IMG4|
## `----' `----' `----' `----' `----' `----' `----' `----'
###########################################################################

# CI HAB CA pool
resource "google_privateca_ca_pool" "hab_ci" {
name = "aw-hab-ca-pool-rev0-ci"
location = "us-central1"
tier = "ENTERPRISE"
publishing_options {
publish_ca_cert = true
publish_crl = false
}
issuance_policy {
baseline_values {
ca_options {
is_ca = true
}
key_usage {
base_key_usage {
cert_sign = true
crl_sign = true
digital_signature = true
}
extended_key_usage {
}
}
}
}
}

# CI HAB Root CA authority
resource "google_privateca_certificate_authority" "hab_root_ci" {
pool = google_privateca_ca_pool.hab_ci.name
certificate_authority_id = "hab-root-ci"
location = "us-central1"
config {
subject_config {
subject {
organization = "TrustFabric"
organizational_unit = "ArmoredWitness CI"
common_name = "ArmoredWitness Root CI"
}
}
x509_config {
ca_options {
# is_ca *MUST* be true for certificate authorities
is_ca = true
}
key_usage {
base_key_usage {
# cert_sign and crl_sign *MUST* be true for certificate authorities
cert_sign = true
crl_sign = true
}
extended_key_usage {
}
}
}
}
type = "SELF_SIGNED"
key_spec {
algorithm = format("RSA_PKCS1_%d_SHA256", var.hab_keylength)
}

// REMOVE BEFORE SUBMIT:

// Disable CA deletion related safe checks for easier cleanup.
deletion_protection = false
skip_grace_period = true
ignore_active_certificates_on_deletion = true
}

locals {
// This simply gives us a list we can use, in combination with the for_each meta attribute, to create
// multiple instances of the subordinate CAs & certs below.
hab_intermediates = [for i in range(1, 1 + var.hab_num_intermediates) : format("%s", i)]
}

# CI HAB SRK intermediates (one each for hab_intermediates above)
resource "google_privateca_certificate_authority" "hab_srk_ci" {
for_each = toset(local.hab_intermediates)

pool = google_privateca_ca_pool.hab_ci.name
certificate_authority_id = format("hab-srk%s-rev%d-ci", each.value, var.hab_ci_srk_revision)
location = "us-central1"

//deletion_protection = "true"

subordinate_config {
certificate_authority = google_privateca_certificate_authority.hab_root_ci.name
}
config {
subject_config {
subject {
organization = "TrustFabric"
organizational_unit = "ArmoredWitness CI"
common_name = format("ArmoredWitness SRK%s CI", each.value)
}
}
x509_config {
ca_options {
is_ca = true
# Force the sub CA to only issue leaf certs
max_issuer_path_length = 0
}
key_usage {
base_key_usage {
cert_sign = true
crl_sign = true
}
extended_key_usage {
}
}
}
}
lifetime = format("%ds", var.hab_pki_lifetime)
key_spec {
algorithm = format("RSA_PKCS1_%d_SHA256", var.hab_keylength)
}
type = "SUBORDINATE"

// REMOVE BEFORE SUBMIT:

// Disable CA deletion related safe checks for easier cleanup.
deletion_protection = false
skip_grace_period = true
ignore_active_certificates_on_deletion = true
}

# CI HAB CSF cert for each of the SRK intermediates above.
resource "google_privateca_certificate" "hab_csf_ci" {
for_each = google_privateca_certificate_authority.hab_srk_ci

name = format("hab-csf%s-rev%d-ci", each.key, var.hab_ci_srk_revision)
location = "us-central1"
pool = each.value.pool
certificate_authority = each.value.certificate_authority_id
lifetime = format("%ds", var.hab_pki_lifetime)
config {
subject_config {
subject {
organization = "TrustFabric"
organizational_unit = "ArmoredWitness CI"
common_name = format("ArmoredWitness SRK%s CSF CI", each.key)
}
}
x509_config {
ca_options {
is_ca = false
}
key_usage {
base_key_usage {
digital_signature = true
}
extended_key_usage {
}
}
}
public_key {
format = "PEM"
key = base64encode(data.google_kms_crypto_key_version.hab_csf_ci[each.key].public_key[0].pem)
}
}
}

# CI HAB IMG cert for each of the SRK intermediates above.
resource "google_privateca_certificate" "hab_img_ci" {
for_each = google_privateca_certificate_authority.hab_srk_ci

name = format("hab-img%s-rev%d-ci", each.key, var.hab_ci_srk_revision)
location = "us-central1"
pool = each.value.pool
certificate_authority = each.value.certificate_authority_id
lifetime = format("%ds", var.hab_pki_lifetime)
config {
subject_config {
subject {
organization = "TrustFabric"
organizational_unit = "ArmoredWitness CI"
common_name = format("ArmoredWitness SRK%s IMG CI", each.key)
}
}
x509_config {
ca_options {
is_ca = false
}
key_usage {
base_key_usage {
digital_signature = true
}
extended_key_usage {
}
}
}
public_key {
format = "PEM"
key = base64encode(data.google_kms_crypto_key_version.hab_img_ci[each.key].public_key[0].pem)
}
}
}

############################################################
## Terraform state bucket
############################################################

resource "google_kms_key_ring" "terraform_state" {
name = "armored-witness-bucket-tfstate"
location = var.tf_state_location
Expand Down
6 changes: 4 additions & 2 deletions deployment/build_and_release/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
project_id = "1071548024491"
project_id = "armored-witness"
signing_keyring_location = "global"
tf_state_location = "europe-west2"
tf_state_location = "europe-west2"

hab_ci_srk_revision = 1
21 changes: 21 additions & 0 deletions deployment/build_and_release/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,25 @@ variable "signing_keyring_location" {

variable "tf_state_location" {
description = "The GCP location to store Terraform remote state"
}

variable "hab_keylength" {
description = "HAB CA RSA key length"
type = number
// From https://github.com/usbarmory/crucible/blob/master/hab/const.go#L13
default = 2048
}

variable "hab_num_intermediates" {
description = "Number of HAB intermediate CAs"
default = 4
}

variable "hab_pki_lifetime" {
description = "Lifetime for HAB PKI certs in seconds"
default = 788400000 // 25 years
}

variable "hab_ci_srk_revision" {
description = "Revision count for CI SRK, CSF, and IMG certs. This must be incremented if these certs are regenerated for any reason"
}

0 comments on commit 37e0b56

Please sign in to comment.