diff options
author | Micah Anderson <micah@riseup.net> | 2016-11-04 10:54:28 -0400 |
---|---|---|
committer | Micah Anderson <micah@riseup.net> | 2016-11-04 10:54:28 -0400 |
commit | 34a381efa8f6295080c843f86bfa07d4e41056af (patch) | |
tree | 9282cf5d4c876688602705a7fa0002bc4a810bde /lib/leap_cli/config/node_cert.rb | |
parent | 0a72bc6fd292bf9367b314fcb0347c4d35042f16 (diff) | |
parent | 5821964ff7e16ca7aa9141bd09a77d355db492a9 (diff) |
Merge branch 'develop'
Diffstat (limited to 'lib/leap_cli/config/node_cert.rb')
-rw-r--r-- | lib/leap_cli/config/node_cert.rb | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/lib/leap_cli/config/node_cert.rb b/lib/leap_cli/config/node_cert.rb new file mode 100644 index 00000000..da63d621 --- /dev/null +++ b/lib/leap_cli/config/node_cert.rb @@ -0,0 +1,124 @@ +# +# x509 related methods for Config::Node +# +module LeapCli; module Config + + class Node < Object + + # + # creates a new server certificate file for this node + # + def generate_cert + require 'leap_cli/x509' + + if self['x509.use'] == false || + !Util.file_exists?(:ca_cert, :ca_key) || + !self.cert_needs_updating? + return false + end + + cert = CertificateAuthority::Certificate.new + provider = env.provider + + # set subject + cert.subject.common_name = self.domain.full + cert.serial_number.number = X509.cert_serial_number(self.domain.full) + + # set expiration + cert.not_before = X509.yesterday + cert.not_after = X509.yesterday_advance(provider.ca.server_certificates.life_span) + + # generate key + cert.key_material.generate_key(provider.ca.server_certificates.bit_size) + + # sign + cert.parent = X509.ca_root + cert.sign!(X509.server_signing_profile(self)) + + # save + Util.write_file!([:node_x509_key, self.name], cert.key_material.private_key.to_pem) + Util.write_file!([:node_x509_cert, self.name], cert.to_pem) + end + + # + # returns true if the certs associated with +node+ need to be regenerated. + # + def cert_needs_updating?(log_comments=true) + require 'leap_cli/x509' + + if log_comments + def log(*args, &block) + Util.log(*args, &block) + end + else + def log(*args); end + end + + node = self + if !Util.file_exists?([:node_x509_cert, node.name], [:node_x509_key, node.name]) + return true + else + cert = X509.load_certificate_file([:node_x509_cert, node.name]) + if !X509.created_by_authority?(cert) + log :updating, "cert for node '#{node.name}' because it was signed by an old CA root cert." + return true + end + if cert.not_after < Time.now.advance(:months => 2) + log :updating, "cert for node '#{node.name}' because it will expire soon" + return true + end + if cert.subject.common_name != node.domain.full + log :updating, "cert for node '#{node.name}' because domain.full has changed (was #{cert.subject.common_name}, now #{node.domain.full})" + return true + end + cert.openssl_body.extensions.each do |ext| + if ext.oid == "subjectAltName" + ips = [] + dns_names = [] + ext.value.split(",").each do |value| + value.strip! + ips << $1 if value =~ /^IP Address:(.*)$/ + dns_names << $1 if value =~ /^DNS:(.*)$/ + end + dns_names.sort! + if ips.first != node.ip_address + log :updating, "cert for node '#{node.name}' because ip_address has changed (from #{ips.first} to #{node.ip_address})" + return true + elsif dns_names != node.all_dns_names + log :updating, "cert for node '#{node.name}' because domain name aliases have changed" do + log "from: #{dns_names.inspect}" + log "to: #{node.all_dns_names.inspect})" + end + return true + end + end + end + end + return false + end + + # + # check the expiration of commercial certs, if any. + # + def warn_if_commercial_cert_will_soon_expire + require 'leap_cli/x509' + + self.all_dns_names.each do |domain| + if Util.file_exists?([:commercial_cert, domain]) + cert = X509.load_certificate_file([:commercial_cert, domain]) + path = Path.relative_path([:commercial_cert, domain]) + if cert.not_after < Time.now.utc + Util.log :error, "the commercial certificate '#{path}' has EXPIRED! " + + "You should renew it with `leap cert renew #{domain}`." + elsif cert.not_after < Time.now.advance(:months => 2) + Util.log :warning, "the commercial certificate '#{path}' will expire soon (#{cert.not_after}). "+ + "You should renew it with `leap cert renew #{domain}`." + end + end + end + end + + end + +end; end + |