certify 0.0.2

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