Você pode não conseguir fazer isso, pelo menos não ainda, ou pelo menos não no caso geral. No entanto, compartilharei o que aprendi e espero atualizar essa resposta no devido tempo.
Primeiro, ao contrário do recurso ssh-agent
, que na verdade armazena em cache as chaves privadas, gpg-agent
pode armazenar em cache as chaves ou senhas. Cabe a cada cliente que armazenar em cache e gpg
usa apenas gpg-agent
para armazenar em cache a frase secreta.
Você pode interagir com gpg-agent
usando o utilitário gpg-connect-agent
. No exemplo a seguir, eu estou passando comandos um de cada vez via STDIN.
$ CACHEID="ThisIsTheTrickyPart"
$ ERRSTR="Error+string+goes+here"
$ PMTSTR="Prompt"
$ DESSTR="Description+string+goes+here"
$ echo "GET_PASSPHRASE --data $CACHEID $ERRSTR $PMTSTR $DESSTR" | gpg-connect-agent
D MyPassPhrase
OK
Ao invocar gpg-connect-agent
e passar este comando, o comando pinentry
configurado no meu sistema usa as strings de erro, prompt e descrição para solicitar uma frase secreta. Neste caso eu entrei em "MyPassPhrase" que é o que é retornado na saída estruturada (veja imagem abaixo) . Se eu enviar GET_PASSPHRASE
para gpg-agent
novamente com o mesmo $CACHEID
, ele retornará a frase secreta em cache em vez de usar pinentry
.
GET_PASSPHRASE
tambémaceitaaopção--no-ask
,queretornaráumerroemumafalhadecache.Aquieuuso"NotCachedID" como o ID do cache e uso strings fictícias para os argumentos necessários que o gpg-agent
não usará.
$ echo "GET_PASSPHRASE --no-ask NotCachedID Err Pmt Des" | gpg-connect-agent
ERR 67108922 No data <GPG Agent>
Em princípio, então, você poderia perguntar ao agente por cada frase-chave armazenada em cache e verificar se há OK
ou ERR
na saída. A questão então se torna, como eu gero o ID do cache? Como podemos ver no exemplo acima, gpg-agent
é liberal no que aceita como o ID do cache. Acontece que gpg
calcula uma impressão digital na chave pública e usa uma representação de cadeia hexadecimal como o ID do cache, mas o problema é que essa impressão digital não é igual à impressão digital que você pode aprender via gpg --fingerprint --list-secret-keys
. Esse resumo é chamado de keygrip (porque é calculado somente sobre o material-chave bruto, enquanto a impressão digital é calculada sobre o material-chave e o timestamp de criação). Se você realmente quiser continuar nesse caminho, você terá que descobrir como gerar a impressão digital correta para cada uma das chaves que deseja verificar (isso será fácil usando a próxima geração do GnuPG, 2.1, com a opção --with-keygrip
).
Aviso: A saída de GET_PASSPHRASE
na verdade contém a frase-senha in clear . Mesmo se você deixar de fora a opção --data
, a senha é claramente visível como uma string codificada em hexadecimal. É provavelmente uma Idéia Muito Ruim (tm) para se meter com isso a menos que você saiba o que está fazendo, e tome as devidas precauções.