key_test.go

 1package identity
 2
 3import (
 4	"crypto/rsa"
 5	"encoding/json"
 6	"testing"
 7	"time"
 8
 9	"github.com/stretchr/testify/require"
10
11	"github.com/git-bug/git-bug/entity"
12	"github.com/git-bug/git-bug/repository"
13	"github.com/git-bug/git-bug/util/lamport"
14	"github.com/git-bug/git-bug/util/timestamp"
15)
16
17type mockIdentity struct {
18	name  string
19	login string
20	email string
21}
22
23func (m *mockIdentity) Name() string                                        { return m.name }
24func (m *mockIdentity) Login() string                                      { return m.login }
25func (m *mockIdentity) Email() string                                     { return m.email }
26func (m *mockIdentity) DisplayName() string                               { return m.name }
27func (m *mockIdentity) AvatarUrl() string                                 { return "" }
28func (m *mockIdentity) Keys() []*Key                                      { return nil }
29func (m *mockIdentity) SigningKey(repo repository.RepoKeyring) (*Key, error) { return nil, nil }
30func (m *mockIdentity) ValidKeysAtTime(clockName string, time lamport.Time) []*Key { return nil }
31func (m *mockIdentity) LastModification() timestamp.Timestamp             { return 0 }
32func (m *mockIdentity) LastModificationLamports() map[string]lamport.Time { return nil }
33func (m *mockIdentity) IsProtected() bool                                 { return false }
34func (m *mockIdentity) Validate() error                                   { return nil }
35func (m *mockIdentity) NeedCommit() bool                                  { return false }
36func (m *mockIdentity) Id() entity.Id                                     { return "" }
37
38func TestPublicKeyJSON(t *testing.T) {
39	id := &mockIdentity{name: "John Smith", email: "jsmith@example.com"}
40	k := generatePublicKey(id)
41
42	dataJSON, err := json.Marshal(k)
43	require.NoError(t, err)
44
45	var read Key
46	err = json.Unmarshal(dataJSON, &read)
47	require.NoError(t, err)
48
49	// Compare public keys since entities may differ in internal structure after deserialization
50	require.Equal(t, k.public.Fingerprint[:], read.public.Fingerprint[:])
51}
52
53func TestStoreLoad(t *testing.T) {
54	repo := repository.NewMockRepoKeyring()
55
56	// public + private
57	id := &mockIdentity{name: "John Smith", email: "jsmith@example.com"}
58	k := GenerateKey(id, WithTime(time.Time{}))
59
60	// Store
61
62	dataJSON, err := json.Marshal(k)
63	require.NoError(t, err)
64
65	err = k.storePrivate(repo)
66	require.NoError(t, err)
67
68	// Load
69
70	var read Key
71	err = json.Unmarshal(dataJSON, &read)
72	require.NoError(t, err)
73
74	err = read.ensurePrivateKey(repo)
75	require.NoError(t, err)
76
77	require.Equal(t, k.public, read.public)
78
79	require.IsType(t, (*rsa.PrivateKey)(nil), k.entity.PrivateKey.PrivateKey)
80
81	// See https://github.com/golang/crypto/pull/175
82	rsaPriv := read.entity.PrivateKey.PrivateKey.(*rsa.PrivateKey)
83	rsaPriv.Primes[0], rsaPriv.Primes[1] = rsaPriv.Primes[1], rsaPriv.Primes[0]
84
85	require.True(t, k.entity.PrivateKey.PrivateKey.(*rsa.PrivateKey).Equal(read.entity.PrivateKey.PrivateKey))
86}