ejson 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45c8c29f86387553314be3e8738a55173944bdf1
4
- data.tar.gz: 3353be24350564b401c3cfc631bd09d7ab98d1d1
3
+ metadata.gz: 9e7a3d4927ceae8e72ece8df8749391e2620d683
4
+ data.tar.gz: d3f5c4b1c24e2d73cde70f136f3a64c6ed0abb18
5
5
  SHA512:
6
- metadata.gz: 52504a192b550a1d4391617b5695a87f14e974299db5760cb845f14612b36faf54e2087b0184ce7cf3556a7c5ec1d2d75ad569cc6ea18cc501c70b8a26d3145c
7
- data.tar.gz: bb65c77a6500b0d550337e51fe7af6704c9c6c81b022e86dee2e968706100318427aea9f872895d0efc328bc38d4c3364299f1e496a8ddbce597dfbe2cd88904
6
+ metadata.gz: 8925b554189010a94fe8760c184c92ab3ab72771ef3cd217192f9a04067f4a650e086d3d3e9ed77c83e21f20ceb34fc63ef52d05965982e747706e3c72c7f490
7
+ data.tar.gz: 7b14d361b4e9b0398208205de262d9c360aeb82a6828e8e324ec0322258b18a2a3cb1a05544425c70d13f758c5ac421f2e3f6561e5903b95615efbc19339b391
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Burke Libbey
1
+ Copyright (c) 2014 Shopify
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -24,13 +24,21 @@ It can be arbitrarily nested.
24
24
  This updates `config/secrets.ejson` in place, encrypting any newly-added or
25
25
  modified values that are not yet encrypted. `ejson` is short-hand for `ejson encrypt`.
26
26
 
27
+ By default, it uses a public key that you won't be able to decrypt (and
28
+ shouldn't use because we *can* decrypt it!). You can use your own by following
29
+ the "Custom keypair" directions below. Feel free to fork the gem to reference
30
+ your own keypair by default.
31
+
27
32
  #### 3) Decrypt the file:
28
33
 
29
34
  ejson decrypt -k ~/.keys/ejson.priv.pem -p config/ejson.pub.pem secrets.production.ejson > secrets.production.json
35
+ # OR
36
+ ejson decrypt -i -k ~/.keys/ejson.priv.pem -p config/ejson.pub.pem secrets.production.ejson
30
37
 
31
38
  Unlike encrypt, decrypt doesn't update the file in-place; it prints the
32
39
  decrypted contents to stdout. It also requires access to the private key
33
- created in step 1.
40
+ created in step 1. By default, the secrets will be decrypted to stdout,
41
+ but passing the `-i` flag causes them to be overwritten to the input file.
34
42
 
35
43
  #### See `ejson help` for more information.
36
44
 
@@ -39,16 +47,15 @@ created in step 1.
39
47
  We use a single keypair internally; the default public key is fetched from S3
40
48
  on each run. However, you can generate your own keypair like so:
41
49
 
42
- mkdir config && cd config
43
50
  openssl req -x509 -nodes -days 100000 -newkey rsa:2048 -keyout privatekey.pem -out publickey.pem -subj '/'
44
51
 
45
52
  `publickey.pem` and `privatekey.pem` are created. Move `privatekey.pem`
46
- somewhere more secure.
47
-
48
- mkdir -p ~/.keys
49
- mv config/privatekey.pem ~/.keys/ejson.pem
53
+ somewhere more private, and move `publickey.pem` somewhere more public.
50
54
 
51
55
  Then you can encrypt like:
52
56
 
53
- ejson encrypt -p config/publickey.pem secrets.ejson
57
+ ejson encrypt -p publickey.pem secrets.ejson
58
+
59
+ If you'd like to fork the gem to reference your own public key, that
60
+ information lives around line 10 of `lib/ejson/cli.rb`.
54
61
 
data/ejson.gemspec CHANGED
@@ -5,7 +5,7 @@ require 'ejson/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "ejson"
8
- spec.version = Ejson::VERSION
8
+ spec.version = EJSON::VERSION
9
9
  spec.authors = ["Burke Libbey"]
10
10
  spec.email = ["burke.libbey@shopify.com"]
11
11
  spec.summary = %q{Asymmetric keywise encryption for JSON}
@@ -19,4 +19,5 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_runtime_dependency "thor", "~> 0.18"
22
+ spec.add_development_dependency "rake", "~> 10.3.2"
22
23
  end
data/lib/ejson.rb CHANGED
@@ -6,8 +6,8 @@ class EJSON
6
6
  extend Forwardable
7
7
  def_delegators :@encryption, :load_string, :dump_string
8
8
 
9
- def initialize(public_key_file, private_key_file = nil)
10
- @encryption = Encryption.new(public_key_file, private_key_file)
9
+ def initialize(public_key, private_key = nil)
10
+ @encryption = Encryption.new(public_key, private_key)
11
11
  end
12
12
 
13
13
  def load(json_text)
data/lib/ejson/cli.rb CHANGED
@@ -12,10 +12,17 @@ class EJSON
12
12
  default_task :encrypt
13
13
 
14
14
  desc "decrypt [file]", "decrypt some data from file to stdout"
15
+ method_option :inplace, type: :boolean, default: false, aliases: "-i", desc: "Overwrite input file rather than dumping to stdout"
15
16
  def decrypt(file)
16
17
  ciphertext = File.read(file)
17
18
  ej = EJSON.new(pubkey, options[:privkey])
18
- puts JSON.pretty_generate(ej.load(ciphertext).decrypt_all)
19
+ output = JSON.pretty_generate(ej.load(ciphertext).decrypt_all)
20
+ if options[:inplace]
21
+ File.open(file, "w") { |f| f.puts output }
22
+ puts "Wrote #{output.size} bytes to #{file}"
23
+ else
24
+ puts output
25
+ end
19
26
  rescue EJSON::Encryption::PrivateKeyMissing => e
20
27
  fatal("can't decrypt data without private key (specify path with -k)", e)
21
28
  rescue EJSON::Encryption::ExpectedEncryptedString => e
@@ -41,6 +48,7 @@ class EJSON
41
48
 
42
49
  desc "version", "show version information"
43
50
  def version
51
+ require 'ejson/version'
44
52
  puts "ejson version #{EJSON::VERSION}"
45
53
  end
46
54
 
@@ -7,10 +7,10 @@ class EJSON
7
7
  PrivateKeyMissing = Class.new(StandardError)
8
8
  ExpectedEncryptedString = Class.new(StandardError)
9
9
 
10
- def initialize(public_key_file, private_key_file)
11
- @public_key_x509 = load_public_key(public_key_file)
12
- if private_key_file
13
- @private_key_rsa = load_private_key(private_key_file)
10
+ def initialize(public_key, private_key)
11
+ @public_key_x509 = load_public_key(public_key)
12
+ if private_key
13
+ @private_key_rsa = load_private_key(private_key)
14
14
  end
15
15
  end
16
16
 
@@ -47,15 +47,16 @@ class EJSON
47
47
  pkcs7.decrypt(@private_key_rsa, @public_key_x509)
48
48
  end
49
49
 
50
- def load_public_key(public_key_file)
51
- public_key_pem = File.read(public_key_file)
52
- OpenSSL::X509::Certificate.new(public_key_pem)
50
+ def load_public_key(public_key)
51
+ OpenSSL::X509::Certificate.new(get_pem(public_key))
53
52
  end
54
53
 
55
- def load_private_key(private_key_file)
56
- private_key_pem = File.read(private_key_file)
57
- OpenSSL::PKey::RSA.new(private_key_pem)
54
+ def load_private_key(private_key)
55
+ OpenSSL::PKey::RSA.new(get_pem(private_key))
58
56
  end
59
57
 
58
+ def get_pem(string)
59
+ string =~ /^-----BEGIN/ ? string : File.read(string)
60
+ end
60
61
  end
61
62
  end
data/lib/ejson/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- class Ejson
2
- VERSION = "0.2.2"
1
+ class EJSON
2
+ VERSION = "0.3.0"
3
3
  end
data/test/ejson_test.rb CHANGED
@@ -6,7 +6,7 @@ require 'ejson/cli'
6
6
  class CLITest < Minitest::Unit::TestCase
7
7
 
8
8
  def test_ejson
9
- f = Tempfile.create("encrypt")
9
+ f = Tempfile.new("encrypt")
10
10
 
11
11
  f.puts JSON.dump({a: "b"})
12
12
  f.close
@@ -33,8 +33,25 @@ class CLITest < Minitest::Unit::TestCase
33
33
  File.unlink(f.path)
34
34
  end
35
35
 
36
+ def test_inplace
37
+ f = Tempfile.new("encrypt")
38
+
39
+ f.puts JSON.dump({a: "b"})
40
+ f.close
41
+
42
+ runcli "encrypt", "-p", pubkey, f.path
43
+ encrypted = JSON.load(File.read(f.path))
44
+ assert_match(/\AENC\[MIIB.*\]\z/, encrypted["a"])
45
+
46
+ runcli "decrypt", "-i", "-p", pubkey, "-k", privkey, f.path
47
+ decrypted = JSON.load(File.read(f.path))
48
+ refute_match(/\AENC\[MIIB.*\]\z/, decrypted["a"])
49
+ ensure
50
+ File.unlink(f.path)
51
+ end
52
+
36
53
  def test_default_key_exists
37
- f = Tempfile.create("encrypt")
54
+ f = Tempfile.new("encrypt")
38
55
 
39
56
  f.puts JSON.dump({a: "b"})
40
57
  f.close
@@ -50,7 +67,7 @@ class CLITest < Minitest::Unit::TestCase
50
67
  end
51
68
 
52
69
  def test_library_is_picky
53
- f = Tempfile.create("decrypt")
70
+ f = Tempfile.new("decrypt")
54
71
  f.puts JSON.dump({a: "b"})
55
72
  f.close
56
73
  assert_raises(EJSON::Encryption::ExpectedEncryptedString) {
@@ -60,6 +77,16 @@ class CLITest < Minitest::Unit::TestCase
60
77
  File.unlink(f.path)
61
78
  end
62
79
 
80
+ def test_key_strings
81
+ public_key = File.read(pubkey)
82
+ private_key = File.read(privkey)
83
+
84
+ @enc = EJSON::Encryption.new(public_key, private_key)
85
+
86
+ assert_equal public_key, @enc.instance_variable_get(:@public_key_x509).to_s
87
+ assert_equal private_key, @enc.instance_variable_get(:@private_key_rsa).to_s
88
+ end
89
+
63
90
  private
64
91
 
65
92
  def encrypt(path)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ejson
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-15 00:00:00.000000000 Z
11
+ date: 2014-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.18'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 10.3.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 10.3.2
27
41
  description: Secret management by encrypting values in a JSON hash with a public/private
28
42
  keypair
29
43
  email:
@@ -67,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
81
  version: '0'
68
82
  requirements: []
69
83
  rubyforge_project:
70
- rubygems_version: 2.2.0
84
+ rubygems_version: 2.2.2
71
85
  signing_key:
72
86
  specification_version: 4
73
87
  summary: Asymmetric keywise encryption for JSON
@@ -75,4 +89,3 @@ test_files:
75
89
  - test/ejson_test.rb
76
90
  - test/privatekey.pem
77
91
  - test/publickey.pem
78
- has_rdoc: