diff options
Diffstat (limited to 'vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb')
-rw-r--r-- | vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb b/vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb new file mode 100644 index 0000000..e222e26 --- /dev/null +++ b/vendor/certificate_authority/lib/certificate_authority/certificate_revocation_list.rb @@ -0,0 +1,77 @@ +module CertificateAuthority + class CertificateRevocationList + include ActiveModel::Validations + + attr_accessor :certificates + attr_accessor :parent + attr_accessor :crl_body + attr_accessor :next_update + + validate do |crl| + errors.add :next_update, "Next update must be a positive value" if crl.next_update < 0 + errors.add :parent, "A parent entity must be set" if crl.parent.nil? + end + + def initialize + self.certificates = [] + self.next_update = 60 * 60 * 4 # 4 hour default + end + + def <<(revocable) + case revocable + when Revocable + raise "Only revoked entities can be added to a CRL" unless revocable.revoked? + self.certificates << revocable + when OpenSSL::X509::Certificate + raise "Not implemented yet" + else + raise "#{revocable.class} cannot be included in a CRL" + end + end + + def sign!(signing_profile={}) + raise "No parent entity has been set!" if self.parent.nil? + raise "Invalid CRL" unless self.valid? + + revocations = self.certificates.collect do |revocable| + revocation = OpenSSL::X509::Revoked.new + + ## We really just need a serial number, now we have to dig it out + case revocable + when Certificate + x509_cert = OpenSSL::X509::Certificate.new(revocable.to_pem) + revocation.serial = x509_cert.serial + when SerialNumber + revocation.serial = revocable.number + end + revocation.time = revocable.revoked_at + revocation + end + + crl = OpenSSL::X509::CRL.new + revocations.each do |revocation| + crl.add_revoked(revocation) + end + + crl.version = 1 + crl.last_update = Time.now + crl.next_update = Time.now + self.next_update + + signing_cert = OpenSSL::X509::Certificate.new(self.parent.to_pem) + if signing_profile["digest"].nil? + digest = OpenSSL::Digest::Digest.new("SHA512") + else + digest = OpenSSL::Digest::Digest.new(signing_profile["digest"]) + end + crl.issuer = signing_cert.subject + self.crl_body = crl.sign(self.parent.key_material.private_key, digest) + + self.crl_body + end + + def to_pem + raise "No signed CRL body" if self.crl_body.nil? + self.crl_body.to_pem + end + end#CertificateRevocationList +end |