Skip to content

Commit

Permalink
Merge pull request #17 from aakso/feat/split-principals-to-multiple-c…
Browse files Browse the repository at this point in the history
…erts

feat: implement max principals per certificate
  • Loading branch information
aakso committed Apr 28, 2022
2 parents e3cc3dc + 1553bf6 commit c7b72c2
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 163 deletions.
11 changes: 11 additions & 0 deletions cliclient/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,15 @@ func init() {
_ = RootCmd.RegisterFlagCompletionFunc("signing-option", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"rsa-sha2-256", "rsa-sha2-512"}, cobra.ShellCompDirectiveNoFileComp
})

if opt := os.Getenv("SSH_INSCRIBE_MAX_PRINCIPALS_PER_CERTIFICATE"); opt != "" {
iv, _ := strconv.ParseInt(opt, 10, 64)
ClientConfig.MaxPrincipalsPerCertificate = int(iv)
}
RootCmd.PersistentFlags().IntVar(
&ClientConfig.MaxPrincipalsPerCertificate,
"max-principals-per-certificate",
ClientConfig.MaxPrincipalsPerCertificate,
"Optional flag that instructs the server to put maximum of N principals per signed certificate.",
)
}
50 changes: 35 additions & 15 deletions pkg/auth/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,42 @@ import (
"golang.org/x/crypto/ssh"
)

func MakeCertificate(key ssh.PublicKey, actx *AuthContext) *ssh.Certificate {
kid := []string{}
kid = append(kid, fmt.Sprintf("subject=%q", actx.GetSubjectName()))
func MakeCertificates(key ssh.PublicKey, actx *AuthContext, validBefore time.Time, maxPrincipalsPerCert int) []*ssh.Certificate {
var kid strings.Builder
kid.WriteString(fmt.Sprintf("subject=%q", actx.GetSubjectName()))
if aid, ok := actx.GetAuthMeta()[MetaAuditID]; ok {
kid = append(kid, fmt.Sprintf("audit_id=%q", aid))
kid.WriteString(fmt.Sprintf(" audit_id=%q", aid))
}
kid = append(kid, fmt.Sprintf("via=%q", strings.Join(actx.GetAuthenticators(), ",")))
return &ssh.Certificate{
Key: key,
CertType: ssh.UserCert,
KeyId: strings.Join(kid, " "),
ValidPrincipals: actx.GetPrincipals(),
ValidAfter: uint64(time.Now().Unix()),
Permissions: ssh.Permissions{
CriticalOptions: actx.GetCriticalOptions(),
Extensions: actx.GetExtensions(),
},
kid.WriteString(fmt.Sprintf(" via=%q", strings.Join(actx.GetAuthenticators(), ",")))

remainingPrincipals := actx.GetPrincipals()
if maxPrincipalsPerCert == 0 {
maxPrincipalsPerCert = len(remainingPrincipals)
}
var certs []*ssh.Certificate
for {
pos := len(remainingPrincipals)
if pos > maxPrincipalsPerCert {
pos = maxPrincipalsPerCert
}
principals := remainingPrincipals[:pos]
remainingPrincipals = remainingPrincipals[pos:]

certs = append(certs, &ssh.Certificate{
Key: key,
CertType: ssh.UserCert,
KeyId: kid.String(),
ValidPrincipals: principals,
ValidAfter: uint64(time.Now().Unix()),
ValidBefore: uint64(validBefore.Unix()),
Permissions: ssh.Permissions{
CriticalOptions: actx.GetCriticalOptions(),
Extensions: actx.GetExtensions(),
},
})
if len(remainingPrincipals) == 0 {
break
}
}
return certs
}
Loading

0 comments on commit c7b72c2

Please sign in to comment.