Skip to content

Commit

Permalink
change from using crypki.PublicKey/SignAlgo to x509.PublicKey/SignAlgo (
Browse files Browse the repository at this point in the history
#126)

* change from using crypki.Public/SignAlgo to x509.Public/SignAlgo

* add correct testcase
  • Loading branch information
hkadakia authored Nov 15, 2021
1 parent 2949ca0 commit a57e576
Show file tree
Hide file tree
Showing 21 changed files with 133 additions and 243 deletions.
5 changes: 3 additions & 2 deletions cmd/gen-cacert/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package main

import (
"context"
"crypto/x509"
"encoding/json"
"errors"
"flag"
Expand Down Expand Up @@ -84,8 +85,8 @@ func main() {
SlotNumber: uint(cc.SlotNumber),
UserPinPath: cc.UserPinPath,
KeyLabel: cc.KeyLabel,
KeyType: crypki.PublicKeyAlgorithm(cc.KeyType),
SignatureAlgo: crypki.SignatureAlgorithm(cc.SignatureAlgo),
KeyType: x509.PublicKeyAlgorithm(cc.KeyType),
SignatureAlgo: x509.SignatureAlgorithm(cc.SignatureAlgo),
SessionPoolSize: 2,
X509CACertLocation: "/tmp/509_ca.crt",
CreateCACertIfNotExist: true,
Expand Down
16 changes: 7 additions & 9 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ package config

import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"fmt"
"os"
"strings"
"time"

"github.com/theparanoids/crypki"
)

const (
Expand All @@ -22,8 +21,8 @@ const (
defaultTLSHost = ""
defaultTLSPort = "4443"
defaultPoolSize = 2
defaultKeyType = crypki.RSA
defaultSignatureAlgo = crypki.SHA256WithRSA
defaultKeyType = x509.RSA
defaultSignatureAlgo = x509.SHA256WithRSA

defaultShutdownOnSigningFailureConsecutiveCount = 4
defaultShutdownOnSigningFailureTimerDurationSecond = 60
Expand Down Expand Up @@ -83,9 +82,9 @@ type KeyConfig struct {
// SessionPoolSize specifies the number of sessions that are opened for this key.
SessionPoolSize int
// KeyType specifies the type of key, such as RSA or ECDSA.
KeyType crypki.PublicKeyAlgorithm
KeyType x509.PublicKeyAlgorithm
// SignatureAlgo specifies the type of signature hash function such as SHA256WithRSA or ECDSAWithSHA384.
SignatureAlgo crypki.SignatureAlgorithm
SignatureAlgo x509.SignatureAlgorithm

// Below are configs of x509 extensions for this key. Useful when this key will be used
// for signing x509 certificates.
Expand Down Expand Up @@ -183,11 +182,11 @@ func (c *Config) validate() error {
return fmt.Errorf("key %q: CA cert is supposed to be created if it doesn't exist but X509CACertLocation is not specified", key.Identifier)
}

if key.KeyType < crypki.RSA || key.KeyType > crypki.ECDSA {
if key.KeyType < x509.RSA || key.KeyType > x509.Ed25519 {
return fmt.Errorf("key %q: invalid Key type specified", key.Identifier)
}

if key.SignatureAlgo < crypki.SHA256WithRSA || key.SignatureAlgo > crypki.ECDSAWithSHA384 {
if key.SignatureAlgo < x509.SHA256WithRSA || key.SignatureAlgo > x509.PureEd25519 {
return fmt.Errorf("key %q: invalid signature hash algo specified", key.Identifier)
}
}
Expand Down Expand Up @@ -255,7 +254,6 @@ func (c *Config) loadDefaults() {
if c.ShutdownOnInternalFailureCriteria.TimerCountLimit == 0 {
c.ShutdownOnInternalFailureCriteria.TimerCountLimit = defaultShutdownOnSigningFailureTimerCount
}

if c.IdleTimeout == 0 {
c.IdleTimeout = defaultIdleTimeout
}
Expand Down
6 changes: 3 additions & 3 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ func TestParse(t *testing.T) {
TLSPort: "4443",
SignersPerPool: 2,
Keys: []KeyConfig{
{"key1", 1, "", "/path/1", "foo", 2, 2, 3, []string{}, []string{}, true, "/path/foo", "", "", "", "", "", "My CA", 0},
{"key2", 2, "", "/path/2", "bar", 2, 1, 1, []string{"http://test.ocsp.com:8888"}, []string{"http://test.crl.com:8889"}, false, "", "", "", "", "", "", "", 0},
{"key3", 0, "foo", "/path/3", "baz", 2, 1, 1, []string{"http://test1.ocsp.com:8888", "http://test2.ocsp.com:8888"}, []string{"http://test1.crl.com:8889", "http://test2.crl.com:8889"}, false, "/path/baz", "", "", "", "", "", "", 0},
{"key1", 1, "", "/path/1", "foo", 2, 3, 10, []string{}, []string{}, true, "/path/foo", "", "", "", "", "", "My CA", 0},
{"key2", 2, "", "/path/2", "bar", 2, 1, 4, []string{"http://test.ocsp.com:8888"}, []string{"http://test.crl.com:8889"}, false, "", "", "", "", "", "", "", 0},
{"key3", 0, "foo", "/path/3", "baz", 2, 1, 4, []string{"http://test1.ocsp.com:8888", "http://test2.ocsp.com:8888"}, []string{"http://test1.crl.com:8889", "http://test2.crl.com:8889"}, false, "/path/baz", "", "", "", "", "", "", 0},
},
KeyUsages: []KeyUsage{
{"/sig/x509-cert", []string{"key1", "key3"}, 3600, true},
Expand Down
2 changes: 1 addition & 1 deletion config/testdata/testconf-bad-endpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"TLSClientAuthMode": 4,
"X509CACertLocation":"testdata/cacert.pem",
"Keys": [
{"Identifier": "key1", "KeyLabel": "foo", "KeyType":1, "SignatureAlgo": 2, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"},
{"Identifier": "key1", "KeyLabel": "foo", "KeyType":1, "SignatureAlgo": 4, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"},
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"},
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"}
],
Expand Down
2 changes: 1 addition & 1 deletion config/testdata/testconf-bad-unknown-signature-algo.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"TLSClientAuthMode": 4,
"X509CACertLocation":"testdata/cacert.pem",
"Keys": [
{"Identifier": "key1", "KeyLabel": "foo", "KeyType":1, "SignatureAlgo": 14, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"},
{"Identifier": "key1", "KeyLabel": "foo", "KeyType":1, "SignatureAlgo": 22, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"},
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"},
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"}
],
Expand Down
2 changes: 1 addition & 1 deletion config/testdata/testconf-bad-unsupported-key-type.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"TLSClientAuthMode": 4,
"X509CACertLocation":"testdata/cacert.pem",
"Keys": [
{"Identifier": "key1", "KeyLabel": "foo", "KeyType":3, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"},
{"Identifier": "key1", "KeyLabel": "foo", "KeyType":5, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"},
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"},
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"}
],
Expand Down
6 changes: 3 additions & 3 deletions config/testdata/testconf-good.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"TLSClientAuthMode": 4,
"X509CACertLocation":"testdata/cacert.pem",
"Keys": [
{"Identifier": "key1", "KeyLabel": "foo", "KeyType": 2, "SignatureAlgo": 3, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA", "OCSPServers": [], "CRLDistributionPoints": []},
{"Identifier": "key2", "KeyLabel": "bar", "KeyType": 1, "SignatureAlgo": 1, "SlotNumber": 2, "UserPinPath" : "/path/2", "OCSPServers": ["http://test.ocsp.com:8888"], "CRLDistributionPoints": ["http://test.crl.com:8889"]},
{"Identifier": "key3", "KeyLabel": "baz", "KeyType": 1, "SignatureAlgo": 1, "SlotNumber": 0, "TokenLabel": "foo", "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz", "OCSPServers": ["http://test1.ocsp.com:8888", "http://test2.ocsp.com:8888"], "CRLDistributionPoints": ["http://test1.crl.com:8889", "http://test2.crl.com:8889"]}
{"Identifier": "key1", "KeyLabel": "foo", "KeyType": 3, "SignatureAlgo": 10, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA", "OCSPServers": [], "CRLDistributionPoints": []},
{"Identifier": "key2", "KeyLabel": "bar", "KeyType": 1, "SignatureAlgo": 4, "SlotNumber": 2, "UserPinPath" : "/path/2", "OCSPServers": ["http://test.ocsp.com:8888"], "CRLDistributionPoints": ["http://test.crl.com:8889"]},
{"Identifier": "key3", "KeyLabel": "baz", "KeyType": 1, "SignatureAlgo": 4, "SlotNumber": 0, "TokenLabel": "foo", "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz", "OCSPServers": ["http://test1.ocsp.com:8888", "http://test2.ocsp.com:8888"], "CRLDistributionPoints": ["http://test1.crl.com:8889", "http://test2.crl.com:8889"]}
],
"KeyUsages": [
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"], "MaxValidity": 3600, "PrioritySchedulingEnabled": true},
Expand Down
24 changes: 0 additions & 24 deletions crypki.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,6 @@ const (
UserSSHKey
)

// PublicKeyAlgorithm is used to specify public key algorithm.
type PublicKeyAlgorithm int

// SignatureAlgorithm is used to specify signature key algorithm.
type SignatureAlgorithm int

// List of supported public key algorithms.
const (
UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
RSA
ECDSA
)

// List of supported signature hash algorithms.
// The naming convention adheres to x509.SignatureAlgorithm.
const (
UnknownSignatureAlgorithm SignatureAlgorithm = iota
SHA256WithRSA
ECDSAWithSHA256
ECDSAWithSHA384
SHA512WithRSA
SHAWithRSA // for backward compatibility
)

const (
// Default values for CAconfig.
defaultCounty = "ZZ" // Unknown or unspecified country
Expand Down
19 changes: 9 additions & 10 deletions pkcs11/algosigner.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@ package pkcs11

import (
"crypto"
"crypto/x509"
"errors"
"io"

"golang.org/x/crypto/ssh"

"github.com/theparanoids/crypki"
)

type sshAlgorithmSigner struct {
Expand All @@ -36,24 +35,24 @@ func (s *sshAlgorithmSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature,
return s.signer.SignWithAlgorithm(rand, data, s.algorithm)
}

func getSignatureAlgorithm(publicAlgo crypki.PublicKeyAlgorithm, signAlgo crypki.SignatureAlgorithm) (algorithm string, err error) {
func getSignatureAlgorithm(publicAlgo x509.PublicKeyAlgorithm, signAlgo x509.SignatureAlgorithm) (algorithm string, err error) {
switch publicAlgo {
case crypki.RSA:
case x509.RSA:
{
switch signAlgo {
case crypki.ECDSAWithSHA256, crypki.ECDSAWithSHA384:
case x509.ECDSAWithSHA256, x509.ECDSAWithSHA384:
err = errors.New("public key algo & signature algo mismatch, unable to get AlgorithmSigner")
case crypki.SHAWithRSA:
case x509.SHA1WithRSA:
algorithm = ssh.SigAlgoRSA
case crypki.SHA512WithRSA:
case x509.SHA512WithRSA:
algorithm = ssh.SigAlgoRSASHA2512
case crypki.SHA256WithRSA:
case x509.SHA256WithRSA:
algorithm = ssh.SigAlgoRSASHA2256
default:
algorithm = ssh.SigAlgoRSASHA2256
}
}
case crypki.ECDSA:
case x509.ECDSA:
// For ECDSA public algorithm, signature algo does not exist. We pass in
// empty algorithm & the crypto library will ensure the right algorithm is chosen
// for signing the cert.
Expand All @@ -64,7 +63,7 @@ func getSignatureAlgorithm(publicAlgo crypki.PublicKeyAlgorithm, signAlgo crypki
return
}

func newAlgorithmSignerFromSigner(signer crypto.Signer, publicAlgo crypki.PublicKeyAlgorithm, signAlgo crypki.SignatureAlgorithm) (ssh.Signer, error) {
func newAlgorithmSignerFromSigner(signer crypto.Signer, publicAlgo x509.PublicKeyAlgorithm, signAlgo x509.SignatureAlgorithm) (ssh.Signer, error) {
sshSigner, err := ssh.NewSignerFromSigner(signer)
if err != nil {
return nil, err
Expand Down
35 changes: 17 additions & 18 deletions pkcs11/algosigner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,60 +14,59 @@
package pkcs11

import (
"crypto/x509"
"testing"

"golang.org/x/crypto/ssh"

"github.com/theparanoids/crypki"
)

func TestGetSignatureAlgorithm(t *testing.T) {
t.Parallel()
tests := map[string]struct {
pubAlgo crypki.PublicKeyAlgorithm
signAlgo crypki.SignatureAlgorithm
pubAlgo x509.PublicKeyAlgorithm
signAlgo x509.SignatureAlgorithm
want string
wantError bool
}{
"rsa pub rsa 256 signing": {
pubAlgo: crypki.RSA,
signAlgo: crypki.SHA256WithRSA,
pubAlgo: x509.RSA,
signAlgo: x509.SHA256WithRSA,
want: ssh.SigAlgoRSASHA2256,
wantError: false,
},
"rsa pub rsa 512 signing": {
pubAlgo: crypki.RSA,
signAlgo: crypki.SHA512WithRSA,
pubAlgo: x509.RSA,
signAlgo: x509.SHA512WithRSA,
want: ssh.SigAlgoRSASHA2512,
wantError: false,
},
"rsa pub sha1 signing": {
pubAlgo: crypki.RSA,
signAlgo: crypki.SHAWithRSA,
pubAlgo: x509.RSA,
signAlgo: x509.SHA1WithRSA,
want: ssh.SigAlgoRSA,
wantError: false,
},
"rsa pub ec signing": {
pubAlgo: crypki.RSA,
signAlgo: crypki.ECDSAWithSHA384,
pubAlgo: x509.RSA,
signAlgo: x509.ECDSAWithSHA384,
want: "",
wantError: true,
},
"rsa pub no signing algo": {
pubAlgo: crypki.RSA,
signAlgo: crypki.UnknownSignatureAlgorithm,
pubAlgo: x509.RSA,
signAlgo: x509.UnknownSignatureAlgorithm,
want: ssh.SigAlgoRSASHA2256,
wantError: false,
},
"ec pub ec sign": {
pubAlgo: crypki.ECDSA,
signAlgo: crypki.ECDSAWithSHA384,
pubAlgo: x509.ECDSA,
signAlgo: x509.ECDSAWithSHA384,
want: "",
wantError: false,
},
"default pub key algo": {
pubAlgo: crypki.UnknownPublicKeyAlgorithm,
signAlgo: crypki.UnknownSignatureAlgorithm,
pubAlgo: x509.UnknownPublicKeyAlgorithm,
signAlgo: x509.UnknownSignatureAlgorithm,
want: "",
wantError: true,
},
Expand Down
4 changes: 2 additions & 2 deletions pkcs11/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func publicECDSA(s *p11Signer) crypto.PublicKey {
func signDataECDSA(ctx PKCS11Ctx, session p11.SessionHandle, hsmPrivateObject p11.ObjectHandle, data []byte, opts crypto.SignerOpts) ([]byte, error) {
const MAXBYTES = 262042
if len(data) > MAXBYTES {
return nil, errors.New("Cannot sign such a large blob of data")
return nil, errors.New("cannot sign such a large blob of data")
}

privateKeyHandle := hsmPrivateObject
Expand All @@ -112,7 +112,7 @@ func signDataECDSA(ctx PKCS11Ctx, session p11.SessionHandle, hsmPrivateObject p1
case crypto.SHA1, crypto.SHA256, crypto.SHA384, crypto.SHA512:
mech[0] = p11.NewMechanism(p11.CKM_ECDSA, nil)
default:
return nil, errors.New("Unsupported hash algorithm")
return nil, errors.New("unsupported hash algorithm")
}

err := ctx.SignInit(session, mech, privateKeyHandle)
Expand Down
21 changes: 10 additions & 11 deletions pkcs11/p11signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,24 @@ package pkcs11

import (
"crypto"
"crypto/x509"
"errors"
"fmt"
"io"

p11 "github.com/miekg/pkcs11"

"github.com/theparanoids/crypki"
)

type p11Signer struct {
context PKCS11Ctx
session p11.SessionHandle
privateKey p11.ObjectHandle
publicKey p11.ObjectHandle
keyType crypki.PublicKeyAlgorithm
signatureAlgo crypki.SignatureAlgorithm
keyType x509.PublicKeyAlgorithm
signatureAlgo x509.SignatureAlgorithm
}

func makeSigner(context PKCS11Ctx, slot uint, tokenLabel string, keyType crypki.PublicKeyAlgorithm, signatureAlgo crypki.SignatureAlgorithm) (*p11Signer, error) {
func makeSigner(context PKCS11Ctx, slot uint, tokenLabel string, keyType x509.PublicKeyAlgorithm, signatureAlgo x509.SignatureAlgorithm) (*p11Signer, error) {
session, err := context.OpenSession(slot, p11.CKF_SERIAL_SESSION)
if err != nil {
return nil, errors.New("makeSigner: error in OpenSession: " + err.Error())
Expand Down Expand Up @@ -56,9 +55,9 @@ func makeSigner(context PKCS11Ctx, slot uint, tokenLabel string, keyType crypki.
// Sign signs the data using PKCS11 library. It is part of the crypto.Signer interface.
func (s *p11Signer) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
switch s.keyType {
case crypki.RSA:
case x509.RSA:
return signDataRSA(s.context, s.session, s.privateKey, msg, opts)
case crypki.ECDSA:
case x509.ECDSA:
return signDataECDSA(s.context, s.session, s.privateKey, msg, opts)
default: // RSA is the default
return signDataRSA(s.context, s.session, s.privateKey, msg, opts)
Expand All @@ -69,21 +68,21 @@ func (s *p11Signer) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]
// Public returns crypto public key.
func (s *p11Signer) Public() crypto.PublicKey {
switch s.keyType {
case crypki.RSA:
case x509.RSA:
return publicRSA(s)
case crypki.ECDSA:
case x509.ECDSA:
return publicECDSA(s)
default: // RSA is the default
return publicRSA(s)
}
}

// publicKeyAlgorithm returns the public key algorithm of signer.
func (s *p11Signer) publicKeyAlgorithm() crypki.PublicKeyAlgorithm {
func (s *p11Signer) publicKeyAlgorithm() x509.PublicKeyAlgorithm {
return s.keyType
}

// signAlgorithm returns the signature algorithm of signer.
func (s *p11Signer) signAlgorithm() crypki.SignatureAlgorithm {
func (s *p11Signer) signAlgorithm() x509.SignatureAlgorithm {
return s.signatureAlgo
}
Loading

0 comments on commit a57e576

Please sign in to comment.