add support for ECDSA keys

This commit is contained in:
Marten Seemann 2019-01-11 13:51:35 +07:00
parent 21cff4764f
commit 955b8056cb
3 changed files with 61 additions and 12 deletions

View File

@ -5,6 +5,7 @@ import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"math/big"
"time"
@ -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) {
@ -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")
}

View File

@ -1,6 +1,7 @@
package libp2ptls
import (
mrand "math/rand"
"testing"
. "github.com/onsi/ginkgo"
@ -11,3 +12,7 @@ func TestLibp2pTLS(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "libp2p TLS Suite")
}
var _ = BeforeSuite(func() {
mrand.Seed(GinkgoRandomSeed())
})

View File

@ -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"
@ -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
@ -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()
})
@ -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)
@ -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)
}()
@ -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())
})
})