From: Joey Hess Date: Tue, 9 Jan 2024 19:31:53 +0000 (-0400) Subject: assistant: When generating a gpg secret key, avoid hardcoding the key algorithm and... X-Git-Tag: archive/raspbian/10.20250416-2+rpi1~1^2~29^2~62 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=de6a297d3643b7085c2166ec5eef296bd0fa4692;p=git-annex.git assistant: When generating a gpg secret key, avoid hardcoding the key algorithm and size This aims to future-proof gpg key generation. OpenPGP is in flux with a conflict over standards ongoing. It seems not unlikely that different systems will have different gpg commands that support different algorithms. This also simplifies the code by using the --quick-gen-key interface rather than the experimental batch interface. It seems less likely that --quick-gen-key will break than an experimental interface (whose documentation I can no longer find). --quick-gen-key is supported since gpg 2.1.0 (2014). Sponsored-by: Graham Spencer on Patreon --- diff --git a/Assistant/WebApp/Gpg.hs b/Assistant/WebApp/Gpg.hs index 3723d03907..79c36a2e0e 100644 --- a/Assistant/WebApp/Gpg.hs +++ b/Assistant/WebApp/Gpg.hs @@ -54,7 +54,7 @@ withNewSecretKey :: (KeyId -> Handler Html) -> Handler Html withNewSecretKey use = do cmd <- liftAnnex $ gpgCmd <$> Annex.getGitConfig userid <- liftIO $ newUserId cmd - liftIO $ genSecretKey cmd RSA "" userid maxRecommendedKeySize + liftIO $ genSecretKey cmd "" userid results <- M.keys . M.filter (== userid) <$> liftIO (secretKeys cmd) case results of [] -> giveup "Failed to generate gpg key!" diff --git a/CHANGELOG b/CHANGELOG index 3790992b0a..60aee29a07 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ git-annex (10.20231228) UNRELEASED; urgency=medium * info: Added "annex sizes of repositories" table to the overall display. * import: Sped up import from special remotes. + * assistant: When generating a gpg secret key, avoid hardcoding the + key algorithm and size. -- Joey Hess Fri, 29 Dec 2023 11:52:06 -0400 diff --git a/Utility/Gpg.hs b/Utility/Gpg.hs index 288499ff8e..7a62066bb6 100644 --- a/Utility/Gpg.hs +++ b/Utility/Gpg.hs @@ -23,8 +23,6 @@ module Utility.Gpg ( findPubKeys, UserId, secretKeys, - KeyType(..), - maxRecommendedKeySize, genSecretKey, genRandom, testKeyId, @@ -60,6 +58,8 @@ newtype KeyIds = KeyIds { keyIds :: [KeyId] } newtype GpgCmd = GpgCmd { unGpgCmd :: String } +type Passphrase = B.ByteString + {- Get gpg command to use, Just what's specified or, if a specific gpg - command was found at configure time, use it, or otherwise, "gpg". -} mkGpgCmd :: Maybe FilePath -> GpgCmd @@ -157,7 +157,7 @@ pipeStrict' (GpgCmd cmd) params environ input = do - the passphrase. - - Note that the reader must fully consume gpg's input before returning. -} -feedRead :: (MonadIO m, MonadMask m) => GpgCmd -> [CommandParam] -> B.ByteString -> (Handle -> IO ()) -> (Handle -> m a) -> m a +feedRead :: (MonadIO m, MonadMask m) => GpgCmd -> [CommandParam] -> Passphrase -> (Handle -> IO ()) -> (Handle -> m a) -> m a feedRead cmd params passphrase feeder reader = do #ifndef mingw32_HOST_OS let setup = liftIO $ do @@ -260,49 +260,29 @@ secretKeys cmd = catchDefaultIO M.empty makemap extract c k (_:rest) = extract c k rest -type Passphrase = String -type Size = Int -data KeyType = Algo Int | DSA | RSA - -{- The maximum key size that gpg currently offers in its UI when - - making keys. -} -maxRecommendedKeySize :: Size -maxRecommendedKeySize = 4096 - {- Generates a secret key using the experimental batch mode. - The key is added to the secret key ring. - Can take a very long time, depending on system entropy levels. -} -genSecretKey :: GpgCmd -> KeyType -> Passphrase -> UserId -> Size -> IO () -genSecretKey (GpgCmd cmd) keytype passphrase userid keysize = - let p = (proc cmd params) - { std_in = CreatePipe } - in withCreateProcess p (go p) +genSecretKey :: GpgCmd -> Passphrase -> UserId -> IO () +genSecretKey gpgcmd passphrase userid = + feedRead gpgcmd params passphrase feeder reader where - params = ["--batch", "--gen-key"] - - go p (Just h) _ _ pid = do - hPutStr h $ unlines $ catMaybes - [ Just $ "Key-Type: " ++ - case keytype of - DSA -> "DSA" - RSA -> "RSA" - Algo n -> show n - , Just $ "Key-Length: " ++ show keysize - , Just $ "Name-Real: " ++ userid - , Just "Expire-Date: 0" - , if null passphrase - then Nothing - else Just $ "Passphrase: " ++ passphrase - ] - hClose h - forceSuccessProcess p pid - go _ _ _ _ _ = error "internal" + params = + [ Param "--batch" + , Param "--quick-gen-key" + , Param userid + , Param "default" -- algo + , Param "default" -- usage + , Param "never" -- expire + ] + feeder = hClose + reader = void . hGetContents {- Creates a block of high-quality random data suitable to use as a cipher. - It is armored, to avoid newlines, since gpg only reads ciphers up to the - first newline. -} -genRandom :: GpgCmd -> Bool -> Size -> IO B.ByteString +genRandom :: GpgCmd -> Bool -> Int -> IO B.ByteString genRandom cmd highQuality size = do s <- readStrict cmd params checksize s diff --git a/templates/configurators/genkeymodal.hamlet b/templates/configurators/genkeymodal.hamlet index 23c3863054..b8f47cb513 100644 --- a/templates/configurators/genkeymodal.hamlet +++ b/templates/configurators/genkeymodal.hamlet @@ -5,7 +5,7 @@

# - Generating a #{maxRecommendedKeySize} bit GnuPg key. + Generating a GnuPg key.

Generating a GnuPg key can take a long time. To speed up the process, #