Example #1
0
func TestMessage(t *testing.T) {
	log := make(chan string, 100)
	priv, x, y := encryption.CreateKey(log)
	pub := elliptic.Marshal(elliptic.P256(), x, y)
	address := encryption.GetAddress(log, x, y)

	msg := new(Message)
	msg.AddrHash = MakeHash(address)
	msg.TxidHash = MakeHash([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})
	msg.Timestamp = time.Now().Round(time.Second)
	msg.Content = *encryption.Encrypt(log, pub, "Hello World!")

	mBytes := msg.GetBytes()
	if mBytes == nil {
		fmt.Println("Error Encoding Message!")
		t.FailNow()
	}

	msg2 := new(Message)
	msg2.FromBytes(mBytes)
	if string(msg2.AddrHash.GetBytes()) != string(msg.AddrHash.GetBytes()) || string(msg2.TxidHash.GetBytes()) != string(msg.TxidHash.GetBytes()) || msg2.Timestamp.Unix() != msg.Timestamp.Unix() {
		fmt.Println("Message Header incorrect: ", msg2)
		t.FailNow()
	}

	if string(encryption.Decrypt(log, priv, &msg.Content)[:12]) != "Hello World!" {
		fmt.Println("Message content incorrect: ", string(encryption.Decrypt(log, priv, &msg.Content)[:12]))
		t.Fail()
	}
}
Example #2
0
// Handle Pubkey, Message, and Purge Registration
func register(config *api.ApiConfig) {
	var message objects.Message
	var txid [16]byte

	for {
		select {
		case pubHash := <-config.PubkeyRegister:

			// Check if pubkey is in database...
			pubkey := checkPubkey(config, pubHash)

			if pubkey == nil {
				break
			}

			outbox := localdb.GetBox(localdb.OUTBOX)
			for _, metamsg := range outbox {
				recvHash := objects.MakeHash([]byte(metamsg.Recipient))
				if string(pubHash.GetBytes()) == string(recvHash.GetBytes()) {
					// Send message and move to sendbox
					msg, err := localdb.GetMessageDetail(metamsg.TxidHash)
					if err != nil {
						config.Log <- err.Error()
						break
					}
					msg.Encrypted = encryption.Encrypt(config.Log, pubkey, string(msg.Decrypted.GetBytes()))
					msg.MetaMessage.Timestamp = time.Now().Round(time.Second)
					err = localdb.AddUpdateMessage(msg, localdb.SENDBOX)
					if err != nil {
						config.Log <- err.Error()
						break
					}

					sendMsg := new(objects.Message)
					sendMsg.Timestamp = msg.MetaMessage.Timestamp
					sendMsg.TxidHash = msg.MetaMessage.TxidHash
					sendMsg.AddrHash = recvHash
					sendMsg.Content = *msg.Encrypted

					config.RecvQueue <- *objects.MakeFrame(objects.MSG, objects.BROADCAST, sendMsg)
				}
			}

		case message = <-config.MessageRegister:
			// If address is registered, store message in inbox
			detail, err := localdb.GetAddressDetail(message.AddrHash)
			if err != nil {
				config.Log <- "Message address not in database..."
				break
			}
			if !detail.IsRegistered {
				config.Log <- "Message not for registered address..."
				break
			}

			config.Log <- "Registering new encrypted message..."

			msg := new(objects.FullMessage)
			msg.MetaMessage.TxidHash = message.TxidHash
			msg.MetaMessage.Timestamp = message.Timestamp
			msg.MetaMessage.Recipient = detail.String
			msg.Encrypted = &message.Content

			err = localdb.AddUpdateMessage(msg, localdb.INBOX)
			if err != nil {
				config.Log <- err.Error()
			}
		case message = <-config.PubRegister:
			// If address is registered, store message in inbox
			detail, err := localdb.GetAddressDetail(message.AddrHash)
			if err != nil {
				config.Log <- "Message address not in database..."
				break
			}
			if !detail.IsSubscribed {
				config.Log <- "Not Subscribed to Address..."
				break
			}

			config.Log <- "Registering new publication..."

			msg := new(objects.FullMessage)
			msg.MetaMessage.TxidHash = message.TxidHash
			msg.MetaMessage.Timestamp = message.Timestamp
			msg.MetaMessage.Sender = detail.String
			msg.MetaMessage.Recipient = "<Subscription Message>"
			msg.Encrypted = &message.Content

			msg.Decrypted = new(objects.DecryptedMessage)
			msg.Decrypted.FromBytes(encryption.DecryptPub(config.Log, detail.Pubkey, msg.Encrypted))

			err = localdb.AddUpdateMessage(msg, localdb.INBOX)
			if err != nil {
				config.Log <- err.Error()
			}
		case txid = <-config.PurgeRegister:
			// If Message in database, mark as purged
			detail, err := localdb.GetMessageDetail(objects.MakeHash(txid[:]))
			if err != nil {
				break
			}
			detail.MetaMessage.Purged = true
			err = localdb.AddUpdateMessage(detail, -1)
			if err != nil {
				config.Log <- fmt.Sprintf("Error registering purge: %s", err)
			}
		} // End select
	} // End for
} // End register
Example #3
0
func (service *EMPService) SendMessage(r *http.Request, args *SendMsg, reply *SendResponse) error {
	if !basicAuth(service.Config, r) {
		service.Config.Log <- fmt.Sprintf("Unauthorized RPC Request from: %s", r.RemoteAddr)
		return errors.New("Unauthorized")
	}

	// Nil Check
	if len(args.Sender) == 0 || len(args.Recipient) == 0 || len(args.Plaintext) == 0 {
		return errors.New("All fields required except signature.")
	}

	var err error

	// Get Addresses
	sendAddr := encryption.StringToAddress(args.Sender)
	if len(sendAddr) == 0 {
		return errors.New("Invalid sender address!")
	}

	recvAddr := encryption.StringToAddress(args.Recipient)
	if len(recvAddr) == 0 {
		return errors.New("Invalid recipient address!")
	}

	sender, err := localdb.GetAddressDetail(objects.MakeHash(sendAddr))
	if err != nil {
		return errors.New(fmt.Sprintf("Error pulling send address from Database: %s", err))
	}
	if sender.Pubkey == nil {
		sender.Pubkey = checkPubkey(service.Config, objects.MakeHash(sendAddr))
		if sender.Pubkey == nil {
			return errors.New("Sender's Public Key is required to send message!")
		}
	}
	if sender.Privkey == nil {
		return errors.New("SendMsg() requires a stored private key. Use SendRawMsg() instead.")
	}

	recipient, err := localdb.GetAddressDetail(objects.MakeHash(recvAddr))
	if err != nil {
		return errors.New(fmt.Sprintf("Error pulling recipient address from Database: %s", err))
	}

	// Create New Message
	msg := new(objects.FullMessage)
	msg.Decrypted = new(objects.DecryptedMessage)
	msg.Encrypted = nil

	// Fill out decrypted message
	n, err := rand.Read(msg.Decrypted.Txid[:])
	if n < len(msg.Decrypted.Txid[:]) || err != nil {
		return errors.New(fmt.Sprintf("Problem with random reader: %s", err))
	}
	copy(msg.Decrypted.Pubkey[:], sender.Pubkey)
	msg.Decrypted.Subject = args.Subject
	msg.Decrypted.MimeType = "text/plain"
	msg.Decrypted.Content = args.Plaintext
	msg.Decrypted.Length = uint32(len(msg.Decrypted.Content))

	// Fill Out Meta Message (save timestamp)
	msg.MetaMessage.Purged = false
	msg.MetaMessage.TxidHash = objects.MakeHash(msg.Decrypted.Txid[:])
	msg.MetaMessage.Sender = sender.String
	msg.MetaMessage.Recipient = recipient.String

	// Get Signature
	priv := new(ecdsa.PrivateKey)
	priv.PublicKey.Curve = encryption.GetCurve()
	priv.D = new(big.Int)
	priv.D.SetBytes(sender.Privkey)

	sign := msg.Decrypted.GetBytes()
	sign = sign[:len(sign)-65]
	signHash := objects.MakeHash(sign)

	x, y, err := ecdsa.Sign(rand.Reader, priv, signHash.GetBytes())
	if err != nil {
		return err
	}

	copy(msg.Decrypted.Signature[:], encryption.MarshalPubkey(x, y))

	// Check for pubkey
	if recipient.Pubkey == nil {
		recipient.Pubkey = checkPubkey(service.Config, objects.MakeHash(recipient.Address))
	}

	if recipient.Pubkey == nil {
		reply.IsSent = false
		// Add message to outbox...
		err = localdb.AddUpdateMessage(msg, localdb.OUTBOX)
		if err != nil {
			return err
		}

	} else {
		// Send message and add to sendbox...
		msg.Encrypted = encryption.Encrypt(service.Config.Log, recipient.Pubkey, string(msg.Decrypted.GetBytes()))
		msg.MetaMessage.Timestamp = time.Now().Round(time.Second)

		err = localdb.AddUpdateMessage(msg, localdb.SENDBOX)
		if err != nil {
			return err
		}

		sendMsg := new(objects.Message)
		sendMsg.TxidHash = msg.MetaMessage.TxidHash
		sendMsg.AddrHash = objects.MakeHash(recipient.Address)
		sendMsg.Timestamp = msg.MetaMessage.Timestamp
		sendMsg.Content = *msg.Encrypted

		service.Config.RecvQueue <- *objects.MakeFrame(objects.MSG, objects.BROADCAST, sendMsg)

		reply.IsSent = true
	}

	// Finish by setting msg's txid
	reply.TxidHash = msg.MetaMessage.TxidHash.GetBytes()
	return nil
}