diff options
author | Azul <azul@leap.se> | 2013-01-26 10:52:36 +0100 |
---|---|---|
committer | Azul <azul@leap.se> | 2013-01-26 10:52:36 +0100 |
commit | 195224a989fa57e9a70fa10c0cdd6603295bb0dd (patch) | |
tree | 46744babf45aea2c9da4b112317f4746ee4f8d09 /certs/app/models/leap_ca | |
parent | 9563ed191556e739c8f99be4d0fc75ac31c8f6cd (diff) |
removing the leap_ca namespacing from certs
Diffstat (limited to 'certs/app/models/leap_ca')
-rw-r--r-- | certs/app/models/leap_ca/cert.rb | 150 |
1 files changed, 0 insertions, 150 deletions
diff --git a/certs/app/models/leap_ca/cert.rb b/certs/app/models/leap_ca/cert.rb deleted file mode 100644 index 6c59144..0000000 --- a/certs/app/models/leap_ca/cert.rb +++ /dev/null @@ -1,150 +0,0 @@ -# -# Model for certificates stored in CouchDB. -# -# This file must be loaded after Config has been loaded. -# -require 'base64' -require 'digest/md5' -require 'openssl' -require 'certificate_authority' -require 'date' - -module LeapCA - class Cert < CouchRest::Model::Base - -# No config yet. use_database LeapCA::Config.db_name - use_database 'client_certificates' - - timestamps! - - property :key, String # the client private RSA key - property :cert, String # the client x509 certificate, signed by the CA - property :valid_until, Time # expiration time of the client certificate - property :random, Float, :accessible => false # used to help pick a random cert by the webapp - - before_validation :generate, :set_random, :on => :create - - validates :key, :presence => true - validates :cert, :presence => true - validates :random, :presence => true - validates :random, :numericality => {:greater_than => 0, :less_than => 1} - - design do - view :by_random - end - - class << self - def sample - self.by_random.startkey(rand).first || self.by_random.first - end - - def pick_from_pool - cert = self.sample - raise RECORD_NOT_FOUND unless cert - cert.destroy - return cert - rescue RESOURCE_NOT_FOUND - retry if self.by_random.count > 0 - raise RECORD_NOT_FOUND - end - - def valid_attributes_hash - {:key => "ABCD", :cert => "A123"} - end - end - - # - # generate the private key and client certificate - # - def generate - cert = CertificateAuthority::Certificate.new - - # set subject - cert.subject.common_name = random_common_name - - # set expiration - self.valid_until = months_from_yesterday(Config.client_cert_lifespan) - cert.not_before = yesterday - cert.not_after = self.valid_until - - # generate key - cert.serial_number.number = cert_serial_number - cert.key_material.generate_key(Config.client_cert_bit_size) - - # sign - cert.parent = Cert.root_ca - cert.sign! client_signing_profile - - self.key = cert.key_material.private_key.to_pem - self.cert = cert.to_pem - end - - private - - def set_random - self.random = rand - end - - def self.root_ca - @root_ca ||= begin - crt = File.read(Config.ca_cert_path) - key = File.read(Config.ca_key_path) - openssl_cert = OpenSSL::X509::Certificate.new(crt) - cert = CertificateAuthority::Certificate.from_openssl(openssl_cert) - cert.key_material.private_key = OpenSSL::PKey::RSA.new(key, Config.ca_key_password) - cert - end - end - - # - # For cert serial numbers, we need a non-colliding number less than 160 bits. - # md5 will do nicely, since there is no need for a secure hash, just a short one. - # (md5 is 128 bits) - # - def cert_serial_number - Digest::MD5.hexdigest("#{rand(10**10)} -- #{Time.now}").to_i(16) - end - - # - # for the random common name, we need a text string that will be unique across all certs. - # ruby 1.8 doesn't have a built-in uuid generator, or we would use SecureRandom.uuid - # - def random_common_name - cert_serial_number.to_s(36) - end - - def client_signing_profile - { - "digest" => Config.client_cert_hash, - "extensions" => { - "keyUsage" => { - "usage" => ["digitalSignature"] - }, - "extendedKeyUsage" => { - "usage" => ["clientAuth"] - } - } - } - end - - ## - ## TIME HELPERS - ## - ## note: we use 'yesterday' instead of 'today', because times are in UTC, and some people on the planet - ## are behind UTC. - ## - - def yesterday - t = Time.now - 24*24*60 - Time.utc t.year, t.month, t.day - end - - def months_from_yesterday(num) - t = yesterday - date = Date.new t.year, t.month, t.day - date = date >> num # >> is months in the future operator - Time.utc date.year, date.month, date.day - end - - end -end |