Skip to content

Commit

Permalink
Feature: an ability to revoke an old Root CA
Browse files Browse the repository at this point in the history
Signed-off-by: Volodymyr Khoroz <[email protected]>
  • Loading branch information
vkhoroz committed Oct 6, 2024
1 parent 7fec7d2 commit 039da9f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
51 changes: 51 additions & 0 deletions subcommands/keys/ca_renewal_revoke_root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package keys

import (
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/foundriesio/fioctl/client"
"github.com/foundriesio/fioctl/subcommands"
"github.com/foundriesio/fioctl/x509"
)

var serialToRevoke string

func init() {
cmd := &cobra.Command{
Use: "revoke-root <PKI Directory>",
Short: "Revoke an inactive root CA for your Factory PKI",
Run: doRevokeRootRenewal,
Args: cobra.ExactArgs(1),
Long: `Revoke an inactive root CAA for your Factory PKI.
This command removes a Root CA with a given serial and associated cross-signed CA certificates.
After that point a given Root CA can no longer be re-activated.
Devices which were not updated with a new Root CA will instantly lose connectivity to Foundries.io services.
This action is irreversible, so plan properly as to when you perform it.
It is usually the last step of the Root CA rotation, which is optional unless your old Root CA was compromised.`,
}
caRenewalCmd.AddCommand(cmd)
cmd.Flags().StringVarP(&serialToRevoke, "serial", "", "",
"A serial number of the Root CA to revoke in hexadecimal format")
_ = cmd.MarkFlagRequired("serial")
addStandardHsmFlags(cmd)
}

func doRevokeRootRenewal(cmd *cobra.Command, args []string) {
factory := viper.GetString("factory")
certsDir := args[0]
subcommands.DieNotNil(os.Chdir(certsDir))
hsm, err := validateStandardHsmArgs(hsmModule, hsmPin, hsmTokenLabel)
subcommands.DieNotNil(err)
x509.InitHsm(hsm)

toRevoke := map[string]int{serialToRevoke: x509.CrlRootRevoke}
// The API will determine and revoke cross-signed certificates as well.
// It will also check that a user is not revoking a currently active Root CA.
req := client.CaCerts{RootRevokeCrl: x509.CreateCrl(toRevoke)}
subcommands.DieNotNil(api.FactoryPatchCA(factory, req))
}
6 changes: 6 additions & 0 deletions x509/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ const (

// CRL constants for root CA revokation.

// Revoke the root CA, so that it is no longer available in the root CAs list.
// Note: the API will revoke the root CA for any reason other than 4, 6, or 8.
// Reasons 6 and 8 are ignored.
// This action is permanent.
CrlRootRevoke = 5 // RFC 5280 - cessationOfOperation

// Supersede the root CA by another root CA.
// This is used to switch the currently active root CA, used to sign/verify device CAs and TLS certificates.
// The superseded CA serial be a currently active root CA, and the CRL must be signed by a newly activated root CA.
Expand Down

0 comments on commit 039da9f

Please sign in to comment.