test annex.shared-sop-command

Test a specified Stateless OpenPGP command with eg:
git-annex test --test-git-config annex.shared-sop-command=sqop

Also documented that config and another one, but so far only the test suite
uses the configs, have not yet implemented using it for actual symmetric
encryption.

Sponsored-by: Joshua Antonishen on Patreon
This commit is contained in:
Joey Hess 2024-01-10 16:30:38 -04:00
parent 812cbf0e17
commit d98f02a5b0
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
7 changed files with 68 additions and 5 deletions

View file

@ -4,6 +4,8 @@ git-annex (10.20231228) UNRELEASED; urgency=medium
* import: Sped up import from special remotes. * import: Sped up import from special remotes.
* assistant: When generating a gpg secret key, avoid hardcoding the * assistant: When generating a gpg secret key, avoid hardcoding the
key algorithm and size. 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 <id@joeyh.name> Fri, 29 Dec 2023 11:52:06 -0400 -- Joey Hess <id@joeyh.name> Fri, 29 Dec 2023 11:52:06 -0400

28
Test.hs
View file

@ -27,6 +27,7 @@ import Control.Concurrent.STM hiding (check)
import Common import Common
import CmdLine.GitAnnex.Options import CmdLine.GitAnnex.Options
import qualified Utility.RawFilePath as R import qualified Utility.RawFilePath as R
import Data.String
import qualified Utility.ShellEscape import qualified Utility.ShellEscape
import qualified Annex import qualified Annex
@ -82,6 +83,7 @@ import qualified Utility.FileSystemEncoding
import qualified Utility.Aeson import qualified Utility.Aeson
import qualified Utility.CopyFile import qualified Utility.CopyFile
import qualified Utility.MoveFile import qualified Utility.MoveFile
import qualified Utility.StatelessOpenPGP
import qualified Types.Remote import qualified Types.Remote
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
import qualified Remote.Helper.Encryptable import qualified Remote.Helper.Encryptable
@ -347,7 +349,8 @@ repoTests note numparts = map mk $ sep
, testCase "rsync remote" test_rsync_remote , testCase "rsync remote" test_rsync_remote
, testCase "bup remote" test_bup_remote , testCase "bup remote" test_bup_remote
, testCase "borg remote" test_borg_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 "preferred content" test_preferred_content
, testCase "required_content" test_required_content , testCase "required_content" test_required_content
, testCase "add subdirs" test_add_subdirs , 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 "drop" [annexedfile] "drop from borg (appendonly)"
git_annex "get" [annexedfile, "--from=borg"] "get from borg" 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 -- gpg is not a build dependency, so only test when it's available
test_crypto :: Assertion test_gpg_crypto :: Assertion
#ifndef mingw32_HOST_OS #ifndef mingw32_HOST_OS
test_crypto = do test_gpg_crypto = do
testscheme "shared" testscheme "shared"
testscheme "hybrid" testscheme "hybrid"
testscheme "pubkey" testscheme "pubkey"

View file

@ -372,6 +372,8 @@ data RemoteGitConfig = RemoteGitConfig
, remoteAnnexRsyncTransport :: [String] , remoteAnnexRsyncTransport :: [String]
, remoteAnnexGnupgOptions :: [String] , remoteAnnexGnupgOptions :: [String]
, remoteAnnexGnupgDecryptOptions :: [String] , remoteAnnexGnupgDecryptOptions :: [String]
, remoteAnnexSharedSOPCommand :: Maybe String
, remoteAnnexSharedSOPProfile :: Maybe String
, remoteAnnexRsyncUrl :: Maybe String , remoteAnnexRsyncUrl :: Maybe String
, remoteAnnexBupRepo :: Maybe String , remoteAnnexBupRepo :: Maybe String
, remoteAnnexBorgRepo :: Maybe String , remoteAnnexBorgRepo :: Maybe String
@ -439,6 +441,8 @@ extractRemoteGitConfig r remotename = do
, remoteAnnexRsyncTransport = getoptions "rsync-transport" , remoteAnnexRsyncTransport = getoptions "rsync-transport"
, remoteAnnexGnupgOptions = getoptions "gnupg-options" , remoteAnnexGnupgOptions = getoptions "gnupg-options"
, remoteAnnexGnupgDecryptOptions = getoptions "gnupg-decrypt-options" , remoteAnnexGnupgDecryptOptions = getoptions "gnupg-decrypt-options"
, remoteAnnexSharedSOPCommand = notempty $ getmaybe "shared-sop-command"
, remoteAnnexSharedSOPProfile = notempty $ getmaybe "shared-sop-profile"
, remoteAnnexRsyncUrl = notempty $ getmaybe "rsyncurl" , remoteAnnexRsyncUrl = notempty $ getmaybe "rsyncurl"
, remoteAnnexBupRepo = getmaybe "buprepo" , remoteAnnexBupRepo = getmaybe "buprepo"
, remoteAnnexBorgRepo = getmaybe "borgrepo" , remoteAnnexBorgRepo = getmaybe "borgrepo"

View file

@ -9,6 +9,10 @@
module Utility.StatelessOpenPGP ( module Utility.StatelessOpenPGP (
SopCmd(..), SopCmd(..),
SopSubCmd,
Password,
Profile,
Armoring(..),
encryptSymmetric, encryptSymmetric,
decryptSymmetric, decryptSymmetric,
test_encrypt_decrypt_Symmetric, 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 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 :: 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 withTmpDir "test" $ \d -> do
let ed = EmptyDirectory d let ed = EmptyDirectory d
enc <- encryptSymmetric a password ed Nothing armoring enc <- encryptSymmetric a password ed Nothing armoring

View file

@ -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 that this is **insecure** unless you trust every clone of the git
repository with access to the encrypted data stored in the special remote. 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) ## regular public key encryption (encryption=pubkey)
This alternative simply encrypts the files in the special remotes to one or This alternative simply encrypts the files in the special remotes to one or

View file

@ -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 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. 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` * `--test-debug`
Normally output of commands run by the test suite is hidden, so even Normally output of commands run by the test suite is hidden, so even

View file

@ -1655,10 +1655,29 @@ Remotes are configured using these settings in `.git/config`.
precedence over the default GnuPG configuration, which is otherwise precedence over the default GnuPG configuration, which is otherwise
used.) used.)
* `remote.<name>.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.<name>.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.ssh-options`, `annex.rsync-options`,
`annex.rsync-upload-options`, `annex.rsync-download-options`, `annex.rsync-upload-options`, `annex.rsync-download-options`,
`annex.bup-split-options`, `annex.gnupg-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 Default options to use if a remote does not have more specific options
as described above. as described above.