carapace 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +31 -14
- data/Gemfile +17 -0
- data/README.md +36 -32
- data/Rakefile +32 -2
- data/carapace.gemspec +29 -0
- data/lib/carapace.rb +2 -124
- data/lib/carapace/carapace.rb +124 -0
- data/lib/carapace/engine.rb +7 -0
- data/lib/carapace/version.rb +3 -0
- data/lib/tasks/carapace_tasks.rake +4 -0
- data/test/dummy/README.md +134 -0
- data/test/{rails_app → dummy}/Rakefile +3 -6
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/javascripts/message.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/message.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/{rails_app → dummy}/app/controllers/message_controller.rb +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/{rails_app → dummy}/app/helpers/message_helper.rb +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/{rails_app → dummy}/app/views/message/index.html.erb +1 -1
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/{rails_app → dummy}/config/database.yml +9 -3
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/{rails_app → dummy}/config/initializers/inflections.rb +7 -2
- data/test/{rails_app → dummy}/config/initializers/mime_types.rb +0 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +61 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/log/development.log +742 -0
- data/test/dummy/log/test.log +27 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/{rails_app → dummy}/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/{rails_app → dummy}/test/functional/message_controller_test.rb +3 -5
- data/test/dummy/test/unit/helpers/message_helper_test.rb +4 -0
- data/test/dummy/tmp/cache/assets/C78/9E0/sprockets%2F8172886cba8a1911b217c81605b19e14 +0 -0
- data/test/dummy/tmp/cache/assets/CD3/C80/sprockets%2F60a4ed28b40070af1a35a65086d3758f +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/D08/C80/sprockets%2Fcb11b48a42f94e0db70f194493a32c77 +0 -0
- data/test/dummy/tmp/cache/assets/D30/D70/sprockets%2Ffba6ea9d0d74a2071065123308daec69 +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D42/790/sprockets%2F63f423d2fb157e98fb0d8ee89c0351a1 +0 -0
- data/test/dummy/tmp/cache/assets/D4C/AD0/sprockets%2F1a9dcbbb7774e26a180893a79bb0889f +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/{rails_app/public/javascripts/carapace.js → dummy/tmp/cache/assets/D55/0F0/sprockets%2Fec9774e5f33cb737f35ee3aa8257963e} +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D88/4B0/sprockets%2Fdc0cf832aa65e1e6dbda9551c17120c1 +0 -0
- data/test/dummy/tmp/cache/assets/D8B/E80/sprockets%2Fd0d64e037bd6d546f0b09a25b2cc24db +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/E02/120/sprockets%2F73ff50f3f5d1f01c2ee1bedfe4e56d67 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E0D/340/sprockets%2Fb7e1e6b8d949eef8a343b78da5f07bae +0 -0
- data/test/integration/static_asset_test.rb +8 -0
- data/test/test_helper.rb +14 -0
- data/{rails_generators/templates → vendor/assets/javascripts}/carapace.js +0 -0
- metadata +194 -57
- data/rails_generators/USAGE +0 -7
- data/rails_generators/carapace_generator.rb +0 -7
- data/test/rails_app/README.md +0 -130
- data/test/rails_app/app/controllers/application.rb +0 -10
- data/test/rails_app/app/helpers/application_helper.rb +0 -3
- data/test/rails_app/config/boot.rb +0 -109
- data/test/rails_app/config/environment.rb +0 -60
- data/test/rails_app/config/environments/development.rb +0 -18
- data/test/rails_app/config/environments/production.rb +0 -19
- data/test/rails_app/config/environments/test.rb +0 -22
- data/test/rails_app/config/routes.rb +0 -35
- data/test/rails_app/doc/README_FOR_APP +0 -2
- data/test/rails_app/public/404.html +0 -30
- data/test/rails_app/public/422.html +0 -30
- data/test/rails_app/public/500.html +0 -30
- data/test/rails_app/public/dispatch.cgi +0 -10
- data/test/rails_app/public/dispatch.fcgi +0 -24
- data/test/rails_app/public/dispatch.rb +0 -10
- data/test/rails_app/public/images/rails.png +0 -0
- data/test/rails_app/public/javascripts/application.js +0 -2
- data/test/rails_app/public/javascripts/controls.js +0 -963
- data/test/rails_app/public/javascripts/dragdrop.js +0 -972
- data/test/rails_app/public/javascripts/effects.js +0 -1120
- data/test/rails_app/public/javascripts/prototype.js +0 -4225
- data/test/rails_app/public/robots.txt +0 -5
- data/test/rails_app/script/about +0 -3
- data/test/rails_app/script/console +0 -3
- data/test/rails_app/script/destroy +0 -3
- data/test/rails_app/script/generate +0 -3
- data/test/rails_app/script/performance/benchmarker +0 -3
- data/test/rails_app/script/performance/profiler +0 -3
- data/test/rails_app/script/performance/request +0 -3
- data/test/rails_app/script/plugin +0 -3
- data/test/rails_app/script/process/inspector +0 -3
- data/test/rails_app/script/process/reaper +0 -3
- data/test/rails_app/script/process/spawner +0 -3
- data/test/rails_app/script/runner +0 -3
- data/test/rails_app/script/server +0 -3
- data/test/rails_app/test/test_helper.rb +0 -38
data/CHANGELOG.md
CHANGED
@@ -1,19 +1,38 @@
|
|
1
1
|
# Carapace Changelog
|
2
2
|
|
3
|
+
## 0.2.0: Monday 4th June 2012
|
4
|
+
|
5
|
+
Major reworking of the gem for Rails 3.2.5. The gem is now a Rails Engine built
|
6
|
+
from the ground up.
|
7
|
+
|
8
|
+
The original `test/rails_app` has been replaced with the Rails 3 standard `test/dummy` app.
|
9
|
+
|
10
|
+
File `carapace.js` has moved from `rails_generators/templates` to `vendor/assets/javascripts`.
|
11
|
+
File `carapace.rb` has moved from `lib` to `lib\carapace` and its Javascript output has been marked as being `html_safe`.
|
12
|
+
|
13
|
+
Various other files have been added/removed/modified to support the Rails 3 framework change.
|
14
|
+
|
15
|
+
This and all subsequent versions are for Rails 3 or later. [For Rails 2.x use version 0.1.2](https://rubygems.org/gems/carapace/versions/0.1.2).
|
16
|
+
|
17
|
+
No testing has been done for Rails 3 versions prior to 3.2.5.
|
18
|
+
|
3
19
|
## 0.1.2: Thursday 31st May 2012
|
4
20
|
|
5
21
|
Update to the ruby code so that it works with version 1.9.3.
|
6
|
-
The change that was required was to overcome an implicit cast that stopped working. The
|
22
|
+
The change that was required was to overcome an implicit cast that stopped working. The
|
7
23
|
solution was to provide an explicit cast. Regression tested to Ruby 1.8.6 and 1.8.7.
|
8
24
|
|
9
|
-
Testing was also performed with Rails 2.3.14, the last version in the 2.x series. The
|
25
|
+
Testing was also performed with Rails 2.3.14, the last version in the 2.x series. The
|
10
26
|
test/rails_app built with Rails 2.0.2 did not work out of the box and so it has also
|
11
27
|
been updated for rails 2.3.14 while maintaining backward compatibility with Rails 2.0.2.
|
12
28
|
|
13
|
-
The changed files are
|
14
|
-
|
29
|
+
The changed files are
|
30
|
+
|
31
|
+
script/server
|
32
|
+
config/environment.rb
|
33
|
+
config/environments/development/rb`
|
15
34
|
|
16
|
-
When using the test/rails app on versions more recent than 2.0.2 run
|
35
|
+
When using the test/rails app on versions more recent than 2.0.2 run `rake rails:update`
|
17
36
|
prior to starting the server.
|
18
37
|
|
19
38
|
This version is the final version that is tested against Ruby 1.8 and Rails 2.x.
|
@@ -21,21 +40,19 @@ This version is the final version that is tested against Ruby 1.8 and Rails 2.x.
|
|
21
40
|
## 0.1.1: Thursday 31st May 2012
|
22
41
|
|
23
42
|
Update to the ruby code so that it works with version 1.8.7.
|
24
|
-
The change that was required was due to OpenSSL::Cipher no longer being a module
|
25
|
-
(the directive `include Cipher` as a module has been removed)
|
26
|
-
See the [Ruby 1.8.7 release news](http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7/NEWS) where it says
|
43
|
+
The change that was required was due to `OpenSSL::Cipher` no longer being a module
|
44
|
+
(the directive `include Cipher` as a module has been removed).
|
45
|
+
See the [Ruby 1.8.7 release news](http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7/NEWS) where it says:
|
27
46
|
|
28
|
-
|
29
|
-
Compatibility classes are provided which will be removed in Ruby 1.9.
|
47
|
+
_Remove redundant module namespace in Cipher, Digest, PKCS7, PKCS12.
|
48
|
+
Compatibility classes are provided which will be removed in Ruby 1.9._
|
30
49
|
|
31
50
|
## 0.1.0: Wednesday 30th May 2012
|
32
51
|
|
33
|
-
Initial gem version
|
52
|
+
Initial gem version.
|
34
53
|
|
35
|
-
Written and tested against Ruby 1.8.6 and Rails 2.0.2
|
54
|
+
Written and tested against Ruby 1.8.6 and Rails 2.0.2.
|
36
55
|
|
37
56
|
## Origin
|
38
57
|
|
39
58
|
The original Carapace code was written on 10th August 2007 for Ruby 1.8.6 and Rails 2.0.2.
|
40
|
-
|
41
|
-
|
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# Declare your gem's dependencies in carapace.gemspec.
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
5
|
+
# development dependencies will be added by default to the :development group.
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
# jquery-rails is used by the dummy application
|
9
|
+
gem "jquery-rails"
|
10
|
+
|
11
|
+
# Declare any dependencies that are still in development here instead of in
|
12
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
13
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
14
|
+
# your gem to rubygems.org.
|
15
|
+
|
16
|
+
# To use debugger
|
17
|
+
# gem 'debugger'
|
data/README.md
CHANGED
@@ -1,56 +1,61 @@
|
|
1
|
-
# Carapace
|
1
|
+
# Carapace
|
2
2
|
|
3
3
|
Carapace enables encrypted transfer of HTTP form field values from
|
4
4
|
the view (client) to the controller (server).
|
5
5
|
|
6
|
-
The data is encrypted by the browser before being posted to the server. The
|
6
|
+
The data is encrypted by the browser before being posted to the server. The
|
7
7
|
server decrypts the data ready for processing.
|
8
8
|
|
9
9
|
Example uses are transfer of user passwords or credit card numbers.
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
13
|
-
|
13
|
+
**This gem is for Rails 3.x. For Rails 2.x please use Carapace 0.1.2.**
|
14
14
|
|
15
|
-
|
15
|
+
1. Add it to your Gemfile:
|
16
16
|
|
17
|
-
|
17
|
+
gem carapace
|
18
18
|
|
19
|
-
|
19
|
+
2. And then:
|
20
|
+
|
21
|
+
$ bundle install
|
20
22
|
|
21
23
|
## Usage
|
22
24
|
|
23
|
-
Client-side, Carapace uses Javascript to perform encryption. Include this like so:
|
25
|
+
Client-side, Carapace uses Javascript to perform encryption. Include this like so:
|
26
|
+
|
27
|
+
<%= javascript_include_tag 'carapace.js' %>
|
28
|
+
<%= carapace_javascript %>
|
24
29
|
|
25
|
-
|
26
|
-
|
30
|
+
Alternatively, add `\\= require carapace` to the `app/assets/javascripts/application.js`
|
31
|
+
file instead of using `<% javascript_include_tag 'carapace.js' %>`.
|
27
32
|
|
28
33
|
Use the `carapace_encrypt` Javascript function on any form fields that
|
29
34
|
require encryption. For example:
|
30
35
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
function onSubmit()
|
37
|
+
{
|
38
|
+
carapace_encrypt(document.getElementById("user_password"));
|
39
|
+
}
|
35
40
|
|
36
|
-
Then, configure the form's
|
41
|
+
Then, configure the form's `submit` button to call it:
|
37
42
|
|
38
|
-
|
43
|
+
<%= submit_tag "Add User", :class => "submit", :onclick => "onSubmit()" %>
|
39
44
|
|
40
|
-
On the server, mix Carapace into a Rails controller (
|
45
|
+
On the server, mix Carapace into a Rails controller (_ApplicationController_) class:
|
41
46
|
|
42
|
-
|
43
|
-
|
47
|
+
require 'carapace'
|
48
|
+
include Carapace
|
44
49
|
|
45
50
|
Then use Carapace from within action methods:
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
def index
|
53
|
+
carapace_session
|
54
|
+
if request.post?
|
55
|
+
@message=params[:message]
|
56
|
+
carapace_decrypt! @message
|
57
|
+
end
|
58
|
+
end
|
54
59
|
|
55
60
|
**Warning:** if the controller rejects a post operation and re-displays itself
|
56
61
|
the data is not encrypted when sent to the browser. To maintain security,
|
@@ -59,7 +64,7 @@ such fields should be cleared before rendering the view.
|
|
59
64
|
## Testing
|
60
65
|
|
61
66
|
Test the gem with `rake test`. There is also a self-contained rails application
|
62
|
-
in `test\
|
67
|
+
in `test\dummy` for further testing and education. See `test\dummy\README.md`
|
63
68
|
for more information.
|
64
69
|
|
65
70
|
## History
|
@@ -68,15 +73,15 @@ Carapace was originally written as part of a larger application in 2007 that nee
|
|
68
73
|
to provide a degree of security for sensitive data in situations where SSL could
|
69
74
|
not be used.
|
70
75
|
|
71
|
-
The Carapace gem was created in 2012 to make it straightforward to re-use the
|
76
|
+
The Carapace gem was created in 2012 to make it straightforward to re-use the
|
72
77
|
original code in new applications. This was done primarily as a learning exercise.
|
73
78
|
|
74
|
-
For revision history see CHANGELOG.md
|
79
|
+
For revision history see `CHANGELOG.md`.
|
75
80
|
|
76
81
|
## Acknowledgement
|
77
82
|
|
78
83
|
Carapace makes use of the [JSBN Library by Tom Wu](http://www-cs-students.stanford.edu/~tjw/jsbn/)
|
79
|
-
under the terms of its license (see file
|
84
|
+
under the terms of its license (see file `LICENCE_JSBN`).
|
80
85
|
|
81
86
|
## About the Name
|
82
87
|
|
@@ -84,8 +89,8 @@ A _Carapace_ is the protective shell that covers and protects animals
|
|
84
89
|
such as crabs and turtles.
|
85
90
|
|
86
91
|
Definitions:
|
87
|
-
[Oxford](http://oxforddictionaries.com/definition/carapace?q=carapace)
|
88
|
-
[Cambridge](http://dictionary.cambridge.org/dictionary/british/carapace)
|
92
|
+
[Oxford](http://oxforddictionaries.com/definition/carapace?q=carapace)
|
93
|
+
[Cambridge](http://dictionary.cambridge.org/dictionary/british/carapace)
|
89
94
|
|
90
95
|
In a similar vein, this gem allows a protective shell to surround data sent from
|
91
96
|
a browser to a web server.
|
@@ -93,4 +98,3 @@ a browser to a web server.
|
|
93
98
|
## License
|
94
99
|
|
95
100
|
Carapace is released under the MIT License. See LICENSE for details.
|
96
|
-
|
data/Rakefile
CHANGED
@@ -1,8 +1,38 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Carapace'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
Bundler::GemHelper.install_tasks
|
27
|
+
|
1
28
|
require 'rake/testtask'
|
2
29
|
|
3
|
-
Rake::TestTask.new do |t|
|
30
|
+
Rake::TestTask.new(:test) do |t|
|
31
|
+
t.libs << 'lib'
|
4
32
|
t.libs << 'test'
|
33
|
+
t.pattern = 'test/**/*_test.rb'
|
34
|
+
t.verbose = false
|
5
35
|
end
|
6
36
|
|
7
|
-
|
37
|
+
|
8
38
|
task :default => :test
|
data/carapace.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
# Maintain your gem's version:
|
4
|
+
require "carapace/version"
|
5
|
+
|
6
|
+
# Describe your gem and declare its dependencies:
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "carapace"
|
9
|
+
s.version = Carapace::VERSION
|
10
|
+
|
11
|
+
s.summary = "RSA encryption for HTML form fields"
|
12
|
+
s.description = "Allows field contents to be encrypted between broswer and webserver"
|
13
|
+
|
14
|
+
s.authors = ["John Lane"]
|
15
|
+
s.email = ["carapace@jelmail.com"]
|
16
|
+
s.homepage = 'https://github.com/johnlane/carapace'
|
17
|
+
s.license = 'MIT'
|
18
|
+
|
19
|
+
s.files = Dir["{lib,vendor}/**/*"] + ["CHANGELOG.md", "LICENSE", "LICENSE_JSBN", "Rakefile", "README.md" ]
|
20
|
+
s.test_files = Dir["test/**/*"] + ["Gemfile", "carapace.gemspec"]
|
21
|
+
|
22
|
+
s.add_dependency "rails", "~> 3.2.5"
|
23
|
+
|
24
|
+
s.add_development_dependency "sqlite3"
|
25
|
+
|
26
|
+
s.add_development_dependency 'minitest'
|
27
|
+
s.add_development_dependency 'capybara'
|
28
|
+
|
29
|
+
end
|
data/lib/carapace.rb
CHANGED
@@ -1,124 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'openssl'
|
4
|
-
include OpenSSL
|
5
|
-
include PKey
|
6
|
-
include Cipher if RUBY_VERSION < "1.8.7"
|
7
|
-
|
8
|
-
@carapace_javascript_written = false
|
9
|
-
|
10
|
-
# Until I can get the below to work it will need to be done in the contoller
|
11
|
-
# helper_method :carapace_javascript
|
12
|
-
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
HEX = { 'a' => 10, 'b' => 11, 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15 } #:nodoc:
|
17
|
-
|
18
|
-
# Pass as parameter to carapace_decrypt to ensure decryption occurs or force error
|
19
|
-
CARAPACE_FORCE_DECRYPT = true
|
20
|
-
|
21
|
-
# Start a Carapace session.
|
22
|
-
#
|
23
|
-
# A Carapace session allows a Rails action to display and process
|
24
|
-
# an HTML form that returns encrypted fields. The action must start a session
|
25
|
-
# for both the initial display and the post-processing of the request.
|
26
|
-
#
|
27
|
-
# Encryption is performed using a 1024 bit RSA key (or other key
|
28
|
-
# length as specified by the optional parameter)
|
29
|
-
#
|
30
|
-
def carapace_session(key_length=1024) #:doc:
|
31
|
-
unless session[:carapace_private_key]
|
32
|
-
key = RSA.new(key_length)
|
33
|
-
session[:carapace_private_key] = key.to_s
|
34
|
-
session[:carapace_public_modulus] = key.public_key.n.to_s(base=16)
|
35
|
-
session[:carapace_public_exponent] = key.public_key.e.to_s(base=16)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Decrypt a string. The return value is the decrypted string.
|
40
|
-
# If the string was not encrypted by the browser it is returned as-is
|
41
|
-
# unless the force_decrypt parameter is given as CARAPACE_FORCE_DECRYPT
|
42
|
-
# in which case nil is returned
|
43
|
-
#
|
44
|
-
# CARAPACE_FORCE_DECRYPT can be used to protect against accepting plaintext
|
45
|
-
# transmissions when the user's browser has Javascript disabled.
|
46
|
-
#
|
47
|
-
def carapace_decrypt(string, force_decrypt=false) #:doc:
|
48
|
-
if carapace_enabled? then # only decrypt if browser was enabled
|
49
|
-
byte = 0 # the converted byte will go here
|
50
|
-
s = "".rjust(string.length/2) # string to receive converted bytes
|
51
|
-
0.upto(string.length-1) do |i| # iterate through string one chr at a time
|
52
|
-
ch = string[i].chr # current character
|
53
|
-
nibble = HEX[ch] || ch.to_i # converted to its binary value
|
54
|
-
if i%2 == 0 then
|
55
|
-
byte = nibble << 4 # most significant nibble is bits 5-8
|
56
|
-
else
|
57
|
-
byte += nibble # lease significant nibble is bits 1-4
|
58
|
-
s[i/2] = byte.chr # store the converted byte
|
59
|
-
end
|
60
|
-
end
|
61
|
-
RSA.new(session[:carapace_private_key],nil).private_decrypt(s) # perform the decryption
|
62
|
-
else
|
63
|
-
force_decrypt ? nil : string # input is unencrypted - return input
|
64
|
-
end # return error if decryption was forced
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
# Decrypt a string. The return value is the decrypted string
|
69
|
-
# The string is decrypted in-situ, meaning its value is modified
|
70
|
-
# (warning, this does not call any customer accessor (e.g. "password=")
|
71
|
-
# so any custom code (such as password hashing) will not execute.)
|
72
|
-
#
|
73
|
-
def carapace_decrypt!(string, force_decrypt=false) #:doc:
|
74
|
-
decrypted_string = carapace_decrypt(string, force_decrypt)
|
75
|
-
string.replace decrypted_string unless !decrypted_string
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
# Helper method for use in the view rhtml to insert Carapace Javascript
|
81
|
-
# The javascript is added to a page once, no matter how often this is called.
|
82
|
-
#
|
83
|
-
def carapace_javascript #:doc:
|
84
|
-
unless @carapace_javascript_written
|
85
|
-
session[:carapace_nonce] = Time.now.to_i.to_s.reverse.crypt(rand.to_s.reverse[0,2])
|
86
|
-
@carapace_javascript_written = true
|
87
|
-
return "<script type='text/javascript'>
|
88
|
-
carapace_modulus = \"#{session[:carapace_public_modulus]}\" ;
|
89
|
-
carapace_exponent = \"#{session[:carapace_public_exponent]}\" ;
|
90
|
-
document.cookie = \"carapace_nonce=#{session[:carapace_nonce]}; path=/\";
|
91
|
-
//alert(\"Session:#{session[:carapace_nonce]}\\nCookie:\"+document.cookie)
|
92
|
-
rsa = new RSAKey();
|
93
|
-
rsa.setPublic(carapace_modulus, carapace_exponent);
|
94
|
-
|
95
|
-
function carapace_encrypt(field)
|
96
|
-
{
|
97
|
-
field.value = rsa.encrypt(field.value);
|
98
|
-
}
|
99
|
-
</script>"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# Returns TRUE if Carapace was enabled on the view. This does not mean that
|
104
|
-
# data was encrypted, just that Carapace Javascript was executed by the
|
105
|
-
# user's browser, making the Carapace encryption services available. This
|
106
|
-
# will be TRUE if everything is set up correctly AND the user's browser has
|
107
|
-
# Javascript enabled
|
108
|
-
#
|
109
|
-
# This can be used to protect against accepting plaintext
|
110
|
-
# transmissions when the user's browser has Javascript disabled.
|
111
|
-
#
|
112
|
-
def carapace_enabled? #:doc:
|
113
|
-
cookies["carapace_nonce"]==session[:carapace_nonce]
|
114
|
-
end
|
115
|
-
|
116
|
-
# This is called when Carapace is included in a controller.
|
117
|
-
# It automatically sets upn the Carapace Javascript helper.
|
118
|
-
def self.included(c)
|
119
|
-
#c.RAILS_DEFAULT_LOGGER.debug "Carapace has been included by #{c.class}"
|
120
|
-
if (c.class == Class)
|
121
|
-
c.helper_method :carapace_javascript
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
1
|
+
require 'carapace/engine'
|
2
|
+
require 'carapace/carapace'
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Carapace
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
include OpenSSL
|
5
|
+
include PKey
|
6
|
+
include Cipher if RUBY_VERSION < "1.8.7"
|
7
|
+
|
8
|
+
@carapace_javascript_written = false
|
9
|
+
|
10
|
+
# Until I can get the below to work it will need to be done in the contoller
|
11
|
+
# helper_method :carapace_javascript
|
12
|
+
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
HEX = { 'a' => 10, 'b' => 11, 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15 } #:nodoc:
|
17
|
+
|
18
|
+
# Pass as parameter to carapace_decrypt to ensure decryption occurs or force error
|
19
|
+
CARAPACE_FORCE_DECRYPT = true
|
20
|
+
|
21
|
+
# Start a Carapace session.
|
22
|
+
#
|
23
|
+
# A Carapace session allows a Rails action to display and process
|
24
|
+
# an HTML form that returns encrypted fields. The action must start a session
|
25
|
+
# for both the initial display and the post-processing of the request.
|
26
|
+
#
|
27
|
+
# Encryption is performed using a 1024 bit RSA key (or other key
|
28
|
+
# length as specified by the optional parameter)
|
29
|
+
#
|
30
|
+
def carapace_session(key_length=1024) #:doc:
|
31
|
+
unless session[:carapace_private_key]
|
32
|
+
key = RSA.new(key_length)
|
33
|
+
session[:carapace_private_key] = key.to_s
|
34
|
+
session[:carapace_public_modulus] = key.public_key.n.to_s(base=16)
|
35
|
+
session[:carapace_public_exponent] = key.public_key.e.to_s(base=16)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Decrypt a string. The return value is the decrypted string.
|
40
|
+
# If the string was not encrypted by the browser it is returned as-is
|
41
|
+
# unless the force_decrypt parameter is given as CARAPACE_FORCE_DECRYPT
|
42
|
+
# in which case nil is returned
|
43
|
+
#
|
44
|
+
# CARAPACE_FORCE_DECRYPT can be used to protect against accepting plaintext
|
45
|
+
# transmissions when the user's browser has Javascript disabled.
|
46
|
+
#
|
47
|
+
def carapace_decrypt(string, force_decrypt=false) #:doc:
|
48
|
+
if carapace_enabled? then # only decrypt if browser was enabled
|
49
|
+
byte = 0 # the converted byte will go here
|
50
|
+
s = "".rjust(string.length/2) # string to receive converted bytes
|
51
|
+
0.upto(string.length-1) do |i| # iterate through string one chr at a time
|
52
|
+
ch = string[i].chr # current character
|
53
|
+
nibble = HEX[ch] || ch.to_i # converted to its binary value
|
54
|
+
if i%2 == 0 then
|
55
|
+
byte = nibble << 4 # most significant nibble is bits 5-8
|
56
|
+
else
|
57
|
+
byte += nibble # lease significant nibble is bits 1-4
|
58
|
+
s[i/2] = byte.chr # store the converted byte
|
59
|
+
end
|
60
|
+
end
|
61
|
+
RSA.new(session[:carapace_private_key],nil).private_decrypt(s) # perform the decryption
|
62
|
+
else
|
63
|
+
force_decrypt ? nil : string # input is unencrypted - return input
|
64
|
+
end # return error if decryption was forced
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
# Decrypt a string. The return value is the decrypted string
|
69
|
+
# The string is decrypted in-situ, meaning its value is modified
|
70
|
+
# (warning, this does not call any customer accessor (e.g. "password=")
|
71
|
+
# so any custom code (such as password hashing) will not execute.)
|
72
|
+
#
|
73
|
+
def carapace_decrypt!(string, force_decrypt=false) #:doc:
|
74
|
+
decrypted_string = carapace_decrypt(string, force_decrypt)
|
75
|
+
string.replace decrypted_string unless !decrypted_string
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Helper method for use in the view rhtml to insert Carapace Javascript
|
81
|
+
# The javascript is added to a page once, no matter how often this is called.
|
82
|
+
#
|
83
|
+
def carapace_javascript #:doc:
|
84
|
+
unless @carapace_javascript_written
|
85
|
+
session[:carapace_nonce] = Time.now.to_i.to_s.reverse.crypt(rand.to_s.reverse[0,2])
|
86
|
+
@carapace_javascript_written = true
|
87
|
+
return "<script type='text/javascript'>
|
88
|
+
carapace_modulus = \"#{session[:carapace_public_modulus]}\" ;
|
89
|
+
carapace_exponent = \"#{session[:carapace_public_exponent]}\" ;
|
90
|
+
document.cookie = \"carapace_nonce=#{session[:carapace_nonce]}; path=/\";
|
91
|
+
//alert(\"Session:#{session[:carapace_nonce]}\\nCookie:\"+document.cookie)
|
92
|
+
rsa = new RSAKey();
|
93
|
+
rsa.setPublic(carapace_modulus, carapace_exponent);
|
94
|
+
|
95
|
+
function carapace_encrypt(field)
|
96
|
+
{
|
97
|
+
field.value = rsa.encrypt(field.value);
|
98
|
+
}
|
99
|
+
</script>".html_safe
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns TRUE if Carapace was enabled on the view. This does not mean that
|
104
|
+
# data was encrypted, just that Carapace Javascript was executed by the
|
105
|
+
# user's browser, making the Carapace encryption services available. This
|
106
|
+
# will be TRUE if everything is set up correctly AND the user's browser has
|
107
|
+
# Javascript enabled
|
108
|
+
#
|
109
|
+
# This can be used to protect against accepting plaintext
|
110
|
+
# transmissions when the user's browser has Javascript disabled.
|
111
|
+
#
|
112
|
+
def carapace_enabled? #:doc:
|
113
|
+
cookies["carapace_nonce"]==session[:carapace_nonce]
|
114
|
+
end
|
115
|
+
|
116
|
+
# This is called when Carapace is included in a controller.
|
117
|
+
# It automatically sets upn the Carapace Javascript helper.
|
118
|
+
def self.included(c)
|
119
|
+
#c.RAILS_DEFAULT_LOGGER.debug "Carapace has been included by #{c.class}"
|
120
|
+
if (c.class == Class)
|
121
|
+
c.helper_method :carapace_javascript
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|