update packaging
[platform/core/system/edge-orchestration.git] / vendor / golang.org / x / crypto / openpgp / keys_test.go
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         // The expiringKeyHex key is structured as:
25         //
26         // pub  1024R/5E237D8C  created: 2013-07-01                      expires: 2013-07-31  usage: SC
27         // sub  1024R/1ABB25A0  created: 2013-07-01 23:11:07 +0200 CEST  expires: 2013-07-08  usage: E
28         // sub  1024R/96A672F5  created: 2013-07-01 23:11:23 +0200 CEST  expires: 2013-07-31  usage: E
29         //
30         // So this should select the newest, non-expired encryption key.
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         // Once the first encryption subkey has expired, the second should be
37         // selected.
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         // Once all the keys have expired, nothing should be returned.
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         // This public key has a signing subkey, but the subkey does not
53         // contain a cross-signature.
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         // This public key has a signing subkey, and the subkey has an
73         // embedded cross-signature. However, the cross-signature does
74         // not correctly validate over the primary and subkey.
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         // This public key has a signing subkey, and the subkey has an
94         // embedded cross-signature which correctly validates over the
95         // primary and subkey.
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         // This key contains 2 UIDs, one of which is revoked:
110         // [ultimate] (1)  Golang Gopher <no-reply@golang.com>
111         // [ revoked] (2)  Golang Gopher <revoked@golang.com>
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 // TestExternallyRevokableKey attempts to load and parse a key with a third party revocation permission.
136 func TestExternallyRevocableKey(t *testing.T) {
137         kring, err := ReadKeyRing(readerFromHex(subkeyUsageHex))
138         if err != nil {
139                 t.Fatal(err)
140         }
141
142         // The 0xA42704B92866382A key can be revoked by 0xBE3893CB843D0FE70C
143         // according to this signature that appears within the key:
144         // :signature packet: algo 1, keyid A42704B92866382A
145         //    version 4, created 1396409682, md5len 0, sigclass 0x1f
146         //    digest algo 2, begin of digest a9 84
147         //    hashed subpkt 2 len 4 (sig created 2014-04-02)
148         //    hashed subpkt 12 len 22 (revocation key: c=80 a=1 f=CE094AA433F7040BB2DDF0BE3893CB843D0FE70C)
149         //    hashed subpkt 7 len 1 (not revocable)
150         //    subpkt 16 len 8 (issuer key ID A42704B92866382A)
151         //    data: [1024 bits]
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         // revokedKeyHex contains these keys:
167         // pub   1024R/9A34F7C0 2014-03-25 [revoked: 2014-03-25]
168         // sub   1024R/1BA3CD60 2014-03-25 [revoked: 2014-03-25]
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         // This key contains a revoked sub key:
185         //  pub   rsa1024/0x4CBD826C39074E38 2018-06-14 [SC]
186         //        Key fingerprint = 3F95 169F 3FFA 7D3F 2B47  6F0C 4CBD 826C 3907 4E38
187         //  uid   Golang Gopher <no-reply@golang.com>
188         //  sub   rsa1024/0x945DB1AF61D85727 2018-06-14 [S] [revoked: 2018-06-14]
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         // Test for an issue where Subkey Binding Signatures (RFC 4880 5.2.1) were added to the identity
202         // preceding the Subkey Packet if the Subkey Packet was followed by more than one signature.
203         // For example, the current key has the following layout:
204         //    PUBKEY UID SELFSIG SUBKEY REV SELFSIG
205         // The last SELFSIG would be added to the UID's signatures. This is wrong.
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         // revokedSubkeyHex contains these keys:
228         // pub   1024R/4EF7E4BECCDE97F0 2014-03-25
229         // sub   1024R/D63636E2B96AE423 2014-03-25
230         // sub   1024D/DBCE4EE19529437F 2014-03-25
231         // sub   1024R/677815E371C2FD23 2014-03-25 [revoked: 2014-03-25]
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         // This key was altered so that the self signatures following the
259         // subkey are in a sub-optimal order.
260         //
261         // Note: Should someone have to create a similar key again, look into
262         //       gpgsplit, gpg --dearmor, and gpg --enarmor.
263         //
264         // The packet ordering is the following:
265         //    PUBKEY UID UIDSELFSIG SUBKEY SELFSIG1 SELFSIG2
266         //
267         // Where:
268         //    SELFSIG1 expires on 2018-06-14 and was created first
269         //    SELFSIG2 does not expire and was created after SELFSIG1
270         //
271         // Test for RFC 4880 5.2.3.3:
272         // > An implementation that encounters multiple self-signatures on the
273         // > same object may resolve the ambiguity in any way it sees fit, but it
274         // > is RECOMMENDED that priority be given to the most recent self-
275         // > signature.
276         //
277         // This means that we should keep SELFSIG2.
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         // subkeyUsageHex contains these keys:
309         // pub  1024R/2866382A  created: 2014-04-01  expires: never       usage: SC
310         // sub  1024R/936C9153  created: 2014-04-01  expires: never       usage: E
311         // sub  1024R/64D5F5BB  created: 2014-04-02  expires: never       usage: E
312         // sub  1024D/BC0BA992  created: 2014-04-02  expires: never       usage: S
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                 // This keyring contains no encryption keys that are also good for signing.
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                 // This keyring contains no encryption keys that are also good for signing.
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 }