carapace 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/CHANGELOG.md +31 -14
  2. data/Gemfile +17 -0
  3. data/README.md +36 -32
  4. data/Rakefile +32 -2
  5. data/carapace.gemspec +29 -0
  6. data/lib/carapace.rb +2 -124
  7. data/lib/carapace/carapace.rb +124 -0
  8. data/lib/carapace/engine.rb +7 -0
  9. data/lib/carapace/version.rb +3 -0
  10. data/lib/tasks/carapace_tasks.rake +4 -0
  11. data/test/dummy/README.md +134 -0
  12. data/test/{rails_app → dummy}/Rakefile +3 -6
  13. data/test/dummy/app/assets/javascripts/application.js +15 -0
  14. data/test/dummy/app/assets/javascripts/message.js +2 -0
  15. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  16. data/test/dummy/app/assets/stylesheets/message.css +4 -0
  17. data/test/dummy/app/controllers/application_controller.rb +3 -0
  18. data/test/{rails_app → dummy}/app/controllers/message_controller.rb +0 -0
  19. data/test/dummy/app/helpers/application_helper.rb +2 -0
  20. data/test/{rails_app → dummy}/app/helpers/message_helper.rb +0 -0
  21. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  22. data/test/{rails_app → dummy}/app/views/message/index.html.erb +1 -1
  23. data/test/dummy/config.ru +4 -0
  24. data/test/dummy/config/application.rb +59 -0
  25. data/test/dummy/config/boot.rb +10 -0
  26. data/test/{rails_app → dummy}/config/database.yml +9 -3
  27. data/test/dummy/config/environment.rb +5 -0
  28. data/test/dummy/config/environments/development.rb +37 -0
  29. data/test/dummy/config/environments/production.rb +67 -0
  30. data/test/dummy/config/environments/test.rb +37 -0
  31. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  32. data/test/{rails_app → dummy}/config/initializers/inflections.rb +7 -2
  33. data/test/{rails_app → dummy}/config/initializers/mime_types.rb +0 -0
  34. data/test/dummy/config/initializers/secret_token.rb +7 -0
  35. data/test/dummy/config/initializers/session_store.rb +8 -0
  36. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  37. data/test/dummy/config/locales/en.yml +5 -0
  38. data/test/dummy/config/routes.rb +61 -0
  39. data/test/dummy/db/development.sqlite3 +0 -0
  40. data/test/dummy/log/development.log +742 -0
  41. data/test/dummy/log/test.log +27 -0
  42. data/test/dummy/public/404.html +26 -0
  43. data/test/dummy/public/422.html +26 -0
  44. data/test/dummy/public/500.html +25 -0
  45. data/test/{rails_app → dummy}/public/favicon.ico +0 -0
  46. data/test/dummy/script/rails +6 -0
  47. data/test/{rails_app → dummy}/test/functional/message_controller_test.rb +3 -5
  48. data/test/dummy/test/unit/helpers/message_helper_test.rb +4 -0
  49. data/test/dummy/tmp/cache/assets/C78/9E0/sprockets%2F8172886cba8a1911b217c81605b19e14 +0 -0
  50. data/test/dummy/tmp/cache/assets/CD3/C80/sprockets%2F60a4ed28b40070af1a35a65086d3758f +0 -0
  51. data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  52. data/test/dummy/tmp/cache/assets/D08/C80/sprockets%2Fcb11b48a42f94e0db70f194493a32c77 +0 -0
  53. data/test/dummy/tmp/cache/assets/D30/D70/sprockets%2Ffba6ea9d0d74a2071065123308daec69 +0 -0
  54. data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  55. data/test/dummy/tmp/cache/assets/D42/790/sprockets%2F63f423d2fb157e98fb0d8ee89c0351a1 +0 -0
  56. data/test/dummy/tmp/cache/assets/D4C/AD0/sprockets%2F1a9dcbbb7774e26a180893a79bb0889f +0 -0
  57. data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  58. data/test/{rails_app/public/javascripts/carapace.js → dummy/tmp/cache/assets/D55/0F0/sprockets%2Fec9774e5f33cb737f35ee3aa8257963e} +0 -0
  59. data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  60. data/test/dummy/tmp/cache/assets/D88/4B0/sprockets%2Fdc0cf832aa65e1e6dbda9551c17120c1 +0 -0
  61. data/test/dummy/tmp/cache/assets/D8B/E80/sprockets%2Fd0d64e037bd6d546f0b09a25b2cc24db +0 -0
  62. data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  63. data/test/dummy/tmp/cache/assets/E02/120/sprockets%2F73ff50f3f5d1f01c2ee1bedfe4e56d67 +0 -0
  64. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  65. data/test/dummy/tmp/cache/assets/E0D/340/sprockets%2Fb7e1e6b8d949eef8a343b78da5f07bae +0 -0
  66. data/test/integration/static_asset_test.rb +8 -0
  67. data/test/test_helper.rb +14 -0
  68. data/{rails_generators/templates → vendor/assets/javascripts}/carapace.js +0 -0
  69. metadata +194 -57
  70. data/rails_generators/USAGE +0 -7
  71. data/rails_generators/carapace_generator.rb +0 -7
  72. data/test/rails_app/README.md +0 -130
  73. data/test/rails_app/app/controllers/application.rb +0 -10
  74. data/test/rails_app/app/helpers/application_helper.rb +0 -3
  75. data/test/rails_app/config/boot.rb +0 -109
  76. data/test/rails_app/config/environment.rb +0 -60
  77. data/test/rails_app/config/environments/development.rb +0 -18
  78. data/test/rails_app/config/environments/production.rb +0 -19
  79. data/test/rails_app/config/environments/test.rb +0 -22
  80. data/test/rails_app/config/routes.rb +0 -35
  81. data/test/rails_app/doc/README_FOR_APP +0 -2
  82. data/test/rails_app/public/404.html +0 -30
  83. data/test/rails_app/public/422.html +0 -30
  84. data/test/rails_app/public/500.html +0 -30
  85. data/test/rails_app/public/dispatch.cgi +0 -10
  86. data/test/rails_app/public/dispatch.fcgi +0 -24
  87. data/test/rails_app/public/dispatch.rb +0 -10
  88. data/test/rails_app/public/images/rails.png +0 -0
  89. data/test/rails_app/public/javascripts/application.js +0 -2
  90. data/test/rails_app/public/javascripts/controls.js +0 -963
  91. data/test/rails_app/public/javascripts/dragdrop.js +0 -972
  92. data/test/rails_app/public/javascripts/effects.js +0 -1120
  93. data/test/rails_app/public/javascripts/prototype.js +0 -4225
  94. data/test/rails_app/public/robots.txt +0 -5
  95. data/test/rails_app/script/about +0 -3
  96. data/test/rails_app/script/console +0 -3
  97. data/test/rails_app/script/destroy +0 -3
  98. data/test/rails_app/script/generate +0 -3
  99. data/test/rails_app/script/performance/benchmarker +0 -3
  100. data/test/rails_app/script/performance/profiler +0 -3
  101. data/test/rails_app/script/performance/request +0 -3
  102. data/test/rails_app/script/plugin +0 -3
  103. data/test/rails_app/script/process/inspector +0 -3
  104. data/test/rails_app/script/process/reaper +0 -3
  105. data/test/rails_app/script/process/spawner +0 -3
  106. data/test/rails_app/script/runner +0 -3
  107. data/test/rails_app/script/server +0 -3
  108. data/test/rails_app/test/test_helper.rb +0 -38
@@ -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
- `script/server`, `config/environment.rb` and `config/environments/development/rb`
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 "rake rails:update"
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
- Remove redundant module namespace in Cipher, Digest, PKCS7, PKCS12.
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
- Install it:
13
+ **This gem is for Rails 3.x. For Rails 2.x please use Carapace 0.1.2.**
14
14
 
15
- $ gem install carapace
15
+ 1. Add it to your Gemfile:
16
16
 
17
- Configure your rails 2.x application:
17
+ gem carapace
18
18
 
19
- $ script/generate carapace
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
- <%= javascript_include_tag 'carapace.js' %>
26
- <%= carapace_javascript %>
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
- function onSubmit()
32
- {
33
- carapace_encrypt(document.getElementById("user_password"));
34
- }
36
+ function onSubmit()
37
+ {
38
+ carapace_encrypt(document.getElementById("user_password"));
39
+ }
35
40
 
36
- Then, configure the form's "submit" button to call it:
41
+ Then, configure the form's `submit` button to call it:
37
42
 
38
- <%= submit_tag "Add User", :class => "submit", :onclick => "onSubmit()" %>
43
+ <%= submit_tag "Add User", :class => "submit", :onclick => "onSubmit()" %>
39
44
 
40
- On the server, mix Carapace into a Rails controller (ApplicationController) class:
45
+ On the server, mix Carapace into a Rails controller (_ApplicationController_) class:
41
46
 
42
- require 'carapace'
43
- include Carapace
47
+ require 'carapace'
48
+ include Carapace
44
49
 
45
50
  Then use Carapace from within action methods:
46
51
 
47
- def index
48
- carapace_session
49
- if request.post?
50
- @message=params[:message]
51
- carapace_decrypt! @message
52
- end
53
- end
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\rails_app` for further testing and education. See `test\rails_app\README.md`
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 LICENCE\_JSBN).
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
- desc "Run tests"
37
+
8
38
  task :default => :test
@@ -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
@@ -1,124 +1,2 @@
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>"
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