// VerifySignatures verifies that the Action contains valid signatures from // known investigators. It does not verify permissions. func (a Action) VerifySignatures(keyring io.Reader) (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("VerifySignatures() -> %v", e) } }() astr, err := a.String() if err != nil { return errors.New("Failed to stringify action") } for _, sig := range a.PGPSignatures { valid, _, err := pgp.Verify(astr, sig, keyring) if err != nil { return errors.New("Failed to verify PGP Signature") } if !valid { return errors.New("Invalid PGP Signature") } } return }
// Validates signatures stored in the manifest against keys in keyring, returns // the number of valid signature matches func (m *ManifestResponse) VerifySignatures(keyring io.Reader) (validcnt int, err error) { var sigs []string // Copy signatures out of the response, and clear them as we do not // include them as part of the JSON document in validation sigs = make([]string, len(m.Signatures)) copy(sigs, m.Signatures) m.Signatures = m.Signatures[:0] mcopy := *m // Also zero the loader name as it is not included in the signature mcopy.LoaderName = "" buf, err := json.Marshal(mcopy) if err != nil { return validcnt, err } // Create a copy of the keyring we can use during validation of each // signature. We don't want to use the keyring directly as it is // backed by a buffer and will be drained after verification of the // first signature. keycopy, err := ioutil.ReadAll(keyring) if err != nil { return validcnt, err } for _, x := range sigs { keyreader := bytes.NewBuffer(keycopy) valid, _, err := pgp.Verify(string(buf), x, keyreader) if err != nil { return validcnt, err } if valid { validcnt++ } } return }