Skip to content

Commit

Permalink
refactor: rename custom errors (#29)
Browse files Browse the repository at this point in the history
Signed-off-by: Binbin Li <libinbin@microsoft.com>
  • Loading branch information
binbin-li committed Aug 10, 2022
1 parent a45a51e commit 2e99fe0
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 91 deletions.
42 changes: 10 additions & 32 deletions signature/algorithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,49 +39,27 @@ type KeySpec struct {
func ExtractKeySpec(signingCert *x509.Certificate) (KeySpec, error) {
switch key := signingCert.PublicKey.(type) {
case *rsa.PublicKey:
switch key.Size() {
case 256:
return KeySpec{
Type: KeyTypeRSA,
Size: 2048,
}, nil
case 384:
switch bitSize := key.Size() << 3; bitSize {
case 2048, 3072, 4096:
return KeySpec{
Type: KeyTypeRSA,
Size: 3072,
}, nil
case 512:
return KeySpec{
Type: KeyTypeRSA,
Size: 4096,
Size: bitSize,
}, nil
default:
return KeySpec{}, UnsupportedSigningKeyError{
keyType: KeyTypeRSA,
keyLength: key.Size(),
return KeySpec{}, &UnsupportedSigningKeyError{
fmt.Sprintf("rsa key size %d is not supported", bitSize),
}
}
case *ecdsa.PublicKey:
switch key.Curve.Params().BitSize {
case 256:
return KeySpec{
Type: KeyTypeEC,
Size: 256,
}, nil
case 384:
return KeySpec{
Type: KeyTypeEC,
Size: 384,
}, nil
case 521:
switch bitSize := key.Curve.Params().BitSize; bitSize {
case 256, 384, 521:
return KeySpec{
Type: KeyTypeEC,
Size: 521,
Size: bitSize,
}, nil
default:
return KeySpec{}, UnsupportedSigningKeyError{
keyType: KeyTypeEC,
keyLength: key.Curve.Params().BitSize,
return KeySpec{}, &UnsupportedSigningKeyError{
fmt.Sprintf("ecdsa key size %d is not supported", bitSize),
}
}
}
Expand Down
49 changes: 23 additions & 26 deletions signature/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,45 @@ import "fmt"

// MalformedSignatureError is used when Signature envelope is malformed.
type MalformedSignatureError struct {
msg string
Msg string
}

// NewMalformedSignatureError creates a MalformedSignatureError with the message
func NewMalformedSignatureError(msg string) MalformedSignatureError {
return MalformedSignatureError{
msg: msg,
}
}

// Error returns the error message
func (e MalformedSignatureError) Error() string {
if e.msg != "" {
return e.msg
// Error returns the error message.
func (e *MalformedSignatureError) Error() string {
if e.Msg != "" {
return e.Msg
}
return "signature envelope format is malformed"
}

// UnsupportedSigningKeyError is used when a signing key is not supported
// UnsupportedSigningKeyError is used when a signing key is not supported.
type UnsupportedSigningKeyError struct {
keyType KeyType
keyLength int
Msg string
}

// Error returns the error message
func (e UnsupportedSigningKeyError) Error() string {
if e.keyType != KeyTypeRSA && e.keyType != KeyTypeEC && e.keyLength != 0 {
return fmt.Sprintf("%d signing key of size %d is not supported", e.keyType, e.keyLength)
// Error returns the error message.
func (e *UnsupportedSigningKeyError) Error() string {
if e.Msg != "" {
return e.Msg
}
return "signing key is not supported"
}

// MalformedArgumentError is used when an argument to a function is malformed.
type MalformedArgumentError struct {
param string
err error
Param string
Err error
}

// Error returns the error message
func (e MalformedArgumentError) Error() string {
if e.err != nil {
return fmt.Sprintf("%q param is malformed. Error: %s", e.param, e.err.Error())
// Error returns the error message.
func (e *MalformedArgumentError) Error() string {
if e.Err != nil {
return fmt.Sprintf("%q param is malformed. Error: %s", e.Param, e.Err.Error())
}
return fmt.Sprintf("%q param is malformed", e.param)
return fmt.Sprintf("%q param is malformed", e.Param)
}

// Unwrap returns the unwrapped error
func (e *MalformedArgumentError) Unwrap() error {
return e.Err
}
70 changes: 38 additions & 32 deletions signature/internal/base/envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@ import (
)

// Envelope represents a general envelope wrapping a raw signature and envelope
// in specific format
// in specific format.
type Envelope struct {
signature.Envelope
Raw []byte
}

var errorFunc = func(s string) error {
return signature.NewMalformedSignatureError(s)
signature.Envelope // internal envelope in a specific format(COSE/JWS)
Raw []byte // raw signature
}

// Sign generates signature using given SignRequest.
Expand All @@ -33,42 +29,46 @@ func (e *Envelope) Sign(req *signature.SignRequest) ([]byte, error) {
return e.Raw, nil
}

// Verify performs integrity and other signature specification related validations
// Verify performs integrity and other signature specification related validations.
// Returns the payload to be signed and SignerInfo object containing the information
// about the signature.
func (e *Envelope) Verify() (*signature.Payload, *signature.SignerInfo, error) {
if len(e.Raw) == 0 {
return nil, nil, errorFunc("")
return nil, nil, &signature.MalformedSignatureError{}
}

if _, _, err := e.Envelope.Verify(); err != nil {
payload, _, err := e.Envelope.Verify()
if err != nil {
return nil, nil, err
}
signerInfo, err := e.Envelope.SignerInfo()

signerInfo, err := e.SignerInfo()
if err != nil {
return nil, nil, err
}

return nil, signerInfo, nil
return payload, signerInfo, nil
}

// Payload returns the payload to be signed
// Payload returns the payload to be signed.
func (e *Envelope) Payload() (*signature.Payload, error) {
if len(e.Raw) == 0 {
return nil, errorFunc("raw signature is empty")
return nil, &signature.MalformedSignatureError{Msg: "raw signature is empty"}
}
return e.Envelope.Payload()
}

// SignerInfo returns information about the Signature envelope
// SignerInfo returns information about the Signature envelope.
func (e *Envelope) SignerInfo() (*signature.SignerInfo, error) {
if len(e.Raw) == 0 {
return nil, errorFunc("raw signature is empty")
return nil, &signature.MalformedSignatureError{Msg: "raw signature is empty"}
}

signerInfo, err := e.Envelope.SignerInfo()
if err != nil {
return nil, errorFunc(fmt.Sprintf("signature envelope format is malformed. error: %s", err))
return nil, &signature.MalformedSignatureError{
Msg: fmt.Sprintf("signature envelope format is malformed. error: %s", err),
}
}

if err := validateSignerInfo(signerInfo); err != nil {
Expand All @@ -82,7 +82,7 @@ func (e *Envelope) SignerInfo() (*signature.SignerInfo, error) {
return signerInfo, nil
}

// validatePayload performs validation of the payload
// validatePayload performs validation of the payload.
func (e *Envelope) validatePayload() error {
payload, err := e.Envelope.Payload()
if err != nil {
Expand All @@ -103,11 +103,11 @@ func validateSignRequest(req *signature.SignRequest) error {
}

if len(req.Payload.Content) == 0 {
return errorFunc("payload not present")
return &signature.MalformedSignatureError{Msg: "payload not present"}
}

if req.Signer == nil {
return errorFunc("signer is nil")
return &signature.MalformedSignatureError{Msg: "signer is nil"}
}

return nil
Expand All @@ -116,11 +116,11 @@ func validateSignRequest(req *signature.SignRequest) error {
// validateSignerInfo performs basic set of validations on SignerInfo struct.
func validateSignerInfo(info *signature.SignerInfo) error {
if len(info.Signature) == 0 {
return errorFunc("signature not present or is empty")
return &signature.MalformedSignatureError{Msg: "signature not present or is empty"}
}

if info.SignatureAlgorithm == 0 {
return errorFunc("SignatureAlgorithm is not present")
return &signature.MalformedSignatureError{Msg: "SignatureAlgorithm is not present"}
}

signingTime := info.SignedAttributes.SigningTime
Expand All @@ -139,45 +139,51 @@ func validateSignerInfo(info *signature.SignerInfo) error {
// time duration.
func validateSigningTime(signingTime, expireTime time.Time) error {
if signingTime.IsZero() {
return errorFunc("signing-time not present")
return &signature.MalformedSignatureError{Msg: "signing-time not present"}
}

if !expireTime.IsZero() && (expireTime.Before(signingTime) || expireTime.Equal(signingTime)) {
return errorFunc("expiry cannot be equal or before the signing time")
return &signature.MalformedSignatureError{Msg: "expiry cannot be equal or before the signing time"}
}
return nil
}

// validatePayload performs validation of the payload
// validatePayload performs validation of the payload.
func validatePayload(payload *signature.Payload) error {
if len(payload.Content) == 0 {
return errorFunc("content not present")
return &signature.MalformedSignatureError{Msg: "content not present"}
}

if payload.ContentType != signature.MediaTypePayloadV1 {
return errorFunc(fmt.Sprintf("payload content type: {%s} not supported", payload.ContentType))
return &signature.MalformedSignatureError{
Msg: fmt.Sprintf("payload content type: {%s} not supported", payload.ContentType),
}
}

return nil
}

// validateCertificateChain performs the validation of the certificate chain
// validateCertificateChain performs the validation of the certificate chain.
func validateCertificateChain(certChain []*x509.Certificate, signTime time.Time, expectedAlg signature.Algorithm) error {
if len(certChain) == 0 {
return errorFunc("certificate-chain not present or is empty")
return &signature.MalformedSignatureError{Msg: "certificate-chain not present or is empty"}
}

err := nx509.ValidateCodeSigningCertChain(certChain, signTime)
if err != nil {
return errorFunc(fmt.Sprintf("certificate-chain is invalid, %s", err))
return &signature.MalformedSignatureError{
Msg: fmt.Sprintf("certificate-chain is invalid, %s", err),
}
}

signingAlg, err := getSignatureAlgorithm(certChain[0])
if err != nil {
return errorFunc(err.Error())
return &signature.MalformedSignatureError{Msg: err.Error()}
}
if signingAlg != expectedAlg {
return errorFunc("mismatch between signature algorithm derived from signing certificate and signing algorithm specified")
return &signature.MalformedSignatureError{
Msg: "mismatch between signature algorithm derived from signing certificate and signing algorithm specified",
}
}

return nil
Expand Down
6 changes: 5 additions & 1 deletion signature/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package signature
import (
"crypto"
"crypto/x509"
"errors"
"fmt"
)

Expand Down Expand Up @@ -32,7 +33,10 @@ type signer struct {
// NewLocalSigner returns a new signer with certificates and private key
func NewLocalSigner(certs []*x509.Certificate, key crypto.PrivateKey) (LocalSigner, error) {
if len(certs) == 0 {
return nil, MalformedArgumentError{param: "certs"}
return nil, &MalformedArgumentError{
Param: "certs",
Err: errors.New("empty certs"),
}
}
keySpec, err := ExtractKeySpec(certs[0])
if err != nil {
Expand Down

0 comments on commit 2e99fe0

Please sign in to comment.