Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleiade committed Sep 15, 2014
2 parents db7bfdc + e17d462 commit aa07142
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 103 deletions.
50 changes: 27 additions & 23 deletions actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ func CreateAction(recipients []string) {
CryptoType: ASYMMETRIC_ENCRYPTION,
CryptoAlgorithm: GPG_ENCRYPTION,
}
tr.Encrypt(store)

err := tr.Write(InferStorePath())
err := tr.Encrypt(store)
if err != nil {
ErrorLogger.Fatal(err)
}

err = tr.Write(InferStorePath())
if err != nil {
ErrorLogger.Fatal(err)
}
Expand Down Expand Up @@ -185,49 +189,49 @@ func ImportAction(from string, strategy ImportStrategy, plain bool) {

localTr, err := OpenTrousseau(localFilePath)
if err != nil {
ErrorLogger.Fatal(err)
ErrorLogger.Fatal(err)
}

localStore, err := localTr.Decrypt()
if err != nil {
ErrorLogger.Fatal(err)
ErrorLogger.Fatal(err)
}

if plain == true {
importedData, err := ioutil.ReadFile(from)
if err != nil {
ErrorLogger.Fatal(err)
}
importedData, err := ioutil.ReadFile(from)
if err != nil {
ErrorLogger.Fatal(err)
}

err = json.Unmarshal(importedData, importedStore)
if err != nil {
ErrorLogger.Fatal(err)
}
err = json.Unmarshal(importedData, importedStore)
if err != nil {
ErrorLogger.Fatal(err)
}
} else {
importedTr, err := OpenTrousseau(from)
if err != nil {
ErrorLogger.Fatal(err)
}
importedTr, err := OpenTrousseau(from)
if err != nil {
ErrorLogger.Fatal(err)
}

importedStore, err = importedTr.Decrypt()
if err != nil {
ErrorLogger.Fatal(err)
}
importedStore, err = importedTr.Decrypt()
if err != nil {
ErrorLogger.Fatal(err)
}
}

err = ImportStore(importedStore, localStore, strategy)
if err != nil {
ErrorLogger.Fatal(err)
ErrorLogger.Fatal(err)
}

err = localTr.Encrypt(localStore)
if err != nil {
ErrorLogger.Fatal(err)
ErrorLogger.Fatal(err)
}

err = localTr.Write(localFilePath)
if err != nil {
ErrorLogger.Fatal(err)
ErrorLogger.Fatal(err)
}

InfoLogger.Println(fmt.Sprintf("Trousseau data store imported: %s", from))
Expand Down
34 changes: 14 additions & 20 deletions cmd/trousseau/before.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
package main

import (
libcli "github.com/codegangsta/cli"
"github.com/codegangsta/cli"
"github.com/oleiade/trousseau"
)

func Before(c *libcli.Context) error {
var err error

err = checkHelp(c)
if err != nil {
return err
}

err = updateStorePath(c)
if err != nil {
return err
}
func Before(c *cli.Context) error {
checkHelp(c)
updateStorePath(c)
updateGnupgHome(c)

return nil
}
Expand All @@ -25,24 +17,26 @@ func Before(c *libcli.Context) error {
// provided context. It is used to bypass the gpg key check
// before the application runs. So users can print the help
// without selecting their master key.
func checkHelp(c *libcli.Context) error {
func checkHelp(c *cli.Context) {
if c.GlobalBool("h") || c.GlobalBool("help") {
if len(c.Args()) >= 1 {
libcli.ShowCommandHelp(c, c.Args().First())
cli.ShowCommandHelp(c, c.Args().First())
} else {
libcli.ShowAppHelp(c)
cli.ShowAppHelp(c)
}
}

return nil
}

// updateStorePath selects the default trousseau data store if
// none were provided on the command line
func updateStorePath(c *libcli.Context) error {
func updateStorePath(c *cli.Context) {
if c.String("store") != "" {
trousseau.SetStorePath(c.String("store"))
}
}

return nil
func updateGnupgHome(c *cli.Context) {
if c.String("gnupg-home") != "" {
trousseau.GnupgHome = c.String("gnupg-home")
}
}
4 changes: 0 additions & 4 deletions cmd/trousseau/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ func CreateCommand() cli.Command {
" trousseau create [email protected]\n" +
" export TROUSSEAU_STORE=/tmp/test_trousseau.tr && trousseau create 16DB4F3\n",
Action: func(c *cli.Context) {
if !hasExpectedArgs(c.Args(), 1) {
trousseau.ErrorLogger.Fatal("Invalid number of arguments provided to create command")
}

var recipients []string = strings.Split(c.Args()[0], ",")
trousseau.CreateAction(recipients)
},
Expand Down
4 changes: 4 additions & 0 deletions cmd/trousseau/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ func main() {
Name: "store, s",
Usage: "Path to the trousseau data store to use",
},
cli.StringFlag{
Name: "gnupg-home",
Usage: "Provide an alternate gnupg home",
},
}

app.Before = Before
Expand Down
27 changes: 16 additions & 11 deletions context.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package trousseau

import (
"github.com/tmc/keyring"
"os"
"path/filepath"
"github.com/tmc/keyring"
)

// Global variables defining default values for S3 and scp
Expand All @@ -19,14 +19,19 @@ var (
}
)

// Global data store file path
var gStorePath string
func SetStorePath(storePath string) { gStorePath = storePath }
func GetStorePath() string { return gStorePath }

func InferStorePath() string {
envPath := os.Getenv(ENV_TROUSSEAU_STORE)
contextPath := GetStorePath()

if envPath != "" {
return envPath
} else if contextPath != "" {
if contextPath != "" {
return contextPath
} else if envPath != "" {
return envPath
}

return filepath.Join(os.Getenv("HOME"), DEFAULT_STORE_FILENAME)
Expand All @@ -40,27 +45,27 @@ func InferStorePath() string {
func GetPassphrase() (passphrase string) {
var err error

// Try to retrieve passphrase from env
// try to retrieve passphrase from env
passphrase = os.Getenv(ENV_PASSPHRASE_KEY)
if len(passphrase) > 0 {
return passphrase
}

// If passphrase wasn't found in env, try to fetch it from
// if passphrase wasn't found in env, try to fetch it from
// system keyring manager.
passphrase, err = keyring.Get(gKeyringService, gKeyringUser)
passphrase, err = keyring.Get(os.Getenv(ENV_KEYRING_SERVICE_KEY), os.Getenv(ENV_KEYRING_USER_KEY))
if len(passphrase) > 0 {
return passphrase
}

// If passphrase was enither found in the environment nor
// if passphrase was enither found in the environment nor
// system keyring manager try to fetch it from gpg-agent
if os.Getenv("GPG_AGENT_INFO") != "" {
passphrase, err = getGpgPassphrase(gMasterGpgId)
if os.Getenv("gpg_agent_info") != "" {
passphrase, err = getGpgPassphrase(os.Getenv(ENV_MASTER_GPG_ID_KEY))
}

if err != nil {
ErrorLogger.Fatal("No passphrase provided. Unable to open data store")
ErrorLogger.Fatal("no passphrase provided. unable to open data store")
}

return passphrase
Expand Down
20 changes: 16 additions & 4 deletions crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package trousseau

import (
"github.com/oleiade/trousseau/crypto/openpgp"
"path"
"os"
)


// Declare encryption types
type CryptoType int

Expand All @@ -20,14 +23,20 @@ const (
AES_256_ENCRYPTION CryptoAlgorithm = 1
)

// Gnupg variables
var GnupgHome = path.Join(os.Getenv("HOME"), ".gnupg")
var GnupgPubring func()string = func()string { return path.Join(GnupgHome, "pubring.gpg") }
var GnupgSecring func()string = func()string { return path.Join(GnupgHome, "secring.gpg") }

// DecryptAsymmetricPGP decrypts an OpenPGP message using GnuPG.
func DecryptAsymmetricPGP(encryptedData []byte, passphrase string) ([]byte, error) {
// Decrypt store data
decryptionKeys, err := openpgp.ReadSecRing(openpgp.SecringFile)
decryptionKeys, err := openpgp.ReadSecRing(GnupgSecring())
if err != nil {
return nil, err
}

plainData, err := openpgp.Decrypt(decryptionKeys, string(encryptedData), passphrase)
plainData, err := openpgp.Decrypt(encryptedData, decryptionKeys, passphrase)
if err != nil {
return nil, err
}
Expand All @@ -36,12 +45,15 @@ func DecryptAsymmetricPGP(encryptedData []byte, passphrase string) ([]byte, erro
}

func EncryptAsymmetricPGP(plainData []byte, recipients []string) ([]byte, error) {
encryptionKeys, err := openpgp.ReadPubRing(openpgp.PubringFile, recipients)
encryptionKeys, err := openpgp.ReadPubRing(GnupgPubring(), recipients)
if err != nil {
return nil, err
}

encData := openpgp.Encrypt(encryptionKeys, string(plainData))
encData, err := openpgp.Encrypt(plainData, encryptionKeys)
if err != nil {
return nil, err
}

return encData, nil
}
55 changes: 40 additions & 15 deletions crypto/openpgp/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,62 @@ import (
"io"
"io/ioutil"
"log"
"strings"
)

func Encrypt(encryptionKeys *openpgp.EntityList, s string) []byte {
buf := &bytes.Buffer{}
// Encrypt the provided bytes for the provided encryption
// keys recipients. Returns the encrypted content bytes.
func Encrypt(d []byte, encryptionKeys *openpgp.EntityList) ([]byte, error) {
var buffer *bytes.Buffer = &bytes.Buffer{}
var armoredWriter io.WriteCloser
var cipheredWriter io.WriteCloser
var err error

wa, err := armor.Encode(buf, "PGP MESSAGE", nil)
// Create an openpgp armored cipher writer pointing on our
// buffer
armoredWriter , err = armor.Encode(buffer, "PGP MESSAGE", nil)
if err != nil {
NewPgpError(ERR_ENCRYPTION_ENCODING, fmt.Sprintf("Can't make armor: %v", err))
}

w, err := openpgp.Encrypt(wa, *encryptionKeys, nil, nil, nil)
// Create an encrypted writer using the provided encryption keys
cipheredWriter, err = openpgp.Encrypt(armoredWriter, *encryptionKeys, nil, nil, nil)
if err != nil {
NewPgpError(ERR_ENCRYPTION_ENCRYPT, fmt.Sprintf("Error encrypting: %v", err))
}

_, err = io.Copy(w, strings.NewReader(s))
// Write (encrypts on the fly) the provided bytes to
// cipheredWriter
_, err = cipheredWriter.Write(d)
if err != nil {
log.Fatalf("Error copying encrypted content: %v", err)
}

w.Close()
wa.Close()
cipheredWriter.Close()
armoredWriter.Close()

return buf.Bytes()
return buffer.Bytes(), nil
}

func Decrypt(decryptionKeys *openpgp.EntityList, s, passphrase string) ([]byte, error) {
if s == "" {
// Decrypt tries to decrypt an OpenPGP armored block using the provided decryption keys
// and passphrase. If succesfull the plain content of the block is returned as []byte.
func Decrypt(d []byte, decryptionKeys *openpgp.EntityList, passphrase string) ([]byte, error) {
var armoredBlock *armor.Block
var message *openpgp.MessageDetails
var plain []byte
var err error

if d == nil {
return nil, nil
}

armorBlock, err := armor.Decode(strings.NewReader(s))
// Decode the OpenPGP armored block
armoredBlock, err = armor.Decode(bytes.NewReader(d))
if err != nil {
return nil, err
}

d, err := openpgp.ReadMessage(armorBlock.Body, decryptionKeys,
// Extract the message from the OpenPGP armored block
message, err = openpgp.ReadMessage(armoredBlock.Body, decryptionKeys,
func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
kp := []byte(passphrase)

Expand All @@ -56,6 +74,8 @@ func Decrypt(decryptionKeys *openpgp.EntityList, s, passphrase string) ([]byte,
for _, k := range keys {
err := k.PrivateKey.Decrypt(kp)
if err == nil {
// If no error were returned, we could succesfully
// decrypt the message using the provided private key
return nil, nil
}
}
Expand All @@ -64,11 +84,16 @@ func Decrypt(decryptionKeys *openpgp.EntityList, s, passphrase string) ([]byte,
"Invalid passphrase supplied.")
},
nil)
if err != nil {
return nil, fmt.Errorf("unable to decrypt trousseau data store. " +
"No private key able to decrypt it found in your keyring.")
}

// Read the plain message bytes
plain, err = ioutil.ReadAll(message.UnverifiedBody)
if err != nil {
return nil, err
}

bytes, err := ioutil.ReadAll(d.UnverifiedBody)
return bytes, err
return plain, err
}
Loading

0 comments on commit aa07142

Please sign in to comment.