Skip to content

Commit

Permalink
feat: add cose support by refining signer module (#25)
Browse files Browse the repository at this point in the history
Signed-off-by: Binbin Li <[email protected]>
  • Loading branch information
binbin-li authored Aug 8, 2022
1 parent 6670fef commit 2994a36
Show file tree
Hide file tree
Showing 7 changed files with 295 additions and 0 deletions.
38 changes: 38 additions & 0 deletions signature/algorithm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package signature

import (
"crypto/x509"
"fmt"
)

// Algorithm lists supported algorithms.
type Algorithm int

// One of following supported specs
// https://github.com/notaryproject/notaryproject/blob/main/signature-specification.md#algorithm-selection
const (
AlgorithmPS256 Algorithm = 1 + iota // RSASSA_PSS_SHA256
AlgorithmPS384 // RSASSA_PSS_SHA384
AlgorithmPS512 // RSASSA_PSS_SHA512
AlgorithmES256 // ECDSA_SHA256
AlgorithmES384 // ECDSA_SHA384
AlgorithmES512 // ECDSA_SHA512
)

// KeyType defines the key type
type KeyType int

const (
KeyTypeRSA KeyType = 1 + iota // KeyType RSA
KeyTypeEC // KeyType EC
)

// KeySpec defines a key type and size.
type KeySpec struct {
Type KeyType
Size int
}

func ExtractKeySpec(signingCert *x509.Certificate) (KeySpec, error) {
return KeySpec{}, fmt.Errorf("not implemented")
}
48 changes: 48 additions & 0 deletions signature/cose/cose.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package cose

import (
"fmt"

"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation-core-go/signature/internal/base"
)

const MediaTypeEnvelope = "application/cose"

func init() {
if err := signature.RegisterEnvelopeType(MediaTypeEnvelope, NewEnvelope, ParseEnvelope); err != nil {
panic(err)
}
}

type envelope struct {
}

func (e *envelope) Sign(req *signature.SignRequest) ([]byte, error) {
return nil, fmt.Errorf("not implemented")
}

func (e *envelope) Verify() (*signature.Payload, *signature.SignerInfo, error) {
return nil, nil, fmt.Errorf("not implemented")
}

func (e *envelope) Payload() (*signature.Payload, error) {
return nil, fmt.Errorf("not implemented")
}

func (e *envelope) SignerInfo() (*signature.SignerInfo, error) {
return nil, fmt.Errorf("not implemented")
}

func NewEnvelope() signature.Envelope {
return &base.Envelope{
Envelope: &envelope{},
}
}

func ParseEnvelope(envelopeBytes []byte) (signature.Envelope, error) {
return &base.Envelope{
Envelope: &envelope{},
Raw: envelopeBytes,
}, nil
}
25 changes: 25 additions & 0 deletions signature/envelope.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package signature

import "fmt"

type Envelope interface {
Sign(req *SignRequest) ([]byte, error)
Verify() (*Payload, *SignerInfo, error)
Payload() (*Payload, error)
SignerInfo() (*SignerInfo, error)
}

type NewEnvelopeFunc func() Envelope
type ParseEnvelopeFunc func([]byte) (Envelope, error)

func RegisterEnvelopeType(mediaType string, newFunc NewEnvelopeFunc, parseFunc ParseEnvelopeFunc) error {
return nil
}

func NewEnvelope(mediaType string) (Envelope, error) {
return nil, fmt.Errorf("not implemented")
}

func ParseEnvelope(mediaType string, envelopeBytes []byte) (Envelope, error) {
return nil, fmt.Errorf("not implemented")
}
41 changes: 41 additions & 0 deletions signature/internal/base/envelope.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package base

import (
"fmt"

"github.com/notaryproject/notation-core-go/signature"
)

type Envelope struct {
signature.Envelope
Raw []byte
}

func (e *Envelope) Sign(req *signature.SignRequest) ([]byte, error) {
err := validateSignRequest(req)
if err != nil {
return nil, err
}
e.Raw, err = e.Envelope.Sign(req)
if err != nil {
return nil, err
}
return e.Raw, nil
}

func (e *Envelope) Verify() (*signature.Payload, *signature.SignerInfo, error) {
return nil, nil, fmt.Errorf("not implemented")
}

func (e *Envelope) Payload() (*signature.Payload, error) {
return nil, fmt.Errorf("not implemented")
}

func (e *Envelope) SignerInfo() (*signature.SignerInfo, error) {
return nil, fmt.Errorf("not implemented")
}

// validateSignRequest performs basic set of validations on SignRequest struct.
func validateSignRequest(req *signature.SignRequest) error {
return nil
}
48 changes: 48 additions & 0 deletions signature/jws/jws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package jws

import (
"fmt"

"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation-core-go/signature/internal/base"
)

const MediaTypeEnvelope = "application/jose+json"

func init() {
if err := signature.RegisterEnvelopeType(MediaTypeEnvelope, NewEnvelope, ParseEnvelope); err != nil {
panic(err)
}
}

type envelope struct {
}

func NewEnvelope() signature.Envelope {
return &base.Envelope{
Envelope: &envelope{},
}
}

func ParseEnvelope(envelopeBytes []byte) (signature.Envelope, error) {
return &base.Envelope{
Envelope: &envelope{},
Raw: envelopeBytes,
}, nil
}

func (e *envelope) Sign(req *signature.SignRequest) ([]byte, error) {
return nil, fmt.Errorf("not implemented")
}

func (e *envelope) Verify() (*signature.Payload, *signature.SignerInfo, error) {
return nil, nil, fmt.Errorf("not implemented")
}

func (e *envelope) Payload() (*signature.Payload, error) {
return nil, fmt.Errorf("not implemented")
}

func (e *envelope) SignerInfo() (*signature.SignerInfo, error) {
return nil, fmt.Errorf("not implemented")
}
45 changes: 45 additions & 0 deletions signature/signer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package signature

import (
"crypto"
"crypto/x509"
"fmt"
)

// Signer is used to sign bytes generated after creating signature envelope.
type Signer interface {
Sign(digest []byte) ([]byte, error)
CertificateChain() ([]*x509.Certificate, error) // note: check signature first
KeySpec() (KeySpec, error)
}

type LocalSigner interface {
Signer
PrivateKey() crypto.PrivateKey
}

type signer struct {
keySpec KeySpec
key crypto.PrivateKey
certs []*x509.Certificate
}

func NewSigner(certs []*x509.Certificate, key crypto.PrivateKey) (Signer, error) {
return nil, fmt.Errorf("not implemented")
}

func (s *signer) Sign(digest []byte) ([]byte, error) {
return nil, fmt.Errorf("local signer doesn't support Sign with digest")
}

func (s *signer) CertificateChain() ([]*x509.Certificate, error) {
return s.certs, nil
}

func (s *signer) KeySpec() (KeySpec, error) {
return s.keySpec, nil
}

func (s *signer) PrivateKey() crypto.PrivateKey {
return s.key
}
50 changes: 50 additions & 0 deletions signature/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package signature

import (
"crypto/x509"
"time"
)

// SignedAttributes represents signed metadata in the Signature envelope
type SignedAttributes struct {
SigningTime time.Time
Expiry time.Time
ExtendedAttributes []Attribute
}

// UnsignedAttributes represents unsigned metadata in the Signature envelope
type UnsignedAttributes struct {
SigningAgent string
}

// Attribute represents metadata in the Signature envelope
type Attribute struct {
Key string
Critical bool
Value interface{}
}

// SignRequest is used to generate Signature.
type SignRequest struct {
Payload Payload
Signer Signer
SigningTime time.Time
Expiry time.Time
ExtendedSignedAttributes []Attribute
SigningAgent string
}

// SignerInfo represents a parsed signature envelope that is agnostic to signature envelope format.
type SignerInfo struct {
SignedAttributes SignedAttributes
UnsignedAttributes UnsignedAttributes
SignatureAlgorithm Algorithm
CertificateChain []*x509.Certificate
Signature []byte
TimestampSignature []byte
}

type Payload struct {
ContentType string
Content []byte
}

0 comments on commit 2994a36

Please sign in to comment.