func checkSignature(ks *Keystore, prefix string, signed, signature io.ReadSeeker) (*openpgp.Entity, error) { acidentifier, err := types.NewACIdentifier(prefix) if err != nil { return nil, err } keyring, err := ks.loadKeyring(acidentifier.String()) if err != nil { return nil, errwrap.Wrap(errors.New("keystore: error loading keyring"), err) } entities, err := openpgp.CheckArmoredDetachedSignature(keyring, signed, signature) if err == io.EOF { // When the signature is binary instead of armored, the error is io.EOF. // Let's try with binary signatures as well if _, err := signed.Seek(0, 0); err != nil { return nil, errwrap.Wrap(errors.New("error seeking ACI file"), err) } if _, err := signature.Seek(0, 0); err != nil { return nil, errwrap.Wrap(errors.New("error seeking signature file"), err) } entities, err = openpgp.CheckDetachedSignature(keyring, signed, signature) } if err == io.EOF { // otherwise, the client failure is just "EOF", which is not helpful return nil, fmt.Errorf("keystore: no valid signatures found in signature file") } return entities, err }
// ParseSigned reads an unencrypted, but signed message. func ParseSigned(ct, addr string, getInfo MailUserInfo, body io.Reader) (*MailContent, error) { mc := new(MailContent) mc.Mode = modeSIGN boundary := extractValue(ct, "boundary") rdr := multipart.NewReader(body, boundary) for { if part, err := rdr.NextPart(); err == nil { ct = part.Header.Get("Content-Type") switch { case strings.HasPrefix(ct, "text/plain;"): data, err := ioutil.ReadAll(part) if err != nil { return nil, err } mc.Body = string(data) case strings.HasPrefix(ct, "application/pgp-signature;"): id := getIdentity(getInfo, infoSENDER, addr) if id == nil { mc.Mode = modeUSIGN continue } buf := bytes.NewBufferString(mc.Body) if _, err := openpgp.CheckArmoredDetachedSignature(openpgp.EntityList{id}, buf, part); err != nil { return nil, err } logger.Println(logger.INFO, "Signature verified OK") } } else if err == io.EOF { break } else { return nil, err } } return mc, nil }
func Verify(publicKeyFileName string, fileToVerify string, sigFileName string) error { signed, err := os.Open(fileToVerify) if err != nil { return err } defer signed.Close() var keyring openpgp.EntityList if keyring, err = readPublicKeyFile(publicKeyFileName); err != nil { return err } signature, err := os.Open(sigFileName) if err != nil { return err } defer signature.Close() signer, err := openpgp.CheckArmoredDetachedSignature(keyring, signed, signature) if err != nil { return err } for _, identity := range signer.Identities { fmt.Fprintf(os.Stderr, "Good signature from \"%s\"\n", identity.Name) } return nil }
func (o *openPGP) Verify(input *os.File, signature *os.File) (err error) { keyRing := openpgp.EntityList{} keyRing = append(keyRing, o.pubKey) _, err = openpgp.CheckArmoredDetachedSignature(keyRing, input, signature) return }
func (ks *Keystore) CheckSignature(name types.ACIdentifier, signed, signature io.Reader) (*openpgp.Entity, error) { kr, err := ks.GetKeysFor(name) if err != nil { return nil, errors.Trace(err) } entities, err := openpgp.CheckArmoredDetachedSignature(kr, signed, signature) if err == io.EOF { err = errors.New("No signatures found") } return entities, err }
func ApprovalCheck(PolicyFile, SignaturesFile, Id string) (bool, error) { var ( commit SignedCommit // Commit corresponding to be verified developers openpgp.EntityList // List of all developers whose public keys are in the policy file approvers map[string]*openpgp.Entity // Map of developers who provided a valid signature. Indexed by public key id (openpgp.PrimaryKey.KeyIdString) err error ) commit.Policy.Threshold, commit.Policy.DevPubKeys, commit.Policy.CothKey, err = PolicyScanner(PolicyFile) checkFileError(err, PolicyFile) commit.Signatures, err = SigScanner(SignaturesFile) checkFileError(err, SignaturesFile) commit.CommitID = Id // commit.CommitID, err = CommitScanner(CommitIdFile) // checkFileError(err, CommitIdFile) // commit.Approval = false approvers = make(map[string]*openpgp.Entity) // Creating openpgp entitylist from list of public keys developers = make(openpgp.EntityList, 0) for _, pubkey := range commit.Policy.DevPubKeys { keybuf, err := openpgp.ReadArmoredKeyRing(strings.NewReader(pubkey)) if err != nil { dbg.Error("Could not decode armored public key", err) } for _, entity := range keybuf { developers = append(developers, entity) } } // Verifying every signature in the list and counting valid ones for _, signature := range commit.Signatures { result, err := openpgp.CheckArmoredDetachedSignature(developers, bytes.NewBufferString(commit.CommitID), strings.NewReader(signature)) if err != nil { dbg.Lvl1("The signature is invalid or cannot be verified due to", err) } else { if approvers[result.PrimaryKey.KeyIdString()] == nil { // We need to check that this is a unique signature approvers[result.PrimaryKey.KeyIdString()] = result dbg.Lvl3("Approver: %+v", result.Identities) } } } dbg.Lvl3("Is release approved? ", len(approvers) >= commit.Policy.Threshold) // commit.Approval = (len(approvers) >= commit.Policy.Threshold) return len(approvers) >= commit.Policy.Threshold, err // return commit, err }
//ValidateSignature is exported for plugin authoring func (s *SigningManager) ValidateSignature(keyringFiles []string, signedFile string, signature []byte) error { var signedby string var e error var checked *openpgp.Entity signed, err := os.Open(signedFile) if err != nil { return fmt.Errorf("%v: %v\n%v", ErrSignedFileNotFound, signedFile, err) } defer signed.Close() //Go through all the keyrings til either signature is valid or end of keyrings for _, keyringFile := range keyringFiles { keyringf, err := os.Open(keyringFile) if err != nil { return fmt.Errorf("%v: %v\n%v", ErrKeyringFileNotFound, keyringFile, err) } defer keyringf.Close() //Read both armored and unarmored keyrings keyring, err := openpgp.ReadArmoredKeyRing(keyringf) if err != nil { keyringf.Seek(0, 0) keyring, err = openpgp.ReadKeyRing(keyringf) if err != nil { return fmt.Errorf("%v: %v\n%v", ErrUnableToReadKeyring, keyringFile, err) } } //Check the armored detached signature checked, e = openpgp.CheckArmoredDetachedSignature(keyring, signed, bytes.NewReader(signature)) if e == nil { for k := range checked.Identities { signedby = signedby + k } fmt.Printf("Signature made %v using RSA key ID %v\nGood signature from %v\n", time.Now().Format(time.RFC1123), checked.PrimaryKey.KeyIdShortString(), signedby) return nil } signed.Seek(0, 0) } return fmt.Errorf("%v\n%v", ErrCheckSignature, e) }
func TestLoadGPGSigner(t *testing.T) { signer, err := LoadGPGSigner("fixtures/secring.gpg", "test") assert.Nil(t, err) // assert that: // - fixture private key is read from a key ring file // - fixture encrypted private key is decrypted by passphrase // - Signer signs a message which can be verified by OpenPGP expectedMessage := "Hello World!" signature := new(bytes.Buffer) fmt.Println(signature) err = signer.Sign(signature, strings.NewReader(expectedMessage)) assert.Nil(t, err) // valid signature // gpg --no-default-keyring --secret-keyring fixtures/secring.gpg --verify sig msg kring, err := os.Open("fixtures/secring.gpg") assert.Nil(t, err) defer kring.Close() entities, err := openpgp.ReadKeyRing(kring) assert.Nil(t, err) _, err = openpgp.CheckArmoredDetachedSignature(entities, strings.NewReader(expectedMessage), signature) assert.Nil(t, err) }
func (s *Signature) Verify() error { signed, err := s.script.Body() if err != nil { return err } defer signed.Close() signature, err := s.Body() if err != nil { return err } defer signature.Close() if _, err := openpgp.CheckDetachedSignature(s.key, signed, signature); err == nil { return nil } signature.Seek(0, 0) // i'm sure there's a good reason i don't need to reset the script... if _, err := openpgp.CheckArmoredDetachedSignature(s.key, signed, signature); err == nil { return nil } return errors.New("Failed to verify signature") }
//codes as below are implemented to support ACI storage func VerifyAciSignature(acipath, signpath, pubkeyspath string) error { files, err := ioutil.ReadDir(pubkeyspath) if err != nil { return fmt.Errorf("Read pubkeys directory failed: %v", err.Error()) } if len(files) <= 0 { return fmt.Errorf("No pubkey file found in %v", pubkeyspath) } var keyring openpgp.EntityList for _, file := range files { pubkeyfile, err := os.Open(pubkeyspath + "/" + file.Name()) if err != nil { return err } defer pubkeyfile.Close() keyList, err := openpgp.ReadArmoredKeyRing(pubkeyfile) if err != nil { return err } if len(keyList) < 1 { return fmt.Errorf("Missing opengpg entity") } keyring = append(keyring, keyList[0]) } acifile, err := os.Open(acipath) if err != nil { return fmt.Errorf("Open ACI file failed: %v", err.Error()) } defer acifile.Close() signfile, err := os.Open(signpath) if err != nil { return fmt.Errorf("Open signature file failed: %v", err.Error()) } defer signfile.Close() if _, err := acifile.Seek(0, 0); err != nil { return fmt.Errorf("Seek ACI file failed: %v", err) } if _, err := signfile.Seek(0, 0); err != nil { return fmt.Errorf("Seek signature file: %v", err) } //Verify detached signature which default is ASCII format _, err = openpgp.CheckArmoredDetachedSignature(keyring, acifile, signfile) if err == io.EOF { if _, err := acifile.Seek(0, 0); err != nil { return fmt.Errorf("Seek ACI file failed: %v", err) } if _, err := signfile.Seek(0, 0); err != nil { return fmt.Errorf("Seek signature file: %v", err) } //try to verify detached signature with binary format _, err = openpgp.CheckDetachedSignature(keyring, acifile, signfile) } if err == io.EOF { return fmt.Errorf("Signature format is invalid") } return err }
func checkGPG(file *File) (state SigState, err error) { var signer *openpgp.Entity var cs *clearsign.Block keypath := path.Join(os.Getenv("HOME"), "/.gnupg/pubring.gpg") keys, err := os.Open(keypath) if err != nil { fmt.Printf("Could not open public keyring at %s\n", keypath) os.Exit(2) } keyring, err := openpgp.ReadKeyRing(keys) if err != nil { fmt.Printf("Error reading public keyring: %s\n", err) os.Exit(2) } if *flagClear { cs, _ = clearsign.Decode(file.content) if cs == nil { fmt.Printf("Problem decoding clearsign signature from file %s\n", file.name) os.Exit(2) } lsig, err := ioutil.ReadAll(cs.ArmoredSignature.Body) if err != nil { fmt.Printf("Problem reading signature from %s. Are you sure this file is clearsigned?: %s\n", file.name, err) os.Exit(2) } if len(lsig) > 0 { file.signature = lsig file.content = cs.Bytes *flagBin = true } } if *flagBin { signer, err = openpgp.CheckDetachedSignature(keyring, bytes.NewReader(file.content), bytes.NewReader(file.signature)) } else { signer, err = openpgp.CheckArmoredDetachedSignature(keyring, bytes.NewReader(file.content), bytes.NewReader(file.signature)) } if err != nil { fmt.Printf("Invalid signature or public key not present: %s\n", err) os.Exit(2) } state.sig = signer.PrimaryKey.KeyIdString() l := len(*flagKeyid) if l > 0 { var rid string // Force the local id to be all uppercase lid := strings.ToUpper(*flagKeyid) // check the number of chars on the remote id to see if it's a // short or long id. If it's not 8 or 16, it's not valid. switch l { case 8: fmt.Println("WARNING: The use of short ids is NOT secure. See https://evil32.com for more info.") fmt.Println("Refusing to use insecure key mechanism. Exiting.") os.Exit(1) case 16: fmt.Println("WARNING: The use of long ids is NOT considered to be secure. See https://evil32.com for more info.") rid = signer.PrimaryKey.KeyIdString() } if len(rid) == 0 { fmt.Printf("You did not specify a valid GPG keyid length. Must be 8 or 16 characters.") os.Exit(2) } if lid != rid { fmt.Printf("The remote file was not signed by the expected GPG Public key. Expected %s and got %s\n", lid, rid) os.Exit(2) } } // Due to how clearsign works, the detached signature has to be // processed using the Bytes field, but the stripped content is located // in the Plaintext field. As we've verified the signature was valid // we can now fix the content if *flagClear { file.content = cs.Plaintext } state.success = true return state, nil }