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 5package openpgp 6 7import ( 8 goerrors "errors" 9 "io" 10 "time" 11 12 "github.com/ProtonMail/go-crypto/openpgp/armor" 13 "github.com/ProtonMail/go-crypto/openpgp/errors" 14 "github.com/ProtonMail/go-crypto/openpgp/packet" 15) 16 17// PublicKeyType is the armor type for a PGP public key. 18var PublicKeyType = "PGP PUBLIC KEY BLOCK" 19 20// PrivateKeyType is the armor type for a PGP private key. 21var 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. 26type 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. 36type 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 Revocations []*packet.Signature 41 Signatures []*packet.Signature // all (potentially unverified) self-signatures, revocations, and third-party signatures 42} 43 44// A Subkey is an additional public key in an Entity. Subkeys can be used for 45// encryption. 46type Subkey struct { 47 PublicKey *packet.PublicKey 48 PrivateKey *packet.PrivateKey 49 Sig *packet.Signature 50 Revocations []*packet.Signature 51} 52 53// A Key identifies a specific public key in an Entity. This is either the 54// Entity's primary key or a subkey. 55type Key struct { 56 Entity *Entity 57 PublicKey *packet.PublicKey 58 PrivateKey *packet.PrivateKey 59 SelfSignature *packet.Signature 60 Revocations []*packet.Signature 61} 62 63// A KeyRing provides access to public and private keys. 64type KeyRing interface { 65 // KeysById returns the set of keys that have the given key id. 66 KeysById(id uint64) []Key 67 // KeysByIdAndUsage returns the set of keys with the given id 68 // that also meet the key usage given by requiredUsage. 69 // The requiredUsage is expressed as the bitwise-OR of 70 // packet.KeyFlag* values. 71 KeysByIdUsage(id uint64, requiredUsage byte) []Key 72 // DecryptionKeys returns all private keys that are valid for 73 // decryption. 74 DecryptionKeys() []Key 75} 76 77// PrimaryIdentity returns an Identity, preferring non-revoked identities, 78// identities marked as primary, or the latest-created identity, in that order. 79func (e *Entity) PrimaryIdentity() *Identity { 80 var primaryIdentity *Identity 81 for _, ident := range e.Identities { 82 if shouldPreferIdentity(primaryIdentity, ident) { 83 primaryIdentity = ident 84 } 85 } 86 return primaryIdentity 87} 88 89func shouldPreferIdentity(existingId, potentialNewId *Identity) bool { 90 if (existingId == nil) { 91 return true 92 } 93 94 if (len(existingId.Revocations) > len(potentialNewId.Revocations)) { 95 return true 96 } 97 98 if (len(existingId.Revocations) < len(potentialNewId.Revocations)) { 99 return false 100 } 101 102 if (existingId.SelfSignature.IsPrimaryId != nil && *existingId.SelfSignature.IsPrimaryId && 103 !(potentialNewId.SelfSignature.IsPrimaryId != nil && *potentialNewId.SelfSignature.IsPrimaryId)) { 104 return false 105 } 106 107 if (!(existingId.SelfSignature.IsPrimaryId != nil && *existingId.SelfSignature.IsPrimaryId) && 108 potentialNewId.SelfSignature.IsPrimaryId != nil && *potentialNewId.SelfSignature.IsPrimaryId) { 109 return true 110 } 111 112 return potentialNewId.SelfSignature.CreationTime.After(existingId.SelfSignature.CreationTime) 113} 114 115// EncryptionKey returns the best candidate Key for encrypting a message to the 116// given Entity. 117func (e *Entity) EncryptionKey(now time.Time) (Key, bool) { 118 // Fail to find any encryption key if the... 119 i := e.PrimaryIdentity() 120 if e.PrimaryKey.KeyExpired(i.SelfSignature, now) || // primary key has expired 121 i.SelfSignature.SigExpired(now) || // user ID self-signature has expired 122 e.Revoked(now) || // primary key has been revoked 123 i.Revoked(now) { // user ID has been revoked 124 return Key{}, false 125 } 126 127 // Iterate the keys to find the newest, unexpired one 128 candidateSubkey := -1 129 var maxTime time.Time 130 for i, subkey := range e.Subkeys { 131 if subkey.Sig.FlagsValid && 132 subkey.Sig.FlagEncryptCommunications && 133 subkey.PublicKey.PubKeyAlgo.CanEncrypt() && 134 !subkey.PublicKey.KeyExpired(subkey.Sig, now) && 135 !subkey.Sig.SigExpired(now) && 136 !subkey.Revoked(now) && 137 (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) { 138 candidateSubkey = i 139 maxTime = subkey.Sig.CreationTime 140 } 141 } 142 143 if candidateSubkey != -1 { 144 subkey := e.Subkeys[candidateSubkey] 145 return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true 146 } 147 148 // If we don't have any candidate subkeys for encryption and 149 // the primary key doesn't have any usage metadata then we 150 // assume that the primary key is ok. Or, if the primary key is 151 // marked as ok to encrypt with, then we can obviously use it. 152 if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications && 153 e.PrimaryKey.PubKeyAlgo.CanEncrypt() { 154 return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature, e.Revocations}, true 155 } 156 157 return Key{}, false 158} 159 160// SigningKey return the best candidate Key for signing a message with this 161// Entity. 162func (e *Entity) SigningKey(now time.Time) (Key, bool) { 163 return e.SigningKeyById(now, 0) 164} 165 166// SigningKeyById return the Key for signing a message with this 167// Entity and keyID. 168func (e *Entity) SigningKeyById(now time.Time, id uint64) (Key, bool) { 169 // Fail to find any signing key if the... 170 i := e.PrimaryIdentity() 171 if e.PrimaryKey.KeyExpired(i.SelfSignature, now) || // primary key has expired 172 i.SelfSignature.SigExpired(now) || // user ID self-signature has expired 173 e.Revoked(now) || // primary key has been revoked 174 i.Revoked(now) { // user ID has been revoked 175 return Key{}, false 176 } 177 178 // Iterate the keys to find the newest, unexpired one 179 candidateSubkey := -1 180 var maxTime time.Time 181 for idx, subkey := range e.Subkeys { 182 if subkey.Sig.FlagsValid && 183 subkey.Sig.FlagSign && 184 subkey.PublicKey.PubKeyAlgo.CanSign() && 185 !subkey.PublicKey.KeyExpired(subkey.Sig, now) && 186 !subkey.Sig.SigExpired(now) && 187 !subkey.Revoked(now) && 188 (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) && 189 (id == 0 || subkey.PublicKey.KeyId == id) { 190 candidateSubkey = idx 191 maxTime = subkey.Sig.CreationTime 192 } 193 } 194 195 if candidateSubkey != -1 { 196 subkey := e.Subkeys[candidateSubkey] 197 return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true 198 } 199 200 // If we have no candidate subkey then we assume that it's ok to sign 201 // with the primary key. Or, if the primary key is marked as ok to 202 // sign with, then we can use it. 203 if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagSign && 204 e.PrimaryKey.PubKeyAlgo.CanSign() && 205 (id == 0 || e.PrimaryKey.KeyId == id) { 206 return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature, e.Revocations}, true 207 } 208 209 // No keys with a valid Signing Flag or no keys matched the id passed in 210 return Key{}, false 211} 212 213func revoked(revocations []*packet.Signature, now time.Time) bool { 214 for _, revocation := range revocations { 215 if revocation.RevocationReason != nil && *revocation.RevocationReason == packet.KeyCompromised { 216 // If the key is compromised, the key is considered revoked even before the revocation date. 217 return true 218 } 219 if !revocation.SigExpired(now) { 220 return true 221 } 222 } 223 return false 224} 225 226// Revoked returns whether the entity has any direct key revocation signatures. 227// Note that third-party revocation signatures are not supported. 228// Note also that Identity and Subkey revocation should be checked separately. 229func (e *Entity) Revoked(now time.Time) bool { 230 return revoked(e.Revocations, now) 231} 232 233// Revoked returns whether the identity has been revoked by a self-signature. 234// Note that third-party revocation signatures are not supported. 235func (i *Identity) Revoked(now time.Time) bool { 236 return revoked(i.Revocations, now) 237} 238 239// Revoked returns whether the subkey has been revoked by a self-signature. 240// Note that third-party revocation signatures are not supported. 241func (s *Subkey) Revoked(now time.Time) bool { 242 return revoked(s.Revocations, now) 243} 244 245// Revoked returns whether the key or subkey has been revoked by a self-signature. 246// Note that third-party revocation signatures are not supported. 247// Note also that Identity revocation should be checked separately. 248// Normally, it's not necessary to call this function, except on keys returned by 249// KeysById or KeysByIdUsage. 250func (key *Key) Revoked(now time.Time) bool { 251 return revoked(key.Revocations, now) 252} 253 254// An EntityList contains one or more Entities. 255type EntityList []*Entity 256 257// KeysById returns the set of keys that have the given key id. 258func (el EntityList) KeysById(id uint64) (keys []Key) { 259 for _, e := range el { 260 if e.PrimaryKey.KeyId == id { 261 ident := e.PrimaryIdentity() 262 selfSig := ident.SelfSignature 263 keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig, e.Revocations}) 264 } 265 266 for _, subKey := range e.Subkeys { 267 if subKey.PublicKey.KeyId == id { 268 keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations}) 269 } 270 } 271 } 272 return 273} 274 275// KeysByIdAndUsage returns the set of keys with the given id that also meet 276// the key usage given by requiredUsage. The requiredUsage is expressed as 277// the bitwise-OR of packet.KeyFlag* values. 278func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) { 279 for _, key := range el.KeysById(id) { 280 if key.SelfSignature.FlagsValid && requiredUsage != 0 { 281 var usage byte 282 if key.SelfSignature.FlagCertify { 283 usage |= packet.KeyFlagCertify 284 } 285 if key.SelfSignature.FlagSign { 286 usage |= packet.KeyFlagSign 287 } 288 if key.SelfSignature.FlagEncryptCommunications { 289 usage |= packet.KeyFlagEncryptCommunications 290 } 291 if key.SelfSignature.FlagEncryptStorage { 292 usage |= packet.KeyFlagEncryptStorage 293 } 294 if usage&requiredUsage != requiredUsage { 295 continue 296 } 297 } 298 299 keys = append(keys, key) 300 } 301 return 302} 303 304// DecryptionKeys returns all private keys that are valid for decryption. 305func (el EntityList) DecryptionKeys() (keys []Key) { 306 for _, e := range el { 307 for _, subKey := range e.Subkeys { 308 if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) { 309 keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations}) 310 } 311 } 312 } 313 return 314} 315 316// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file. 317func ReadArmoredKeyRing(r io.Reader) (EntityList, error) { 318 block, err := armor.Decode(r) 319 if err == io.EOF { 320 return nil, errors.InvalidArgumentError("no armored data found") 321 } 322 if err != nil { 323 return nil, err 324 } 325 if block.Type != PublicKeyType && block.Type != PrivateKeyType { 326 return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type) 327 } 328 329 return ReadKeyRing(block.Body) 330} 331 332// ReadKeyRing reads one or more public/private keys. Unsupported keys are 333// ignored as long as at least a single valid key is found. 334func ReadKeyRing(r io.Reader) (el EntityList, err error) { 335 packets := packet.NewReader(r) 336 var lastUnsupportedError error 337 338 for { 339 var e *Entity 340 e, err = ReadEntity(packets) 341 if err != nil { 342 // TODO: warn about skipped unsupported/unreadable keys 343 if _, ok := err.(errors.UnsupportedError); ok { 344 lastUnsupportedError = err 345 err = readToNextPublicKey(packets) 346 } else if _, ok := err.(errors.StructuralError); ok { 347 // Skip unreadable, badly-formatted keys 348 lastUnsupportedError = err 349 err = readToNextPublicKey(packets) 350 } 351 if err == io.EOF { 352 err = nil 353 break 354 } 355 if err != nil { 356 el = nil 357 break 358 } 359 } else { 360 el = append(el, e) 361 } 362 } 363 364 if len(el) == 0 && err == nil { 365 err = lastUnsupportedError 366 } 367 return 368} 369 370// readToNextPublicKey reads packets until the start of the entity and leaves 371// the first packet of the new entity in the Reader. 372func readToNextPublicKey(packets *packet.Reader) (err error) { 373 var p packet.Packet 374 for { 375 p, err = packets.Next() 376 if err == io.EOF { 377 return 378 } else if err != nil { 379 if _, ok := err.(errors.UnsupportedError); ok { 380 err = nil 381 continue 382 } 383 return 384 } 385 386 if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey { 387 packets.Unread(p) 388 return 389 } 390 } 391} 392 393// ReadEntity reads an entity (public key, identities, subkeys etc) from the 394// given Reader. 395func ReadEntity(packets *packet.Reader) (*Entity, error) { 396 e := new(Entity) 397 e.Identities = make(map[string]*Identity) 398 399 p, err := packets.Next() 400 if err != nil { 401 return nil, err 402 } 403 404 var ok bool 405 if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok { 406 if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok { 407 packets.Unread(p) 408 return nil, errors.StructuralError("first packet was not a public/private key") 409 } 410 e.PrimaryKey = &e.PrivateKey.PublicKey 411 } 412 413 if !e.PrimaryKey.PubKeyAlgo.CanSign() { 414 return nil, errors.StructuralError("primary key cannot be used for signatures") 415 } 416 417 var revocations []*packet.Signature 418EachPacket: 419 for { 420 p, err := packets.Next() 421 if err == io.EOF { 422 break 423 } else if err != nil { 424 return nil, err 425 } 426 427 switch pkt := p.(type) { 428 case *packet.UserId: 429 if err := addUserID(e, packets, pkt); err != nil { 430 return nil, err 431 } 432 case *packet.Signature: 433 if pkt.SigType == packet.SigTypeKeyRevocation { 434 revocations = append(revocations, pkt) 435 } else if pkt.SigType == packet.SigTypeDirectSignature { 436 // TODO: RFC4880 5.2.1 permits signatures 437 // directly on keys (eg. to bind additional 438 // revocation keys). 439 } 440 // Else, ignoring the signature as it does not follow anything 441 // we would know to attach it to. 442 case *packet.PrivateKey: 443 if pkt.IsSubkey == false { 444 packets.Unread(p) 445 break EachPacket 446 } 447 err = addSubkey(e, packets, &pkt.PublicKey, pkt) 448 if err != nil { 449 return nil, err 450 } 451 case *packet.PublicKey: 452 if pkt.IsSubkey == false { 453 packets.Unread(p) 454 break EachPacket 455 } 456 err = addSubkey(e, packets, pkt, nil) 457 if err != nil { 458 return nil, err 459 } 460 default: 461 // we ignore unknown packets 462 } 463 } 464 465 if len(e.Identities) == 0 { 466 return nil, errors.StructuralError("entity without any identities") 467 } 468 469 for _, revocation := range revocations { 470 err = e.PrimaryKey.VerifyRevocationSignature(revocation) 471 if err == nil { 472 e.Revocations = append(e.Revocations, revocation) 473 } else { 474 // TODO: RFC 4880 5.2.3.15 defines revocation keys. 475 return nil, errors.StructuralError("revocation signature signed by alternate key") 476 } 477 } 478 479 return e, nil 480} 481 482func addUserID(e *Entity, packets *packet.Reader, pkt *packet.UserId) error { 483 // Make a new Identity object, that we might wind up throwing away. 484 // We'll only add it if we get a valid self-signature over this 485 // userID. 486 identity := new(Identity) 487 identity.Name = pkt.Id 488 identity.UserId = pkt 489 490 for { 491 p, err := packets.Next() 492 if err == io.EOF { 493 break 494 } else if err != nil { 495 return err 496 } 497 498 sig, ok := p.(*packet.Signature) 499 if !ok { 500 packets.Unread(p) 501 break 502 } 503 504 if sig.SigType != packet.SigTypeGenericCert && 505 sig.SigType != packet.SigTypePersonaCert && 506 sig.SigType != packet.SigTypeCasualCert && 507 sig.SigType != packet.SigTypePositiveCert && 508 sig.SigType != packet.SigTypeCertificationRevocation { 509 return errors.StructuralError("user ID signature with wrong type") 510 } 511 512 513 if sig.CheckKeyIdOrFingerprint(e.PrimaryKey) { 514 if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil { 515 return errors.StructuralError("user ID self-signature invalid: " + err.Error()) 516 } 517 if sig.SigType == packet.SigTypeCertificationRevocation { 518 identity.Revocations = append(identity.Revocations, sig) 519 } else if identity.SelfSignature == nil || sig.CreationTime.After(identity.SelfSignature.CreationTime) { 520 identity.SelfSignature = sig 521 } 522 identity.Signatures = append(identity.Signatures, sig) 523 e.Identities[pkt.Id] = identity 524 } else { 525 identity.Signatures = append(identity.Signatures, sig) 526 } 527 } 528 529 return nil 530} 531 532func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error { 533 var subKey Subkey 534 subKey.PublicKey = pub 535 subKey.PrivateKey = priv 536 537 for { 538 p, err := packets.Next() 539 if err == io.EOF { 540 break 541 } else if err != nil { 542 return errors.StructuralError("subkey signature invalid: " + err.Error()) 543 } 544 545 sig, ok := p.(*packet.Signature) 546 if !ok { 547 packets.Unread(p) 548 break 549 } 550 551 if sig.SigType != packet.SigTypeSubkeyBinding && sig.SigType != packet.SigTypeSubkeyRevocation { 552 return errors.StructuralError("subkey signature with wrong type") 553 } 554 555 if err := e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, sig); err != nil { 556 return errors.StructuralError("subkey signature invalid: " + err.Error()) 557 } 558 559 switch sig.SigType { 560 case packet.SigTypeSubkeyRevocation: 561 subKey.Revocations = append(subKey.Revocations, sig) 562 case packet.SigTypeSubkeyBinding: 563 if subKey.Sig == nil || sig.CreationTime.After(subKey.Sig.CreationTime) { 564 subKey.Sig = sig 565 } 566 } 567 } 568 569 if subKey.Sig == nil { 570 return errors.StructuralError("subkey packet not followed by signature") 571 } 572 573 e.Subkeys = append(e.Subkeys, subKey) 574 575 return nil 576} 577 578// SerializePrivate serializes an Entity, including private key material, but 579// excluding signatures from other entities, to the given Writer. 580// Identities and subkeys are re-signed in case they changed since NewEntry. 581// If config is nil, sensible defaults will be used. 582func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) { 583 if e.PrivateKey.Dummy() { 584 return errors.ErrDummyPrivateKey("dummy private key cannot re-sign identities") 585 } 586 return e.serializePrivate(w, config, true) 587} 588 589// SerializePrivateWithoutSigning serializes an Entity, including private key 590// material, but excluding signatures from other entities, to the given Writer. 591// Self-signatures of identities and subkeys are not re-signed. This is useful 592// when serializing GNU dummy keys, among other things. 593// If config is nil, sensible defaults will be used. 594func (e *Entity) SerializePrivateWithoutSigning(w io.Writer, config *packet.Config) (err error) { 595 return e.serializePrivate(w, config, false) 596} 597 598func (e *Entity) serializePrivate(w io.Writer, config *packet.Config, reSign bool) (err error) { 599 if e.PrivateKey == nil { 600 return goerrors.New("openpgp: private key is missing") 601 } 602 err = e.PrivateKey.Serialize(w) 603 if err != nil { 604 return 605 } 606 for _, revocation := range e.Revocations { 607 err := revocation.Serialize(w) 608 if err != nil { 609 return err 610 } 611 } 612 for _, ident := range e.Identities { 613 err = ident.UserId.Serialize(w) 614 if err != nil { 615 return 616 } 617 if reSign { 618 err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config) 619 if err != nil { 620 return 621 } 622 } 623 for _, revocation := range ident.Revocations { 624 err := revocation.Serialize(w) 625 if err != nil { 626 return err 627 } 628 } 629 err = ident.SelfSignature.Serialize(w) 630 if err != nil { 631 return 632 } 633 } 634 for _, subkey := range e.Subkeys { 635 err = subkey.PrivateKey.Serialize(w) 636 if err != nil { 637 return 638 } 639 if reSign { 640 err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config) 641 if err != nil { 642 return 643 } 644 if subkey.Sig.EmbeddedSignature != nil { 645 err = subkey.Sig.EmbeddedSignature.CrossSignKey(subkey.PublicKey, e.PrimaryKey, 646 subkey.PrivateKey, config) 647 if err != nil { 648 return 649 } 650 } 651 } 652 for _, revocation := range subkey.Revocations { 653 err := revocation.Serialize(w) 654 if err != nil { 655 return err 656 } 657 } 658 err = subkey.Sig.Serialize(w) 659 if err != nil { 660 return 661 } 662 } 663 return nil 664} 665 666// Serialize writes the public part of the given Entity to w, including 667// signatures from other entities. No private key material will be output. 668func (e *Entity) Serialize(w io.Writer) error { 669 err := e.PrimaryKey.Serialize(w) 670 if err != nil { 671 return err 672 } 673 for _, revocation := range e.Revocations { 674 err := revocation.Serialize(w) 675 if err != nil { 676 return err 677 } 678 } 679 for _, ident := range e.Identities { 680 err = ident.UserId.Serialize(w) 681 if err != nil { 682 return err 683 } 684 for _, sig := range ident.Signatures { 685 err = sig.Serialize(w) 686 if err != nil { 687 return err 688 } 689 } 690 } 691 for _, subkey := range e.Subkeys { 692 err = subkey.PublicKey.Serialize(w) 693 if err != nil { 694 return err 695 } 696 for _, revocation := range subkey.Revocations { 697 err := revocation.Serialize(w) 698 if err != nil { 699 return err 700 } 701 } 702 err = subkey.Sig.Serialize(w) 703 if err != nil { 704 return err 705 } 706 } 707 return nil 708} 709 710// SignIdentity adds a signature to e, from signer, attesting that identity is 711// associated with e. The provided identity must already be an element of 712// e.Identities and the private key of signer must have been decrypted if 713// necessary. 714// If config is nil, sensible defaults will be used. 715func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error { 716 if signer.PrivateKey == nil { 717 return errors.InvalidArgumentError("signing Entity must have a private key") 718 } 719 if signer.PrivateKey.Encrypted { 720 return errors.InvalidArgumentError("signing Entity's private key must be decrypted") 721 } 722 ident, ok := e.Identities[identity] 723 if !ok { 724 return errors.InvalidArgumentError("given identity string not found in Entity") 725 } 726 727 sig := &packet.Signature{ 728 Version: signer.PrivateKey.Version, 729 SigType: packet.SigTypeGenericCert, 730 PubKeyAlgo: signer.PrivateKey.PubKeyAlgo, 731 Hash: config.Hash(), 732 CreationTime: config.Now(), 733 IssuerKeyId: &signer.PrivateKey.KeyId, 734 } 735 if err := sig.SignUserId(identity, e.PrimaryKey, signer.PrivateKey, config); err != nil { 736 return err 737 } 738 ident.Signatures = append(ident.Signatures, sig) 739 return nil 740} 741 742// RevokeKey generates a key revocation signature (packet.SigTypeKeyRevocation) with the 743// specified reason code and text (RFC4880 section-5.2.3.23). 744// If config is nil, sensible defaults will be used. 745func (e *Entity) RevokeKey(reason packet.ReasonForRevocation, reasonText string, config *packet.Config) error { 746 revSig := &packet.Signature{ 747 Version: e.PrimaryKey.Version, 748 CreationTime: config.Now(), 749 SigType: packet.SigTypeKeyRevocation, 750 PubKeyAlgo: e.PrimaryKey.PubKeyAlgo, 751 Hash: config.Hash(), 752 RevocationReason: &reason, 753 RevocationReasonText: reasonText, 754 IssuerKeyId: &e.PrimaryKey.KeyId, 755 } 756 757 if err := revSig.RevokeKey(e.PrimaryKey, e.PrivateKey, config); err != nil { 758 return err 759 } 760 e.Revocations = append(e.Revocations, revSig) 761 return nil 762} 763 764// RevokeSubkey generates a subkey revocation signature (packet.SigTypeSubkeyRevocation) for 765// a subkey with the specified reason code and text (RFC4880 section-5.2.3.23). 766// If config is nil, sensible defaults will be used. 767func (e *Entity) RevokeSubkey(sk *Subkey, reason packet.ReasonForRevocation, reasonText string, config *packet.Config) error { 768 if err := e.PrimaryKey.VerifyKeySignature(sk.PublicKey, sk.Sig); err != nil { 769 return errors.InvalidArgumentError("given subkey is not associated with this key") 770 } 771 772 revSig := &packet.Signature{ 773 Version: e.PrimaryKey.Version, 774 CreationTime: config.Now(), 775 SigType: packet.SigTypeSubkeyRevocation, 776 PubKeyAlgo: e.PrimaryKey.PubKeyAlgo, 777 Hash: config.Hash(), 778 RevocationReason: &reason, 779 RevocationReasonText: reasonText, 780 IssuerKeyId: &e.PrimaryKey.KeyId, 781 } 782 783 if err := revSig.RevokeSubkey(sk.PublicKey, e.PrivateKey, config); err != nil { 784 return err 785 } 786 787 sk.Revocations = append(sk.Revocations, revSig) 788 return nil 789} 790