Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Role requesting certs #251

Merged
merged 16 commits into from
Dec 9, 2024
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ endif
BINARY=keymaster

# These are the values we want to pass for Version and BuildTime
VERSION?=1.15.5
VERSION?=1.16.0
DEFAULT_HOST?=
VERSION_FLAVOUR?=
EXTRA_LDFLAGS?=
Expand Down
66 changes: 43 additions & 23 deletions cmd/keymasterd/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,15 @@ func (state *RuntimeState) getUsernameIfKeymasterSigned(VerifiedChains [][]*x509
if err != nil {
return "", time.Time{}, err
}
userPubKeyFP, err := getKeyFingerprint(chain[0].PublicKey)
if err != nil {
return "", time.Time{}, err
}
for _, revokedKeyFP := range state.Config.DenyTrustData.KeyDenyFPsshSha256 {
if userPubKeyFP == revokedKeyFP {
return "", time.Time{}, fmt.Errorf("revoked key with FP:%s", revokedKeyFP)
}
}
for _, key := range state.KeymasterPublicKeys {
fp, err := getKeyFingerprint(key)
if err != nil {
Expand Down Expand Up @@ -869,36 +878,45 @@ func (state *RuntimeState) checkAuth(w http.ResponseWriter, r *http.Request, req
state.logger.Debugf(3,
"looks like authtype tls keymaster or ip cert, r.tls=%+v", r.TLS)
if len(r.TLS.VerifiedChains) > 0 {
if (requiredAuthType & AuthTypeKeymasterX509) != 0 {
tlsAuthUser, notBefore, err :=
state.getUsernameIfKeymasterSigned(r.TLS.VerifiedChains)
if err == nil && tlsAuthUser != "" {
return &authInfo{
AuthType: AuthTypeKeymasterX509,
IssuedAt: notBefore,
Username: tlsAuthUser,
}, nil
}
var authData authInfo
tlsAuthUser, notBefore, err :=
state.getUsernameIfKeymasterSigned(r.TLS.VerifiedChains)
if err == nil && tlsAuthUser != "" {
state.logger.Debugf(4, "Auth, Is keymastercert")
authData.AuthType = authData.AuthType | AuthTypeKeymasterX509
authData.IssuedAt = notBefore
authData.Username = tlsAuthUser
}
if (requiredAuthType & AuthTypeIPCertificate) != 0 {
clientName, notBefore, userErr, err :=
state.getUsernameIfIPRestricted(r.TLS.VerifiedChains, r)
if userErr != nil {
state.writeFailureResponse(w, r, http.StatusForbidden,
fmt.Sprintf("%s", userErr))
return nil, userErr
// if not keymasterd cert AND not ipcert either then we return
// more explicit errors
if authData.Username == "" {
state.logger.Printf("after eval, but username is empty")
if userErr != nil {
state.writeFailureResponse(w, r, http.StatusForbidden,
fmt.Sprintf("%s", userErr))
return nil, userErr
}
if err != nil {
state.writeFailureResponse(w, r,
http.StatusInternalServerError, "")
return nil, err
}
}
if err != nil {
state.writeFailureResponse(w, r,
http.StatusInternalServerError, "")
return nil, err

if err == nil && userErr == nil {
authData.AuthType = authData.AuthType | AuthTypeIPCertificate
authData.IssuedAt = notBefore
authData.Username = clientName
}
return &authInfo{
AuthType: AuthTypeIPCertificate,
IssuedAt: notBefore,
Username: clientName,
}, nil
}
if authData.Username != "" {
state.logger.Debugf(4, "returning tls cert authinfo")
return &authData, nil
}
state.logger.Debugf(4, "NOT returning tls cert authinfo authData=%+v", authData)
}
}
// Next we check for cookies
Expand Down Expand Up @@ -1937,6 +1955,8 @@ func main() {
serviceMux.HandleFunc(paths.VerifyAuthToken,
runtimeState.VerifyAuthTokenHandler)
}
serviceMux.HandleFunc(getRoleRequestingPath, runtimeState.roleRequetingCertGenHandler)
serviceMux.HandleFunc(refreshRoleRequestingCertPath, runtimeState.refreshRoleRequetingCertGenHandler)
serviceMux.HandleFunc("/", runtimeState.defaultPathHandler)

cfg := &tls.Config{
Expand Down
6 changes: 6 additions & 0 deletions cmd/keymasterd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ type baseConfig struct {
SecsBetweenDependencyChecks int `yaml:"secs_between_dependency_checks"`
AutomationUserGroups []string `yaml:"automation_user_groups"`
AutomationUsers []string `yaml:"automation_users"`
AutomationAdmins []string `yaml:"automation_admins"`
DisableUsernameNormalization bool `yaml:"disable_username_normalization"`
EnableLocalTOTP bool `yaml:"enable_local_totp"`
EnableBootstrapOTP bool `yaml:"enable_bootstrapotp"`
Expand Down Expand Up @@ -189,6 +190,10 @@ type SymantecVIPConfig struct {
RequireAppAproval bool `yaml:"require_app_approval"`
}

type DenyKeyConfig struct {
KeyDenyFPsshSha256 []string `yaml:"key_deny_list_ssh_sha256"`
}

type AppConfigFile struct {
Base baseConfig
AwsCerts awsCertsConfig `yaml:"aws_certs"`
Expand All @@ -202,6 +207,7 @@ type AppConfigFile struct {
OpenIDConnectIDP OpenIDConnectIDPConfig `yaml:"openid_connect_idp"`
SymantecVIP SymantecVIPConfig
ProfileStorage ProfileStorageConfig
DenyTrustData DenyKeyConfig
rgooch marked this conversation as resolved.
Show resolved Hide resolved
}

const (
Expand Down
Loading
Loading