nimbussecure 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.md +104 -0
- data/Rakefile +6 -0
- data/bin/nimbussecure +102 -0
- data/lib/nimbussecure.rb +72 -0
- data/lib/nimbussecure/accounts.rb +16 -0
- data/lib/nimbussecure/attr_accessor.rb +21 -0
- data/lib/nimbussecure/base.rb +44 -0
- data/lib/nimbussecure/config.rb +19 -0
- data/lib/nimbussecure/connect.rb +60 -0
- data/lib/nimbussecure/crypt_key.rb +75 -0
- data/lib/nimbussecure/errors.rb +7 -0
- data/lib/nimbussecure/results.rb +20 -0
- data/lib/nimbussecure/stored_key.rb +47 -0
- data/lib/nimbussecure/version.rb +3 -0
- data/nimbussecure.gemspec +27 -0
- data/pry_load.rb +2 -0
- data/test/accounts_spec.rb +18 -0
- data/test/basic_key_lookup_spec.rb +31 -0
- data/test/fixtures/vcr_cassettes/accounts/test.yml +52 -0
- data/test/fixtures/vcr_cassettes/lookup/key1.yml +52 -0
- data/test/fixtures/vcr_cassettes/lookup/key2.yml +101 -0
- data/test/fixtures/vcr_cassettes/lookup/key3.yml +52 -0
- data/test/minitest_helper.rb +10 -0
- data/test/run_tests.rb +6 -0
- metadata +135 -0
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# Nimbus Secure Store Client
|
2
|
+
This gem provides the functionality required to talk to the Nimbus Secure
|
3
|
+
service.
|
4
|
+
Nimbus Secure is a service that provides highly encrypted storage of
|
5
|
+
keys, passwords, tokens, and other private information necessary for running
|
6
|
+
an application.
|
7
|
+
For instance, you may store database credentials, service credentials,
|
8
|
+
session cookie encryption keys, AWS keys, and other sensitive information
|
9
|
+
without fear of them being stolen or accessible from any unauthorized
|
10
|
+
individual.
|
11
|
+
The data is stored encrypted, and the encryption keys are not communicated
|
12
|
+
to the Nimbus Secure, meaning no one other than you may have access
|
13
|
+
to this secure information.
|
14
|
+
|
15
|
+
# The Service
|
16
|
+
To use this Gem, you must sign up for the service by visiting
|
17
|
+
www.nimbus secure.com and signing up for an account. Both
|
18
|
+
paid and free accounts are available.
|
19
|
+
|
20
|
+
Once you sign up for the service, you create crypt keys, which are
|
21
|
+
secured tokens used to encrypt and decrypt the data you store within
|
22
|
+
the service. While you set up the crypt keys from the service
|
23
|
+
website, the crypt keys themselves are never sent to our servers,
|
24
|
+
only you and anyone or system you authorize by giving them your
|
25
|
+
crypt key will have access to the stored data within the service.
|
26
|
+
|
27
|
+
You may create as many crypt keys as you desire. Typically, one per
|
28
|
+
service or system is a good choice. Additionally, you can add new
|
29
|
+
crypt keys and roll your data over to use a new crypt key very
|
30
|
+
easily in order to increase your security (key rotation). Each crypt
|
31
|
+
key has a name for easy identification, and we store a salted digest
|
32
|
+
of the key itself to verify correctness when it is provided.
|
33
|
+
|
34
|
+
Once your crypt keys are setup, you then enter all your sensitive data
|
35
|
+
as "stored keys". Stored keys are encrypted using your specified
|
36
|
+
crypt_keys before they are uploaded to our servers.
|
37
|
+
|
38
|
+
For security purposes, anytime the website or this Gem require a
|
39
|
+
crypt key, it must be provided by you (the user of the website or Gem),
|
40
|
+
and the value provided is checked against a stored signed digest
|
41
|
+
for valdity before it is used to perform the requested encryption/decryption.
|
42
|
+
The requested encryption/decryption occurs entirely within the client's
|
43
|
+
computer (user's browser for the website, application server for users
|
44
|
+
of the Gem), and is never communicated with Nimbus Secure directly.
|
45
|
+
|
46
|
+
# Using the Secured Data
|
47
|
+
Once you have your data uploaded to your service, you can then
|
48
|
+
install this Gem into your application, and use it's programmatic
|
49
|
+
interface (or command line) to download and decrypt the stored
|
50
|
+
credential so you may use it within your application.
|
51
|
+
|
52
|
+
# Needed Credentials
|
53
|
+
In order to use this Gem, you need two pieces of secure information.
|
54
|
+
The first is an API key that provides access to the API and allows
|
55
|
+
you to access your online account. You can create an API key by
|
56
|
+
logging into the service.
|
57
|
+
|
58
|
+
The second is the crypt key that you created above that is used
|
59
|
+
to encrypt/decrypt your stored data. If you used more than one key,
|
60
|
+
then you will need all the encrypted keys.
|
61
|
+
|
62
|
+
Typically, you store these two pieces of information outside of your
|
63
|
+
application source repository itself, and only provide them to your
|
64
|
+
application during application startup (typically via ENVIRONMENT
|
65
|
+
variables or other boot parameters). That way, you do not have
|
66
|
+
to share the credentials or persist them source repository.
|
67
|
+
|
68
|
+
Given these two pieces of information, this Gem, and the properly
|
69
|
+
setup service, you can dynamically grab all your sensitive credentials
|
70
|
+
and data needed to run your application. This typically happens during
|
71
|
+
your application boot up process.
|
72
|
+
|
73
|
+
# Setting up your .nibmussecure.yml file:
|
74
|
+
The easiest way to setup Nimbus Secure is to setup a configuration file in your home directory.
|
75
|
+
This file will contain sensitive information, so it should be marked as readable to you only
|
76
|
+
(permission mode 400). The following is a sample configuration file:
|
77
|
+
|
78
|
+
account: <my_account_id>
|
79
|
+
apikey: <my_accounts_apikey>
|
80
|
+
crypt_keys:
|
81
|
+
key1: <my_secret_value_for_key1>
|
82
|
+
key2: <my_secret_value_for_key2>
|
83
|
+
|
84
|
+
The value "<my_account_id>" is the same value that appears in the base part of your URL you use to
|
85
|
+
access Nmbus Secure. So, for example, if the URL you use to access Nimbus Secure is this:
|
86
|
+
|
87
|
+
https://www.nimbussecure.com/myaccount
|
88
|
+
|
89
|
+
Then your account id is "myaccount". Your "apikey" can be retrieved from the "Api Keys" tab in
|
90
|
+
Nimbus Secure.
|
91
|
+
|
92
|
+
For each encryption key you have in your account and you wish to use, you must have a line in the
|
93
|
+
"crypt_keys:"" section of the config file. In the above example, "key1" is the name assigned to the
|
94
|
+
first encryption key, and "<my_secret_value_for_key1>" is the secret value you assigned when
|
95
|
+
you created this encryption key.
|
96
|
+
|
97
|
+
# Using in Ruby
|
98
|
+
Assuming you have a stored key with a name "testmessage" setup, with an approprate encryption key.
|
99
|
+
Also assuming your ~/.nimbussecure.yml file is setup with your account identifier, API Key,
|
100
|
+
and the encryption key value. Then the following can be used to retrieve and decrypt a stored key:
|
101
|
+
|
102
|
+
require 'nimbussecure'
|
103
|
+
stored_value=nimbussecure.lookup_value "testmessage"
|
104
|
+
puts "The decrypted stored value is: #{stored_value}"
|
data/Rakefile
ADDED
data/bin/nimbussecure
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'yaml'
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
require 'nimbussecure'
|
6
|
+
|
7
|
+
def keystore
|
8
|
+
$keystore||=NimbusSecure.new config_file: $filename
|
9
|
+
end
|
10
|
+
|
11
|
+
def usage
|
12
|
+
puts "
|
13
|
+
Usage:
|
14
|
+
nimbussecure [-f <config_file>] account
|
15
|
+
nimbussecure [-f <config_file>] lookup <name>
|
16
|
+
<value> is sent to stdout
|
17
|
+
Where:
|
18
|
+
-f <config_file> Specifies a config file (rather than \"~/.nimbussecure.yml\")
|
19
|
+
<value> is the specific value being encrypted and stored.
|
20
|
+
|
21
|
+
Config File
|
22
|
+
The config file should look like the following:
|
23
|
+
================
|
24
|
+
account: myacct
|
25
|
+
apikey: myapikey
|
26
|
+
crypt_keys:
|
27
|
+
key1: value1
|
28
|
+
key2: value2
|
29
|
+
================
|
30
|
+
|
31
|
+
NOTE:
|
32
|
+
account:
|
33
|
+
The account value (\"myacct\" in the example above) can be found based on the
|
34
|
+
URL you use to access Nimbus Secure.
|
35
|
+
If your URL is:
|
36
|
+
https://www.nimbussecure.com/my_acct/
|
37
|
+
Then the \"account\" value in your config file should be \"my_acct\"
|
38
|
+
apikey:
|
39
|
+
You can find your API Key by clicking on \"API Keys\" when you are logged into
|
40
|
+
the Nimbus Secure website.
|
41
|
+
crypt_keys:
|
42
|
+
This is a set of key/value pairs. The key is the name as defined in your
|
43
|
+
Nimbus Secure \"Encryption Keys\" section, and the value is the secret value
|
44
|
+
you used when you created your encryption key.
|
45
|
+
"
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
def show_error
|
49
|
+
puts "Error: #{keystore.last_error_message}"
|
50
|
+
keystore.last_error_details.each do |subject,error_list|
|
51
|
+
error_list.each do |error|
|
52
|
+
puts " #{subject} #{error}"
|
53
|
+
end
|
54
|
+
end if keystore.last_error_details
|
55
|
+
end
|
56
|
+
|
57
|
+
def main
|
58
|
+
usage if ARGV.size<1
|
59
|
+
idx=0
|
60
|
+
$filename="~/.nimbussecure.yml"
|
61
|
+
if ARGV[idx]=='-f'
|
62
|
+
usage if ARGV.size<=2
|
63
|
+
$filename=ARGV[idx+1]
|
64
|
+
idx+=2
|
65
|
+
end
|
66
|
+
case ARGV[idx]
|
67
|
+
when "account" then
|
68
|
+
usage if ARGV.size!=idx+1
|
69
|
+
account
|
70
|
+
when "lookup" then
|
71
|
+
usage if ARGV.size!=idx+2
|
72
|
+
lookup ARGV[idx+1]
|
73
|
+
else
|
74
|
+
usage
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def account
|
79
|
+
begin
|
80
|
+
account=keystore.account
|
81
|
+
puts " Name: #{account.name}"
|
82
|
+
puts " # Crypt Keys: #{account.num_crypt_keys}"
|
83
|
+
puts " # Stored Keys: #{account.num_stored_keys}"
|
84
|
+
rescue => error
|
85
|
+
puts "Error: #{error}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def lookup name
|
90
|
+
begin
|
91
|
+
res=keystore.lookup name
|
92
|
+
if res.nil?
|
93
|
+
show_error
|
94
|
+
return
|
95
|
+
end
|
96
|
+
puts res.decrypted_value
|
97
|
+
rescue => error
|
98
|
+
puts "Error: #{error}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
main
|
data/lib/nimbussecure.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require "nimbussecure/version"
|
2
|
+
require "nimbussecure/errors"
|
3
|
+
require "nimbussecure/attr_accessor"
|
4
|
+
require "nimbussecure/config"
|
5
|
+
require "nimbussecure/base"
|
6
|
+
require "nimbussecure/connect"
|
7
|
+
require "nimbussecure/results"
|
8
|
+
require "nimbussecure/accounts"
|
9
|
+
require "nimbussecure/crypt_key"
|
10
|
+
require "nimbussecure/stored_key"
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
#
|
15
|
+
# Simplified Usage
|
16
|
+
# (assumes ~/.nimbussecure.yml is setup)
|
17
|
+
# ======================================
|
18
|
+
#
|
19
|
+
# Get account details:
|
20
|
+
# nimbussecure.account
|
21
|
+
#
|
22
|
+
# Lookup a stored value and return the decrypted version (assumes crypt key is in ~/.nimbussecure.yml):
|
23
|
+
# nimbussecure.lookup_value :storedvalue_identifier
|
24
|
+
#
|
25
|
+
# Full Usage
|
26
|
+
# ==========
|
27
|
+
#
|
28
|
+
# Setup access:
|
29
|
+
# * Assumes ~/.nimbussecure.yml is setup:
|
30
|
+
# ns=NimbusSecure.new
|
31
|
+
# * Assumes otherfile.yml is setup:
|
32
|
+
# ns=NimbusSecure.new config_file: "otherfile.yml"
|
33
|
+
# * Manual Configuration:
|
34
|
+
# ns=NimbusSecure account: "ident", apikey: "apikey", crypt_keys: {key1: "value1",key2: "value2"}
|
35
|
+
#
|
36
|
+
# Get account details
|
37
|
+
# account=ns.account
|
38
|
+
# account.name
|
39
|
+
# account.num_crypt_keys
|
40
|
+
# account.num_stored_keys
|
41
|
+
#
|
42
|
+
# Get details on all configured encryption keys:
|
43
|
+
# crypt_keys=ns.crypt_keys
|
44
|
+
#
|
45
|
+
# Get all stored values:
|
46
|
+
# stored_keys=ns.stored_keys
|
47
|
+
#
|
48
|
+
# Lookup a single stored value:
|
49
|
+
# stored_key=ns.lookup ident
|
50
|
+
#
|
51
|
+
# With the stored_key object:
|
52
|
+
# stored_key.ident
|
53
|
+
# stored_key.decrypted_value # Assuming secret value for corresponding crypt_key is available locally
|
54
|
+
# stored_key.encrypted_value
|
55
|
+
# stored_key.key_type
|
56
|
+
#
|
57
|
+
# Ruby on Rails Usage
|
58
|
+
# ===================
|
59
|
+
#
|
60
|
+
# Example usage in Rails to load the secret_token (config/initializers/secret_token.rb):
|
61
|
+
# require 'nimbussecure'
|
62
|
+
# secret_token=nimbussecure.lookup "secret_token"
|
63
|
+
# raise "Secret token missing" unless secret_token
|
64
|
+
# NimbusData::Application.config.secret_token = secret_token.decrypted_value
|
65
|
+
# Or, alternately:
|
66
|
+
# require 'nimbussecure'
|
67
|
+
# secret_token=nimbussecure.lookup_value "secret_token"
|
68
|
+
# raise "Secret token missing" unless secret_token
|
69
|
+
# NimbusData::Application.config.secret_token = secret_token
|
70
|
+
#
|
71
|
+
# Assumes config file in ~/.nimbussecure
|
72
|
+
#
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class NimbusSecure
|
2
|
+
class Account<NimbusSecure::Base
|
3
|
+
nimbus_attr_accessor :name,:num_crypt_keys,:num_stored_keys
|
4
|
+
def initialize name,num_crypt_keys,num_stored_keys
|
5
|
+
@name=name
|
6
|
+
@num_crypt_keys=num_crypt_keys
|
7
|
+
@num_stored_keys=num_stored_keys
|
8
|
+
end
|
9
|
+
end
|
10
|
+
def account
|
11
|
+
return @account if @account
|
12
|
+
res=request_get "/account"
|
13
|
+
raise ServerError,"Invalid Account" unless res and res["account"]
|
14
|
+
@account=Account.new res["account"]["name"],res["account"]["num_crypt_keys"],res["account"]["num_stored_keys"]
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module NimbusSecureAttrAccessor
|
2
|
+
def nimbus_attr_accessor *list
|
3
|
+
list.each do |attr|
|
4
|
+
define_method(attr) do
|
5
|
+
instance_variable_get("@#{attr}")
|
6
|
+
end
|
7
|
+
|
8
|
+
define_method("#{attr}=") do |val|
|
9
|
+
instance_variable_set("@#{attr}",val)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
class NimbusSecure
|
15
|
+
private
|
16
|
+
class Base
|
17
|
+
class<<self
|
18
|
+
include NimbusSecureAttrAccessor
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class NimbusSecure
|
2
|
+
#
|
3
|
+
# Possible ways to initialize:
|
4
|
+
#
|
5
|
+
# 1) Explicit:
|
6
|
+
# ns=NimbusSecure.new account: "ident",apikey: "xyzzy", crypt_keys:{"key1":"value1","key2":"value2"}
|
7
|
+
# 2) File:
|
8
|
+
# ns=NimbusSecure.new config_file: "./nsconfig.yml"
|
9
|
+
# nsconfig.yml:
|
10
|
+
# -------------
|
11
|
+
# account: ident
|
12
|
+
# apikey: xxx
|
13
|
+
# crypt_keys:
|
14
|
+
# key1: value1
|
15
|
+
# key2: value2
|
16
|
+
# 3) YAML string (not file):
|
17
|
+
# ns=NimbusSecure.new config: "account: ident\napikey: xxx\ncrypt_keys:\n key1: value1\n key2:value2\n"
|
18
|
+
# 4) Default:
|
19
|
+
# ns=NimbusSecure.new
|
20
|
+
# ...reads configuration from ~/nimbussecure.yml
|
21
|
+
#
|
22
|
+
def initialize opts={}
|
23
|
+
raise InvalidConfig unless opts.respond_to?(:size) and opts.respond_to?(:[])
|
24
|
+
opts[:config_file]=File.expand_path("~/.nimbussecure.yml") if opts.size==0
|
25
|
+
if opts[:config] || opts[:config_file]
|
26
|
+
raw_config_str=opts[:config]
|
27
|
+
raw_config_str = File.read(File.expand_path(opts[:config_file])) if opts[:config_file]
|
28
|
+
raise InvalidConfigFile unless raw_config_str
|
29
|
+
opts=YAML.load(raw_config_str)
|
30
|
+
raise InvalidConfigFile unless opts
|
31
|
+
end
|
32
|
+
opts=Hash[opts.map{ |k, v| [k.to_sym, v] }]
|
33
|
+
config.account="xxx"
|
34
|
+
config.endpoint=opts[:endpoint].to_s if opts[:endpoint]
|
35
|
+
config.account=opts[:account].to_s
|
36
|
+
config.apikey=opts[:apikey].to_s
|
37
|
+
config.crypt_keys=Hash[opts[:crypt_keys].map{ |k, v| [k.to_sym, v.to_s] }] if opts[:crypt_keys]
|
38
|
+
raise InvalidConfig,"Config is missing or incomplete" unless config.valid?
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
def nimbussecure
|
43
|
+
@nimbussecure||=NimbusSecure.new
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
class NimbusSecure
|
3
|
+
class Config
|
4
|
+
attr_accessor :endpoint,:account,:apikey,:crypt_keys
|
5
|
+
def initialize
|
6
|
+
@crypt_keys={}
|
7
|
+
@endpoint="https://www.nimbussecure.com"
|
8
|
+
end
|
9
|
+
def invalid?
|
10
|
+
endpoint.nil? || account.nil? || apikey.nil? || crypt_keys.size==0
|
11
|
+
end
|
12
|
+
def valid?
|
13
|
+
!invalid?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def config
|
17
|
+
@config||=Config.new
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'faraday'
|
3
|
+
class NimbusSecure
|
4
|
+
private
|
5
|
+
def request_get path,data={}
|
6
|
+
response=request_connection.get do |req|
|
7
|
+
req.url "/#{config.account}/api/v1#{path}"
|
8
|
+
req.params data unless data.nil? or data.size==0
|
9
|
+
end
|
10
|
+
process_response response
|
11
|
+
end
|
12
|
+
def request_post path,data={}
|
13
|
+
response=request_connection.post do |req|
|
14
|
+
req.url "/#{config.account}/api/v1#{path}"
|
15
|
+
req.body=data
|
16
|
+
end
|
17
|
+
process_response response
|
18
|
+
end
|
19
|
+
def request_connection
|
20
|
+
raise MissingOrInvalidConfiguation if config.endpoint.nil? or config.apikey.nil?
|
21
|
+
@request_connection||=Faraday.new(url:config.endpoint) do |builder|
|
22
|
+
builder.request :url_encoded
|
23
|
+
# builder.response :logger
|
24
|
+
builder.use AuthenticationMiddleware,config.apikey
|
25
|
+
builder.adapter :net_http
|
26
|
+
end
|
27
|
+
end
|
28
|
+
def process_response response
|
29
|
+
raise ServerError,response if(response.status!=200)
|
30
|
+
@last_result=JSON.parse(response.body)
|
31
|
+
@last_status=@last_result["status"]
|
32
|
+
@last_error_message=nil
|
33
|
+
@last_error_details=nil
|
34
|
+
@last_error_message=@last_result["errormsg"] if @last_status!="success"
|
35
|
+
@last_error_details=@last_result["errordetails"] if @last_status!="success"
|
36
|
+
@last_result.delete "status"
|
37
|
+
@last_result.delete "errormsg"
|
38
|
+
@last_result.delete "errordetails"
|
39
|
+
return nil if @last_status!="success"
|
40
|
+
@last_result
|
41
|
+
end
|
42
|
+
class AuthenticationMiddleware < Faraday::Middleware
|
43
|
+
def initialize(app,apikey)
|
44
|
+
super(app)
|
45
|
+
@apikey=apikey
|
46
|
+
end
|
47
|
+
def call(env)
|
48
|
+
set_header env,'X-Nimbus-Component-Key',@apikey
|
49
|
+
set_header env,'X-Nimbus-Client-Version',NimbusSecure::VERSION
|
50
|
+
set_header env,'X-Nimbus-Client',"muskratsoftware/NimbusSecureClient"
|
51
|
+
set_header env,'X-Nimbus-Language',"ruby"
|
52
|
+
@app.call(env)
|
53
|
+
end
|
54
|
+
def set_header(env,header,value)
|
55
|
+
unless env[:request_headers][header]
|
56
|
+
env[:request_headers][header] = value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'gibberish'
|
2
|
+
class NimbusSecure
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# Crypt Key
|
6
|
+
#
|
7
|
+
#
|
8
|
+
class CryptKey<NimbusSecure::Base
|
9
|
+
nimbus_attr_accessor :id,:valid,:ident,:salt,:digest,:key_value
|
10
|
+
def initialize nss,ck
|
11
|
+
@valid=true
|
12
|
+
@id=ck["id"]
|
13
|
+
@ident=ck["ident"].to_sym
|
14
|
+
@salt=ck["salt"]
|
15
|
+
@digest=ck["digest"]
|
16
|
+
if nss.config.crypt_keys[@ident.to_sym]
|
17
|
+
@key_value=nss.config.crypt_keys[@ident.to_sym]
|
18
|
+
sha256=Digest::SHA256.new
|
19
|
+
sha256 << @salt+@key_value
|
20
|
+
digest=sha256.to_s
|
21
|
+
if digest!=@digest
|
22
|
+
@valid=false
|
23
|
+
@salt=nil
|
24
|
+
@digest=nil
|
25
|
+
@key_value=nil
|
26
|
+
@invalid_message="Local encryption key does not match stored digest on server"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
def valid?
|
31
|
+
@valid
|
32
|
+
end
|
33
|
+
def has_key_value?
|
34
|
+
return false unless valid?
|
35
|
+
!@key_value.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
def encrypt data
|
39
|
+
cipher.enc(data)
|
40
|
+
end
|
41
|
+
def decrypt data
|
42
|
+
cipher.dec(data)
|
43
|
+
end
|
44
|
+
private ################################################################################
|
45
|
+
def cipher
|
46
|
+
raise InvalidEncryptionKey,@invalid_message if @invalid_message
|
47
|
+
raise InvalidEncryptionKey,"Encryption Key does not have value configured locally" unless self.has_key_value?
|
48
|
+
raise InvalidEncryptionKey,"Invalid encryption key" unless self.valid?
|
49
|
+
Gibberish::AES.new(@key_value)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
#
|
55
|
+
# Access Crypt Keys
|
56
|
+
#
|
57
|
+
#
|
58
|
+
def crypt_keys
|
59
|
+
res=request_get "/crypt_keys"
|
60
|
+
@cached_crypt_keys=res["crypt_keys"].map{|key|NimbusSecure::CryptKey.new self,key}
|
61
|
+
end
|
62
|
+
def crypt_keys_from_cache
|
63
|
+
return @cached_crypt_keys if @cached_crypt_keys
|
64
|
+
crypt_keys
|
65
|
+
end
|
66
|
+
def clear_crypt_key_cache
|
67
|
+
@cached_crypt_keys=nil
|
68
|
+
end
|
69
|
+
def crypt_key ident
|
70
|
+
crypt_keys_from_cache.each do |ck|
|
71
|
+
return ck if ck.ident==ident.to_sym
|
72
|
+
end
|
73
|
+
return nil
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class NimbusSecure
|
2
|
+
def last_result
|
3
|
+
@last_result
|
4
|
+
end
|
5
|
+
def last_status
|
6
|
+
@last_status
|
7
|
+
end
|
8
|
+
def success?
|
9
|
+
last_status=="success"
|
10
|
+
end
|
11
|
+
def failed?
|
12
|
+
last_status!="success"
|
13
|
+
end
|
14
|
+
def last_error_message
|
15
|
+
@last_error_message
|
16
|
+
end
|
17
|
+
def last_error_details
|
18
|
+
@last_error_details
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'gibberish'
|
2
|
+
class NimbusSecure
|
3
|
+
#
|
4
|
+
#
|
5
|
+
# Stored Key
|
6
|
+
#
|
7
|
+
#
|
8
|
+
#
|
9
|
+
class StoredKey<NimbusSecure::Base
|
10
|
+
nimbus_attr_accessor :id,:ident,:encrypted_value,:decrypted_value,:crypt_key,:key_type
|
11
|
+
def initialize nss,skparams
|
12
|
+
@id=skparams["id"]
|
13
|
+
@ident=skparams["ident"]
|
14
|
+
@encrypted_value=skparams["encrypted_value"]
|
15
|
+
@decrypted_value=nil
|
16
|
+
@crypt_key=NimbusSecure::CryptKey.new(nss,skparams["crypt_key"])
|
17
|
+
@key_type=skparams["key_type"]
|
18
|
+
end
|
19
|
+
def apply_crypt_key ck
|
20
|
+
self.decrypted_value=ck.decrypt self.encrypted_value
|
21
|
+
end
|
22
|
+
def value
|
23
|
+
apply_crypt_key self.crypt_key unless decrypted_value
|
24
|
+
decrypted_value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def lookup ident #,crypt_key
|
29
|
+
res=request_get "/stored_keys/#{ident}/locate"
|
30
|
+
return nil unless res
|
31
|
+
return nil unless res["stored_key"]
|
32
|
+
stored_key=NimbusSecure::StoredKey.new self,res["stored_key"]
|
33
|
+
ck=stored_key.crypt_key
|
34
|
+
return nil unless stored_key.encrypted_value
|
35
|
+
stored_key.apply_crypt_key ck
|
36
|
+
stored_key
|
37
|
+
end
|
38
|
+
def lookup_value ident
|
39
|
+
sk=lookup ident
|
40
|
+
return nil if sk.nil?
|
41
|
+
sk.value
|
42
|
+
end
|
43
|
+
def stored_keys
|
44
|
+
res=request_get "/stored_keys"
|
45
|
+
res["stored_keys"].map{|key|NimbusSecure::StoredKey.new self,key}
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "nimbussecure/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "nimbussecure"
|
7
|
+
s.version = NimbusSecure::VERSION
|
8
|
+
s.authors = ["Lee Atchison"]
|
9
|
+
s.email = ["lee@nimbussecure.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Client library for NimbusSecure}
|
12
|
+
s.description = %q{Client library for NimbusSecure}
|
13
|
+
|
14
|
+
s.rubyforge_project = "nimbussecure"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "minitest"
|
22
|
+
s.add_development_dependency "vcr"
|
23
|
+
s.add_development_dependency "fakeweb"
|
24
|
+
s.add_runtime_dependency "faraday"
|
25
|
+
# s.add_runtime_dependency "rest-client"
|
26
|
+
s.add_runtime_dependency "gibberish"
|
27
|
+
end
|
data/pry_load.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
|
3
|
+
describe NimbusSecure::Account do
|
4
|
+
before do
|
5
|
+
@ns=NimbusSecure.new({endpoint: "http://localhost:3000",
|
6
|
+
account: "vcrtest",
|
7
|
+
apikey: "34807a2d4d-a9990c4748218eb6ed-70886bc0fd",
|
8
|
+
crypt_keys:{"primary"=>"xyzzyxyzzy"}})
|
9
|
+
end
|
10
|
+
it "should get a list of all accounts (when there is just one)" do
|
11
|
+
VCR.use_cassette "accounts/test" do
|
12
|
+
acct=@ns.account
|
13
|
+
acct.name.must_equal "VCR Account"
|
14
|
+
acct.num_crypt_keys.must_equal 23
|
15
|
+
acct.num_stored_keys.must_equal 34
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
describe "Key Lookup" do
|
3
|
+
before do
|
4
|
+
@ns=NimbusSecure.new({endpoint: "http://localhost:3000",
|
5
|
+
account: "vcrtest",
|
6
|
+
apikey: "34807a2d4d-a9990c4748218eb6ed-70886bc0fd",
|
7
|
+
crypt_keys:{"primary"=>"xyzzyxyzzy","secondary"=>"yzzyxyzzyx"}})
|
8
|
+
end
|
9
|
+
it "should be able to lookup a key and decrypt it" do
|
10
|
+
VCR.use_cassette "lookup/key1" do
|
11
|
+
@ns.lookup_value(:test1).must_equal "This is a test stored key"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
it "should be able to lookup a second key and decrypt it" do
|
15
|
+
VCR.use_cassette "lookup/key2" do
|
16
|
+
code=@ns.lookup_value(:test1).must_equal "This is a test stored key"
|
17
|
+
code=@ns.lookup_value(:test2).must_equal "This is another test stored key"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
it "should be able to fail gracefully if key is not found" do
|
21
|
+
VCR.use_cassette "lookup/key3" do
|
22
|
+
code=@ns.lookup_value :invalidkey
|
23
|
+
code.must_be_nil
|
24
|
+
@ns.success?.must_equal false
|
25
|
+
@ns.last_error_message.must_equal "Could not locate Stored Key invalidkey"
|
26
|
+
@ns.last_error_details.must_be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO: We don't get an error when we lookup a key that doesn't exist...and other error cases...
|
@@ -0,0 +1,52 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://localhost:3000/vcrtest/api/v1/account
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
x-nimbus-component-key:
|
11
|
+
- 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
|
12
|
+
x-nimbus-client-version:
|
13
|
+
- 0.4.0
|
14
|
+
x-nimbus-client:
|
15
|
+
- muskratsoftware/NimbusSecureClient
|
16
|
+
x-nimbus-language:
|
17
|
+
- ruby
|
18
|
+
accept-encoding:
|
19
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
20
|
+
accept:
|
21
|
+
- ! '*/*'
|
22
|
+
user-agent:
|
23
|
+
- Ruby
|
24
|
+
response:
|
25
|
+
status:
|
26
|
+
code: 200
|
27
|
+
message: OK
|
28
|
+
headers:
|
29
|
+
content-type:
|
30
|
+
- application/json; charset=utf-8
|
31
|
+
x-ua-compatible:
|
32
|
+
- IE=Edge
|
33
|
+
etag:
|
34
|
+
- ! '"e3a4296c05b32d0ff0c13b3792a87ec5"'
|
35
|
+
cache-control:
|
36
|
+
- max-age=0, private, must-revalidate
|
37
|
+
x-request-id:
|
38
|
+
- 31dee43871629934ff8e333f5151a2a3
|
39
|
+
x-runtime:
|
40
|
+
- '0.024024'
|
41
|
+
content-length:
|
42
|
+
- '92'
|
43
|
+
connection:
|
44
|
+
- close
|
45
|
+
server:
|
46
|
+
- thin 1.4.1 codename Chromeo
|
47
|
+
body:
|
48
|
+
encoding: US-ASCII
|
49
|
+
string: ! '{"status":"success","account":{"name":"VCR Account","num_crypt_keys":23,"num_stored_keys":34}}'
|
50
|
+
http_version: '1.1'
|
51
|
+
recorded_at: Thu, 02 Aug 2012 03:54:45 GMT
|
52
|
+
recorded_with: VCR 2.2.4
|
@@ -0,0 +1,52 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://localhost:3000/vcrtest/api/v1/stored_keys/test1/locate
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
x-nimbus-component-key:
|
11
|
+
- 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
|
12
|
+
x-nimbus-client-version:
|
13
|
+
- 0.4.0
|
14
|
+
x-nimbus-client:
|
15
|
+
- muskratsoftware/NimbusSecureClient
|
16
|
+
x-nimbus-language:
|
17
|
+
- ruby
|
18
|
+
accept-encoding:
|
19
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
20
|
+
accept:
|
21
|
+
- ! '*/*'
|
22
|
+
user-agent:
|
23
|
+
- Ruby
|
24
|
+
response:
|
25
|
+
status:
|
26
|
+
code: 200
|
27
|
+
message: OK
|
28
|
+
headers:
|
29
|
+
content-type:
|
30
|
+
- application/json; charset=utf-8
|
31
|
+
x-ua-compatible:
|
32
|
+
- IE=Edge
|
33
|
+
etag:
|
34
|
+
- ! '"af24594f0840cb2713181cae549d7d53"'
|
35
|
+
cache-control:
|
36
|
+
- max-age=0, private, must-revalidate
|
37
|
+
x-request-id:
|
38
|
+
- 5588bd8d8d6058def7ed0ac007ea17b2
|
39
|
+
x-runtime:
|
40
|
+
- '0.029527'
|
41
|
+
content-length:
|
42
|
+
- '324'
|
43
|
+
connection:
|
44
|
+
- close
|
45
|
+
server:
|
46
|
+
- thin 1.4.1 codename Chromeo
|
47
|
+
body:
|
48
|
+
encoding: US-ASCII
|
49
|
+
string: ! '{"status":"success","stored_key":{"id":3,"ident":"test1","encrypted_value":"U2FsdGVkX1/GKKaIUe5+lSzPJ0shgBrFDx0oGQO0LBNvOPmo69NiN7SiuLMBQTCV\r\n","key_type":"symmetric","crypt_key":{"id":9,"ident":"primary","salt":"$2a$10$zT38XT42BXYjcfd5uFO2E.","digest":"d6992c3ad871a429b4485967456b87fbc916a126b60c788516e11dd4cb3e1410"}}}'
|
50
|
+
http_version: '1.1'
|
51
|
+
recorded_at: Thu, 02 Aug 2012 03:59:40 GMT
|
52
|
+
recorded_with: VCR 2.2.4
|
@@ -0,0 +1,101 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://localhost:3000/vcrtest/api/v1/stored_keys/test1/locate
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
x-nimbus-component-key:
|
11
|
+
- 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
|
12
|
+
x-nimbus-client-version:
|
13
|
+
- 0.4.0
|
14
|
+
x-nimbus-client:
|
15
|
+
- muskratsoftware/NimbusSecureClient
|
16
|
+
x-nimbus-language:
|
17
|
+
- ruby
|
18
|
+
accept-encoding:
|
19
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
20
|
+
accept:
|
21
|
+
- ! '*/*'
|
22
|
+
user-agent:
|
23
|
+
- Ruby
|
24
|
+
response:
|
25
|
+
status:
|
26
|
+
code: 200
|
27
|
+
message: OK
|
28
|
+
headers:
|
29
|
+
content-type:
|
30
|
+
- application/json; charset=utf-8
|
31
|
+
x-ua-compatible:
|
32
|
+
- IE=Edge
|
33
|
+
etag:
|
34
|
+
- ! '"af24594f0840cb2713181cae549d7d53"'
|
35
|
+
cache-control:
|
36
|
+
- max-age=0, private, must-revalidate
|
37
|
+
x-request-id:
|
38
|
+
- 2a95b9c8862fb4b248da9467446f8c9c
|
39
|
+
x-runtime:
|
40
|
+
- '0.033637'
|
41
|
+
content-length:
|
42
|
+
- '324'
|
43
|
+
connection:
|
44
|
+
- close
|
45
|
+
server:
|
46
|
+
- thin 1.4.1 codename Chromeo
|
47
|
+
body:
|
48
|
+
encoding: US-ASCII
|
49
|
+
string: ! '{"status":"success","stored_key":{"id":3,"ident":"test1","encrypted_value":"U2FsdGVkX1/GKKaIUe5+lSzPJ0shgBrFDx0oGQO0LBNvOPmo69NiN7SiuLMBQTCV\r\n","key_type":"symmetric","crypt_key":{"id":9,"ident":"primary","salt":"$2a$10$zT38XT42BXYjcfd5uFO2E.","digest":"d6992c3ad871a429b4485967456b87fbc916a126b60c788516e11dd4cb3e1410"}}}'
|
50
|
+
http_version: '1.1'
|
51
|
+
recorded_at: Thu, 02 Aug 2012 03:59:40 GMT
|
52
|
+
- request:
|
53
|
+
method: get
|
54
|
+
uri: http://localhost:3000/vcrtest/api/v1/stored_keys/test2/locate
|
55
|
+
body:
|
56
|
+
encoding: US-ASCII
|
57
|
+
string: ''
|
58
|
+
headers:
|
59
|
+
x-nimbus-component-key:
|
60
|
+
- 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
|
61
|
+
x-nimbus-client-version:
|
62
|
+
- 0.4.0
|
63
|
+
x-nimbus-client:
|
64
|
+
- muskratsoftware/NimbusSecureClient
|
65
|
+
x-nimbus-language:
|
66
|
+
- ruby
|
67
|
+
accept-encoding:
|
68
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
69
|
+
accept:
|
70
|
+
- ! '*/*'
|
71
|
+
user-agent:
|
72
|
+
- Ruby
|
73
|
+
response:
|
74
|
+
status:
|
75
|
+
code: 200
|
76
|
+
message: OK
|
77
|
+
headers:
|
78
|
+
content-type:
|
79
|
+
- application/json; charset=utf-8
|
80
|
+
x-ua-compatible:
|
81
|
+
- IE=Edge
|
82
|
+
etag:
|
83
|
+
- ! '"63fba6143471cebd1321622de55ef88e"'
|
84
|
+
cache-control:
|
85
|
+
- max-age=0, private, must-revalidate
|
86
|
+
x-request-id:
|
87
|
+
- 570fcdfafe42ade8d7f96cc9fe8fcb8e
|
88
|
+
x-runtime:
|
89
|
+
- '0.106230'
|
90
|
+
content-length:
|
91
|
+
- '327'
|
92
|
+
connection:
|
93
|
+
- close
|
94
|
+
server:
|
95
|
+
- thin 1.4.1 codename Chromeo
|
96
|
+
body:
|
97
|
+
encoding: US-ASCII
|
98
|
+
string: ! '{"status":"success","stored_key":{"id":4,"ident":"test2","encrypted_value":"U2FsdGVkX18WTqz1XtiUi7s1riXV6w49980V3E4ysvhyNgVxTY8eocj8jgsGn4PG\r\n","key_type":"symmetric","crypt_key":{"id":10,"ident":"secondary","salt":"$2a$10$bcYes9rn8wAX0W/eIVSUBu","digest":"09890ee6ed6bb70d8a8671ab8bd6102da2d6e4f2e8311ccb5ca83195276e4581"}}}'
|
99
|
+
http_version: '1.1'
|
100
|
+
recorded_at: Thu, 02 Aug 2012 03:59:40 GMT
|
101
|
+
recorded_with: VCR 2.2.4
|
@@ -0,0 +1,52 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://localhost:3000/vcrtest/api/v1/stored_keys/invalidkey/locate
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
x-nimbus-component-key:
|
11
|
+
- 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
|
12
|
+
x-nimbus-client-version:
|
13
|
+
- 0.4.0
|
14
|
+
x-nimbus-client:
|
15
|
+
- muskratsoftware/NimbusSecureClient
|
16
|
+
x-nimbus-language:
|
17
|
+
- ruby
|
18
|
+
accept-encoding:
|
19
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
20
|
+
accept:
|
21
|
+
- ! '*/*'
|
22
|
+
user-agent:
|
23
|
+
- Ruby
|
24
|
+
response:
|
25
|
+
status:
|
26
|
+
code: 200
|
27
|
+
message: OK
|
28
|
+
headers:
|
29
|
+
content-type:
|
30
|
+
- application/json; charset=utf-8
|
31
|
+
x-ua-compatible:
|
32
|
+
- IE=Edge
|
33
|
+
etag:
|
34
|
+
- ! '"fe603117385eb96a83f0de7440c7ad4e"'
|
35
|
+
cache-control:
|
36
|
+
- max-age=0, private, must-revalidate
|
37
|
+
x-request-id:
|
38
|
+
- 3dd7d8ef85311f6e9d0d8e2a6e064421
|
39
|
+
x-runtime:
|
40
|
+
- '0.021249'
|
41
|
+
content-length:
|
42
|
+
- '90'
|
43
|
+
connection:
|
44
|
+
- close
|
45
|
+
server:
|
46
|
+
- thin 1.4.1 codename Chromeo
|
47
|
+
body:
|
48
|
+
encoding: US-ASCII
|
49
|
+
string: ! '{"status":"error","errormsg":"Could not locate Stored Key invalidkey","errordetails":null}'
|
50
|
+
http_version: '1.1'
|
51
|
+
recorded_at: Thu, 02 Aug 2012 03:59:40 GMT
|
52
|
+
recorded_with: VCR 2.2.4
|
@@ -0,0 +1,10 @@
|
|
1
|
+
$LOAD_PATH << File.dirname(File.expand_path(__FILE__).to_s).to_s+"/../lib/"
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'vcr'
|
4
|
+
require 'nimbussecure'
|
5
|
+
|
6
|
+
VCR.configure do |c|
|
7
|
+
c.cassette_library_dir = 'test/fixtures/vcr_cassettes'
|
8
|
+
c.hook_into :fakeweb
|
9
|
+
# c.stub_with :fakeweb
|
10
|
+
end
|
data/test/run_tests.rb
ADDED
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nimbussecure
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Lee Atchison
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: minitest
|
16
|
+
requirement: &70236373001520 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70236373001520
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: vcr
|
27
|
+
requirement: &70236373001100 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70236373001100
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: fakeweb
|
38
|
+
requirement: &70236373000680 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70236373000680
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: faraday
|
49
|
+
requirement: &70236373000240 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70236373000240
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: gibberish
|
60
|
+
requirement: &70236372999780 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70236372999780
|
69
|
+
description: Client library for NimbusSecure
|
70
|
+
email:
|
71
|
+
- lee@nimbussecure.com
|
72
|
+
executables:
|
73
|
+
- nimbussecure
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- bin/nimbussecure
|
82
|
+
- lib/nimbussecure.rb
|
83
|
+
- lib/nimbussecure/accounts.rb
|
84
|
+
- lib/nimbussecure/attr_accessor.rb
|
85
|
+
- lib/nimbussecure/base.rb
|
86
|
+
- lib/nimbussecure/config.rb
|
87
|
+
- lib/nimbussecure/connect.rb
|
88
|
+
- lib/nimbussecure/crypt_key.rb
|
89
|
+
- lib/nimbussecure/errors.rb
|
90
|
+
- lib/nimbussecure/results.rb
|
91
|
+
- lib/nimbussecure/stored_key.rb
|
92
|
+
- lib/nimbussecure/version.rb
|
93
|
+
- nimbussecure.gemspec
|
94
|
+
- pry_load.rb
|
95
|
+
- test/accounts_spec.rb
|
96
|
+
- test/basic_key_lookup_spec.rb
|
97
|
+
- test/fixtures/vcr_cassettes/accounts/test.yml
|
98
|
+
- test/fixtures/vcr_cassettes/lookup/key1.yml
|
99
|
+
- test/fixtures/vcr_cassettes/lookup/key2.yml
|
100
|
+
- test/fixtures/vcr_cassettes/lookup/key3.yml
|
101
|
+
- test/minitest_helper.rb
|
102
|
+
- test/run_tests.rb
|
103
|
+
homepage: ''
|
104
|
+
licenses: []
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project: nimbussecure
|
123
|
+
rubygems_version: 1.8.15
|
124
|
+
signing_key:
|
125
|
+
specification_version: 3
|
126
|
+
summary: Client library for NimbusSecure
|
127
|
+
test_files:
|
128
|
+
- test/accounts_spec.rb
|
129
|
+
- test/basic_key_lookup_spec.rb
|
130
|
+
- test/fixtures/vcr_cassettes/accounts/test.yml
|
131
|
+
- test/fixtures/vcr_cassettes/lookup/key1.yml
|
132
|
+
- test/fixtures/vcr_cassettes/lookup/key2.yml
|
133
|
+
- test/fixtures/vcr_cassettes/lookup/key3.yml
|
134
|
+
- test/minitest_helper.rb
|
135
|
+
- test/run_tests.rb
|