Skip to content

Instantly share code, notes, and snippets.

@fancyremarker
Created June 17, 2015 00:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fancyremarker/569e37f373cbc2a138e5 to your computer and use it in GitHub Desktop.
Save fancyremarker/569e37f373cbc2a138e5 to your computer and use it in GitHub Desktop.
Automatically concatenate any certificate chain in its proper order
#!/usr/bin/env ruby
# cert-wizard: Concatenate a certificate chain in its correct order
require 'openssl'
COMMAND = ARGV[0]
CERTIFICATE_FILES = ARGV[1..-1]
@filenames = {}
def subject_cn(certificate)
certificate.subject.to_s[%r(/CN=(.*)), 1]
end
def issuer_cn(certificate)
certificate.issuer.to_s[%r(/CN=(.*)), 1]
end
def original_filename(certificate)
@filenames[certificate.to_s]
end
def load_certificates
certificates = CERTIFICATE_FILES.map do |file|
OpenSSL::X509::Certificate.new(File.open(file).read).tap do |c|
@filenames[c.to_s] = file
end
end
end
def sort_certificates(certificates)
sorted = []
primaries = certificates.select { |c| subject_cn(c) =~ /^[^\s]+$/ }
fail 'Could not identify primary certificate' unless primaries.count == 1
primary = primaries.first
sorted << certificates.delete(primary)
while certificates.any?
# Each certificate will be followed by the certificate of its issuer
parent = certificates.find do |c|
subject_cn(c) == issuer_cn(sorted.last)
end
sorted << certificates.delete(parent)
end
sorted
end
unless %w(info cat).include?(COMMAND)
fail 'Usage: cert-wizard [info|cat] CERT1 [CERT2] [CERT3] ...'
end
certificates = load_certificates
sorted = sort_certificates(certificates)
if COMMAND == 'info'
sorted.each do |certificate|
puts "#{original_filename(certificate)}: #{subject_cn(certificate)}"
end
elsif COMMAND == 'cat'
sorted.each { |certificate| puts certificate.to_s }
end
@fancyremarker
Copy link
Author

Usage: ruby cert-wizard.rb [info|cat] CERT1 [CERT2] [CERT3] ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment