diff options
Diffstat (limited to 'vendor/golang.org/x/crypto/openpgp/keys.go')
-rw-r--r-- | vendor/golang.org/x/crypto/openpgp/keys.go | 637 |
1 files changed, 637 insertions, 0 deletions
diff --git a/vendor/golang.org/x/crypto/openpgp/keys.go b/vendor/golang.org/x/crypto/openpgp/keys.go new file mode 100644 index 0000000..68b14c6 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/keys.go | |||
@@ -0,0 +1,637 @@ | |||
1 | // Copyright 2011 The Go Authors. All rights reserved. | ||
2 | // Use of this source code is governed by a BSD-style | ||
3 | // license that can be found in the LICENSE file. | ||
4 | |||
5 | package openpgp | ||
6 | |||
7 | import ( | ||
8 | "crypto/rsa" | ||
9 | "io" | ||
10 | "time" | ||
11 | |||
12 | "golang.org/x/crypto/openpgp/armor" | ||
13 | "golang.org/x/crypto/openpgp/errors" | ||
14 | "golang.org/x/crypto/openpgp/packet" | ||
15 | ) | ||
16 | |||
17 | // PublicKeyType is the armor type for a PGP public key. | ||
18 | var PublicKeyType = "PGP PUBLIC KEY BLOCK" | ||
19 | |||
20 | // PrivateKeyType is the armor type for a PGP private key. | ||
21 | var PrivateKeyType = "PGP PRIVATE KEY BLOCK" | ||
22 | |||
23 | // An Entity represents the components of an OpenPGP key: a primary public key | ||
24 | // (which must be a signing key), one or more identities claimed by that key, | ||
25 | // and zero or more subkeys, which may be encryption keys. | ||
26 | type Entity struct { | ||
27 | PrimaryKey *packet.PublicKey | ||
28 | PrivateKey *packet.PrivateKey | ||
29 | Identities map[string]*Identity // indexed by Identity.Name | ||
30 | Revocations []*packet.Signature | ||
31 | Subkeys []Subkey | ||
32 | } | ||
33 | |||
34 | // An Identity represents an identity claimed by an Entity and zero or more | ||
35 | // assertions by other entities about that claim. | ||
36 | type Identity struct { | ||
37 | Name string // by convention, has the form "Full Name (comment) <email@example.com>" | ||
38 | UserId *packet.UserId | ||
39 | SelfSignature *packet.Signature | ||
40 | Signatures []*packet.Signature | ||
41 | } | ||
42 | |||
43 | // A Subkey is an additional public key in an Entity. Subkeys can be used for | ||
44 | // encryption. | ||
45 | type Subkey struct { | ||
46 | PublicKey *packet.PublicKey | ||
47 | PrivateKey *packet.PrivateKey | ||
48 | Sig *packet.Signature | ||
49 | } | ||
50 | |||
51 | // A Key identifies a specific public key in an Entity. This is either the | ||
52 | // Entity's primary key or a subkey. | ||
53 | type Key struct { | ||
54 | Entity *Entity | ||
55 | PublicKey *packet.PublicKey | ||
56 | PrivateKey *packet.PrivateKey | ||
57 | SelfSignature *packet.Signature | ||
58 | } | ||
59 | |||
60 | // A KeyRing provides access to public and private keys. | ||
61 | type KeyRing interface { | ||
62 | // KeysById returns the set of keys that have the given key id. | ||
63 | KeysById(id uint64) []Key | ||
64 | // KeysByIdAndUsage returns the set of keys with the given id | ||
65 | // that also meet the key usage given by requiredUsage. | ||
66 | // The requiredUsage is expressed as the bitwise-OR of | ||
67 | // packet.KeyFlag* values. | ||
68 | KeysByIdUsage(id uint64, requiredUsage byte) []Key | ||
69 | // DecryptionKeys returns all private keys that are valid for | ||
70 | // decryption. | ||
71 | DecryptionKeys() []Key | ||
72 | } | ||
73 | |||
74 | // primaryIdentity returns the Identity marked as primary or the first identity | ||
75 | // if none are so marked. | ||
76 | func (e *Entity) primaryIdentity() *Identity { | ||
77 | var firstIdentity *Identity | ||
78 | for _, ident := range e.Identities { | ||
79 | if firstIdentity == nil { | ||
80 | firstIdentity = ident | ||
81 | } | ||
82 | if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId { | ||
83 | return ident | ||
84 | } | ||
85 | } | ||
86 | return firstIdentity | ||
87 | } | ||
88 | |||
89 | // encryptionKey returns the best candidate Key for encrypting a message to the | ||
90 | // given Entity. | ||
91 | func (e *Entity) encryptionKey(now time.Time) (Key, bool) { | ||
92 | candidateSubkey := -1 | ||
93 | |||
94 | // Iterate the keys to find the newest key | ||
95 | var maxTime time.Time | ||
96 | for i, subkey := range e.Subkeys { | ||
97 | if subkey.Sig.FlagsValid && | ||
98 | subkey.Sig.FlagEncryptCommunications && | ||
99 | subkey.PublicKey.PubKeyAlgo.CanEncrypt() && | ||
100 | !subkey.Sig.KeyExpired(now) && | ||
101 | (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) { | ||
102 | candidateSubkey = i | ||
103 | maxTime = subkey.Sig.CreationTime | ||
104 | } | ||
105 | } | ||
106 | |||
107 | if candidateSubkey != -1 { | ||
108 | subkey := e.Subkeys[candidateSubkey] | ||
109 | return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true | ||
110 | } | ||
111 | |||
112 | // If we don't have any candidate subkeys for encryption and | ||
113 | // the primary key doesn't have any usage metadata then we | ||
114 | // assume that the primary key is ok. Or, if the primary key is | ||
115 | // marked as ok to encrypt to, then we can obviously use it. | ||
116 | i := e.primaryIdentity() | ||
117 | if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications && | ||
118 | e.PrimaryKey.PubKeyAlgo.CanEncrypt() && | ||
119 | !i.SelfSignature.KeyExpired(now) { | ||
120 | return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true | ||
121 | } | ||
122 | |||
123 | // This Entity appears to be signing only. | ||
124 | return Key{}, false | ||
125 | } | ||
126 | |||
127 | // signingKey return the best candidate Key for signing a message with this | ||
128 | // Entity. | ||
129 | func (e *Entity) signingKey(now time.Time) (Key, bool) { | ||
130 | candidateSubkey := -1 | ||
131 | |||
132 | for i, subkey := range e.Subkeys { | ||
133 | if subkey.Sig.FlagsValid && | ||
134 | subkey.Sig.FlagSign && | ||
135 | subkey.PublicKey.PubKeyAlgo.CanSign() && | ||
136 | !subkey.Sig.KeyExpired(now) { | ||
137 | candidateSubkey = i | ||
138 | break | ||
139 | } | ||
140 | } | ||
141 | |||
142 | if candidateSubkey != -1 { | ||
143 | subkey := e.Subkeys[candidateSubkey] | ||
144 | return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true | ||
145 | } | ||
146 | |||
147 | // If we have no candidate subkey then we assume that it's ok to sign | ||
148 | // with the primary key. | ||
149 | i := e.primaryIdentity() | ||
150 | if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagSign && | ||
151 | !i.SelfSignature.KeyExpired(now) { | ||
152 | return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true | ||
153 | } | ||
154 | |||
155 | return Key{}, false | ||
156 | } | ||
157 | |||
158 | // An EntityList contains one or more Entities. | ||
159 | type EntityList []*Entity | ||
160 | |||
161 | // KeysById returns the set of keys that have the given key id. | ||
162 | func (el EntityList) KeysById(id uint64) (keys []Key) { | ||
163 | for _, e := range el { | ||
164 | if e.PrimaryKey.KeyId == id { | ||
165 | var selfSig *packet.Signature | ||
166 | for _, ident := range e.Identities { | ||
167 | if selfSig == nil { | ||
168 | selfSig = ident.SelfSignature | ||
169 | } else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId { | ||
170 | selfSig = ident.SelfSignature | ||
171 | break | ||
172 | } | ||
173 | } | ||
174 | keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig}) | ||
175 | } | ||
176 | |||
177 | for _, subKey := range e.Subkeys { | ||
178 | if subKey.PublicKey.KeyId == id { | ||
179 | keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig}) | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | return | ||
184 | } | ||
185 | |||
186 | // KeysByIdAndUsage returns the set of keys with the given id that also meet | ||
187 | // the key usage given by requiredUsage. The requiredUsage is expressed as | ||
188 | // the bitwise-OR of packet.KeyFlag* values. | ||
189 | func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) { | ||
190 | for _, key := range el.KeysById(id) { | ||
191 | if len(key.Entity.Revocations) > 0 { | ||
192 | continue | ||
193 | } | ||
194 | |||
195 | if key.SelfSignature.RevocationReason != nil { | ||
196 | continue | ||
197 | } | ||
198 | |||
199 | if key.SelfSignature.FlagsValid && requiredUsage != 0 { | ||
200 | var usage byte | ||
201 | if key.SelfSignature.FlagCertify { | ||
202 | usage |= packet.KeyFlagCertify | ||
203 | } | ||
204 | if key.SelfSignature.FlagSign { | ||
205 | usage |= packet.KeyFlagSign | ||
206 | } | ||
207 | if key.SelfSignature.FlagEncryptCommunications { | ||
208 | usage |= packet.KeyFlagEncryptCommunications | ||
209 | } | ||
210 | if key.SelfSignature.FlagEncryptStorage { | ||
211 | usage |= packet.KeyFlagEncryptStorage | ||
212 | } | ||
213 | if usage&requiredUsage != requiredUsage { | ||
214 | continue | ||
215 | } | ||
216 | } | ||
217 | |||
218 | keys = append(keys, key) | ||
219 | } | ||
220 | return | ||
221 | } | ||
222 | |||
223 | // DecryptionKeys returns all private keys that are valid for decryption. | ||
224 | func (el EntityList) DecryptionKeys() (keys []Key) { | ||
225 | for _, e := range el { | ||
226 | for _, subKey := range e.Subkeys { | ||
227 | if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) { | ||
228 | keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig}) | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | return | ||
233 | } | ||
234 | |||
235 | // ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file. | ||
236 | func ReadArmoredKeyRing(r io.Reader) (EntityList, error) { | ||
237 | block, err := armor.Decode(r) | ||
238 | if err == io.EOF { | ||
239 | return nil, errors.InvalidArgumentError("no armored data found") | ||
240 | } | ||
241 | if err != nil { | ||
242 | return nil, err | ||
243 | } | ||
244 | if block.Type != PublicKeyType && block.Type != PrivateKeyType { | ||
245 | return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type) | ||
246 | } | ||
247 | |||
248 | return ReadKeyRing(block.Body) | ||
249 | } | ||
250 | |||
251 | // ReadKeyRing reads one or more public/private keys. Unsupported keys are | ||
252 | // ignored as long as at least a single valid key is found. | ||
253 | func ReadKeyRing(r io.Reader) (el EntityList, err error) { | ||
254 | packets := packet.NewReader(r) | ||
255 | var lastUnsupportedError error | ||
256 | |||
257 | for { | ||
258 | var e *Entity | ||
259 | e, err = ReadEntity(packets) | ||
260 | if err != nil { | ||
261 | // TODO: warn about skipped unsupported/unreadable keys | ||
262 | if _, ok := err.(errors.UnsupportedError); ok { | ||
263 | lastUnsupportedError = err | ||
264 | err = readToNextPublicKey(packets) | ||
265 | } else if _, ok := err.(errors.StructuralError); ok { | ||
266 | // Skip unreadable, badly-formatted keys | ||
267 | lastUnsupportedError = err | ||
268 | err = readToNextPublicKey(packets) | ||
269 | } | ||
270 | if err == io.EOF { | ||
271 | err = nil | ||
272 | break | ||
273 | } | ||
274 | if err != nil { | ||
275 | el = nil | ||
276 | break | ||
277 | } | ||
278 | } else { | ||
279 | el = append(el, e) | ||
280 | } | ||
281 | } | ||
282 | |||
283 | if len(el) == 0 && err == nil { | ||
284 | err = lastUnsupportedError | ||
285 | } | ||
286 | return | ||
287 | } | ||
288 | |||
289 | // readToNextPublicKey reads packets until the start of the entity and leaves | ||
290 | // the first packet of the new entity in the Reader. | ||
291 | func readToNextPublicKey(packets *packet.Reader) (err error) { | ||
292 | var p packet.Packet | ||
293 | for { | ||
294 | p, err = packets.Next() | ||
295 | if err == io.EOF { | ||
296 | return | ||
297 | } else if err != nil { | ||
298 | if _, ok := err.(errors.UnsupportedError); ok { | ||
299 | err = nil | ||
300 | continue | ||
301 | } | ||
302 | return | ||
303 | } | ||
304 | |||
305 | if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey { | ||
306 | packets.Unread(p) | ||
307 | return | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | |||
312 | // ReadEntity reads an entity (public key, identities, subkeys etc) from the | ||
313 | // given Reader. | ||
314 | func ReadEntity(packets *packet.Reader) (*Entity, error) { | ||
315 | e := new(Entity) | ||
316 | e.Identities = make(map[string]*Identity) | ||
317 | |||
318 | p, err := packets.Next() | ||
319 | if err != nil { | ||
320 | return nil, err | ||
321 | } | ||
322 | |||
323 | var ok bool | ||
324 | if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok { | ||
325 | if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok { | ||
326 | packets.Unread(p) | ||
327 | return nil, errors.StructuralError("first packet was not a public/private key") | ||
328 | } else { | ||
329 | e.PrimaryKey = &e.PrivateKey.PublicKey | ||
330 | } | ||
331 | } | ||
332 | |||
333 | if !e.PrimaryKey.PubKeyAlgo.CanSign() { | ||
334 | return nil, errors.StructuralError("primary key cannot be used for signatures") | ||
335 | } | ||
336 | |||
337 | var current *Identity | ||
338 | var revocations []*packet.Signature | ||
339 | EachPacket: | ||
340 | for { | ||
341 | p, err := packets.Next() | ||
342 | if err == io.EOF { | ||
343 | break | ||
344 | } else if err != nil { | ||
345 | return nil, err | ||
346 | } | ||
347 | |||
348 | switch pkt := p.(type) { | ||
349 | case *packet.UserId: | ||
350 | current = new(Identity) | ||
351 | current.Name = pkt.Id | ||
352 | current.UserId = pkt | ||
353 | e.Identities[pkt.Id] = current | ||
354 | |||
355 | for { | ||
356 | p, err = packets.Next() | ||
357 | if err == io.EOF { | ||
358 | return nil, io.ErrUnexpectedEOF | ||
359 | } else if err != nil { | ||
360 | return nil, err | ||
361 | } | ||
362 | |||
363 | sig, ok := p.(*packet.Signature) | ||
364 | if !ok { | ||
365 | return nil, errors.StructuralError("user ID packet not followed by self-signature") | ||
366 | } | ||
367 | |||
368 | if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId { | ||
369 | if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil { | ||
370 | return nil, errors.StructuralError("user ID self-signature invalid: " + err.Error()) | ||
371 | } | ||
372 | current.SelfSignature = sig | ||
373 | break | ||
374 | } | ||
375 | current.Signatures = append(current.Signatures, sig) | ||
376 | } | ||
377 | case *packet.Signature: | ||
378 | if pkt.SigType == packet.SigTypeKeyRevocation { | ||
379 | revocations = append(revocations, pkt) | ||
380 | } else if pkt.SigType == packet.SigTypeDirectSignature { | ||
381 | // TODO: RFC4880 5.2.1 permits signatures | ||
382 | // directly on keys (eg. to bind additional | ||
383 | // revocation keys). | ||
384 | } else if current == nil { | ||
385 | return nil, errors.StructuralError("signature packet found before user id packet") | ||
386 | } else { | ||
387 | current.Signatures = append(current.Signatures, pkt) | ||
388 | } | ||
389 | case *packet.PrivateKey: | ||
390 | if pkt.IsSubkey == false { | ||
391 | packets.Unread(p) | ||
392 | break EachPacket | ||
393 | } | ||
394 | err = addSubkey(e, packets, &pkt.PublicKey, pkt) | ||
395 | if err != nil { | ||
396 | return nil, err | ||
397 | } | ||
398 | case *packet.PublicKey: | ||
399 | if pkt.IsSubkey == false { | ||
400 | packets.Unread(p) | ||
401 | break EachPacket | ||
402 | } | ||
403 | err = addSubkey(e, packets, pkt, nil) | ||
404 | if err != nil { | ||
405 | return nil, err | ||
406 | } | ||
407 | default: | ||
408 | // we ignore unknown packets | ||
409 | } | ||
410 | } | ||
411 | |||
412 | if len(e.Identities) == 0 { | ||
413 | return nil, errors.StructuralError("entity without any identities") | ||
414 | } | ||
415 | |||
416 | for _, revocation := range revocations { | ||
417 | err = e.PrimaryKey.VerifyRevocationSignature(revocation) | ||
418 | if err == nil { | ||
419 | e.Revocations = append(e.Revocations, revocation) | ||
420 | } else { | ||
421 | // TODO: RFC 4880 5.2.3.15 defines revocation keys. | ||
422 | return nil, errors.StructuralError("revocation signature signed by alternate key") | ||
423 | } | ||
424 | } | ||
425 | |||
426 | return e, nil | ||
427 | } | ||
428 | |||
429 | func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error { | ||
430 | var subKey Subkey | ||
431 | subKey.PublicKey = pub | ||
432 | subKey.PrivateKey = priv | ||
433 | p, err := packets.Next() | ||
434 | if err == io.EOF { | ||
435 | return io.ErrUnexpectedEOF | ||
436 | } | ||
437 | if err != nil { | ||
438 | return errors.StructuralError("subkey signature invalid: " + err.Error()) | ||
439 | } | ||
440 | var ok bool | ||
441 | subKey.Sig, ok = p.(*packet.Signature) | ||
442 | if !ok { | ||
443 | return errors.StructuralError("subkey packet not followed by signature") | ||
444 | } | ||
445 | if subKey.Sig.SigType != packet.SigTypeSubkeyBinding && subKey.Sig.SigType != packet.SigTypeSubkeyRevocation { | ||
446 | return errors.StructuralError("subkey signature with wrong type") | ||
447 | } | ||
448 | err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig) | ||
449 | if err != nil { | ||
450 | return errors.StructuralError("subkey signature invalid: " + err.Error()) | ||
451 | } | ||
452 | e.Subkeys = append(e.Subkeys, subKey) | ||
453 | return nil | ||
454 | } | ||
455 | |||
456 | const defaultRSAKeyBits = 2048 | ||
457 | |||
458 | // NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a | ||
459 | // single identity composed of the given full name, comment and email, any of | ||
460 | // which may be empty but must not contain any of "()<>\x00". | ||
461 | // If config is nil, sensible defaults will be used. | ||
462 | func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) { | ||
463 | currentTime := config.Now() | ||
464 | |||
465 | bits := defaultRSAKeyBits | ||
466 | if config != nil && config.RSABits != 0 { | ||
467 | bits = config.RSABits | ||
468 | } | ||
469 | |||
470 | uid := packet.NewUserId(name, comment, email) | ||
471 | if uid == nil { | ||
472 | return nil, errors.InvalidArgumentError("user id field contained invalid characters") | ||
473 | } | ||
474 | signingPriv, err := rsa.GenerateKey(config.Random(), bits) | ||
475 | if err != nil { | ||
476 | return nil, err | ||
477 | } | ||
478 | encryptingPriv, err := rsa.GenerateKey(config.Random(), bits) | ||
479 | if err != nil { | ||
480 | return nil, err | ||
481 | } | ||
482 | |||
483 | e := &Entity{ | ||
484 | PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey), | ||
485 | PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv), | ||
486 | Identities: make(map[string]*Identity), | ||
487 | } | ||
488 | isPrimaryId := true | ||
489 | e.Identities[uid.Id] = &Identity{ | ||
490 | Name: uid.Name, | ||
491 | UserId: uid, | ||
492 | SelfSignature: &packet.Signature{ | ||
493 | CreationTime: currentTime, | ||
494 | SigType: packet.SigTypePositiveCert, | ||
495 | PubKeyAlgo: packet.PubKeyAlgoRSA, | ||
496 | Hash: config.Hash(), | ||
497 | IsPrimaryId: &isPrimaryId, | ||
498 | FlagsValid: true, | ||
499 | FlagSign: true, | ||
500 | FlagCertify: true, | ||
501 | IssuerKeyId: &e.PrimaryKey.KeyId, | ||
502 | }, | ||
503 | } | ||
504 | |||
505 | // If the user passes in a DefaultHash via packet.Config, | ||
506 | // set the PreferredHash for the SelfSignature. | ||
507 | if config != nil && config.DefaultHash != 0 { | ||
508 | e.Identities[uid.Id].SelfSignature.PreferredHash = []uint8{hashToHashId(config.DefaultHash)} | ||
509 | } | ||
510 | |||
511 | e.Subkeys = make([]Subkey, 1) | ||
512 | e.Subkeys[0] = Subkey{ | ||
513 | PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey), | ||
514 | PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv), | ||
515 | Sig: &packet.Signature{ | ||
516 | CreationTime: currentTime, | ||
517 | SigType: packet.SigTypeSubkeyBinding, | ||
518 | PubKeyAlgo: packet.PubKeyAlgoRSA, | ||
519 | Hash: config.Hash(), | ||
520 | FlagsValid: true, | ||
521 | FlagEncryptStorage: true, | ||
522 | FlagEncryptCommunications: true, | ||
523 | IssuerKeyId: &e.PrimaryKey.KeyId, | ||
524 | }, | ||
525 | } | ||
526 | e.Subkeys[0].PublicKey.IsSubkey = true | ||
527 | e.Subkeys[0].PrivateKey.IsSubkey = true | ||
528 | |||
529 | return e, nil | ||
530 | } | ||
531 | |||
532 | // SerializePrivate serializes an Entity, including private key material, to | ||
533 | // the given Writer. For now, it must only be used on an Entity returned from | ||
534 | // NewEntity. | ||
535 | // If config is nil, sensible defaults will be used. | ||
536 | func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) { | ||
537 | err = e.PrivateKey.Serialize(w) | ||
538 | if err != nil { | ||
539 | return | ||
540 | } | ||
541 | for _, ident := range e.Identities { | ||
542 | err = ident.UserId.Serialize(w) | ||
543 | if err != nil { | ||
544 | return | ||
545 | } | ||
546 | err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config) | ||
547 | if err != nil { | ||
548 | return | ||
549 | } | ||
550 | err = ident.SelfSignature.Serialize(w) | ||
551 | if err != nil { | ||
552 | return | ||
553 | } | ||
554 | } | ||
555 | for _, subkey := range e.Subkeys { | ||
556 | err = subkey.PrivateKey.Serialize(w) | ||
557 | if err != nil { | ||
558 | return | ||
559 | } | ||
560 | err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config) | ||
561 | if err != nil { | ||
562 | return | ||
563 | } | ||
564 | err = subkey.Sig.Serialize(w) | ||
565 | if err != nil { | ||
566 | return | ||
567 | } | ||
568 | } | ||
569 | return nil | ||
570 | } | ||
571 | |||
572 | // Serialize writes the public part of the given Entity to w. (No private | ||
573 | // key material will be output). | ||
574 | func (e *Entity) Serialize(w io.Writer) error { | ||
575 | err := e.PrimaryKey.Serialize(w) | ||
576 | if err != nil { | ||
577 | return err | ||
578 | } | ||
579 | for _, ident := range e.Identities { | ||
580 | err = ident.UserId.Serialize(w) | ||
581 | if err != nil { | ||
582 | return err | ||
583 | } | ||
584 | err = ident.SelfSignature.Serialize(w) | ||
585 | if err != nil { | ||
586 | return err | ||
587 | } | ||
588 | for _, sig := range ident.Signatures { | ||
589 | err = sig.Serialize(w) | ||
590 | if err != nil { | ||
591 | return err | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | for _, subkey := range e.Subkeys { | ||
596 | err = subkey.PublicKey.Serialize(w) | ||
597 | if err != nil { | ||
598 | return err | ||
599 | } | ||
600 | err = subkey.Sig.Serialize(w) | ||
601 | if err != nil { | ||
602 | return err | ||
603 | } | ||
604 | } | ||
605 | return nil | ||
606 | } | ||
607 | |||
608 | // SignIdentity adds a signature to e, from signer, attesting that identity is | ||
609 | // associated with e. The provided identity must already be an element of | ||
610 | // e.Identities and the private key of signer must have been decrypted if | ||
611 | // necessary. | ||
612 | // If config is nil, sensible defaults will be used. | ||
613 | func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error { | ||
614 | if signer.PrivateKey == nil { | ||
615 | return errors.InvalidArgumentError("signing Entity must have a private key") | ||
616 | } | ||
617 | if signer.PrivateKey.Encrypted { | ||
618 | return errors.InvalidArgumentError("signing Entity's private key must be decrypted") | ||
619 | } | ||
620 | ident, ok := e.Identities[identity] | ||
621 | if !ok { | ||
622 | return errors.InvalidArgumentError("given identity string not found in Entity") | ||
623 | } | ||
624 | |||
625 | sig := &packet.Signature{ | ||
626 | SigType: packet.SigTypeGenericCert, | ||
627 | PubKeyAlgo: signer.PrivateKey.PubKeyAlgo, | ||
628 | Hash: config.Hash(), | ||
629 | CreationTime: config.Now(), | ||
630 | IssuerKeyId: &signer.PrivateKey.KeyId, | ||
631 | } | ||
632 | if err := sig.SignUserId(identity, e.PrimaryKey, signer.PrivateKey, config); err != nil { | ||
633 | return err | ||
634 | } | ||
635 | ident.Signatures = append(ident.Signatures, sig) | ||
636 | return nil | ||
637 | } | ||