diff --git a/api/types/trust.go b/api/types/trust.go index 6811b22bb3575..528ab0ef45baa 100644 --- a/api/types/trust.go +++ b/api/types/trust.go @@ -66,6 +66,9 @@ const ( // AWSRACA identifies the certificate authority that will be used by the // AWS IAM Roles Anywhere integration functionality. AWSRACA CertAuthType = "awsra" + // BoundKeypairCA identifies the CA used to sign bound keypair client state + // documents. + BoundKeypairCA CertAuthType = "bound_keypair" ) // CertAuthTypes lists all certificate authority types. @@ -80,6 +83,7 @@ var CertAuthTypes = []CertAuthType{HostCA, SPIFFECA, OktaCA, AWSRACA, + BoundKeypairCA, } // NewlyAdded should return true for CA types that were added in the current @@ -102,7 +106,7 @@ func (c CertAuthType) addedInMajorVer() int64 { return 15 case OktaCA: return 16 - case AWSRACA: + case AWSRACA, BoundKeypairCA: return 18 default: // We don't care about other CAs added before v4.0.0 diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 66953ba1804c9..c75f69d0a48c4 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -7706,7 +7706,7 @@ func newKeySet(ctx context.Context, keyStore *keystore.Manager, caID types.CertA // Add JWT keys if necessary. switch caID.Type { - case types.JWTSigner, types.OIDCIdPCA, types.SPIFFECA, types.OktaCA: + case types.JWTSigner, types.OIDCIdPCA, types.SPIFFECA, types.OktaCA, types.BoundKeypairCA: jwtKeyPair, err := keyStore.NewJWTKeyPair(ctx, jwtCAKeyPurpose(caID.Type)) if err != nil { return keySet, trace.Wrap(err) @@ -7759,6 +7759,8 @@ func jwtCAKeyPurpose(caType types.CertAuthType) cryptosuites.KeyPurpose { return cryptosuites.SPIFFECAJWT case types.OktaCA: return cryptosuites.OktaCAJWT + case types.BoundKeypairCA: + return cryptosuites.BoundKeypairCAJWT } return cryptosuites.KeyPurposeUnspecified } diff --git a/lib/auth/init.go b/lib/auth/init.go index 6c4ab2294bd60..af2493e73572c 100644 --- a/lib/auth/init.go +++ b/lib/auth/init.go @@ -1387,7 +1387,7 @@ func checkResourceConsistency(ctx context.Context, keyStore *keystore.Manager, c _, signerErr = keyStore.GetSSHSigner(ctx, r) case types.DatabaseCA, types.DatabaseClientCA, types.SAMLIDPCA, types.SPIFFECA, types.AWSRACA: _, _, signerErr = keyStore.GetTLSCertAndSigner(ctx, r) - case types.JWTSigner, types.OIDCIdPCA, types.OktaCA: + case types.JWTSigner, types.OIDCIdPCA, types.OktaCA, types.BoundKeypairCA: _, signerErr = keyStore.GetJWTSigner(ctx, r) default: return trace.BadParameter("unexpected cert_authority type %s for cluster %v", r.GetType(), clusterName) diff --git a/lib/cryptosuites/suites.go b/lib/cryptosuites/suites.go index 17e1f56fdf834..02abb97488a18 100644 --- a/lib/cryptosuites/suites.go +++ b/lib/cryptosuites/suites.go @@ -125,6 +125,9 @@ const ( // identity. BoundKeypairJoining + // BoundKeypairCAJWT represents the JWT key for the bound_keypair CA. + BoundKeypairCAJWT + // keyPurposeMax is 1 greater than the last valid key purpose, used to test that all values less than this // are valid for each suite. keyPurposeMax @@ -168,7 +171,10 @@ type suite map[KeyPurpose]Algorithm var ( // legacy is the original algorithm suite, which exclusively uses RSA2048 // for features developed before ECDSA and Ed25519 support were added. New - // features should always use the new algorithms. + // features should always use the new algorithms, and new CAs should use the + // algorithms in `fipsV1` for compatibility with FIPS mode clusters and + // HSMs. See also: + // https://github.com/gravitational/teleport/blob/master/rfd/0136-modern-signature-algorithms.md#legacy-suite legacy = suite{ UserCATLS: RSA2048, UserCASSH: RSA2048, @@ -202,6 +208,7 @@ var ( GitClient: Ed25519, AWSRACATLS: ECDSAP256, BoundKeypairJoining: Ed25519, + BoundKeypairCAJWT: ECDSAP256, } // balancedV1 strikes a balance between security, compatibility, and @@ -235,6 +242,7 @@ var ( GitClient: Ed25519, AWSRACATLS: ECDSAP256, BoundKeypairJoining: Ed25519, + BoundKeypairCAJWT: Ed25519, } // fipsv1 is an algorithm suite tailored for FIPS compliance. It is based on @@ -269,6 +277,7 @@ var ( GitClient: ECDSAP256, AWSRACATLS: ECDSAP256, BoundKeypairJoining: ECDSAP256, + BoundKeypairCAJWT: ECDSAP256, } // hsmv1 in an algorithm suite tailored for clusters using an HSM or KMS @@ -305,6 +314,7 @@ var ( GitClient: Ed25519, AWSRACATLS: ECDSAP256, BoundKeypairJoining: Ed25519, + BoundKeypairCAJWT: ECDSAP256, } allSuites = map[types.SignatureAlgorithmSuite]suite{ diff --git a/lib/services/authority.go b/lib/services/authority.go index 2d938c7a05670..3ef6b11a69bdf 100644 --- a/lib/services/authority.go +++ b/lib/services/authority.go @@ -68,7 +68,7 @@ func ValidateCertAuthority(ca types.CertAuthority) (err error) { err = checkDatabaseCA(ca) case types.OpenSSHCA: err = checkOpenSSHCA(ca) - case types.JWTSigner, types.OIDCIdPCA, types.OktaCA: + case types.JWTSigner, types.OIDCIdPCA, types.OktaCA, types.BoundKeypairCA: err = checkJWTKeys(ca) case types.SAMLIDPCA: err = checkSAMLIDPCA(ca) diff --git a/lib/services/suite/suite.go b/lib/services/suite/suite.go index 5e7a682934626..820860aae6728 100644 --- a/lib/services/suite/suite.go +++ b/lib/services/suite/suite.go @@ -175,7 +175,7 @@ func NewTestCAWithConfig(config TestCAConfig) *types.CertAuthorityV2 { // Add JWT keys if necessary. switch config.Type { - case types.JWTSigner, types.OIDCIdPCA, types.SPIFFECA, types.OktaCA: + case types.JWTSigner, types.OIDCIdPCA, types.SPIFFECA, types.OktaCA, types.BoundKeypairCA: pubKeyPEM, err := keys.MarshalPublicKey(key.Public()) if err != nil { panic(err) diff --git a/tool/tctl/common/auth_rotate_command.go b/tool/tctl/common/auth_rotate_command.go index ab43bb3d9735c..ccecd5ee5856d 100644 --- a/tool/tctl/common/auth_rotate_command.go +++ b/tool/tctl/common/auth_rotate_command.go @@ -1238,6 +1238,9 @@ func manualSteps(caType types.CertAuthType, phase string) []string { case types.AWSRACA: // TODO(marco): populate any known manual steps during AWS IAM Roles Anywhere CA rotation. fallthrough + case types.BoundKeypairCA: + // TODO(timothyb89): add any manual steps; this should mostly be handled automatically. + fallthrough default: return []string{"Consult the CA rotation docs for any manual steps that may be required: https://goteleport.com/docs/admin-guides/management/operations/ca-rotation/"} }