github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/security/ticket/ssh.go (about)

     1  // Copyright 2020 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache-2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  package ticket
     6  
     7  import (
     8  	"time"
     9  
    10  	"github.com/Schaudge/grailbase/common/log"
    11  	"github.com/Schaudge/grailbase/security/keycrypt"
    12  	"github.com/Schaudge/grailbase/security/ssh/certificateauthority"
    13  )
    14  
    15  const sshDriftMargin = 10 * time.Minute
    16  
    17  func (b *SshCertAuthorityBuilder) newSshCertificateTicket(ctx *TicketContext) (TicketSshCertificateTicket, error) {
    18  	sshCert, err := b.genSshCertWithKeyUsage(ctx)
    19  
    20  	if err != nil {
    21  		return TicketSshCertificateTicket{}, err
    22  	}
    23  
    24  	return TicketSshCertificateTicket{
    25  		Value: SshCertificateTicket{
    26  			Credentials: sshCert,
    27  		},
    28  	}, nil
    29  }
    30  
    31  func (b *SshCertAuthorityBuilder) genSshCertWithKeyUsage(ctx *TicketContext) (SshCert, error) {
    32  	log.Info(ctx.ctx, "Generating SSH certificate.", "SshCertAuthorityBuilder", b)
    33  	empty := SshCert{}
    34  
    35  	CaPrivateKey, err := keycrypt.Lookup(b.CaPrivateKey)
    36  	if err != nil {
    37  		return empty, err
    38  	}
    39  
    40  	authority := certificateauthority.CertificateAuthority{DriftMargin: sshDriftMargin, PrivateKey: CaPrivateKey, Certificate: b.CaCertificate}
    41  	if err = authority.Init(); err != nil {
    42  		return empty, err
    43  	}
    44  
    45  	ttl := time.Duration(b.TtlMin) * time.Minute
    46  
    47  	cr := certificateauthority.CertificateRequest{
    48  		// SSH Public Key that is being signed
    49  		SshPublicKey: []byte(b.PublicKey),
    50  
    51  		// List of host names, or usernames that will be added to the cert
    52  		Principals: b.Principals,
    53  		Ttl:        ttl,
    54  		KeyID:      ctx.remoteBlessings.String(),
    55  
    56  		CertType: "user",
    57  
    58  		CriticalOptions: b.CriticalOptions,
    59  
    60  		// Extensions to assign to the ssh Certificate
    61  		//  The default allow basic function - permit-pty is usually required
    62  		//  Recommended values are:
    63  		//  []string{
    64  		//   "permit-X11-forwarding",
    65  		//   "permit-agent-forwarding",
    66  		//   "permit-port-forwarding",
    67  		//   "permit-pty",
    68  		//   "permit-user-rc",
    69  		//   }
    70  		Extensions: b.ExtensionsOptions,
    71  	}
    72  
    73  	sshCert, err := authority.IssueWithKeyUsage(cr)
    74  	if err != nil {
    75  		return empty, err
    76  	}
    77  
    78  	r := SshCert{Cert: sshCert}
    79  	return r, nil
    80  }