func (d *dashEscaper) Close() (err error) { if !d.atBeginningOfLine { if err = d.buffered.WriteByte(lf); err != nil { return } } sig := new(packet.Signature) sig.SigType = packet.SigTypeText sig.PubKeyAlgo = d.privateKey.PubKeyAlgo sig.Hash = d.hashType sig.CreationTime = d.config.Now() sig.IssuerKeyId = &d.privateKey.KeyId if err = sig.Sign(d.h, d.privateKey, d.config); err != nil { return } out, err := armor.Encode(d.buffered, "PGP SIGNATURE", nil) if err != nil { return } if err = sig.Serialize(out); err != nil { return } if err = out.Close(); err != nil { return } if err = d.buffered.Flush(); err != nil { return } return }
func detachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) { if signer.PrivateKey == nil { return errors.InvalidArgumentError("signing key doesn't have a private key") } if signer.PrivateKey.Encrypted { return errors.InvalidArgumentError("signing key is encrypted") } sig := new(packet.Signature) sig.SigType = sigType sig.PubKeyAlgo = signer.PrivateKey.PubKeyAlgo sig.Hash = config.Hash() sig.CreationTime = config.Now() sig.IssuerKeyId = &signer.PrivateKey.KeyId h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType) if err != nil { return } io.Copy(wrappedHash, message) err = sig.Sign(h, signer.PrivateKey, config) if err != nil { return } return sig.Serialize(w) }
func signContent(content []byte, privKey *packet.PrivateKey) ([]byte, error) { sig := new(packet.Signature) sig.PubKeyAlgo = privKey.PubKeyAlgo sig.Hash = openpgpConfig.Hash() sig.CreationTime = time.Now() sig.IssuerKeyId = &privKey.KeyId h := openpgpConfig.Hash().New() h.Write(content) err := sig.Sign(h, privKey, openpgpConfig) if err != nil { return nil, err } buf := bytes.NewBufferString("openpgp ") // TODO: split the base64 blob over many lines for readability of the resulting file enc := base64.NewEncoder(base64.StdEncoding, buf) err = sig.Serialize(enc) if err != nil { return nil, err } enc.Close() return buf.Bytes(), nil }
func (chks *checkSuite) TestCheckForgery(c *C) { trustedKey := testPrivKey0 cfg := &asserts.DatabaseConfig{ Backstore: chks.bs, KeypairManager: asserts.NewMemoryKeypairManager(), TrustedKeys: []*asserts.AccountKey{asserts.BootstrapAccountKeyForTest("canonical", &trustedKey.PublicKey)}, } db, err := asserts.OpenDatabase(cfg) c.Assert(err, IsNil) encoded := asserts.Encode(chks.a) content, encodedSig := chks.a.Signature() // forgery forgedSig := new(packet.Signature) forgedSig.PubKeyAlgo = testPrivKey1.PubKeyAlgo forgedSig.Hash = crypto.SHA256 forgedSig.CreationTime = time.Now() forgedSig.IssuerKeyId = &testPrivKey0.KeyId h := crypto.SHA256.New() h.Write(content) err = forgedSig.Sign(h, testPrivKey1, &packet.Config{DefaultHash: crypto.SHA256}) c.Assert(err, IsNil) buf := new(bytes.Buffer) forgedSig.Serialize(buf) forgedSigEncoded := "openpgp " + base64.StdEncoding.EncodeToString(buf.Bytes()) forgedEncoded := bytes.Replace(encoded, encodedSig, []byte(forgedSigEncoded), 1) c.Assert(forgedEncoded, Not(DeepEquals), encoded) forgedAssert, err := asserts.Decode(forgedEncoded) c.Assert(err, IsNil) err = db.Check(forgedAssert) c.Assert(err, ErrorMatches, "failed signature verification: .*") }
func signContent(content []byte, privateKey PrivateKey) ([]byte, error) { opgPrivKey, ok := privateKey.(openpgpPrivateKey) if !ok { panic(fmt.Errorf("not an internally supported PrivateKey: %T", privateKey)) } privKey := opgPrivKey.privk sig := new(packet.Signature) sig.PubKeyAlgo = privKey.PubKeyAlgo sig.Hash = openpgpConfig.Hash() sig.CreationTime = time.Now() sig.IssuerKeyId = &privKey.KeyId h := openpgpConfig.Hash().New() h.Write(content) err := sig.Sign(h, privKey, openpgpConfig) if err != nil { return nil, err } buf := new(bytes.Buffer) err = sig.Serialize(buf) if err != nil { return nil, err } return encodeFormatAndData("openpgp", buf.Bytes()), nil }
// Given a control.Marshal'able object, encode it to the blobstore, while // also doing a detached OpenPGP signature. The objects returned (in order) // are data, commited to the blobstore, the signature for that object, commited // to the blobstore, and any error(s), finally. func (a Archive) encodeSigned(data interface{}) (*blobstore.Object, *blobstore.Object, error) { /* Right, so, the trick here is that we secretly call out to encode, * but tap it with a pipe into the signing code */ if a.signingKey == nil { return nil, nil, fmt.Errorf("No signing key loaded") } signature, err := a.Store.Create() if err != nil { return nil, nil, err } defer signature.Close() hash := sha512.New() obj, err := a.encode(data, hash) if err != nil { return nil, nil, err } sig := new(packet.Signature) sig.SigType = packet.SigTypeBinary sig.PubKeyAlgo = a.signingKey.PrivateKey.PubKeyAlgo sig.Hash = crypto.SHA512 sig.CreationTime = new(packet.Config).Now() sig.IssuerKeyId = &(a.signingKey.PrivateKey.KeyId) err = sig.Sign(hash, a.signingKey.PrivateKey, &packet.Config{ DefaultHash: crypto.SHA512, }) if err != nil { return nil, nil, err } if err := sig.Serialize(signature); err != nil { return nil, nil, err } sigObj, err := a.Store.Commit(*signature) if err != nil { return nil, nil, err } return obj, sigObj, nil }
func (chks *checkSuite) TestCheckForgery(c *C) { trustedKey := testPrivKey0 cfg := &asserts.DatabaseConfig{ Backstore: chks.bs, Trusted: []asserts.Assertion{asserts.BootstrapAccountKeyForTest("canonical", trustedKey.PublicKey())}, } db, err := asserts.OpenDatabase(cfg) c.Assert(err, IsNil) encoded := asserts.Encode(chks.a) content, encodedSig := chks.a.Signature() // forgery forgedSig := new(packet.Signature) forgedSig.PubKeyAlgo = packet.PubKeyAlgoRSA forgedSig.Hash = crypto.SHA512 forgedSig.CreationTime = time.Now() h := crypto.SHA512.New() h.Write(content) pk1 := packet.NewRSAPrivateKey(time.Unix(1, 0), testPrivKey1RSA) err = forgedSig.Sign(h, pk1, &packet.Config{DefaultHash: crypto.SHA512}) c.Assert(err, IsNil) buf := new(bytes.Buffer) forgedSig.Serialize(buf) b := append([]byte{0x1}, buf.Bytes()...) forgedSigEncoded := base64.StdEncoding.EncodeToString(b) forgedEncoded := bytes.Replace(encoded, encodedSig, []byte(forgedSigEncoded), 1) c.Assert(forgedEncoded, Not(DeepEquals), encoded) forgedAssert, err := asserts.Decode(forgedEncoded) c.Assert(err, IsNil) err = db.Check(forgedAssert) c.Assert(err, ErrorMatches, "failed signature verification: .*") }
func (opgPrivK openpgpPrivateKey) sign(content []byte) (*packet.Signature, error) { privk := opgPrivK.privk sig := new(packet.Signature) sig.PubKeyAlgo = privk.PubKeyAlgo sig.Hash = openpgpConfig.Hash() sig.CreationTime = time.Now() h := openpgpConfig.Hash().New() h.Write(content) err := sig.Sign(h, privk, openpgpConfig) if err != nil { return nil, err } return sig, nil }
func (gkms *gpgKeypairMgrSuite) TestUseInSigningBrokenSignature(c *C) { _, rsaPrivKey := assertstest.ReadPrivKey(assertstest.DevKey) pgpPrivKey := packet.NewRSAPrivateKey(time.Unix(1, 0), rsaPrivKey) var breakSig func(sig *packet.Signature, cont []byte) []byte mockGPG := func(prev asserts.GPGRunner, input []byte, args ...string) ([]byte, error) { if args[1] == "--list-secret-keys" || args[1] == "--export" { return prev(input, args...) } n := len(args) c.Assert(args[n-1], Equals, "--detach-sign") sig := new(packet.Signature) sig.PubKeyAlgo = packet.PubKeyAlgoRSA sig.Hash = crypto.SHA512 sig.CreationTime = time.Now() // poking to break the signature cont := breakSig(sig, input) h := sig.Hash.New() h.Write([]byte(cont)) err := sig.Sign(h, pgpPrivKey, nil) c.Assert(err, IsNil) buf := new(bytes.Buffer) sig.Serialize(buf) return buf.Bytes(), nil } restore := asserts.MockRunGPG(mockGPG) defer restore() signDB, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ KeypairManager: gkms.keypairMgr, }) c.Assert(err, IsNil) headers := map[string]interface{}{ "authority-id": "dev1-id", "snap-sha3-384": blobSHA3_384, "snap-id": "snap-id-1", "grade": "devel", "snap-size": "1025", "timestamp": time.Now().Format(time.RFC3339), } tests := []struct { breakSig func(*packet.Signature, []byte) []byte expectedErr string }{ {func(sig *packet.Signature, cont []byte) []byte { sig.Hash = crypto.SHA1 return cont }, "cannot sign assertion: bad GPG produced signature: expected SHA512 digest"}, {func(sig *packet.Signature, cont []byte) []byte { return cont[:5] }, "cannot sign assertion: bad GPG produced signature: it does not verify:.*"}, } for _, t := range tests { breakSig = t.breakSig _, err = signDB.Sign(asserts.SnapBuildType, headers, nil, assertstest.DevKeyID) c.Check(err, ErrorMatches, t.expectedErr) } }