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  }