~bfiedler/go-threema

97f9d9c50d77f74b7145149768aba2d426f5f9c7 — Ben Fiedler 1 year, 6 months ago 293b495
Return raw bytes when hashing phone numbers

It is up to the caller to encode the result if necessary
3 files changed, 15 insertions(+), 25 deletions(-)

M client/client.go
M client/crypto.go
M client/crypto_test.go
M client/client.go => client/client.go +2 -2
@@ 218,7 218,7 @@ func (c *client) LookupIDByPhoneHash(phoneNumber string) (ThreemaID, error) {
		return "", err
	}

	path := fmt.Sprintf("/lookup/phone_hash/%s", hash) + c.defaultQuery()
	path := fmt.Sprintf("/lookup/phone_hash/%s", hex.EncodeToString(hash)) + c.defaultQuery()
	resp, err := c.httpClient.Get(c.gatewayUrl + path)
	if err != nil {
		return "", err


@@ 244,7 244,7 @@ func (c *client) LookupIDByEmailHash(address string) (ThreemaID, error) {
		return "", err
	}

	path := fmt.Sprintf("/lookup/email_hash/%s", hash) + c.defaultQuery()
	path := fmt.Sprintf("/lookup/email_hash/%s", hex.EncodeToString(hash)) + c.defaultQuery()
	resp, err := c.httpClient.Get(c.gatewayUrl + path)
	if err != nil {
		return "", err

M client/crypto.go => client/crypto.go +10 -21
@@ 2,7 2,6 @@ package client

import (
	"crypto/rand"
	"encoding/hex"
	"math/big"
	"strings"



@@ 28,42 27,32 @@ func computePublicKey(privateKey PrivateKey) PublicKey {
	return publicKey
}

// Hashes the given phone number using the defined HMAC function. Returns the
// hex-encoded hash as string.
func (c *client) hashPhone(phoneNumber string) (string, error) {
// Hashes the given phone number using the defined HMAC function.
func (c *client) hashPhone(phoneNumber string) ([]byte, error) {
	c.phoneMu.Lock()
	defer c.phoneMu.Unlock()

	c.phoneHMAC.Reset()
	_, err := c.phoneHMAC.Write([]byte(phoneNumber))
	if err != nil {
		c.phoneMu.Unlock()
		return "", err
		return nil, err
	}
	hashed := c.phoneHMAC.Sum(nil)

	c.phoneMu.Unlock()

	return hex.EncodeToString(hashed), nil
	return c.phoneHMAC.Sum(nil), nil
}

// Hashes the given e-mail address using the defined HMAC function. Returns the
// hex-encoded hash as string.
func (c *client) hashEmail(address string) (string, error) {
// Hashes the given e-mail address using the defined HMAC function.
func (c *client) hashEmail(address string) ([]byte, error) {
	address = strings.ToLower(strings.TrimSpace(address))

	c.emailMu.Lock()
	defer c.emailMu.Unlock()

	c.emailHMAC.Reset()
	_, err := c.emailHMAC.Write([]byte(address))
	if err != nil {
		c.emailMu.Unlock()
		return "", err
		return nil, err
	}
	hashed := c.emailHMAC.Sum(nil)

	c.emailMu.Unlock()

	return hex.EncodeToString(hashed), nil
	return c.emailHMAC.Sum(nil), nil
}

// Constructs, encrypts and encodes `msg` as text message. Returns the

M client/crypto_test.go => client/crypto_test.go +3 -2
@@ 1,6 1,7 @@
package client

import (
	"encoding/hex"
	"testing"

	"github.com/stretchr/testify/assert"


@@ 32,7 33,7 @@ func TestHashPhone(t *testing.T) {
	phone := "41791234567"
	hash, err := c.hashPhone(phone)
	assert.Nil(t, err)
	assert.Equal(t, "ad398f4d7ebe63c6550a486cc6e07f9baa09bd9d8b3d8cb9d9be106d35a7fdbc", hash)
	assert.Equal(t, "ad398f4d7ebe63c6550a486cc6e07f9baa09bd9d8b3d8cb9d9be106d35a7fdbc", hex.EncodeToString(hash))
}

// Test case available on the Threema Gateway documentation


@@ 51,7 52,7 @@ func TestHashEmail(t *testing.T) {
		t.Run(name, func(t *testing.T) {
			hash, err := c.hashEmail(testcase)
			assert.Nil(t, err)
			assert.Equal(t, "1ea093239cc5f0e1b6ec81b866265b921f26dc4033025410063309f4d1a8ee2c", hash)
			assert.Equal(t, "1ea093239cc5f0e1b6ec81b866265b921f26dc4033025410063309f4d1a8ee2c", hex.EncodeToString(hash))
		})
	}
}