mirror of
https://github.com/Egida/EndGame0.git
synced 2025-08-06 21:34:26 -04:00
113 lines
3.3 KiB
Go
113 lines
3.3 KiB
Go
package onionbalance
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/binary"
|
|
"errors"
|
|
"github.com/sirupsen/logrus"
|
|
"golang.org/x/crypto/sha3"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type TorNode struct {
|
|
microdescriptor MicroDescriptor
|
|
microdescriptorMtx sync.RWMutex
|
|
routerstatus *RouterStatus
|
|
routerstatusMtx sync.RWMutex
|
|
}
|
|
|
|
func NewNode(microdescriptor MicroDescriptor, routerstatus *RouterStatus) *TorNode {
|
|
logrus.Debugf("Initializing node with fpr %s", routerstatus.Fingerprint)
|
|
|
|
n := &TorNode{}
|
|
n.setMicrodescriptor(microdescriptor)
|
|
n.setRouterstatus(routerstatus)
|
|
return n
|
|
}
|
|
|
|
func (n *TorNode) getRouterstatus() *RouterStatus {
|
|
n.routerstatusMtx.RLock()
|
|
defer n.routerstatusMtx.RUnlock()
|
|
return n.routerstatus
|
|
}
|
|
|
|
func (n *TorNode) setRouterstatus(newVal *RouterStatus) {
|
|
n.routerstatusMtx.Lock()
|
|
defer n.routerstatusMtx.Unlock()
|
|
n.routerstatus = newVal
|
|
}
|
|
|
|
func (n *TorNode) getMicrodescriptor() MicroDescriptor {
|
|
n.microdescriptorMtx.RLock()
|
|
defer n.microdescriptorMtx.RUnlock()
|
|
return n.microdescriptor
|
|
}
|
|
|
|
func (n *TorNode) setMicrodescriptor(newVal MicroDescriptor) {
|
|
n.microdescriptorMtx.Lock()
|
|
defer n.microdescriptorMtx.Unlock()
|
|
n.microdescriptor = newVal
|
|
}
|
|
|
|
func (n *TorNode) GetHexFingerprint() Fingerprint {
|
|
return n.getRouterstatus().Fingerprint
|
|
}
|
|
|
|
var ErrNoHSDir = errors.New("NoHSDir")
|
|
var ErrNoEd25519Identity = errors.New("NoEd25519Identity")
|
|
|
|
// GetHsdirIndex get the HSDir index for this node:
|
|
//
|
|
// hsdir_index(node) = H("node-idx" | node_identity |
|
|
// shared_random_value |
|
|
// INT_8(period_num) |
|
|
// INT_8(period_length) )
|
|
//
|
|
// Raises NoHSDir or NoEd25519Identity in case of errors.
|
|
func (n *TorNode) GetHsdirIndex(srv []byte, period_num int64, consensus *Consensus) ([]byte, error) {
|
|
// See if this node can be an HSDir (it needs to be supported both in
|
|
// protover and in flags)
|
|
//arr, found := n.routerstatus.Protocols["HSDir"]
|
|
//if !found {
|
|
// panic("NoHSDir")
|
|
//}
|
|
//found = false
|
|
//for _, el := range arr {
|
|
// if 2 == el {
|
|
// found = true
|
|
// break
|
|
// }
|
|
//}
|
|
//if !found {
|
|
// panic("NoHSDir")
|
|
//}
|
|
if !n.getRouterstatus().Flags.HSDir {
|
|
return nil, ErrNoHSDir
|
|
}
|
|
|
|
// See if ed25519 identity is supported for this node
|
|
if _, found := n.getMicrodescriptor().Identifiers["ed25519"]; !found {
|
|
return nil, ErrNoEd25519Identity
|
|
}
|
|
|
|
// In stem the ed25519 identity is a base64 string and we need to add
|
|
// the missing padding so that the python base64 module can successfully
|
|
// decode it.
|
|
// TODO: Abstract this into its own function...
|
|
ed25519NodeIdentityB64 := n.getMicrodescriptor().Identifiers["ed25519"]
|
|
missingPadding := len(ed25519NodeIdentityB64) % 4
|
|
ed25519NodeIdentityB64 += strings.Repeat("=", missingPadding)
|
|
ed25519NodeIdentity, _ := base64.StdEncoding.DecodeString(ed25519NodeIdentityB64)
|
|
|
|
periodNumInt8 := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(periodNumInt8[len(periodNumInt8)-8:], uint64(period_num))
|
|
periodLength := consensus.Consensus().GetTimePeriodLength()
|
|
periodLengthInt8 := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(periodLengthInt8[len(periodLengthInt8)-8:], uint64(periodLength))
|
|
|
|
hashBody := "node-idx" + string(ed25519NodeIdentity) + string(srv) + string(periodNumInt8) + string(periodLengthInt8)
|
|
hsdirIndex := sha3.Sum256([]byte(hashBody))
|
|
|
|
return hsdirIndex[:], nil
|
|
}
|