|
1 | 1 | package git
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
| 5 | + "strings" |
4 | 6 | "time"
|
5 | 7 |
|
| 8 | + "golang.org/x/crypto/openpgp" |
| 9 | + "golang.org/x/crypto/openpgp/armor" |
| 10 | + "golang.org/x/crypto/openpgp/errors" |
6 | 11 | "gopkg.in/src-d/go-git.v4/plumbing"
|
7 | 12 | "gopkg.in/src-d/go-git.v4/plumbing/object"
|
8 | 13 | "gopkg.in/src-d/go-git.v4/plumbing/storer"
|
@@ -135,6 +140,62 @@ func (s *WorktreeSuite) TestRemoveAndCommitAll(c *C) {
|
135 | 140 | assertStorageStatus(c, s.Repository, 13, 11, 11, expected)
|
136 | 141 | }
|
137 | 142 |
|
| 143 | +func (s *WorktreeSuite) TestCommitSign(c *C) { |
| 144 | + fs := memfs.New() |
| 145 | + storage := memory.NewStorage() |
| 146 | + |
| 147 | + r, err := Init(storage, fs) |
| 148 | + c.Assert(err, IsNil) |
| 149 | + |
| 150 | + w, err := r.Worktree() |
| 151 | + c.Assert(err, IsNil) |
| 152 | + |
| 153 | + util.WriteFile(fs, "foo", []byte("foo"), 0644) |
| 154 | + |
| 155 | + _, err = w.Add("foo") |
| 156 | + c.Assert(err, IsNil) |
| 157 | + |
| 158 | + key := commitSignKey(c, true) |
| 159 | + hash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature(), SignKey: key}) |
| 160 | + c.Assert(err, IsNil) |
| 161 | + |
| 162 | + // Verify the commit. |
| 163 | + pks := new(bytes.Buffer) |
| 164 | + pkw, err := armor.Encode(pks, openpgp.PublicKeyType, nil) |
| 165 | + c.Assert(err, IsNil) |
| 166 | + |
| 167 | + err = key.Serialize(pkw) |
| 168 | + c.Assert(err, IsNil) |
| 169 | + err = pkw.Close() |
| 170 | + c.Assert(err, IsNil) |
| 171 | + |
| 172 | + expectedCommit, err := r.CommitObject(hash) |
| 173 | + c.Assert(err, IsNil) |
| 174 | + actual, err := expectedCommit.Verify(pks.String()) |
| 175 | + c.Assert(err, IsNil) |
| 176 | + c.Assert(actual.PrimaryKey, DeepEquals, key.PrimaryKey) |
| 177 | +} |
| 178 | + |
| 179 | +func (s *WorktreeSuite) TestCommitSignBadKey(c *C) { |
| 180 | + fs := memfs.New() |
| 181 | + storage := memory.NewStorage() |
| 182 | + |
| 183 | + r, err := Init(storage, fs) |
| 184 | + c.Assert(err, IsNil) |
| 185 | + |
| 186 | + w, err := r.Worktree() |
| 187 | + c.Assert(err, IsNil) |
| 188 | + |
| 189 | + util.WriteFile(fs, "foo", []byte("foo"), 0644) |
| 190 | + |
| 191 | + _, err = w.Add("foo") |
| 192 | + c.Assert(err, IsNil) |
| 193 | + |
| 194 | + key := commitSignKey(c, false) |
| 195 | + _, err = w.Commit("foo\n", &CommitOptions{Author: defaultSignature(), SignKey: key}) |
| 196 | + c.Assert(err, Equals, errors.InvalidArgumentError("signing key is encrypted")) |
| 197 | +} |
| 198 | + |
138 | 199 | func assertStorageStatus(
|
139 | 200 | c *C, r *Repository,
|
140 | 201 | treesCount, blobCount, commitCount int, head plumbing.Hash,
|
@@ -173,3 +234,83 @@ func defaultSignature() *object.Signature {
|
173 | 234 | When: when,
|
174 | 235 | }
|
175 | 236 | }
|
| 237 | + |
| 238 | +func commitSignKey(c *C, decrypt bool) *openpgp.Entity { |
| 239 | + s := strings.NewReader(armoredKeyRing) |
| 240 | + es, err := openpgp.ReadArmoredKeyRing(s) |
| 241 | + c.Assert(err, IsNil) |
| 242 | + |
| 243 | + c.Assert(es, HasLen, 1) |
| 244 | + c.Assert(es[0].Identities, HasLen, 1) |
| 245 | + _, ok := es[ 0]. Identities[ "foo bar <[email protected]>"] |
| 246 | + c.Assert(ok, Equals, true) |
| 247 | + |
| 248 | + key := es[0] |
| 249 | + if decrypt { |
| 250 | + err = key.PrivateKey.Decrypt([]byte(keyPassphrase)) |
| 251 | + c.Assert(err, IsNil) |
| 252 | + } |
| 253 | + |
| 254 | + return key |
| 255 | +} |
| 256 | + |
| 257 | +const armoredKeyRing = ` |
| 258 | +-----BEGIN PGP PRIVATE KEY BLOCK----- |
| 259 | +
|
| 260 | +lQdGBFt2OHgBEADQpRmFm9X9xBfUljVs1B24MXWRHcEP5tx2k6Cp90sSz/ZOJcxH |
| 261 | +RjzYuXjpkE7g/PaZxAMVS1PptJip/w1/+5l2gZ7RmzU/e3hKe4vALHzKMVp8t7Ta |
| 262 | +0e2K3STxapCr9FNITjQRGOhnFwqiYoPCf9u5Iy8uszDH7HHnBZx+Nvbl95dDvmMs |
| 263 | +aFUKMeaoFD19iwEdRu6gJo7YIWF/8zwHi49neKigisGKh5PI0KUYeRPydXeCZIKQ |
| 264 | +ofdk+CPUS4r3dVhxTMYeHn/Vrep3blEA45E7KJ+TESmKkwliEgdjJwaVkUfJhBkb |
| 265 | +p2pMPKwbxLma9GCJBimOkehFv8/S+xn/xrLSsTxeOCIzMp3I5vgjR5QfONq5kuB1 |
| 266 | +qbr8rDpSCHmTd7tzixFA0tVPBsvToA5Cz2MahJ+vmouusiWq/2YzGNE4zlzezNZ1 |
| 267 | +3dgsVJm67xUSs0qY5ipKzButCFSKnaj1hLNR1NsUd0NPrVBTGblxULLuD99GhoXk |
| 268 | +/pcM5dCGTUX7XIarSFTEgBNQytpmfgt1Xbw2ErmlAdiFb4/5uBdbsVFAjglBvRI5 |
| 269 | +VhFXr7mUd+XR/23aRczdAnp+Zg7VvyaJQi0ZwEj7VvLzpSAneVrxEcnuc2MBkUgT |
| 270 | +TN/Z5LYqC93nr6vB7+HMwoBZ8hBAkO4rTKYQl3eMUSkIsE45CqI7Hz0eXQARAQAB |
| 271 | +/gcDAqG5KzRnSp/38h4JKzJhSBRyyBPrgpYqR6ivFABzPUPJjO0gqRYzx/C+HJyl |
| 272 | +z+QED0WH+sW8Ns4PkAgNWZ+225fzSssavLcPwjncy9pzcV+7bc76cFb77fSve+1D |
| 273 | +LxhpzN58q03cSXPoamcDD7yY8GYYkAquLDZw+eRQ57BbBrNjXyfpGkBmtULymLqZ |
| 274 | +SgkuV5we7//lRPDIuPk+9lszJXBUW3k5e32CR47B/hI6Pu0DTlN9VesAEmXRNsi9 |
| 275 | +YlRiO74nGPQPEWGjnEUQ++W8ip0CzoSrmPhrdGQlSR+SBEbBCuXz1lsj7D9cBxwH |
| 276 | +qHgwhYKvWz/gaY702+i/S1Cu/PjEpY3WPC5oSSNSSgypD8uSpcb4s2LffIegJNck |
| 277 | +e1AuiovG6u/3QXPot0jHhdy+Qwe+oaJfSEBGQ4fD4W6GbPxwOIQGgXV0bRaeHYgL |
| 278 | +iUWbN3rTLLVfDJKVo2ahvqZ7i4whfMuu1gGWQ4OEizrCDqp0x48HchEOC+T1eP3T |
| 279 | +Zjth2YMtzZdXlpt5HNKeaY6ZP+NWILwvOQBd3UtNpeaCNhUa0YyB7GD/k7tZnCIZ |
| 280 | +aNyF/DpnRrSQ9mAOffVn2NDGUv+01LnhIfa2tJes9XPmTc6ASrn/RGE9xH0X7wBD |
| 281 | +HfAdGhHgbkzwNeYkQvSh1WyWj5C0Sq7X70dIYdcO81i5MMtlJrzrlB5/YCFVWSxt |
| 282 | +7/EqwMBT3g9mkjAqo6beHxI1Hukn9rt9A6+MU64r0/cB+mVZuiBDoU/+KIiXBWiE |
| 283 | +F/C1n/BO115WoWG35vj5oH+syuv3lRuPaz8GxoffcT+FUkmevZO1/BjEAABAwMS1 |
| 284 | +nlB4y6xMJ0i2aCB2kp7ThDOOeTIQpdvtDLqRtQsVTpk73AEuDeKmULJnE2+Shi7v |
| 285 | +yrNj1CPiBdYzz8jBDJYQH87iFQrro7VQNZzMMxpMWXQOZYWidHuBz4TgJJ0ll0JN |
| 286 | +KwLtqv5wdf2zG8zNli0Dz+JwiwQ1kXDcA03rxHBCFALvkdIX0KUvTaTSV7OJ65VI |
| 287 | +rcIwB5fSZgRE7m/9RjBGq/U+n4Kw+vlfpL7UeECJM0N7l8ekgTqqKv2Czu29eTjF |
| 288 | +QOnpQtjgsWVpOnHKpQUfCN1Nxg8H1ytH9HQwLn+cGjm/yK55yIK+03X/vSs2m2qz |
| 289 | +2zDhWlgvHLsDOEQkNsuOIvLkNM6Hv3MLTldknC+vMla34fYqpHfV1phL4npVByMW |
| 290 | +CFOOzLa3qCoBXIGWvtnDx06r/8apHnt256G2X0iuRWWK+XpatMjmriZnj8vyGdIg |
| 291 | +TZ1sNXnuFKMcXYMIvLANZXz4Rabbe6tTJ+BUVkbCGja4Z9iwmYvga77Mr2vjhtwi |
| 292 | +CesRpcz6gR6U5fLddRZXyzKGxC3uQzokc9RtTuRNgSBZQ0oki++d6sr0+jOb54Mr |
| 293 | +wfcMbMgpkQK0IJsMoOxzPLU8s6rISJvFi4IQ2dPYog17GS7Kjb1IGjGUxNKVHiIE |
| 294 | +Is9wB+6bB51ZUUwc0zDSkuS6EaXLLVzmS7a3TOkVzu6J760TDVLL2+PDYkkBUP6O |
| 295 | +SA2yeHirpyMma9QII1sw3xcKH/kDeyWigiB1VDKQpuq1PP98lYjQwAbe3Xrpy2FO |
| 296 | +L/v6dSOJ+imgxD4osT0SanGkZEwPqJFvs6BI9Af8q9ia0xfK3Iu6F2F8JxmG1YiR |
| 297 | +tUm9kCu3X/fNyE08G2sxD8QzGP9VS529nEDRBqkAgY6EHTpRKhPer9QrkUnqEyDZ |
| 298 | +4s7RPcJW+cII/FPW8mSMgTqxFtTZgqNaqPPLevrTnTYTdrW/RkEs1mm0FWZvbyBi |
| 299 | +YXIgPGZvb0Bmb28uZm9vPokCVAQTAQgAPhYhBJICM5a3zdmD+nRGF3grx+nZaj4C |
| 300 | +BQJbdjh4AhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEHgrx+nZ |
| 301 | +aj4CTyUP/2+4k4hXkkBrEeD0yDpmR/FrAgCOZ3iRWca9bJwKtV0hW0HSztlPEfng |
| 302 | +wkwBmmyrnDevA+Ur4/hsBoTzfL4Fzo4OQDg2PZpSpIAHC1m/SQMN/s188RM8eK+Q |
| 303 | +JBtinAo2IDoZyBi5Ar4rVNXrRpgvzwOLm15kpuPp15wxO+4gYOkNIT06yUrDNh3J |
| 304 | +ccXmgZoVD54JmvKrEXscqX71/1NkaUhwZfFALN3+TVXUUdv1icQUJtxNBc29arwM |
| 305 | +LuPuj9XAm5XJaVXDfsJyGu4aj4g6AJDXjVW1d2MgXv1rMRud7CGuX2PmO3CUUua9 |
| 306 | +cUaavop5AmtF/+IsHae9qRt8PiMGTebV8IZ3Z6DZeOYDnfJVOXoIUcrAvX3LoImc |
| 307 | +ephBdZ0KmYvaxlDrjtWAvmD6sPgwSvjLiXTmbmAkjRBXCVve4THf05kVUMcr8tmz |
| 308 | +Il8LB+Dri2TfanBKykf6ulH0p2MHgSGQbYA5MuSp+soOitD5YvCxM7o/O0frrfit |
| 309 | +p/O8mPerMEaYF1+3QbF5ApJkXCmjFCj71EPwXEDcl3VIGc+zA49oNjZMMmCcX2Gc |
| 310 | +JyKTWizfuRBGeG5VhCCmTQQjZHPMVO255mdzsPkb6ZHEnolDapY6QXccV5x05XqD |
| 311 | +sObFTy6iwEITdGmxN40pNE3WbhYGqOoXb8iRIG2hURv0gfG1/iI0 |
| 312 | +=8g3t |
| 313 | +-----END PGP PRIVATE KEY BLOCK----- |
| 314 | +` |
| 315 | + |
| 316 | +const keyPassphrase = "abcdef0123456789" |
0 commit comments