1 package openpgp
2
3 import (
4 "bytes"
5 "crypto"
6 "strings"
7 "testing"
8 "time"
9
10 "golang.org/x/crypto/openpgp/errors"
11 "golang.org/x/crypto/openpgp/packet"
12 )
13
14 func TestKeyExpiry(t *testing.T) {
15 kring, err := ReadKeyRing(readerFromHex(expiringKeyHex))
16 if err != nil {
17 t.Fatal(err)
18 }
19 entity := kring[0]
20
21 const timeFormat = "2006-01-02"
22 time1, _ := time.Parse(timeFormat, "2013-07-01")
23
24
25
26
27
28
29
30
31 key, _ := entity.encryptionKey(time1)
32 if id, expected := key.PublicKey.KeyIdShortString(), "96A672F5"; id != expected {
33 t.Errorf("Expected key %s at time %s, but got key %s", expected, time1.Format(timeFormat), id)
34 }
35
36
37
38 time2, _ := time.Parse(timeFormat, "2013-07-09")
39 key, _ = entity.encryptionKey(time2)
40 if id, expected := key.PublicKey.KeyIdShortString(), "96A672F5"; id != expected {
41 t.Errorf("Expected key %s at time %s, but got key %s", expected, time2.Format(timeFormat), id)
42 }
43
44
45 time3, _ := time.Parse(timeFormat, "2013-08-01")
46 if key, ok := entity.encryptionKey(time3); ok {
47 t.Errorf("Expected no key at time %s, but got key %s", time3.Format(timeFormat), key.PublicKey.KeyIdShortString())
48 }
49 }
50
51 func TestMissingCrossSignature(t *testing.T) {
52
53
54 keys, err := ReadArmoredKeyRing(bytes.NewBufferString(missingCrossSignatureKey))
55 if len(keys) != 0 {
56 t.Errorf("Accepted key with missing cross signature")
57 }
58 if err == nil {
59 t.Fatal("Failed to detect error in keyring with missing cross signature")
60 }
61 structural, ok := err.(errors.StructuralError)
62 if !ok {
63 t.Fatalf("Unexpected class of error: %T. Wanted StructuralError", err)
64 }
65 const expectedMsg = "signing subkey is missing cross-signature"
66 if !strings.Contains(string(structural), expectedMsg) {
67 t.Fatalf("Unexpected error: %q. Expected it to contain %q", err, expectedMsg)
68 }
69 }
70
71 func TestInvalidCrossSignature(t *testing.T) {
72
73
74
75 keys, err := ReadArmoredKeyRing(bytes.NewBufferString(invalidCrossSignatureKey))
76 if len(keys) != 0 {
77 t.Errorf("Accepted key with invalid cross signature")
78 }
79 if err == nil {
80 t.Fatal("Failed to detect error in keyring with an invalid cross signature")
81 }
82 structural, ok := err.(errors.StructuralError)
83 if !ok {
84 t.Fatalf("Unexpected class of error: %T. Wanted StructuralError", err)
85 }
86 const expectedMsg = "subkey signature invalid"
87 if !strings.Contains(string(structural), expectedMsg) {
88 t.Fatalf("Unexpected error: %q. Expected it to contain %q", err, expectedMsg)
89 }
90 }
91
92 func TestGoodCrossSignature(t *testing.T) {
93
94
95
96 keys, err := ReadArmoredKeyRing(bytes.NewBufferString(goodCrossSignatureKey))
97 if err != nil {
98 t.Fatal(err)
99 }
100 if len(keys) != 1 {
101 t.Errorf("Failed to accept key with good cross signature, %d", len(keys))
102 }
103 if len(keys[0].Subkeys) != 1 {
104 t.Errorf("Failed to accept good subkey, %d", len(keys[0].Subkeys))
105 }
106 }
107
108 func TestRevokedUserID(t *testing.T) {
109
110
111
112 keys, err := ReadArmoredKeyRing(bytes.NewBufferString(revokedUserIDKey))
113 if err != nil {
114 t.Fatal(err)
115 }
116
117 if len(keys) != 1 {
118 t.Fatal("Failed to read key with a revoked user id")
119 }
120
121 var identities []*Identity
122 for _, identity := range keys[0].Identities {
123 identities = append(identities, identity)
124 }
125
126 if numIdentities, numExpected := len(identities), 1; numIdentities != numExpected {
127 t.Errorf("obtained %d identities, expected %d", numIdentities, numExpected)
128 }
129
130 if identityName, expectedName := identities[0].Name, "Golang Gopher <no-reply@golang.com>"; identityName != expectedName {
131 t.Errorf("obtained identity %s expected %s", identityName, expectedName)
132 }
133 }
134
135
136 func TestExternallyRevocableKey(t *testing.T) {
137 kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
138 if err != nil {
139 t.Fatal(err)
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153 id := uint64(0xA42704B92866382A)
154 keys := kring.KeysById(id)
155 if len(keys) != 1 {
156 t.Errorf("Expected to find key id %X, but got %d matches", id, len(keys))
157 }
158 }
159
160 func TestKeyRevocation(t *testing.T) {
161 kring, err := ReadKeyRing(readerFromHex(revokedKeyHex))
162 if err != nil {
163 t.Fatal(err)
164 }
165
166
167
168
169 ids := []uint64{0xA401D9F09A34F7C0, 0x5CD3BE0A1BA3CD60}
170
171 for _, id := range ids {
172 keys := kring.KeysById(id)
173 if len(keys) != 1 {
174 t.Errorf("Expected KeysById to find revoked key %X, but got %d matches", id, len(keys))
175 }
176 keys = kring.KeysByIdUsage(id, 0)
177 if len(keys) != 0 {
178 t.Errorf("Expected KeysByIdUsage to filter out revoked key %X, but got %d matches", id, len(keys))
179 }
180 }
181 }
182
183 func TestKeyWithRevokedSubKey(t *testing.T) {
184
185
186
187
188
189
190 keys, err := ReadArmoredKeyRing(bytes.NewBufferString(keyWithSubKey))
191 if err != nil {
192 t.Fatal(err)
193 }
194
195 if len(keys) != 1 {
196 t.Fatal("Failed to read key with a sub key")
197 }
198
199 identity := keys[0].Identities["Golang Gopher <no-reply@golang.com>"]
200
201
202
203
204
205
206 if numIdentitySigs, numExpected := len(identity.Signatures), 0; numIdentitySigs != numExpected {
207 t.Fatalf("got %d identity signatures, expected %d", numIdentitySigs, numExpected)
208 }
209
210 if numSubKeys, numExpected := len(keys[0].Subkeys), 1; numSubKeys != numExpected {
211 t.Fatalf("got %d subkeys, expected %d", numSubKeys, numExpected)
212 }
213
214 subKey := keys[0].Subkeys[0]
215 if subKey.Sig == nil {
216 t.Fatalf("subkey signature is nil")
217 }
218
219 }
220
221 func TestSubkeyRevocation(t *testing.T) {
222 kring, err := ReadKeyRing(readerFromHex(revokedSubkeyHex))
223 if err != nil {
224 t.Fatal(err)
225 }
226
227
228
229
230
231
232 validKeys := []uint64{0x4EF7E4BECCDE97F0, 0xD63636E2B96AE423, 0xDBCE4EE19529437F}
233 revokedKey := uint64(0x677815E371C2FD23)
234
235 for _, id := range validKeys {
236 keys := kring.KeysById(id)
237 if len(keys) != 1 {
238 t.Errorf("Expected KeysById to find key %X, but got %d matches", id, len(keys))
239 }
240 keys = kring.KeysByIdUsage(id, 0)
241 if len(keys) != 1 {
242 t.Errorf("Expected KeysByIdUsage to find key %X, but got %d matches", id, len(keys))
243 }
244 }
245
246 keys := kring.KeysById(revokedKey)
247 if len(keys) != 1 {
248 t.Errorf("Expected KeysById to find key %X, but got %d matches", revokedKey, len(keys))
249 }
250
251 keys = kring.KeysByIdUsage(revokedKey, 0)
252 if len(keys) != 0 {
253 t.Errorf("Expected KeysByIdUsage to filter out revoked key %X, but got %d matches", revokedKey, len(keys))
254 }
255 }
256
257 func TestKeyWithSubKeyAndBadSelfSigOrder(t *testing.T) {
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279 keys, err := ReadArmoredKeyRing(bytes.NewBufferString(keyWithSubKeyAndBadSelfSigOrder))
280 if err != nil {
281 t.Fatal(err)
282 }
283
284 if len(keys) != 1 {
285 t.Fatal("Failed to read key with a sub key and a bad selfsig packet order")
286 }
287
288 key := keys[0]
289
290 if numKeys, expected := len(key.Subkeys), 1; numKeys != expected {
291 t.Fatalf("Read %d subkeys, expected %d", numKeys, expected)
292 }
293
294 subKey := key.Subkeys[0]
295
296 if lifetime := subKey.Sig.KeyLifetimeSecs; lifetime != nil {
297 t.Errorf("The signature has a key lifetime (%d), but it should be nil", *lifetime)
298 }
299
300 }
301
302 func TestKeyUsage(t *testing.T) {
303 kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
304 if err != nil {
305 t.Fatal(err)
306 }
307
308
309
310
311
312
313 certifiers := []uint64{0xA42704B92866382A}
314 signers := []uint64{0xA42704B92866382A, 0x42CE2C64BC0BA992}
315 encrypters := []uint64{0x09C0C7D9936C9153, 0xC104E98664D5F5BB}
316
317 for _, id := range certifiers {
318 keys := kring.KeysByIdUsage(id, packet.KeyFlagCertify)
319 if len(keys) == 1 {
320 if keys[0].PublicKey.KeyId != id {
321 t.Errorf("Expected to find certifier key id %X, but got %X", id, keys[0].PublicKey.KeyId)
322 }
323 } else {
324 t.Errorf("Expected one match for certifier key id %X, but got %d matches", id, len(keys))
325 }
326 }
327
328 for _, id := range signers {
329 keys := kring.KeysByIdUsage(id, packet.KeyFlagSign)
330 if len(keys) == 1 {
331 if keys[0].PublicKey.KeyId != id {
332 t.Errorf("Expected to find signing key id %X, but got %X", id, keys[0].PublicKey.KeyId)
333 }
334 } else {
335 t.Errorf("Expected one match for signing key id %X, but got %d matches", id, len(keys))
336 }
337
338
339 keys = kring.KeysByIdUsage(id, packet.KeyFlagEncryptStorage|packet.KeyFlagEncryptCommunications)
340 if len(keys) != 0 {
341 t.Errorf("Unexpected match for encryption key id %X", id)
342 }
343 }
344
345 for _, id := range encrypters {
346 keys := kring.KeysByIdUsage(id, packet.KeyFlagEncryptStorage|packet.KeyFlagEncryptCommunications)
347 if len(keys) == 1 {
348 if keys[0].PublicKey.KeyId != id {
349 t.Errorf("Expected to find encryption key id %X, but got %X", id, keys[0].PublicKey.KeyId)
350 }
351 } else {
352 t.Errorf("Expected one match for encryption key id %X, but got %d matches", id, len(keys))
353 }
354
355
356 keys = kring.KeysByIdUsage(id, packet.KeyFlagSign)
357 if len(keys) != 0 {
358 t.Errorf("Unexpected match for signing key id %X", id)
359 }
360 }
361 }
362
363 func TestIdVerification(t *testing.T) {
364 kring, err := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
365 if err != nil {
366 t.Fatal(err)
367 }
368 if err := kring[1].PrivateKey.Decrypt([]byte("passphrase")); err != nil {
369 t.Fatal(err)
370 }
371
372 const identity = "Test Key 1 (RSA)"
373 if err := kring[0].SignIdentity(identity, kring[1], nil); err != nil {
374 t.Fatal(err)
375 }
376
377 ident, ok := kring[0].Identities[identity]
378 if !ok {
379 t.Fatal("identity missing from key after signing")
380 }
381
382 checked := false
383 for _, sig := range ident.Signatures {
384 if sig.IssuerKeyId == nil || *sig.IssuerKeyId != kring[1].PrimaryKey.KeyId {
385 continue
386 }
387
388 if err := kring[1].PrimaryKey.VerifyUserIdSignature(identity, kring[0].PrimaryKey, sig); err != nil {
389 t.Fatalf("error verifying new identity signature: %s", err)
390 }
391 checked = true
392 break
393 }
394
395 if !checked {
396 t.Fatal("didn't find identity signature in Entity")
397 }
398 }
399
400 func TestNewEntityWithPreferredHash(t *testing.T) {
401 c := &packet.Config{
402 DefaultHash: crypto.SHA256,
403 }
404 entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", c)
405 if err != nil {
406 t.Fatal(err)
407 }
408
409 for _, identity := range entity.Identities {
410 if len(identity.SelfSignature.PreferredHash) == 0 {
411 t.Fatal("didn't find a preferred hash in self signature")
412 }
413 ph := hashToHashId(c.DefaultHash)
414 if identity.SelfSignature.PreferredHash[0] != ph {
415 t.Fatalf("Expected preferred hash to be %d, got %d", ph, identity.SelfSignature.PreferredHash[0])
416 }
417 }
418 }
419
420 func TestNewEntityWithoutPreferredHash(t *testing.T) {
421 entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
422 if err != nil {
423 t.Fatal(err)
424 }
425
426 for _, identity := range entity.Identities {
427 if len(identity.SelfSignature.PreferredHash) != 0 {
428 t.Fatalf("Expected preferred hash to be empty but got length %d", len(identity.SelfSignature.PreferredHash))
429 }
430 }
431 }
432
433 func TestNewEntityCorrectName(t *testing.T) {
434 entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
435 if err != nil {
436 t.Fatal(err)
437 }
438 if len(entity.Identities) != 1 {
439 t.Fatalf("len(entity.Identities) = %d, want 1", len(entity.Identities))
440 }
441 var got string
442 for _, i := range entity.Identities {
443 got = i.Name
444 }
445 want := "Golang Gopher (Test Key) <no-reply@golang.com>"
446 if got != want {
447 t.Fatalf("Identity.Name = %q, want %q", got, want)
448 }
449 }
450
451 func TestNewEntityWithPreferredSymmetric(t *testing.T) {
452 c := &packet.Config{
453 DefaultCipher: packet.CipherAES256,
454 }
455 entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", c)
456 if err != nil {
457 t.Fatal(err)
458 }
459
460 for _, identity := range entity.Identities {
461 if len(identity.SelfSignature.PreferredSymmetric) == 0 {
462 t.Fatal("didn't find a preferred cipher in self signature")
463 }
464 if identity.SelfSignature.PreferredSymmetric[0] != uint8(c.DefaultCipher) {
465 t.Fatalf("Expected preferred cipher to be %d, got %d", uint8(c.DefaultCipher), identity.SelfSignature.PreferredSymmetric[0])
466 }
467 }
468 }
469
470 func TestNewEntityWithoutPreferredSymmetric(t *testing.T) {
471 entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
472 if err != nil {
473 t.Fatal(err)
474 }
475
476 for _, identity := range entity.Identities {
477 if len(identity.SelfSignature.PreferredSymmetric) != 0 {
478 t.Fatalf("Expected preferred cipher to be empty but got length %d", len(identity.SelfSignature.PreferredSymmetric))
479 }
480 }
481 }
482
483 func TestNewEntityPublicSerialization(t *testing.T) {
484 entity, err := NewEntity("Golang Gopher", "Test Key", "no-reply@golang.com", nil)
485 if err != nil {
486 t.Fatal(err)
487 }
488 serializedEntity := bytes.NewBuffer(nil)
489 entity.Serialize(serializedEntity)
490
491 _, err = ReadEntity(packet.NewReader(bytes.NewBuffer(serializedEntity.Bytes())))
492 if err != nil {
493 t.Fatal(err)
494 }
495 }
496
View as plain text