Add SSL cert and key validation
This commit is contained in:
parent
1255cb94ea
commit
400ffa73e6
5 changed files with 67 additions and 0 deletions
|
@ -3,7 +3,10 @@ import os
|
|||
import json
|
||||
import ldap
|
||||
import peewee
|
||||
import OpenSSL
|
||||
import logging
|
||||
|
||||
from fnmatch import fnmatch
|
||||
from data.users import LDAPConnection
|
||||
from flask import Flask
|
||||
from flask.ext.mail import Mail, Message
|
||||
|
@ -13,6 +16,8 @@ from app import app, CONFIG_PROVIDER
|
|||
from auth.auth_context import get_authenticated_user
|
||||
from util.oauth import GoogleOAuthConfig, GithubOAuthConfig
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SSL_FILENAMES = ['ssl.cert', 'ssl.key']
|
||||
|
||||
def get_storage_provider(config):
|
||||
|
@ -35,6 +40,7 @@ def validate_service_for_config(service, config):
|
|||
'status': True
|
||||
}
|
||||
except Exception as ex:
|
||||
logger.exception('Validation exception')
|
||||
return {
|
||||
'status': False,
|
||||
'reason': str(ex)
|
||||
|
@ -150,6 +156,50 @@ def _validate_ssl(config):
|
|||
if not CONFIG_PROVIDER.volume_file_exists(filename):
|
||||
raise Exception('Missing required SSL file: %s' % filename)
|
||||
|
||||
with CONFIG_PROVIDER.get_volume_file(SSL_FILENAMES[0]) as f:
|
||||
cert_contents = f.read()
|
||||
|
||||
# Validate the certificate.
|
||||
try:
|
||||
cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_contents)
|
||||
except:
|
||||
raise Exception('Could not parse certificate file. Is it a valid PEM certificate?')
|
||||
|
||||
if cert.has_expired():
|
||||
raise Exception('The specified SSL certificate has expired.')
|
||||
|
||||
private_key_path = None
|
||||
with CONFIG_PROVIDER.get_volume_file(SSL_FILENAMES[1]) as f:
|
||||
private_key_path = f.name
|
||||
|
||||
if not private_key_path:
|
||||
# Only in testing.
|
||||
return
|
||||
|
||||
# Validate the private key with the certificate.
|
||||
context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
|
||||
context.use_certificate(cert)
|
||||
|
||||
try:
|
||||
context.use_privatekey_file(private_key_path)
|
||||
except:
|
||||
raise Exception('Could not parse key file. Is it a valid PEM private key?')
|
||||
|
||||
try:
|
||||
context.check_privatekey()
|
||||
except OpenSSL.SSL.Error as e:
|
||||
raise Exception('SSL key failed to validate: %s' % str(e))
|
||||
|
||||
# Verify the hostname matches the name in the certificate.
|
||||
common_name = cert.get_subject().commonName
|
||||
if common_name is None:
|
||||
raise Exception('Missing CommonName (CN) from SSL certificate')
|
||||
|
||||
if not fnmatch(config['SERVER_HOSTNAME'], common_name):
|
||||
raise Exception('CommonName (CN) "%s" in SSL cert does not match server hostname "%s"' %
|
||||
(common_name, config['SERVER_HOSTNAME']))
|
||||
|
||||
|
||||
|
||||
def _validate_ldap(config):
|
||||
""" Validates the LDAP connection. """
|
||||
|
|
Reference in a new issue