generated from sigstore/sigstore-project-template
-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds the ability for gitsign commits to include rekor log entry details to enable offline verification of commits. - Adds new unauthenticated attributes corresponding to Rekor log entry values. - Adds support for offline commit verification along side existing SHA based online verification. - Adds config option for users to select offline or online storage options. Defaults to existing online behavior to allow users to opt-in, this will be changed to offline after a release. - Adds e2e test for offline verification. Signed-off-by: Billy Lynch <billy@chainguard.dev>
- Loading branch information
Showing
18 changed files
with
801 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# Verification | ||
|
||
## Offline Verification | ||
|
||
In offline Rekor storage mode Gitsign will store a HashedRekord in Rekor | ||
corresponding to the commit content. | ||
|
||
Unfortunately this is a bit complex to query manually. Roughly this is: | ||
|
||
``` | ||
sha256(der(sort(system time | commit data | content type))) | ||
``` | ||
|
||
The resulting Rekor log entry fields and inclusion proof will be stored in the | ||
PKCS7 object as unauthenticated (i.e. not included in the cryptographic | ||
signature) attributes. | ||
|
||
``` | ||
unauth_attr: | ||
object: undefined (1.3.6.1.4.1.57264.3.8) | ||
value.set: | ||
INTEGER:6954358 | ||
object: undefined (1.3.6.1.4.1.57264.3.9) | ||
value.set: | ||
INTEGER:6954357 | ||
object: undefined (1.3.6.1.4.1.57264.3.1) | ||
value.set: | ||
INTEGER:1673643613 | ||
object: undefined (1.3.6.1.4.1.57264.3.3) | ||
value.set: | ||
INTEGER:11117788 | ||
object: undefined (1.3.6.1.4.1.57264.3.2) | ||
value.set: | ||
PRINTABLESTRING:c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d | ||
object: undefined (1.3.6.1.4.1.57264.3.7) | ||
value.set: | ||
PRINTABLESTRING:373443ac6ee5e01d4bfa00666f79d5c7cee0380684ebe571fc98bdffea82f972 | ||
object: undefined (1.3.6.1.4.1.57264.3.4) | ||
value.set: | ||
OCTET STRING: | ||
0000 - 30 45 02 20 00 d0 88 ff-91 18 75 1c 90 0E. ......u.. | ||
000d - 4c aa f3 37 94 45 a8 ca-1e a4 de 60 10 L..7.E.....`. | ||
001a - 0a 22 69 03 c9 2d d2 0e-1a 9f 02 21 00 ."i..-.....!. | ||
0027 - af cd 78 85 f2 66 5f 22-c5 d3 a2 5c fc ..x..f_"...\. | ||
0034 - e2 c1 fe 0c f2 27 aa f0-fa fd 73 ca 5d .....'....s.] | ||
0041 - 58 98 9c 00 df 5c X....\ | ||
object: undefined (1.3.6.1.4.1.57264.3.5) | ||
value.set: | ||
UTF8STRING:rekor.sigstore.dev - 2605736670972794746 | ||
``` | ||
|
||
These OIDs are defined by [Rekor](https://github.com/sigstore/rekor) and are | ||
used during verification to reconstruct the Rekor log entry and verify the | ||
commit signature. | ||
|
||
## Online Verification | ||
|
||
In online Rekor storage mode Gitsign will store the Git commit SHA in rekor | ||
rather that persisting the Rekor log details in the commit itself. Gitsign is in | ||
the process of migrating clients to offline verification, but this section | ||
explains how verification used to work. | ||
|
||
As part of signature verification, `gitsign` not only checks that the given | ||
signature matches the commit, but also that the commit exists within the Rekor | ||
transparency log. | ||
|
||
We can manually validate that the commit exists in the transparency log by | ||
running: | ||
|
||
```sh | ||
$ uuid=$(rekor-cli search --artifact <(git rev-parse HEAD | tr -d '\n') | tail -n 1) | ||
$ rekor-cli get --uuid=$uuid --format=json | jq . | ||
LogID: c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d | ||
Index: 2212633 | ||
IntegratedTime: 2022-05-02T20:51:49Z | ||
UUID: d0444ed9897f31fefc820ade9a706188a3bb030055421c91e64475a8c955ae2c | ||
Body: { | ||
"HashedRekordObj": { | ||
"data": { | ||
"hash": { | ||
"algorithm": "sha256", | ||
"value": "05b4f02a24d1c4c2c95dacaee30de2a6ce4b5b88fa981f4e7b456b76ea103141" | ||
} | ||
}, | ||
"signature": { | ||
"content": "MEYCIQCeZwhnq9dgS7ZvU2K5m785V6PqqWAsmkNzAOsf8F++gAIhAKfW2qReBZL34Xrzd7r4JzUlJbf5eoeUZvKT+qsbbskL", | ||
"publicKey": { | ||
"content": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNGVENDQVp1Z0F3SUJBZ0lVQUxZY1ZSbUZTcG05VnhJTjdIVzdtaHBPeSs4d0NnWUlLb1pJemowRUF3TXcKS2pFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUkV3RHdZRFZRUURFd2h6YVdkemRHOXlaVEFlRncweQpNakExTURJeU1EVXhORGRhRncweU1qQTFNREl5TVRBeE5EWmFNQUF3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPClBRTUJCd05DQUFUc1lFdG5xaWpaTlBPRG5CZWx5S1dIWHQ3YndtWElpK2JjeEcrY2gyQUZRaGozdHcyUEJ2RmkKenBwWm5YRVNWUnZEMU1lUXBmWUt0QnF6RHFjOVRoSTRvNEhJTUlIRk1BNEdBMVVkRHdFQi93UUVBd0lIZ0RBVApCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBekFNQmdOVkhSTUJBZjhFQWpBQU1CMEdBMVVkRGdRV0JCU2dzZW9ECnhRaEtjSk1oMnFPZ0MweFZTZE1HUFRBZkJnTlZIU01FR0RBV2dCUll3QjVma1VXbFpxbDZ6SkNoa3lMUUtzWEYKK2pBaUJnTlZIUkVCQWY4RUdEQVdnUlJpYVd4c2VVQmphR0ZwYm1kMVlYSmtMbVJsZGpBc0Jnb3JCZ0VFQVlPLwpNQUVCQkI1b2RIUndjem92TDJkcGRHaDFZaTVqYjIwdmJHOW5hVzR2YjJGMWRHZ3dDZ1lJS29aSXpqMEVBd01ECmFBQXdaUUl4QUsrKzliL25CZlVWNGdlRlNBRE9nUjQrdW5zaDArU2tpdWJsT0o4QmloWnNUTk9VcjNmd2ZXNngKblBrcCtTeTFFd0l3ZE91bFdvcDNvSlYvUW83ZmF1MG1sc3kwTUNtM2xCZ3l4bzJscEFhSTRnRlJ4R0UyR2hwVgo3TitrQ29TMUEyNFMKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=" | ||
} | ||
} | ||
} | ||
} | ||
|
||
$ sig=$(rekor-cli get --uuid=$uuid --format=json | jq -r .Body.HashedRekordObj.signature.content) | ||
$ cert=$(rekor-cli get --uuid=$uuid --format=json | jq -r .Body.HashedRekordObj.signature.publicKey.content) | ||
$ cosign verify-blob --cert <(echo $cert | base64 --decode) --signature <(echo $sig | base64 --decode) <(git rev-parse HEAD | tr -d '\n') | ||
tlog entry verified with uuid: d0444ed9897f31fefc820ade9a706188a3bb030055421c91e64475a8c955ae2c index: 2212633 | ||
Verified OK | ||
$ echo $cert | base64 --decode | openssl x509 -text | ||
Certificate: | ||
Data: | ||
Version: 3 (0x2) | ||
Serial Number: | ||
b6:1c:55:19:85:4a:99:bd:57:12:0d:ec:75:bb:9a:1a:4e:cb:ef | ||
Signature Algorithm: ecdsa-with-SHA384 | ||
Issuer: O=sigstore.dev, CN=sigstore | ||
Validity | ||
Not Before: May 2 20:51:47 2022 GMT | ||
Not After : May 2 21:01:46 2022 GMT | ||
Subject: | ||
Subject Public Key Info: | ||
Public Key Algorithm: id-ecPublicKey | ||
Public-Key: (256 bit) | ||
pub: | ||
04:ec:60:4b:67:aa:28:d9:34:f3:83:9c:17:a5:c8: | ||
a5:87:5e:de:db:c2:65:c8:8b:e6:dc:c4:6f:9c:87: | ||
60:05:42:18:f7:b7:0d:8f:06:f1:62:ce:9a:59:9d: | ||
71:12:55:1b:c3:d4:c7:90:a5:f6:0a:b4:1a:b3:0e: | ||
a7:3d:4e:12:38 | ||
ASN1 OID: prime256v1 | ||
NIST CURVE: P-256 | ||
X509v3 extensions: | ||
X509v3 Key Usage: critical | ||
Digital Signature | ||
X509v3 Extended Key Usage: | ||
Code Signing | ||
X509v3 Basic Constraints: critical | ||
CA:FALSE | ||
X509v3 Subject Key Identifier: | ||
A0:B1:EA:03:C5:08:4A:70:93:21:DA:A3:A0:0B:4C:55:49:D3:06:3D | ||
X509v3 Authority Key Identifier: | ||
keyid:58:C0:1E:5F:91:45:A5:66:A9:7A:CC:90:A1:93:22:D0:2A:C5:C5:FA | ||
|
||
X509v3 Subject Alternative Name: critical | ||
email:billy@chainguard.dev | ||
1.3.6.1.4.1.57264.1.1: | ||
https://github.com/login/oauth | ||
Signature Algorithm: ecdsa-with-SHA384 | ||
30:65:02:31:00:af:be:f5:bf:e7:05:f5:15:e2:07:85:48:00: | ||
ce:81:1e:3e:ba:7b:21:d3:e4:a4:8a:e6:e5:38:9f:01:8a:16: | ||
6c:4c:d3:94:af:77:f0:7d:6e:b1:9c:f9:29:f9:2c:b5:13:02: | ||
30:74:eb:a5:5a:8a:77:a0:95:7f:42:8e:df:6a:ed:26:96:cc: | ||
b4:30:29:b7:94:18:32:c6:8d:a5:a4:06:88:e2:01:51:c4:61: | ||
36:1a:1a:55:ec:df:a4:0a:84:b5:03:6e:12 | ||
-----BEGIN CERTIFICATE----- | ||
MIICFTCCAZugAwIBAgIUALYcVRmFSpm9VxIN7HW7mhpOy+8wCgYIKoZIzj0EAwMw | ||
KjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y | ||
MjA1MDIyMDUxNDdaFw0yMjA1MDIyMTAxNDZaMAAwWTATBgcqhkjOPQIBBggqhkjO | ||
PQMBBwNCAATsYEtnqijZNPODnBelyKWHXt7bwmXIi+bcxG+ch2AFQhj3tw2PBvFi | ||
zppZnXESVRvD1MeQpfYKtBqzDqc9ThI4o4HIMIHFMA4GA1UdDwEB/wQEAwIHgDAT | ||
BgNVHSUEDDAKBggrBgEFBQcDAzAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSgseoD | ||
xQhKcJMh2qOgC0xVSdMGPTAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF | ||
+jAiBgNVHREBAf8EGDAWgRRiaWxseUBjaGFpbmd1YXJkLmRldjAsBgorBgEEAYO/ | ||
MAEBBB5odHRwczovL2dpdGh1Yi5jb20vbG9naW4vb2F1dGgwCgYIKoZIzj0EAwMD | ||
aAAwZQIxAK++9b/nBfUV4geFSADOgR4+unsh0+SkiublOJ8BihZsTNOUr3fwfW6x | ||
nPkp+Sy1EwIwdOulWop3oJV/Qo7fau0mlsy0MCm3lBgyxo2lpAaI4gFRxGE2GhpV | ||
7N+kCoS1A24S | ||
-----END CERTIFICATE----- | ||
``` | ||
|
||
Notice that **the Rekor entry uses the same cert that was used to generate the | ||
git commit signature**. This can be used to correlate the 2 messages, even | ||
though they signed different content! | ||
|
||
Note that for Git tags, the annotated tag object SHA is what is used (i.e. the | ||
output of `git rev-parse <tag>`), **not** the SHA of the underlying tagged | ||
commit. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.