mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-22 15:20:30 +00:00
Merge pull request #652 from yggdrasil-network/neilalexander/api
Use public keys in API functions
This commit is contained in:
commit
0b26551f07
@ -194,6 +194,16 @@ type BoxSharedKey [BoxSharedKeyLen]byte
|
|||||||
// BoxNonce is the nonce used in NaCl-like crypto "box" operations (curve25519+xsalsa20+poly1305), and must not be reused for different messages encrypted using the same BoxSharedKey.
|
// BoxNonce is the nonce used in NaCl-like crypto "box" operations (curve25519+xsalsa20+poly1305), and must not be reused for different messages encrypted using the same BoxSharedKey.
|
||||||
type BoxNonce [BoxNonceLen]byte
|
type BoxNonce [BoxNonceLen]byte
|
||||||
|
|
||||||
|
// String returns a string representation of the "box" key.
|
||||||
|
func (k BoxPubKey) String() string {
|
||||||
|
return hex.EncodeToString(k[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Network returns "curve25519" for "box" keys.
|
||||||
|
func (n BoxPubKey) Network() string {
|
||||||
|
return "curve25519"
|
||||||
|
}
|
||||||
|
|
||||||
// NewBoxKeys generates a new pair of public/private crypto box keys.
|
// NewBoxKeys generates a new pair of public/private crypto box keys.
|
||||||
func NewBoxKeys() (*BoxPubKey, *BoxPrivKey) {
|
func NewBoxKeys() (*BoxPubKey, *BoxPrivKey) {
|
||||||
pubBytes, privBytes, err := box.GenerateKey(rand.Reader)
|
pubBytes, privBytes, err := box.GenerateKey(rand.Reader)
|
||||||
|
@ -92,8 +92,7 @@ func (s *tunConn) _read(bs []byte) (err error) {
|
|||||||
// The destination address isn't in our CKR allowed range
|
// The destination address isn't in our CKR allowed range
|
||||||
skip = true
|
skip = true
|
||||||
} else if key, err := s.tun.ckr.getPublicKeyForAddress(srcAddr, addrlen); err == nil {
|
} else if key, err := s.tun.ckr.getPublicKeyForAddress(srcAddr, addrlen); err == nil {
|
||||||
srcNodeID := crypto.GetNodeID(&key)
|
if *s.conn.RemoteAddr().(*crypto.BoxPubKey) == key {
|
||||||
if *s.conn.RemoteAddr().(*crypto.NodeID) == *srcNodeID {
|
|
||||||
// This is the one allowed CKR case, where source and destination addresses are both good
|
// This is the one allowed CKR case, where source and destination addresses are both good
|
||||||
} else {
|
} else {
|
||||||
// The CKR key associated with this address doesn't match the sender's NodeID
|
// The CKR key associated with this address doesn't match the sender's NodeID
|
||||||
@ -169,8 +168,7 @@ func (s *tunConn) _write(bs []byte) (err error) {
|
|||||||
// The source address isn't in our CKR allowed range
|
// The source address isn't in our CKR allowed range
|
||||||
skip = true
|
skip = true
|
||||||
} else if key, err := s.tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
|
} else if key, err := s.tun.ckr.getPublicKeyForAddress(dstAddr, addrlen); err == nil {
|
||||||
dstNodeID := crypto.GetNodeID(&key)
|
if *s.conn.RemoteAddr().(*crypto.BoxPubKey) == key {
|
||||||
if *s.conn.RemoteAddr().(*crypto.NodeID) == *dstNodeID {
|
|
||||||
// This is the one allowed CKR case, where source and destination addresses are both good
|
// This is the one allowed CKR case, where source and destination addresses are both good
|
||||||
} else {
|
} else {
|
||||||
// The CKR key associated with this address doesn't match the sender's NodeID
|
// The CKR key associated with this address doesn't match the sender's NodeID
|
||||||
|
@ -251,7 +251,8 @@ func (tun *TunAdapter) _wrap(conn *yggdrasil.Conn) (c *tunConn, err error) {
|
|||||||
}
|
}
|
||||||
c = &s
|
c = &s
|
||||||
// Get the remote address and subnet of the other side
|
// Get the remote address and subnet of the other side
|
||||||
remoteNodeID := conn.RemoteAddr().(*crypto.NodeID)
|
remotePubKey := conn.RemoteAddr().(*crypto.BoxPubKey)
|
||||||
|
remoteNodeID := crypto.GetNodeID(remotePubKey)
|
||||||
s.addr = *address.AddrForNodeID(remoteNodeID)
|
s.addr = *address.AddrForNodeID(remoteNodeID)
|
||||||
s.snet = *address.SubnetForNodeID(remoteNodeID)
|
s.snet = *address.SubnetForNodeID(remoteNodeID)
|
||||||
// Work out if this is already a destination we already know about
|
// Work out if this is already a destination we already know about
|
||||||
|
@ -350,16 +350,19 @@ func (c *Conn) Close() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocalAddr returns the complete node ID of the local side of the connection.
|
// LocalAddr returns the complete public key of the local side of the
|
||||||
// This is always going to return your own node's node ID.
|
// connection. This is always going to return your own node's public key.
|
||||||
func (c *Conn) LocalAddr() net.Addr {
|
func (c *Conn) LocalAddr() net.Addr {
|
||||||
return crypto.GetNodeID(&c.core.boxPub)
|
return &c.core.boxPub
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteAddr returns the complete node ID of the remote side of the connection.
|
// RemoteAddr returns the complete public key of the remote side of the
|
||||||
|
// connection.
|
||||||
func (c *Conn) RemoteAddr() net.Addr {
|
func (c *Conn) RemoteAddr() net.Addr {
|
||||||
// RemoteAddr is set during the dial or accept, and isn't changed, so it's safe to access directly
|
if c.session != nil {
|
||||||
return c.nodeID
|
return &c.session.theirPermPub
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDeadline is equivalent to calling both SetReadDeadline and
|
// SetDeadline is equivalent to calling both SetReadDeadline and
|
||||||
|
@ -17,19 +17,32 @@ type Dialer struct {
|
|||||||
core *Core
|
core *Core
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dial opens a session to the given node. The first parameter should be "nodeid"
|
// Dial opens a session to the given node. The first parameter should be
|
||||||
// and the second parameter should contain a hexadecimal representation of the
|
// "curve25519" or "nodeid" and the second parameter should contain a
|
||||||
// target node ID. It uses DialContext internally.
|
// hexadecimal representation of the target. It uses DialContext internally.
|
||||||
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
|
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
|
||||||
return d.DialContext(nil, network, address)
|
return d.DialContext(nil, network, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialContext is used internally by Dial, and should only be used with a context that includes a timeout. It uses DialByNodeIDandMask internally.
|
// DialContext is used internally by Dial, and should only be used with a
|
||||||
|
// context that includes a timeout. It uses DialByNodeIDandMask internally when
|
||||||
|
// the network is "nodeid", or DialByPublicKey when the network is "curve25519".
|
||||||
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
var nodeID crypto.NodeID
|
var nodeID crypto.NodeID
|
||||||
var nodeMask crypto.NodeID
|
var nodeMask crypto.NodeID
|
||||||
// Process
|
// Process
|
||||||
switch network {
|
switch network {
|
||||||
|
case "curve25519":
|
||||||
|
dest, err := hex.DecodeString(address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(dest) != crypto.BoxPubKeyLen {
|
||||||
|
return nil, errors.New("invalid key length supplied")
|
||||||
|
}
|
||||||
|
var pubKey crypto.BoxPubKey
|
||||||
|
copy(pubKey[:], dest)
|
||||||
|
return d.DialByPublicKey(ctx, &pubKey)
|
||||||
case "nodeid":
|
case "nodeid":
|
||||||
// A node ID was provided - we don't need to do anything special with it
|
// A node ID was provided - we don't need to do anything special with it
|
||||||
if tokens := strings.Split(address, "/"); len(tokens) == 2 {
|
if tokens := strings.Split(address, "/"); len(tokens) == 2 {
|
||||||
@ -62,8 +75,9 @@ func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialByNodeIDandMask opens a session to the given node based on raw
|
// DialByNodeIDandMask opens a session to the given node based on raw NodeID
|
||||||
// NodeID parameters. If ctx is nil or has no timeout, then a default timeout of 6 seconds will apply, beginning *after* the search finishes.
|
// parameters. If ctx is nil or has no timeout, then a default timeout of 6
|
||||||
|
// seconds will apply, beginning *after* the search finishes.
|
||||||
func (d *Dialer) DialByNodeIDandMask(ctx context.Context, nodeID, nodeMask *crypto.NodeID) (net.Conn, error) {
|
func (d *Dialer) DialByNodeIDandMask(ctx context.Context, nodeID, nodeMask *crypto.NodeID) (net.Conn, error) {
|
||||||
startDial := time.Now()
|
startDial := time.Now()
|
||||||
conn := newConn(d.core, nodeID, nodeMask, nil)
|
conn := newConn(d.core, nodeID, nodeMask, nil)
|
||||||
@ -92,3 +106,15 @@ func (d *Dialer) DialByNodeIDandMask(ctx context.Context, nodeID, nodeMask *cryp
|
|||||||
return nil, errors.New("session handshake timeout")
|
return nil, errors.New("session handshake timeout")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DialByPublicKey opens a session to the given node based on the public key. If
|
||||||
|
// ctx is nil or has no timeout, then a default timeout of 6 seconds will apply,
|
||||||
|
// beginning *after* the search finishes.
|
||||||
|
func (d *Dialer) DialByPublicKey(ctx context.Context, pubKey *crypto.BoxPubKey) (net.Conn, error) {
|
||||||
|
nodeID := crypto.GetNodeID(pubKey)
|
||||||
|
var nodeMask crypto.NodeID
|
||||||
|
for i := range nodeMask {
|
||||||
|
nodeMask[i] = 0xFF
|
||||||
|
}
|
||||||
|
return d.DialByNodeIDandMask(ctx, nodeID, &nodeMask)
|
||||||
|
}
|
||||||
|
@ -113,9 +113,9 @@ a Dialer:
|
|||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
You can then dial using the 16-byte node ID in hexadecimal format, for example:
|
You can then dial using the node's public key in hexadecimal format, for example:
|
||||||
|
|
||||||
conn, err := dialer.Dial("nodeid", "24a58cfce691ec016b0f698f7be1bee983cea263781017e99ad3ef62b4ef710a45d6c1a072c5ce46131bd574b78818c9957042cafeeed13966f349e94eb771bf")
|
conn, err := dialer.Dial("curve25519", "55071be281f50d0abbda63aadc59755624280c44b2f1f47684317aa4e0325604")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ func (l *Listener) Close() (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addr is not implemented for this type yet
|
// Addr returns the address of the listener
|
||||||
func (l *Listener) Addr() net.Addr {
|
func (l *Listener) Addr() net.Addr {
|
||||||
return nil
|
return &l.core.boxPub
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user