github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/saltpack_enc.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package libkb 5 6 import ( 7 "errors" 8 "io" 9 10 "github.com/keybase/saltpack" 11 ) 12 13 type SaltpackEncryptArg struct { 14 Source io.Reader 15 Sink io.WriteCloser 16 Receivers []NaclDHKeyPublic 17 Sender NaclDHKeyPair 18 SenderSigning NaclSigningKeyPair 19 Binary bool 20 EncryptionOnlyMode bool 21 SymmetricReceivers []saltpack.ReceiverSymmetricKey 22 SaltpackVersion saltpack.Version 23 24 VisibleRecipientsForTesting bool 25 } 26 27 // SaltpackEncrypt reads from the given source, encrypts it for the given 28 // receivers from the given sender, and writes it to sink. If 29 // Binary is false, the data written to sink will be armored. 30 func SaltpackEncrypt(m MetaContext, arg *SaltpackEncryptArg) error { 31 var receiverBoxKeys []saltpack.BoxPublicKey 32 for _, k := range arg.Receivers { 33 // Since signcryption became the default, we never use visible 34 // recipients in encryption mode, except in tests. 35 if arg.VisibleRecipientsForTesting { 36 receiverBoxKeys = append(receiverBoxKeys, naclBoxPublicKey(k)) 37 } else { 38 receiverBoxKeys = append(receiverBoxKeys, hiddenNaclBoxPublicKey(k)) 39 } 40 } 41 42 var bsk saltpack.BoxSecretKey 43 if !arg.Sender.IsNil() { 44 bsk = naclBoxSecretKey(arg.Sender) 45 } 46 47 // If the version is unspecified, default to the current version. 48 saltpackVersion := arg.SaltpackVersion 49 if saltpackVersion == (saltpack.Version{}) { 50 saltpackVersion = saltpack.CurrentVersion() 51 } 52 53 var plainsink io.WriteCloser 54 var err error 55 if !arg.EncryptionOnlyMode { 56 if arg.SaltpackVersion.Major == 1 { 57 return errors.New("specifying saltpack version 1 requires repudiable authentication") 58 } 59 var signer saltpack.SigningSecretKey 60 if !arg.SenderSigning.IsNil() { 61 signer = saltSigner{arg.SenderSigning} 62 } 63 if arg.Binary { 64 plainsink, err = saltpack.NewSigncryptSealStream(arg.Sink, emptyKeyring{}, signer, receiverBoxKeys, arg.SymmetricReceivers) 65 } else { 66 plainsink, err = saltpack.NewSigncryptArmor62SealStream(arg.Sink, emptyKeyring{}, signer, receiverBoxKeys, arg.SymmetricReceivers, KeybaseSaltpackBrand) 67 } 68 } else { 69 if arg.Binary { 70 plainsink, err = saltpack.NewEncryptStream(saltpackVersion, arg.Sink, bsk, receiverBoxKeys) 71 } else { 72 plainsink, err = saltpack.NewEncryptArmor62Stream(saltpackVersion, arg.Sink, bsk, receiverBoxKeys, KeybaseSaltpackBrand) 73 } 74 } 75 if err != nil { 76 return err 77 } 78 79 n, err := io.Copy(plainsink, arg.Source) 80 if err != nil { 81 return err 82 } 83 84 m.Debug("Encrypt: wrote %d bytes", n) 85 86 if err := plainsink.Close(); err != nil { 87 return err 88 } 89 return arg.Sink.Close() 90 }