mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-26 00:11:36 +00:00
Use query string instead, allow specifying multiple keys (might be useful for DNS RR)
This commit is contained in:
parent
e849b3e119
commit
fbf59184ee
@ -70,7 +70,8 @@ type linkInterface struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type linkOptions struct {
|
type linkOptions struct {
|
||||||
pinningInfo *url.Userinfo
|
pinnedCurve25519Keys []crypto.BoxPubKey
|
||||||
|
pinnedEd25519Keys []crypto.SigPubKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *link) init(c *Core) error {
|
func (l *link) init(c *Core) error {
|
||||||
@ -99,8 +100,27 @@ func (l *link) call(uri string, sintf string) error {
|
|||||||
}
|
}
|
||||||
pathtokens := strings.Split(strings.Trim(u.Path, "/"), "/")
|
pathtokens := strings.Split(strings.Trim(u.Path, "/"), "/")
|
||||||
tcpOpts := tcpOptions{}
|
tcpOpts := tcpOptions{}
|
||||||
if u.User != nil {
|
if pubkeys, ok := u.Query()["curve25519"]; ok && len(pubkeys) > 0 {
|
||||||
tcpOpts.pinningInfo = u.User
|
for _, pubkey := range pubkeys {
|
||||||
|
if boxPub, err := hex.DecodeString(pubkey); err != nil {
|
||||||
|
var boxPubKey crypto.BoxPubKey
|
||||||
|
copy(boxPubKey[:], boxPub)
|
||||||
|
tcpOpts.pinnedCurve25519Keys = append(
|
||||||
|
tcpOpts.pinnedCurve25519Keys, boxPubKey,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pubkeys, ok := u.Query()["ed25519"]; ok && len(pubkeys) > 0 {
|
||||||
|
for _, pubkey := range pubkeys {
|
||||||
|
if sigPub, err := hex.DecodeString(pubkey); err != nil {
|
||||||
|
var sigPubKey crypto.SigPubKey
|
||||||
|
copy(sigPubKey[:], sigPub)
|
||||||
|
tcpOpts.pinnedEd25519Keys = append(
|
||||||
|
tcpOpts.pinnedEd25519Keys, sigPubKey,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
@ -196,32 +216,24 @@ func (intf *linkInterface) handler() error {
|
|||||||
}
|
}
|
||||||
// Check if the remote side matches the keys we expected. This is a bit of a weak
|
// Check if the remote side matches the keys we expected. This is a bit of a weak
|
||||||
// check - in future versions we really should check a signature or something like that.
|
// check - in future versions we really should check a signature or something like that.
|
||||||
if pinning := intf.options.pinningInfo; pinning != nil {
|
if pinned := intf.options.pinnedCurve25519Keys; len(pinned) > 0 {
|
||||||
allowed := true
|
allowed := false
|
||||||
keytype := pinning.Username()
|
for _, key := range pinned {
|
||||||
if pubkey, ok := pinning.Password(); ok {
|
allowed = allowed || (bytes.Compare(key[:], meta.box[:]) == 0)
|
||||||
switch keytype {
|
|
||||||
case "curve25519":
|
|
||||||
boxPub, err := hex.DecodeString(pubkey)
|
|
||||||
if err != nil || len(boxPub) != crypto.BoxPubKeyLen {
|
|
||||||
allowed = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
allowed = bytes.Compare(boxPub, meta.box[:]) == 0
|
|
||||||
case "ed25519":
|
|
||||||
sigPub, err := hex.DecodeString(pubkey)
|
|
||||||
if err != nil || len(sigPub) != crypto.SigPubKeyLen {
|
|
||||||
allowed = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
allowed = bytes.Compare(sigPub, meta.sig[:]) == 0
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
allowed = false
|
|
||||||
}
|
}
|
||||||
if !allowed {
|
if !allowed {
|
||||||
intf.link.core.log.Errorf("Failed to connect to node: %q sent key that does not match pinned %q key", intf.name, keytype)
|
intf.link.core.log.Errorf("Failed to connect to node: %q sent curve25519 key that does not match pinned keys", intf.name)
|
||||||
return fmt.Errorf("failed to connect: host does not match pinned %q key", pinning.Username())
|
return fmt.Errorf("failed to connect: host sent curve25519 key that does not match pinned keys")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pinned := intf.options.pinnedEd25519Keys; len(pinned) > 0 {
|
||||||
|
allowed := false
|
||||||
|
for _, key := range pinned {
|
||||||
|
allowed = allowed || (bytes.Compare(key[:], meta.sig[:]) == 0)
|
||||||
|
}
|
||||||
|
if !allowed {
|
||||||
|
intf.link.core.log.Errorf("Failed to connect to node: %q sent ed25519 key that does not match pinned keys", intf.name)
|
||||||
|
return fmt.Errorf("failed to connect: host sent ed25519 key that does not match pinned keys")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if we're authorized to connect to this key / IP
|
// Check if we're authorized to connect to this key / IP
|
||||||
|
Loading…
Reference in New Issue
Block a user