// DecryptBytes takes in base64-encoded encrypted bytes and the base64-encoded // private key and decrypts it. A bytes.Buffer is returned to allow the caller // to do useful thing with it (get it as a []byte, get it as a string, use it // as an io.Reader, etc), and also because this function doesn't know if what // comes out is binary data or a string, so let the caller decide. func DecryptBytes(encodedCrypt, privKey string) (*bytes.Buffer, error) { privKeyBytes, err := base64.StdEncoding.DecodeString(privKey) if err != nil { return nil, fmt.Errorf("Error decoding base64 private key: %s", err) } cryptBytes, err := base64.StdEncoding.DecodeString(encodedCrypt) if err != nil { return nil, fmt.Errorf("Error decoding base64 crypted bytes: %s", err) } entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(privKeyBytes))) if err != nil { return nil, fmt.Errorf("Error parsing private key: %s", err) } entityList := &openpgp.EntityList{entity} md, err := openpgp.ReadMessage(bytes.NewBuffer(cryptBytes), entityList, nil, nil) if err != nil { return nil, fmt.Errorf("Error decrypting the messages: %s", err) } ptBuf := bytes.NewBuffer(nil) ptBuf.ReadFrom(md.UnverifiedBody) return ptBuf, nil }
func TestFetchKeybasePubkeys(t *testing.T) { testset := []string{"keybase:jefferai", "keybase:hashicorp"} ret, err := FetchKeybasePubkeys(testset) if err != nil { t.Fatalf("bad: %v", err) } fingerprints := []string{} for _, user := range testset { data, err := base64.StdEncoding.DecodeString(ret[user]) if err != nil { t.Fatalf("error decoding key for user %s: %v", user, err) } entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data))) if err != nil { t.Fatalf("error parsing key for user %s: %v", user, err) } fingerprints = append(fingerprints, hex.EncodeToString(entity.PrimaryKey.Fingerprint[:])) } exp := []string{ "0f801f518ec853daff611e836528efcac6caa3db", "91a6e7f85d05c65630bef18951852d87348ffc4c", } if !reflect.DeepEqual(fingerprints, exp) { t.Fatalf("fingerprints do not match; expected \n%#v\ngot\n%#v\n", exp, fingerprints) } }
// EncryptShares takes an ordered set of Shamir key share fragments and // PGP public keys and encrypts each Shamir key fragment with the corresponding // public key // // Note: There is no corresponding test function; this functionality is // thoroughly tested in the init and rekey command unit tests func EncryptShares(secretShares [][]byte, pgpKeys []string) ([][]byte, error) { if len(secretShares) != len(pgpKeys) { return nil, fmt.Errorf("Mismatch between number of generated shares and number of PGP keys") } encryptedShares := [][]byte{} for i, keystring := range pgpKeys { data, err := base64.StdEncoding.DecodeString(keystring) if err != nil { return nil, fmt.Errorf("Error decoding given PGP key: %s", err) } entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data))) if err != nil { return nil, fmt.Errorf("Error parsing given PGP key: %s", err) } ctBuf := bytes.NewBuffer(nil) pt, err := openpgp.Encrypt(ctBuf, []*openpgp.Entity{entity}, nil, nil, nil) if err != nil { return nil, fmt.Errorf("Error setting up encryption for PGP message: %s", err) } _, err = pt.Write([]byte(hex.EncodeToString(secretShares[i]))) if err != nil { return nil, fmt.Errorf("Error encrypting PGP message: %s", err) } pt.Close() encryptedShares = append(encryptedShares, ctBuf.Bytes()) } return encryptedShares, nil }
func testSignedManifest(t *testing.T, modify func(*pods.Manifest, *openpgp.Entity)) (*pods.Manifest, *openpgp.Entity) { testManifest := testManifest(t) if fakeSigner == nil { var err error fakeSigner, err = openpgp.ReadEntity(packet.NewReader(bytes.NewReader(fakeEntity))) Assert(t).IsNil(err, "should have read entity") } if modify != nil { modify(testManifest, fakeSigner) } manifestBytes, err := testManifest.Marshal() Assert(t).IsNil(err, "manifest bytes error should have been nil") var buf bytes.Buffer sigWriter, err := clearsign.Encode(&buf, fakeSigner.PrivateKey, nil) Assert(t).IsNil(err, "clearsign Encode error should have been nil") sigWriter.Write(manifestBytes) sigWriter.Close() manifest, err := pods.ManifestFromBytes(buf.Bytes()) Assert(t).IsNil(err, "should have generated manifest from signed bytes") return manifest, fakeSigner }
// loadKey loads a GPG key found at a particular path. func loadKey(keypath string) (*openpgp.Entity, error) { f, err := os.Open(keypath) if err != nil { return nil, err } defer f.Close() pr := packet.NewReader(f) return openpgp.ReadEntity(pr) }
func PublicKeyToPGPClient(publicKey string) PGPClient { block, err := armor.Decode(strings.NewReader(publicKey)) if err != nil { panic(err) } entity, err := openpgp.ReadEntity(packet.NewReader(block.Body)) if err != nil { panic(err) } return PGPClient{openpgp.EntityList{entity}} }
// GetEntities takes in a string array of base64-encoded PGP keys and returns // the openpgp Entities func GetEntities(pgpKeys []string) ([]*openpgp.Entity, error) { ret := make([]*openpgp.Entity, 0, len(pgpKeys)) for _, keystring := range pgpKeys { data, err := base64.StdEncoding.DecodeString(keystring) if err != nil { return nil, fmt.Errorf("Error decoding given PGP key: %s", err) } entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data))) if err != nil { return nil, fmt.Errorf("Error parsing given PGP key: %s", err) } ret = append(ret, entity) } return ret, nil }
func encryptEmail(e *Email) error { if len(e.OpenPGPEncryptTo) == 0 { return nil } buf := &bytes.Buffer{} var destEntities []*openpgp.Entity for _, eto := range e.OpenPGPEncryptTo { r := bytes.NewBufferString(eto) blk, err := armor.Decode(r) if err != nil { return err } rr := packet.NewReader(blk.Body) e, err := openpgp.ReadEntity(rr) if err != nil { return err } destEntities = append(destEntities, e) } aew, err := armor.Encode(buf, "PGP MESSAGE", map[string]string{ "Version": "OpenPGP", }) if err != nil { return err } wr, err := openpgp.Encrypt(aew, destEntities, nil, nil, nil) if err != nil { return err } _, err = wr.Write([]byte(e.Body)) if err != nil { wr.Close() return err } wr.Close() aew.Close() e.Body = string(buf.Bytes()) return nil }
func TestPubKeyFilesFlagSetKeybase(t *testing.T) { tempDir, err := ioutil.TempDir("", "vault-test") if err != nil { t.Fatalf("Error creating temporary directory: %s", err) } defer os.RemoveAll(tempDir) err = ioutil.WriteFile(tempDir+"/pubkey2", []byte(pubKey2), 0755) if err != nil { t.Fatalf("Error writing pub key 2 to temp file: %s", err) } pkf := new(PubKeyFilesFlag) err = pkf.Set("keybase:jefferai,@" + tempDir + "/pubkey2" + ",keybase:hashicorp") if err != nil { t.Fatalf("err: %s", err) } fingerprints := []string{} for _, pubkey := range []string(*pkf) { keyBytes, err := base64.StdEncoding.DecodeString(pubkey) if err != nil { t.Fatalf("bad: %v", err) } pubKeyBuf := bytes.NewBuffer(keyBytes) reader := packet.NewReader(pubKeyBuf) entity, err := openpgp.ReadEntity(reader) if err != nil { t.Fatalf("bad: %v", err) } if entity == nil { t.Fatalf("nil entity encountered") } fingerprints = append(fingerprints, hex.EncodeToString(entity.PrimaryKey.Fingerprint[:])) } exp := []string{ "0f801f518ec853daff611e836528efcac6caa3db", "cf3d4694c9f57b28cb4092c2eb832c67eb5e8957", "91a6e7f85d05c65630bef18951852d87348ffc4c", } if !reflect.DeepEqual(fingerprints, exp) { t.Fatalf("bad: got \n%#v\nexpected\n%#v\n", fingerprints, exp) } }
func (o *openPGP) SetKey(k key) (err error) { keyPath := filepath.Join(conf.mountPoint, k.Path) keyFile, err := os.Open(keyPath) if err != nil { return } defer keyFile.Close() keyBlock, err := armor.Decode(keyFile) if err != nil { return } reader := packet.NewReader(keyBlock.Body) entity, err := openpgp.ReadEntity(reader) if err != nil { return } switch keyBlock.Type { case openpgp.PrivateKeyType: if k.Private != true { return fmt.Errorf("public key detected in private key slot") } o.secKey = entity case openpgp.PublicKeyType: if k.Private == true { return fmt.Errorf("private key detected in public key slot") } o.pubKey = entity default: return fmt.Errorf("key type error: %s", keyBlock.Type) } return }
// Import private key from defined path. func Import(privKeyPath string) (*PGP, error) { privKeyFile, err := os.Open(privKeyPath) if err != nil { return nil, err } defer privKeyFile.Close() file := packet.NewReader(bufio.NewReader(privKeyFile)) entity, err := openpgp.ReadEntity(file) if err != nil { return nil, errwrap.Wrapf(err, "can't read entity from path") } obj := &PGP{ Entity: entity, } log.Printf("PGP: Imported key: %s", obj.Entity.PrivateKey.KeyIdShortString()) return obj, nil }
// Validate is used to sanity check the seal configuration func (s *SealConfig) Validate() error { if s.SecretShares < 1 { return fmt.Errorf("shares must be at least one") } if s.SecretThreshold < 1 { return fmt.Errorf("threshold must be at least one") } if s.SecretShares > 1 && s.SecretThreshold == 1 { return fmt.Errorf("threshold must be greater than one for multiple shares") } if s.SecretShares > 255 { return fmt.Errorf("shares must be less than 256") } if s.SecretThreshold > 255 { return fmt.Errorf("threshold must be less than 256") } if s.SecretThreshold > s.SecretShares { return fmt.Errorf("threshold cannot be larger than shares") } if s.StoredShares > s.SecretShares { return fmt.Errorf("stored keys cannot be larger than shares") } if len(s.PGPKeys) > 0 && len(s.PGPKeys) != s.SecretShares-s.StoredShares { return fmt.Errorf("count mismatch between number of provided PGP keys and number of shares") } if len(s.PGPKeys) > 0 { for _, keystring := range s.PGPKeys { data, err := base64.StdEncoding.DecodeString(keystring) if err != nil { return fmt.Errorf("Error decoding given PGP key: %s", err) } _, err = openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data))) if err != nil { return fmt.Errorf("Error parsing given PGP key: %s", err) } } } return nil }
// ParsePublicKey parses the given public key file func ParsePublicKey(keyPath string) (*openpgp.Entity, error) { f, err := os.Open(keyPath) if err != nil { return nil, err } defer f.Close() // Parse our key key, err := armor.Decode(f) if err != nil { return nil, err } if key.Type != openpgp.PublicKeyType { return nil, fmt.Errorf("Key of wrong type:%s", key.Type) } r := packet.NewReader(key.Body) to, err := openpgp.ReadEntity(r) if err != nil { return nil, err } return to, nil }
func parseDecryptAndTestUnsealKeys(t *testing.T, input, rootToken string, fingerprints bool, backupKeys map[string][]string, core *vault.Core) { decoder := base64.StdEncoding priv1Bytes, err := decoder.DecodeString(privKey1) if err != nil { t.Fatalf("Error decoding bytes for private key 1: %s", err) } priv2Bytes, err := decoder.DecodeString(privKey2) if err != nil { t.Fatalf("Error decoding bytes for private key 2: %s", err) } priv3Bytes, err := decoder.DecodeString(privKey3) if err != nil { t.Fatalf("Error decoding bytes for private key 3: %s", err) } privBytes := [][]byte{ priv1Bytes, priv2Bytes, priv3Bytes, } var re *regexp.Regexp if fingerprints { re, err = regexp.Compile("\\s*Key\\s+\\d+\\s+fingerprint:\\s+([0-9a-fA-F]+);\\s+value:\\s+(.*)") } else { re, err = regexp.Compile("\\s*Key\\s+\\d+:\\s+(.*)") } if err != nil { t.Fatalf("Error compiling regex: %s", err) } matches := re.FindAllStringSubmatch(input, -1) if len(matches) != 3 { t.Fatalf("Unexpected number of keys returned, got %d, matches was \n\n%#v\n\n, input was \n\n%s\n\n", len(matches), matches, input) } encodedKeys := []string{} matchedFingerprints := []string{} for _, tuple := range matches { if fingerprints { if len(tuple) != 3 { t.Fatalf("Key not found: %#v", tuple) } matchedFingerprints = append(matchedFingerprints, tuple[1]) encodedKeys = append(encodedKeys, tuple[2]) } else { if len(tuple) != 2 { t.Fatalf("Key not found: %#v", tuple) } encodedKeys = append(encodedKeys, tuple[1]) } } if backupKeys != nil && len(matchedFingerprints) != 0 { testMap := map[string][]string{} for i, v := range matchedFingerprints { testMap[v] = append(testMap[v], encodedKeys[i]) sort.Strings(testMap[v]) } if !reflect.DeepEqual(testMap, backupKeys) { t.Fatalf("test map and backup map do not match, test map is\n%#v\nbackup map is\n%#v", testMap, backupKeys) } } unsealKeys := []string{} ptBuf := bytes.NewBuffer(nil) for i, keyHex := range privBytes { if i > 2 { break } ptBuf.Reset() entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(keyHex))) if err != nil { t.Fatalf("Error parsing private key %d: %s", i, err) } keyBytes, err := hex.DecodeString(encodedKeys[i]) if err != nil { t.Fatalf("Error hex-decoding key %d: %s", i, err) } entityList := &openpgp.EntityList{entity} md, err := openpgp.ReadMessage(bytes.NewBuffer(keyBytes), entityList, nil, nil) if err != nil { t.Fatalf("Error decrypting with key %d (%s): %s", i, encodedKeys[i], err) } ptBuf.ReadFrom(md.UnverifiedBody) unsealKeys = append(unsealKeys, ptBuf.String()) } err = core.Seal(rootToken) if err != nil { t.Fatalf("Error sealing vault with provided root token: %s", err) } for i, unsealKey := range unsealKeys { unsealBytes, err := hex.DecodeString(unsealKey) if err != nil { t.Fatalf("Error hex decoding unseal key %s: %s", unsealKey, err) } unsealed, err := core.Unseal(unsealBytes) if err != nil { t.Fatalf("Error using unseal key %s: %s", unsealKey, err) } if i >= 2 && !unsealed { t.Fatalf("Error: Provided two unseal keys but core is not unsealed") } } }
func main2() { // open ascii armored private key from, err := os.Open("my.asc.key") logging.CheckFatal(err) defer from.Close() // decode armor and check key type fromBlock, err := armor.Decode(from) logging.CheckFatal(err) if fromBlock.Type != openpgp.PrivateKeyType { logging.CheckFatal(fmt.Errorf("from key type:%s", fromBlock.Type)) } // parse and decrypt decoded key fromReader := packet.NewReader(fromBlock.Body) fromEntity, err := openpgp.ReadEntity(fromReader) logging.CheckFatal(err) log.Println("Enter Key Passphrase:") pw, err := terminal.ReadPassword(0) logging.CheckFatal(err) err = fromEntity.PrivateKey.Decrypt(pw) logging.CheckFatal(err) // open destination key (no ascii armor here) to, err := os.Open("mkd.pubkey") logging.CheckFatal(err) defer to.Close() toReader := packet.NewReader(to) toEntity, err := openpgp.ReadEntity(toReader) logging.CheckFatal(err) log.Printf("to: %x", toEntity.PrimaryKey.Fingerprint) log.Printf("from: %x", fromEntity.PrimaryKey.Fingerprint) // output file out, err := os.Create("out.enc") logging.CheckFatal(err) defer out.Close() hints := &openpgp.FileHints{ IsBinary: true, FileName: "test.zip", ModTime: time.Now(), } // prepare encryption pipe encOut, err := openpgp.Encrypt(out, []*openpgp.Entity{toEntity}, fromEntity, hints, nil) logging.CheckFatal(err) // for fun, lets write a zip file to it created inline zipW := zip.NewWriter(encOut) t1, err := zipW.Create("test1.de.txt") logging.CheckFatal(err) fmt.Fprintln(t1, "Hallo Welt") t2, err := zipW.Create("test1.en.txt") logging.CheckFatal(err) fmt.Fprintln(t2, "Hello World - the 2nd") logging.CheckFatal(zipW.Flush()) logging.CheckFatal(zipW.Close()) // close the encPipe to finish the process logging.CheckFatal(encOut.Close()) }
func parseDecryptAndTestUnsealKeys(t *testing.T, input, rootToken string, core *vault.Core) { decoder := base64.StdEncoding priv1Bytes, err := decoder.DecodeString(privKey1) if err != nil { t.Fatalf("Error decoding bytes for private key 1: %s", err) } priv2Bytes, err := decoder.DecodeString(privKey2) if err != nil { t.Fatalf("Error decoding bytes for private key 2: %s", err) } priv3Bytes, err := decoder.DecodeString(privKey3) if err != nil { t.Fatalf("Error decoding bytes for private key 3: %s", err) } privBytes := [][]byte{ priv1Bytes, priv2Bytes, priv3Bytes, } re, err := regexp.Compile("\\s*Key\\s+\\d+:\\s+(.*)") if err != nil { t.Fatalf("Error compiling regex: %s", err) } matches := re.FindAllStringSubmatch(input, -1) if len(matches) != 3 { t.Fatalf("Unexpected number of keys returned, got %d, matches was \n\n%#v\n\n, input was \n\n%s\n\n", len(matches), matches, input) } encodedKeys := []string{} for _, pair := range matches { if len(pair) != 2 { t.Fatalf("Key not found: %#v", pair) } encodedKeys = append(encodedKeys, pair[1]) } unsealKeys := []string{} ptBuf := bytes.NewBuffer(nil) for i, keyHex := range privBytes { if i > 2 { break } ptBuf.Reset() entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(keyHex))) if err != nil { t.Fatalf("Error parsing private key %d: %s", i, err) } keyBytes, err := hex.DecodeString(encodedKeys[i]) if err != nil { t.Fatalf("Error hex-decoding key %d: %s", i, err) } entityList := &openpgp.EntityList{entity} md, err := openpgp.ReadMessage(bytes.NewBuffer(keyBytes), entityList, nil, nil) if err != nil { t.Fatalf("Error decrypting with key %d (%s): %s", i, encodedKeys[i], err) } ptBuf.ReadFrom(md.UnverifiedBody) unsealKeys = append(unsealKeys, ptBuf.String()) } err = core.Seal(rootToken) if err != nil { t.Fatalf("Error sealing vault with provided root token: %s", err) } for i, unsealKey := range unsealKeys { unsealBytes, err := hex.DecodeString(unsealKey) if err != nil { t.Fatalf("Error hex decoding unseal key %s: %s", unsealKey, err) } unsealed, err := core.Unseal(unsealBytes) if err != nil { t.Fatalf("Error using unseal key %s: %s", unsealKey, err) } if i >= 2 && !unsealed { t.Fatalf("Error: Provided two unseal keys but core is not unsealed") } } }