Esempio n. 1
0
func checkPubkey(config *api.ApiConfig, addrHash objects.Hash) []byte {

	// First check local DB
	detail, err := localdb.GetAddressDetail(addrHash)
	if err != nil {
		// If not in database, won't be able to decrypt anyway!
		return nil
	}
	if len(detail.Pubkey) > 0 {
		if db.Contains(addrHash) != db.PUBKEY {
			enc := new(objects.EncryptedPubkey)

			enc.IV, enc.Payload, _ = encryption.SymmetricEncrypt(detail.Address, string(detail.Pubkey))
			enc.AddrHash = objects.MakeHash(detail.Address)

			config.RecvQueue <- *objects.MakeFrame(objects.PUBKEY, objects.BROADCAST, enc)
		}
		return detail.Pubkey
	}

	// If not there, check local database
	if db.Contains(addrHash) == db.PUBKEY {
		enc := db.GetPubkey(config.Log, addrHash)

		pubkey := encryption.SymmetricDecrypt(enc.IV, detail.Address, enc.Payload)
		pubkey = pubkey[:65]

		// Check public Key
		x, y := encryption.UnmarshalPubkey(pubkey)
		if x == nil {
			config.Log <- "Decrypted Public Key Invalid"
			return nil
		}

		address2 := encryption.GetAddress(config.Log, x, y)
		if string(detail.Address) != string(address2) {
			config.Log <- "Decrypted Public Key doesn't match provided address!"
			return nil
		}

		detail.Pubkey = pubkey
		err := localdb.AddUpdateAddress(detail)
		if err != nil {
			config.Log <- "Error adding pubkey to local database!"
			return nil
		}

		return pubkey
	}

	// If not there, send a pubkey request
	config.RecvQueue <- *objects.MakeFrame(objects.PUBKEY_REQUEST, objects.BROADCAST, &addrHash)
	return nil
}
Esempio n. 2
0
func (service *EMPService) OpenMessage(r *http.Request, args *[]byte, reply *objects.FullMessage) error {
	if !basicAuth(service.Config, r) {
		service.Config.Log <- fmt.Sprintf("Unauthorized RPC Request from: %s", r.RemoteAddr)
		return errors.New("Unauthorized")
	}

	var txidHash objects.Hash
	txidHash.FromBytes(*args)

	// Get Message from Database
	msg, err := localdb.GetMessageDetail(txidHash)
	if err != nil {
		return err
	}

	if msg.Encrypted == nil {
		*reply = *msg
		return nil
	}

	// If not decrypted, decrypt message and purge
	if msg.Decrypted == nil {
		recipient, err := localdb.GetAddressDetail(objects.MakeHash(encryption.StringToAddress(msg.MetaMessage.Recipient)))
		if err != nil {
			return err
		}

		if recipient.Privkey == nil {
			*reply = *msg
			return nil
		}

		// Decrypt Message
		decrypted := encryption.Decrypt(service.Config.Log, recipient.Privkey, msg.Encrypted)
		if len(decrypted) == 0 {
			*reply = *msg
			return nil
		}
		msg.Decrypted = new(objects.DecryptedMessage)
		msg.Decrypted.FromBytes(decrypted)

		// Update Sender

		x, y := encryption.UnmarshalPubkey(msg.Decrypted.Pubkey[:])
		address := encryption.GetAddress(service.Config.Log, x, y)
		addrStr := encryption.AddressToString(address)
		addrHash := objects.MakeHash(address)

		detail, _ := localdb.GetAddressDetail(addrHash)
		if detail == nil {
			detail = new(objects.AddressDetail)
		}
		detail.Address = address
		detail.String = addrStr
		detail.Pubkey = msg.Decrypted.Pubkey[:]

		localdb.AddUpdateAddress(detail)
		msg.MetaMessage.Sender = detail.String

		// Send Purge Request
		purge := new(objects.Purge)
		purge.Txid = msg.Decrypted.Txid

		service.Config.RecvQueue <- *objects.MakeFrame(objects.PURGE, objects.BROADCAST, purge)
		msg.MetaMessage.Purged = true

		localdb.AddUpdateMessage(msg, localdb.Contains(msg.MetaMessage.TxidHash))
	} else {
		if msg.MetaMessage.Purged == false && localdb.Contains(txidHash) == localdb.INBOX {
			msg.MetaMessage.Purged = true
			localdb.AddUpdateMessage(msg, localdb.Contains(msg.MetaMessage.TxidHash))
		}
	}

	*reply = *msg
	return nil
}