Skip to content

Commit

Permalink
Support ed25519 signature algorithm
Browse files Browse the repository at this point in the history
Considering the efforts to give ed25519 support
in fabric and fabric-gateway, this commit intends
to provide ed25519 support for fabric-ca.

With these efforts, cryptogen can generate ed25519
keys for the CA, motivating these changes to keep
compatibility in terms of crypto support.

Fabric main branch current version (3.0.0) does not
support RSA anymore. For that reason, I had to manually
merge the ed25519 pull request
(hyperledger/fabric#3343)
with fabric v1.4.11. The adapated version replaces
fabric v1.4.11 in 'go.mod'.

Signed-off-by: Johann Westphall <johannwestphall@gmail.com>
  • Loading branch information
johannww committed Nov 30, 2022
1 parent ee69f51 commit 20728c5
Show file tree
Hide file tree
Showing 19 changed files with 1,575 additions and 64 deletions.
1 change: 1 addition & 0 deletions cmd/fabric-ca-server/bad.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
signing: true
510 changes: 510 additions & 0 deletions cmd/fabric-ca-server/config.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEICDfhemqJ348UZHCVYvCYf1m8jcS3WtIyUywWM/3ipRg
-----END PRIVATE KEY-----
510 changes: 510 additions & 0 deletions cmd/fabric-ca-server/s.yaml

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ module github.com/hyperledger/fabric-ca

go 1.17

//replace github.com/hyperledger/fabric => github.com/johannww/fabric-1 v1.4.11

replace github.com/hyperledger/fabric v1.4.11 => github.com/johannww/fabric-1 v0.0.0-20221130143147-4c6de157c5c4

require (
github.com/IBM/idemix v0.0.0-20220113150823-80dd4cb2d74e
github.com/IBM/mathlib v0.0.0-20220414125002-6f78dce8f91c
Expand Down Expand Up @@ -37,7 +41,6 @@ require (
)

require (
github.com/VividCortex/gohistogram v1.0.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/consensys/gnark-crypto v0.6.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down Expand Up @@ -73,7 +76,6 @@ require (
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect
golang.org/x/text v0.3.3 // indirect
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 // indirect
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
google.golang.org/grpc v1.31.0 // indirect
google.golang.org/protobuf v1.23.0 // indirect
Expand All @@ -83,3 +85,5 @@ require (
gopkg.in/yaml.v2 v2.3.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)

//replace github.com/hyperledger/fabric => /home/johann/doutorado/prj/fabric
135 changes: 125 additions & 10 deletions go.sum

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions lib/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"bytes"
"crypto/dsa"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
Expand Down Expand Up @@ -1180,6 +1181,16 @@ func validateMatchingKeys(cert *x509.Certificate, keyFile string) error {
if privKey.PublicKey.X.Cmp(pubKey.X) != 0 {
return errors.New("Public key and private key do not match")
}
case ed25519.PublicKey:
privKey, err := util.GetEd25519PrivateKey(keyPEM)
if err != nil {
return err
}

publicFromPriv := privKey.Public().(ed25519.PublicKey)
if !publicFromPriv.Equal(pubKey) {
return errors.New("Public key and private key do not match")
}
}

return nil
Expand Down
13 changes: 13 additions & 0 deletions util/csp.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package util
import (
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
Expand Down Expand Up @@ -136,6 +137,8 @@ func getBCCSPKeyOpts(kr *csr.KeyRequest, ephemeral bool) (opts bccsp.KeyGenOpts,
default:
return nil, errors.Errorf("Invalid ECDSA key size: %d", kr.Size())
}
case "ed25519":
return &bccsp.ED25519KeyGenOpts{Temporary: ephemeral}, nil
default:
return nil, errors.Errorf("Invalid algorithm: %s", kr.Algo())
}
Expand Down Expand Up @@ -229,6 +232,16 @@ func ImportBCCSPKeyFromPEM(keyFile string, myCSP bccsp.BCCSP, temporary bool) (b
return sk, nil
case *rsa.PrivateKey:
return nil, errors.Errorf("Failed to import RSA key from %s; RSA private key import is not supported", keyFile)
case ed25519.PrivateKey:
priv, err := utils.PrivateKeyToDER(&key)
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("Failed to convert Ed25519 private key for '%s'", keyFile))
}
sk, err := myCSP.KeyImport(priv, &bccsp.ED25519PrivateKeyImportOpts{Temporary: temporary})
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("Failed to import Ed25519 private key for '%s'", keyFile))
}
return sk, nil
default:
return nil, errors.Errorf("Failed to import key from %s: invalid secret key type", keyFile)
}
Expand Down
26 changes: 26 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package util
import (
"bytes"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
Expand Down Expand Up @@ -289,6 +290,8 @@ func GetECPrivateKey(raw []byte) (*ecdsa.PrivateKey, error) {
return key, nil
case *rsa.PrivateKey:
return nil, errors.New("Expecting EC private key but found RSA private key")
case ed25519.PrivateKey:
return nil, errors.New("Expecting EC private key but found Ed25519 private key")
default:
return nil, errors.New("Invalid private key type in PKCS#8 wrapping")
}
Expand All @@ -313,13 +316,36 @@ func GetRSAPrivateKey(raw []byte) (*rsa.PrivateKey, error) {
return nil, errors.New("Expecting RSA private key but found EC private key")
case *rsa.PrivateKey:
return key, nil
case ed25519.PrivateKey:
return nil, errors.New("Expecting RSA private key but found Ed25519 private key")
default:
return nil, errors.New("Invalid private key type in PKCS#8 wrapping")
}
}
return nil, errors.Wrap(err, "Failed parsing RSA private key")
}

func GetEd25519PrivateKey(raw []byte) (ed25519.PrivateKey, error) {
decoded, _ := pem.Decode(raw)
if decoded == nil {
return nil, errors.New("Failed to decode the PEM-encoded ECDSA key")
}
key, err2 := x509.ParsePKCS8PrivateKey(decoded.Bytes)
if err2 == nil {
switch key := key.(type) {
case ed25519.PrivateKey:
return key, nil
case *ecdsa.PrivateKey:
return nil, errors.New("Expecting Ed25519 private key but found EC private key")
case *rsa.PrivateKey:
return nil, errors.New("Expecting Ed25519 private key but found RSA private key")
default:
return nil, errors.New("Invalid private key type in PKCS#8 wrapping")
}
}
return nil, errors.Wrap(err2, "Failed parsing EC private key")
}

// B64Encode base64 encodes bytes
func B64Encode(buf []byte) string {
return base64.StdEncoding.EncodeToString(buf)
Expand Down
49 changes: 49 additions & 0 deletions vendor/github.com/hyperledger/fabric/bccsp/opts.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions vendor/github.com/hyperledger/fabric/bccsp/signer/signer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions vendor/github.com/hyperledger/fabric/bccsp/sw/ed25519.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

109 changes: 109 additions & 0 deletions vendor/github.com/hyperledger/fabric/bccsp/sw/ed25519key.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 20728c5

Please sign in to comment.