yasst 0.1.1 → 0.2.0

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