urg 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/one_time_secret.rb +79 -0
- data/lib/secure_data.rb +31 -0
- data/lib/urg.rb +23 -0
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: caa54c0d547147e299a5fe633dffb9788ad484bfd1a2b6069de082b2eed9eb21
|
4
|
+
data.tar.gz: 6d2cbad977fe534ca66cd7c529c72a619e4cfcfe37d1bb8844738390fb7aca16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0045e15e2b7ac46f47ec6bcb5a8dee46e00902da8e26eb6e2bf364743db62f207967d669d184e6b09c20df37ff2675af6c6616b5d91b6319ff3dcc1527360c2
|
7
|
+
data.tar.gz: 83716724a828da6cd6a63054fca9b7b1917692aed9796b85d7de9a474a5f81c3e4c87555fac011d546e75d3d28f1b1a95a28332c91f14241b65bd4947084fba9
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "faraday"
|
2
|
+
|
3
|
+
module Urg
|
4
|
+
class OneTimeSecret
|
5
|
+
def share_secret(secret, passphrase:nil, ttl: nil, notify_email: nil)
|
6
|
+
secret_params = {
|
7
|
+
secret: secret,
|
8
|
+
passphrase: passphrase,
|
9
|
+
ttl: ttl.presence || default_secret_ttl,
|
10
|
+
recipient: notify_email
|
11
|
+
}
|
12
|
+
|
13
|
+
conn = Faraday.new(
|
14
|
+
url: api_url("/share"),
|
15
|
+
params: secret_params,
|
16
|
+
headers: api_headers
|
17
|
+
)
|
18
|
+
|
19
|
+
resp = conn.post
|
20
|
+
|
21
|
+
unless resp.success?
|
22
|
+
raise "OneTimeSecret share_secret request failed with status #{resp.status}, and body `#{resp.body}`"
|
23
|
+
end
|
24
|
+
|
25
|
+
JSON.parse(resp.body)
|
26
|
+
end
|
27
|
+
|
28
|
+
def fetch_secret(secret_key, passphrase: nil)
|
29
|
+
secret_params = {
|
30
|
+
passphrase: passphrase
|
31
|
+
}
|
32
|
+
|
33
|
+
conn = Faraday.new(
|
34
|
+
url: api_url("/secret/#{secret_key}"),
|
35
|
+
params: secret_params,
|
36
|
+
headers: api_headers
|
37
|
+
)
|
38
|
+
|
39
|
+
resp = conn.post
|
40
|
+
|
41
|
+
unless resp.success?
|
42
|
+
raise "OneTimeSecret fetch_secret request failed with status #{resp.status}#{' (it\'s possible that the secret has already been consumed)' if resp.status == 404}, and body `#{resp.body}`"
|
43
|
+
end
|
44
|
+
|
45
|
+
JSON.parse(resp.body)
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def default_secret_ttl
|
52
|
+
600 # in seconds => 10 minutes
|
53
|
+
end
|
54
|
+
|
55
|
+
def api_url(path)
|
56
|
+
api_base_url + path
|
57
|
+
end
|
58
|
+
|
59
|
+
def api_base_url
|
60
|
+
"https://#{[username.sub('@', '%40'), api_key].join(":")}@onetimesecret.com/api/v1"
|
61
|
+
end
|
62
|
+
|
63
|
+
def api_headers
|
64
|
+
{
|
65
|
+
"Content-Type" => "application/json"
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def username
|
70
|
+
"tech@unreasonablegroup.com"
|
71
|
+
end
|
72
|
+
|
73
|
+
def api_key
|
74
|
+
# TODO!
|
75
|
+
# ENV["OTS_API_KEY"]
|
76
|
+
"8489b3912d38b9d1ba0ab943c28543a44548f909"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/secure_data.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
|
3
|
+
module Urg
|
4
|
+
class SecureData
|
5
|
+
def self.encrypt(plaintext)
|
6
|
+
cipher.encrypt
|
7
|
+
key = cipher.random_key
|
8
|
+
iv = cipher.random_iv
|
9
|
+
cyphertext = cipher.update(plaintext) + cipher.final
|
10
|
+
|
11
|
+
{
|
12
|
+
cyphertext: Base64.strict_encode64(cyphertext),
|
13
|
+
key: Base64.strict_encode64(key),
|
14
|
+
iv: Base64.strict_encode64(iv)
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.decrypt(cyphertext, iv:, key:)
|
19
|
+
cipher.decrypt
|
20
|
+
cipher.key = Base64.strict_decode64(key)
|
21
|
+
cipher.iv = Base64.strict_decode64(iv)
|
22
|
+
cipher.update(Base64.strict_decode64(cyphertext)) + cipher.final
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def self.cipher
|
28
|
+
@cipher ||= OpenSSL::Cipher::AES.new(256, :CBC)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/urg.rb
CHANGED
@@ -3,9 +3,32 @@ require "zlib"
|
|
3
3
|
require "openssl"
|
4
4
|
require "open-uri"
|
5
5
|
|
6
|
+
require_relative "./one_time_secret"
|
7
|
+
require_relative "./secure_data"
|
8
|
+
|
6
9
|
module Urg
|
7
10
|
DEFAULT_PUBLIC_KEY_URI = "https://urg-public-keys.s3-us-west-2.amazonaws.com/urg-exfil.pub"
|
8
11
|
|
12
|
+
def self.export(object)
|
13
|
+
string = Base64.encode64(Zlib::Deflate.deflate(Marshal.dump(object)))
|
14
|
+
|
15
|
+
encryption = SecureData.encrypt(string)
|
16
|
+
|
17
|
+
ots_passphrase = SecureRandom.urlsafe_base64
|
18
|
+
ots = OneTimeSecret.new.share_secret(encryption[:cyphertext], passphrase: ots_passphrase)
|
19
|
+
|
20
|
+
puts (("*" * 25) + "\n") * 1
|
21
|
+
puts "Exported. Data will self-destruct in 10 minutes OR after first use, whichever comes first."
|
22
|
+
puts "Import data remotely via: Urg.import(ots_key: \"#{ots['secret_key']}\", ots_passphrase: \"#{ots_passphrase}\", decryption_key: \"#{encryption[:key]}\", decryption_iv: \"#{encryption[:iv]}\")"
|
23
|
+
puts (("*" * 25) + "\n") * 1
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.import(ots_key:, ots_passphrase:, decryption_key:, decryption_iv:)
|
27
|
+
ots = OneTimeSecret.new.fetch_secret(ots_key, passphrase: ots_passphrase)
|
28
|
+
plaintext = SecureData.decrypt(ots["value"], iv: decryption_iv, key: decryption_key)
|
29
|
+
Marshal.load(Zlib::Inflate.inflate(Base64.decode64(plaintext)))
|
30
|
+
end
|
31
|
+
|
9
32
|
def self.exfil(object, key: DEFAULT_PUBLIC_KEY_URI)
|
10
33
|
if key
|
11
34
|
public_key_uri = URI.parse(key)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: urg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lawson Kurtz
|
@@ -9,13 +9,29 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2019-08-08 00:00:00.000000000 Z
|
12
|
-
dependencies:
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.15.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.15.4
|
13
27
|
description: Utils for urg
|
14
28
|
email: lawson.kurtz@gmail.com
|
15
29
|
executables: []
|
16
30
|
extensions: []
|
17
31
|
extra_rdoc_files: []
|
18
32
|
files:
|
33
|
+
- lib/one_time_secret.rb
|
34
|
+
- lib/secure_data.rb
|
19
35
|
- lib/urg.rb
|
20
36
|
homepage: https://rubygems.org/gems/urg
|
21
37
|
licenses:
|
@@ -36,8 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
36
52
|
- !ruby/object:Gem::Version
|
37
53
|
version: '0'
|
38
54
|
requirements: []
|
39
|
-
|
40
|
-
rubygems_version: 2.7.6
|
55
|
+
rubygems_version: 3.1.2
|
41
56
|
signing_key:
|
42
57
|
specification_version: 4
|
43
58
|
summary: urg, mostly.
|