github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/trust.go (about) 1 /* 2 Copyright 2020 Gravitational, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package types 18 19 import ( 20 "fmt" 21 "strings" 22 "time" 23 24 "github.com/gravitational/trace" 25 "github.com/jonboulle/clockwork" 26 27 "github.com/gravitational/teleport/api" 28 "github.com/gravitational/teleport/api/defaults" 29 ) 30 31 // CertAuthType specifies certificate authority type. New variants should be 32 // added to CertAuthTypes and, for one major version, to NewlyAdded(). 33 type CertAuthType string 34 35 const ( 36 // HostCA identifies the key as a host certificate authority 37 HostCA CertAuthType = "host" 38 // UserCA identifies the key as a user certificate authority 39 UserCA CertAuthType = "user" 40 // DatabaseCA is a certificate authority used as a server CA in database 41 // access. 42 DatabaseCA CertAuthType = "db" 43 // DatabaseClientCA is a certificate authority used as a client CA in 44 // database access. 45 DatabaseClientCA CertAuthType = "db_client" 46 // OpenSSHCA is a certificate authority used when connecting to agentless nodes. 47 OpenSSHCA CertAuthType = "openssh" 48 // JWTSigner identifies type of certificate authority as JWT signer. In this 49 // case JWT is not a certificate authority because it does not issue 50 // certificates but rather is an authority that signs tokens, however it behaves 51 // much like a CA in terms of rotation and storage. 52 JWTSigner CertAuthType = "jwt" 53 // SAMLIDPCA identifies the certificate authority that will be used by the 54 // SAML identity provider. 55 SAMLIDPCA CertAuthType = "saml_idp" 56 // OIDCIdPCA (OpenID Connect Identity Provider Certificate Authority) identifies 57 // the certificate authority that will be used by the OIDC Identity Provider. 58 // Similar to JWTSigner, it doesn't issue Certificates but signs JSON Web Tokens. 59 OIDCIdPCA CertAuthType = "oidc_idp" 60 // SPIFFECA identifies the certificate authority that will be used by the 61 // SPIFFE Workload Identity provider functionality. 62 SPIFFECA CertAuthType = "spiffe" 63 ) 64 65 // CertAuthTypes lists all certificate authority types. 66 var CertAuthTypes = []CertAuthType{HostCA, 67 UserCA, 68 DatabaseCA, 69 DatabaseClientCA, 70 OpenSSHCA, 71 JWTSigner, 72 SAMLIDPCA, 73 OIDCIdPCA, 74 SPIFFECA, 75 } 76 77 // NewlyAdded should return true for CA types that were added in the current 78 // major version, so that we can avoid erroring out when a potentially older 79 // remote server doesn't know about them. 80 func (c CertAuthType) NewlyAdded() bool { 81 return c.addedInMajorVer() >= api.SemVersion.Major 82 } 83 84 // addedInVer return the major version in which given CA was added. 85 func (c CertAuthType) addedInMajorVer() int64 { 86 switch c { 87 case DatabaseCA: 88 return 9 89 case OpenSSHCA, SAMLIDPCA, OIDCIdPCA: 90 return 12 91 case DatabaseClientCA: 92 return 15 93 case SPIFFECA: 94 return 15 95 default: 96 // We don't care about other CAs added before v4.0.0 97 return 4 98 } 99 } 100 101 // IsUnsupportedAuthorityErr returns whether an error is due to an unsupported 102 // CertAuthType. 103 func IsUnsupportedAuthorityErr(err error) bool { 104 return err != nil && trace.IsBadParameter(err) && 105 strings.Contains(err.Error(), authTypeNotSupported) 106 } 107 108 const authTypeNotSupported string = "authority type is not supported" 109 110 // Check checks if certificate authority type value is correct 111 func (c CertAuthType) Check() error { 112 for _, caType := range CertAuthTypes { 113 if c == caType { 114 return nil 115 } 116 } 117 118 return trace.BadParameter("%q %s", c, authTypeNotSupported) 119 } 120 121 // CertAuthID - id of certificate authority (it's type and domain name) 122 type CertAuthID struct { 123 Type CertAuthType `json:"type"` 124 DomainName string `json:"domain_name"` 125 } 126 127 func (c CertAuthID) String() string { 128 return fmt.Sprintf("CA(type=%q, domain=%q)", c.Type, c.DomainName) 129 } 130 131 // Check returns error if any of the id parameters are bad, nil otherwise 132 func (c *CertAuthID) Check() error { 133 if err := c.Type.Check(); err != nil { 134 return trace.Wrap(err) 135 } 136 if strings.TrimSpace(c.DomainName) == "" { 137 return trace.BadParameter("identity validation error: empty domain name") 138 } 139 return nil 140 } 141 142 type RotateRequest struct { 143 // Type is a certificate authority type, if omitted, both user and host CA 144 // will be rotated. 145 Type CertAuthType `json:"type"` 146 // GracePeriod is used to generate cert rotation schedule that defines 147 // times at which different rotation phases will be applied by the auth server 148 // in auto mode. It is not used in manual rotation mode. 149 // If omitted, default value is set, if 0 is supplied, it is interpreted as 150 // forcing rotation of all certificate authorities with no grace period, 151 // all existing users and hosts will have to re-login and re-added 152 // into the cluster. 153 GracePeriod *time.Duration `json:"grace_period,omitempty"` 154 // TargetPhase sets desired rotation phase to move to, if not set 155 // will be set automatically, it is a required argument 156 // for manual rotation. 157 TargetPhase string `json:"target_phase,omitempty"` 158 // Mode sets manual or auto rotation mode. 159 Mode string `json:"mode"` 160 // Schedule is an optional rotation schedule, 161 // autogenerated based on GracePeriod parameter if not set. 162 Schedule *RotationSchedule `json:"schedule"` 163 } 164 165 // CheckAndSetDefaults checks and sets default values. 166 func (r *RotateRequest) CheckAndSetDefaults(clock clockwork.Clock) error { 167 if r.TargetPhase == "" { 168 // if phase is not set, imply that the first meaningful phase 169 // is set as a target phase 170 r.TargetPhase = RotationPhaseInit 171 } 172 // if mode is not set, default to manual (as it's safer) 173 if r.Mode == "" { 174 r.Mode = RotationModeManual 175 } 176 177 if err := r.Type.Check(); err != nil { 178 return trace.Wrap(err) 179 } 180 if r.GracePeriod == nil { 181 period := defaults.MaxCertDuration 182 r.GracePeriod = &period 183 } 184 if r.Schedule == nil { 185 var err error 186 r.Schedule, err = GenerateSchedule(clock.Now(), *r.GracePeriod) 187 if err != nil { 188 return trace.Wrap(err) 189 } 190 } else { 191 if err := r.Schedule.CheckAndSetDefaults(clock.Now()); err != nil { 192 return trace.Wrap(err) 193 } 194 } 195 return nil 196 }