From 1da7ea66464c8128d339da84646d348be88520b4 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Tue, 23 Nov 2021 17:52:39 -0800 Subject: [PATCH] Return always http errors in sign ssh options. --- authority/provisioner/sign_ssh_options.go | 61 ++++++++++++----------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/authority/provisioner/sign_ssh_options.go b/authority/provisioner/sign_ssh_options.go index 6cd38c59..80ff884e 100644 --- a/authority/provisioner/sign_ssh_options.go +++ b/authority/provisioner/sign_ssh_options.go @@ -58,6 +58,11 @@ func (o SignSSHOptions) Validate() error { if o.CertType != "" && o.CertType != SSHUserCert && o.CertType != SSHHostCert { return errs.BadRequest("unknown certificate type '%s'", o.CertType) } + for _, p := range o.Principals { + if p == "" { + return errs.BadRequest("principals cannot contain empty values") + } + } return nil } @@ -75,7 +80,7 @@ func (o SignSSHOptions) Modify(cert *ssh.Certificate, _ SignSSHOptions) error { case SSHHostCert: cert.CertType = ssh.HostCert default: - return errors.Errorf("ssh certificate has an unknown type - %s", o.CertType) + return errs.BadRequest("ssh certificate has an unknown type '%s'", o.CertType) } cert.KeyId = o.KeyID @@ -95,7 +100,7 @@ func (o SignSSHOptions) ModifyValidity(cert *ssh.Certificate) error { cert.ValidBefore = uint64(o.ValidBefore.RelativeTime(t).Unix()) } if cert.ValidAfter > 0 && cert.ValidBefore > 0 && cert.ValidAfter > cert.ValidBefore { - return errors.New("ssh certificate valid after cannot be greater than valid before") + return errs.BadRequest("ssh certificate validAfter cannot be greater than validBefore") } return nil } @@ -104,16 +109,16 @@ func (o SignSSHOptions) ModifyValidity(cert *ssh.Certificate) error { // ignores zero values. func (o SignSSHOptions) match(got SignSSHOptions) error { if o.CertType != "" && got.CertType != "" && o.CertType != got.CertType { - return errors.Errorf("ssh certificate type does not match - got %v, want %v", got.CertType, o.CertType) + return errs.BadRequest("ssh certificate type does not match - got %v, want %v", got.CertType, o.CertType) } if len(o.Principals) > 0 && len(got.Principals) > 0 && !containsAllMembers(o.Principals, got.Principals) { - return errors.Errorf("ssh certificate principals does not match - got %v, want %v", got.Principals, o.Principals) + return errs.BadRequest("ssh certificate principals does not match - got %v, want %v", got.Principals, o.Principals) } if !o.ValidAfter.IsZero() && !got.ValidAfter.IsZero() && !o.ValidAfter.Equal(&got.ValidAfter) { - return errors.Errorf("ssh certificate valid after does not match - got %v, want %v", got.ValidAfter, o.ValidAfter) + return errs.BadRequest("ssh certificate validAfter does not match - got %v, want %v", got.ValidAfter, o.ValidAfter) } if !o.ValidBefore.IsZero() && !got.ValidBefore.IsZero() && !o.ValidBefore.Equal(&got.ValidBefore) { - return errors.Errorf("ssh certificate valid before does not match - got %v, want %v", got.ValidBefore, o.ValidBefore) + return errs.BadRequest("ssh certificate validBefore does not match - got %v, want %v", got.ValidBefore, o.ValidBefore) } return nil } @@ -206,7 +211,7 @@ func (m *sshDefaultExtensionModifier) Modify(cert *ssh.Certificate, _ SignSSHOpt cert.Extensions["permit-user-rc"] = "" return nil default: - return errors.New("ssh certificate type has not been set or is invalid") + return errs.BadRequest("ssh certificate has an unknown type '%d'", cert.CertType) } } @@ -272,7 +277,7 @@ func (m *sshLimitDuration) Modify(cert *ssh.Certificate, o SignSSHOptions) error certValidAfter := time.Unix(int64(cert.ValidAfter), 0) if certValidAfter.After(m.NotAfter) { - return errors.Errorf("provisioning credential expiration (%s) is before requested certificate validAfter (%s)", + return errs.Forbidden("provisioning credential expiration (%s) is before requested certificate validAfter (%s)", m.NotAfter, certValidAfter) } @@ -285,7 +290,7 @@ func (m *sshLimitDuration) Modify(cert *ssh.Certificate, o SignSSHOptions) error } else { certValidBefore := time.Unix(int64(cert.ValidBefore), 0) if m.NotAfter.Before(certValidBefore) { - return errors.Errorf("provisioning credential expiration (%s) is before requested certificate validBefore (%s)", + return errs.Forbidden("provisioning credential expiration (%s) is before requested certificate validBefore (%s)", m.NotAfter, certValidBefore) } } @@ -319,11 +324,11 @@ type sshCertOptionsRequireValidator struct { func (v *sshCertOptionsRequireValidator) Valid(got SignSSHOptions) error { switch { case v.CertType && got.CertType == "": - return errors.New("ssh certificate certType cannot be empty") + return errs.BadRequest("ssh certificate certType cannot be empty") case v.KeyID && got.KeyID == "": - return errors.New("ssh certificate keyID cannot be empty") + return errs.BadRequest("ssh certificate keyID cannot be empty") case v.Principals && len(got.Principals) == 0: - return errors.New("ssh certificate principals cannot be empty") + return errs.BadRequest("ssh certificate principals cannot be empty") default: return nil } @@ -354,7 +359,7 @@ func (v *sshCertValidityValidator) Valid(cert *ssh.Certificate, opts SignSSHOpti case 0: return errs.BadRequest("ssh certificate type has not been set") default: - return errs.BadRequest("unknown ssh certificate type %d", cert.CertType) + return errs.BadRequest("unknown ssh certificate type '%d'", cert.CertType) } // To not take into account the backdate, time.Now() will be used to @@ -381,25 +386,25 @@ type sshCertDefaultValidator struct{} func (v *sshCertDefaultValidator) Valid(cert *ssh.Certificate, o SignSSHOptions) error { switch { case len(cert.Nonce) == 0: - return errors.New("ssh certificate nonce cannot be empty") + return errs.Forbidden("ssh certificate nonce cannot be empty") case cert.Key == nil: - return errors.New("ssh certificate key cannot be nil") + return errs.Forbidden("ssh certificate key cannot be nil") case cert.Serial == 0: - return errors.New("ssh certificate serial cannot be 0") + return errs.Forbidden("ssh certificate serial cannot be 0") case cert.CertType != ssh.UserCert && cert.CertType != ssh.HostCert: - return errors.Errorf("ssh certificate has an unknown type: %d", cert.CertType) + return errs.Forbidden("ssh certificate has an unknown type '%d'", cert.CertType) case cert.KeyId == "": - return errors.New("ssh certificate key id cannot be empty") + return errs.Forbidden("ssh certificate key id cannot be empty") case cert.ValidAfter == 0: - return errors.New("ssh certificate validAfter cannot be 0") + return errs.Forbidden("ssh certificate validAfter cannot be 0") case cert.ValidBefore < uint64(now().Unix()): - return errors.New("ssh certificate validBefore cannot be in the past") + return errs.Forbidden("ssh certificate validBefore cannot be in the past") case cert.ValidBefore < cert.ValidAfter: - return errors.New("ssh certificate validBefore cannot be before validAfter") + return errs.Forbidden("ssh certificate validBefore cannot be before validAfter") case cert.SignatureKey == nil: - return errors.New("ssh certificate signature key cannot be nil") + return errs.Forbidden("ssh certificate signature key cannot be nil") case cert.Signature == nil: - return errors.New("ssh certificate signature cannot be nil") + return errs.Forbidden("ssh certificate signature cannot be nil") default: return nil } @@ -411,25 +416,25 @@ type sshDefaultPublicKeyValidator struct{} // Valid checks that certificate request common name matches the one configured. func (v sshDefaultPublicKeyValidator) Valid(cert *ssh.Certificate, o SignSSHOptions) error { if cert.Key == nil { - return errors.New("ssh certificate key cannot be nil") + return errs.BadRequest("ssh certificate key cannot be nil") } switch cert.Key.Type() { case ssh.KeyAlgoRSA: _, in, ok := sshParseString(cert.Key.Marshal()) if !ok { - return errors.New("ssh certificate key is invalid") + return errs.BadRequest("ssh certificate key is invalid") } key, err := sshParseRSAPublicKey(in) if err != nil { - return err + return errs.BadRequestErr(err, "error parsing public key") } if key.Size() < keyutil.MinRSAKeyBytes { - return errors.Errorf("ssh certificate key must be at least %d bits (%d bytes)", + return errs.Forbidden("ssh certificate key must be at least %d bits (%d bytes)", 8*keyutil.MinRSAKeyBytes, keyutil.MinRSAKeyBytes) } return nil case ssh.KeyAlgoDSA: - return errors.New("ssh certificate key algorithm (DSA) is not supported") + return errs.BadRequest("ssh certificate key algorithm (DSA) is not supported") default: return nil }