r509-ca-http 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/Rakefile +18 -18
  2. data/doc/R509/CertificateAuthority/Http/Factory/CsrFactory.html +11 -11
  3. data/doc/R509/CertificateAuthority/Http/Factory/SpkiFactory.html +11 -11
  4. data/doc/R509/CertificateAuthority/Http/Factory.html +9 -9
  5. data/doc/R509/CertificateAuthority/Http/Server.html +9 -9
  6. data/doc/R509/CertificateAuthority/Http/SubjectParser.html +22 -22
  7. data/doc/R509/CertificateAuthority/Http/ValidityPeriodConverter.html +19 -19
  8. data/doc/R509/CertificateAuthority/Http.html +11 -11
  9. data/doc/R509/CertificateAuthority.html +6 -6
  10. data/doc/R509.html +5 -5
  11. data/doc/_index.html +21 -21
  12. data/doc/class_list.html +2 -2
  13. data/doc/css/style.css +10 -0
  14. data/doc/file.README.html +7 -7
  15. data/doc/file_list.html +1 -1
  16. data/doc/frames.html +1 -1
  17. data/doc/index.html +7 -7
  18. data/doc/js/full_list.js +6 -1
  19. data/doc/method_list.html +10 -20
  20. data/doc/top-level-namespace.html +5 -5
  21. data/lib/r509/certificateauthority/http/factory.rb +12 -12
  22. data/lib/r509/certificateauthority/http/server.rb +219 -223
  23. data/lib/r509/certificateauthority/http/subjectparser.rb +27 -27
  24. data/lib/r509/certificateauthority/http/validityperiodconverter.rb +14 -14
  25. data/lib/r509/certificateauthority/http/version.rb +4 -4
  26. data/lib/r509/certificateauthority/http/views/test_issue.erb +73 -73
  27. data/lib/r509/certificateauthority/http/views/test_revoke.erb +19 -19
  28. data/lib/r509/certificateauthority/http/views/test_unrevoke.erb +14 -14
  29. data/spec/fixtures/test_config.yaml +14 -15
  30. data/spec/http_spec.rb +235 -227
  31. data/spec/spec_helper.rb +1 -1
  32. data/spec/subject_parser_spec.rb +2 -2
  33. data/spec/validity_period_converter_spec.rb +2 -2
  34. metadata +20 -20
@@ -1,4 +1,3 @@
1
- require 'rubygems' if RUBY_VERSION < "1.9"
2
1
  require 'sinatra/base'
3
2
  require 'r509'
4
3
  require "#{File.dirname(__FILE__)}/subjectparser"
@@ -10,228 +9,225 @@ require 'logger'
10
9
  require 'dependo'
11
10
 
12
11
  module R509
13
- module CertificateAuthority
14
- module Http
15
- class Server < Sinatra::Base
16
- extend Dependo::Mixin
17
- include Dependo::Mixin
18
-
19
- configure do
20
- disable :protection #disable Rack::Protection (for speed)
21
- disable :logging
22
- set :environment, :production
23
-
24
- crls = {}
25
- certificate_authorities = {}
26
- config_pool.names.each do |name|
27
- crls[name] = R509::Crl::Administrator.new(config_pool[name])
28
- certificate_authorities[name] = R509::CertificateAuthority::Signer.new(config_pool[name])
29
- end
30
-
31
- set :crls, crls
32
- set :certificate_authorities, certificate_authorities
33
- set :subject_parser, R509::CertificateAuthority::Http::SubjectParser.new
34
- set :validity_period_converter, R509::CertificateAuthority::Http::ValidityPeriodConverter.new
35
- set :csr_factory, R509::CertificateAuthority::Http::Factory::CsrFactory.new
36
- set :spki_factory, R509::CertificateAuthority::Http::Factory::SpkiFactory.new
37
- end
38
-
39
- before do
40
- content_type :text
41
- end
42
-
43
- helpers do
44
- def crl(name)
45
- settings.crls[name]
46
- end
47
- def ca(name)
48
- settings.certificate_authorities[name]
49
- end
50
- def subject_parser
51
- settings.subject_parser
52
- end
53
- def validity_period_converter
54
- settings.validity_period_converter
55
- end
56
- def csr_factory
57
- settings.csr_factory
58
- end
59
- def spki_factory
60
- settings.spki_factory
61
- end
62
- end
63
-
64
- error do
65
- log.error env["sinatra.error"].inspect
66
- log.error env["sinatra.error"].backtrace.join("\n")
67
- "Something is amiss with our CA. You should ... wait?"
68
- end
69
-
70
- error StandardError do
71
- log.error env["sinatra.error"].inspect
72
- log.error env["sinatra.error"].backtrace.join("\n")
73
- env["sinatra.error"].inspect
74
- end
75
-
76
- get '/favicon.ico' do
77
- log.debug "go away. no children."
78
- "go away. no children"
79
- end
80
-
81
- get '/1/crl/:ca/get/?' do
82
- log.info "Get CRL for #{params[:ca]}"
83
-
84
- if not crl(params[:ca])
85
- raise ArgumentError, "CA not found"
86
- end
87
-
88
- crl(params[:ca]).to_pem
89
- end
90
-
91
- get '/1/crl/:ca/generate/?' do
92
- log.info "Generate CRL for #{params[:ca]}"
93
-
94
- if not crl(params[:ca])
95
- raise ArgumentError, "CA not found"
96
- end
97
-
98
- crl(params[:ca]).generate_crl
99
- end
100
-
101
- post '/1/certificate/issue/?' do
102
- log.info "Issue Certificate"
103
- raw = request.env["rack.input"].read
104
- env["rack.input"].rewind
105
- log.info raw
106
-
107
- log.info params.inspect
108
-
109
- if not params.has_key?("ca")
110
- raise ArgumentError, "Must provide a CA"
111
- end
112
- if not ca(params["ca"])
113
- raise ArgumentError, "CA not found"
114
- end
115
- if not params.has_key?("profile")
116
- raise ArgumentError, "Must provide a CA profile"
117
- end
118
- if not params.has_key?("validityPeriod")
119
- raise ArgumentError, "Must provide a validity period"
120
- end
121
- if not params.has_key?("csr") and not params.has_key?("spki")
122
- raise ArgumentError, "Must provide a CSR or SPKI"
123
- end
124
-
125
- subject = subject_parser.parse(raw, "subject")
126
- log.info subject.inspect
127
- log.info subject.to_s
128
- if subject.empty?
129
- raise ArgumentError, "Must provide a subject"
130
- end
131
-
132
- if params.has_key?("extensions") and params["extensions"].has_key?("subjectAlternativeName")
133
- san_names = params["extensions"]["subjectAlternativeName"].select { |name| not name.empty? }
134
- else
135
- san_names = []
136
- end
137
-
138
- data_hash = {
139
- :subject => subject,
140
- :san_names => san_names
141
- }
142
-
143
- validity_period = validity_period_converter.convert(params["validityPeriod"])
144
-
145
- if params.has_key?("csr")
146
- csr = csr_factory.build(:csr => params["csr"])
147
- cert = ca(params["ca"]).sign(
148
- :csr => csr,
149
- :profile_name => params["profile"],
150
- :data_hash => data_hash,
151
- :not_before => validity_period[:not_before],
152
- :not_after => validity_period[:not_after]
153
- )
154
- elsif params.has_key?("spki")
155
- spki = spki_factory.build(:spki => params["spki"], :subject => subject)
156
- cert = ca(params["ca"]).sign(
157
- :spki => spki,
158
- :profile_name => params["profile"],
159
- :data_hash => data_hash,
160
- :not_before => validity_period[:not_before],
161
- :not_after => validity_period[:not_after]
162
- )
163
- else
164
- raise ArgumentError, "Must provide a CSR or SPKI"
165
- end
166
-
167
- pem = cert.to_pem
168
- log.info pem
169
-
170
- pem
171
- end
172
-
173
- post '/1/certificate/revoke/?' do
174
- ca = params[:ca]
175
- serial = params[:serial]
176
- reason = params[:reason]
177
- log.info "Revoke for serial #{serial} on CA #{ca}"
178
-
179
- if not ca
180
- raise ArgumentError, "CA must be provided"
181
- end
182
- if not crl(ca)
183
- raise ArgumentError, "CA not found"
184
- end
185
- if not serial
186
- raise ArgumentError, "Serial must be provided"
187
- end
188
- if not reason
189
- reason = 0
190
- end
191
-
192
- crl(ca).revoke_cert(serial.to_i, reason.to_i)
193
-
194
- crl(ca).to_pem
195
- end
196
-
197
- post '/1/certificate/unrevoke/?' do
198
- ca = params[:ca]
199
- serial = params[:serial]
200
- log.info "Unrevoke for serial #{serial} on CA #{ca}"
201
-
202
- if not ca
203
- raise ArgumentError, "CA must be provided"
204
- end
205
- if not crl(ca)
206
- raise ArgumentError, "CA not found"
207
- end
208
- if not serial
209
- raise ArgumentError, "Serial must be provided"
210
- end
211
-
212
- crl(ca).unrevoke_cert(serial.to_i)
213
-
214
- crl(ca).to_pem
215
- end
216
-
217
- get '/test/certificate/issue/?' do
218
- log.info "Loaded test issuance interface"
219
- content_type :html
220
- erb :test_issue
221
- end
222
-
223
- get '/test/certificate/revoke/?' do
224
- log.info "Loaded test revoke interface"
225
- content_type :html
226
- erb :test_revoke
227
- end
228
-
229
- get '/test/certificate/unrevoke/?' do
230
- log.info "Loaded test unrevoke interface"
231
- content_type :html
232
- erb :test_unrevoke
233
- end
234
- end
12
+ module CertificateAuthority
13
+ module HTTP
14
+ class Server < Sinatra::Base
15
+ extend Dependo::Mixin
16
+ include Dependo::Mixin
17
+
18
+ configure do
19
+ disable :protection #disable Rack::Protection (for speed)
20
+ disable :logging
21
+ set :environment, :production
22
+
23
+ crls = {}
24
+ certificate_authorities = {}
25
+ config_pool.names.each do |name|
26
+ crls[name] = R509::CRL::Administrator.new(config_pool[name])
27
+ certificate_authorities[name] = R509::CertificateAuthority::Signer.new(config_pool[name])
28
+ end
29
+
30
+ set :crls, crls
31
+ set :certificate_authorities, certificate_authorities
32
+ set :subject_parser, R509::CertificateAuthority::HTTP::SubjectParser.new
33
+ set :validity_period_converter, R509::CertificateAuthority::HTTP::ValidityPeriodConverter.new
34
+ set :csr_factory, R509::CertificateAuthority::HTTP::Factory::CSRFactory.new
35
+ set :spki_factory, R509::CertificateAuthority::HTTP::Factory::SPKIFactory.new
235
36
  end
37
+
38
+ before do
39
+ content_type :text
40
+ end
41
+
42
+ helpers do
43
+ def crl(name)
44
+ settings.crls[name]
45
+ end
46
+ def ca(name)
47
+ settings.certificate_authorities[name]
48
+ end
49
+ def subject_parser
50
+ settings.subject_parser
51
+ end
52
+ def validity_period_converter
53
+ settings.validity_period_converter
54
+ end
55
+ def csr_factory
56
+ settings.csr_factory
57
+ end
58
+ def spki_factory
59
+ settings.spki_factory
60
+ end
61
+ end
62
+
63
+ error do
64
+ log.error env["sinatra.error"].inspect
65
+ log.error env["sinatra.error"].backtrace.join("\n")
66
+ "Something is amiss with our CA. You should ... wait?"
67
+ end
68
+
69
+ error StandardError do
70
+ log.error env["sinatra.error"].inspect
71
+ log.error env["sinatra.error"].backtrace.join("\n")
72
+ env["sinatra.error"].inspect
73
+ end
74
+
75
+ get '/favicon.ico' do
76
+ log.debug "go away. no children."
77
+ "go away. no children"
78
+ end
79
+
80
+ get '/1/crl/:ca/get/?' do
81
+ log.info "Get CRL for #{params[:ca]}"
82
+
83
+ if not crl(params[:ca])
84
+ raise ArgumentError, "CA not found"
85
+ end
86
+
87
+ crl(params[:ca]).to_pem
88
+ end
89
+
90
+ get '/1/crl/:ca/generate/?' do
91
+ log.info "Generate CRL for #{params[:ca]}"
92
+
93
+ if not crl(params[:ca])
94
+ raise ArgumentError, "CA not found"
95
+ end
96
+
97
+ crl(params[:ca]).generate_crl
98
+ end
99
+
100
+ post '/1/certificate/issue/?' do
101
+ log.info "Issue Certificate"
102
+ raw = request.env["rack.input"].read
103
+ env["rack.input"].rewind
104
+ log.info raw
105
+
106
+ log.info params.inspect
107
+
108
+ if not params.has_key?("ca")
109
+ raise ArgumentError, "Must provide a CA"
110
+ end
111
+ if not ca(params["ca"])
112
+ raise ArgumentError, "CA not found"
113
+ end
114
+ if not params.has_key?("profile")
115
+ raise ArgumentError, "Must provide a CA profile"
116
+ end
117
+ if not params.has_key?("validityPeriod")
118
+ raise ArgumentError, "Must provide a validity period"
119
+ end
120
+ if not params.has_key?("csr") and not params.has_key?("spki")
121
+ raise ArgumentError, "Must provide a CSR or SPKI"
122
+ end
123
+
124
+ subject = subject_parser.parse(raw, "subject")
125
+ log.info subject.inspect
126
+ log.info subject.to_s
127
+ if subject.empty?
128
+ raise ArgumentError, "Must provide a subject"
129
+ end
130
+
131
+ if params.has_key?("extensions") and params["extensions"].has_key?("subjectAlternativeName")
132
+ san_names = params["extensions"]["subjectAlternativeName"].select { |name| not name.empty? }
133
+ else
134
+ san_names = []
135
+ end
136
+
137
+ validity_period = validity_period_converter.convert(params["validityPeriod"])
138
+
139
+ if params.has_key?("csr")
140
+ csr = csr_factory.build(:csr => params["csr"])
141
+ cert = ca(params["ca"]).sign(
142
+ :csr => csr,
143
+ :profile_name => params["profile"],
144
+ :subject => subject,
145
+ :san_names => san_names,
146
+ :not_before => validity_period[:not_before],
147
+ :not_after => validity_period[:not_after]
148
+ )
149
+ elsif params.has_key?("spki")
150
+ spki = spki_factory.build(:spki => params["spki"], :subject => subject)
151
+ cert = ca(params["ca"]).sign(
152
+ :spki => spki,
153
+ :profile_name => params["profile"],
154
+ :subject => subject,
155
+ :san_names => san_names,
156
+ :not_before => validity_period[:not_before],
157
+ :not_after => validity_period[:not_after]
158
+ )
159
+ else
160
+ raise ArgumentError, "Must provide a CSR or SPKI"
161
+ end
162
+
163
+ pem = cert.to_pem
164
+ log.info pem
165
+
166
+ pem
167
+ end
168
+
169
+ post '/1/certificate/revoke/?' do
170
+ ca = params[:ca]
171
+ serial = params[:serial]
172
+ reason = params[:reason]
173
+ log.info "Revoke for serial #{serial} on CA #{ca}"
174
+
175
+ if not ca
176
+ raise ArgumentError, "CA must be provided"
177
+ end
178
+ if not crl(ca)
179
+ raise ArgumentError, "CA not found"
180
+ end
181
+ if not serial
182
+ raise ArgumentError, "Serial must be provided"
183
+ end
184
+ if not reason
185
+ reason = 0
186
+ end
187
+
188
+ crl(ca).revoke_cert(serial.to_i, reason.to_i)
189
+
190
+ crl(ca).crl.to_pem
191
+ end
192
+
193
+ post '/1/certificate/unrevoke/?' do
194
+ ca = params[:ca]
195
+ serial = params[:serial]
196
+ log.info "Unrevoke for serial #{serial} on CA #{ca}"
197
+
198
+ if not ca
199
+ raise ArgumentError, "CA must be provided"
200
+ end
201
+ if not crl(ca)
202
+ raise ArgumentError, "CA not found"
203
+ end
204
+ if not serial
205
+ raise ArgumentError, "Serial must be provided"
206
+ end
207
+
208
+ crl(ca).unrevoke_cert(serial.to_i)
209
+
210
+ crl(ca).crl.to_pem
211
+ end
212
+
213
+ get '/test/certificate/issue/?' do
214
+ log.info "Loaded test issuance interface"
215
+ content_type :html
216
+ erb :test_issue
217
+ end
218
+
219
+ get '/test/certificate/revoke/?' do
220
+ log.info "Loaded test revoke interface"
221
+ content_type :html
222
+ erb :test_revoke
223
+ end
224
+
225
+ get '/test/certificate/unrevoke/?' do
226
+ log.info "Loaded test unrevoke interface"
227
+ content_type :html
228
+ erb :test_unrevoke
229
+ end
230
+ end
236
231
  end
232
+ end
237
233
  end
@@ -1,33 +1,33 @@
1
1
  module R509
2
- module CertificateAuthority
3
- module Http
4
- class SubjectParser
5
- def parse(raw, name="subject")
6
- if raw.nil?
7
- raise ArgumentError, "Must provide a query string"
8
- end
2
+ module CertificateAuthority
3
+ module HTTP
4
+ class SubjectParser
5
+ def parse(raw, name="subject")
6
+ if raw.nil?
7
+ raise ArgumentError, "Must provide a query string"
8
+ end
9
9
 
10
- subject = R509::Subject.new
11
- raw.split(/[&;] */n).each { |pair|
12
- key, value = pair.split('=', 2).map { |data| unescape(data) }
13
- match = key.match(/#{name}\[(.*)\]/)
14
- if not match.nil? and not value.empty?
15
- subject[match[1]] = value
16
- end
17
- }
18
- subject
19
- end
20
-
21
- if defined?(::Encoding)
22
- def unescape(s, encoding = Encoding::UTF_8)
23
- URI.decode_www_form_component(s, encoding)
24
- end
25
- else
26
- def unescape(s, encoding = nil)
27
- URI.decode_www_form_component(s, encoding)
28
- end
29
- end
10
+ subject = R509::Subject.new
11
+ raw.split(/[&;] */n).each { |pair|
12
+ key, value = pair.split('=', 2).map { |data| unescape(data) }
13
+ match = key.match(/#{name}\[(.*)\]/)
14
+ if not match.nil? and not value.empty?
15
+ subject[match[1]] = value
30
16
  end
17
+ }
18
+ subject
19
+ end
20
+
21
+ if defined?(::Encoding)
22
+ def unescape(s, encoding = Encoding::UTF_8)
23
+ URI.decode_www_form_component(s, encoding)
24
+ end
25
+ else
26
+ def unescape(s, encoding = nil)
27
+ URI.decode_www_form_component(s, encoding)
28
+ end
31
29
  end
30
+ end
32
31
  end
32
+ end
33
33
  end
@@ -1,16 +1,16 @@
1
- module R509::CertificateAuthority::Http
2
- class ValidityPeriodConverter
3
- def convert(validity_period)
4
- if validity_period.nil?
5
- raise ArgumentError, "Must provide validity period"
6
- end
7
- if validity_period.to_i <= 0
8
- raise ArgumentError, "Validity period must be positive"
9
- end
10
- {
11
- :not_before => Time.now - 6 * 60 * 60,
12
- :not_after => Time.now + validity_period.to_i,
13
- }
14
- end
1
+ module R509::CertificateAuthority::HTTP
2
+ class ValidityPeriodConverter
3
+ def convert(validity_period)
4
+ if validity_period.nil?
5
+ raise ArgumentError, "Must provide validity period"
6
+ end
7
+ if validity_period.to_i <= 0
8
+ raise ArgumentError, "Validity period must be positive"
9
+ end
10
+ {
11
+ :not_before => Time.now - 6 * 60 * 60,
12
+ :not_after => Time.now + validity_period.to_i,
13
+ }
15
14
  end
15
+ end
16
16
  end
@@ -1,7 +1,7 @@
1
1
  module R509
2
- module CertificateAuthority
3
- module Http
4
- VERSION="0.1"
5
- end
2
+ module CertificateAuthority
3
+ module HTTP
4
+ VERSION="0.2"
6
5
  end
6
+ end
7
7
  end