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:



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/r509/crl.rb', line 141

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



138
139
140
# File 'lib/r509/crl.rb', line 138

def crl
  @crl
end

- (Object) crl_list_file (readonly)

Returns the value of attribute crl_list_file



138
139
140
# File 'lib/r509/crl.rb', line 138

def crl_list_file
  @crl_list_file
end

- (Object) crl_number (readonly)

Returns the value of attribute crl_number



138
139
140
# File 'lib/r509/crl.rb', line 138

def crl_number
  @crl_number
end

- (Object) crl_number_file (readonly)

Returns the value of attribute crl_number_file



138
139
140
# File 'lib/r509/crl.rb', line 138

def crl_number_file
  @crl_number_file
end

- (Object) validity_hours (readonly)

Returns the value of attribute validity_hours



138
139
140
# File 'lib/r509/crl.rb', line 138

def validity_hours
  @validity_hours
end

Instance Method Details

- (String) generate_crl

Remove serial from revocation list

Returns:

  • (String)

    PEM encoded signed CRL



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/r509/crl.rb', line 228

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.name

  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)



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/r509/crl.rb', line 197

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.



168
169
170
# File 'lib/r509/crl.rb', line 168

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



173
174
175
# File 'lib/r509/crl.rb', line 173

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.



268
269
270
271
272
273
274
# File 'lib/r509/crl.rb', line 268

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.



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

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.



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

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



218
219
220
221
222
223
# File 'lib/r509/crl.rb', line 218

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