/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/chat/attachments/crypt.go
158 строк
5 KB
zoom-ua
gofumpt (#28710)
17 дек 2025, 17:16
Не верифицирован
17 дек 2025, 17:16
cda510b
Код
Авторство
О чём код?
package attachments import ( "crypto/ed25519" "crypto/rand" "errors" "io" "github.com/keybase/client/go/chat/signencrypt" "github.com/keybase/client/go/kbcrypto" "github.com/keybase/client/go/libkb" ) type Encrypter interface { // EncryptedLen returns the number of bytes that the ciphertext of // size plaintext bytes will be. EncryptedLen(size int) int // Encrypt takes a plaintext reader and returns a ciphertext reader. // It generates new keys every time it is called and uses a // constant nonce. Encrypt(plaintext io.Reader) (ciphertext io.Reader, err error) // EncryptWithNonce takes a plaintext reader and returns a ciphertext reader. // It generates new keys every time it is called and uses // the provided nonce. EncryptWithNonce(plaintext io.Reader, nonce signencrypt.Nonce) (ciphertext io.Reader, err error) // EncryptResume takes a plaintext reader and a set of keys. It // returns a ciphertext reader. It *does not* generate new keys // but uses the parameter keys. These keys should *only* be used // to encrypt the same plaintext as a previous attempt. EncryptResume(r io.Reader, nonce signencrypt.Nonce, encKey signencrypt.SecretboxKey, signKey signencrypt.SignKey, verifyKey signencrypt.VerifyKey) (io.Reader, error) // EncryptKey returns the ephemeral key that was used during the // last invocation of Encrypt. EncryptKey() []byte // VerifyKey returns the public portion of the signing key used during // the last invocation of Encrypt. It can be used for signature // verification. VerifyKey() []byte } type Decrypter interface { // Decrypt takes a ciphertext reader, encryption and verify keys. // It returns a plaintext reader. It uses the constant nonce. Decrypt(ciphertext io.Reader, encKey, verifyKey []byte) (plaintext io.Reader) // DecryptWithNonce takes a ciphertext reader, nonce, encryption and verify keys. // It returns a plaintext reader. DecryptWithNonce(ciphertext io.Reader, nonce signencrypt.Nonce, encKey, verifyKey []byte) (plaintext io.Reader) } // The ASCII bytes "kbchatattachment". var nonceConst signencrypt.Nonce = &[16]byte{0x6b, 0x62, 0x63, 0x68, 0x61, 0x74, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74} type SignEncrypter struct { encKey signencrypt.SecretboxKey signKey signencrypt.SignKey verifyKey signencrypt.VerifyKey } func NewSignEncrypter() *SignEncrypter { return &SignEncrypter{} } func (s *SignEncrypter) EncryptedLen(size int64) int64 { return signencrypt.GetSealedSize(size) } func (s *SignEncrypter) Encrypt(r io.Reader) (io.Reader, error) { // It is *very* important that Encrypt calls makeKeys() to make // new keys every time it runs. The keys it uses cannot be reused // since we are using a constant nonce. if err := s.makeKeys(); err != nil { return nil, err } return signencrypt.NewEncodingReader(s.encKey, s.signKey, kbcrypto.SignaturePrefixChatAttachment, nonceConst, r), nil } func (s *SignEncrypter) EncryptWithNonce(r io.Reader, nonce signencrypt.Nonce) (io.Reader, error) { if err := s.makeKeys(); err != nil { return nil, err } return signencrypt.NewEncodingReader(s.encKey, s.signKey, kbcrypto.SignaturePrefixChatAttachment, nonce, r), nil } // EncryptResume is used to create a SignEncrypter to resume an interrupted attachment upload. // It is *very* important that the keys passed in are not used to encrypt different plaintext // than their original usage. func (s *SignEncrypter) EncryptResume(r io.Reader, nonce signencrypt.Nonce, encKey signencrypt.SecretboxKey, signKey signencrypt.SignKey, verifyKey signencrypt.VerifyKey) (io.Reader, error) { s.encKey = encKey s.signKey = signKey s.verifyKey = verifyKey return signencrypt.NewEncodingReader(s.encKey, s.signKey, kbcrypto.SignaturePrefixChatAttachment, nonce, r), nil } func (s *SignEncrypter) EncryptKey() []byte { return (*s.encKey)[:] } func (s *SignEncrypter) SignKey() []byte { return (*s.signKey)[:] } func (s *SignEncrypter) VerifyKey() []byte { return (*s.verifyKey)[:] } func (s *SignEncrypter) makeKeys() error { var encKey [signencrypt.SecretboxKeySize]byte n, err := rand.Read(encKey[:]) if err != nil { return err } if n != signencrypt.SecretboxKeySize { return errors.New("failed to rand.Read the correct number of bytes") } sign, err := libkb.GenerateNaclSigningKeyPair() if err != nil { return err } var signKey [ed25519.PrivateKeySize]byte copy(signKey[:], (*sign.Private)[:]) var verifyKey [ed25519.PublicKeySize]byte copy(verifyKey[:], sign.Public[:]) s.encKey = &encKey s.signKey = &signKey s.verifyKey = &verifyKey return nil } type SignDecrypter struct{} func NewSignDecrypter() *SignDecrypter { return &SignDecrypter{} } func (s *SignDecrypter) Decrypt(r io.Reader, encKey, verifyKey []byte) io.Reader { var xencKey [signencrypt.SecretboxKeySize]byte copy(xencKey[:], encKey) var xverifyKey [ed25519.PublicKeySize]byte copy(xverifyKey[:], verifyKey) return signencrypt.NewDecodingReader(&xencKey, &xverifyKey, kbcrypto.SignaturePrefixChatAttachment, nonceConst, r) } func (s *SignDecrypter) DecryptWithNonce(r io.Reader, nonce signencrypt.Nonce, encKey, verifyKey []byte) (plaintext io.Reader) { var xencKey [signencrypt.SecretboxKeySize]byte copy(xencKey[:], encKey) var xverifyKey [ed25519.PublicKeySize]byte copy(xverifyKey[:], verifyKey) return signencrypt.NewDecodingReader(&xencKey, &xverifyKey, kbcrypto.SignaturePrefixChatAttachment, nonce, r) }