func testParse(t *testing.T, input []byte, expected, expectedPlaintext string) { b, rest := Decode(input) if b == nil { t.Fatal("failed to decode clearsign message") } if !bytes.Equal(rest, []byte("trailing")) { t.Errorf("unexpected remaining bytes returned: %s", string(rest)) } if b.ArmoredSignature.Type != "PGP SIGNATURE" { t.Errorf("bad armor type, got:%s, want:PGP SIGNATURE", b.ArmoredSignature.Type) } if !bytes.Equal(b.Bytes, []byte(expected)) { t.Errorf("bad body, got:%x want:%x", b.Bytes, expected) } if !bytes.Equal(b.Plaintext, []byte(expectedPlaintext)) { t.Errorf("bad plaintext, got:%x want:%x", b.Plaintext, expectedPlaintext) } keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey)) if err != nil { t.Errorf("failed to parse public key: %s", err) } if _, err := openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body); err != nil { t.Errorf("failed to check signature: %s", err) } }
// NewDetachedSignature creates a new openpgp armored detached signature for the given ACI // signed with armoredPrivateKey. func NewDetachedSignature(armoredPrivateKey string, aci io.Reader) (io.Reader, error) { entityList, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(armoredPrivateKey)) if err != nil { return nil, err } if len(entityList) < 1 { return nil, errors.New("empty entity list") } signature := &bytes.Buffer{} if err := openpgp.ArmoredDetachSign(signature, entityList[0], aci, nil); err != nil { return nil, err } return signature, nil }
// NewMessageAndSignature generates a new random message signed by the given entity. // NewMessageAndSignature returns message, signature and an error if any. func NewMessageAndSignature(armoredPrivateKey string) (io.ReadSeeker, io.ReadSeeker, error) { entityList, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(armoredPrivateKey)) if err != nil { return nil, nil, err } if len(entityList) < 1 { return nil, nil, errors.New("empty entity list") } signature := &bytes.Buffer{} message := []byte("data") if err := openpgp.ArmoredDetachSign(signature, entityList[0], bytes.NewReader(message), nil); err != nil { return nil, nil, err } return bytes.NewReader(message), bytes.NewReader(signature.Bytes()), nil }
func (ks *Keystore) TrustedKeyPrefixExists(prefix string, r io.ReadSeeker) (bool, error) { defer r.Seek(0, os.SEEK_SET) entityList, err := openpgp.ReadArmoredKeyRing(r) if err != nil { return false, err } if len(entityList) < 1 { return false, errors.New("missing opengpg entity") } pubKey := entityList[0].PrimaryKey fileName := fingerprintToFilename(pubKey.Fingerprint) pathNamesRoot := []string{ // example: /etc/rkt/trustedkeys/root.d/8b86de38890ddb7291867b025210bd8888182190 path.Join(ks.LocalRootPath, fileName), // example: /usr/lib/rkt/trustedkeys/root.d/8b86de38890ddb7291867b025210bd8888182190 path.Join(ks.SystemRootPath, fileName), } var pathNamesPrefix []string if prefix != "" { acidentifier, err := types.NewACIdentifier(prefix) if err != nil { return false, err } pathNamesPrefix = []string{ // example: /etc/rkt/trustedkeys/prefix.d/coreos.com/etcd/8b86de38890ddb7291867b025210bd8888182190 path.Join(ks.LocalPrefixPath, acidentifier.String(), fileName), // example: /usr/lib/rkt/trustedkeys/prefix.d/coreos.com/etcd/8b86de38890ddb7291867b025210bd8888182190 path.Join(ks.SystemPrefixPath, acidentifier.String(), fileName), } } pathNames := append(pathNamesRoot, pathNamesPrefix...) for _, p := range pathNames { _, err := os.Stat(p) if err == nil { return true, nil } else if !os.IsNotExist(err) { return false, fmt.Errorf("cannot check file %q: %v", p, err) } } return false, nil }
func storeTrustedKey(dir string, r io.Reader) (string, error) { pubkeyBytes, err := ioutil.ReadAll(r) if err != nil { return "", err } if err := os.MkdirAll(dir, 0755); err != nil { return "", err } entityList, err := openpgp.ReadArmoredKeyRing(bytes.NewReader(pubkeyBytes)) if err != nil { return "", err } pubKey := entityList[0].PrimaryKey trustedKeyPath := path.Join(dir, fingerprintToFilename(pubKey.Fingerprint)) if err := ioutil.WriteFile(trustedKeyPath, pubkeyBytes, 0644); err != nil { return "", err } return trustedKeyPath, nil }
func TestSigning(t *testing.T) { keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey)) if err != nil { t.Errorf("failed to parse public key: %s", err) } for i, test := range signingTests { var buf bytes.Buffer plaintext, err := Encode(&buf, keyring[0].PrivateKey, nil) if err != nil { t.Errorf("#%d: error from Encode: %s", i, err) continue } if _, err := plaintext.Write([]byte(test.in)); err != nil { t.Errorf("#%d: error from Write: %s", i, err) continue } if err := plaintext.Close(); err != nil { t.Fatalf("#%d: error from Close: %s", i, err) continue } b, _ := Decode(buf.Bytes()) if b == nil { t.Errorf("#%d: failed to decode clearsign message", i) continue } if !bytes.Equal(b.Bytes, []byte(test.signed)) { t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Bytes, test.signed) continue } if !bytes.Equal(b.Plaintext, []byte(test.plaintext)) { t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Plaintext, test.plaintext) continue } if _, err := openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body); err != nil { t.Errorf("#%d: failed to check signature: %s", i, err) } } }
// displayKey shows the key summary func displayKey(prefix, location string, key *os.File) error { defer key.Seek(0, os.SEEK_SET) kr, err := openpgp.ReadArmoredKeyRing(key) if err != nil { return fmt.Errorf("error reading key: %v", err) } stderr("prefix: %q\nkey: %q", prefix, location) for _, k := range kr { stderr("gpg key fingerprint is: %s", fingerToString(k.PrimaryKey.Fingerprint)) for _, sk := range k.Subkeys { stderr(" subkey fingerprint: %s", fingerToString(sk.PublicKey.Fingerprint)) } for n, _ := range k.Identities { stderr("\t%s", n) } } return nil }
func entityFromFile(path string) (*openpgp.Entity, error) { trustedKey, err := os.Open(path) if err != nil { return nil, err } defer trustedKey.Close() entityList, err := openpgp.ReadArmoredKeyRing(trustedKey) if err != nil { return nil, err } if len(entityList) < 1 { return nil, errors.New("missing opengpg entity") } fingerprint := fingerprintToFilename(entityList[0].PrimaryKey.Fingerprint) keyFile := filepath.Base(trustedKey.Name()) if fingerprint != keyFile { return nil, fmt.Errorf("fingerprint mismatch: %q:%q", keyFile, fingerprint) } return entityList[0], nil }
// reviewKey shows the key summary and conditionally asks the user to accept it func reviewKey(prefix string, location string, key *os.File, forceAccept bool) (bool, error) { defer key.Seek(0, os.SEEK_SET) kr, err := openpgp.ReadArmoredKeyRing(key) if err != nil { return false, fmt.Errorf("error reading key: %v", err) } stderr("Prefix: %q\nKey: %q", prefix, location) for _, k := range kr { stderr("GPG key fingerprint is: %s", fingerToString(k.PrimaryKey.Fingerprint)) for _, sk := range k.Subkeys { stderr(" Subkey fingerprint: %s", fingerToString(sk.PublicKey.Fingerprint)) } for n, _ := range k.Identities { stderr("\t%s", n) } } if !forceAccept { in := bufio.NewReader(os.Stdin) for { stderr("Are you sure you want to trust this key (yes/no)?") input, err := in.ReadString('\n') if err != nil { return false, fmt.Errorf("error reading input: %v", err) } switch input { case "yes\n": return true, nil case "no\n": return false, nil default: stderr("Please enter 'yes' or 'no'") } } } else { stderr("rkt: warning: trust fingerprint verification has been disabled") } return true, nil }