leap_cli 1.5.6 → 1.6.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.
- data/bin/leap +29 -6
- data/lib/leap/platform.rb +36 -1
- data/lib/leap_cli/commands/ca.rb +97 -20
- data/lib/leap_cli/commands/compile.rb +49 -8
- data/lib/leap_cli/commands/db.rb +13 -4
- data/lib/leap_cli/commands/deploy.rb +138 -29
- data/lib/leap_cli/commands/env.rb +76 -0
- data/lib/leap_cli/commands/facts.rb +10 -3
- data/lib/leap_cli/commands/inspect.rb +2 -2
- data/lib/leap_cli/commands/list.rb +10 -10
- data/lib/leap_cli/commands/node.rb +7 -132
- data/lib/leap_cli/commands/node_init.rb +169 -0
- data/lib/leap_cli/commands/pre.rb +4 -27
- data/lib/leap_cli/commands/ssh.rb +152 -0
- data/lib/leap_cli/commands/test.rb +22 -13
- data/lib/leap_cli/commands/user.rb +12 -4
- data/lib/leap_cli/commands/vagrant.rb +4 -4
- data/lib/leap_cli/config/filter.rb +175 -0
- data/lib/leap_cli/config/manager.rb +130 -61
- data/lib/leap_cli/config/node.rb +32 -0
- data/lib/leap_cli/config/object.rb +69 -44
- data/lib/leap_cli/config/object_list.rb +44 -39
- data/lib/leap_cli/config/secrets.rb +24 -12
- data/lib/leap_cli/config/tag.rb +7 -0
- data/lib/{core_ext → leap_cli/core_ext}/boolean.rb +0 -0
- data/lib/{core_ext → leap_cli/core_ext}/hash.rb +0 -0
- data/lib/{core_ext → leap_cli/core_ext}/json.rb +0 -0
- data/lib/{core_ext → leap_cli/core_ext}/nil.rb +0 -0
- data/lib/{core_ext → leap_cli/core_ext}/string.rb +0 -0
- data/lib/leap_cli/core_ext/yaml.rb +29 -0
- data/lib/leap_cli/exceptions.rb +24 -0
- data/lib/leap_cli/leapfile.rb +60 -10
- data/lib/{lib_ext → leap_cli/lib_ext}/capistrano_connections.rb +0 -0
- data/lib/{lib_ext → leap_cli/lib_ext}/gli.rb +0 -0
- data/lib/leap_cli/log.rb +1 -1
- data/lib/leap_cli/logger.rb +18 -1
- data/lib/leap_cli/markdown_document_listener.rb +1 -1
- data/lib/leap_cli/override/json.rb +11 -0
- data/lib/leap_cli/path.rb +20 -6
- data/lib/leap_cli/remote/leap_plugin.rb +2 -2
- data/lib/leap_cli/remote/puppet_plugin.rb +1 -1
- data/lib/leap_cli/remote/rsync_plugin.rb +1 -1
- data/lib/leap_cli/remote/tasks.rb +1 -1
- data/lib/leap_cli/ssh_key.rb +63 -1
- data/lib/leap_cli/util/remote_command.rb +19 -2
- data/lib/leap_cli/util/secret.rb +1 -1
- data/lib/leap_cli/util/x509.rb +3 -2
- data/lib/leap_cli/util.rb +11 -3
- data/lib/leap_cli/version.rb +2 -2
- data/lib/leap_cli.rb +24 -14
- data/vendor/certificate_authority/lib/certificate_authority/certificate.rb +85 -29
- data/vendor/certificate_authority/lib/certificate_authority/distinguished_name.rb +5 -0
- data/vendor/certificate_authority/lib/certificate_authority/extensions.rb +406 -41
- data/vendor/certificate_authority/lib/certificate_authority/key_material.rb +0 -34
- data/vendor/certificate_authority/lib/certificate_authority/serial_number.rb +6 -0
- data/vendor/certificate_authority/lib/certificate_authority/signing_request.rb +36 -1
- metadata +25 -24
- data/lib/leap_cli/commands/shell.rb +0 -89
- data/lib/leap_cli/config/macros.rb +0 -430
- data/lib/leap_cli/constants.rb +0 -7
- data/lib/leap_cli/requirements.rb +0 -19
- data/lib/lib_ext/markdown_document_listener.rb +0 -122
@@ -5,6 +5,10 @@ module CertificateAuthority
|
|
5
5
|
raise "Implementation required"
|
6
6
|
end
|
7
7
|
|
8
|
+
def self.parse(value, critical)
|
9
|
+
raise "Implementation required"
|
10
|
+
end
|
11
|
+
|
8
12
|
def config_extensions
|
9
13
|
{}
|
10
14
|
end
|
@@ -12,21 +16,40 @@ module CertificateAuthority
|
|
12
16
|
def openssl_identifier
|
13
17
|
raise "Implementation required"
|
14
18
|
end
|
19
|
+
|
20
|
+
def ==(value)
|
21
|
+
raise "Implementation required"
|
22
|
+
end
|
15
23
|
end
|
16
24
|
|
25
|
+
# Specifies whether an X.509v3 certificate can act as a CA, signing other
|
26
|
+
# certificates to be verified. If set, a path length constraint can also be
|
27
|
+
# specified.
|
28
|
+
# Reference: Section 4.2.1.10 of RFC3280
|
29
|
+
# http://tools.ietf.org/html/rfc3280#section-4.2.1.10
|
17
30
|
class BasicConstraints
|
31
|
+
OPENSSL_IDENTIFIER = "basicConstraints"
|
32
|
+
|
18
33
|
include ExtensionAPI
|
19
34
|
include ActiveModel::Validations
|
35
|
+
|
36
|
+
attr_accessor :critical
|
20
37
|
attr_accessor :ca
|
21
38
|
attr_accessor :path_len
|
39
|
+
validates :critical, :inclusion => [true,false]
|
22
40
|
validates :ca, :inclusion => [true,false]
|
23
41
|
|
24
42
|
def initialize
|
25
|
-
|
43
|
+
@critical = false
|
44
|
+
@ca = false
|
45
|
+
end
|
46
|
+
|
47
|
+
def openssl_identifier
|
48
|
+
OPENSSL_IDENTIFIER
|
26
49
|
end
|
27
50
|
|
28
51
|
def is_ca?
|
29
|
-
|
52
|
+
@ca
|
30
53
|
end
|
31
54
|
|
32
55
|
def path_len=(value)
|
@@ -34,29 +57,54 @@ module CertificateAuthority
|
|
34
57
|
@path_len = value
|
35
58
|
end
|
36
59
|
|
37
|
-
def
|
38
|
-
|
60
|
+
def to_s
|
61
|
+
res = []
|
62
|
+
res << "CA:#{@ca}"
|
63
|
+
res << "pathlen:#{@path_len}" unless @path_len.nil?
|
64
|
+
res.join(',')
|
39
65
|
end
|
40
66
|
|
41
|
-
def
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
67
|
+
def ==(o)
|
68
|
+
o.class == self.class && o.state == state
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.parse(value, critical)
|
72
|
+
obj = self.new
|
73
|
+
return obj if value.nil?
|
74
|
+
obj.critical = critical
|
75
|
+
value.split(/,\s*/).each do |v|
|
76
|
+
c = v.split(':', 2)
|
77
|
+
obj.ca = (c.last.upcase == "TRUE") if c.first == "CA"
|
78
|
+
obj.path_len = c.last.to_i if c.first == "pathlen"
|
79
|
+
end
|
80
|
+
obj
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
def state
|
85
|
+
[@critical,@ca,@path_len]
|
46
86
|
end
|
47
87
|
end
|
48
88
|
|
89
|
+
# Specifies where CRL information be be retrieved. This extension isn't
|
90
|
+
# critical, but is recommended for proper CAs.
|
91
|
+
# Reference: Section 4.2.1.14 of RFC3280
|
92
|
+
# http://tools.ietf.org/html/rfc3280#section-4.2.1.14
|
49
93
|
class CrlDistributionPoints
|
94
|
+
OPENSSL_IDENTIFIER = "crlDistributionPoints"
|
95
|
+
|
50
96
|
include ExtensionAPI
|
51
97
|
|
52
|
-
attr_accessor :
|
98
|
+
attr_accessor :critical
|
99
|
+
attr_accessor :uris
|
53
100
|
|
54
101
|
def initialize
|
55
|
-
|
102
|
+
@critical = false
|
103
|
+
@uris = []
|
56
104
|
end
|
57
105
|
|
58
106
|
def openssl_identifier
|
59
|
-
|
107
|
+
OPENSSL_IDENTIFIER
|
60
108
|
end
|
61
109
|
|
62
110
|
## NB: At this time it seems OpenSSL's extension handlers don't support
|
@@ -69,99 +117,302 @@ module CertificateAuthority
|
|
69
117
|
}
|
70
118
|
end
|
71
119
|
|
120
|
+
# This is for legacy support. Technically it can (and probably should)
|
121
|
+
# be an array. But if someone is calling the old accessor we shouldn't
|
122
|
+
# necessarily break it.
|
123
|
+
def uri=(value)
|
124
|
+
@uris << value
|
125
|
+
end
|
126
|
+
|
72
127
|
def to_s
|
73
|
-
|
74
|
-
|
128
|
+
res = []
|
129
|
+
@uris.each do |uri|
|
130
|
+
res << "URI:#{uri}"
|
131
|
+
end
|
132
|
+
res.join(',')
|
133
|
+
end
|
134
|
+
|
135
|
+
def ==(o)
|
136
|
+
o.class == self.class && o.state == state
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.parse(value, critical)
|
140
|
+
obj = self.new
|
141
|
+
return obj if value.nil?
|
142
|
+
obj.critical = critical
|
143
|
+
value.split(/,\s*/).each do |v|
|
144
|
+
c = v.split(':', 2)
|
145
|
+
obj.uris << c.last if c.first == "URI"
|
146
|
+
end
|
147
|
+
obj
|
148
|
+
end
|
149
|
+
|
150
|
+
protected
|
151
|
+
def state
|
152
|
+
[@critical,@uri]
|
75
153
|
end
|
76
154
|
end
|
77
155
|
|
156
|
+
# Identifies the public key associated with a given certificate.
|
157
|
+
# Should be required for "CA" certificates.
|
158
|
+
# Reference: Section 4.2.1.2 of RFC3280
|
159
|
+
# http://tools.ietf.org/html/rfc3280#section-4.2.1.2
|
78
160
|
class SubjectKeyIdentifier
|
161
|
+
OPENSSL_IDENTIFIER = "subjectKeyIdentifier"
|
162
|
+
|
79
163
|
include ExtensionAPI
|
164
|
+
|
165
|
+
attr_accessor :critical
|
166
|
+
attr_accessor :identifier
|
167
|
+
|
168
|
+
def initialize
|
169
|
+
@critical = false
|
170
|
+
@identifier = "hash"
|
171
|
+
end
|
172
|
+
|
80
173
|
def openssl_identifier
|
81
|
-
|
174
|
+
OPENSSL_IDENTIFIER
|
82
175
|
end
|
83
176
|
|
84
177
|
def to_s
|
85
|
-
|
178
|
+
res = []
|
179
|
+
res << @identifier
|
180
|
+
res.join(',')
|
181
|
+
end
|
182
|
+
|
183
|
+
def ==(o)
|
184
|
+
o.class == self.class && o.state == state
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.parse(value, critical)
|
188
|
+
obj = self.new
|
189
|
+
return obj if value.nil?
|
190
|
+
obj.critical = critical
|
191
|
+
obj.identifier = value
|
192
|
+
obj
|
193
|
+
end
|
194
|
+
|
195
|
+
protected
|
196
|
+
def state
|
197
|
+
[@critical,@identifier]
|
86
198
|
end
|
87
199
|
end
|
88
200
|
|
201
|
+
# Identifies the public key associated with a given private key.
|
202
|
+
# Reference: Section 4.2.1.1 of RFC3280
|
203
|
+
# http://tools.ietf.org/html/rfc3280#section-4.2.1.1
|
89
204
|
class AuthorityKeyIdentifier
|
205
|
+
OPENSSL_IDENTIFIER = "authorityKeyIdentifier"
|
206
|
+
|
90
207
|
include ExtensionAPI
|
91
208
|
|
209
|
+
attr_accessor :critical
|
210
|
+
attr_accessor :identifier
|
211
|
+
|
212
|
+
def initialize
|
213
|
+
@critical = false
|
214
|
+
@identifier = ["keyid", "issuer"]
|
215
|
+
end
|
216
|
+
|
92
217
|
def openssl_identifier
|
93
|
-
|
218
|
+
OPENSSL_IDENTIFIER
|
94
219
|
end
|
95
220
|
|
96
221
|
def to_s
|
97
|
-
|
222
|
+
res = []
|
223
|
+
res += @identifier
|
224
|
+
res.join(',')
|
225
|
+
end
|
226
|
+
|
227
|
+
def ==(o)
|
228
|
+
o.class == self.class && o.state == state
|
229
|
+
end
|
230
|
+
|
231
|
+
def self.parse(value, critical)
|
232
|
+
obj = self.new
|
233
|
+
return obj if value.nil?
|
234
|
+
obj.critical = critical
|
235
|
+
obj.identifier = value.split(/,\s*/).last.chomp
|
236
|
+
obj
|
237
|
+
end
|
238
|
+
|
239
|
+
protected
|
240
|
+
def state
|
241
|
+
[@critical,@identifier]
|
98
242
|
end
|
99
243
|
end
|
100
244
|
|
245
|
+
# Specifies how to access CA information and services for the CA that
|
246
|
+
# issued this certificate.
|
247
|
+
# Generally used to specify OCSP servers.
|
248
|
+
# Reference: Section 4.2.2.1 of RFC3280
|
249
|
+
# http://tools.ietf.org/html/rfc3280#section-4.2.2.1
|
101
250
|
class AuthorityInfoAccess
|
251
|
+
OPENSSL_IDENTIFIER = "authorityInfoAccess"
|
252
|
+
|
102
253
|
include ExtensionAPI
|
103
254
|
|
255
|
+
attr_accessor :critical
|
104
256
|
attr_accessor :ocsp
|
257
|
+
attr_accessor :ca_issuers
|
105
258
|
|
106
259
|
def initialize
|
107
|
-
|
260
|
+
@critical = false
|
261
|
+
@ocsp = []
|
262
|
+
@ca_issuers = []
|
108
263
|
end
|
109
264
|
|
110
265
|
def openssl_identifier
|
111
|
-
|
266
|
+
OPENSSL_IDENTIFIER
|
112
267
|
end
|
113
268
|
|
114
269
|
def to_s
|
115
|
-
|
116
|
-
"OCSP;URI:#{
|
270
|
+
res = []
|
271
|
+
res += @ocsp.map {|o| "OCSP;URI:#{o}" }
|
272
|
+
res += @ca_issuers.map {|c| "caIssuers;URI:#{c}" }
|
273
|
+
res.join(',')
|
274
|
+
end
|
275
|
+
|
276
|
+
def ==(o)
|
277
|
+
o.class == self.class && o.state == state
|
278
|
+
end
|
279
|
+
|
280
|
+
def self.parse(value, critical)
|
281
|
+
obj = self.new
|
282
|
+
return obj if value.nil?
|
283
|
+
obj.critical = critical
|
284
|
+
value.split("\n").each do |v|
|
285
|
+
if v =~ /^OCSP/
|
286
|
+
obj.ocsp << v.split.last
|
287
|
+
end
|
288
|
+
|
289
|
+
if v =~ /^CA Issuers/
|
290
|
+
obj.ca_issuers << v.split.last
|
291
|
+
end
|
292
|
+
end
|
293
|
+
obj
|
294
|
+
end
|
295
|
+
|
296
|
+
protected
|
297
|
+
def state
|
298
|
+
[@critical,@ocsp,@ca_issuers]
|
117
299
|
end
|
118
300
|
end
|
119
301
|
|
302
|
+
# Specifies the allowed usage purposes of the keypair specified in this certificate.
|
303
|
+
# Reference: Section 4.2.1.3 of RFC3280
|
304
|
+
# http://tools.ietf.org/html/rfc3280#section-4.2.1.3
|
305
|
+
#
|
306
|
+
# Note: OpenSSL when parsing an extension will return results in the form
|
307
|
+
# 'Digital Signature', but on signing you have to set it to 'digitalSignature'.
|
308
|
+
# So copying an extension from an imported cert isn't going to work yet.
|
120
309
|
class KeyUsage
|
310
|
+
OPENSSL_IDENTIFIER = "keyUsage"
|
311
|
+
|
121
312
|
include ExtensionAPI
|
122
313
|
|
314
|
+
attr_accessor :critical
|
123
315
|
attr_accessor :usage
|
124
316
|
|
125
317
|
def initialize
|
126
|
-
|
318
|
+
@critical = false
|
319
|
+
@usage = ["digitalSignature", "nonRepudiation"]
|
127
320
|
end
|
128
321
|
|
129
322
|
def openssl_identifier
|
130
|
-
|
323
|
+
OPENSSL_IDENTIFIER
|
131
324
|
end
|
132
325
|
|
133
326
|
def to_s
|
134
|
-
|
327
|
+
res = []
|
328
|
+
res += @usage
|
329
|
+
res.join(',')
|
330
|
+
end
|
331
|
+
|
332
|
+
def ==(o)
|
333
|
+
o.class == self.class && o.state == state
|
334
|
+
end
|
335
|
+
|
336
|
+
def self.parse(value, critical)
|
337
|
+
obj = self.new
|
338
|
+
return obj if value.nil?
|
339
|
+
obj.critical = critical
|
340
|
+
obj.usage = value.split(/,\s*/)
|
341
|
+
obj
|
342
|
+
end
|
343
|
+
|
344
|
+
protected
|
345
|
+
def state
|
346
|
+
[@critical,@usage]
|
135
347
|
end
|
136
348
|
end
|
137
349
|
|
350
|
+
# Specifies even more allowed usages in addition to what is specified in
|
351
|
+
# the Key Usage extension.
|
352
|
+
# Reference: Section 4.2.1.13 of RFC3280
|
353
|
+
# http://tools.ietf.org/html/rfc3280#section-4.2.1.13
|
138
354
|
class ExtendedKeyUsage
|
355
|
+
OPENSSL_IDENTIFIER = "extendedKeyUsage"
|
356
|
+
|
139
357
|
include ExtensionAPI
|
140
358
|
|
359
|
+
attr_accessor :critical
|
141
360
|
attr_accessor :usage
|
142
361
|
|
143
362
|
def initialize
|
144
|
-
|
363
|
+
@critical = false
|
364
|
+
@usage = ["serverAuth"]
|
145
365
|
end
|
146
366
|
|
147
367
|
def openssl_identifier
|
148
|
-
|
368
|
+
OPENSSL_IDENTIFIER
|
149
369
|
end
|
150
370
|
|
151
371
|
def to_s
|
152
|
-
|
372
|
+
res = []
|
373
|
+
res += @usage
|
374
|
+
res.join(',')
|
375
|
+
end
|
376
|
+
|
377
|
+
def ==(o)
|
378
|
+
o.class == self.class && o.state == state
|
379
|
+
end
|
380
|
+
|
381
|
+
def self.parse(value, critical)
|
382
|
+
obj = self.new
|
383
|
+
return obj if value.nil?
|
384
|
+
obj.critical = critical
|
385
|
+
obj.usage = value.split(/,\s*/)
|
386
|
+
obj
|
387
|
+
end
|
388
|
+
|
389
|
+
protected
|
390
|
+
def state
|
391
|
+
[@critical,@usage]
|
153
392
|
end
|
154
393
|
end
|
155
394
|
|
395
|
+
# Specifies additional "names" for which this certificate is valid.
|
396
|
+
# Reference: Section 4.2.1.7 of RFC3280
|
397
|
+
# http://tools.ietf.org/html/rfc3280#section-4.2.1.7
|
156
398
|
class SubjectAlternativeName
|
399
|
+
OPENSSL_IDENTIFIER = "subjectAltName"
|
400
|
+
|
157
401
|
include ExtensionAPI
|
158
402
|
|
159
|
-
attr_accessor :
|
403
|
+
attr_accessor :critical
|
404
|
+
attr_accessor :uris, :dns_names, :ips, :emails
|
160
405
|
|
161
406
|
def initialize
|
162
|
-
|
163
|
-
|
164
|
-
|
407
|
+
@critical = false
|
408
|
+
@uris = []
|
409
|
+
@dns_names = []
|
410
|
+
@ips = []
|
411
|
+
@emails = []
|
412
|
+
end
|
413
|
+
|
414
|
+
def openssl_identifier
|
415
|
+
OPENSSL_IDENTIFIER
|
165
416
|
end
|
166
417
|
|
167
418
|
def uris=(value)
|
@@ -179,22 +430,50 @@ module CertificateAuthority
|
|
179
430
|
@ips = value
|
180
431
|
end
|
181
432
|
|
182
|
-
def
|
183
|
-
"
|
433
|
+
def emails=(value)
|
434
|
+
raise "Emails must be an array" unless value.is_a?(Array)
|
435
|
+
@emails = value
|
184
436
|
end
|
185
437
|
|
186
438
|
def to_s
|
187
|
-
res =
|
188
|
-
res +=
|
189
|
-
res +=
|
439
|
+
res = []
|
440
|
+
res += @uris.map {|u| "URI:#{u}" }
|
441
|
+
res += @dns_names.map {|d| "DNS:#{d}" }
|
442
|
+
res += @ips.map {|i| "IP:#{i}" }
|
443
|
+
res += @emails.map {|i| "email:#{i}" }
|
444
|
+
res.join(',')
|
445
|
+
end
|
446
|
+
|
447
|
+
def ==(o)
|
448
|
+
o.class == self.class && o.state == state
|
449
|
+
end
|
450
|
+
|
451
|
+
def self.parse(value, critical)
|
452
|
+
obj = self.new
|
453
|
+
return obj if value.nil?
|
454
|
+
obj.critical = critical
|
455
|
+
value.split(/,\s*/).each do |v|
|
456
|
+
c = v.split(':', 2)
|
457
|
+
obj.uris << c.last if c.first == "URI"
|
458
|
+
obj.dns_names << c.last if c.first == "DNS"
|
459
|
+
obj.ips << c.last if c.first == "IP"
|
460
|
+
obj.emails << c.last if c.first == "EMAIL"
|
461
|
+
end
|
462
|
+
obj
|
463
|
+
end
|
190
464
|
|
191
|
-
|
465
|
+
protected
|
466
|
+
def state
|
467
|
+
[@critical,@uris,@dns_names,@ips,@emails]
|
192
468
|
end
|
193
469
|
end
|
194
470
|
|
195
471
|
class CertificatePolicies
|
472
|
+
OPENSSL_IDENTIFIER = "certificatePolicies"
|
473
|
+
|
196
474
|
include ExtensionAPI
|
197
475
|
|
476
|
+
attr_accessor :critical
|
198
477
|
attr_accessor :policy_identifier
|
199
478
|
attr_accessor :cps_uris
|
200
479
|
##User notice
|
@@ -203,12 +482,12 @@ module CertificateAuthority
|
|
203
482
|
attr_accessor :notice_numbers
|
204
483
|
|
205
484
|
def initialize
|
485
|
+
self.critical = false
|
206
486
|
@contains_data = false
|
207
487
|
end
|
208
488
|
|
209
|
-
|
210
489
|
def openssl_identifier
|
211
|
-
|
490
|
+
OPENSSL_IDENTIFIER
|
212
491
|
end
|
213
492
|
|
214
493
|
def user_notice=(value={})
|
@@ -258,7 +537,93 @@ module CertificateAuthority
|
|
258
537
|
|
259
538
|
def to_s
|
260
539
|
return "" unless @contains_data
|
261
|
-
|
540
|
+
res = []
|
541
|
+
res << "ia5org"
|
542
|
+
res += @config_extensions["custom_policies"] unless @config_extensions.nil?
|
543
|
+
res.join(',')
|
544
|
+
end
|
545
|
+
|
546
|
+
def self.parse(value, critical)
|
547
|
+
obj = self.new
|
548
|
+
return obj if value.nil?
|
549
|
+
obj.critical = critical
|
550
|
+
value.split(/,\s*/).each do |v|
|
551
|
+
c = v.split(':', 2)
|
552
|
+
obj.policy_identifier = c.last if c.first == "policyIdentifier"
|
553
|
+
obj.cps_uris << c.last if c.first =~ %r{CPS.\d+}
|
554
|
+
# TODO: explicit_text, organization, notice_numbers
|
555
|
+
end
|
556
|
+
obj
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
# DEPRECATED
|
561
|
+
# Specifics the purposes for which a certificate can be used.
|
562
|
+
# The basicConstraints, keyUsage, and extendedKeyUsage extensions are now used instead.
|
563
|
+
# https://www.openssl.org/docs/apps/x509v3_config.html#Netscape_Certificate_Type
|
564
|
+
class NetscapeCertificateType
|
565
|
+
OPENSSL_IDENTIFIER = "nsCertType"
|
566
|
+
|
567
|
+
include ExtensionAPI
|
568
|
+
|
569
|
+
attr_accessor :critical
|
570
|
+
attr_accessor :flags
|
571
|
+
|
572
|
+
def initialize
|
573
|
+
self.critical = false
|
574
|
+
self.flags = []
|
575
|
+
end
|
576
|
+
|
577
|
+
def openssl_identifier
|
578
|
+
OPENSSL_IDENTIFIER
|
579
|
+
end
|
580
|
+
|
581
|
+
def to_s
|
582
|
+
res = []
|
583
|
+
res += self.flags
|
584
|
+
res.join(',')
|
585
|
+
end
|
586
|
+
|
587
|
+
def self.parse(value, critical)
|
588
|
+
obj = self.new
|
589
|
+
return obj if value.nil?
|
590
|
+
obj.critical = critical
|
591
|
+
obj.flags = value.split(/,\s*/)
|
592
|
+
obj
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
# DEPRECATED
|
597
|
+
# Contains a comment which will be displayed when the certificate is viewed in some browsers.
|
598
|
+
# https://www.openssl.org/docs/apps/x509v3_config.html#Netscape_String_extensions_
|
599
|
+
class NetscapeComment
|
600
|
+
OPENSSL_IDENTIFIER = "nsComment"
|
601
|
+
|
602
|
+
include ExtensionAPI
|
603
|
+
|
604
|
+
attr_accessor :critical
|
605
|
+
attr_accessor :comment
|
606
|
+
|
607
|
+
def initialize
|
608
|
+
self.critical = false
|
609
|
+
end
|
610
|
+
|
611
|
+
def openssl_identifier
|
612
|
+
OPENSSL_IDENTIFIER
|
613
|
+
end
|
614
|
+
|
615
|
+
def to_s
|
616
|
+
res = []
|
617
|
+
res << self.comment if self.comment
|
618
|
+
res.join(',')
|
619
|
+
end
|
620
|
+
|
621
|
+
def self.parse(value, critical)
|
622
|
+
obj = self.new
|
623
|
+
return obj if value.nil?
|
624
|
+
obj.critical = critical
|
625
|
+
obj.comment = value
|
626
|
+
obj
|
262
627
|
end
|
263
628
|
end
|
264
629
|
|
@@ -111,38 +111,4 @@ module CertificateAuthority
|
|
111
111
|
@public_key
|
112
112
|
end
|
113
113
|
end
|
114
|
-
|
115
|
-
class SigningRequestKeyMaterial
|
116
|
-
include KeyMaterial
|
117
|
-
include ActiveModel::Validations
|
118
|
-
|
119
|
-
validates_each :public_key do |record, attr, value|
|
120
|
-
record.errors.add :public_key, "cannot be blank" if record.public_key.nil?
|
121
|
-
end
|
122
|
-
|
123
|
-
attr_accessor :public_key
|
124
|
-
|
125
|
-
def initialize(request=nil)
|
126
|
-
if request.is_a? OpenSSL::X509::Request
|
127
|
-
raise "Invalid certificate signing request" unless request.verify request.public_key
|
128
|
-
self.public_key = request.public_key
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
def is_in_hardware?
|
133
|
-
false
|
134
|
-
end
|
135
|
-
|
136
|
-
def is_in_memory?
|
137
|
-
true
|
138
|
-
end
|
139
|
-
|
140
|
-
def private_key
|
141
|
-
nil
|
142
|
-
end
|
143
|
-
|
144
|
-
def public_key
|
145
|
-
@public_key
|
146
|
-
end
|
147
|
-
end
|
148
114
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module CertificateAuthority
|
2
4
|
class SerialNumber
|
3
5
|
include ActiveModel::Validations
|
@@ -6,5 +8,9 @@ module CertificateAuthority
|
|
6
8
|
attr_accessor :number
|
7
9
|
|
8
10
|
validates :number, :presence => true, :numericality => {:greater_than => 0}
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
self.number = SecureRandom.random_number(2**128-1)
|
14
|
+
end
|
9
15
|
end
|
10
16
|
end
|