Commit 66fbf89d authored by Marten Seemann's avatar Marten Seemann

add support for ECDSA keys

parent a1e7e95d
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"errors" "errors"
"fmt"
"math/big" "math/big"
"time" "time"
...@@ -93,7 +94,14 @@ func getRemotePubKey(chain []*x509.Certificate) (ic.PubKey, error) { ...@@ -93,7 +94,14 @@ func getRemotePubKey(chain []*x509.Certificate) (ic.PubKey, error) {
if err != nil { if err != nil {
return nil, err 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) { func keyToCertificate(sk ic.PrivKey) (interface{}, *x509.Certificate, error) {
...@@ -124,7 +132,14 @@ func keyToCertificate(sk ic.PrivKey) (interface{}, *x509.Certificate, error) { ...@@ -124,7 +132,14 @@ func keyToCertificate(sk ic.PrivKey) (interface{}, *x509.Certificate, error) {
} }
publicKey = &k.PublicKey publicKey = &k.PublicKey
privateKey = k 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: default:
return nil, nil, errors.New("unsupported key type for TLS") return nil, nil, errors.New("unsupported key type for TLS")
} }
......
package libp2ptls package libp2ptls
import ( import (
mrand "math/rand"
"testing" "testing"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
...@@ -11,3 +12,7 @@ func TestLibp2pTLS(t *testing.T) { ...@@ -11,3 +12,7 @@ func TestLibp2pTLS(t *testing.T) {
RegisterFailHandler(Fail) RegisterFailHandler(Fail)
RunSpecs(t, "libp2p TLS Suite") RunSpecs(t, "libp2p TLS Suite")
} }
var _ = BeforeSuite(func() {
mrand.Seed(GinkgoRandomSeed())
})
...@@ -2,9 +2,12 @@ package libp2ptls ...@@ -2,9 +2,12 @@ package libp2ptls
import ( import (
"context" "context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/x509" "fmt"
mrand "math/rand"
"net" "net"
cs "github.com/libp2p/go-conn-security" cs "github.com/libp2p/go-conn-security"
...@@ -21,10 +24,18 @@ var _ = Describe("Transport", func() { ...@@ -21,10 +24,18 @@ var _ = Describe("Transport", func() {
) )
createPeer := func() (peer.ID, ic.PrivKey) { createPeer := func() (peer.ID, ic.PrivKey) {
key, err := rsa.GenerateKey(rand.Reader, 1024) var priv ic.PrivKey
Expect(err).ToNot(HaveOccurred()) if mrand.Int()%2 == 0 {
priv, err := ic.UnmarshalRsaPrivateKey(x509.MarshalPKCS1PrivateKey(key)) fmt.Fprintln(GinkgoWriter, " using an ECDSA key")
Expect(err).ToNot(HaveOccurred()) 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) id, err := peer.IDFromPrivateKey(priv)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
return id, priv return id, priv
...@@ -48,13 +59,24 @@ var _ = Describe("Transport", func() { ...@@ -48,13 +59,24 @@ var _ = Describe("Transport", func() {
// modify the cert chain such that verificiation will fail // modify the cert chain such that verificiation will fail
invalidateCertChain := func(identity *Identity) { invalidateCertChain := func(identity *Identity) {
key, err := rsa.GenerateKey(rand.Reader, 1024) switch identity.Config.Certificates[0].PrivateKey.(type) {
Expect(err).ToNot(HaveOccurred()) case *rsa.PrivateKey:
identity.Config.Certificates[0].PrivateKey = key 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() { BeforeEach(func() {
fmt.Fprintf(GinkgoWriter, "Initializing a server")
serverID, serverKey = createPeer() serverID, serverKey = createPeer()
fmt.Fprintf(GinkgoWriter, "Initializing a client")
clientID, clientKey = createPeer() clientID, clientKey = createPeer()
}) })
...@@ -135,6 +157,7 @@ var _ = Describe("Transport", func() { ...@@ -135,6 +157,7 @@ var _ = Describe("Transport", func() {
}) })
It("fails if the peer ID doesn't match", func() { It("fails if the peer ID doesn't match", func() {
fmt.Fprintf(GinkgoWriter, "Creating another peer")
thirdPartyID, _ := createPeer() thirdPartyID, _ := createPeer()
serverTransport, err := New(serverKey) serverTransport, err := New(serverKey)
...@@ -172,7 +195,10 @@ var _ = Describe("Transport", func() { ...@@ -172,7 +195,10 @@ var _ = Describe("Transport", func() {
defer GinkgoRecover() defer GinkgoRecover()
_, err := serverTransport.SecureInbound(context.Background(), serverInsecureConn) _, err := serverTransport.SecureInbound(context.Background(), serverInsecureConn)
Expect(err).To(HaveOccurred()) 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) close(done)
}() }()
...@@ -202,7 +228,10 @@ var _ = Describe("Transport", func() { ...@@ -202,7 +228,10 @@ var _ = Describe("Transport", func() {
_, err = clientTransport.SecureOutbound(context.Background(), clientInsecureConn, serverID) _, err = clientTransport.SecureOutbound(context.Background(), clientInsecureConn, serverID)
Expect(err).To(HaveOccurred()) 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()) Eventually(done).Should(BeClosed())
}) })
}) })
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment