mirror of https://github.com/libp2p/go-libp2p.git
Marten Seemann
5 years ago
6 changed files with 57 additions and 219 deletions
@ -1,123 +0,0 @@ |
|||
package libp2pquic |
|||
|
|||
import ( |
|||
"crypto/ecdsa" |
|||
"crypto/elliptic" |
|||
"crypto/rand" |
|||
"crypto/tls" |
|||
"crypto/x509" |
|||
"errors" |
|||
"math/big" |
|||
"time" |
|||
|
|||
"github.com/gogo/protobuf/proto" |
|||
ic "github.com/libp2p/go-libp2p-core/crypto" |
|||
pb "github.com/libp2p/go-libp2p-core/crypto/pb" |
|||
) |
|||
|
|||
// mint certificate selection is broken.
|
|||
const hostname = "quic.ipfs" |
|||
|
|||
const alpn string = "libp2p" |
|||
|
|||
const certValidityPeriod = 180 * 24 * time.Hour |
|||
|
|||
func generateConfig(privKey ic.PrivKey) (*tls.Config, error) { |
|||
key, hostCert, err := keyToCertificate(privKey) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
// The ephemeral key used just for a couple of connections (or a limited time).
|
|||
ephemeralKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
// Sign the ephemeral key using the host key.
|
|||
// This is the only time that the host's private key of the peer is needed.
|
|||
// Note that this step could be done asynchronously, such that a running node doesn't need access its private key at all.
|
|||
certTemplate := &x509.Certificate{ |
|||
DNSNames: []string{hostname}, |
|||
SerialNumber: big.NewInt(1), |
|||
NotBefore: time.Now().Add(-24 * time.Hour), |
|||
NotAfter: time.Now().Add(certValidityPeriod), |
|||
} |
|||
certDER, err := x509.CreateCertificate(rand.Reader, certTemplate, hostCert, ephemeralKey.Public(), key) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
cert, err := x509.ParseCertificate(certDER) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
return &tls.Config{ |
|||
ServerName: hostname, |
|||
InsecureSkipVerify: true, // This is not insecure here. We will verify the cert chain ourselves.
|
|||
ClientAuth: tls.RequireAnyClientCert, |
|||
Certificates: []tls.Certificate{{ |
|||
Certificate: [][]byte{cert.Raw, hostCert.Raw}, |
|||
PrivateKey: ephemeralKey, |
|||
}}, |
|||
NextProtos: []string{alpn}, |
|||
}, nil |
|||
} |
|||
|
|||
func getRemotePubKey(chain []*x509.Certificate) (ic.PubKey, error) { |
|||
if len(chain) != 2 { |
|||
return nil, errors.New("expected 2 certificates in the chain") |
|||
} |
|||
pool := x509.NewCertPool() |
|||
pool.AddCert(chain[1]) |
|||
if _, err := chain[0].Verify(x509.VerifyOptions{Roots: pool}); err != nil { |
|||
return nil, err |
|||
} |
|||
remotePubKey, err := x509.MarshalPKIXPublicKey(chain[1].PublicKey) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
return ic.UnmarshalRsaPublicKey(remotePubKey) |
|||
} |
|||
|
|||
func keyToCertificate(sk ic.PrivKey) (interface{}, *x509.Certificate, error) { |
|||
sn, err := rand.Int(rand.Reader, big.NewInt(1<<62)) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
tmpl := &x509.Certificate{ |
|||
SerialNumber: sn, |
|||
NotBefore: time.Now().Add(-24 * time.Hour), |
|||
NotAfter: time.Now().Add(certValidityPeriod), |
|||
IsCA: true, |
|||
BasicConstraintsValid: true, |
|||
} |
|||
|
|||
var publicKey, privateKey interface{} |
|||
keyBytes, err := sk.Bytes() |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
pbmes := new(pb.PrivateKey) |
|||
if err := proto.Unmarshal(keyBytes, pbmes); err != nil { |
|||
return nil, nil, err |
|||
} |
|||
switch pbmes.GetType() { |
|||
case pb.KeyType_RSA: |
|||
k, err := x509.ParsePKCS1PrivateKey(pbmes.GetData()) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
publicKey = &k.PublicKey |
|||
privateKey = k |
|||
// TODO: add support for ECDSA
|
|||
default: |
|||
return nil, nil, errors.New("unsupported key type for TLS") |
|||
} |
|||
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, publicKey, privateKey) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
cert, err := x509.ParseCertificate(certDER) |
|||
if err != nil { |
|||
return nil, nil, err |
|||
} |
|||
return privateKey, cert, nil |
|||
} |
Loading…
Reference in new issue