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

Refactor Sign/Verify functions into their own library. #108

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions certstore/certstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@ var (
// ErrUnsupportedHash is returned by Signer.Sign() when the provided hash
// algorithm isn't supported.
ErrUnsupportedHash = errors.New("unsupported hash algorithm")

openStore func() (Store, error)
)

// RegisterStore registers a func to initialize a new certificate store.
// This should be invoked by providers during init().
func RegisterStore(f func() (Store, error)) {
openStore = f
}

// Open opens the system's certificate store.
func Open() (Store, error) {
return openStore()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package certstore
package providers

/*
#cgo CFLAGS: -x objective-c
Expand All @@ -16,8 +16,14 @@ import (
"fmt"
"io"
"unsafe"

"github.com/github/smimesign/certstore"
)

func init() {
certstore.RegisterStore(openStore)
}

// work around https://golang.org/doc/go1.10#cgo
// in go>=1.10 CFTypeRefs are translated to uintptrs instead of pointers.
var (
Expand All @@ -37,12 +43,12 @@ var (
type macStore int

// openStore is a function for opening a macStore.
func openStore() (macStore, error) {
func openStore() (certstore.Store, error) {
return macStore(0), nil
}

// Identities implements the Store interface.
func (s macStore) Identities() ([]Identity, error) {
func (s macStore) Identities() ([]certstore.Identity, error) {
query := mapToCFDictionary(map[C.CFTypeRef]C.CFTypeRef{
C.CFTypeRef(C.kSecClass): C.CFTypeRef(C.kSecClassIdentity),
C.CFTypeRef(C.kSecReturnRef): C.CFTypeRef(C.kCFBooleanTrue),
Expand All @@ -56,7 +62,7 @@ func (s macStore) Identities() ([]Identity, error) {
var absResult C.CFTypeRef
if err := osStatusError(C.SecItemCopyMatching(query, &absResult)); err != nil {
if err == errSecItemNotFound {
return []Identity{}, nil
return []certstore.Identity{}, nil
}

return nil, err
Expand All @@ -71,7 +77,7 @@ func (s macStore) Identities() ([]Identity, error) {
identRefs := make([]C.CFTypeRef, n)
C.CFArrayGetValues(aryResult, C.CFRange{0, n}, (*unsafe.Pointer)(unsafe.Pointer(&identRefs[0])))

idents := make([]Identity, 0, n)
idents := make([]certstore.Identity, 0, n)
for _, identRef := range identRefs {
idents = append(idents, newMacIdentity(C.SecIdentityRef(identRef)))
}
Expand Down Expand Up @@ -319,7 +325,7 @@ func (i *macIdentity) getAlgo(hash crypto.Hash) (algo C.SecKeyAlgorithm, err err
case crypto.SHA512:
algo = C.kSecKeyAlgorithmECDSASignatureDigestX962SHA512
default:
err = ErrUnsupportedHash
err = certstore.ErrUnsupportedHash
}
case *rsa.PublicKey:
switch hash {
Expand All @@ -332,7 +338,7 @@ func (i *macIdentity) getAlgo(hash crypto.Hash) (algo C.SecKeyAlgorithm, err err
case crypto.SHA512:
algo = C.kSecKeyAlgorithmRSASignatureDigestPKCS1v15SHA512
default:
err = ErrUnsupportedHash
err = certstore.ErrUnsupportedHash
}
default:
err = errors.New("unsupported key type")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package certstore
package providers

import "errors"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package certstore
package providers

import (
"crypto"
Expand All @@ -11,6 +11,7 @@ import (
"crypto/x509"
"testing"

"github.com/github/smimesign/certstore"
"github.com/github/smimesign/fakeca"
)

Expand All @@ -24,7 +25,7 @@ func TestImportDeleteECDSA(t *testing.T) {

// ImportDeleteHelper is an abstraction for testing identity Import()/Delete().
func ImportDeleteHelper(t *testing.T, i *fakeca.Identity) {
withStore(t, func(store Store) {
withStore(t, func(store certstore.Store) {
// Import an identity
if err := store.Import(i.PFX("asdf"), "asdf"); err != nil {
t.Fatal(err)
Expand All @@ -39,7 +40,7 @@ func ImportDeleteHelper(t *testing.T, i *fakeca.Identity) {
defer ident.Close()
}

var found Identity
var found certstore.Identity
for _, ident := range idents {
crt, errr := ident.Certificate()
if errr != nil {
Expand Down Expand Up @@ -95,7 +96,7 @@ func TestSignerRSA(t *testing.T) {
t.Fatal("expected priv to be an RSA private key")
}

withIdentity(t, leafRSA, func(ident Identity) {
withIdentity(t, leafRSA, func(ident certstore.Identity) {
signer, err := ident.Signer()
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -129,7 +130,7 @@ func TestSignerRSA(t *testing.T) {
// SHA256WithRSA
sha256Digest := sha256.Sum256([]byte("hello"))
sig, err = signer.Sign(rand.Reader, sha256Digest[:], crypto.SHA256)
if err == ErrUnsupportedHash {
if err == certstore.ErrUnsupportedHash {
// Some Windows CSPs may not support this algorithm. Pass...
} else if err != nil {
t.Fatal(err)
Expand All @@ -142,7 +143,7 @@ func TestSignerRSA(t *testing.T) {
// SHA384WithRSA
sha384Digest := sha512.Sum384([]byte("hello"))
sig, err = signer.Sign(rand.Reader, sha384Digest[:], crypto.SHA384)
if err == ErrUnsupportedHash {
if err == certstore.ErrUnsupportedHash {
// Some Windows CSPs may not support this algorithm. Pass...
} else if err != nil {
t.Fatal(err)
Expand All @@ -155,7 +156,7 @@ func TestSignerRSA(t *testing.T) {
// SHA512WithRSA
sha512Digest := sha512.Sum512([]byte("hello"))
sig, err = signer.Sign(rand.Reader, sha512Digest[:], crypto.SHA512)
if err == ErrUnsupportedHash {
if err == certstore.ErrUnsupportedHash {
// Some Windows CSPs may not support this algorithm. Pass...
} else if err != nil {
t.Fatal(err)
Expand All @@ -174,7 +175,7 @@ func TestSignerRSA(t *testing.T) {
// Unsupported hash
sha224Digest := sha256.Sum224([]byte("hello"))
_, err = signer.Sign(rand.Reader, sha224Digest[:], crypto.SHA224)
if err != ErrUnsupportedHash {
if err != certstore.ErrUnsupportedHash {
t.Fatal("expected ErrUnsupportedHash, got ", err)
}
})
Expand All @@ -186,7 +187,7 @@ func TestSignerECDSA(t *testing.T) {
t.Fatal("expected priv to be an ECDSA private key")
}

withIdentity(t, leafEC, func(ident Identity) {
withIdentity(t, leafEC, func(ident certstore.Identity) {
signer, err := ident.Signer()
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -263,9 +264,9 @@ func TestCertificateEC(t *testing.T) {
}

func CertificateHelper(t *testing.T, leaf *fakeca.Identity) {
withIdentity(t, root, func(caIdent Identity) {
withIdentity(t, intermediate, func(interIdent Identity) {
withIdentity(t, leaf, func(leafIdent Identity) {
withIdentity(t, root, func(caIdent certstore.Identity) {
withIdentity(t, intermediate, func(interIdent certstore.Identity) {
withIdentity(t, leaf, func(leafIdent certstore.Identity) {
crtActual, err := leafIdent.Certificate()
if err != nil {
t.Fatal(err)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package certstore
package providers

/*
#cgo windows LDFLAGS: -lcrypt32 -lncrypt
Expand Down Expand Up @@ -75,8 +75,12 @@ type winStore struct {
store C.HCERTSTORE
}

func init() {
certstore.RegisterStore(openStore)
}

// openStore opens the current user's personal cert store.
func openStore() (*winStore, error) {
func openStore() (certstore.Store, error) {
storeName := unsafe.Pointer(stringToUTF16("MY"))
defer C.free(storeName)

Expand Down
18 changes: 10 additions & 8 deletions certstore/main_test.go → certstore/providers/main_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package certstore
package providers

import (
"crypto/ecdsa"
Expand All @@ -9,6 +9,7 @@ import (
"crypto/x509/pkix"
"testing"

"github.com/github/smimesign/certstore"
"github.com/github/smimesign/fakeca"
)

Expand Down Expand Up @@ -38,11 +39,12 @@ var (

func init() {
// delete any fixtures from a previous test run.
certstore.RegisterStore(openStore)
clearFixtures()
}

func withStore(t *testing.T, cb func(Store)) {
store, err := Open()
func withStore(t *testing.T, cb func(certstore.Store)) {
store, err := certstore.Open()
if err != nil {
t.Fatal(err)
}
Expand All @@ -51,8 +53,8 @@ func withStore(t *testing.T, cb func(Store)) {
cb(store)
}

func withIdentity(t *testing.T, i *fakeca.Identity, cb func(Identity)) {
withStore(t, func(store Store) {
func withIdentity(t *testing.T, i *fakeca.Identity, cb func(certstore.Identity)) {
withStore(t, func(store certstore.Store) {
// Import an identity
if err := store.Import(i.PFX("asdf"), "asdf"); err != nil {
t.Fatal(err)
Expand All @@ -67,7 +69,7 @@ func withIdentity(t *testing.T, i *fakeca.Identity, cb func(Identity)) {
defer ident.Close()
}

var found Identity
var found certstore.Identity
for _, ident := range idents {
crt, err := ident.Certificate()
if err != nil {
Expand All @@ -86,7 +88,7 @@ func withIdentity(t *testing.T, i *fakeca.Identity, cb func(Identity)) {
}

// Clean up after ourselves.
defer func(f Identity) {
defer func(f certstore.Identity) {
if err := f.Delete(); err != nil {
t.Fatal(err)
}
Expand All @@ -97,7 +99,7 @@ func withIdentity(t *testing.T, i *fakeca.Identity, cb func(Identity)) {
}

func clearFixtures() {
store, err := Open()
store, err := certstore.Open()
if err != nil {
panic(err)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package certstore
package providers

import (
"fmt"
Expand Down
Loading