mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	update vendor keybase/go-crypto (#10234)
This commit is contained in:
		
							
								
								
									
										101
									
								
								vendor/github.com/keybase/go-crypto/openpgp/armor/armor.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										101
									
								
								vendor/github.com/keybase/go-crypto/openpgp/armor/armor.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -10,6 +10,7 @@ import ( | ||||
| 	"bufio" | ||||
| 	"bytes" | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| 	"unicode" | ||||
| @@ -89,50 +90,114 @@ func (l *lineReader) Read(p []byte) (n int, err error) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	line, _, err := l.in.ReadLine() | ||||
| 	line, isPrefix, err := l.in.ReadLine() | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// Entry-level cleanup, just trim spaces. | ||||
| 	line = bytes.TrimFunc(line, ourIsSpace) | ||||
|  | ||||
| 	if len(line) == 5 && line[0] == '=' { | ||||
| 		// This is the checksum line | ||||
| 	lineWithChecksum := false | ||||
| 	foldedChecksum := false | ||||
| 	if !isPrefix && len(line) >= 5 && line[len(line)-5] == '=' && line[len(line)-4] != '=' { | ||||
| 		// This is the checksum line. Checksum should appear on separate line, | ||||
| 		// but some bundles don't have a newline between main payload and the | ||||
| 		// checksum, and we try to support that. | ||||
|  | ||||
| 		// `=` is not a base64 character with the exception of padding, and the | ||||
| 		// padding can only be 2 characters long at most ("=="), so we can | ||||
| 		// safely assume that 5 characters starting with `=` at the end of the | ||||
| 		// line can't be a valid ending of a base64 stream. In other words, `=` | ||||
| 		// at position len-5 in base64 stream can never be a valid part of that | ||||
| 		// stream. | ||||
|  | ||||
| 		// Checksum can never appear if isPrefix is true - that is, when | ||||
| 		// ReadLine returned non-final part of some line because it was longer | ||||
| 		// than its buffer. | ||||
|  | ||||
| 		if l.crc != nil { | ||||
| 			// Error out early if there are multiple checksums. | ||||
| 			return 0, ArmorCorrupt | ||||
| 		} | ||||
|  | ||||
| 		var expectedBytes [3]byte | ||||
| 		var m int | ||||
| 		m, err = base64.StdEncoding.Decode(expectedBytes[0:], line[1:]) | ||||
| 		if m != 3 || err != nil { | ||||
| 			return | ||||
| 		m, err = base64.StdEncoding.Decode(expectedBytes[0:], line[len(line)-4:]) | ||||
| 		if err != nil { | ||||
| 			return 0, fmt.Errorf("error decoding CRC: %s", err.Error()) | ||||
| 		} else if m != 3 { | ||||
| 			return 0, fmt.Errorf("error decoding CRC: wrong size CRC") | ||||
| 		} | ||||
|  | ||||
| 		crc := uint32(expectedBytes[0])<<16 | | ||||
| 			uint32(expectedBytes[1])<<8 | | ||||
| 			uint32(expectedBytes[2]) | ||||
| 		l.crc = &crc | ||||
|  | ||||
| 		line = line[:len(line)-5] | ||||
|  | ||||
| 		lineWithChecksum = true | ||||
|  | ||||
| 		// If we've found a checksum but there is still data left, we don't | ||||
| 		// want to enter the "looking for armor end" loop, we still need to | ||||
| 		// return the leftover data to the reader. | ||||
| 		foldedChecksum = len(line) > 0 | ||||
|  | ||||
| 		// At this point, `line` contains leftover data or "" (if checksum | ||||
| 		// was on separate line.) | ||||
| 	} | ||||
|  | ||||
| 	expectArmorEnd := false | ||||
| 	if l.crc != nil && !foldedChecksum { | ||||
| 		// "looking for armor end" loop | ||||
|  | ||||
| 		// We have a checksum, and we are now reading what comes afterwards. | ||||
| 		// Skip all empty lines until we see something and we except it to be | ||||
| 		// ArmorEnd at this point. | ||||
|  | ||||
| 		// This loop is not entered if there is more data *before* the CRC | ||||
| 		// suffix (if the CRC is not on separate line). | ||||
| 		for { | ||||
| 			line, _, err = l.in.ReadLine() | ||||
| 			if err != nil && err != io.EOF { | ||||
| 				return | ||||
| 			} | ||||
| 			if len(strings.TrimSpace(string(line))) > 0 { | ||||
| 				break | ||||
| 			} | ||||
| 			lineWithChecksum = false | ||||
| 			line, _, err = l.in.ReadLine() | ||||
| 			if err == io.EOF { | ||||
| 				break | ||||
| 			} | ||||
| 			if err != nil { | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
| 		if !bytes.HasPrefix(line, armorEnd) { | ||||
| 			return 0, ArmorCorrupt | ||||
| 		} | ||||
|  | ||||
| 		l.eof = true | ||||
| 		return 0, io.EOF | ||||
| 		expectArmorEnd = true | ||||
| 	} | ||||
|  | ||||
| 	if bytes.HasPrefix(line, armorEnd) { | ||||
| 		// Unexpected ending, there was no checksum. | ||||
| 		if lineWithChecksum { | ||||
| 			// ArmorEnd and checksum at the same line? | ||||
| 			return 0, ArmorCorrupt | ||||
| 		} | ||||
| 		l.eof = true | ||||
| 		l.crc = nil | ||||
| 		return 0, io.EOF | ||||
| 	} else if expectArmorEnd { | ||||
| 		// We wanted armorEnd but didn't see one. | ||||
| 		return 0, ArmorCorrupt | ||||
| 	} | ||||
|  | ||||
| 	// Clean-up line from whitespace to pass it further (to base64 | ||||
| 	// decoder). This is done after test for CRC and test for | ||||
| 	// armorEnd. Keys that have whitespace in CRC will have CRC | ||||
| 	// treated as part of the payload and probably fail in base64 | ||||
| 	// reading. | ||||
| 	line = bytes.Map(func(r rune) rune { | ||||
| 		if ourIsSpace(r) { | ||||
| 			return -1 | ||||
| 		} | ||||
| 		return r | ||||
| 	}, line) | ||||
|  | ||||
| 	n = copy(p, line) | ||||
| 	bytesToSave := len(line) - n | ||||
| 	if bytesToSave > 0 { | ||||
|   | ||||
							
								
								
									
										34
									
								
								vendor/github.com/keybase/go-crypto/openpgp/ecdh/ecdh.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/keybase/go-crypto/openpgp/ecdh/ecdh.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -280,3 +280,37 @@ func Unmarshal(curve elliptic.Curve, data []byte) (x, y *big.Int) { | ||||
|  | ||||
| 	return elliptic.Unmarshal(curve, data) | ||||
| } | ||||
|  | ||||
| func GenerateKey(curve elliptic.Curve, random io.Reader) (priv *PrivateKey, err error) { | ||||
| 	var privBytes []byte | ||||
| 	var Vx, Vy *big.Int | ||||
|  | ||||
| 	if _, ok := curve25519.ToCurve25519(curve); ok { | ||||
| 		privBytes = make([]byte, 32) | ||||
| 		_, err = io.ReadFull(random, privBytes) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		// NOTE: PGP expect scalars in reverse order than Curve 25519 | ||||
| 		// go library. That's why this trimming is backwards compared | ||||
| 		// to curve25519.go | ||||
| 		privBytes[31] &= 248 | ||||
| 		privBytes[0] &= 127 | ||||
| 		privBytes[0] |= 64 | ||||
|  | ||||
| 		Vx,Vy = curve.ScalarBaseMult(privBytes) | ||||
| 	} else { | ||||
| 		privBytes, Vx, Vy, err = elliptic.GenerateKey(curve, random) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	priv = &PrivateKey{} | ||||
| 	priv.X = new(big.Int).SetBytes(privBytes) | ||||
| 	priv.PublicKey.Curve = curve | ||||
| 	priv.PublicKey.X = Vx | ||||
| 	priv.PublicKey.Y = Vy | ||||
| 	return priv, nil | ||||
| } | ||||
|   | ||||
							
								
								
									
										8
									
								
								vendor/github.com/keybase/go-crypto/openpgp/errors/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/keybase/go-crypto/openpgp/errors/errors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -70,3 +70,11 @@ type UnknownPacketTypeError uint8 | ||||
| func (upte UnknownPacketTypeError) Error() string { | ||||
| 	return "openpgp: unknown packet type: " + strconv.Itoa(int(upte)) | ||||
| } | ||||
|  | ||||
| // DeprecatedKeyError indicates that the key was read and verified | ||||
| // properly, but uses a deprecated algorithm and can't be used. | ||||
| type DeprecatedKeyError string | ||||
|  | ||||
| func (d DeprecatedKeyError) Error() string { | ||||
| 	return "openpgp: key is deprecated: " + string(d) | ||||
| } | ||||
|   | ||||
							
								
								
									
										46
									
								
								vendor/github.com/keybase/go-crypto/openpgp/keys.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/keybase/go-crypto/openpgp/keys.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -118,7 +118,8 @@ func (e *Entity) primaryIdentity() *Identity { | ||||
| func (e *Entity) encryptionKey(now time.Time) (Key, bool) { | ||||
| 	candidateSubkey := -1 | ||||
|  | ||||
| 	// Iterate the keys to find the newest key | ||||
| 	// Iterate the keys to find the newest, non-revoked key that can | ||||
| 	// encrypt. | ||||
| 	var maxTime time.Time | ||||
| 	for i, subkey := range e.Subkeys { | ||||
|  | ||||
| @@ -172,13 +173,18 @@ func (e *Entity) encryptionKey(now time.Time) (Key, bool) { | ||||
| func (e *Entity) signingKey(now time.Time) (Key, bool) { | ||||
| 	candidateSubkey := -1 | ||||
|  | ||||
| 	// Iterate the keys to find the newest, non-revoked key that can | ||||
| 	// sign. | ||||
| 	var maxTime time.Time | ||||
| 	for i, subkey := range e.Subkeys { | ||||
| 		if (!subkey.Sig.FlagsValid || subkey.Sig.FlagSign) && | ||||
| 			subkey.PrivateKey.PrivateKey != nil && | ||||
| 			subkey.PublicKey.PubKeyAlgo.CanSign() && | ||||
| 			!subkey.Sig.KeyExpired(now) && | ||||
| 			subkey.Revocation == nil && | ||||
| 			!subkey.Sig.KeyExpired(now) { | ||||
| 			(maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) { | ||||
| 			candidateSubkey = i | ||||
| 			maxTime = subkey.Sig.CreationTime | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| @@ -504,7 +510,7 @@ EachPacket: | ||||
| 					// Only register an identity once we've gotten a valid self-signature. | ||||
| 					// It's possible therefore for us to throw away `current` in the case | ||||
| 					// no valid self-signatures were found. That's OK as long as there are | ||||
| 					// other identies that make sense. | ||||
| 					// other identities that make sense. | ||||
| 					// | ||||
| 					// NOTE! We might later see a revocation for this very same UID, and it | ||||
| 					// won't be undone. We've preserved this feature from the original | ||||
| @@ -645,6 +651,15 @@ func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *p | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if subKey.Sig != nil { | ||||
| 		if err := subKey.PublicKey.ErrorIfDeprecated(); err != nil { | ||||
| 			// Key passed signature check but is deprecated. | ||||
| 			subKey.Sig = nil | ||||
| 			lastErr = err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if subKey.Sig != nil { | ||||
| 		e.Subkeys = append(e.Subkeys, subKey) | ||||
| 	} else { | ||||
| @@ -690,7 +705,7 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err | ||||
| 	} | ||||
| 	isPrimaryId := true | ||||
| 	e.Identities[uid.Id] = &Identity{ | ||||
| 		Name:   uid.Name, | ||||
| 		Name:   uid.Id, | ||||
| 		UserId: uid, | ||||
| 		SelfSignature: &packet.Signature{ | ||||
| 			CreationTime: currentTime, | ||||
| @@ -705,6 +720,17 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	// 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)} | ||||
| 	} | ||||
|  | ||||
| 	// Likewise for DefaultCipher. | ||||
| 	if config != nil && config.DefaultCipher != 0 { | ||||
| 		e.Identities[uid.Id].SelfSignature.PreferredSymmetric = []uint8{uint8(config.DefaultCipher)} | ||||
| 	} | ||||
|  | ||||
| 	e.Subkeys = make([]Subkey, 1) | ||||
| 	e.Subkeys[0] = Subkey{ | ||||
| 		PublicKey:  packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey), | ||||
| @@ -756,10 +782,16 @@ func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 		// Workaround shortcoming of SignKey(), which doesn't work to reverse-sign | ||||
| 		// sub-signing keys. So if requested, just reuse the signatures already | ||||
| 		// available to us (if we read this key from a keyring). | ||||
| 		if e.PrivateKey.PrivateKey != nil && !config.ReuseSignatures() { | ||||
| 			// If not reusing existing signatures, sign subkey using private key | ||||
| 			// (subkey binding), but also sign primary key using subkey (primary | ||||
| 			// key binding) if subkey is used for signing. | ||||
| 			if subkey.Sig.FlagSign { | ||||
| 				err = subkey.Sig.CrossSignKey(e.PrimaryKey, subkey.PrivateKey, config) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} | ||||
| 			err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config) | ||||
| 			if err != nil { | ||||
| 				return | ||||
|   | ||||
							
								
								
									
										7
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/encrypted_key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/encrypted_key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -83,6 +83,10 @@ func checksumKeyMaterial(key []byte) uint16 { | ||||
| // private key must have been decrypted first. | ||||
| // If config is nil, sensible defaults will be used. | ||||
| func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error { | ||||
| 	if priv == nil || priv.PrivateKey == nil { | ||||
| 		return errors.InvalidArgumentError("attempting to decrypt with nil PrivateKey") | ||||
| 	} | ||||
|  | ||||
| 	var err error | ||||
| 	var b []byte | ||||
|  | ||||
| @@ -90,7 +94,8 @@ func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error { | ||||
| 	// padding oracle attacks. | ||||
| 	switch priv.PubKeyAlgo { | ||||
| 	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: | ||||
| 		b, err = rsa.DecryptPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1.bytes) | ||||
| 		k := priv.PrivateKey.(*rsa.PrivateKey) | ||||
| 		b, err = rsa.DecryptPKCS1v15(config.Random(), k, padToKeySize(&k.PublicKey, e.encryptedMPI1.bytes)) | ||||
| 	case PubKeyAlgoElGamal: | ||||
| 		c1 := new(big.Int).SetBytes(e.encryptedMPI1.bytes) | ||||
| 		c2 := new(big.Int).SetBytes(e.encryptedMPI2.bytes) | ||||
|   | ||||
							
								
								
									
										35
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/packet.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/packet.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -17,6 +17,7 @@ import ( | ||||
|  | ||||
| 	"github.com/keybase/go-crypto/cast5" | ||||
| 	"github.com/keybase/go-crypto/openpgp/errors" | ||||
| 	"github.com/keybase/go-crypto/rsa" | ||||
| ) | ||||
|  | ||||
| // readFull is the same as io.ReadFull except that reading zero bytes returns | ||||
| @@ -413,10 +414,12 @@ const ( | ||||
| 	PubKeyAlgoElGamal        PublicKeyAlgorithm = 16 | ||||
| 	PubKeyAlgoDSA            PublicKeyAlgorithm = 17 | ||||
| 	// RFC 6637, Section 5. | ||||
| 	PubKeyAlgoECDH  PublicKeyAlgorithm = 18 | ||||
| 	PubKeyAlgoECDSA PublicKeyAlgorithm = 19 | ||||
| 	PubKeyAlgoECDH           PublicKeyAlgorithm = 18 | ||||
| 	PubKeyAlgoECDSA          PublicKeyAlgorithm = 19 | ||||
|  | ||||
| 	PubKeyAlgoBadElGamal     PublicKeyAlgorithm = 20 // Reserved (deprecated, formerly ElGamal Encrypt or Sign) | ||||
| 	// RFC -1 | ||||
| 	PubKeyAlgoEdDSA PublicKeyAlgorithm = 22 | ||||
| 	PubKeyAlgoEdDSA          PublicKeyAlgorithm = 22 | ||||
| ) | ||||
|  | ||||
| // CanEncrypt returns true if it's possible to encrypt a message to a public | ||||
| @@ -507,19 +510,17 @@ func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err error) { | ||||
| 	numBytes := (int(bitLength) + 7) / 8 | ||||
| 	mpi = make([]byte, numBytes) | ||||
| 	_, err = readFull(r, mpi) | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // mpiLength returns the length of the given *big.Int when serialized as an | ||||
| // MPI. | ||||
| func mpiLength(n *big.Int) (mpiLengthInBytes int) { | ||||
| 	mpiLengthInBytes = 2 /* MPI length */ | ||||
| 	mpiLengthInBytes += (n.BitLen() + 7) / 8 | ||||
| 	// According to RFC 4880 3.2. we should check that the MPI has no leading | ||||
| 	// zeroes (at least when not an encrypted MPI?), but this implementation | ||||
| 	// does generate leading zeroes, so we keep accepting them. | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // writeMPI serializes a big integer to w. | ||||
| func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err error) { | ||||
| 	// Note that we can produce leading zeroes, in violation of RFC 4880 3.2. | ||||
| 	// Implementations seem to be tolerant of them, and stripping them would | ||||
| 	// make it complex to guarantee matching re-serialization. | ||||
| 	_, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)}) | ||||
| 	if err == nil { | ||||
| 		_, err = w.Write(mpiBytes) | ||||
| @@ -551,6 +552,18 @@ func writeBig(w io.Writer, i *big.Int) error { | ||||
| 	return writeMPI(w, uint16(i.BitLen()), i.Bytes()) | ||||
| } | ||||
|  | ||||
| // padToKeySize left-pads a MPI with zeroes to match the length of the | ||||
| // specified RSA public. | ||||
| func padToKeySize(pub *rsa.PublicKey, b []byte) []byte { | ||||
| 	k := (pub.N.BitLen() + 7) / 8 | ||||
| 	if len(b) >= k { | ||||
| 		return b | ||||
| 	} | ||||
| 	bb := make([]byte, k) | ||||
| 	copy(bb[len(bb)-len(b):], b) | ||||
| 	return bb | ||||
| } | ||||
|  | ||||
| // CompressionAlgo Represents the different compression algorithms | ||||
| // supported by OpenPGP (except for BZIP2, which is not currently | ||||
| // supported). See Section 9.3 of RFC 4880. | ||||
|   | ||||
							
								
								
									
										16
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/private_key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/private_key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -44,6 +44,10 @@ type EdDSAPrivateKey struct { | ||||
| 	seed parsedMPI | ||||
| } | ||||
|  | ||||
| func (e *EdDSAPrivateKey) Seed() []byte { | ||||
| 	return e.seed.bytes | ||||
| } | ||||
|  | ||||
| func (e *EdDSAPrivateKey) Sign(digest []byte) (R, S []byte, err error) { | ||||
| 	r := bytes.NewReader(e.seed.bytes) | ||||
| 	publicKey, privateKey, err := ed25519.GenerateKey(r) | ||||
| @@ -89,6 +93,13 @@ func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateK | ||||
| 	return pk | ||||
| } | ||||
|  | ||||
| func NewECDHPrivateKey(currentTime time.Time, priv *ecdh.PrivateKey) *PrivateKey { | ||||
| 	pk := new(PrivateKey) | ||||
| 	pk.PublicKey = *NewECDHPublicKey(currentTime, &priv.PublicKey) | ||||
| 	pk.PrivateKey = priv | ||||
| 	return pk | ||||
| } | ||||
|  | ||||
| func (pk *PrivateKey) parse(r io.Reader) (err error) { | ||||
| 	err = (&pk.PublicKey).parse(r) | ||||
| 	if err != nil { | ||||
| @@ -415,8 +426,11 @@ func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) { | ||||
| 		return pk.parseECDHPrivateKey(data) | ||||
| 	case PubKeyAlgoEdDSA: | ||||
| 		return pk.parseEdDSAPrivateKey(data) | ||||
| 	case PubKeyAlgoBadElGamal: | ||||
| 		return errors.UnsupportedError("parsing el-gamal sign-or-encrypt privatekeys is unsupported") | ||||
| 	default: | ||||
| 		return errors.UnsupportedError("cannot parse this private key type") | ||||
| 	} | ||||
| 	panic("impossible") | ||||
| } | ||||
|  | ||||
| func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) { | ||||
|   | ||||
							
								
								
									
										105
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/public_key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/public_key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -27,10 +27,13 @@ import ( | ||||
| 	"github.com/keybase/go-crypto/openpgp/ecdh" | ||||
| 	"github.com/keybase/go-crypto/openpgp/elgamal" | ||||
| 	"github.com/keybase/go-crypto/openpgp/errors" | ||||
| 	"github.com/keybase/go-crypto/openpgp/s2k" | ||||
| 	"github.com/keybase/go-crypto/rsa" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// NIST curve P-224 | ||||
| 	oidCurveP224 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x21} | ||||
| 	// NIST curve P-256 | ||||
| 	oidCurveP256 []byte = []byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07} | ||||
| 	// NIST curve P-384 | ||||
| @@ -128,6 +131,8 @@ func (f *ecdsaKey) serialize(w io.Writer) (err error) { | ||||
|  | ||||
| func getCurveByOid(oid []byte) elliptic.Curve { | ||||
| 	switch { | ||||
| 	case bytes.Equal(oid, oidCurveP224): | ||||
| 		return elliptic.P224() | ||||
| 	case bytes.Equal(oid, oidCurveP256): | ||||
| 		return elliptic.P256() | ||||
| 	case bytes.Equal(oid, oidCurveP384): | ||||
| @@ -324,6 +329,30 @@ func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *Public | ||||
| 	return pk | ||||
| } | ||||
|  | ||||
| func getCurveOid(curve elliptic.Curve) (res []byte, err error) { | ||||
| 	switch curve { | ||||
| 	case elliptic.P224(): | ||||
| 		res = oidCurveP224 | ||||
| 	case elliptic.P256(): | ||||
| 		res = oidCurveP256 | ||||
| 	case elliptic.P384(): | ||||
| 		res = oidCurveP384 | ||||
| 	case elliptic.P521(): | ||||
| 		res = oidCurveP521 | ||||
| 	case brainpool.P256r1(): | ||||
| 		res = oidCurveP256r1 | ||||
| 	case brainpool.P384r1(): | ||||
| 		res = oidCurveP384r1 | ||||
| 	case brainpool.P512r1(): | ||||
| 		res = oidCurveP512r1 | ||||
| 	case curve25519.Cv25519(): | ||||
| 		res = oidCurve25519 | ||||
| 	default: | ||||
| 		err = errors.UnsupportedError("unknown curve") | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey { | ||||
| 	pk := &PublicKey{ | ||||
| 		CreationTime: creationTime, | ||||
| @@ -331,22 +360,34 @@ func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey | ||||
| 		PublicKey:    pub, | ||||
| 		ec:           new(ecdsaKey), | ||||
| 	} | ||||
| 	switch pub.Curve { | ||||
| 	case elliptic.P256(): | ||||
| 		pk.ec.oid = oidCurveP256 | ||||
| 	case elliptic.P384(): | ||||
| 		pk.ec.oid = oidCurveP384 | ||||
| 	case elliptic.P521(): | ||||
| 		pk.ec.oid = oidCurveP521 | ||||
| 	case brainpool.P256r1(): | ||||
| 		pk.ec.oid = oidCurveP256r1 | ||||
| 	case brainpool.P384r1(): | ||||
| 		pk.ec.oid = oidCurveP384r1 | ||||
| 	case brainpool.P512r1(): | ||||
| 		pk.ec.oid = oidCurveP512r1 | ||||
| 	oid, _ := getCurveOid(pub.Curve) | ||||
| 	pk.ec.oid = oid | ||||
| 	bs, bitLen := ecdh.Marshal(pub.Curve, pub.X, pub.Y) | ||||
| 	pk.ec.p.bytes = bs | ||||
| 	pk.ec.p.bitLength = uint16(bitLen) | ||||
|  | ||||
| 	pk.setFingerPrintAndKeyId() | ||||
| 	return pk | ||||
| } | ||||
|  | ||||
| func NewECDHPublicKey(creationTime time.Time, pub *ecdh.PublicKey) *PublicKey { | ||||
| 	pk := &PublicKey{ | ||||
| 		CreationTime: creationTime, | ||||
| 		PubKeyAlgo:   PubKeyAlgoECDH, | ||||
| 		PublicKey:    pub, | ||||
| 		ec:           new(ecdsaKey), | ||||
| 	} | ||||
| 	oid, _ := getCurveOid(pub.Curve) | ||||
| 	pk.ec.oid = oid | ||||
| 	bs, bitLen := ecdh.Marshal(pub.Curve, pub.X, pub.Y) | ||||
| 	pk.ec.p.bytes = bs | ||||
| 	pk.ec.p.bitLength = uint16(bitLen) | ||||
|  | ||||
| 	hashbyte, _ := s2k.HashToHashId(crypto.SHA512) | ||||
| 	pk.ecdh = &ecdhKdf{ | ||||
| 		KdfHash: kdfHashFunction(hashbyte), | ||||
| 		KdfAlgo: kdfAlgorithm(CipherAES256), | ||||
| 	} | ||||
| 	pk.ec.p.bytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) | ||||
| 	pk.ec.p.bitLength = uint16(8 * len(pk.ec.p.bytes)) | ||||
|  | ||||
| 	pk.setFingerPrintAndKeyId() | ||||
| 	return pk | ||||
| @@ -377,6 +418,9 @@ func (pk *PublicKey) parse(r io.Reader) (err error) { | ||||
| 			return err | ||||
| 		} | ||||
| 		err = pk.edk.check() | ||||
| 		if err == nil { | ||||
| 			pk.PublicKey = ed25519.PublicKey(pk.edk.p.bytes[1:]) | ||||
| 		} | ||||
| 	case PubKeyAlgoECDSA: | ||||
| 		pk.ec = new(ecdsaKey) | ||||
| 		if err = pk.ec.parse(r); err != nil { | ||||
| @@ -393,6 +437,14 @@ func (pk *PublicKey) parse(r io.Reader) (err error) { | ||||
| 			return | ||||
| 		} | ||||
| 		pk.PublicKey, err = pk.ec.newECDH() | ||||
| 	case PubKeyAlgoBadElGamal: | ||||
| 		// Key has ElGamal format but nil-implementation - it will | ||||
| 		// load but it's not possible to do any operations using this | ||||
| 		// key. | ||||
| 		err = pk.parseElGamal(r) | ||||
| 		if err != nil { | ||||
| 			pk.PublicKey = nil | ||||
| 		} | ||||
| 	default: | ||||
| 		err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo))) | ||||
| 	} | ||||
| @@ -433,6 +485,8 @@ func (pk *PublicKey) parseRSA(r io.Reader) (err error) { | ||||
| 		N: new(big.Int).SetBytes(pk.n.bytes), | ||||
| 		E: 0, | ||||
| 	} | ||||
| 	// Warning: incompatibility with crypto/rsa: keybase fork uses | ||||
| 	// int64 public exponents instead of int32. | ||||
| 	for i := 0; i < len(pk.e.bytes); i++ { | ||||
| 		rsa.E <<= 8 | ||||
| 		rsa.E |= int64(pk.e.bytes[i]) | ||||
| @@ -508,7 +562,7 @@ func (pk *PublicKey) SerializeSignaturePrefix(h io.Writer) { | ||||
| 		pLength += 2 + uint16(len(pk.q.bytes)) | ||||
| 		pLength += 2 + uint16(len(pk.g.bytes)) | ||||
| 		pLength += 2 + uint16(len(pk.y.bytes)) | ||||
| 	case PubKeyAlgoElGamal: | ||||
| 	case PubKeyAlgoElGamal, PubKeyAlgoBadElGamal: | ||||
| 		pLength += 2 + uint16(len(pk.p.bytes)) | ||||
| 		pLength += 2 + uint16(len(pk.g.bytes)) | ||||
| 		pLength += 2 + uint16(len(pk.y.bytes)) | ||||
| @@ -539,7 +593,7 @@ func (pk *PublicKey) Serialize(w io.Writer) (err error) { | ||||
| 		length += 2 + len(pk.q.bytes) | ||||
| 		length += 2 + len(pk.g.bytes) | ||||
| 		length += 2 + len(pk.y.bytes) | ||||
| 	case PubKeyAlgoElGamal: | ||||
| 	case PubKeyAlgoElGamal, PubKeyAlgoBadElGamal: | ||||
| 		length += 2 + len(pk.p.bytes) | ||||
| 		length += 2 + len(pk.g.bytes) | ||||
| 		length += 2 + len(pk.y.bytes) | ||||
| @@ -587,7 +641,7 @@ func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) { | ||||
| 		return writeMPIs(w, pk.n, pk.e) | ||||
| 	case PubKeyAlgoDSA: | ||||
| 		return writeMPIs(w, pk.p, pk.q, pk.g, pk.y) | ||||
| 	case PubKeyAlgoElGamal: | ||||
| 	case PubKeyAlgoElGamal, PubKeyAlgoBadElGamal: | ||||
| 		return writeMPIs(w, pk.p, pk.g, pk.y) | ||||
| 	case PubKeyAlgoECDSA: | ||||
| 		return pk.ec.serialize(w) | ||||
| @@ -637,7 +691,7 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro | ||||
| 	switch pk.PubKeyAlgo { | ||||
| 	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||||
| 		rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey) | ||||
| 		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes) | ||||
| 		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes)) | ||||
| 		if err != nil { | ||||
| 			return errors.SignatureError("RSA verification failure") | ||||
| 		} | ||||
| @@ -694,7 +748,7 @@ func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err | ||||
| 	switch pk.PubKeyAlgo { | ||||
| 	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||||
| 		rsaPublicKey := pk.PublicKey.(*rsa.PublicKey) | ||||
| 		if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil { | ||||
| 		if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes)); err != nil { | ||||
| 			return errors.SignatureError("RSA verification failure") | ||||
| 		} | ||||
| 		return | ||||
| @@ -910,7 +964,7 @@ func (pk *PublicKey) BitLength() (bitLength uint16, err error) { | ||||
| 		bitLength = pk.n.bitLength | ||||
| 	case PubKeyAlgoDSA: | ||||
| 		bitLength = pk.p.bitLength | ||||
| 	case PubKeyAlgoElGamal: | ||||
| 	case PubKeyAlgoElGamal, PubKeyAlgoBadElGamal: | ||||
| 		bitLength = pk.p.bitLength | ||||
| 	case PubKeyAlgoECDH: | ||||
| 		ecdhPublicKey := pk.PublicKey.(*ecdh.PublicKey) | ||||
| @@ -928,3 +982,12 @@ func (pk *PublicKey) BitLength() (bitLength uint16, err error) { | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func (pk *PublicKey) ErrorIfDeprecated() error { | ||||
| 	switch pk.PubKeyAlgo { | ||||
| 	case PubKeyAlgoBadElGamal: | ||||
| 		return errors.DeprecatedKeyError("ElGamal Encrypt or Sign (algo 20) is deprecated") | ||||
| 	default: | ||||
| 		return nil | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/public_key_v3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/public_key_v3.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -105,6 +105,8 @@ func (pk *PublicKeyV3) parseRSA(r io.Reader) (err error) { | ||||
| 		return | ||||
| 	} | ||||
| 	rsa := &rsa.PublicKey{N: new(big.Int).SetBytes(pk.n.bytes)} | ||||
| 	// Warning: incompatibility with crypto/rsa: keybase fork uses | ||||
| 	// int64 public exponents instead of int32. | ||||
| 	for i := 0; i < len(pk.e.bytes); i++ { | ||||
| 		rsa.E <<= 8 | ||||
| 		rsa.E |= int64(pk.e.bytes[i]) | ||||
|   | ||||
							
								
								
									
										91
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										91
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/signature.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -10,6 +10,7 @@ import ( | ||||
| 	"crypto/dsa" | ||||
| 	"crypto/ecdsa" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"hash" | ||||
| 	"io" | ||||
| 	"strconv" | ||||
| @@ -384,18 +385,20 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r | ||||
| 			err = errors.StructuralError("empty key flags subpacket") | ||||
| 			return | ||||
| 		} | ||||
| 		sig.FlagsValid = true | ||||
| 		if subpacket[0]&KeyFlagCertify != 0 { | ||||
| 			sig.FlagCertify = true | ||||
| 		} | ||||
| 		if subpacket[0]&KeyFlagSign != 0 { | ||||
| 			sig.FlagSign = true | ||||
| 		} | ||||
| 		if subpacket[0]&KeyFlagEncryptCommunications != 0 { | ||||
| 			sig.FlagEncryptCommunications = true | ||||
| 		} | ||||
| 		if subpacket[0]&KeyFlagEncryptStorage != 0 { | ||||
| 			sig.FlagEncryptStorage = true | ||||
| 		if subpacket[0] != 0 { | ||||
| 			sig.FlagsValid = true | ||||
| 			if subpacket[0]&KeyFlagCertify != 0 { | ||||
| 				sig.FlagCertify = true | ||||
| 			} | ||||
| 			if subpacket[0]&KeyFlagSign != 0 { | ||||
| 				sig.FlagSign = true | ||||
| 			} | ||||
| 			if subpacket[0]&KeyFlagEncryptCommunications != 0 { | ||||
| 				sig.FlagEncryptCommunications = true | ||||
| 			} | ||||
| 			if subpacket[0]&KeyFlagEncryptStorage != 0 { | ||||
| 				sig.FlagEncryptStorage = true | ||||
| 			} | ||||
| 		} | ||||
| 	case reasonForRevocationSubpacket: | ||||
| 		// Reason For Revocation, section 5.2.3.23 | ||||
| @@ -624,6 +627,13 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	// Parameter check, if this is wrong we will make a signature but | ||||
| 	// not serialize it later. | ||||
| 	if sig.PubKeyAlgo != priv.PubKeyAlgo { | ||||
| 		err = errors.InvalidArgumentError("signature pub key algo does not match priv key") | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	switch priv.PubKeyAlgo { | ||||
| 	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||||
| 		sig.RSASignature.bytes, err = rsa.SignPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), sig.Hash, digest) | ||||
| @@ -637,26 +647,29 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e | ||||
| 			digest = digest[:subgroupSize] | ||||
| 		} | ||||
| 		r, s, err := dsa.Sign(config.Random(), dsaPriv, digest) | ||||
| 		if err == nil { | ||||
| 			sig.DSASigR.bytes = r.Bytes() | ||||
| 			sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes)) | ||||
| 			sig.DSASigS.bytes = s.Bytes() | ||||
| 			sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes)) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		sig.DSASigR.bytes = r.Bytes() | ||||
| 		sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes)) | ||||
| 		sig.DSASigS.bytes = s.Bytes() | ||||
| 		sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes)) | ||||
| 	case PubKeyAlgoECDSA: | ||||
| 		r, s, err := ecdsa.Sign(config.Random(), priv.PrivateKey.(*ecdsa.PrivateKey), digest) | ||||
| 		if err == nil { | ||||
| 			sig.ECDSASigR = FromBig(r) | ||||
| 			sig.ECDSASigS = FromBig(s) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		sig.ECDSASigR = FromBig(r) | ||||
| 		sig.ECDSASigS = FromBig(s) | ||||
| 	case PubKeyAlgoEdDSA: | ||||
| 		r, s, err := priv.PrivateKey.(*EdDSAPrivateKey).Sign(digest) | ||||
| 		if err == nil { | ||||
| 			sig.EdDSASigR = FromBytes(r) | ||||
| 			sig.EdDSASigS = FromBytes(s) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		sig.EdDSASigR = FromBytes(r) | ||||
| 		sig.EdDSASigS = FromBytes(s) | ||||
| 	default: | ||||
| 		err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo))) | ||||
| 		err = errors.UnsupportedError("public key algorithm for signing: " + strconv.Itoa(int(priv.PubKeyAlgo))) | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| @@ -704,6 +717,28 @@ func (sig *Signature) SignKeyWithSigner(signeePubKey *PublicKey, signerPubKey *P | ||||
| 	return sig.Sign(s, nil, config) | ||||
| } | ||||
|  | ||||
| // CrossSignKey creates PrimaryKeyBinding signature in sig.EmbeddedSignature by | ||||
| // signing `primary` key's hash using `priv` subkey private key. Primary public | ||||
| // key is the `signee` here. | ||||
| func (sig *Signature) CrossSignKey(primary *PublicKey, priv *PrivateKey, config *Config) error { | ||||
| 	if len(sig.outSubpackets) > 0 { | ||||
| 		return fmt.Errorf("outSubpackets already exists, looks like CrossSignKey was called after Sign") | ||||
| 	} | ||||
|  | ||||
| 	sig.EmbeddedSignature = &Signature{ | ||||
| 		CreationTime: sig.CreationTime, | ||||
| 		SigType:      SigTypePrimaryKeyBinding, | ||||
| 		PubKeyAlgo:   priv.PubKeyAlgo, | ||||
| 		Hash:         sig.Hash, | ||||
| 	} | ||||
|  | ||||
| 	h, err := keySignatureHash(primary, &priv.PublicKey, sig.Hash) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return sig.EmbeddedSignature.Sign(h, priv, config) | ||||
| } | ||||
|  | ||||
| // Serialize marshals sig to w. Sign, SignUserId or SignKey must have been | ||||
| // called first. | ||||
| func (sig *Signature) Serialize(w io.Writer) (err error) { | ||||
| @@ -832,6 +867,14 @@ func (sig *Signature) buildSubpackets() (subpackets []outputSubpacket) { | ||||
| 		subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression}) | ||||
| 	} | ||||
|  | ||||
| 	if sig.EmbeddedSignature != nil { | ||||
| 		buf := bytes.NewBuffer(nil) | ||||
| 		if err := sig.EmbeddedSignature.Serialize(buf); err == nil { | ||||
| 			byteContent := buf.Bytes()[2:] // skip 2-byte length header | ||||
| 			subpackets = append(subpackets, outputSubpacket{false, embeddedSignatureSubpacket, true, byteContent}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										6
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/symmetric_key_encrypted.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/keybase/go-crypto/openpgp/packet/symmetric_key_encrypted.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -91,10 +91,10 @@ func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) ([]byte, CipherFunc | ||||
| 		return nil, ske.CipherFunc, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc))) | ||||
| 	} | ||||
| 	plaintextKey = plaintextKey[1:] | ||||
| 	if l := len(plaintextKey); l == 0 || l%cipherFunc.blockSize() != 0 { | ||||
| 		return nil, cipherFunc, errors.StructuralError("length of decrypted key not a multiple of block size") | ||||
| 	if l, cipherKeySize := len(plaintextKey), cipherFunc.KeySize(); l != cipherFunc.KeySize() { | ||||
| 		return nil, cipherFunc, errors.StructuralError("length of decrypted key (" + strconv.Itoa(l) + ") " + | ||||
| 			"not equal to cipher keysize (" + strconv.Itoa(cipherKeySize) + ")") | ||||
| 	} | ||||
|  | ||||
| 	return plaintextKey, cipherFunc, nil | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										90
									
								
								vendor/github.com/keybase/go-crypto/openpgp/read.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										90
									
								
								vendor/github.com/keybase/go-crypto/openpgp/read.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -61,6 +61,9 @@ type MessageDetails struct { | ||||
| 	Signature      *packet.Signature   // the signature packet itself, if v4 (default) | ||||
| 	SignatureV3    *packet.SignatureV3 // the signature packet if it is a v2 or v3 signature | ||||
|  | ||||
| 	// Does the Message include multiple signatures? Also called "nested signatures". | ||||
| 	MultiSig bool | ||||
|  | ||||
| 	decrypted io.ReadCloser | ||||
| } | ||||
|  | ||||
| @@ -158,8 +161,15 @@ FindKey: | ||||
| 				continue | ||||
| 			} | ||||
| 			if !pk.key.PrivateKey.Encrypted { | ||||
| 				if pk.key.PrivateKey.PrivateKey == nil { | ||||
| 					// Key is stubbed | ||||
| 					continue | ||||
| 				} | ||||
| 				if len(pk.encryptedKey.Key) == 0 { | ||||
| 					pk.encryptedKey.Decrypt(pk.key.PrivateKey, config) | ||||
| 					err := pk.encryptedKey.Decrypt(pk.key.PrivateKey, config) | ||||
| 					if err != nil { | ||||
| 						continue | ||||
| 					} | ||||
| 				} | ||||
| 				if len(pk.encryptedKey.Key) == 0 { | ||||
| 					continue | ||||
| @@ -244,8 +254,17 @@ FindLiteralData: | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		case *packet.OnePassSignature: | ||||
| 			if !p.IsLast { | ||||
| 				return nil, errors.UnsupportedError("nested signatures") | ||||
| 			if md.IsSigned { | ||||
| 				// If IsSigned is set, it means we have multiple | ||||
| 				// OnePassSignature packets. | ||||
| 				md.MultiSig = true | ||||
| 				if md.SignedBy != nil { | ||||
| 					// We've already found the signature we were looking | ||||
| 					// for, made by key that we had in keyring and can | ||||
| 					// check signature against. Continue with that instead | ||||
| 					// of trying to find another. | ||||
| 					continue FindLiteralData | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			h, wrappedHash, err = hashForSignature(p.Hash, p.SigType) | ||||
| @@ -329,29 +348,54 @@ func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) { | ||||
| 	n, err = scr.md.LiteralData.Body.Read(buf) | ||||
| 	scr.wrappedHash.Write(buf[:n]) | ||||
| 	if err == io.EOF { | ||||
| 		var p packet.Packet | ||||
| 		p, scr.md.SignatureError = scr.packets.Next() | ||||
| 		if scr.md.SignatureError != nil { | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		var ok bool | ||||
| 		if scr.md.Signature, ok = p.(*packet.Signature); ok { | ||||
| 			var err error | ||||
| 			if fingerprint := scr.md.Signature.IssuerFingerprint; fingerprint != nil { | ||||
| 				if !hmac.Equal(fingerprint, scr.md.SignedBy.PublicKey.Fingerprint[:]) { | ||||
| 					err = errors.StructuralError("bad key fingerprint") | ||||
| 		for { | ||||
| 			var p packet.Packet | ||||
| 			p, scr.md.SignatureError = scr.packets.Next() | ||||
| 			if scr.md.SignatureError != nil { | ||||
| 				if scr.md.MultiSig { | ||||
| 					// If we are in MultiSig, we might have found other | ||||
| 					// signature that cannot be verified using our key. | ||||
| 					// Clear Signature field so it's clear for consumers | ||||
| 					// that this message failed to verify. | ||||
| 					scr.md.Signature = nil | ||||
| 				} | ||||
| 				return | ||||
| 			} | ||||
| 			if err == nil { | ||||
| 				err = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature) | ||||
|  | ||||
| 			var ok bool | ||||
| 			if scr.md.Signature, ok = p.(*packet.Signature); ok { | ||||
| 				var err error | ||||
| 				if keyID := scr.md.Signature.IssuerKeyId; keyID != nil { | ||||
| 					if *keyID != scr.md.SignedBy.PublicKey.KeyId { | ||||
| 						if scr.md.MultiSig { | ||||
| 							continue // try again to find a sig we can verify | ||||
| 						} | ||||
| 						err = errors.StructuralError("bad key id") | ||||
| 					} | ||||
| 				} | ||||
| 				if fingerprint := scr.md.Signature.IssuerFingerprint; fingerprint != nil { | ||||
| 					if !hmac.Equal(fingerprint, scr.md.SignedBy.PublicKey.Fingerprint[:]) { | ||||
| 						if scr.md.MultiSig { | ||||
| 							continue // try again to find a sig we can verify | ||||
| 						} | ||||
| 						err = errors.StructuralError("bad key fingerprint") | ||||
| 					} | ||||
| 				} | ||||
| 				if err == nil { | ||||
| 					err = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature) | ||||
| 				} | ||||
| 				scr.md.SignatureError = err | ||||
| 			} else if scr.md.SignatureV3, ok = p.(*packet.SignatureV3); ok { | ||||
| 				scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignatureV3(scr.h, scr.md.SignatureV3) | ||||
| 			} else { | ||||
| 				scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature") | ||||
| 				return | ||||
| 			} | ||||
| 			scr.md.SignatureError = err | ||||
| 		} else if scr.md.SignatureV3, ok = p.(*packet.SignatureV3); ok { | ||||
| 			scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignatureV3(scr.h, scr.md.SignatureV3) | ||||
| 		} else { | ||||
| 			scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature") | ||||
| 			return | ||||
|  | ||||
| 			// Parse only one packet by default, unless message is MultiSig. Then | ||||
| 			// we ask for more packets after discovering non-matching signature, | ||||
| 			// until we find one that we can verify. | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		// The SymmetricallyEncrypted packet, if any, might have an | ||||
|   | ||||
							
								
								
									
										13
									
								
								vendor/github.com/keybase/go-crypto/openpgp/write.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/keybase/go-crypto/openpgp/write.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -458,7 +458,18 @@ func AttachedSign(out io.WriteCloser, signed Entity, hints *FileHints, | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	hasher := crypto.SHA512 | ||||
| 	if algo := config.Compression(); algo != packet.CompressionNone { | ||||
| 		var compConfig *packet.CompressionConfig | ||||
| 		if config != nil { | ||||
| 			compConfig = config.CompressionConfig | ||||
| 		} | ||||
| 		out, err = packet.SerializeCompressed(out, algo, compConfig) | ||||
| 		if err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	hasher := config.Hash() // defaults to SHA-256 | ||||
|  | ||||
| 	ops := &packet.OnePassSignature{ | ||||
| 		SigType:    packet.SigTypeBinary, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user