mirror of
				https://gitea.com/gitea/tea.git
				synced 2025-10-31 17:25:27 +01:00 
			
		
		
		
	Update Dependencies (#390)
Co-authored-by: Norwin Roosen <git@nroo.de> Co-authored-by: Norwin <git@nroo.de> Reviewed-on: https://gitea.com/gitea/tea/pulls/390 Reviewed-by: 6543 <6543@obermui.de> Reviewed-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Norwin <noerw@noreply.gitea.io> Co-committed-by: Norwin <noerw@noreply.gitea.io>
This commit is contained in:
		
							
								
								
									
										367
									
								
								vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								vendor/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,367 @@ | ||||
| // 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 s2k implements the various OpenPGP string-to-key transforms as | ||||
| // specified in RFC 4800 section 3.7.1. | ||||
| package s2k // import "github.com/ProtonMail/go-crypto/openpgp/s2k" | ||||
|  | ||||
| import ( | ||||
| 	"crypto" | ||||
| 	"hash" | ||||
| 	"io" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"github.com/ProtonMail/go-crypto/openpgp/errors" | ||||
| 	"github.com/ProtonMail/go-crypto/openpgp/internal/algorithm" | ||||
| ) | ||||
|  | ||||
| // Config collects configuration parameters for s2k key-stretching | ||||
| // transformations. A nil *Config is valid and results in all default | ||||
| // values. Currently, Config is used only by the Serialize function in | ||||
| // this package. | ||||
| type Config struct { | ||||
| 	// S2KMode is the mode of s2k function. | ||||
| 	// It can be 0 (simple), 1(salted), 3(iterated) | ||||
| 	// 2(reserved) 100-110(private/experimental). | ||||
| 	S2KMode uint8 | ||||
| 	// Hash is the default hash function to be used. If | ||||
| 	// nil, SHA256 is used. | ||||
| 	Hash crypto.Hash | ||||
| 	// S2KCount is only used for symmetric encryption. It | ||||
| 	// determines the strength of the passphrase stretching when | ||||
| 	// the said passphrase is hashed to produce a key. S2KCount | ||||
| 	// should be between 65536 and 65011712, inclusive. If Config | ||||
| 	// is nil or S2KCount is 0, the value 16777216 used. Not all | ||||
| 	// values in the above range can be represented. S2KCount will | ||||
| 	// be rounded up to the next representable value if it cannot | ||||
| 	// be encoded exactly. See RFC 4880 Section 3.7.1.3. | ||||
| 	S2KCount int | ||||
| } | ||||
|  | ||||
| // Params contains all the parameters of the s2k packet | ||||
| type Params struct { | ||||
| 	// mode is the mode of s2k function. | ||||
| 	// It can be 0 (simple), 1(salted), 3(iterated) | ||||
| 	// 2(reserved) 100-110(private/experimental). | ||||
| 	mode uint8 | ||||
| 	// hashId is the ID of the hash function used in any of the modes | ||||
| 	hashId byte | ||||
| 	// salt is a byte array to use as a salt in hashing process | ||||
| 	salt []byte | ||||
| 	// countByte is used to determine how many rounds of hashing are to | ||||
| 	// be performed in s2k mode 3. See RFC 4880 Section 3.7.1.3. | ||||
| 	countByte byte | ||||
| } | ||||
|  | ||||
| func (c *Config) hash() crypto.Hash { | ||||
| 	if c == nil || uint(c.Hash) == 0 { | ||||
| 		return crypto.SHA256 | ||||
| 	} | ||||
|  | ||||
| 	return c.Hash | ||||
| } | ||||
|  | ||||
| // EncodedCount get encoded count | ||||
| func (c *Config) EncodedCount() uint8 { | ||||
| 	if c == nil || c.S2KCount == 0 { | ||||
| 		return 224 // The common case. Corresponding to 16777216 | ||||
| 	} | ||||
|  | ||||
| 	i := c.S2KCount | ||||
|  | ||||
| 	switch { | ||||
| 	case i < 65536: | ||||
| 		i = 65536 | ||||
| 	case i > 65011712: | ||||
| 		i = 65011712 | ||||
| 	} | ||||
|  | ||||
| 	return encodeCount(i) | ||||
| } | ||||
|  | ||||
| // encodeCount converts an iterative "count" in the range 1024 to | ||||
| // 65011712, inclusive, to an encoded count. The return value is the | ||||
| // octet that is actually stored in the GPG file. encodeCount panics | ||||
| // if i is not in the above range (encodedCount above takes care to | ||||
| // pass i in the correct range). See RFC 4880 Section 3.7.7.1. | ||||
| func encodeCount(i int) uint8 { | ||||
| 	if i < 65536 || i > 65011712 { | ||||
| 		panic("count arg i outside the required range") | ||||
| 	} | ||||
|  | ||||
| 	for encoded := 96; encoded < 256; encoded++ { | ||||
| 		count := decodeCount(uint8(encoded)) | ||||
| 		if count >= i { | ||||
| 			return uint8(encoded) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 255 | ||||
| } | ||||
|  | ||||
| // decodeCount returns the s2k mode 3 iterative "count" corresponding to | ||||
| // the encoded octet c. | ||||
| func decodeCount(c uint8) int { | ||||
| 	return (16 + int(c&15)) << (uint32(c>>4) + 6) | ||||
| } | ||||
|  | ||||
| // Simple writes to out the result of computing the Simple S2K function (RFC | ||||
| // 4880, section 3.7.1.1) using the given hash and input passphrase. | ||||
| func Simple(out []byte, h hash.Hash, in []byte) { | ||||
| 	Salted(out, h, in, nil) | ||||
| } | ||||
|  | ||||
| var zero [1]byte | ||||
|  | ||||
| // Salted writes to out the result of computing the Salted S2K function (RFC | ||||
| // 4880, section 3.7.1.2) using the given hash, input passphrase and salt. | ||||
| func Salted(out []byte, h hash.Hash, in []byte, salt []byte) { | ||||
| 	done := 0 | ||||
| 	var digest []byte | ||||
|  | ||||
| 	for i := 0; done < len(out); i++ { | ||||
| 		h.Reset() | ||||
| 		for j := 0; j < i; j++ { | ||||
| 			h.Write(zero[:]) | ||||
| 		} | ||||
| 		h.Write(salt) | ||||
| 		h.Write(in) | ||||
| 		digest = h.Sum(digest[:0]) | ||||
| 		n := copy(out[done:], digest) | ||||
| 		done += n | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Iterated writes to out the result of computing the Iterated and Salted S2K | ||||
| // function (RFC 4880, section 3.7.1.3) using the given hash, input passphrase, | ||||
| // salt and iteration count. | ||||
| func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) { | ||||
| 	combined := make([]byte, len(in)+len(salt)) | ||||
| 	copy(combined, salt) | ||||
| 	copy(combined[len(salt):], in) | ||||
|  | ||||
| 	if count < len(combined) { | ||||
| 		count = len(combined) | ||||
| 	} | ||||
|  | ||||
| 	done := 0 | ||||
| 	var digest []byte | ||||
| 	for i := 0; done < len(out); i++ { | ||||
| 		h.Reset() | ||||
| 		for j := 0; j < i; j++ { | ||||
| 			h.Write(zero[:]) | ||||
| 		} | ||||
| 		written := 0 | ||||
| 		for written < count { | ||||
| 			if written+len(combined) > count { | ||||
| 				todo := count - written | ||||
| 				h.Write(combined[:todo]) | ||||
| 				written = count | ||||
| 			} else { | ||||
| 				h.Write(combined) | ||||
| 				written += len(combined) | ||||
| 			} | ||||
| 		} | ||||
| 		digest = h.Sum(digest[:0]) | ||||
| 		n := copy(out[done:], digest) | ||||
| 		done += n | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Generate generates valid parameters from given configuration. | ||||
| // It will enforce salted + hashed s2k method | ||||
| func Generate(rand io.Reader, c *Config) (*Params, error) { | ||||
| 	hashId, ok := HashToHashId(c.Hash) | ||||
| 	if !ok { | ||||
| 		return nil, errors.UnsupportedError("no such hash") | ||||
| 	} | ||||
|  | ||||
| 	params := &Params{ | ||||
| 		mode:      3, // Enforce iterared + salted method | ||||
| 		hashId:    hashId, | ||||
| 		salt:      make([]byte, 8), | ||||
| 		countByte: c.EncodedCount(), | ||||
| 	} | ||||
|  | ||||
| 	if _, err := io.ReadFull(rand, params.salt); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return params, nil | ||||
| } | ||||
|  | ||||
| // Parse reads a binary specification for a string-to-key transformation from r | ||||
| // and returns a function which performs that transform. If the S2K is a special | ||||
| // GNU extension that indicates that the private key is missing, then the error | ||||
| // returned is errors.ErrDummyPrivateKey. | ||||
| func Parse(r io.Reader) (f func(out, in []byte), err error) { | ||||
| 	params, err := ParseIntoParams(r) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return params.Function() | ||||
| } | ||||
|  | ||||
| // ParseIntoParams reads a binary specification for a string-to-key | ||||
| // transformation from r and returns a struct describing the s2k parameters. | ||||
| func ParseIntoParams(r io.Reader) (params *Params, err error) { | ||||
| 	var buf [9]byte | ||||
|  | ||||
| 	_, err = io.ReadFull(r, buf[:2]) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	params = &Params{ | ||||
| 		mode:   buf[0], | ||||
| 		hashId: buf[1], | ||||
| 	} | ||||
|  | ||||
| 	switch params.mode { | ||||
| 	case 0: | ||||
| 		return params, nil | ||||
| 	case 1: | ||||
| 		_, err = io.ReadFull(r, buf[:8]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		params.salt = buf[:8] | ||||
| 		return params, nil | ||||
| 	case 3: | ||||
| 		_, err = io.ReadFull(r, buf[:9]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		params.salt = buf[:8] | ||||
| 		params.countByte = buf[8] | ||||
| 		return params, nil | ||||
| 	case 101: | ||||
| 		// This is a GNU extension. See | ||||
| 		// https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=doc/DETAILS;h=fe55ae16ab4e26d8356dc574c9e8bc935e71aef1;hb=23191d7851eae2217ecdac6484349849a24fd94a#l1109 | ||||
| 		if _, err = io.ReadFull(r, buf[:4]); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if buf[0] == 'G' && buf[1] == 'N' && buf[2] == 'U' && buf[3] == 1 { | ||||
| 			return params, nil | ||||
| 		} | ||||
| 		return nil, errors.UnsupportedError("GNU S2K extension") | ||||
| 	} | ||||
|  | ||||
| 	return nil, errors.UnsupportedError("S2K function") | ||||
| } | ||||
|  | ||||
| func (params *Params) Dummy() bool { | ||||
| 	return params != nil && params.mode == 101 | ||||
| } | ||||
|  | ||||
| func (params *Params) Function() (f func(out, in []byte), err error) { | ||||
| 	if params.Dummy() { | ||||
| 		return nil, errors.ErrDummyPrivateKey("dummy key found") | ||||
| 	} | ||||
| 	hashObj, ok := HashIdToHash(params.hashId) | ||||
| 	if !ok { | ||||
| 		return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(params.hashId))) | ||||
| 	} | ||||
| 	if !hashObj.Available() { | ||||
| 		return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashObj))) | ||||
| 	} | ||||
|  | ||||
| 	switch params.mode { | ||||
| 	case 0: | ||||
| 		f := func(out, in []byte) { | ||||
| 			Simple(out, hashObj.New(), in) | ||||
| 		} | ||||
|  | ||||
| 		return f, nil | ||||
| 	case 1: | ||||
| 		f := func(out, in []byte) { | ||||
| 			Salted(out, hashObj.New(), in, params.salt) | ||||
| 		} | ||||
|  | ||||
| 		return f, nil | ||||
| 	case 3: | ||||
| 		f := func(out, in []byte) { | ||||
| 			Iterated(out, hashObj.New(), in, params.salt, decodeCount(params.countByte)) | ||||
| 		} | ||||
|  | ||||
| 		return f, nil | ||||
| 	} | ||||
|  | ||||
| 	return nil, errors.UnsupportedError("S2K function") | ||||
| } | ||||
|  | ||||
| func (params *Params) Serialize(w io.Writer) (err error) { | ||||
| 	if _, err = w.Write([]byte{params.mode}); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if _, err = w.Write([]byte{params.hashId}); err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	if params.Dummy() { | ||||
| 		_, err = w.Write(append([]byte("GNU"), 1)) | ||||
| 		return | ||||
| 	} | ||||
| 	if params.mode > 0 { | ||||
| 		if _, err = w.Write(params.salt); err != nil { | ||||
| 			return | ||||
| 		} | ||||
| 		if params.mode == 3 { | ||||
| 			_, err = w.Write([]byte{params.countByte}) | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // Serialize salts and stretches the given passphrase and writes the | ||||
| // resulting key into key. It also serializes an S2K descriptor to | ||||
| // w. The key stretching can be configured with c, which may be | ||||
| // nil. In that case, sensible defaults will be used. | ||||
| func Serialize(w io.Writer, key []byte, rand io.Reader, passphrase []byte, c *Config) error { | ||||
| 	params, err := Generate(rand, c) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = params.Serialize(w) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	f, err := params.Function() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	f(key, passphrase) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // HashIdToHash returns a crypto.Hash which corresponds to the given OpenPGP | ||||
| // hash id. | ||||
| func HashIdToHash(id byte) (h crypto.Hash, ok bool) { | ||||
| 	if hash, ok := algorithm.HashById[id]; ok { | ||||
| 		return hash.HashFunc(), true | ||||
| 	} | ||||
| 	return 0, false | ||||
| } | ||||
|  | ||||
| // HashIdToString returns the name of the hash function corresponding to the | ||||
| // given OpenPGP hash id. | ||||
| func HashIdToString(id byte) (name string, ok bool) { | ||||
| 	if hash, ok := algorithm.HashById[id]; ok { | ||||
| 		return hash.String(), true | ||||
| 	} | ||||
| 	return "", false | ||||
| } | ||||
|  | ||||
| // HashIdToHash returns an OpenPGP hash id which corresponds the given Hash. | ||||
| func HashToHashId(h crypto.Hash) (id byte, ok bool) { | ||||
| 	for id, hash := range algorithm.HashById { | ||||
| 		if hash.HashFunc() == h { | ||||
| 			return id, true | ||||
| 		} | ||||
| 	} | ||||
| 	return 0, false | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Norwin
					Norwin