Verified Commit c51d89df authored by onyinyang's avatar onyinyang 🔒
Browse files

Move key generation to core

parent 584ac724
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -5,9 +5,13 @@
package core

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/binary"
	"encoding/json"
	"errors"
	"fmt"
	"hash"
	"hash/crc64"
	"log"
	"sort"
@@ -41,6 +45,35 @@ type ResourceState struct {
	Notworking []Resource `json:"not_working"`
}

// Rootkey represents the hmac root key created from the rdsys secret key
// and used to derive distributor keys for each rdsys distributor
type RootKey hash.Hash

// BucketKey is the hmac key derived from RootKey for a specific distributor
type BucketKey struct {
	bucketKey hash.Hash
}

func NewRootKey(secretKey string) RootKey {
	rootKey := []byte(secretKey)
	return hmac.New(sha256.New, rootKey)
}

func NewBucketKey(secret string, distName string) BucketKey {
	rootKey := NewRootKey(secret)
	rootKey.Write([]byte(distName))
	bucketKey := rootKey.Sum(nil)
	return BucketKey{
		bucketKey: hmac.New(sha256.New, bucketKey),
	}
}

func (b *BucketKey) NewBucketHash(usrBytes []byte) Hashkey {
	b.bucketKey.Write(usrBytes)
	h := b.bucketKey.Sum(nil)
	return Hashkey(binary.BigEndian.Uint64(h[:8]))
}

// Hashkey represents an index in a hashring.
type Hashkey uint64

+4 −4
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ func (td *TimeDistribution) housekeeping(rStream chan *core.ResourceDiff) {
	}
}

func (td *TimeDistribution) GetBridges(tpe string, ip net.IP, req *core.BridgeRequest) []string {
func (td *TimeDistribution) GetBridges(tpe string, ip net.IP, req *core.BridgeRequest, bucketKey core.BucketKey) []string {
	hashring := td.collection.GetHashring(td.getProportionIndex(), tpe)

	var resources []core.Resource
@@ -96,7 +96,7 @@ func (td *TimeDistribution) GetBridges(tpe string, ip net.IP, req *core.BridgeRe
		resources = hashring.GetAll()
	} else {
		var err error
		resources, err = hashring.GetMany(IpHashkey(ip), td.Cfg.NumBridgesPerRequest, req)
		resources, err = hashring.GetMany(IpHashkey(ip, bucketKey), td.Cfg.NumBridgesPerRequest, req)
		if err != nil {
			log.Println("Error getting resources from the subhashring:", err)
		}
@@ -126,10 +126,10 @@ func (td *TimeDistribution) getProportionIndex() string {
	return strconv.Itoa(period % td.Cfg.NumPeriods)
}

func IpHashkey(ip net.IP) core.Hashkey {
func IpHashkey(ip net.IP, bucketKey core.BucketKey) core.Hashkey {
	mask := net.CIDRMask(32, 128)
	if ip.To4() != nil {
		mask = net.CIDRMask(16, 32)
	}
	return core.NewHashkey(ip.Mask(mask).String())
	return bucketKey.NewBucketHash([]byte(ip.Mask(mask)))
}
+4 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ type EmailDistributor struct {
	ipc        delivery.Mechanism
	wg         sync.WaitGroup
	shutdown   chan bool
	bucketKey  core.BucketKey
}

type Command struct {
@@ -59,6 +60,8 @@ func (d *EmailDistributor) Init(cfg *internal.Config) {
	d.cfg = &cfg.Distributors.Email
	d.shutdown = make(chan bool)

	d.bucketKey = core.NewBucketKey(cfg.Backend.SecretHashKey, DistName)

	collectionConfig := core.CollectionConfig{}
	for _, rType := range d.cfg.Resources {
		collectionConfig.Types = append(collectionConfig.Types, core.TypeConfig{
@@ -123,7 +126,7 @@ func (d *EmailDistributor) GetResources(address string, command *Command) []core

	now := time.Now().Unix() / (60 * 60)
	period := now / int64(d.cfg.RotationPeriodHours)
	hashKey := core.NewHashkey(fmt.Sprintf("%s-%d", address, period))
	hashKey := d.bucketKey.NewBucketHash([]byte(fmt.Sprintf("%s-%d", address, period)))

	ipVersion := core.IPv4
	if command.IPv6 {
+3 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ const (
// HttpsDistributor contains all the context that the distributor needs to run.
type HttpsDistributor struct {
	timeDistribution *common.TimeDistribution
	bucketKey        core.BucketKey

	cfg *internal.Config
}
@@ -60,7 +61,7 @@ func (d *HttpsDistributor) RequestBridges(opts RequestBridgesOptions) ([]string,
	if opts.IPv6 {
		req.IPVersion = core.IPv6
	}
	r := d.timeDistribution.GetBridges(opts.Type, opts.IP, req)
	r := d.timeDistribution.GetBridges(opts.Type, opts.IP, req, d.bucketKey)
	return r, nil
}

@@ -69,6 +70,7 @@ func (d *HttpsDistributor) Init(cfg *internal.Config) {
	log.Printf("Initialising %s distributor.", DistName)

	d.cfg = cfg
	d.bucketKey = core.NewBucketKey(cfg.Backend.SecretHashKey, DistName)
	log.Printf("Initialising resource stream.")
	d.timeDistribution = &common.TimeDistribution{
		ResourceStreamURL: cfg.Backend.ResourceStreamURL(),
+4 −2
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ type MoatDistributor struct {
	cfg                   *internal.MoatDistConfig
	wg                    sync.WaitGroup
	shutdown              chan bool
	bucketKey             core.BucketKey

	// FetchBridges gets the list of builtin bridgelines from a remote url
	// the bridgeLines map is indexed by bridge type
@@ -153,7 +154,7 @@ func (d *MoatDistributor) getBridges(bs BridgeSettings, ip net.IP, shimToken, co
		return bridges[bs.Type]

	case "bridgedb":
		return d.timeDistribution.GetBridges(bs.Type, ip, req)
		return d.timeDistribution.GetBridges(bs.Type, ip, req, d.bucketKey)

	default:
		log.Println("Requested an unsuported bridge source:", bs.Source)
@@ -178,7 +179,7 @@ func (d *MoatDistributor) GetBridges(transport string, ip net.IP, country string
		IPVersion: core.IPv4,
		Country:   country,
	}
	return d.timeDistribution.GetBridges(transport, ip, req)
	return d.timeDistribution.GetBridges(transport, ip, req, d.bucketKey)
}

func (d *MoatDistributor) GetBuiltInBridges(types []string) map[string][]string {
@@ -239,6 +240,7 @@ func (d *MoatDistributor) Init(cfg *internal.Config) {
	d.shutdown = make(chan bool)
	d.builtinBridges = make(map[string][]string)
	d.fetchBuiltinBridges()
	d.bucketKey = core.NewBucketKey(cfg.Backend.SecretHashKey, DistName)

	d.timeDistribution = &common.TimeDistribution{
		ResourceStreamURL: cfg.Backend.ResourceStreamURL(),