mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 11:15:07 +03:00 
			
		
		
		
	Use query string instead, allow specifying multiple keys (might be useful for DNS RR)
This commit is contained in:
		
							parent
							
								
									e849b3e119
								
							
						
					
					
						commit
						fbf59184ee
					
				
					 1 changed files with 39 additions and 27 deletions
				
			
		| 
						 | 
					@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue