diff --git a/CHANGELOG b/CHANGELOG index 60aee29a07..7e2796be3f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,8 @@ git-annex (10.20231228) UNRELEASED; urgency=medium * import: Sped up import from special remotes. * assistant: When generating a gpg secret key, avoid hardcoding the key algorithm and size. + * test: Test a specified Stateless OpenPGP command when + run with eg --test-git-config annex.shared-sop-command=sqop -- Joey Hess Fri, 29 Dec 2023 11:52:06 -0400 diff --git a/Test.hs b/Test.hs index 9856974d78..75a963ca87 100644 --- a/Test.hs +++ b/Test.hs @@ -27,6 +27,7 @@ import Control.Concurrent.STM hiding (check) import Common import CmdLine.GitAnnex.Options import qualified Utility.RawFilePath as R +import Data.String import qualified Utility.ShellEscape import qualified Annex @@ -82,6 +83,7 @@ import qualified Utility.FileSystemEncoding import qualified Utility.Aeson import qualified Utility.CopyFile import qualified Utility.MoveFile +import qualified Utility.StatelessOpenPGP import qualified Types.Remote #ifndef mingw32_HOST_OS import qualified Remote.Helper.Encryptable @@ -347,7 +349,8 @@ repoTests note numparts = map mk $ sep , testCase "rsync remote" test_rsync_remote , testCase "bup remote" test_bup_remote , testCase "borg remote" test_borg_remote - , testCase "crypto" test_crypto + , testCase "gpg crypto" test_gpg_crypto + , testCase "sop crypto" test_sop_crypto , testCase "preferred content" test_preferred_content , testCase "required_content" test_required_content , testCase "add subdirs" test_add_subdirs @@ -1824,10 +1827,29 @@ test_borg_remote = when BuildInfo.borg $ do git_annex "drop" [annexedfile] "drop from borg (appendonly)" git_annex "get" [annexedfile, "--from=borg"] "get from borg" +-- To test Stateless OpenPGP, annex.shared-sop-command has to be set using +-- the --test-git-config option. +test_sop_crypto :: Assertion +test_sop_crypto = do + gc <- testGitConfig . testOptions <$> getTestMode + case filter (\(k, _) -> k == ck) gc of + [] -> noop + ((_, sopcmd):_) -> go $ + Utility.StatelessOpenPGP.SopCmd $ + Git.Types.fromConfigValue sopcmd + where + ck = fromString "annex.shared-sop-command" + pw = fromString "testpassword" + v = fromString "somevalue" + unarmored = Utility.StatelessOpenPGP.Armoring False + go sopcmd = do + Utility.StatelessOpenPGP.test_encrypt_decrypt_Symmetric sopcmd sopcmd pw unarmored v + @? "sop command roundtrips symmetric encryption" + -- gpg is not a build dependency, so only test when it's available -test_crypto :: Assertion +test_gpg_crypto :: Assertion #ifndef mingw32_HOST_OS -test_crypto = do +test_gpg_crypto = do testscheme "shared" testscheme "hybrid" testscheme "pubkey" diff --git a/Types/GitConfig.hs b/Types/GitConfig.hs index 6ded7b6df3..cb8ecdf003 100644 --- a/Types/GitConfig.hs +++ b/Types/GitConfig.hs @@ -372,6 +372,8 @@ data RemoteGitConfig = RemoteGitConfig , remoteAnnexRsyncTransport :: [String] , remoteAnnexGnupgOptions :: [String] , remoteAnnexGnupgDecryptOptions :: [String] + , remoteAnnexSharedSOPCommand :: Maybe String + , remoteAnnexSharedSOPProfile :: Maybe String , remoteAnnexRsyncUrl :: Maybe String , remoteAnnexBupRepo :: Maybe String , remoteAnnexBorgRepo :: Maybe String @@ -439,6 +441,8 @@ extractRemoteGitConfig r remotename = do , remoteAnnexRsyncTransport = getoptions "rsync-transport" , remoteAnnexGnupgOptions = getoptions "gnupg-options" , remoteAnnexGnupgDecryptOptions = getoptions "gnupg-decrypt-options" + , remoteAnnexSharedSOPCommand = notempty $ getmaybe "shared-sop-command" + , remoteAnnexSharedSOPProfile = notempty $ getmaybe "shared-sop-profile" , remoteAnnexRsyncUrl = notempty $ getmaybe "rsyncurl" , remoteAnnexBupRepo = getmaybe "buprepo" , remoteAnnexBorgRepo = getmaybe "borgrepo" diff --git a/Utility/StatelessOpenPGP.hs b/Utility/StatelessOpenPGP.hs index e6ca08b54c..dfee3ec3c5 100644 --- a/Utility/StatelessOpenPGP.hs +++ b/Utility/StatelessOpenPGP.hs @@ -9,6 +9,10 @@ module Utility.StatelessOpenPGP ( SopCmd(..), + SopSubCmd, + Password, + Profile, + Armoring(..), encryptSymmetric, decryptSymmetric, test_encrypt_decrypt_Symmetric, @@ -98,7 +102,7 @@ decryptSymmetric sopcmd password emptydirectory feeder reader = {- Test a value round-trips through symmetric encryption and decryption. -} test_encrypt_decrypt_Symmetric :: SopCmd -> SopCmd -> Password -> Armoring -> B.ByteString -> IO Bool -test_encrypt_decrypt_Symmetric a b password armoring v = +test_encrypt_decrypt_Symmetric a b password armoring v = catchBoolIO $ withTmpDir "test" $ \d -> do let ed = EmptyDirectory d enc <- encryptSymmetric a password ed Nothing armoring diff --git a/doc/encryption.mdwn b/doc/encryption.mdwn index 50d479b898..970232d216 100644 --- a/doc/encryption.mdwn +++ b/doc/encryption.mdwn @@ -76,6 +76,14 @@ The advantage is you don't need to set up gpg keys. The disadvantage is that this is **insecure** unless you trust every clone of the git repository with access to the encrypted data stored in the special remote. +By default `gpg` is used for shared encryption, but it is also possible to +use other programs that implement the Stateless OpenPGP command line +interface. For example, to use Sequoia PGP's `sqop` command, configured to +be backwards compatable with `gpg`: + + git config annex.shared-sop-command sqop + git config annex.shared-sop-profile rfc4880 + ## regular public key encryption (encryption=pubkey) This alternative simply encrypts the files in the special remotes to one or diff --git a/doc/git-annex-test.mdwn b/doc/git-annex-test.mdwn index 18a219c6b2..83bdc5bd3e 100644 --- a/doc/git-annex-test.mdwn +++ b/doc/git-annex-test.mdwn @@ -44,6 +44,10 @@ framework. Pass --help for details about those. One valid use of this is to change a git configuration to a value that is planned to be the new default in a future version of git. + Also, some things can only be tested with a git configuration. For + example, annex.shared-sop-command has to be set for the test suite to + test using that command. + * `--test-debug` Normally output of commands run by the test suite is hidden, so even diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn index 5f43deb1ee..deeb4703ea 100644 --- a/doc/git-annex.mdwn +++ b/doc/git-annex.mdwn @@ -1655,10 +1655,29 @@ Remotes are configured using these settings in `.git/config`. precedence over the default GnuPG configuration, which is otherwise used.) +* `remote..annex-shared-sop-command` + + Use this command, which is an implementation of the Stateless OpenPGP + command line interface, rather than GnuPG for encrypting and decrypting + data. This is only used when a special remote is configured with + encryption=shared. + + For example, to use Sequoia PGP's sqop command, set this to "sqop". + +* `remote..annex-shared-sop-profile` + + When encrypting with a Stateless OpenPGP command, this can be used + to specify the profile to use, such as "rfc4880". + + For a list of available profiles, run eg "sqop list-profiles encrypt" + + sqop list-profiles encrypt + * `annex.ssh-options`, `annex.rsync-options`, `annex.rsync-upload-options`, `annex.rsync-download-options`, `annex.bup-split-options`, `annex.gnupg-options`, - `annex.gnupg-decrypt-options` + `annex.gnupg-decrypt-options`, + `annex.shared-sop-command`, `annex.shared-sop-profile` Default options to use if a remote does not have more specific options as described above.