OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / golang.org / x / crypto / openpgp / keys.go
diff --git a/vendor/golang.org/x/crypto/openpgp/keys.go b/vendor/golang.org/x/crypto/openpgp/keys.go
new file mode 100644 (file)
index 0000000..68b14c6
--- /dev/null
@@ -0,0 +1,637 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package openpgp
+
+import (
+       "crypto/rsa"
+       "io"
+       "time"
+
+       "golang.org/x/crypto/openpgp/armor"
+       "golang.org/x/crypto/openpgp/errors"
+       "golang.org/x/crypto/openpgp/packet"
+)
+
+// PublicKeyType is the armor type for a PGP public key.
+var PublicKeyType = "PGP PUBLIC KEY BLOCK"
+
+// PrivateKeyType is the armor type for a PGP private key.
+var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
+
+// An Entity represents the components of an OpenPGP key: a primary public key
+// (which must be a signing key), one or more identities claimed by that key,
+// and zero or more subkeys, which may be encryption keys.
+type Entity struct {
+       PrimaryKey  *packet.PublicKey
+       PrivateKey  *packet.PrivateKey
+       Identities  map[string]*Identity // indexed by Identity.Name
+       Revocations []*packet.Signature
+       Subkeys     []Subkey
+}
+
+// An Identity represents an identity claimed by an Entity and zero or more
+// assertions by other entities about that claim.
+type Identity struct {
+       Name          string // by convention, has the form "Full Name (comment) <email@example.com>"
+       UserId        *packet.UserId
+       SelfSignature *packet.Signature
+       Signatures    []*packet.Signature
+}
+
+// A Subkey is an additional public key in an Entity. Subkeys can be used for
+// encryption.
+type Subkey struct {
+       PublicKey  *packet.PublicKey
+       PrivateKey *packet.PrivateKey
+       Sig        *packet.Signature
+}
+
+// A Key identifies a specific public key in an Entity. This is either the
+// Entity's primary key or a subkey.
+type Key struct {
+       Entity        *Entity
+       PublicKey     *packet.PublicKey
+       PrivateKey    *packet.PrivateKey
+       SelfSignature *packet.Signature
+}
+
+// A KeyRing provides access to public and private keys.
+type KeyRing interface {
+       // KeysById returns the set of keys that have the given key id.
+       KeysById(id uint64) []Key
+       // KeysByIdAndUsage returns the set of keys with the given id
+       // that also meet the key usage given by requiredUsage.
+       // The requiredUsage is expressed as the bitwise-OR of
+       // packet.KeyFlag* values.
+       KeysByIdUsage(id uint64, requiredUsage byte) []Key
+       // DecryptionKeys returns all private keys that are valid for
+       // decryption.
+       DecryptionKeys() []Key
+}
+
+// primaryIdentity returns the Identity marked as primary or the first identity
+// if none are so marked.
+func (e *Entity) primaryIdentity() *Identity {
+       var firstIdentity *Identity
+       for _, ident := range e.Identities {
+               if firstIdentity == nil {
+                       firstIdentity = ident
+               }
+               if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
+                       return ident
+               }
+       }
+       return firstIdentity
+}
+
+// encryptionKey returns the best candidate Key for encrypting a message to the
+// given Entity.
+func (e *Entity) encryptionKey(now time.Time) (Key, bool) {
+       candidateSubkey := -1
+
+       // Iterate the keys to find the newest key
+       var maxTime time.Time
+       for i, subkey := range e.Subkeys {
+               if subkey.Sig.FlagsValid &&
+                       subkey.Sig.FlagEncryptCommunications &&
+                       subkey.PublicKey.PubKeyAlgo.CanEncrypt() &&
+                       !subkey.Sig.KeyExpired(now) &&
+                       (maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) {
+                       candidateSubkey = i
+                       maxTime = subkey.Sig.CreationTime
+               }
+       }
+
+       if candidateSubkey != -1 {
+               subkey := e.Subkeys[candidateSubkey]
+               return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
+       }
+
+       // If we don't have any candidate subkeys for encryption and
+       // the primary key doesn't have any usage metadata then we
+       // assume that the primary key is ok. Or, if the primary key is
+       // marked as ok to encrypt to, then we can obviously use it.
+       i := e.primaryIdentity()
+       if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications &&
+               e.PrimaryKey.PubKeyAlgo.CanEncrypt() &&
+               !i.SelfSignature.KeyExpired(now) {
+               return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
+       }
+
+       // This Entity appears to be signing only.
+       return Key{}, false
+}
+
+// signingKey return the best candidate Key for signing a message with this
+// Entity.
+func (e *Entity) signingKey(now time.Time) (Key, bool) {
+       candidateSubkey := -1
+
+       for i, subkey := range e.Subkeys {
+               if subkey.Sig.FlagsValid &&
+                       subkey.Sig.FlagSign &&
+                       subkey.PublicKey.PubKeyAlgo.CanSign() &&
+                       !subkey.Sig.KeyExpired(now) {
+                       candidateSubkey = i
+                       break
+               }
+       }
+
+       if candidateSubkey != -1 {
+               subkey := e.Subkeys[candidateSubkey]
+               return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
+       }
+
+       // If we have no candidate subkey then we assume that it's ok to sign
+       // with the primary key.
+       i := e.primaryIdentity()
+       if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagSign &&
+               !i.SelfSignature.KeyExpired(now) {
+               return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
+       }
+
+       return Key{}, false
+}
+
+// An EntityList contains one or more Entities.
+type EntityList []*Entity
+
+// KeysById returns the set of keys that have the given key id.
+func (el EntityList) KeysById(id uint64) (keys []Key) {
+       for _, e := range el {
+               if e.PrimaryKey.KeyId == id {
+                       var selfSig *packet.Signature
+                       for _, ident := range e.Identities {
+                               if selfSig == nil {
+                                       selfSig = ident.SelfSignature
+                               } else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
+                                       selfSig = ident.SelfSignature
+                                       break
+                               }
+                       }
+                       keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig})
+               }
+
+               for _, subKey := range e.Subkeys {
+                       if subKey.PublicKey.KeyId == id {
+                               keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
+                       }
+               }
+       }
+       return
+}
+
+// KeysByIdAndUsage returns the set of keys with the given id that also meet
+// the key usage given by requiredUsage.  The requiredUsage is expressed as
+// the bitwise-OR of packet.KeyFlag* values.
+func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) {
+       for _, key := range el.KeysById(id) {
+               if len(key.Entity.Revocations) > 0 {
+                       continue
+               }
+
+               if key.SelfSignature.RevocationReason != nil {
+                       continue
+               }
+
+               if key.SelfSignature.FlagsValid && requiredUsage != 0 {
+                       var usage byte
+                       if key.SelfSignature.FlagCertify {
+                               usage |= packet.KeyFlagCertify
+                       }
+                       if key.SelfSignature.FlagSign {
+                               usage |= packet.KeyFlagSign
+                       }
+                       if key.SelfSignature.FlagEncryptCommunications {
+                               usage |= packet.KeyFlagEncryptCommunications
+                       }
+                       if key.SelfSignature.FlagEncryptStorage {
+                               usage |= packet.KeyFlagEncryptStorage
+                       }
+                       if usage&requiredUsage != requiredUsage {
+                               continue
+                       }
+               }
+
+               keys = append(keys, key)
+       }
+       return
+}
+
+// DecryptionKeys returns all private keys that are valid for decryption.
+func (el EntityList) DecryptionKeys() (keys []Key) {
+       for _, e := range el {
+               for _, subKey := range e.Subkeys {
+                       if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
+                               keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
+                       }
+               }
+       }
+       return
+}
+
+// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
+func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
+       block, err := armor.Decode(r)
+       if err == io.EOF {
+               return nil, errors.InvalidArgumentError("no armored data found")
+       }
+       if err != nil {
+               return nil, err
+       }
+       if block.Type != PublicKeyType && block.Type != PrivateKeyType {
+               return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type)
+       }
+
+       return ReadKeyRing(block.Body)
+}
+
+// ReadKeyRing reads one or more public/private keys. Unsupported keys are
+// ignored as long as at least a single valid key is found.
+func ReadKeyRing(r io.Reader) (el EntityList, err error) {
+       packets := packet.NewReader(r)
+       var lastUnsupportedError error
+
+       for {
+               var e *Entity
+               e, err = ReadEntity(packets)
+               if err != nil {
+                       // TODO: warn about skipped unsupported/unreadable keys
+                       if _, ok := err.(errors.UnsupportedError); ok {
+                               lastUnsupportedError = err
+                               err = readToNextPublicKey(packets)
+                       } else if _, ok := err.(errors.StructuralError); ok {
+                               // Skip unreadable, badly-formatted keys
+                               lastUnsupportedError = err
+                               err = readToNextPublicKey(packets)
+                       }
+                       if err == io.EOF {
+                               err = nil
+                               break
+                       }
+                       if err != nil {
+                               el = nil
+                               break
+                       }
+               } else {
+                       el = append(el, e)
+               }
+       }
+
+       if len(el) == 0 && err == nil {
+               err = lastUnsupportedError
+       }
+       return
+}
+
+// readToNextPublicKey reads packets until the start of the entity and leaves
+// the first packet of the new entity in the Reader.
+func readToNextPublicKey(packets *packet.Reader) (err error) {
+       var p packet.Packet
+       for {
+               p, err = packets.Next()
+               if err == io.EOF {
+                       return
+               } else if err != nil {
+                       if _, ok := err.(errors.UnsupportedError); ok {
+                               err = nil
+                               continue
+                       }
+                       return
+               }
+
+               if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
+                       packets.Unread(p)
+                       return
+               }
+       }
+}
+
+// ReadEntity reads an entity (public key, identities, subkeys etc) from the
+// given Reader.
+func ReadEntity(packets *packet.Reader) (*Entity, error) {
+       e := new(Entity)
+       e.Identities = make(map[string]*Identity)
+
+       p, err := packets.Next()
+       if err != nil {
+               return nil, err
+       }
+
+       var ok bool
+       if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
+               if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
+                       packets.Unread(p)
+                       return nil, errors.StructuralError("first packet was not a public/private key")
+               } else {
+                       e.PrimaryKey = &e.PrivateKey.PublicKey
+               }
+       }
+
+       if !e.PrimaryKey.PubKeyAlgo.CanSign() {
+               return nil, errors.StructuralError("primary key cannot be used for signatures")
+       }
+
+       var current *Identity
+       var revocations []*packet.Signature
+EachPacket:
+       for {
+               p, err := packets.Next()
+               if err == io.EOF {
+                       break
+               } else if err != nil {
+                       return nil, err
+               }
+
+               switch pkt := p.(type) {
+               case *packet.UserId:
+                       current = new(Identity)
+                       current.Name = pkt.Id
+                       current.UserId = pkt
+                       e.Identities[pkt.Id] = current
+
+                       for {
+                               p, err = packets.Next()
+                               if err == io.EOF {
+                                       return nil, io.ErrUnexpectedEOF
+                               } else if err != nil {
+                                       return nil, err
+                               }
+
+                               sig, ok := p.(*packet.Signature)
+                               if !ok {
+                                       return nil, errors.StructuralError("user ID packet not followed by self-signature")
+                               }
+
+                               if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
+                                       if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
+                                               return nil, errors.StructuralError("user ID self-signature invalid: " + err.Error())
+                                       }
+                                       current.SelfSignature = sig
+                                       break
+                               }
+                               current.Signatures = append(current.Signatures, sig)
+                       }
+               case *packet.Signature:
+                       if pkt.SigType == packet.SigTypeKeyRevocation {
+                               revocations = append(revocations, pkt)
+                       } else if pkt.SigType == packet.SigTypeDirectSignature {
+                               // TODO: RFC4880 5.2.1 permits signatures
+                               // directly on keys (eg. to bind additional
+                               // revocation keys).
+                       } else if current == nil {
+                               return nil, errors.StructuralError("signature packet found before user id packet")
+                       } else {
+                               current.Signatures = append(current.Signatures, pkt)
+                       }
+               case *packet.PrivateKey:
+                       if pkt.IsSubkey == false {
+                               packets.Unread(p)
+                               break EachPacket
+                       }
+                       err = addSubkey(e, packets, &pkt.PublicKey, pkt)
+                       if err != nil {
+                               return nil, err
+                       }
+               case *packet.PublicKey:
+                       if pkt.IsSubkey == false {
+                               packets.Unread(p)
+                               break EachPacket
+                       }
+                       err = addSubkey(e, packets, pkt, nil)
+                       if err != nil {
+                               return nil, err
+                       }
+               default:
+                       // we ignore unknown packets
+               }
+       }
+
+       if len(e.Identities) == 0 {
+               return nil, errors.StructuralError("entity without any identities")
+       }
+
+       for _, revocation := range revocations {
+               err = e.PrimaryKey.VerifyRevocationSignature(revocation)
+               if err == nil {
+                       e.Revocations = append(e.Revocations, revocation)
+               } else {
+                       // TODO: RFC 4880 5.2.3.15 defines revocation keys.
+                       return nil, errors.StructuralError("revocation signature signed by alternate key")
+               }
+       }
+
+       return e, nil
+}
+
+func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
+       var subKey Subkey
+       subKey.PublicKey = pub
+       subKey.PrivateKey = priv
+       p, err := packets.Next()
+       if err == io.EOF {
+               return io.ErrUnexpectedEOF
+       }
+       if err != nil {
+               return errors.StructuralError("subkey signature invalid: " + err.Error())
+       }
+       var ok bool
+       subKey.Sig, ok = p.(*packet.Signature)
+       if !ok {
+               return errors.StructuralError("subkey packet not followed by signature")
+       }
+       if subKey.Sig.SigType != packet.SigTypeSubkeyBinding && subKey.Sig.SigType != packet.SigTypeSubkeyRevocation {
+               return errors.StructuralError("subkey signature with wrong type")
+       }
+       err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig)
+       if err != nil {
+               return errors.StructuralError("subkey signature invalid: " + err.Error())
+       }
+       e.Subkeys = append(e.Subkeys, subKey)
+       return nil
+}
+
+const defaultRSAKeyBits = 2048
+
+// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
+// single identity composed of the given full name, comment and email, any of
+// which may be empty but must not contain any of "()<>\x00".
+// If config is nil, sensible defaults will be used.
+func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
+       currentTime := config.Now()
+
+       bits := defaultRSAKeyBits
+       if config != nil && config.RSABits != 0 {
+               bits = config.RSABits
+       }
+
+       uid := packet.NewUserId(name, comment, email)
+       if uid == nil {
+               return nil, errors.InvalidArgumentError("user id field contained invalid characters")
+       }
+       signingPriv, err := rsa.GenerateKey(config.Random(), bits)
+       if err != nil {
+               return nil, err
+       }
+       encryptingPriv, err := rsa.GenerateKey(config.Random(), bits)
+       if err != nil {
+               return nil, err
+       }
+
+       e := &Entity{
+               PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey),
+               PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv),
+               Identities: make(map[string]*Identity),
+       }
+       isPrimaryId := true
+       e.Identities[uid.Id] = &Identity{
+               Name:   uid.Name,
+               UserId: uid,
+               SelfSignature: &packet.Signature{
+                       CreationTime: currentTime,
+                       SigType:      packet.SigTypePositiveCert,
+                       PubKeyAlgo:   packet.PubKeyAlgoRSA,
+                       Hash:         config.Hash(),
+                       IsPrimaryId:  &isPrimaryId,
+                       FlagsValid:   true,
+                       FlagSign:     true,
+                       FlagCertify:  true,
+                       IssuerKeyId:  &e.PrimaryKey.KeyId,
+               },
+       }
+
+       // If the user passes in a DefaultHash via packet.Config,
+       // set the PreferredHash for the SelfSignature.
+       if config != nil && config.DefaultHash != 0 {
+               e.Identities[uid.Id].SelfSignature.PreferredHash = []uint8{hashToHashId(config.DefaultHash)}
+       }
+
+       e.Subkeys = make([]Subkey, 1)
+       e.Subkeys[0] = Subkey{
+               PublicKey:  packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
+               PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv),
+               Sig: &packet.Signature{
+                       CreationTime:              currentTime,
+                       SigType:                   packet.SigTypeSubkeyBinding,
+                       PubKeyAlgo:                packet.PubKeyAlgoRSA,
+                       Hash:                      config.Hash(),
+                       FlagsValid:                true,
+                       FlagEncryptStorage:        true,
+                       FlagEncryptCommunications: true,
+                       IssuerKeyId:               &e.PrimaryKey.KeyId,
+               },
+       }
+       e.Subkeys[0].PublicKey.IsSubkey = true
+       e.Subkeys[0].PrivateKey.IsSubkey = true
+
+       return e, nil
+}
+
+// SerializePrivate serializes an Entity, including private key material, to
+// the given Writer. For now, it must only be used on an Entity returned from
+// NewEntity.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
+       err = e.PrivateKey.Serialize(w)
+       if err != nil {
+               return
+       }
+       for _, ident := range e.Identities {
+               err = ident.UserId.Serialize(w)
+               if err != nil {
+                       return
+               }
+               err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
+               if err != nil {
+                       return
+               }
+               err = ident.SelfSignature.Serialize(w)
+               if err != nil {
+                       return
+               }
+       }
+       for _, subkey := range e.Subkeys {
+               err = subkey.PrivateKey.Serialize(w)
+               if err != nil {
+                       return
+               }
+               err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
+               if err != nil {
+                       return
+               }
+               err = subkey.Sig.Serialize(w)
+               if err != nil {
+                       return
+               }
+       }
+       return nil
+}
+
+// Serialize writes the public part of the given Entity to w. (No private
+// key material will be output).
+func (e *Entity) Serialize(w io.Writer) error {
+       err := e.PrimaryKey.Serialize(w)
+       if err != nil {
+               return err
+       }
+       for _, ident := range e.Identities {
+               err = ident.UserId.Serialize(w)
+               if err != nil {
+                       return err
+               }
+               err = ident.SelfSignature.Serialize(w)
+               if err != nil {
+                       return err
+               }
+               for _, sig := range ident.Signatures {
+                       err = sig.Serialize(w)
+                       if err != nil {
+                               return err
+                       }
+               }
+       }
+       for _, subkey := range e.Subkeys {
+               err = subkey.PublicKey.Serialize(w)
+               if err != nil {
+                       return err
+               }
+               err = subkey.Sig.Serialize(w)
+               if err != nil {
+                       return err
+               }
+       }
+       return nil
+}
+
+// SignIdentity adds a signature to e, from signer, attesting that identity is
+// associated with e. The provided identity must already be an element of
+// e.Identities and the private key of signer must have been decrypted if
+// necessary.
+// If config is nil, sensible defaults will be used.
+func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
+       if signer.PrivateKey == nil {
+               return errors.InvalidArgumentError("signing Entity must have a private key")
+       }
+       if signer.PrivateKey.Encrypted {
+               return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
+       }
+       ident, ok := e.Identities[identity]
+       if !ok {
+               return errors.InvalidArgumentError("given identity string not found in Entity")
+       }
+
+       sig := &packet.Signature{
+               SigType:      packet.SigTypeGenericCert,
+               PubKeyAlgo:   signer.PrivateKey.PubKeyAlgo,
+               Hash:         config.Hash(),
+               CreationTime: config.Now(),
+               IssuerKeyId:  &signer.PrivateKey.KeyId,
+       }
+       if err := sig.SignUserId(identity, e.PrimaryKey, signer.PrivateKey, config); err != nil {
+               return err
+       }
+       ident.Signatures = append(ident.Signatures, sig)
+       return nil
+}