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:



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/r509/crl.rb', line 119

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_list_file (readonly)

Returns the value of attribute crl_list_file



116
117
118
# File 'lib/r509/crl.rb', line 116

def crl_list_file
  @crl_list_file
end

- (Object) crl_number (readonly)

Returns the value of attribute crl_number



116
117
118
# File 'lib/r509/crl.rb', line 116

def crl_number
  @crl_number
end

- (Object) crl_number_file (readonly)

Returns the value of attribute crl_number_file



116
117
118
# File 'lib/r509/crl.rb', line 116

def crl_number_file
  @crl_number_file
end

- (Object) validity_hours (readonly)

Returns the value of attribute validity_hours



116
117
118
# File 'lib/r509/crl.rb', line 116

def validity_hours
  @validity_hours
end

Instance Method Details

- (String) generate_crl

Remove serial from revocation list

Returns:

  • (String)

    PEM encoded signed CRL



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/r509/crl.rb', line 258

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 = crl
    @crl.to_pem
end

- (Time) last_update

Returns the signing time of the CRL

Returns:

  • (Time)

    when the CRL was signed



196
197
198
# File 'lib/r509/crl.rb', line 196

def last_update
    @crl.last_update
end

- (Time) next_update

Returns the next update time for the CRL

Returns:

  • (Time)

    when it will be updated next



203
204
205
# File 'lib/r509/crl.rb', line 203

def next_update
    @crl.next_update
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

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)

    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) }


227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/r509/crl.rb', line 227

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.



146
147
148
# File 'lib/r509/crl.rb', line 146

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



151
152
153
# File 'lib/r509/crl.rb', line 151

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.



298
299
300
301
302
303
304
# File 'lib/r509/crl.rb', line 298

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.



313
314
315
316
317
318
319
320
321
322
# File 'lib/r509/crl.rb', line 313

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.



331
332
333
334
335
336
337
# File 'lib/r509/crl.rb', line 331

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

- (R509::Crl::Parser) to_crl

Returns:



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

def to_crl
  return nil if @crl.nil?
  return R509::Crl::Parser.new(@crl)
end

- (String) to_der

Returns the CRL in DER format

Returns:

  • (String)

    the CRL in DER format



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

def to_der
    @crl.to_der
end

- (String) to_pem Also known as: to_s

Returns the CRL in PEM format

Returns:

  • (String)

    the CRL in PEM format



158
159
160
# File 'lib/r509/crl.rb', line 158

def to_pem
    @crl.to_pem
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



248
249
250
251
252
253
# File 'lib/r509/crl.rb', line 248

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

- (Object) write_der(filename_or_io)

Writes the CRL into the PEM format

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.



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

def write_der(filename_or_io)
    write_data(filename_or_io, @crl.to_der)
end

- (Object) write_pem(filename_or_io)

Writes the CRL into the PEM format

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.



181
182
183
# File 'lib/r509/crl.rb', line 181

def write_pem(filename_or_io)
    write_data(filename_or_io, @crl.to_pem)
end