Class: R509::Crl::Administrator

Inherits:
Object
  • Object
show all
Includes:
IOHelpers
Defined in:
lib/r509/crl.rb

Overview

Used to manage revocations and generate CRLs

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Methods included from IOHelpers

#read_data, read_data, #write_data, write_data

Constructor Details

- (Administrator) initialize(config)

A new instance of Administrator

Parameters:



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/r509/crl.rb', line 157

def initialize(config)
  @config = config

  unless @config.kind_of?(R509::Config::CaConfig)
    raise R509Error, "config must be a kind of R509::Config::CaConfig"
  end

  @validity_hours = @config.crl_validity_hours
  @start_skew_seconds = @config.crl_start_skew_seconds
  @crl = nil

  @crl_number_file = @config.crl_number_file
  if not @crl_number_file.nil?
    @crl_number = read_data(@crl_number_file).to_i
  else
    @crl_number = 0
  end


  @crl_list_file = @config.crl_list_file
  load_crl_list(@crl_list_file)
end

Instance Attribute Details

- (Object) crl (readonly)

Returns the value of attribute crl



154
155
156
# File 'lib/r509/crl.rb', line 154

def crl
  @crl
end

- (Object) crl_list_file (readonly)

Returns the value of attribute crl_list_file



154
155
156
# File 'lib/r509/crl.rb', line 154

def crl_list_file
  @crl_list_file
end

- (Object) crl_number (readonly)

Returns the value of attribute crl_number



154
155
156
# File 'lib/r509/crl.rb', line 154

def crl_number
  @crl_number
end

- (Object) crl_number_file (readonly)

Returns the value of attribute crl_number_file



154
155
156
# File 'lib/r509/crl.rb', line 154

def crl_number_file
  @crl_number_file
end

- (Object) validity_hours (readonly)

Returns the value of attribute validity_hours



154
155
156
# File 'lib/r509/crl.rb', line 154

def validity_hours
  @validity_hours
end

Instance Method Details

- (String) generate_crl

Remove serial from revocation list

Returns:

  • (String)

    PEM encoded signed CRL



244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/r509/crl.rb', line 244

def generate_crl
  crl = OpenSSL::X509::CRL.new
  crl.version = 1
  now = Time.at Time.now.to_i
  crl.last_update = now-@start_skew_seconds
  crl.next_update = now+@validity_hours*3600
  crl.issuer = @config.ca_cert.subject

  self.revoked_certs.each do |serial, reason, revoke_time|
    revoked = OpenSSL::X509::Revoked.new
    revoked.serial = OpenSSL::BN.new serial.to_s
    revoked.time = Time.at(revoke_time)
    if !reason.nil?
      enum = OpenSSL::ASN1::Enumerated(reason) #see reason codes below
      ext = OpenSSL::X509::Extension.new("CRLReason", enum)
      revoked.add_extension(ext)
    end
    #now add it to the crl
    crl.add_revoked(revoked)
  end

  ef = OpenSSL::X509::ExtensionFactory.new
  ef.issuer_certificate = @config.ca_cert.cert
  ef.crl = crl
  #grab crl number from file, increment, write back
  crl_number = increment_crl_number
  crlnum = OpenSSL::ASN1::Integer(crl_number)
  crl.add_extension(OpenSSL::X509::Extension.new("crlNumber", crlnum))
  extensions = []
  extensions << ["authorityKeyIdentifier", "keyid:always,issuer:always", false]
  extensions.each{|oid, value, critical|
    crl.add_extension(ef.create_extension(oid, value, critical))
  }
  crl.sign(@config.ca_cert.key.key, OpenSSL::Digest::SHA1.new)
  @crl = R509::Crl::SignedList.new crl
  @crl.to_pem
end

- (Object) revoke_cert(serial, reason = nil, revoke_time = Time.now.to_i, generate_and_save = true)

Adds a certificate to the revocation list. After calling you must call generate_crl to sign a new CRL

reason codes defined by rfc 5280

CRLReason ::= ENUMERATED {

unspecified       (0),
keyCompromise       (1),
cACompromise        (2),
affiliationChanged    (3),
superseded        (4),
cessationOfOperation    (5),
certificateHold     (6),
removeFromCRL       (8),
privilegeWithdrawn    (9),
aACompromise       (10) }

Parameters:

  • serial (Integer)

    serial number of the certificate to revoke

  • reason (Integer) (defaults to: nil)

    reason for revocation

  • revoke_time (Integer) (defaults to: Time.now.to_i)
  • generate_and_save (Boolean) (defaults to: true)

    whether we want to generate the CRL and save its file (default=true)



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/r509/crl.rb', line 213

def revoke_cert(serial,reason=nil, revoke_time=Time.now.to_i, generate_and_save=true)
  if not reason.to_i.between?(0,10)
    reason = 0
  end
  serial = serial.to_i
  reason = reason.to_i
  revoke_time = revoke_time.to_i
  if revoked?(serial)
    raise R509::R509Error, "Cannot revoke a previously revoked certificate"
  end
  @revoked_certs[serial] = {:reason => reason, :revoke_time => revoke_time}
  if generate_and_save
    generate_crl
    save_crl_list
  end
  nil
end

- (Boolean) revoked?(serial)

Indicates whether the serial number has been revoked, or not.

Parameters:

  • serial (Integer)

    The serial number we want to check

Returns:

  • (Boolean)

    True if the serial number was revoked. False, otherwise.



184
185
186
# File 'lib/r509/crl.rb', line 184

def revoked?(serial)
  @revoked_certs.has_key?(serial)
end

- (Array) revoked_cert(serial)

Serial, reason, revoke_time tuple

Returns:

  • (Array)

    serial, reason, revoke_time tuple



189
190
191
# File 'lib/r509/crl.rb', line 189

def revoked_cert(serial)
  @revoked_certs[serial]
end

- (Array<Array>) revoked_certs

Returns an array of serial, reason, revoke_time tuples.

Returns:

  • (Array<Array>)

    Returns an array of serial, reason, revoke_time tuples.



284
285
286
287
288
289
290
# File 'lib/r509/crl.rb', line 284

def revoked_certs
  ret = []
  @revoked_certs.keys.sort.each do |serial|
    ret << [serial, @revoked_certs[serial][:reason], @revoked_certs[serial][:revoke_time]]
  end
  ret
end

- (Object) save_crl_list(filename_or_io = @crl_list_file)

Saves the CRL list to a filename or IO. If the class was initialized with :crl_list_file, then the filename specified by that will be used by default.

Parameters:

  • filename_or_io (String, #write, nil) (defaults to: @crl_list_file)

    If provided, the generated crl will be written to either the file (if a string), or IO. If nil, then the @crl_list_file will be used. If that is nil, then an error will be raised.



299
300
301
302
303
304
305
306
307
308
# File 'lib/r509/crl.rb', line 299

def save_crl_list(filename_or_io = @crl_list_file)
  return nil if filename_or_io.nil?

  data = []
  self.revoked_certs.each do |serial, reason, revoke_time|
    data << [serial, revoke_time, reason].join(',')
  end
  write_data(filename_or_io, data.join("\n"))
  nil
end

- (Object) save_crl_number(filename_or_io = @crl_number_file)

Save the CRL number to a filename or IO. If the class was initialized with :crl_number_file, then the filename specified by that will be used by default.

Parameters:

  • filename_or_io (String, #write, nil) (defaults to: @crl_number_file)

    If provided, the current crl number will be written to either the file (if a string), or IO. If nil, then the @crl_number_file will be used. If that is nil, then an error will be raised.



317
318
319
320
321
322
323
# File 'lib/r509/crl.rb', line 317

def save_crl_number(filename_or_io = @crl_number_file)
  return nil if filename_or_io.nil?
  # No valid filename or IO was specified, so bail.

  write_data(filename_or_io, self.crl_number.to_s)
  nil
end

- (Object) unrevoke_cert(serial)

Remove serial from revocation list. After unrevoking you must call generate_crl to sign a new CRL

Parameters:

  • serial (Integer)

    serial number of the certificate to remove from revocation



234
235
236
237
238
239
# File 'lib/r509/crl.rb', line 234

def unrevoke_cert(serial)
  @revoked_certs.delete(serial)
  generate_crl
  save_crl_list
  nil
end