Skip to content

Commit

Permalink
[FAB-1648] PKCS11 BCCSP now calls PKCS11 functions
Browse files Browse the repository at this point in the history
For all ECDSA operations, replace current PKCS11 CSP software
calls with PKCS11 operations

Note: KeyImport and KeyDerivation should not be allowed by
a properly configured crypto card, but it does work with
SoftHSM and is legal PKCS11

Change-Id: I0087c86cda048bf5f8df965580bef8896984e897
Signed-off-by: Volodymyr Paprotski <[email protected]>
  • Loading branch information
Volodymyr Paprotski committed Jan 25, 2017
1 parent cafeaf1 commit fd0c5c4
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 181 deletions.
12 changes: 6 additions & 6 deletions bccsp/pkcs11/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ limitations under the License.
package pkcs11

import (
"crypto/elliptic"
"crypto/sha256"
"crypto/sha512"
"encoding/asn1"
"fmt"
"hash"

Expand All @@ -30,7 +30,7 @@ type config struct {
securityLevel int
hashFamily string

ellipticCurve elliptic.Curve
ellipticCurve asn1.ObjectIdentifier
hashFunction func() hash.Hash
aesBitLength int
rsaBitLength int
Expand All @@ -51,12 +51,12 @@ func (conf *config) setSecurityLevel(securityLevel int, hashFamily string) (err
func (conf *config) setSecurityLevelSHA2(level int) (err error) {
switch level {
case 256:
conf.ellipticCurve = elliptic.P256()
conf.ellipticCurve = oidNamedCurveP256
conf.hashFunction = sha256.New
conf.rsaBitLength = 2048
conf.aesBitLength = 32
case 384:
conf.ellipticCurve = elliptic.P384()
conf.ellipticCurve = oidNamedCurveP384
conf.hashFunction = sha512.New384
conf.rsaBitLength = 3072
conf.aesBitLength = 32
Expand All @@ -69,12 +69,12 @@ func (conf *config) setSecurityLevelSHA2(level int) (err error) {
func (conf *config) setSecurityLevelSHA3(level int) (err error) {
switch level {
case 256:
conf.ellipticCurve = elliptic.P256()
conf.ellipticCurve = oidNamedCurveP256
conf.hashFunction = sha3.New256
conf.rsaBitLength = 2048
conf.aesBitLength = 32
case 384:
conf.ellipticCurve = elliptic.P384()
conf.ellipticCurve = oidNamedCurveP384
conf.hashFunction = sha3.New384
conf.rsaBitLength = 3072
conf.aesBitLength = 32
Expand Down
20 changes: 9 additions & 11 deletions bccsp/pkcs11/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ limitations under the License.
package pkcs11

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/asn1"
"errors"
"fmt"
Expand Down Expand Up @@ -74,44 +72,44 @@ func unmarshalECDSASignature(raw []byte) (*big.Int, *big.Int, error) {
return sig.R, sig.S, nil
}

func (csp *impl) signECDSA(k *ecdsa.PrivateKey, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
r, s, err := ecdsa.Sign(rand.Reader, k, digest)
func (csp *impl) signECDSA(k ecdsaPrivateKey, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
r, s, err := signECDSA(k.ski, digest)
if err != nil {
return nil, err
}

// check for low-S
halfOrder, ok := curveHalfOrders[k.Curve]
halfOrder, ok := curveHalfOrders[k.pub.pub.Curve]
if !ok {
return nil, fmt.Errorf("Curve not recognized [%s]", k.Curve)
return nil, fmt.Errorf("Curve not recognized [%s]", k.pub.pub.Curve)
}

// is s > halfOrder Then
if s.Cmp(halfOrder) == 1 {
// Set s to N - s that will be then in the lower part of signature space
// less or equal to half order
s.Sub(k.Params().N, s)
s.Sub(k.pub.pub.Params().N, s)
}

return marshalECDSASignature(r, s)
}

func (csp *impl) verifyECDSA(k *ecdsa.PublicKey, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
func (csp *impl) verifyECDSA(k ecdsaPublicKey, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
r, s, err := unmarshalECDSASignature(signature)
if err != nil {
return false, fmt.Errorf("Failed unmashalling signature [%s]", err)
}

// check for low-S
halfOrder, ok := curveHalfOrders[k.Curve]
halfOrder, ok := curveHalfOrders[k.pub.Curve]
if !ok {
return false, fmt.Errorf("Curve not recognized [%s]", k.Curve)
return false, fmt.Errorf("Curve not recognized [%s]", k.pub.Curve)
}

// If s > halfOrder Then
if s.Cmp(halfOrder) == 1 {
return false, fmt.Errorf("Invalid S. Must be smaller than half the order [%s][%s].", s, halfOrder)
}

return ecdsa.Verify(k, digest, r, s), nil
return verifyECDSA(k.ski, digest, r, s)
}
41 changes: 9 additions & 32 deletions bccsp/pkcs11/ecdsakey.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,15 @@ package pkcs11
import (
"crypto/ecdsa"
"crypto/x509"
"fmt"

"crypto/sha256"

"errors"

"crypto/elliptic"
"fmt"

"github.com/hyperledger/fabric/bccsp"
)

type ecdsaPrivateKey struct {
privKey *ecdsa.PrivateKey
ski []byte
pub ecdsaPublicKey
}

// Bytes converts this key to its byte representation,
Expand All @@ -41,17 +37,7 @@ func (k *ecdsaPrivateKey) Bytes() (raw []byte, err error) {

// SKI returns the subject key identifier of this key.
func (k *ecdsaPrivateKey) SKI() (ski []byte) {
if k.privKey == nil {
return nil
}

// Marshall the public key
raw := elliptic.Marshal(k.privKey.Curve, k.privKey.PublicKey.X, k.privKey.PublicKey.Y)

// Hash it
hash := sha256.New()
hash.Write(raw)
return hash.Sum(nil)
return k.ski
}

// Symmetric returns true if this key is a symmetric key,
Expand All @@ -69,17 +55,18 @@ func (k *ecdsaPrivateKey) Private() bool {
// PublicKey returns the corresponding public key part of an asymmetric public/private key pair.
// This method returns an error in symmetric key schemes.
func (k *ecdsaPrivateKey) PublicKey() (bccsp.Key, error) {
return &ecdsaPublicKey{&k.privKey.PublicKey}, nil
return &k.pub, nil
}

type ecdsaPublicKey struct {
pubKey *ecdsa.PublicKey
ski []byte
pub *ecdsa.PublicKey
}

// Bytes converts this key to its byte representation,
// if this operation is allowed.
func (k *ecdsaPublicKey) Bytes() (raw []byte, err error) {
raw, err = x509.MarshalPKIXPublicKey(k.pubKey)
raw, err = x509.MarshalPKIXPublicKey(k.pub)
if err != nil {
return nil, fmt.Errorf("Failed marshalling key [%s]", err)
}
Expand All @@ -88,17 +75,7 @@ func (k *ecdsaPublicKey) Bytes() (raw []byte, err error) {

// SKI returns the subject key identifier of this key.
func (k *ecdsaPublicKey) SKI() (ski []byte) {
if k.pubKey == nil {
return nil
}

// Marshall the public key
raw := elliptic.Marshal(k.pubKey.Curve, k.pubKey.X, k.pubKey.Y)

// Hash it
hash := sha256.New()
hash.Write(raw)
return hash.Sum(nil)
return k.ski
}

// Symmetric returns true if this key is a symmetric key,
Expand Down
33 changes: 5 additions & 28 deletions bccsp/pkcs11/fileks.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,15 @@ limitations under the License.
package pkcs11

import (
"io/ioutil"
"os"
"sync"

"errors"
"strings"

"crypto/ecdsa"
"crypto/rsa"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"

"github.com/hyperledger/fabric/bccsp"
"github.com/hyperledger/fabric/bccsp/utils"
Expand Down Expand Up @@ -127,8 +124,6 @@ func (ks *FileBasedKeyStore) GetKey(ski []byte) (k bccsp.Key, err error) {
}

switch key.(type) {
case *ecdsa.PrivateKey:
return &ecdsaPrivateKey{key.(*ecdsa.PrivateKey)}, nil
case *rsa.PrivateKey:
return &rsaPrivateKey{key.(*rsa.PrivateKey)}, nil
default:
Expand All @@ -142,8 +137,6 @@ func (ks *FileBasedKeyStore) GetKey(ski []byte) (k bccsp.Key, err error) {
}

switch key.(type) {
case *ecdsa.PublicKey:
return &ecdsaPublicKey{key.(*ecdsa.PublicKey)}, nil
case *rsa.PublicKey:
return &rsaPublicKey{key.(*rsa.PublicKey)}, nil
default:
Expand All @@ -165,22 +158,6 @@ func (ks *FileBasedKeyStore) StoreKey(k bccsp.Key) (err error) {
return errors.New("Invalid key. It must be different from nil.")
}
switch k.(type) {
case *ecdsaPrivateKey:
kk := k.(*ecdsaPrivateKey)

err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey)
if err != nil {
return fmt.Errorf("Failed storing ECDSA private key [%s]", err)
}

case *ecdsaPublicKey:
kk := k.(*ecdsaPublicKey)

err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.pubKey)
if err != nil {
return fmt.Errorf("Failed storing ECDSA public key [%s]", err)
}

case *rsaPrivateKey:
kk := k.(*rsaPrivateKey)

Expand Down
10 changes: 0 additions & 10 deletions bccsp/pkcs11/fileks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@ func TestInvalidStoreKey(t *testing.T) {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&ecdsaPrivateKey{nil})
if err == nil {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&ecdsaPublicKey{nil})
if err == nil {
t.Fatal("Error should be different from nil in this case")
}

err = ks.StoreKey(&rsaPublicKey{nil})
if err == nil {
t.Fatal("Error should be different from nil in this case")
Expand Down
Loading

0 comments on commit fd0c5c4

Please sign in to comment.