r509-ca-http 0.1 → 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 (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