forked from TrueCloudLab/certificates
Render proper policy and constrains errors
This commit is contained in:
parent
4b79405dac
commit
72e2c4eb2e
4 changed files with 47 additions and 26 deletions
|
@ -6,6 +6,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/smallstep/certificates/errs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var oidExtensionNameConstraints = []int{2, 5, 29, 30}
|
var oidExtensionNameConstraints = []int{2, 5, 29, 30}
|
||||||
|
@ -23,9 +25,18 @@ func (e ConstraintError) Error() string {
|
||||||
return e.Detail
|
return e.Detail
|
||||||
}
|
}
|
||||||
|
|
||||||
// StatusCode implements an status coder interface.
|
// As implements the As(any) bool interface and allows to use "errors.As()" to
|
||||||
func (e ConstraintError) StatusCode() int {
|
// convert the ConstraintError to an errs.Error.
|
||||||
return http.StatusForbidden
|
func (e ConstraintError) As(v any) bool {
|
||||||
|
if err, ok := v.(**errs.Error); ok {
|
||||||
|
*err = &errs.Error{
|
||||||
|
Status: http.StatusForbidden,
|
||||||
|
Msg: e.Detail,
|
||||||
|
Err: e,
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Engine implements a constraint validator for DNS names, IP addresses, Email
|
// Engine implements a constraint validator for DNS names, IP addresses, Email
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -20,7 +19,6 @@ import (
|
||||||
"github.com/smallstep/certificates/authority/provisioner"
|
"github.com/smallstep/certificates/authority/provisioner"
|
||||||
"github.com/smallstep/certificates/db"
|
"github.com/smallstep/certificates/db"
|
||||||
"github.com/smallstep/certificates/errs"
|
"github.com/smallstep/certificates/errs"
|
||||||
policy "github.com/smallstep/certificates/policy"
|
|
||||||
"github.com/smallstep/certificates/templates"
|
"github.com/smallstep/certificates/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -255,15 +253,9 @@ func (a *Authority) SignSSH(ctx context.Context, key ssh.PublicKey, opts provisi
|
||||||
|
|
||||||
// Check if authority is allowed to sign the certificate
|
// Check if authority is allowed to sign the certificate
|
||||||
if err := a.isAllowedToSignSSHCertificate(certTpl); err != nil {
|
if err := a.isAllowedToSignSSHCertificate(certTpl); err != nil {
|
||||||
var pe *policy.NamePolicyError
|
var ee *errs.Error
|
||||||
if errors.As(err, &pe) && pe.Reason == policy.NotAllowed {
|
if errors.As(err, &ee) {
|
||||||
return nil, &errs.Error{
|
return nil, ee
|
||||||
// NOTE: custom forbidden error, so that denied name is sent to client
|
|
||||||
// as well as shown in the logs.
|
|
||||||
Status: http.StatusForbidden,
|
|
||||||
Err: fmt.Errorf("authority not allowed to sign: %w", err),
|
|
||||||
Msg: fmt.Sprintf("The request was forbidden by the certificate authority: %s", err.Error()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, errs.InternalServerErr(err,
|
return nil, errs.InternalServerErr(err,
|
||||||
errs.WithMessage("authority.SignSSH: error creating ssh certificate"),
|
errs.WithMessage("authority.SignSSH: error creating ssh certificate"),
|
||||||
|
|
|
@ -28,7 +28,6 @@ import (
|
||||||
casapi "github.com/smallstep/certificates/cas/apiv1"
|
casapi "github.com/smallstep/certificates/cas/apiv1"
|
||||||
"github.com/smallstep/certificates/db"
|
"github.com/smallstep/certificates/db"
|
||||||
"github.com/smallstep/certificates/errs"
|
"github.com/smallstep/certificates/errs"
|
||||||
"github.com/smallstep/certificates/policy"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetTLSOptions returns the tls options configured.
|
// GetTLSOptions returns the tls options configured.
|
||||||
|
@ -213,15 +212,9 @@ func (a *Authority) Sign(csr *x509.CertificateRequest, signOpts provisioner.Sign
|
||||||
|
|
||||||
// Check if authority is allowed to sign the certificate
|
// Check if authority is allowed to sign the certificate
|
||||||
if err := a.isAllowedToSignX509Certificate(leaf); err != nil {
|
if err := a.isAllowedToSignX509Certificate(leaf); err != nil {
|
||||||
var pe *policy.NamePolicyError
|
var ee *errs.Error
|
||||||
if errors.As(err, &pe) && pe.Reason == policy.NotAllowed {
|
if errors.As(err, &ee) {
|
||||||
return nil, errs.ApplyOptions(&errs.Error{
|
return nil, ee
|
||||||
// NOTE: custom forbidden error, so that denied name is sent to client
|
|
||||||
// as well as shown in the logs.
|
|
||||||
Status: http.StatusForbidden,
|
|
||||||
Err: fmt.Errorf("authority not allowed to sign: %w", err),
|
|
||||||
Msg: fmt.Sprintf("The request was forbidden by the certificate authority: %s", err.Error()),
|
|
||||||
}, opts...)
|
|
||||||
}
|
}
|
||||||
return nil, errs.InternalServerErr(err,
|
return nil, errs.InternalServerErr(err,
|
||||||
errs.WithKeyVal("csr", csr),
|
errs.WithKeyVal("csr", csr),
|
||||||
|
@ -358,7 +351,14 @@ func (a *Authority) Rekey(oldCert *x509.Certificate, pk crypto.PublicKey) ([]*x5
|
||||||
// Check if the certificate is allowed to be renewed, policies or
|
// Check if the certificate is allowed to be renewed, policies or
|
||||||
// constraints might change over time.
|
// constraints might change over time.
|
||||||
if err := a.isAllowedToSignX509Certificate(newCert); err != nil {
|
if err := a.isAllowedToSignX509Certificate(newCert); err != nil {
|
||||||
return nil, err
|
var ee *errs.Error
|
||||||
|
if errors.As(err, &ee) {
|
||||||
|
return nil, ee
|
||||||
|
}
|
||||||
|
return nil, errs.InternalServerErr(err,
|
||||||
|
errs.WithKeyVal("serialNumber", oldCert.SerialNumber.String()),
|
||||||
|
errs.WithMessage("error renewing certificate"),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := a.x509CAService.RenewCertificate(&casapi.RenewCertificateRequest{
|
resp, err := a.x509CAService.RenewCertificate(&casapi.RenewCertificateRequest{
|
||||||
|
|
|
@ -4,11 +4,13 @@ import (
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"go.step.sm/crypto/x509util"
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
|
||||||
"go.step.sm/crypto/x509util"
|
"github.com/smallstep/certificates/errs"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NamePolicyReason int
|
type NamePolicyReason int
|
||||||
|
@ -62,6 +64,22 @@ func (e *NamePolicyError) Error() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As implements the As(any) bool interface and allows to use "errors.As()" to
|
||||||
|
// convert a NotAllowed NamePolicyError to an errs.Error.
|
||||||
|
func (e *NamePolicyError) As(v any) bool {
|
||||||
|
if e.Reason == NotAllowed {
|
||||||
|
if err, ok := v.(**errs.Error); ok {
|
||||||
|
*err = &errs.Error{
|
||||||
|
Status: http.StatusForbidden,
|
||||||
|
Msg: fmt.Sprintf("The request was forbidden by the certificate authority: %s", e.Error()),
|
||||||
|
Err: e,
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (e *NamePolicyError) Detail() string {
|
func (e *NamePolicyError) Detail() string {
|
||||||
return e.detail
|
return e.detail
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue