ejson 0.4.0 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/ejson +12 -2
- data/build/darwin-amd64/ejson +0 -0
- data/build/linux-amd64/ejson +0 -0
- data/ejson.gemspec +6 -9
- data/lib/ejson/version.rb +2 -2
- data/man/man1/ejson-decrypt.1.gz +0 -0
- data/man/man1/ejson-encrypt.1.gz +0 -0
- data/man/man1/ejson-keygen.1.gz +0 -0
- data/man/man1/ejson.1.gz +0 -0
- data/man/man5/ejson.5.gz +0 -0
- metadata +13 -47
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/README.md +0 -61
- data/Rakefile +0 -7
- data/lib/ejson/cli.rb +0 -94
- data/lib/ejson/encryption.rb +0 -62
- data/lib/ejson.rb +0 -81
- data/test/ejson_test.rb +0 -124
- data/test/privatekey.pem +0 -27
- data/test/publickey.pem +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edf2ad7b024d89456d694953b6710bd2e6d41761
|
4
|
+
data.tar.gz: 2ea3452b0e34fb1401a078f1cee4b81e0b595ce4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7801843e1f8e78e796f43ef8fe4131131351e27777c3aacd66cbba110aafc58a60268c43d91849df3b4d92356940a8493a416f638145730bac4466a92f432c8
|
7
|
+
data.tar.gz: 3c59e675ea9276bf587eb174cb1f62210917683f89ca3d676dd38674bb092404140f5d80034283a6fb127d6e6baffd9cb01069c7fcda0dccd69130d9d8d6d6ef
|
data/bin/ejson
CHANGED
@@ -1,4 +1,14 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
platform = `uname -sm`
|
2
3
|
|
3
|
-
|
4
|
-
|
4
|
+
dir = case platform
|
5
|
+
when /^Darwin/ ; "darwin-amd64"
|
6
|
+
when /^Linux.*64/ ; "linux-amd64"
|
7
|
+
else
|
8
|
+
puts "Ejson is not supported on your platform."
|
9
|
+
end
|
10
|
+
|
11
|
+
bindir = File.expand_path("../../build/#{dir}", __FILE__)
|
12
|
+
ENV['PATH'] = "#{bindir}:#{ENV['PATH']}"
|
13
|
+
ENV['MANPATH'] = File.expand_path("../../man", __FILE__)
|
14
|
+
exec "ejson", *ARGV
|
Binary file
|
Binary file
|
data/ejson.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
require File.expand_path('../lib/ejson/version', __FILE__)
|
3
|
+
|
4
|
+
files = File.read("MANIFEST").lines.map(&:chomp)
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "ejson"
|
@@ -13,11 +13,8 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "https://github.com/Shopify/ejson"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files =
|
17
|
-
spec.executables =
|
18
|
-
spec.test_files =
|
16
|
+
spec.files = files
|
17
|
+
spec.executables = ["ejson"]
|
18
|
+
spec.test_files = []
|
19
19
|
spec.require_paths = ["lib"]
|
20
|
-
|
21
|
-
spec.add_runtime_dependency "thor", "~> 0.18"
|
22
|
-
spec.add_development_dependency "rake", "~> 10.3.2"
|
23
20
|
end
|
data/lib/ejson/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.
|
1
|
+
module EJSON
|
2
|
+
VERSION = "1.0.0.rc1"
|
3
3
|
end
|
Binary file
|
Binary file
|
Binary file
|
data/man/man1/ejson.1.gz
ADDED
Binary file
|
data/man/man5/ejson.5.gz
ADDED
Binary file
|
metadata
CHANGED
@@ -1,43 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ejson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.rc1
|
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-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: thor
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.18'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
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
|
11
|
+
date: 2014-11-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
41
13
|
description: Secret management by encrypting values in a JSON hash with a public/private
|
42
14
|
keypair
|
43
15
|
email:
|
@@ -47,20 +19,17 @@ executables:
|
|
47
19
|
extensions: []
|
48
20
|
extra_rdoc_files: []
|
49
21
|
files:
|
50
|
-
- ".gitignore"
|
51
|
-
- Gemfile
|
52
22
|
- LICENSE.txt
|
53
|
-
- README.md
|
54
|
-
- Rakefile
|
55
23
|
- bin/ejson
|
24
|
+
- build/darwin-amd64/ejson
|
25
|
+
- build/linux-amd64/ejson
|
56
26
|
- ejson.gemspec
|
57
|
-
- lib/ejson.rb
|
58
|
-
- lib/ejson/cli.rb
|
59
|
-
- lib/ejson/encryption.rb
|
60
27
|
- lib/ejson/version.rb
|
61
|
-
-
|
62
|
-
-
|
63
|
-
-
|
28
|
+
- man/man1/ejson-decrypt.1.gz
|
29
|
+
- man/man1/ejson-encrypt.1.gz
|
30
|
+
- man/man1/ejson-keygen.1.gz
|
31
|
+
- man/man1/ejson.1.gz
|
32
|
+
- man/man5/ejson.5.gz
|
64
33
|
homepage: https://github.com/Shopify/ejson
|
65
34
|
licenses:
|
66
35
|
- MIT
|
@@ -76,16 +45,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
45
|
version: '0'
|
77
46
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
47
|
requirements:
|
79
|
-
- - "
|
48
|
+
- - ">"
|
80
49
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
50
|
+
version: 1.3.1
|
82
51
|
requirements: []
|
83
52
|
rubyforge_project:
|
84
53
|
rubygems_version: 2.2.2
|
85
54
|
signing_key:
|
86
55
|
specification_version: 4
|
87
56
|
summary: Asymmetric keywise encryption for JSON
|
88
|
-
test_files:
|
89
|
-
- test/ejson_test.rb
|
90
|
-
- test/privatekey.pem
|
91
|
-
- test/publickey.pem
|
57
|
+
test_files: []
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/README.md
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# EJSON
|
2
|
-
|
3
|
-
EJSON is a small library to manage encrypted secrets using PKCS7 (asymmetric)
|
4
|
-
encryption. It provides a simple command interface to manage and update secrets
|
5
|
-
in a JSON file where keys are cleartext and values are encrypted.
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
It's on rubygems. Just `gem install ejson` or add it to your `Gemfile`.
|
10
|
-
|
11
|
-
## Usage
|
12
|
-
|
13
|
-
#### 1) Create a `secrets.ejson`:
|
14
|
-
|
15
|
-
echo '{"a": "b"}' > config/secrets.production.ejson
|
16
|
-
|
17
|
-
Keys in this file will remain in cleartext, while values will all be encrypted.
|
18
|
-
It can be arbitrarily nested.
|
19
|
-
|
20
|
-
#### 2) Encrypt the file:
|
21
|
-
|
22
|
-
ejson
|
23
|
-
|
24
|
-
This updates `config/secrets.ejson` in place, encrypting any newly-added or
|
25
|
-
modified values that are not yet encrypted. `ejson` is short-hand for `ejson encrypt`.
|
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
|
-
|
32
|
-
#### 3) Decrypt the file:
|
33
|
-
|
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
|
37
|
-
|
38
|
-
Unlike encrypt, decrypt doesn't update the file in-place; it prints the
|
39
|
-
decrypted contents to stdout. It also requires access to the private key
|
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.
|
42
|
-
|
43
|
-
#### See `ejson help` for more information.
|
44
|
-
|
45
|
-
## Custom keypair:
|
46
|
-
|
47
|
-
We use a single keypair internally; the default public key is fetched from S3
|
48
|
-
on each run. However, you can generate your own keypair like so:
|
49
|
-
|
50
|
-
openssl req -x509 -nodes -days 100000 -newkey rsa:2048 -keyout privatekey.pem -out publickey.pem -subj '/'
|
51
|
-
|
52
|
-
`publickey.pem` and `privatekey.pem` are created. Move `privatekey.pem`
|
53
|
-
somewhere more private, and move `publickey.pem` somewhere more public.
|
54
|
-
|
55
|
-
Then you can encrypt like:
|
56
|
-
|
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`.
|
61
|
-
|
data/Rakefile
DELETED
data/lib/ejson/cli.rb
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
require 'thor'
|
2
|
-
require 'json'
|
3
|
-
require 'ejson'
|
4
|
-
require 'net/http'
|
5
|
-
|
6
|
-
class EJSON
|
7
|
-
|
8
|
-
class CLI < Thor
|
9
|
-
class_option "privkey", type: :string, aliases: "-k", desc: "Path to PKCS7 private key in PEM format"
|
10
|
-
class_option "pubkey", type: :string, aliases: "-p", desc: "Path or URL to PKCS7 public key in PEM format", default: "https://s3.amazonaws.com/shopify-ops/ejson-publickey.pem"
|
11
|
-
|
12
|
-
default_task :encrypt
|
13
|
-
|
14
|
-
desc "decrypt [file]", "decrypt some data from file to stdout"
|
15
|
-
method_option :out, type: :string, default: false, aliases: "-o", desc: "Write to a file rather than stdout"
|
16
|
-
def decrypt(file)
|
17
|
-
ciphertext = File.read(file)
|
18
|
-
ej = EJSON.new(pubkey, options[:privkey])
|
19
|
-
output = JSON.pretty_generate(ej.load(ciphertext).decrypt_all)
|
20
|
-
if options[:out]
|
21
|
-
File.open(options[:out], "w") { |f| f.puts output }
|
22
|
-
puts "Wrote #{output.size} bytes to #{options[:out]}"
|
23
|
-
else
|
24
|
-
puts output
|
25
|
-
end
|
26
|
-
rescue EJSON::Encryption::PrivateKeyMissing => e
|
27
|
-
fatal("can't decrypt data without private key (specify path with -k)", e)
|
28
|
-
rescue EJSON::Encryption::ExpectedEncryptedString => e
|
29
|
-
fatal("can't decrypt data with cleartext strings (use ejson recrypt first)", e)
|
30
|
-
end
|
31
|
-
|
32
|
-
desc "encrypt [file=**/*.ejson]", "encrypt an ejson file in place (encrypt any unencrypted values)"
|
33
|
-
def encrypt(file="**/*.ejson")
|
34
|
-
ej = EJSON.new(pubkey)
|
35
|
-
fpaths = Dir.glob(file)
|
36
|
-
if fpaths.empty?
|
37
|
-
fatal("no ejson files found!", nil)
|
38
|
-
end
|
39
|
-
fpaths.each do |fpath|
|
40
|
-
data = ej.load(File.read(fpath))
|
41
|
-
dump = data.dump
|
42
|
-
File.open(fpath, "w") { |f| f.puts dump }
|
43
|
-
puts "Wrote #{dump.size+1} bytes to #{fpath}"
|
44
|
-
end
|
45
|
-
rescue OpenSSL::X509::CertificateError => e
|
46
|
-
fatal("invalid certificate", e)
|
47
|
-
end
|
48
|
-
|
49
|
-
desc "version", "show version information"
|
50
|
-
def version
|
51
|
-
require 'ejson/version'
|
52
|
-
puts "ejson version #{EJSON::VERSION}"
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def fatal(str, err=str)
|
58
|
-
raise err if defined?(Minitest)
|
59
|
-
msg = $stderr.tty? ? "\x1b[31m#{str}\x1b[0m" : str
|
60
|
-
$stderr.puts msg
|
61
|
-
exit 1
|
62
|
-
end
|
63
|
-
|
64
|
-
def get_input(file)
|
65
|
-
return File.read(file) if file
|
66
|
-
$stdin.read
|
67
|
-
end
|
68
|
-
|
69
|
-
def pubkey
|
70
|
-
@pubkey ||= _pubkey
|
71
|
-
end
|
72
|
-
|
73
|
-
def _pubkey
|
74
|
-
if options[:pubkey] =~ %r{https://}
|
75
|
-
uri = URI.parse(options[:pubkey])
|
76
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
77
|
-
http.use_ssl = true
|
78
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
79
|
-
req = Net::HTTP::Get.new(URI.parse(options[:pubkey]).request_uri)
|
80
|
-
resp = http.request(req)
|
81
|
-
resp.value # raises on code >399
|
82
|
-
f = Tempfile.new("pubkey")
|
83
|
-
f.write resp.body
|
84
|
-
f.close
|
85
|
-
at_exit { f.unlink }
|
86
|
-
f.path
|
87
|
-
else
|
88
|
-
options[:pubkey]
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
data/lib/ejson/encryption.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'openssl'
|
2
|
-
require 'base64'
|
3
|
-
|
4
|
-
class EJSON
|
5
|
-
|
6
|
-
class Encryption
|
7
|
-
PrivateKeyMissing = Class.new(StandardError)
|
8
|
-
ExpectedEncryptedString = Class.new(StandardError)
|
9
|
-
|
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
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
ENCRYPTED = /\AENC\[(.*)\]\n*\z/m
|
18
|
-
|
19
|
-
def load(str)
|
20
|
-
if str =~ ENCRYPTED
|
21
|
-
decrypt_string($1)
|
22
|
-
else
|
23
|
-
raise ExpectedEncryptedString
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def dump(str)
|
28
|
-
if str =~ ENCRYPTED
|
29
|
-
str
|
30
|
-
else
|
31
|
-
"ENC[#{encrypt_string(str)}]"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def encrypt_string(plaintext)
|
38
|
-
cipher = OpenSSL::Cipher::AES.new(256, :CBC)
|
39
|
-
bin = OpenSSL::PKCS7.encrypt([@public_key_x509], plaintext, cipher, OpenSSL::PKCS7::BINARY).to_der
|
40
|
-
Base64.encode64(bin).tr("\n",'')
|
41
|
-
end
|
42
|
-
|
43
|
-
def decrypt_string(ciphertext)
|
44
|
-
raise PrivateKeyMissing unless @private_key_rsa
|
45
|
-
bin = Base64.decode64(ciphertext)
|
46
|
-
pkcs7 = OpenSSL::PKCS7.new(bin)
|
47
|
-
pkcs7.decrypt(@private_key_rsa, @public_key_x509)
|
48
|
-
end
|
49
|
-
|
50
|
-
def load_public_key(public_key)
|
51
|
-
OpenSSL::X509::Certificate.new(get_pem(public_key))
|
52
|
-
end
|
53
|
-
|
54
|
-
def load_private_key(private_key)
|
55
|
-
OpenSSL::PKey::RSA.new(get_pem(private_key))
|
56
|
-
end
|
57
|
-
|
58
|
-
def get_pem(string)
|
59
|
-
string =~ /^-----BEGIN/ ? string : File.read(string)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
data/lib/ejson.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'forwardable'
|
3
|
-
require 'ejson/encryption'
|
4
|
-
|
5
|
-
class EJSON
|
6
|
-
extend Forwardable
|
7
|
-
def_delegators :@encryption, :load_string, :dump_string
|
8
|
-
|
9
|
-
def initialize(public_key, private_key = nil)
|
10
|
-
@encryption = Encryption.new(public_key, private_key)
|
11
|
-
end
|
12
|
-
|
13
|
-
def load(json_text)
|
14
|
-
Data.new(JSON.load(json_text), @encryption)
|
15
|
-
end
|
16
|
-
|
17
|
-
def serializer
|
18
|
-
@serializer ||= Serializer.new(@encryption)
|
19
|
-
end
|
20
|
-
|
21
|
-
class Serializer
|
22
|
-
|
23
|
-
def initialize(encryption)
|
24
|
-
@encryption = encryption
|
25
|
-
end
|
26
|
-
|
27
|
-
def dump(data)
|
28
|
-
data = Data.new(data, @encryption) unless data.is_a?(Data)
|
29
|
-
data.dump
|
30
|
-
end
|
31
|
-
|
32
|
-
def load(data)
|
33
|
-
Data.new(JSON.parse(data), @encryption).decrypt_all
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
class Data
|
39
|
-
extend Forwardable
|
40
|
-
def_delegators :@data, :[]=
|
41
|
-
|
42
|
-
attr_reader :encryption
|
43
|
-
def initialize(data, encryption)
|
44
|
-
@data, @encryption = data, encryption
|
45
|
-
end
|
46
|
-
|
47
|
-
def dump
|
48
|
-
JSON.pretty_generate(encrypt_all(@data))
|
49
|
-
end
|
50
|
-
|
51
|
-
def encrypt_all(data=@data)
|
52
|
-
case data
|
53
|
-
when Hash
|
54
|
-
Hash[ data.map { |k,v| [k, encrypt_all(v)] } ]
|
55
|
-
when Array
|
56
|
-
data.map { |d| encrypt_all(d) }
|
57
|
-
when String
|
58
|
-
encryption.dump(data)
|
59
|
-
else
|
60
|
-
data
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def decrypt_all(data=@data)
|
65
|
-
case data
|
66
|
-
when Hash
|
67
|
-
Hash[ data.map { |k,v| [k, decrypt_all(v)] } ]
|
68
|
-
when Array
|
69
|
-
data.map { |d| decrypt_all(d) }
|
70
|
-
when String
|
71
|
-
encryption.load(data)
|
72
|
-
else
|
73
|
-
data
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
|
data/test/ejson_test.rb
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'tempfile'
|
3
|
-
|
4
|
-
require 'ejson/cli'
|
5
|
-
|
6
|
-
class CLITest < Minitest::Unit::TestCase
|
7
|
-
|
8
|
-
def test_ejson
|
9
|
-
f = Tempfile.new("encrypt")
|
10
|
-
|
11
|
-
f.puts JSON.dump({a: "b"})
|
12
|
-
f.close
|
13
|
-
|
14
|
-
encrypt f.path
|
15
|
-
|
16
|
-
first_run = JSON.load(File.read(f.path))
|
17
|
-
assert_match(/\AENC\[MIIB.*\]\z/, first_run["a"])
|
18
|
-
|
19
|
-
File.open(f.path, "w") { |f2|
|
20
|
-
f2.puts JSON.dump(first_run.merge({new_key: "new_value"}))
|
21
|
-
}
|
22
|
-
|
23
|
-
encrypt f.path
|
24
|
-
|
25
|
-
second_run = JSON.load(File.read(f.path))
|
26
|
-
|
27
|
-
assert_equal first_run["a"], second_run["a"]
|
28
|
-
assert_match(/\AENC\[MIIB.*\]\z/, second_run["new_key"])
|
29
|
-
|
30
|
-
val = JSON.parse(decrypt(f.path))
|
31
|
-
assert_equal({"a" => "b", "new_key" => "new_value"}, val)
|
32
|
-
ensure
|
33
|
-
File.unlink(f.path)
|
34
|
-
end
|
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", "-o", f.path, "-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
|
-
|
53
|
-
def test_default_key_exists
|
54
|
-
f = Tempfile.new("encrypt")
|
55
|
-
|
56
|
-
f.puts JSON.dump({a: "b"})
|
57
|
-
f.close
|
58
|
-
|
59
|
-
runcli "encrypt", f.path # no pubkey specified
|
60
|
-
|
61
|
-
first_run = JSON.load(File.read(f.path))
|
62
|
-
# We don't have the decryption key to this, and it may change over time,
|
63
|
-
# so just make sure it was encrypted.
|
64
|
-
assert_match(/\AENC\[MIIB.*\]\z/, first_run["a"])
|
65
|
-
ensure
|
66
|
-
File.unlink(f.path)
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_library_is_picky
|
70
|
-
f = Tempfile.new("decrypt")
|
71
|
-
f.puts JSON.dump({a: "b"})
|
72
|
-
f.close
|
73
|
-
assert_raises(EJSON::Encryption::ExpectedEncryptedString) {
|
74
|
-
decrypt(f.path)
|
75
|
-
}
|
76
|
-
ensure
|
77
|
-
File.unlink(f.path)
|
78
|
-
end
|
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
|
-
|
90
|
-
def test_serializer_api
|
91
|
-
serializer = EJSON.new(pubkey, privkey).serializer
|
92
|
-
data = {'foo' => 'bar'}
|
93
|
-
|
94
|
-
assert_equal data, serializer.load(serializer.dump(data))
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_serializer_safety
|
98
|
-
serializer = EJSON.new(pubkey, privkey).serializer
|
99
|
-
refute serializer.dump('foo' => 'bar').include?('bar')
|
100
|
-
end
|
101
|
-
|
102
|
-
private
|
103
|
-
|
104
|
-
def encrypt(path)
|
105
|
-
runcli "encrypt", "-p", pubkey, path
|
106
|
-
end
|
107
|
-
|
108
|
-
def decrypt(path)
|
109
|
-
runcli "decrypt", "-p", pubkey, "-k", privkey, path
|
110
|
-
end
|
111
|
-
|
112
|
-
def runcli(*args)
|
113
|
-
sio = StringIO.new
|
114
|
-
_stdout, $stdout = $stdout, sio
|
115
|
-
EJSON::CLI.start(args)
|
116
|
-
sio.string.chomp
|
117
|
-
ensure
|
118
|
-
$stdout = _stdout
|
119
|
-
end
|
120
|
-
|
121
|
-
def pubkey ; File.expand_path("../publickey.pem", __FILE__); end
|
122
|
-
def privkey ; File.expand_path("../privatekey.pem", __FILE__); end
|
123
|
-
|
124
|
-
end
|
data/test/privatekey.pem
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
-----BEGIN RSA PRIVATE KEY-----
|
2
|
-
MIIEogIBAAKCAQEAunMnKCNM9NRDvaANZ3wSBTM7EA4fl3ix/QjwCp3k118n7+Jf
|
3
|
-
1DpdBAjqbx0jWVUZHjKan4t4ZHkCTKW4BXGzdEWVkFebYtYdxCm9DAiHFV53RscI
|
4
|
-
gVmzrxxpC8Lxa7RApam1iGPK7TXXlkMe+2d3Jij1hZdCHCYT48/DDBRtIEcXCZRg
|
5
|
-
nFkoSuvGbGwMBCxVhLTnvveIF5IgBV3la3vPJFfY62Hafuinpsy/hL4108pbrQcq
|
6
|
-
oiyb3OgflTe6JrBmA29qqWoCLAW+6XRgcHsOUfTYiBx6XFHQ42SfzQhu+FY57a38
|
7
|
-
Q3TkZLOb6abE6t5lsBqnJoE+dL/2WjLkhxQ/jQIDAQABAoIBAErqjBg/nuNdCt79
|
8
|
-
mYU0QBVg0WGRGzaEo5fVaIYLjXDQZj6oCfM/hDJj1rbQ0WxKmi4dDS4AH17XlInx
|
9
|
-
qHBfkEiu0PrPiLr857bzQme8YXK/o1OIE63NujopQzgbm1+4bKVj/HISDu6jTL2u
|
10
|
-
uJsxpplpqcWE0mZ3ElTeHTQUXQizdz12DPn5vgXvtVS0yFFBErE7aAKorRRFoLPq
|
11
|
-
OcajLIMODMo6huUAJW7uYR6PT6uwbt3Phc+VLQtdXpCCfLtDJK427G/5uJ/2vnY/
|
12
|
-
rLVWConeNZcUDWRuc34agiXA4yjErXdKXJ/yiEdz2pKtAerf+N9VCoIBLBala3oL
|
13
|
-
2BeMYY0CgYEA848omruvavfp4dJimdEHj0yTsFFggGHefoJWHG8Cvgyv9avISiAk
|
14
|
-
T5gB01pSjpTTGL+Ba2aeSPKgKZcGNjp/F5xzeZzuP2tMxT8bs2FR3y9tGmLnhvF8
|
15
|
-
JkKtlHilrGLt4pWh9eF+jiLDDmJE1N3fCU8TtIva+a/M60ZORA5ZSrcCgYEAw/k3
|
16
|
-
sJs72xhUhjrNdpzww5dpHYxmoOxhCTyKG1H0r4sQ0Jv9w4K3mrphp/WRygA2LylO
|
17
|
-
iCEc+56JJ6l4A6rdSFyV+YRtcdU7TKi9sarMDVBttqWsDkr/bnIIHE+QQhsScEBH
|
18
|
-
e7rHE+1NP5rPfDB7ibBJ3QCOCpjHbkhUGAZIU9sCgYBa176RWAepoiY98DaOoIRt
|
19
|
-
UmaTkQapW9ec4Ag2OsGPGTRYMWZXH33rogqsRjgcri2+QU+IO5I2KyjJ2maau17D
|
20
|
-
87quVXYXeXH87/jpAxeCYzIScWlhz5g6vQv5ILbKgWuw45axGxYU9apDJyv9KXQT
|
21
|
-
CMeUw8U88/E+n855W9C6KQKBgGtfKU7+zl2tR+o/X4FEXXmchIAnA7fZqxTHcZek
|
22
|
-
YJ6pX+4b+X5cKUKCKa0/k8AMO6O9SwS0t894vgbYCCRiQlk6OQV7tAcxYAsRTNWC
|
23
|
-
Ecidr27p+IngN3EI0z7HrO87K/AKl9/HpvlZBAD8Tf/qBFWdG+sVOb2+lU3sHP8I
|
24
|
-
uioPAoGAVWyvmQsABl3ydPrvVl4zk3AHm3Bnouy1vM1RchQzXp6OD/u5mNGJ37Ks
|
25
|
-
zIgipj/z9xf4J3ii5w0Qnxusq9Zy/6xKO1pgIEhiJUAYcm5jHGC51n7Y+d1NUPe1
|
26
|
-
gnJAzuwmvbefN800tmZJtWv7dWSc7whoFsdR1rNwrlZXUoNJzPk=
|
27
|
-
-----END RSA PRIVATE KEY-----
|
data/test/publickey.pem
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
2
|
-
MIIC5jCCAc6gAwIBAgIJAKY1nRwN7afeMA0GCSqGSIb3DQEBBQUAMAAwIBcNMTQw
|
3
|
-
MzE0MTc1ODQzWhgPMjI4NzEyMjgxNzU4NDNaMAAwggEiMA0GCSqGSIb3DQEBAQUA
|
4
|
-
A4IBDwAwggEKAoIBAQC6cycoI0z01EO9oA1nfBIFMzsQDh+XeLH9CPAKneTXXyfv
|
5
|
-
4l/UOl0ECOpvHSNZVRkeMpqfi3hkeQJMpbgFcbN0RZWQV5ti1h3EKb0MCIcVXndG
|
6
|
-
xwiBWbOvHGkLwvFrtEClqbWIY8rtNdeWQx77Z3cmKPWFl0IcJhPjz8MMFG0gRxcJ
|
7
|
-
lGCcWShK68ZsbAwELFWEtOe+94gXkiAFXeVre88kV9jrYdp+6KemzL+EvjXTylut
|
8
|
-
ByqiLJvc6B+VN7omsGYDb2qpagIsBb7pdGBwew5R9NiIHHpcUdDjZJ/NCG74Vjnt
|
9
|
-
rfxDdORks5vppsTq3mWwGqcmgT50v/ZaMuSHFD+NAgMBAAGjYTBfMB0GA1UdDgQW
|
10
|
-
BBTzh5Sf8+voPm2ZI6iHFQ+gItYb6zAwBgNVHSMEKTAngBTzh5Sf8+voPm2ZI6iH
|
11
|
-
FQ+gItYb66EEpAIwAIIJAKY1nRwN7afeMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN
|
12
|
-
AQEFBQADggEBACr61pBSpsz931OUztFcDjm07u+vatM5XE5qAH18BZeKbXzCRz4j
|
13
|
-
9cAEYIYrtBdJZj3RLDzKB3Hn38BeuXebb4UlbzPJwIj1klHKH90Nwl84XWBCJqPX
|
14
|
-
rsGv7C5EOLAR1w/hxT+K2JC2LDJz9hkuDU1hjX1MeRpnJwXzPbHBQvgYb4lIgaOb
|
15
|
-
ikSlcTpkdG5fGafanyZwxDeQsy4tHAUP/jRQ4/Xzkzp0GzuX+v9d+2FXJLyoh6vJ
|
16
|
-
Fze3kL1+RH13Fn5NkdTAHpkX9AX0BuLKWslY3I/lusn3x9kPxVQTmTF2WQTVdKDg
|
17
|
-
FDvqWYvyLcuiWcfNUdy3EOpKLBKyyan3DZ8=
|
18
|
-
-----END CERTIFICATE-----
|