certify 0.0.2

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.
Files changed (98) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +55 -0
  4. data/app/assets/javascripts/certify/application.js +15 -0
  5. data/app/assets/javascripts/certify/authorities.js +2 -0
  6. data/app/assets/javascripts/certify/certificates.js +2 -0
  7. data/app/assets/stylesheets/certify/application.css +13 -0
  8. data/app/assets/stylesheets/certify/authorities.css +4 -0
  9. data/app/assets/stylesheets/certify/certificates.css +4 -0
  10. data/app/assets/stylesheets/scaffold.css +56 -0
  11. data/app/controllers/certify/application_controller.rb +4 -0
  12. data/app/controllers/certify/authorities_controller.rb +64 -0
  13. data/app/controllers/certify/certificates_controller.rb +70 -0
  14. data/app/helpers/certify/application_helper.rb +4 -0
  15. data/app/helpers/certify/authorities_helper.rb +4 -0
  16. data/app/helpers/certify/certificates_helper.rb +4 -0
  17. data/app/models/certify/authority.rb +133 -0
  18. data/app/models/certify/certificate.rb +51 -0
  19. data/app/views/certify/authorities/_form.html.erb +45 -0
  20. data/app/views/certify/authorities/index.html.erb +24 -0
  21. data/app/views/certify/authorities/new.html.erb +5 -0
  22. data/app/views/certify/authorities/show.html.erb +61 -0
  23. data/app/views/certify/certificates/_form.html.erb +29 -0
  24. data/app/views/certify/certificates/edit.html.erb +6 -0
  25. data/app/views/certify/certificates/new.html.erb +24 -0
  26. data/app/views/certify/certificates/show.html.erb +18 -0
  27. data/app/views/layouts/certify/application.html.erb +14 -0
  28. data/config/initializers/certify_helpers.rb +7 -0
  29. data/config/routes.rb +10 -0
  30. data/db/migrate/20120421191150_create_certify_authorities.rb +10 -0
  31. data/db/migrate/20120421193104_create_certify_certificates.rb +11 -0
  32. data/lib/certify/engine.rb +5 -0
  33. data/lib/certify/version.rb +3 -0
  34. data/lib/certify.rb +4 -0
  35. data/lib/tasks/certify_tasks.rake +4 -0
  36. data/test/certify_test.rb +7 -0
  37. data/test/dummy/README.rdoc +261 -0
  38. data/test/dummy/Rakefile +7 -0
  39. data/test/dummy/app/assets/javascripts/application.js +15 -0
  40. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  41. data/test/dummy/app/controllers/application_controller.rb +3 -0
  42. data/test/dummy/app/helpers/application_helper.rb +2 -0
  43. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  44. data/test/dummy/config/application.rb +56 -0
  45. data/test/dummy/config/boot.rb +10 -0
  46. data/test/dummy/config/database.yml +25 -0
  47. data/test/dummy/config/environment.rb +5 -0
  48. data/test/dummy/config/environments/development.rb +37 -0
  49. data/test/dummy/config/environments/production.rb +67 -0
  50. data/test/dummy/config/environments/test.rb +37 -0
  51. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  52. data/test/dummy/config/initializers/inflections.rb +15 -0
  53. data/test/dummy/config/initializers/mime_types.rb +5 -0
  54. data/test/dummy/config/initializers/secret_token.rb +7 -0
  55. data/test/dummy/config/initializers/session_store.rb +8 -0
  56. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  57. data/test/dummy/config/locales/en.yml +5 -0
  58. data/test/dummy/config/routes.rb +4 -0
  59. data/test/dummy/config.ru +4 -0
  60. data/test/dummy/db/development.sqlite3 +0 -0
  61. data/test/dummy/db/schema.rb +32 -0
  62. data/test/dummy/db/test.sqlite3 +0 -0
  63. data/test/dummy/log/development.log +7598 -0
  64. data/test/dummy/log/test.log +219 -0
  65. data/test/dummy/public/404.html +26 -0
  66. data/test/dummy/public/422.html +26 -0
  67. data/test/dummy/public/500.html +25 -0
  68. data/test/dummy/public/favicon.ico +0 -0
  69. data/test/dummy/script/rails +6 -0
  70. data/test/dummy/tmp/cache/assets/CB6/030/sprockets%2F775fc1bd751301d4927737b307c89ac7 +0 -0
  71. data/test/dummy/tmp/cache/assets/CB9/AE0/sprockets%2F4a4ada8738e3e94519b45230993e362f +0 -0
  72. data/test/dummy/tmp/cache/assets/D13/A70/sprockets%2F9a0b998930150626fe3b797bbd12dfd1 +0 -0
  73. data/test/dummy/tmp/cache/assets/D16/EC0/sprockets%2F8bab9b8821aa75f983875a4bd01588b0 +0 -0
  74. data/test/dummy/tmp/cache/assets/D19/FE0/sprockets%2Fd328975fb93d34ecd25215acc964076f +0 -0
  75. data/test/dummy/tmp/cache/assets/D1B/170/sprockets%2Fafe11ecf2cc7a6f6678864f884501424 +0 -0
  76. data/test/dummy/tmp/cache/assets/D1C/B20/sprockets%2F00670b9787d694f37cb29eefe470ca61 +0 -0
  77. data/test/dummy/tmp/cache/assets/D27/4B0/sprockets%2F7a813da99da2f1f34f1ce3c0031e1240 +0 -0
  78. data/test/dummy/tmp/cache/assets/D3D/FB0/sprockets%2Fc0702248e63540fef5eae5f55f3eb541 +0 -0
  79. data/test/dummy/tmp/cache/assets/D44/9C0/sprockets%2F059b7f1796e5ecacb822b01b3d86992b +0 -0
  80. data/test/dummy/tmp/cache/assets/D44/D90/sprockets%2Fe8c4cd2cadb7097c6330b29298840a9e +0 -0
  81. data/test/dummy/tmp/cache/assets/D45/9E0/sprockets%2Ff00a8d8913f43c497ea6c062519cef7b +0 -0
  82. data/test/dummy/tmp/cache/assets/D62/DF0/sprockets%2F3acf41c1f03d1d25f94944d7616ac3ac +0 -0
  83. data/test/dummy/tmp/cache/assets/D65/3F0/sprockets%2F98a86ab032e4ae420ba5e53730af6ed7 +0 -0
  84. data/test/dummy/tmp/cache/assets/D92/F80/sprockets%2Fbaf0af64d62bd10af2761f52f4c42f57 +0 -0
  85. data/test/dummy/tmp/cache/assets/DDB/300/sprockets%2F592980ebf604de84ff6e4dc63aff51bb +0 -0
  86. data/test/dummy/tmp/cache/assets/E14/280/sprockets%2Febb1c4d0a16a2df2c9e7bdd6c0053a7a +0 -0
  87. data/test/dummy/tmp/cache/assets/E60/490/sprockets%2F17edcb20bffd48ab56be79dc15fad6b9 +0 -0
  88. data/test/fixtures/certify/authorities.yml +0 -0
  89. data/test/fixtures/certify/certificates.yml +0 -0
  90. data/test/functional/certify/authorities_controller_test.rb +7 -0
  91. data/test/functional/certify/certificates_controller_test.rb +7 -0
  92. data/test/integration/navigation_test.rb +6 -0
  93. data/test/test_helper.rb +15 -0
  94. data/test/unit/certify/authority_test.rb +20 -0
  95. data/test/unit/certify/certificate_test.rb +39 -0
  96. data/test/unit/helpers/certify/authorities_helper_test.rb +6 -0
  97. data/test/unit/helpers/certify/certificates_helper_test.rb +6 -0
  98. metadata +238 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = Certify
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,55 @@
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 = 'Certify'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
41
+
42
+ begin
43
+ require 'jeweler'
44
+ Jeweler::Tasks.new do |gemspec|
45
+ gemspec.name = "uniquify"
46
+ gemspec.summary = "Generate a unique token with Active Record."
47
+ gemspec.description = "Generate a unique token with Active Record."
48
+ gemspec.email = "ryan@railscasts.com"
49
+ gemspec.homepage = "http://github.com/ryanb/uniquify"
50
+ gemspec.authors = ["Ryan Bates"]
51
+ end
52
+ Jeweler::GemcutterTasks.new
53
+ rescue LoadError
54
+ puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
55
+ end
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,56 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ div.field, div.actions {
20
+ margin-bottom: 10px;
21
+ }
22
+
23
+ #notice {
24
+ color: green;
25
+ }
26
+
27
+ .field_with_errors {
28
+ padding: 2px;
29
+ background-color: red;
30
+ display: table;
31
+ }
32
+
33
+ #error_explanation {
34
+ width: 450px;
35
+ border: 2px solid red;
36
+ padding: 7px;
37
+ padding-bottom: 0;
38
+ margin-bottom: 20px;
39
+ background-color: #f0f0f0;
40
+ }
41
+
42
+ #error_explanation h2 {
43
+ text-align: left;
44
+ font-weight: bold;
45
+ padding: 5px 5px 5px 15px;
46
+ font-size: 12px;
47
+ margin: -7px;
48
+ margin-bottom: 0px;
49
+ background-color: #c00;
50
+ color: #fff;
51
+ }
52
+
53
+ #error_explanation ul li {
54
+ font-size: 12px;
55
+ list-style: square;
56
+ }
@@ -0,0 +1,4 @@
1
+ module Certify
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,64 @@
1
+ module Certify
2
+ class AuthoritiesController < ApplicationController
3
+ # GET /authorities
4
+ # GET /authorities.json
5
+ def index
6
+ @authorities = Authority.all
7
+
8
+ respond_to do |format|
9
+ format.html # _certificate_overview.html.erb
10
+ format.json { render json: @authorities }
11
+ end
12
+ end
13
+
14
+ # GET /authorities/1
15
+ # GET /authorities/1.json
16
+ def show
17
+ @authority = Authority.find(params[:id])
18
+
19
+ respond_to do |format|
20
+ format.html # show.html.erb
21
+ format.json { render json: @authority }
22
+ end
23
+ end
24
+
25
+ # GET /authorities/new
26
+ # GET /authorities/new.json
27
+ def new
28
+ @authority = Authority.new
29
+
30
+ respond_to do |format|
31
+ format.html # new.html.erb
32
+ format.json { render json: @authority }
33
+ end
34
+ end
35
+
36
+ # POST /authorities
37
+ # POST /authorities.json
38
+ def create
39
+ @authority = Authority.new(params[:authority])
40
+
41
+ respond_to do |format|
42
+ if @authority.save
43
+ format.html { redirect_to @authority, notice: 'Authority was successfully created.' }
44
+ format.json { render json: @authority, status: :created, location: @authority }
45
+ else
46
+ format.html { render action: "new" }
47
+ format.json { render json: @authority.errors, status: :unprocessable_entity }
48
+ end
49
+ end
50
+ end
51
+
52
+ # DELETE /authorities/1
53
+ # DELETE /authorities/1.json
54
+ def destroy
55
+ @authority = Authority.find(params[:id])
56
+ @authority.destroy
57
+
58
+ respond_to do |format|
59
+ format.html { redirect_to authorities_url }
60
+ format.json { head :no_content }
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,70 @@
1
+ module Certify
2
+ class CertificatesController < ApplicationController
3
+
4
+ # GET /certificates/1
5
+ # GET /certificates/1.json
6
+ def show
7
+ @certificate = Certificate.find(params[:id])
8
+
9
+ respond_to do |format|
10
+ format.html # show.html.erb
11
+ format.json { render json: @certificate }
12
+ end
13
+ end
14
+
15
+ # GET /certificates/new
16
+ # GET /certificates/new.json
17
+ def new
18
+ # get the authority
19
+ @authority = Authority.find(params[:certify_authority_id])
20
+
21
+ # generate a new one
22
+ @certificate = Certificate.new()
23
+
24
+ respond_to do |format|
25
+ format.html # new.html.erb
26
+ format.json { render json: @certificate }
27
+ end
28
+ end
29
+
30
+ # POST /certificates
31
+ # POST /certificates.json
32
+ def create
33
+ # get the ca
34
+ @authority = Authority.find(params[:certify_authority_id])
35
+
36
+ # create the cert
37
+ @certificate = @authority.certificates.build()
38
+
39
+ # apply the csr
40
+ @certificate.csr=params[:csr]
41
+
42
+ # format
43
+ respond_to do |format|
44
+ if @certificate.save
45
+ format.html { redirect_to authority_path(@authority), notice: 'Certificate was successfully created.' }
46
+ format.json { render json: @certificate, status: :created, location: @certificate }
47
+ else
48
+ format.html { render action: "new" }
49
+ format.json { render json: @certificate.errors, status: :unprocessable_entity }
50
+ end
51
+ end
52
+ end
53
+
54
+ # DELETE /certificates/1
55
+ # DELETE /certificates/1.json
56
+ def destroy
57
+ # get the ca
58
+ @authority = Authority.find(params[:certify_authority_id])
59
+
60
+ # get the certificate
61
+ @certificate = Certificate.find(params[:id])
62
+ @certificate.destroy
63
+
64
+ respond_to do |format|
65
+ format.html { redirect_to authority_path(@authority), notice: 'Certificate removed' }
66
+ format.json { head :no_content }
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,4 @@
1
+ module Certify
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Certify
2
+ module AuthoritiesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Certify
2
+ module CertificatesHelper
3
+ end
4
+ end
@@ -0,0 +1,133 @@
1
+ module Certify
2
+ class Authority < ActiveRecord::Base
3
+ # make this attributes accessable in forms and so on
4
+ attr_accessible :commonname, :organization, :city, :state, :country, :email
5
+
6
+ # virtual attributes
7
+ attr_writer :commonname, :organization, :city, :state, :country, :email
8
+
9
+ # associations
10
+ has_many :certificates, :dependent => :destroy, :inverse_of => :authority
11
+
12
+ # validates
13
+ validates :uniqueid, :uniqueness => true
14
+ validates :commonname, :city, :state, :country, :organization, :email, :presence => true
15
+ validates_format_of :commonname, :with => /^[\w\-@]*$/, :message => "Only letters or numbers allowed"
16
+ validates_length_of :country, :maximum => 2
17
+ validates_format_of :country, :with => /^[a-zA-Z]*$/, :message => "Only letters allowed"
18
+ validates_email_format_of :email
19
+
20
+ # handler
21
+ after_initialize :generate_unique_id
22
+ before_create :generate_new_ca
23
+
24
+ # property accessors
25
+ def private_key
26
+ OpenSSL::PKey::RSA.new(self.rsakey) if self.rsakey
27
+ end
28
+
29
+ def root_certificate
30
+ OpenSSL::X509::Certificate.new(self.sslcert) if self.sslcert
31
+ end
32
+
33
+ def commonname
34
+ if root_certificate
35
+ subject_hash["CN"]
36
+ else
37
+ @commonname
38
+ end
39
+ end
40
+
41
+ def organization
42
+ if root_certificate
43
+ subject_hash["O"]
44
+ else
45
+ @organization
46
+ end
47
+ end
48
+
49
+ def city
50
+ if root_certificate
51
+ subject_hash["L"]
52
+ else
53
+ @city
54
+ end
55
+ end
56
+
57
+ def state
58
+ if root_certificate
59
+ subject_hash["ST"]
60
+ else
61
+ @state
62
+ end
63
+ end
64
+
65
+ def country
66
+ if root_certificate
67
+ subject_hash["C"]
68
+ else
69
+ @country
70
+ end
71
+ end
72
+
73
+ def email
74
+ if root_certificate
75
+ subject_hash["emailAddress"]
76
+ else
77
+ @email
78
+ end
79
+ end
80
+
81
+ #
82
+ # This method builds the subject hash from the x509 name
83
+ def subject_hash
84
+ # get the array from the name
85
+ dataArray = self.root_certificate.subject.to_a
86
+
87
+ # create the result hash
88
+ dataHash = Hash.new()
89
+
90
+ # go through
91
+ dataArray.each do |item|
92
+ dataHash[item[0]] = item[1]
93
+ end
94
+
95
+ # emit
96
+ dataHash
97
+ end
98
+
99
+ # builds a new CA
100
+ def generate_new_ca()
101
+ # generate the root key pair
102
+ root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
103
+ self.rsakey = root_key.to_pem
104
+
105
+ # generate the CA name
106
+ ca_name_str = "/C=#{country}/ST=#{state}/O=#{organization}/L=#{city}/CN=#{commonname}/emailAddress=#{email}"
107
+
108
+ # parse the name
109
+ ca_name = OpenSSL::X509::Name.parse ca_name_str
110
+
111
+ # generate the root certificate
112
+ root_ca = OpenSSL::X509::Certificate.new
113
+ root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
114
+ root_ca.serial = 1
115
+ root_ca.subject = ca_name
116
+ root_ca.issuer = root_ca.subject # root CA's are "self-signed"
117
+ root_ca.public_key = root_key.public_key
118
+ root_ca.not_before = Time.now
119
+ root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
120
+ ef = OpenSSL::X509::ExtensionFactory.new
121
+ ef.subject_certificate = root_ca
122
+ ef.issuer_certificate = root_ca
123
+ root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
124
+ root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
125
+ root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
126
+ root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
127
+ root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
128
+
129
+ # store the root ca
130
+ self.sslcert = root_ca.to_pem
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,51 @@
1
+ module Certify
2
+ class Certificate < ActiveRecord::Base
3
+ # accessor
4
+ attr_accessible :certify_authority, :ssldata, :uniqueid
5
+
6
+ # associations
7
+ belongs_to :authority, :inverse_of => :certificates
8
+
9
+ # validates
10
+ validates :uniqueid, :uniqueness => true
11
+ validates :uniqueid, :ssldata, :presence => true
12
+
13
+ # handler
14
+ after_initialize :generate_unique_id
15
+
16
+ # set the csr where you want to generate a certificate from
17
+ def csr=(csrpem)
18
+ # read the csr
19
+ csr = OpenSSL::X509::Request.new(csrpem)
20
+
21
+ # get the ca_cert
22
+ ca = self.authority
23
+ ca_cert = ca.root_certificate
24
+ ca_key = ca.private_key
25
+
26
+ # generate a new cert
27
+ csr_cert = OpenSSL::X509::Certificate.new
28
+ csr_cert.serial = 0
29
+ csr_cert.version = 2
30
+ csr_cert.not_before = Time.now
31
+ csr_cert.not_after = Time.now + 600
32
+
33
+ csr_cert.subject = csr.subject
34
+ csr_cert.public_key = csr.public_key
35
+ csr_cert.issuer = ca_cert.subject
36
+
37
+ extension_factory = OpenSSL::X509::ExtensionFactory.new
38
+ extension_factory.subject_certificate = csr_cert
39
+ extension_factory.issuer_certificate = ca_cert
40
+
41
+ extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
42
+ extension_factory.create_extension 'keyUsage',
43
+ 'keyEncipherment,dataEncipherment,digitalSignature'
44
+ extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
45
+
46
+ csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
47
+
48
+ self.ssldata = csr_cert.to_pem
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,45 @@
1
+ <%= form_for(@authority) do |f| %>
2
+ <% if @authority.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@authority.errors.count, "error") %> prohibited this certificate_authority from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @authority.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :uniqueid %><br />
16
+ <%= f.text_field :uniqueid, :disabled => true %>
17
+ </div>
18
+ <div class="field">
19
+ <%= f.label :commonname %><br />
20
+ <%= f.text_field :commonname %>
21
+ </div>
22
+ <div class="field">
23
+ <%= f.label :organization %><br />
24
+ <%= f.text_field :organization %>
25
+ </div>
26
+ <div class="field">
27
+ <%= f.label :city %><br />
28
+ <%= f.text_field :city %>
29
+ </div>
30
+ <div class="field">
31
+ <%= f.label :state %><br />
32
+ <%= f.text_field :state %>
33
+ </div>
34
+ <div class="field">
35
+ <%= f.label :country %><br />
36
+ <%= f.text_field :country %>
37
+ </div>
38
+ <div class="field">
39
+ <%= f.label :email %><br />
40
+ <%= f.text_field :email %>
41
+ </div>
42
+ <div class="actions">
43
+ <%= f.submit %>
44
+ </div>
45
+ <% end %>
@@ -0,0 +1,24 @@
1
+ <h1>Existing Certificate Authorities</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Commonname</th>
6
+ <th>Organization</th>
7
+ <th>Email</th>
8
+ <th></th>
9
+ <th></th>
10
+ </tr>
11
+
12
+ <% @authorities.each do |authority| %>
13
+ <tr>
14
+ <td><%= link_to authority.commonname , authority %></td>
15
+ <td><%= authority.organization %></td>
16
+ <td><%= authority.email %></td>
17
+ <td><%= link_to 'Destroy', authority, confirm: 'Are you sure?', method: :delete %></td>
18
+ </tr>
19
+ <% end %>
20
+ </table>
21
+
22
+ <br />
23
+
24
+ <%= link_to 'New Certificate authority', new_authority_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New Certificate Authority</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', authorities_path %>
@@ -0,0 +1,61 @@
1
+ <h1><%= @authority.organization %> (<%= @authority.commonname %>)</h1>
2
+ <p id="notice"><%= notice %></p>
3
+
4
+ <p>
5
+ <b>Unique:</b>
6
+ <%= @authority.uniqueid %>
7
+ </p>
8
+
9
+ <p>
10
+ <b>City:</b>
11
+ <%= @authority.city %>
12
+ </p>
13
+
14
+ <p>
15
+ <b>State:</b>
16
+ <%= @authority.state %>
17
+ </p>
18
+
19
+ <p>
20
+ <b>Country:</b>
21
+ <%= @authority.country %>
22
+ </p>
23
+
24
+ <p>
25
+ <b>Email:</b>
26
+ <%= @authority.email %>
27
+ </p>
28
+
29
+ <p>
30
+ <b>Private-Key:</b>
31
+ <%= @authority.private_key.to_pem %>
32
+ </p>
33
+
34
+ <p>
35
+ <b>Root-Certificate:</b>
36
+ <%= @authority.root_certificate.to_pem %>
37
+ </p>
38
+
39
+ <h1>Listing certificates</h1>
40
+
41
+ <table>
42
+ <tr>
43
+ <th>Uniqueid</th>
44
+ <th>Ssldata</th>
45
+ <th></th>
46
+ <th></th>
47
+ </tr>
48
+
49
+ <% @authority.certificates.each do |certificate| %>
50
+ <tr>
51
+ <td><%= certificate.uniqueid %></td>
52
+ <td><%= certificate.ssldata %></td>
53
+ <td><%= link_to 'Show', certificate_path(certificate, :certify_authority_id => certificate.authority)%></td>
54
+ <td><%= link_to 'Destroy', certificate_path(certificate, :certify_authority_id => certificate.authority), confirm: 'Are you sure?', method: :delete %></td>
55
+ </tr>
56
+ <% end %>
57
+ </table>
58
+ <BR/>
59
+
60
+ <%= link_to 'Add Certificate', new_certificate_path(@authority) %> |
61
+ <%= link_to 'Back', authorities_path %>