Exemple #1
0
func kissGenerateCtx(underly io.ReadWriteCloser, our_priv natrium.ECDHPrivate, their_pub natrium.ECDHPublic) *kissContext {
	shared_secret := natrium.ECDHSecret(our_priv, their_pub)
	read_nonce := natrium.SecureHash(append(our_priv.PublicKey(), their_pub...), nil)
	write_nonce := natrium.SecureHash(append(their_pub, our_priv.PublicKey()...), nil)

	toret := new(kissContext)
	toret.read_buff = new(bytes.Buffer)
	toret.transport = underly
	toret.read_chug = natrium.AEAD(natrium.SecureHash(shared_secret, read_nonce))
	toret.write_chug = natrium.AEAD(natrium.SecureHash(shared_secret, write_nonce))
	return toret
}
Exemple #2
0
// LLObfsServerHandshake negotiates low-level obfuscation (content hiding but no
// volume hiding) on a network connection, acting as the server. The master
// secret must be provided.
func LLObfsServerHandshake(secret []byte, transport io.ReadWriteCloser) (io.ReadWriteCloser, error) {
	// Client needs to send proof that they actually have our secret
	proof := make([]byte, 64)
	_, err := io.ReadFull(transport, proof)
	if err != nil {
		return nil, err
	}
	kilog.FineDebug("llobfs: server obtained proof")
	// We need to verify proof
	nonce := proof[:32]
	hash := proof[32:]
	if subtle.ConstantTimeCompare(natrium.SecureHash(secret, nonce), hash) != 1 {
		return nil, errors.New("Client did not give the right proof")
	}
	// Generate our ephemeral keys
	our_keys := UDHGenerateKeys()

	// Send our public key
	_, err = transport.Write(our_keys.Public)
	if err != nil {
		return nil, err
	}
	kilog.FineDebug("llobfs: server sent public key")

	// Read their public key
	their_public := make([]byte, 1536/8)
	_, err = io.ReadFull(transport, their_public)
	if err != nil {
		return nil, err
	}
	kilog.FineDebug("llobfs: server read public key")
	// Compute shared secret
	shared_secret := UDHSecret(our_keys.Private, their_public)
	// Read and write keys
	read_key := natrium.SecureHash(shared_secret, []byte("llobfs-upstream-key"))
	write_key := natrium.SecureHash(shared_secret, []byte("llobfs-downstream-key"))
	// Create struct
	toret := new(llobfsContext)

	toret.read_chug, _ = rc4.NewCipher(read_key)
	toret.write_chug, _ = rc4.NewCipher(write_key)

	dummy := make([]byte, 1536)
	toret.read_chug.XORKeyStream(dummy, dummy)
	toret.write_chug.XORKeyStream(dummy, dummy)

	toret.underlying = transport
	return toret, nil
}
Exemple #3
0
func (sg *servGroup) connAmb(i int) (*kiricom.ServerCtx, error) {
	nonce := make([]byte, 8)
	binary.BigEndian.PutUint64(nonce, uint64(i))
	hash := natrium.SecureHash(sg.aidee.PublicKey(), nonce)

	kilog.Debug("serv: building circuit %v -> %x for %v", i, hash, sg.aidee.PublicKey())
	var tgt directory.ChordKey
	tgt.FromBytes(hash)

	// build circuit to each and every one of them
	thingy, err := buildCirc(tgt)
	if err != nil {
		//thingy.Destroy()
		return nil, err
	}
	haha, err := thingy.RegAmbassador(sg.aidee.PublicKey())
	if err != nil {
		thingy.Destroy()
		if err == core2core.ErrRejectedReq {
			kilog.Warning("serv: circuit number %v for %v rejected", i, sg.aidee.PublicKey())
			return nil, err
		} else {
			return nil, err
		}
	}
	return haha, nil
}
Exemple #4
0
// makes a hash value out of the naked neighbor info to sign
func (nin neighInfoNaked) HashValue() []byte {
	acc := make([]byte, 8)
	binary.LittleEndian.PutUint64(acc, uint64(nin.Expires))
	acc = append(acc, nin.IssuedTo...)
	for _, bts := range nin.NeighList {
		acc = append(acc, bts...)
	}
	return natrium.SecureHash(acc, nil)
}
Exemple #5
0
// LLObfsClientHandshake negotiates low-level obfuscation as a client. The server
// secret must be given so that the client can prove knowledge.
func LLObfsClientHandshake(secret []byte, transport io.ReadWriteCloser) (io.ReadWriteCloser, error) {
	// Prove knowledge to client first
	nonce := make([]byte, 32)
	rand.Read(nonce)
	hash := natrium.SecureHash(secret, nonce)
	_, err := transport.Write(append(nonce, hash...))
	if err != nil {
		return nil, err
	}
	kilog.FineDebug("llobfs: client sent proof")
	// Read their public key
	their_public := make([]byte, 1536/8)
	_, err = io.ReadFull(transport, their_public)
	if err != nil {
		return nil, err
	}
	kilog.FineDebug("llobfs: client read server's public key")
	// Make our keys
	our_keys := UDHGenerateKeys()
	// Send our public key
	_, err = transport.Write(our_keys.Public)
	if err != nil {
		return nil, err
	}
	kilog.FineDebug("llobfs: client sent public key")
	// Compute shared secret
	shared_secret := UDHSecret(our_keys.Private, their_public)
	// Derive keys
	read_key := natrium.SecureHash(shared_secret, []byte("llobfs-downstream-key"))
	write_key := natrium.SecureHash(shared_secret, []byte("llobfs-upstream-key"))
	toret := new(llobfsContext)
	toret.read_chug, _ = rc4.NewCipher(read_key)
	toret.write_chug, _ = rc4.NewCipher(write_key)

	dummy := make([]byte, 1536)
	toret.read_chug.XORKeyStream(dummy, dummy)
	toret.write_chug.XORKeyStream(dummy, dummy)
	toret.underlying = transport

	return toret, nil
}
Exemple #6
0
func (cc *CollisionCache) Search() Solution {
	var found []byte
	wg := new(sync.WaitGroup)

	offset := uint64(rand.Uint32())<<32 | uint64(rand.Uint32())
	fmt.Printf("*** OFFSET = %v ***\n", offset)

	wg.Add(runtime.GOMAXPROCS(0))
	for i := 0; i < runtime.GOMAXPROCS(0); i++ {
		i := i
		go func() {
			defer wg.Done()
			stpt := (^uint64(0) / uint64(runtime.GOMAXPROCS(0))) * (uint64(i) - 1)
			stpt += offset
			for i := stpt; found == nil; i++ {
				//fmt.Println(i)
				bts := (*[8]byte)(unsafe.Pointer(&i))[:]
				hsh := uint64(*(*uint64)(
					unsafe.Pointer(&natrium.SecureHash(cc.nonce, bts)[0])))
				hsh >>= uint(64 - cc.pflen)

				cc.Lock()
				ex, ok := cc.cash[hsh]
				cc.cash[hsh] = i
				cc.Unlock()

				if ok && ex != i {
					fmt.Printf("%v collides with %v (%v)\n", ex, i, hsh)
					fnd := make([]byte, 16)
					binary.LittleEndian.PutUint64(fnd[:8], ex)
					binary.LittleEndian.PutUint64(fnd[8:], i)
					found = fnd
					break
				}
			}
		}()
	}

	wg.Wait()
	return found
}
Exemple #7
0
func newCircGroup(dest natrium.EdDSAPublic) (*circGroup, error) {
	// 8 targets in total
	targets := make([]directory.ChordKey, 8)
	for i := 0; i < 8; i++ {
		nonce := make([]byte, 8)
		binary.BigEndian.PutUint64(nonce, uint64(i))
		hash := natrium.SecureHash(dest, nonce)
		targets[i].FromBytes(hash)
	}

	toret := new(circGroup)
	toret.inchan = make(chan chan io.ReadWriteCloser)
	toret.dedchan = make(chan bool)

	okaych := make(chan bool, 10)

	// spin off goroutines
	for i, tgt := range targets {
		tgt := tgt
		i := i
		kilog.Debug("circ: building circuit %v -> %x for %v", i, tgt.ToBytes(), dest)
		go func() {
			goto SKIP

			// error
		DIE_IN_DISGRACE:
			kilog.Warning("circ: circuit action %v for %v (%x) is aborted!", i, dest, tgt.ToBytes())
			// TODO don't die when just one circuit dies
			//toret.Destroy()
			return
		SKIP:

			spider, err := buildCirc(tgt)
			if err != nil {
				toret.Destroy()
				goto DIE_IN_DISGRACE
			}

			kilog.Debug("circ: circuit to the closest node to %x (%v) established",
				tgt.ToBytes(), spider.CurrentPublic())
			kilog.Debug("circ: patching through ambassador %v to %v...", i, dest)
			thing, err := spider.ConnAmbassador(dest)
			if err != nil {
				spider.Destroy()
				goto DIE_IN_DISGRACE
			}
			kilog.Debug("circ: patched through ambassador to %v! circuit length %v", dest, spider.CircLength())
			defer thing.Close()
			/*if spider.CircLength() < 1 {
				kilog.Debug("circ: aborting %v due to bad length", i)
				return
			}*/
			okaych <- true
			for {
				select {
				case req := <-toret.inchan:
					kilog.Debug("circ: request to %v routed through %v", dest, i)
					wire, err := thing.Dial()
					if err != nil {
						kilog.Warning("circ: request to %v through %v encountered unusable dialer!", dest, i)
						go func() {
							select {
							case toret.inchan <- req:
							case <-time.After(time.Second * 2):
								close(req)
							}
						}()
						return
					}
					go func() {
						select {
						case req <- wire:
						case <-toret.dedchan:
							kilog.Debug("circ: circuit %v for %v closing down safely", i, dest)
						}
					}()
				case <-toret.dedchan:
					kilog.Debug("circ: circuit %v for %v closing down safely", i, dest)
					return
				}
			}

		}()
	}
	select {
	case <-okaych:
	case <-time.After(time.Second * 20):
		kilog.Warning("circ: nothing happened in 20 seconds for %v, dying", dest)
		toret.Destroy()
		return nil, io.ErrNoProgress
	}
	// return
	return toret, nil
}