Skip to content

Commit

Permalink
Merge pull request #9 from libp2p/ecdsa
Browse files Browse the repository at this point in the history
add support for ECDSA keys
  • Loading branch information
marten-seemann authored Jan 12, 2019
2 parents 21cff47 + 955b805 commit 936688b
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 12 deletions.
19 changes: 17 additions & 2 deletions p2p/security/tls/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"math/big"
"time"

Expand Down Expand Up @@ -93,7 +94,14 @@ func getRemotePubKey(chain []*x509.Certificate) (ic.PubKey, error) {
if err != nil {
return nil, err
}
return ic.UnmarshalRsaPublicKey(remotePubKey)
switch chain[0].PublicKeyAlgorithm {
case x509.RSA:
return ic.UnmarshalRsaPublicKey(remotePubKey)
case x509.ECDSA:
return ic.UnmarshalECDSAPublicKey(remotePubKey)
default:
return nil, fmt.Errorf("unexpected public key algorithm: %d", chain[0].PublicKeyAlgorithm)
}
}

func keyToCertificate(sk ic.PrivKey) (interface{}, *x509.Certificate, error) {
Expand Down Expand Up @@ -124,7 +132,14 @@ func keyToCertificate(sk ic.PrivKey) (interface{}, *x509.Certificate, error) {
}
publicKey = &k.PublicKey
privateKey = k
// TODO: add support for ECDSA
case pb.KeyType_ECDSA:
k, err := x509.ParseECPrivateKey(pbmes.GetData())
if err != nil {
return nil, nil, err
}
publicKey = &k.PublicKey
privateKey = k
// TODO: add support for Ed25519
default:
return nil, nil, errors.New("unsupported key type for TLS")
}
Expand Down
5 changes: 5 additions & 0 deletions p2p/security/tls/libp2p_tls_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package libp2ptls

import (
mrand "math/rand"
"testing"

. "github.com/onsi/ginkgo"
Expand All @@ -11,3 +12,7 @@ func TestLibp2pTLS(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "libp2p TLS Suite")
}

var _ = BeforeSuite(func() {
mrand.Seed(GinkgoRandomSeed())
})
49 changes: 39 additions & 10 deletions p2p/security/tls/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package libp2ptls

import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"fmt"
mrand "math/rand"
"net"

cs "github.com/libp2p/go-conn-security"
Expand All @@ -21,10 +24,18 @@ var _ = Describe("Transport", func() {
)

createPeer := func() (peer.ID, ic.PrivKey) {
key, err := rsa.GenerateKey(rand.Reader, 1024)
Expect(err).ToNot(HaveOccurred())
priv, err := ic.UnmarshalRsaPrivateKey(x509.MarshalPKCS1PrivateKey(key))
Expect(err).ToNot(HaveOccurred())
var priv ic.PrivKey
if mrand.Int()%2 == 0 {
fmt.Fprintln(GinkgoWriter, " using an ECDSA key")
var err error
priv, _, err = ic.GenerateECDSAKeyPair(rand.Reader)
Expect(err).ToNot(HaveOccurred())
} else {
fmt.Fprintln(GinkgoWriter, " using an RSA key")
var err error
priv, _, err = ic.GenerateRSAKeyPair(1024, rand.Reader)
Expect(err).ToNot(HaveOccurred())
}
id, err := peer.IDFromPrivateKey(priv)
Expect(err).ToNot(HaveOccurred())
return id, priv
Expand All @@ -48,13 +59,24 @@ var _ = Describe("Transport", func() {

// modify the cert chain such that verificiation will fail
invalidateCertChain := func(identity *Identity) {
key, err := rsa.GenerateKey(rand.Reader, 1024)
Expect(err).ToNot(HaveOccurred())
identity.Config.Certificates[0].PrivateKey = key
switch identity.Config.Certificates[0].PrivateKey.(type) {
case *rsa.PrivateKey:
key, err := rsa.GenerateKey(rand.Reader, 1024)
Expect(err).ToNot(HaveOccurred())
identity.Config.Certificates[0].PrivateKey = key
case *ecdsa.PrivateKey:
key, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
Expect(err).ToNot(HaveOccurred())
identity.Config.Certificates[0].PrivateKey = key
default:
Fail("unexpected private key type")
}
}

BeforeEach(func() {
fmt.Fprintf(GinkgoWriter, "Initializing a server")
serverID, serverKey = createPeer()
fmt.Fprintf(GinkgoWriter, "Initializing a client")
clientID, clientKey = createPeer()
})

Expand Down Expand Up @@ -135,6 +157,7 @@ var _ = Describe("Transport", func() {
})

It("fails if the peer ID doesn't match", func() {
fmt.Fprintf(GinkgoWriter, "Creating another peer")
thirdPartyID, _ := createPeer()

serverTransport, err := New(serverKey)
Expand Down Expand Up @@ -172,7 +195,10 @@ var _ = Describe("Transport", func() {
defer GinkgoRecover()
_, err := serverTransport.SecureInbound(context.Background(), serverInsecureConn)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("crypto/rsa: verification error"))
Expect(err.Error()).To(Or(
ContainSubstring("crypto/rsa: verification error"),
ContainSubstring("ECDSA verification failure"),
))
close(done)
}()

Expand Down Expand Up @@ -202,7 +228,10 @@ var _ = Describe("Transport", func() {

_, err = clientTransport.SecureOutbound(context.Background(), clientInsecureConn, serverID)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("crypto/rsa: verification error"))
Expect(err.Error()).To(Or(
ContainSubstring("crypto/rsa: verification error"),
ContainSubstring("ECDSA verification failure"),
))
Eventually(done).Should(BeClosed())
})
})

0 comments on commit 936688b

Please sign in to comment.