Commit 930a7030 authored by Kamil Trzcinski's avatar Kamil Trzcinski Committed by James Edwards-Jones

Implement proper verification of certificate's public_key against the private_key

parent 5f7257c2
......@@ -54,8 +54,9 @@ class Projects::PagesController < Projects::ApplicationController
return false unless certificate
return false unless certificate_key
certificate.verify(certificate_key)
rescue OpenSSL::X509::CertificateError
# We compare the public key stored in certificate with public key from certificate key
certificate.public_key.to_pem == certificate_key.public_key.to_pem
rescue OpenSSL::X509::CertificateError, OpenSSL::PKey::PKeyError
false
end
......
......@@ -76,8 +76,6 @@ class Project < ActiveRecord::Base
attr_accessor :new_default_branch
attr_accessor :old_path_with_namespace
attr_encrypted :pages_custom_certificate_key, mode: :per_attribute_iv_and_salt, key: Gitlab::Application.secrets.db_key_base
alias_attribute :title, :name
# Relations
......@@ -209,14 +207,16 @@ class Project < ActiveRecord::Base
validates :pages_custom_domain, hostname: true, allow_blank: true, allow_nil: true
validates_uniqueness_of :pages_custom_domain, allow_nil: true, allow_blank: true
validates :pages_custom_certificate, certificate: { intermediate: true }
validates :pages_custom_certificate_key, certificate_key: true
validates :pages_custom_certificate, certificate: true, allow_nil: true, allow_blank: true
validates :pages_custom_certificate_key, certificate_key: true, allow_nil: true, allow_blank: true
add_authentication_token_field :runners_token
before_save :ensure_runners_token
mount_uploader :avatar, AvatarUploader
attr_encrypted :pages_custom_certificate_key, mode: :per_attribute_iv_and_salt, key: Gitlab::Application.secrets.db_key_base
# Scopes
default_scope { where(pending_delete: false) }
......
......@@ -16,6 +16,7 @@ class CertificateKeyValidator < ActiveModel::EachValidator
private
def valid_private_key_pem?(value)
return unless value
pkey = OpenSSL::PKey::RSA.new(value)
pkey.private?
rescue OpenSSL::PKey::PKeyError
......
......@@ -3,26 +3,20 @@
# Custom validator for private keys.
#
# class Project < ActiveRecord::Base
# validates :certificate_key, certificate_key: true
# validates :certificate_key, certificate: true
# end
#
class CertificateValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
certificate = parse_certificate(value)
unless certificate
unless valid_certificate_pem?(value)
record.errors.add(attribute, "must be a valid PEM certificate")
end
if options[:intermediates]
unless certificate
record.errors.add(attribute, "certificate verification failed: missing intermediate certificates")
end
end
end
private
def parse_certificate(value)
def valid_certificate_pem?(value)
return unless value
OpenSSL::X509::Certificate.new(value)
rescue OpenSSL::X509::CertificateError
nil
......
......@@ -134,47 +134,6 @@
= link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar"
= f.submit 'Save changes', class: "btn btn-save"
- if Settings.pages.enabled
.pages-settings
.panel.panel-default
.panel-heading Pages
.errors-holder
.panel-body
- if @project.pages_url
%strong
Congratulations! Your pages are served at:
%p= link_to @project.pages_url, @project.pages_url
- else
%p
Learn how to upload your static site and have it served by
GitLab by following the #{link_to "documentation on GitLab Pages", "http://doc.gitlab.com/ee/pages/README.html", target: :blank}.
%p
In the example below we define a special job named
%code pages
which is using Jekyll to build a static site. The generated
HTML will be stored in the
%code public/
directory which will then be archived and uploaded to GitLab.
The name of the directory should not be different than
%code public/
in order for the pages to work.
%ul
%li
%pre
:plain
pages:
image: jekyll/jekyll
script: jekyll build -d public/
artifacts:
paths:
- public/
- if @project.pages_url && can?(current_user, :remove_pages, @project)
.form-actions
= link_to 'Remove pages', remove_pages_namespace_project_path(@project.namespace, @project),
data: { confirm: "Are you sure that you want to remove pages for this project?" },
method: :post, class: "btn btn-warning"
.row.prepend-top-default
%hr
.row.prepend-top-default
......
......@@ -6,13 +6,3 @@
%p
Learn how to upload your static site and have it served by
GitLab by following the #{link_to "documentation on GitLab Pages", "http://doc.gitlab.com/ee/pages/README.html", target: :blank}.
%p
In the example below we define a special job named
%code pages
which is using Jekyll to build a static site. The generated
HTML will be stored in the
%code public/
directory which will then be archived and uploaded to GitLab.
The name of the directory should not be different than
%code public/
in order for the pages to work.
class AddPagesCustomDomainToProjects < ActiveRecord::Migration
def change
add_column :projects, :pages_custom_certificate, :text
add_column :projects, :pages_custom_certificate_key, :text
add_column :projects, :pages_custom_certificate_key_iv, :string
add_column :projects, :pages_custom_certificate_key_salt, :string
add_column :projects, :encrypted_pages_custom_certificate_key, :text
add_column :projects, :encrypted_pages_custom_certificate_key_iv, :string
add_column :projects, :encrypted_pages_custom_certificate_key_salt, :string
add_column :projects, :pages_custom_domain, :string, unique: true
add_column :projects, :pages_redirect_http, :boolean, default: false, null: false
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment