Skip to content

Commit

Permalink
certificate details
Browse files Browse the repository at this point in the history
  • Loading branch information
lslezak committed Apr 30, 2014
1 parent 12cd022 commit f5ad1f9
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 50 deletions.
39 changes: 11 additions & 28 deletions src/data/registration/certificate_summary.erb
Expand Up @@ -21,30 +21,18 @@ textdomain "registration"
<h4><%= _("Issued To") %></h4>
<blockquote>
<p>
<% # label followed by the SSL certificate subject identification
%>
<b><%= _("Common Name (CN):") %></b> <%= h(Helpers.find_name_attribute(@subject, "CN")) %><br>
<% # label followed by the SSL certificate subject identification
%>
<b><%= _("Organization (O):") %></b> <%= h(Helpers.find_name_attribute(@subject, "O")) %><br>
<% # label followed by the SSL certificate subject identification
%>
<b><%= _("Organization Unit (OU):") %></b> <%= h(Helpers.find_name_attribute(@subject, "OU")) %>
<b><%= _("Common Name (CN): ") %></b><%= h(Helpers.find_name_attribute(@subject, "CN")) %><br>
<b><%= _("Organization (O): ") %></b><%= h(Helpers.find_name_attribute(@subject, "O")) %><br>
<b><%= _("Organization Unit (OU): ") %></b><%= h(Helpers.find_name_attribute(@subject, "OU")) %>
</p>
</blockquote>

<h4><%= _("Issued By") %></h4>
<blockquote>
<p>
<% # label followed by the SSL certificate issuer identification
%>
<b><%= _("Common Name (CN):") %></b> <%= h(Helpers.find_name_attribute(@issuer, "CN")) %><br>
<% # label followed by the SSL certificate issuer identification
%>
<b><%= _("Organization (O):") %></b> <%= h(Helpers.find_name_attribute(@issuer, "O")) %><br>
<% # label followed by the SSL certificate issuer identification
%>
<b><%= _("Organization Unit (OU):") %></b> <%= h(Helpers.find_name_attribute(@issuer, "OU")) %>
<b><%= _("Common Name (CN): ") %></b><%= h(Helpers.find_name_attribute(@issuer, "CN")) %><br>
<b><%= _("Organization (O): ") %></b><%= h(Helpers.find_name_attribute(@issuer, "O")) %><br>
<b><%= _("Organization Unit (OU): ") %></b><%= h(Helpers.find_name_attribute(@issuer, "OU")) %>
</p>
</blockquote>

Expand All @@ -53,7 +41,7 @@ textdomain "registration"
<p>
<% # label followed by the certificate issue date
%>
<b><%= _("Issued On:") %></b> <%= h(@certificate.not_before.localtime.strftime("%F")) %><br>
<b><%= _("Issued On: ") %></b><%= h(@certificate.not_before.localtime.strftime("%F")) %><br>
<% if Time.now < @certificate.not_before %>
<% # warning added after the certificate issue date
# if the certificate is not valid yet
Expand All @@ -62,7 +50,7 @@ textdomain "registration"
<% end %>
<% # label followed by the certificate expiration date
%>
<b><%= _("Expires On:") %></b> <%= h(@certificate.not_after.localtime.strftime("%F")) %><br>
<b><%= _("Expires On: ") %></b><%= h(@certificate.not_after.localtime.strftime("%F")) %><br>
<% if Time.now > @certificate.not_after %>
<% # warning added after the certificate expiration date
# if the certificate has expired
Expand All @@ -76,14 +64,9 @@ textdomain "registration"
<p>
<% # label followed by the certificate serial number (in HEX format, e.g. AB:CD:42:FF...)
%>
<b><%= _("Serial Number:") %></b> <%= h(@certificate.serial.to_s(16).scan(/../).join(":")) %><br>

<% # label followed by the certificate SHA1 sum (in HEX format, e.g. AB:CD:42:FF...)
%>
<b><%= _("SHA1 Fingerprint:") %></b>
<b><%= _("Serial Number: ") %></b><%= h(@certificate.serial.to_s(16).scan(/../).join(":")) %><br>
<b><%= _("SHA1 Fingerprint: ") %></b>
<%= h(::SUSE::Connect::SSLCertificate.sha1_fingerprint(@certificate)) %>
<% # label followed by the certificate SHA256 sum (in HEX format, e.g. AB:CD:42:FF...)
%>
<b><%= _("SHA256 Fingerprint:") %></b>
<b><%= _("SHA256 Fingerprint: ") %></b>
<%= h(::SUSE::Connect::SSLCertificate.sha256_fingerprint(@certificate)) %>
</p>
59 changes: 45 additions & 14 deletions src/lib/registration/connect_helpers.rb
Expand Up @@ -105,8 +105,13 @@ def self.catch_registration_errors(&block)
# retry after successfull import
retry if import_ssl_certificate(cert)
else
# try to use a translatable message first, if not found then use
# the original error message from openSSL
msg = UI::ImportCertificateDialog::OPENSSL_ERROR_MESSAGES[error_code]
msg = msg ? _(msg) : Storage::SSLErrors.instance.ssl_error_msg

Yast::Report.Error(
error_with_details(_("OpenSSL connection error."), ssl_error_details)
error_with_details(_("Secure connection error: %s") % msg, ssl_error_details)
)
end

Expand Down Expand Up @@ -134,37 +139,63 @@ def self.error_with_details(error, details)
end

def self.ssl_error_details()
cert = Storage::SSLErrors.instance.ssl_failed_cert
msg = Storage::SSLErrors.instance.ssl_error_msg
log.error "SSL error message msg: #{msg}"

details = []
details << msg if msg
details = [ ]

cert = Storage::SSLErrors.instance.ssl_failed_cert
if cert
details << "" unless details.empty?
details << _("Failed Certificate Details:")

details << _("Issued To: ") << cert.subject
details << _("Issued By: ") << cert.issuer
details << _("SHA1 Fingerprint: ") <<
::SUSE::Connect::SSLCertificate.sha1_fingerprint(cert)
details << _("Issued To")
details.concat(cert_name_details(cert.subject))
details << ""
details << _("Issued By")
details.concat(cert_name_details(cert.issuer))
details << ""
details << _("SHA1 Fingerprint: ")
details << " " + ::SUSE::Connect::SSLCertificate.sha1_fingerprint(cert)
details << _("SHA256 Fingerprint: ")

sha256 = ::SUSE::Connect::SSLCertificate.sha256_fingerprint(cert)
if Yast::UI.TextMode
details << " " + sha256[0..59]
details << " " + sha256[60..-1]
else
details << " " + sha256
end
end

details.join("\n")
end

def self.cert_name_details(x509_name)
spacing = " "
details = []

# label followed by the SSL certificate identification
details << spacing + _("Common Name (CN): ") + Helpers.find_name_attribute(x509_name, "CN")
# label followed by the SSL certificate identification
details << spacing + _("Organization (O): ") + Helpers.find_name_attribute(x509_name, "O")
# label followed by the SSL certificate identification
details << spacing + _("Organization Unit (OU): ") + Helpers.find_name_attribute(x509_name, "OU")

details
end

def self.import_ssl_certificate(cert)
# run the import dialog, check the user selection
if UI::ImportCertificateDialog.run(cert) == :import
cn = Helpers.find_name_attribute(cert.subject, "CN")
log.info "Importing '#{cn}' certificate..."

# progress label
result = Yast::Popup.Feedback(_("Importing the SSL certificate"),
_("Importing '%s' certificate...") % cn) do

::SUSE::Connect::SSLCertificate.import(cert)
end

log.info "Certificate import result: #{result}"
return true
else
log.info "Certificate import rejected"
end

false
Expand Down
30 changes: 22 additions & 8 deletions src/lib/registration/ui/import_certificate_dialog.rb
Expand Up @@ -29,32 +29,45 @@ class ImportCertificateDialog
Yast.import "UI"
Yast.import "Label"

# create a new dialog for importing a SSL certificate and run it
# @param cert [OpenSSL::X509::Name] certificate to display
# @return [Symbol] user input (:import, :cancel)
def self.run(cert)
dialog = ImportCertificateDialog.new(cert)
dialog.run
end

# @param cert []
# @param cert [OpenSSL::X509::Name] certificate to display
def initialize(cert)
textdomain "registration"
@certificate = cert
end

# display the dialog and wait for a button click
# @return [Symbol] user input (:import, :cancel)
def run
log.info "Displaying certificate import dialog:"
log.info " * Issuer: #{@certificate.issuer}"
log.info " * Subject: #{@certificate.subject}"
log.info " * SHA1: #{::SUSE::Connect::SSLCertificate.sha1_fingerprint(@certificate)}"

dialog_content = import_dialog_content
log.debug "Certificate import dialog: #{dialog_content}"
Yast::UI.OpenDialog(Opt(:decorated), dialog_content)

begin
Yast::UI.SetFocus(:cancel)
return Yast::UI.UserInput
ui = Yast::UI.UserInput
log.info "User input: #{ui}"
return ui
ensure
Yast::UI.CloseDialog
end
end

private

# create dialog content
def import_dialog_content
displayinfo = Yast::UI.GetDisplayInfo
# hide additional help text in narrow terminals
Expand All @@ -75,7 +88,6 @@ def import_dialog_content
VBox(
HSpacing(75),
MarginBox(0.4, 0.4, RichText(certificate_description)),
# dialog buttons
ButtonBox(
# push button
PushButton(Id(:import), Opt(:key_F10, :okButton), _("&Trust and Import")),
Expand All @@ -90,6 +102,7 @@ def import_dialog_content
)
end

# render Richtext description with the certificate details
def certificate_description
# use erb template for rendering the richtext summary
erb_file = File.expand_path("../../../../data/registration/certificate_summary.erb", __FILE__)
Expand All @@ -103,26 +116,27 @@ def certificate_description
erb.result(binding)
end

# inline help text displayed in the import dialog
def warning_text
# help text for importing a SSL certificate (1/5)
# help text (RichText) for importing a SSL certificate (1/5)
_("<p>Secure connection (HTTPS) uses SSL certificates for verifying the " \
"authenticity of the server and for encrypting the transferred data.</p>") +

# help text for importing a SSL certificate (2/5)
# help text (RichText) for importing a SSL certificate (2/5)
_("<p>You can choose to import the certificate it into the list of known " \
"certificate autohorities (CA), meaning that you trust the subject " \
"and the issuer of the unknown certificate.</p>") +

# help text for importing a SSL certificate (3/5)
# help text (RichText) for importing a SSL certificate (3/5)
_("<p>Importing a certificate will allow to use for example a " \
"self-signed certificate.</p>") +

# help text for importing a SSL certificate (4/5)
# help text (RichText) for importing a SSL certificate (4/5)
_("<p><b>Important:</b> You should verify the fingerprint of the " \
"certificate to be sure you import the genuine certificate from " \
"the requested server.</p>") +

# help text for importing a SSL certificate (5/5)
# help text (RichText) for importing a SSL certificate (5/5)
_("<p><b>Importing an unknown certificate without " \
"verification is a big security risk.</b></p>")
end
Expand Down

0 comments on commit f5ad1f9

Please sign in to comment.