summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/leap_cli/commands/ca.rb23
1 files changed, 23 insertions, 0 deletions
diff --git a/lib/leap_cli/commands/ca.rb b/lib/leap_cli/commands/ca.rb
index d5c6240d..3a0786e2 100644
--- a/lib/leap_cli/commands/ca.rb
+++ b/lib/leap_cli/commands/ca.rb
@@ -215,6 +215,10 @@ module LeapCli; module Commands
return true
else
cert = load_certificate_file([:node_x509_cert, node.name])
+ if !created_by_authority?(cert, ca_root)
+ 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
@@ -246,6 +250,25 @@ module LeapCli; module Commands
return false
end
+ def created_by_authority?(cert, ca)
+ authority_key_id = cert.extensions["authorityKeyIdentifier"].identifier.sub(/^keyid:/, '')
+ authority_key_id == public_key_id_for_ca(ca)
+ end
+
+ # calculate the "key id" for a root CA, that matches the value
+ # Authority Key Identifier in the x509 extensions of a cert.
+ def public_key_id_for_ca(ca_cert)
+ @ca_key_ids ||= {}
+ @ca_key_ids[ca_cert.object_id] ||= begin
+ pubkey = ca_cert.key_material.public_key
+ seq = OpenSSL::ASN1::Sequence([
+ OpenSSL::ASN1::Integer.new(pubkey.n),
+ OpenSSL::ASN1::Integer.new(pubkey.e)
+ ])
+ Digest::SHA1.hexdigest(seq.to_der).upcase.scan(/../).join(':')
+ end
+ end
+
def warn_if_commercial_cert_will_soon_expire(node)
dns_names_for_node(node).each do |domain|
if file_exists?([:commercial_cert, domain])