ejson 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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: