Beispiel #1
0
// ReceiveMessage receives a Client-Mix message
func ReceiveMessage(lookupKey KeyFunc, message []byte) (*ReceiveStruct, error) {
	// var uniqueDat []UniquenessData
	var rstr ReceiveStruct
	var lenB uint16
	decMessage, err := Decrypt(lookupKey, message)
	if err != nil {
		return nil, err
	}
	rstr.MixHeader, lenB, err = new(ClientMixHeader).Unmarshal(decMessage)
	if err != nil {
		return nil, err
	}
	// Test Size
	msgLen := len(decMessage) - int(lenB)
	if rstr.MixHeader.MessageType == MessageTypeRelay && (msgLen < RelayMinSize || msgLen > RelayMaxSize) {
		fmt.Println(msgLen)
		return nil, ErrSize
	}
	if rstr.MixHeader.MessageType == MessageTypeForward && (msgLen < ForwardMinSize || msgLen > ForwardMaxSize) {
		return nil, ErrSize
	}
	// Uniqueness data collection
	if rstr.MixHeader.MessageType == MessageTypeRelay {
		rstr.NymAddress, err = nymaddr.ParseAddress(rstr.MixHeader.Address)
		if err != nil {
			return nil, err
		}
		rstr.NymAddressPrivate, err = rstr.NymAddress.GetMixData(nymaddr.KeyFunc(lookupKey))
		if err != nil {
			return nil, err
		}
		// First 256byte of message
		rstr.UniqueTest = append(rstr.UniqueTest, UniquenessData{
			Expire: rstr.NymAddressPrivate.Expire,
			Hash:   mkHash(decMessage[lenB : lenB+256]), // First 256 byte of message
		})
		if rstr.NymAddressPrivate.SingleUse {
			rstr.UniqueTest = append(rstr.UniqueTest, UniquenessData{
				Expire: rstr.NymAddressPrivate.Expire,
				Hash:   rstr.NymAddressPrivate.ReceiverPubKey,
			})
		}
	} else {
		rstr.UniqueTest = append(rstr.UniqueTest, UniquenessData{
			Expire: timeNow() + ExpireReceive,
			Hash:   mkHash(decMessage[lenB : lenB+256]), // First 256 byte of message
		})
	}
	rstr.Message = decMessage[lenB:]
	return &rstr, nil
}
Beispiel #2
0
// NewNymAddress generates a new nym address.
func NewNymAddress(
	domain string,
	secret []byte,
	expire int64,
	singleUse bool,
	minDelay, maxDelay int32,
	id string,
	pubkey *[ed25519.PublicKeySize]byte,
	server string,
	caCert []byte,
) (mixaddress, nymaddress string, err error) {
	if err := identity.IsMapped(id); err != nil {
		return "", "", log.Error(err)
	}
	if MixAddress == "" {
		return "", "", log.Error("util: MixAddress undefined")
	}
	mixAddresses, err := client.GetMixKeys(MixAddress, caCert)
	if err != nil {
		return "", "", log.Error(err)
	}
	tmp := nymaddr.AddressTemplate{
		Secret:        secret,
		System:        0,
		MixCandidates: mixAddresses.Addresses,
		Expire:        expire,
		SingleUse:     singleUse,
		MinDelay:      minDelay,
		MaxDelay:      maxDelay,
	}
	nymAddress, err := tmp.NewAddress(MailboxAddress(pubkey, server),
		cipher.SHA256([]byte(id)))
	if err != nil {
		return "", "", log.Error(err)
	}
	addr, err := nymaddr.ParseAddress(nymAddress)
	if err != nil {
		return "", "", log.Error(err)
	}
	return string(addr.MixAddress), base64.Encode(nymAddress), nil
}
Beispiel #3
0
// NewRelayMessage creates a new message with type MessageTypeRelay. Uses ClientMixHeader SenderMinDelay,SenderMaxDelay,Token. Sets revokeID
func (cl *ClientMixHeader) NewRelayMessage(NymAddress []byte, msg []byte) (message []byte, deliverAddress string, err error) {
	if cl == nil {
		cl = new(ClientMixHeader)
	}
	address, err := nymaddr.ParseAddress(NymAddress)
	if err != nil {
		return nil, "", err
	}
	NextHopKey := new([KeySize]byte)
	copy(NextHopKey[:], address.MixPubKey)
	cl.MessageType = MessageTypeRelay
	cl.Address = NymAddress
	revokeID, _ := genNonce()
	cl.RevokeID = revokeID[:]
	header := cl.Marshal()
	messageC := make([]byte, len(header)+len(msg))
	copy(messageC[0:len(header)], header)
	copy(messageC[len(header):], msg)
	msgEncrypted, err := Encrypt(NextHopKey, nil, messageC)
	return msgEncrypted, string(address.MixAddress), err
}
Beispiel #4
0
func (ce *CtrlEngine) procOutQueue(
	c *cli.Context,
	nym string,
	failDelivery bool,
) error {
	log.Debug("procOutQueue()")
	for {
		oqIdx, msg, nymaddress, minDelay, maxDelay, envelope, err :=
			ce.msgDB.GetOutQueue(nym)
		if err != nil {
			return err
		}
		if msg == "" {
			log.Debug("break")
			break // no more messages in outqueue
		}
		if !envelope {
			log.Debug("envelope")
			// parse nymaddress
			na, err := base64.Decode(nymaddress)
			if err != nil {
				return log.Error(na)
			}
			addr, err := nymaddr.ParseAddress(na)
			if err != nil {
				return err
			}
			// get token from wallet
			var pubkey [32]byte
			copy(pubkey[:], addr.TokenPubKey)
			token, err := wallet.GetToken(ce.client, "Message", &pubkey)
			if err != nil {
				return err
			}
			// `muteproto create`
			env, err := muteprotoCreate(c, msg, minDelay, maxDelay,
				base64.Encode(token.Token), nymaddress)
			if err != nil {
				return log.Error(err)
			}
			// update outqueue
			if err := ce.msgDB.SetOutQueue(oqIdx, env); err != nil {
				ce.client.UnlockToken(token.Hash)
				return err
			}
			ce.client.DelToken(token.Hash)
			msg = env
		}
		// `muteproto deliver`
		if failDelivery {
			return log.Error(ErrDeliveryFailed)
		}
		sendTime := times.Now() + int64(minDelay) // earliest
		resend, err := muteprotoDeliver(c, msg)
		if err != nil {
			// If the message delivery failed because the token expired in the
			// meantime we retract the message from the outqueue (setting it
			// back to 'ToSend') and start the delivery process for this
			// message all over again.
			// Matching the error message string is not optimal, but the best
			// available solution since the error results from calling another
			// binary (muteproto).
			if strings.HasSuffix(err.Error(), client.ErrFinal.Error()) {
				log.Debug("retract")
				if err := ce.msgDB.RetractOutQueue(oqIdx); err != nil {
					return err
				}
				continue
			}
			return log.Error(err)
		}
		if resend {
			// set resend status
			log.Debug("resend")
			if err := ce.msgDB.SetResendOutQueue(oqIdx); err != nil {
				return err
			}
		} else {
			// remove from outqueue
			log.Debug("remove")
			if err := ce.msgDB.RemoveOutQueue(oqIdx, sendTime); err != nil {
				return err
			}
		}
	}
	return nil
}