注意:最高git 2.5,git verify-commit并且git verify-tag仅显示人类可读的消息。
如果要自动执行检查,git 2.6+(2015年第三季度)将添加另一个输出。
请参见brian m的提交e18443e,提交aeff29d,提交ca194d5,提交434060e,提交8e98e5f,提交a4cc18f,提交d66aeff(2015年6月21日)。卡尔森(bk2204)。
(由Junio C gitsterHamano合并--在commit ba12cb2中,2015年8月3日)
verify-tag/ verify-commit:添加选项以打印原始gpg状态信息
verify-tag/ verify-commit默认情况下显示标准错误时人类可读的输出。
但是,访问机器可读的原始gpg状态信息也很有用,它可以自动执行签名策略。
添加一个--raw选项,以verify-tag生成标准错误而不是人类可读格式的gpg状态信息。
加:
verify-tag如果签名正确但密钥不受信任,则成功退出。verify-commit退出失败。
这种行为上的差异是意外的和不希望的。
由于verify-tag存在较早,因此添加失败测试以具有verify-commitshare verify-tag的行为。
git 2.9(2016年6月)更新了git merge doc:
参见Keller Fuchs(``)的commit 05a5869(2016年5月13日)。
帮助:Junio C Hamano(gitster)。
(由Junio C gitsterHamano合并--在提交be6ec17中,2016年5月17日)
--verify-signatures:
--no-verify-signatures:
验证是否使用有效密钥(即具有有效uid的密钥)对
要合并的侧分支的尖端提交进行了签名:在默认信任模型中,这意味着签名密钥已由可信密钥签名。
如果未使用有效密钥对侧分支的尖端提交进行签名,则合并将中止。
更新Git 2.10(2016年第三季度)
参见Linus Torvalds()的commit b624a3e(2016年8月16日)。(由Junio C Hamano合并--在commit 83d9eb0中,2016年8月19日)torvalds
gitster
gpg-interface:在验证pgp签名时更喜欢“长”键格式输出
” git log --show-signature和其他显示PGP签名验证状态的命令现在显示更长的key-id,因为上个世纪32位key-id是如此。
Linus的原始版本经过重新设计,可以应用于维护跟踪,以防万一过去陷入困境的二进制分发者希望将其带入其较早的代码库。
Git 2.11+(2016年第四季度)将更加精确。
参见Michael J Gruber()提交661a180(2016年10月12日)。(由Junio C Hamano合并--在commit 56d268b中,2016年10月26日)mjg
gitster
%G?漂亮的格式说明符中显示的GPG验证状态不够丰富,无法区分由过期密钥生成的签名,由撤销密钥生成的签名等。
已分配了新的输出字母来表示它们。
根据gpg2的doc/DETAILS:
每个签名只有代码之一GOODSIG,BADSIG,EXPSIG,EXPKEYSIG,REVKEYSIG或ERRSIG将被发射。
该git pretty-format文档现在包括:
- '
%G?':显示
- ”
G ”(有效的签名),
- “
B”表示签名不正确,
- “
U”表示签名有效,但未知,
- “
X”表示有效的签名已过期,
- “
Y”表示已过期的密钥做出了很好的签名,
- “
R”,以获得被撤销的密钥的良好签名,
- “
E”如果签名不能被选中(如丢失密钥)和“N”表示没有签名
Git的2.12(Q1 2017)“ git tag”和“ git verify-tag” 学会把他们“GPG验证状态--format=<placeholders>”输出格式。
请参阅Santiago Torres()的commit 4fea72f,commit 02c5433和ff3c8c8(2017年1月17日)。
参见commit 07d347cSantiagoTorres
Lukas Puehringer(``)的,commit 2111aa7和commit 94240b9(2017年1月17日)。
(通过合并JUNIOÇ滨野- gitster-在提交237bdd9,2017年1月31日)
添加--format到git tag -v会使GPG验证的默认输出静音,而是打印格式化的标签对象。
这样,调用者就可以在GPG验证后,将引用/标记中的标记名与标记对象标头中的标记名进行交叉检查。
Git 2.16(Q1 2018)将允许使用merge.verifySignatures配置变量使提交签名验证更加自动化。
参见commit 7f8ca20,commit ca779e8 Hans Jerry Illikainen(``)的(2017年12月10日)。
(通过合并JUNIOÇ滨野- gitster-在提交0433d53 12月28日2017)
merge:为添加配置选项 verifySignatures
git merge --verify-signatures 可以用来验证要合并的分支的尖端提交是否已正确签名,但是每次都要指定该麻烦。
添加一个配置选项,该选项默认情况下启用此行为,可以被覆盖--no-verify-signatures。
现在,git merge配置手册页显示为:
merge.verifySignatures:
如果为true,则等效于--verify-signatures命令行选项。
Git 2.19(Q3 2018)更加有用,因为已经教会了“ git verify-tag”和“ git verify-commit”使用底层“ gpg --verify” 的退出状态来表示发现的错误或不可信签名。
注意:使用Git 2.19时gpg.format,可以将其设置为“ openpgp”或“x509 ”,并gpg.<format>.program用于指定要使用哪种程序来处理该格式),以允许通过“ gpgsm”(而不是openpgp通过)使用带有CMS的x.509证书。 “ gnupg”。
参见Junio C Hamano()提交4e5dc9c(2018年8月9日)。
帮助:Vojtech Myslivec(),布莱恩·米。卡尔森()和杰夫金()。(由Junio C Hamano合并--gitster
VojtechMyslivecbk2204peff
gitster Hamano在commit 4d34122中,2018年8月20日)
gpg-interface:将退出状态从gpg回传给呼叫者
当gpg-interface API在2015年中的v2.6.0-rc0〜114左右统一支持签名标签和签名提交的签名验证代码路径时,我们意外地松开了GPG签名验证。
在更改之前,通过G忽略GPG的退出签名来验证签名提交,而忽略gpg --verify进程的退出状态,而通过简单地传递退出状态来验证签名标签"gpg --verify。
我们当前拥有的统一代码会忽略“ gpg --verify” 的退出状态,并在签名与未过期的密钥匹配时返回成功的验证,而与密钥上的信任无关(即,除了G“ ood”之外,我们接受“ U” ntrusted“)。
当底层的“ gpg --verify”(或gpg.program配置变量“ ” 指定的自定义命令)这样做时,使这些命令以退出状态来表示失败。
这实质上以向后不兼容的方式更改了其行为,以拒绝使用不可信密钥进行的签名,即使它们正确地进行了验证也是如此,因为这是“ gpg --verify”行为。
请注意,如果输出未表明签名是正确的或计算正确但使用不受信任的密钥完成,则代码仍会覆盖从“ gpg”(或gpg.program)获得的零退出状态,以捕获gpg用户可能给我们的包装不良的包装。
我们可以U从此后备代码中排除不受信任的支持,但这将在一次提交中进行两个向后不兼容的更改,因此现在就避免这样做。
如果需要,可以进行后续更改。
在进行任何加密之前,需要对密钥进行信任/签名
在信任方面,我们取得了进步:
借助Git 2.26(2020年第一季度),gpg.minTrustLevel引入了配置变量,以告知各种签名验证代码路径所需的最低信任级别。
参见Hans Jerry Illikainen()提交的54887b4(2019年12月27日)。illikainen
(由Junio C gitsterHamano合并--在commit 11ad30b中,2020年1月30日)
签字人:汉斯·杰里·伊利卡宁
以前,如果关键还得的一个信托层次的合并和抽取操作签名验证检查TRUST_NEVER或TRUST_UNDEFINED在verify_merge_signature()。
如果是这样,则处理die()'d。
进行签名验证的其他代码路径完全依赖于的返回代码check_commit_signature()。
不论信任级别如何,使用好密钥进行的签名都被视为有效check_commit_signature()。
这种行为上的差异可能会导致用户错误地认为Git始终会考虑其密钥环中密钥的信任级别,即使对于没有使用密钥的操作(例如,verify-commit或verify-tag)也是如此。
它的工作方式是gpg-interface.c将密钥/签名状态和最低两个信任级别的结果存储在resultsignature_check结构成员中(遇到的这些状态行中的最后一个被写入result)。
这些已在GPG中的小节中记录 General status codes和Key related分别。
GPG文档在TRUST_ status代码中说明了以下内容:
这些是几个类似的状态代码:
- TRUST_UNDEFINED <error_token>
- TRUST_NEVER <error_token>
- TRUST_MARGINAL [0 [<validation_model>]]
- TRUST_FULLY [0 [<validation_model>]]
- TRUST_ULTIMATE [0 [<validation_model>]]
对于好的签名,发出这些状态行之一以指示用于创建签名的密钥的有效性。
错误令牌值当前仅由gpgsm发出。
我的解释是,信任级别在概念上与密钥和/或签名的有效性不同。
这似乎也是对旧代码的假设,check_signature()其中' G'(如GOODSIG)和' U'(如TRUST_NEVER或TRUST_UNDEFINED)都被视为成功)的结果。
在两种情况下的“结果U”有特殊的含义是在verify_merge_signature()(其中这引起了git到die()),并在format_commit_one()(它影响到的输出%G?格式说明)。
我认为重构行的处理是有意义的,TRUST_ status以便用户可以配置全局强制实施的最低信任级别,而不是让各个部分git(例如合并)自己完成(具有向后兼容性的宽限期除外)。
我还认为,不要将信任级别存储在与密钥/签名状态相同的结构成员中。
虽然TRUST_ status代码的存在确实意味着签名是好的(请参见上面随附的代码段的第一段),但据我所知,GPG状态行的顺序尚不明确;因此,如果将信任级别存储在signature_check结构的同一成员中,则可以用密钥/签名状态覆盖信任级别似乎是合理的。
该补丁引入了一个新的配置选项:gpg.minTrustLevel。
它将信任级别验证合并到该结构,并向该结构gpg-interface.c添加新trust_level成员signature_check。
向后兼容性是通过引入一种特殊情况来维护的,verify_merge_signature()因此,如果未gpg.minTrustLevel设置用户可配置的,则旧的拒绝TRUST_UNDEFINED和TRUST_NEVER强制执行。
另一方面,如果gpg.minTrustLevel已设置,则该值将覆盖旧的行为。
同样,%G?格式说明符将继续显示U对使用信任级别为TRUST_UNDEFINED或TRUST_NEVER,即使该结构成员中U不再存在' '字符的密钥进行签名的' ' 。 resultsignature_check
%GT还为希望显示签名的所有可能信任级别的用户引入了新的格式说明符。
另一种方法是简单地将中的信任级别要求删除verify_merge_signature()。
这也将使行为与执行签名验证的git其他部分一致。
但是,对于签名密钥要求最低的信任级别似乎确实具有实际用例。
例如,Qubes OS项目使用的构建系统当前解析来自verify-tag的原始输出,以便为用于签名git标签的密钥声明最小信任级别。
该git config gpg手册页现在包括:
gpg.minTrustLevel:
指定签名验证的最低信任级别。
如果未设置此选项,则用于合并操作的签名验证需要至少具有marginal信任关系的密钥。
执行签名验证的其他操作至少需要undefined信任的密钥。
设置此选项将覆盖所有操作所需的信任级别。支持的值,按升序排列:
undefined
never
marginal
fully
ultimate
在Git 2.26(Q1 2020)中,“ git show”和其他人在其错误输出中以原始格式给出了对象名称,该名称已被更正为十六进制。
show_one_mergetag:以十六进制形式打印非父级。
当合并标记命名为非父标记时(可能在浅克隆之后出现),其哈希值先前已作为原始数据打印。
而是以十六进制形式打印。
git -C shallow log --graph --show-signature -n1 plain-shallow经过测试git clone --depth 1 --no-local . shallow
在Git 2.27(2020年第二季度)中,与GnuPG交互的代码已重构。
参见Hans Jerry Illikainen()提交的6794898和f1e3df3(2020年3月4日)。(通过合并JUNIOÇ滨野- -在提交fa82be9 3月27日2020)illikainen
gitster
gpg-interface:首选check_signature()进行GPG验证
签字人:汉斯·杰里·伊利卡宁
该提交将重构verify_signed_buffer()外部gpg-interface.c使用check_signature()代替。
它也变成verify_signed_buffer()了文件本地函数,因为现在它仅由内部调用check_signature()。
之前在Git的不同部分中使用了两个全局范围的函数来执行GPG签名验证:verify_signed_buffer()和check_signature()。
现在仅check_signature()使用。
如MichałGórny所述,该verify_signed_buffer()函数不能防止重复签名。
取而代之的是,它仅确保GPG的退出代码正确无误,并且至少存在一个GOODSIG状态字段。
与此形成对比的是check_signature(),如果遇到多个签名,则返回错误。
较低的验证程度使 verify_signed_buffer()如果呼叫者自己不自行解析和验证GPG状态消息的各个部分,则问题。
处理这些消息似乎是gpg-interface.c该功能应保留的任务check_signature()。
此外,使用verify_signed_buffer()使得难以引入依赖于GPG状态行内容的新功能。
现在,所有执行签名验证的操作都共享一个指向的入口gpg-interface.c。
这使得更容易将GPG签名验证中的更改功能或其他功能传播到Git的所有部分,而不会出现不执行相同程度验证的奇特情况。
git commit ...和git log ...。据我所知,gpg还没有添加可以git透明地传递给子命令的子命令...我没有任何可测试的存储库,但是git show --show-signature <commitish>行得通吗?