yasst 0.1.1 → 0.2.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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- N2Y1N2Y4ZjIwNDY5ZjUzNWNmNDQzOTU0OTIzZDRhN2ViZWFkMTcxYg==
4
+ MWIyYWE0MWYyMmM2ZTJmMjJlMjMzMDUwNmZjMzA5MDdmMDZhZjdjNw==
5
5
  data.tar.gz: !binary |-
6
- M2ExMWRhNDA2MDYzZjhmMTk2NTkzMDllZWNjMmRhMjM3NDk5ZTE1MA==
6
+ NmNkODBiNTMwYmIxYmZiZTMxY2RhOGRmOTFmMTNjODIwMGVkYTZkOA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZTE2MWQ0NGY1YjBkODUxY2YyYTE5NzA4ZWJmZjllNTcwM2RiYjY5NzU2NmUx
10
- MGIxNWNlMjhhZjA3MmMwYWRmN2U2YzIyZWM3MTAxYjI3NzA5MDFmNTEyMWJh
11
- NWQ3YzI5YzI3ZTc1ODViMDc5YzllM2UyN2IwYjdjNjZkZDNkMDQ=
9
+ YWVjNmY5NjVkYjRkNzljZjI0NThjNzU0OWYwOWYwNzA5YzBmNGM2NDIwOTI2
10
+ ZDQ4MWQ1OWJkZWVjZmU4NjAzNjNiMWEyNDk1NmQ3YjJjMjAxOWU3ZjBhZjg5
11
+ OWM1YTUxMzY4M2ViMGIwYjg5ZGJmZTQwNTk5NmI2NmE2NGI1ODM=
12
12
  data.tar.gz: !binary |-
13
- ZDc4NWYzYWMwZWQ0MWZhZjM4ODQ4ZmEyYWQ1NmExOTVlM2FmN2NhMGY2MTI2
14
- NWZkMWZiOWFiNjcxMDJlMzU0Zjk3Mzc2OTE4YWZkMWFhNWE0MzcxOTlmY2Qz
15
- ODk5YjlkYTZhZGZmNDk0YWYzYzNhNzJjNTA1YTlhZGU1YTc2YzI=
13
+ ZGUzOGRmMzg5NjgzNDc3N2I5ODA3MzExMjliOWI4ZWFiNzY1N2VkZjM3YTZi
14
+ Yzc1ZjA0MDNlZmJjMWRkNjViYTljYTA1ZDZlZWIxMDg1ZTk4NjNjZDk5ODgy
15
+ MGE5M2JkMzZhNGUyNTk4MzAwNmQ0NTMzNGM4ZGUwODY5Y2NkZDk=
@@ -2,7 +2,11 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
- ## [Unreleased]
5
+ ## [0.2.0] - 2016-03-10
6
+ ### Added
7
+ * First implementation of YasstFile encrypt/decrypt actions
8
+ ### Changed
9
+ * Update README with gem release instructions
6
10
 
7
11
  ## [0.1.1] - 2016-02-11
8
12
  ### Changed
@@ -15,6 +19,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
15
19
  ### Added
16
20
  * Initial Release
17
21
 
18
- [Unreleased]: https://github.com/rdark/yasst/compare/0.1.1...develop
22
+ [Unreleased]: https://github.com/rdark/yasst/compare/0.2.0...develop
23
+ [0.2.0]: https://github.com/rdark/yasst/compare/0.1.1...0.2.0
19
24
  [0.1.1]: https://github.com/rdark/yasst/tree/0.1.0...0.1.1
20
25
  [0.1.0]: https://github.com/rdark/yasst/tree/0.1.0
data/README.md CHANGED
@@ -72,7 +72,29 @@ Additionally, the OpenSSL provider will ensure that there is:
72
72
 
73
73
  ### YasstFile
74
74
 
75
- NotImplementedError
75
+ Still under active development, interface may change
76
+
77
+ #### Set up a Provider
78
+
79
+ provider = Yasst::Provider::OpenSSL.new(passphrase: 'a really strong passphrase')
80
+
81
+ #### Encrypt a YasstFile
82
+
83
+ file = YasstFile.new('/tmp/plain_file.txt')
84
+ file.provider = provider
85
+ file.encrypted?
86
+ => false
87
+ file.encrypt
88
+ => "/tmp/plain_file.txt.aes"
89
+
90
+ #### Decrypt a YasstFile
91
+
92
+ file = YasstFile.new('/tmp/plain_file.txt.aes')
93
+ file.provider = provider
94
+ file.encrypted?
95
+ => true
96
+ file.decrypt
97
+ => "/tmp/plain_file.txt"
76
98
 
77
99
  ## Installation
78
100
 
@@ -92,9 +114,22 @@ Or install it yourself as:
92
114
 
93
115
  ## Development
94
116
 
95
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
117
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
118
+ `rake` to run the tests. You can also run `bin/console` for an interactive
119
+ prompt that will allow you to experiment.
120
+
121
+ To install this gem onto your local machine, run `bundle exec rake install`.
122
+
123
+ To release a new version, use [git flow][git_flow] (e.g `git flow release start
124
+ 0.1.2`) to create a release branch. Once on the release branch, update
125
+ `lib/yasst/version.rb` with the version number, and update `CHANGELOG.md` with
126
+ the changes. Once committed, push the changes (and sign them) using `git flow
127
+ release finish -sp $version` (where `$version`) is the new version.
128
+ [Travis][travis_yasst] will create a new rubygem release on receiving a new
129
+ tag.
96
130
 
97
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
131
+ [travis_yasst]: https://travis-ci.org/rdark/yasst
132
+ [git_flow]: http://nvie.com/posts/a-successful-git-branching-model/
98
133
 
99
134
  ## Contributing
100
135
 
data/TODO.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## General Functionality
4
4
 
5
- * YasstFile Implementation
5
+ * secure file delete/scrubbing
6
6
  * support for larger-than-memory files
7
7
  * support for authenticated cipher modes
8
8
  * support for OpenPGP crypto provider
@@ -11,6 +11,7 @@ module Yasst
11
11
  class InvalidCryptoProfile < self; end
12
12
  class InvalidCryptoAlgorithm < self; end
13
13
  class InvalidPassPhrase < self; end
14
+ class InvalidFileDestination < self; end
14
15
  class AlreadyEncrypted < self; end
15
16
  class AlreadyDecrypted < self; end
16
17
  end
@@ -30,6 +30,13 @@ module Yasst
30
30
  (self.pbkdf2_iterations = args[:pbkdf2_iterations])
31
31
  end
32
32
 
33
+ ##
34
+ # files matching this are deemed to be already encrypted by default
35
+ # TODO: auto file extension based on the algorithm in use
36
+ def file_extension
37
+ 'aes'
38
+ end
39
+
33
40
  # setter method for algorithm
34
41
  def algorithm=(alg)
35
42
  valgs = Yasst::Primatives::OpenSSL::Metadata.list_ciphers
@@ -1,3 +1,3 @@
1
1
  module Yasst
2
- VERSION = '0.1.1'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -1,7 +1,170 @@
1
1
  ##
2
2
  # Decorator pattern for File
3
+ #
4
+ # TODO: initialise with a provider?
5
+ # * file encrypt state should be detected when passed through YasstFile.new -
6
+ # but need to add a provider to it for detection at init time
7
+ # * possible use of destructive/non-destructive methods for optionally writing
8
+ # files
9
+ # * check file open modes for destructive actions (e.g NOCREAT or something)
10
+ # * use a module/mixin for functional stuff
11
+ # * method for shredding files
12
+ # * verify support for blocks
13
+ # * helper methods and have a block that you can throw to open?
14
+ # (encrypt_and_shred, open_and_decrypt, read?)
3
15
  class YasstFile < File
4
- def initialize(*_args)
5
- raise NotImplementedError
16
+ attr_writer :encrypted
17
+
18
+ # if a provider does not provide a file_extension method then this is the
19
+ # default file extension that will be used
20
+ DEFAULT_ENC_FILE_EXT = 'enc'.freeze
21
+ CRYPTO_METHODS = [:in_memory].freeze
22
+
23
+ ##
24
+ # Encrypt self using a Yasst::Provider
25
+ # Returns a string with the path name of the encrypted file
26
+ def encrypt(method = :in_memory)
27
+ raise Yasst::Error::AlreadyEncrypted,
28
+ 'File is already encrypted' if encrypted?
29
+ raise Yasst::Error::InvalidFileDestination,
30
+ 'encrypt_to is not set' if encrypt_to.nil?
31
+ encrypt_using(method)
32
+ encrypt_to
33
+ end
34
+
35
+ ##
36
+ # Decrypt self using a Yasst::Provider
37
+ # Returns a string with the path name of the decrypted file
38
+ def decrypt(method = :in_memory)
39
+ raise Yasst::Error::AlreadyDecrypted,
40
+ 'File is not encrypted' unless encrypted?
41
+ raise Yasst::Error::InvalidFileDestination,
42
+ 'decrypt_to is not set' if decrypt_to.nil?
43
+ decrypt_using(method)
44
+ decrypt_to
45
+ end
46
+
47
+ def encrypted?
48
+ @encrypted ||= false
49
+ end
50
+
51
+ def encrypt_to
52
+ @encrypt_to ||= default_encrypt_to
53
+ end
54
+
55
+ def decrypt_to
56
+ @decrypt_to ||= default_decrypt_to
57
+ end
58
+
59
+ ##
60
+ # Where to write the encrypted version of the file to
61
+ def encrypt_to=(e_path)
62
+ raise Yasst::Error::InvalidFileDestination,
63
+ 'cannot overwrite self' if e_path == path
64
+ @encrypt_to = e_path
65
+ end
66
+
67
+ ##
68
+ # Where to decrypt the file to
69
+ def decrypt_to=(d_path)
70
+ raise Yasst::Error::InvalidFileDestination,
71
+ 'cannot overwrite self' if d_path == path
72
+ @decrypt_to = d_path
73
+ end
74
+
75
+ ##
76
+ # Setter method for provider. Also sets @encrypted where the filename matches
77
+ # the extension for the provider, unless it has previously been set
78
+ def provider=(provider)
79
+ @provider = provider
80
+ @encrypted.nil? && (matches_provider_extension? && @encrypted = true)
81
+ end
82
+
83
+ ##
84
+ # If a file matches the provider profiles file extension, it is deemed to be
85
+ # encrypted by default
86
+ # Where a provider does not support the file_extension method, the default
87
+ # extension is used to match against.
88
+ def matches_provider_extension?
89
+ ext = DEFAULT_ENC_FILE_EXT
90
+ (@provider.profile.respond_to? 'file_extension') &&
91
+ ext = @provider.profile.file_extension
92
+ path =~ /#{ext}$/
93
+ end
94
+
95
+ private
96
+
97
+ ##
98
+ # The default destination that the encrypted file will be written.
99
+ # This is the same as the path (i.e the parent directory of the file), if the
100
+ # file already has a matching extension, otherwise it is the path with the
101
+ # extension postfixed
102
+ def default_encrypt_to
103
+ return nil if encrypted?
104
+ return "#{path}.#{DEFAULT_ENC_FILE_EXT}" unless
105
+ @provider.profile.respond_to? 'file_extension'
106
+ return path if path =~ /#{@provider.profile.file_extension}$/
107
+ "#{path}.#{@provider.profile.file_extension}"
108
+ end
109
+
110
+ ##
111
+ # The default destination that the decrypted file will be written.
112
+ # This is the same as the path (i.e the parent directory of the file), if the
113
+ # file already has a matching extension, otherwise it is the path with
114
+ # encryption provider extension removed
115
+ def default_decrypt_to
116
+ return nil unless encrypted?
117
+ prov_ext = DEFAULT_ENC_FILE_EXT
118
+ (@provider.profile.respond_to? 'file_extension') &&
119
+ prov_ext = @provider.profile.file_extension
120
+ path.sub(/\.#{prov_ext}$/, '')
121
+ end
122
+
123
+ ##
124
+ # execute an encrypt method
125
+ def encrypt_using(method)
126
+ raise NotImplementedError unless
127
+ CRYPTO_METHODS.include? method
128
+ method == :in_memory && encrypt_in_memory
129
+ end
130
+
131
+ ##
132
+ # execute a decrypt method
133
+ def decrypt_using(method)
134
+ raise NotImplementedError unless
135
+ CRYPTO_METHODS.include? method
136
+ method == :in_memory && decrypt_in_memory
137
+ end
138
+
139
+ ##
140
+ # Implementation of encrypt that reads a whole file into memory as a
141
+ # YasstString, encrypts it and then writes out to the chosen destination
142
+ # ensures that self.close is called on completion (or failure)
143
+ def encrypt_in_memory
144
+ ystr = YasstString.new(read)
145
+ ystr.encrypt(@provider)
146
+ begin
147
+ open(encrypt_to, 'w') do |f|
148
+ f << ystr
149
+ end
150
+ ensure
151
+ close
152
+ end
153
+ end
154
+
155
+ ##
156
+ # Implementation of decrypt that reads a whole file into memory as a
157
+ # YasstString, decrypts it and then writes out to the chosen destination
158
+ # ensures that self.close is called on completion (or failure)
159
+ def decrypt_in_memory
160
+ ystr = YasstString.new(read, true)
161
+ ystr.decrypt(@provider)
162
+ begin
163
+ open(decrypt_to, 'w') do |f|
164
+ f << ystr
165
+ end
166
+ ensure
167
+ close
168
+ end
6
169
  end
7
170
  end
@@ -14,7 +14,7 @@ class YasstString < String
14
14
  # Encrypt self using a Yasst::Provider
15
15
  def encrypt(provider)
16
16
  raise Yasst::Error::AlreadyEncrypted,
17
- 'File is already encrypted' if encrypted?
17
+ 'String is already encrypted' if encrypted?
18
18
  @encrypted = true
19
19
  replace(provider.encrypt(to_s))
20
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yasst
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Clark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-11 00:00:00.000000000 Z
11
+ date: 2016-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler