Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
p2p
go-p2p-tls
Commits
1aaea78d
Commit
1aaea78d
authored
Feb 21, 2019
by
Marten Seemann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
derive and save the server's pub key in tls.Config.VerifyPeerCertificate
parent
9ecd0944
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
29 additions
and
30 deletions
+29
-30
crypto.go
crypto.go
+5
-6
transport.go
transport.go
+24
-24
No files found.
crypto.go
View file @
1aaea78d
...
...
@@ -69,7 +69,10 @@ func NewIdentity(
// ConfigForPeer creates a new tls.Config that verifies the peers certificate chain.
// It should be used to create a new tls.Config before dialing.
func
(
i
*
Identity
)
ConfigForPeer
(
remote
peer
.
ID
)
*
tls
.
Config
{
func
(
i
*
Identity
)
ConfigForPeer
(
remote
peer
.
ID
,
verifiedPeerCallback
func
(
ic
.
PubKey
),
)
*
tls
.
Config
{
// We need to check the peer ID in the VerifyPeerCertificate callback.
// The tls.Config it is also used for listening, and we might also have concurrent dials.
// Clone it so we can check for the specific peer ID we're dialing here.
...
...
@@ -92,16 +95,12 @@ func (i *Identity) ConfigForPeer(remote peer.ID) *tls.Config {
if
!
remote
.
MatchesPublicKey
(
pubKey
)
{
return
errors
.
New
(
"peer IDs don't match"
)
}
verifiedPeerCallback
(
pubKey
)
return
nil
}
return
conf
}
// KeyFromChain takes a chain of x509.Certificates and returns the peer's public key.
func
KeyFromChain
(
chain
[]
*
x509
.
Certificate
)
(
ic
.
PubKey
,
error
)
{
return
getRemotePubKey
(
chain
)
}
// getRemotePubKey derives the remote's public key from the certificate chain.
func
getRemotePubKey
(
chain
[]
*
x509
.
Certificate
)
(
ic
.
PubKey
,
error
)
{
if
len
(
chain
)
!=
1
{
...
...
transport.go
View file @
1aaea78d
...
...
@@ -3,6 +3,7 @@ package libp2ptls
import
(
"context"
"crypto/tls"
"errors"
"net"
"os"
"sync"
...
...
@@ -29,8 +30,8 @@ type Transport struct {
localPeer
peer
.
ID
privKey
ci
.
PrivKey
incoming
Mutex
sync
.
Mutex
incoming
map
[
net
.
Conn
]
ic
.
PubKey
active
Mutex
sync
.
Mutex
active
map
[
net
.
Conn
]
ic
.
PubKey
}
// New creates a TLS encrypted transport
...
...
@@ -42,9 +43,14 @@ func New(key ci.PrivKey) (*Transport, error) {
t
:=
&
Transport
{
localPeer
:
id
,
privKey
:
key
,
incoming
:
make
(
map
[
net
.
Conn
]
ic
.
PubKey
),
active
:
make
(
map
[
net
.
Conn
]
ic
.
PubKey
),
}
identity
,
err
:=
NewIdentity
(
key
,
t
.
verifiedPeer
)
identity
,
err
:=
NewIdentity
(
key
,
func
(
conn
net
.
Conn
,
pubKey
ic
.
PubKey
)
{
t
.
activeMutex
.
Lock
()
t
.
active
[
conn
]
=
pubKey
t
.
activeMutex
.
Unlock
()
})
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -57,10 +63,10 @@ var _ cs.Transport = &Transport{}
// SecureInbound runs the TLS handshake as a server.
func
(
t
*
Transport
)
SecureInbound
(
ctx
context
.
Context
,
insecure
net
.
Conn
)
(
cs
.
Conn
,
error
)
{
defer
func
()
{
t
.
incoming
Mutex
.
Lock
()
t
.
active
Mutex
.
Lock
()
// only contains this connection if we successfully derived the client's key
delete
(
t
.
incoming
,
insecure
)
t
.
incoming
Mutex
.
Unlock
()
delete
(
t
.
active
,
insecure
)
t
.
active
Mutex
.
Unlock
()
}()
serv
:=
tls
.
Server
(
insecure
,
t
.
identity
.
Config
)
...
...
@@ -75,7 +81,12 @@ func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn) (cs.Co
// If the handshake fails, the server will close the connection. The client will
// notice this after 1 RTT when calling Read.
func
(
t
*
Transport
)
SecureOutbound
(
ctx
context
.
Context
,
insecure
net
.
Conn
,
p
peer
.
ID
)
(
cs
.
Conn
,
error
)
{
cl
:=
tls
.
Client
(
insecure
,
t
.
identity
.
ConfigForPeer
(
p
))
verifiedCallback
:=
func
(
pubKey
ic
.
PubKey
)
{
t
.
activeMutex
.
Lock
()
t
.
active
[
insecure
]
=
pubKey
t
.
activeMutex
.
Unlock
()
}
cl
:=
tls
.
Client
(
insecure
,
t
.
identity
.
ConfigForPeer
(
p
,
verifiedCallback
))
return
t
.
handshake
(
ctx
,
insecure
,
cl
)
}
...
...
@@ -120,26 +131,15 @@ func (t *Transport) handshake(
return
conn
,
nil
}
func
(
t
*
Transport
)
verifiedPeer
(
conn
net
.
Conn
,
pubKey
ic
.
PubKey
)
{
t
.
incomingMutex
.
Lock
()
t
.
incoming
[
conn
]
=
pubKey
t
.
incomingMutex
.
Unlock
()
}
func
(
t
*
Transport
)
setupConn
(
insecure
net
.
Conn
,
tlsConn
*
tls
.
Conn
)
(
cs
.
Conn
,
error
)
{
t
.
incoming
Mutex
.
Lock
()
remotePubKey
:=
t
.
incoming
[
insecure
]
t
.
incoming
Mutex
.
Unlock
()
t
.
active
Mutex
.
Lock
()
remotePubKey
:=
t
.
active
[
insecure
]
t
.
active
Mutex
.
Unlock
()
// This case only occurs for the client.
// Servers already determined the client's key in the VerifyPeerCertificate callback.
if
remotePubKey
==
nil
{
var
err
error
remotePubKey
,
err
=
KeyFromChain
(
tlsConn
.
ConnectionState
()
.
PeerCertificates
)
if
err
!=
nil
{
return
nil
,
err
}
return
nil
,
errors
.
New
(
"go-libp2p-tls BUG: expected remote pub key to be set"
)
}
remotePeerID
,
err
:=
peer
.
IDFromPublicKey
(
remotePubKey
)
if
err
!=
nil
{
return
nil
,
err
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment