Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 99 additions & 10 deletions src/Crypt/CryptConnection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import ssl
import hashlib
import random

from Config import config
from util import SslPatch
Expand All @@ -11,6 +12,7 @@

class CryptConnectionManager:
def __init__(self):
# TODO: UGLY UGLY UGLY
# OpenSSL params
if sys.platform.startswith("win"):
self.openssl_bin = "src\\lib\\opensslVerify\\openssl.exe"
Expand All @@ -19,6 +21,11 @@ def __init__(self):
self.openssl_env = {"OPENSSL_CONF": "src/lib/opensslVerify/openssl.cnf"}

self.crypt_supported = [] # Supported cryptos
self.cacert_pem = config.data_dir+"/cacert-rsa.pem"
self.cakey_pem = config.data_dir+"/cakey-rsa.pem"
self.cert_pem = config.data_dir+"/cert-rsa.pem"
self.cert_csr = config.data_dir+"/cert-rsa.csr"
self.key_pem = config.data_dir+"/key-rsa.pem"

# Select crypt that supported by both sides
# Return: Name of the crypto
Expand All @@ -36,8 +43,8 @@ def wrapSocket(self, sock, crypt, server=False, cert_pin=None):
ciphers += "!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK"
if server:
sock_wrapped = ssl.wrap_socket(
sock, server_side=server, keyfile='%s/key-rsa.pem' % config.data_dir,
certfile='%s/cert-rsa.pem' % config.data_dir, ciphers=ciphers)
sock, server_side=server, keyfile=self.key_pem,
certfile=self.cert_pem, ciphers=ciphers)
else:
sock_wrapped = ssl.wrap_socket(sock, ciphers=ciphers)
if cert_pin:
Expand All @@ -50,7 +57,7 @@ def wrapSocket(self, sock, crypt, server=False, cert_pin=None):
def removeCerts(self):
if config.keep_ssl_cert:
return False
for file_name in ["cert-rsa.pem", "key-rsa.pem"]:
for file_name in ["cert-rsa.pem", "key-rsa.pem", "cacert-rsa.pem", "cakey-rsa.pem", "cert-rsa.csr"]:
file_path = "%s/%s" % (config.data_dir, file_name)
if os.path.isfile(file_path):
os.unlink(file_path)
Expand All @@ -66,25 +73,107 @@ def loadCerts(self):
# Try to create RSA server cert + sign for connection encryption
# Return: True on success
def createSslRsaCert(self):
if os.path.isfile("%s/cert-rsa.pem" % config.data_dir) and os.path.isfile("%s/key-rsa.pem" % config.data_dir):
casubjects = [
"/C=US/O=Amazon/OU=Server CA 1B/CN=Amazon",
"/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3",
"/C=US/O=DigiCert Inc/OU=www.digicert.com/CN = DigiCert SHA2 High Assurance Server CA",
"/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN = COMODO RSA Domain Validation Secure Server CA"
]
fakedomains = [
"yahoo.com",
"amazon.com",
"live.com",
"microsoft.com",
"mail.ru",
"csdn.net",
"bing.com",
"amazon.co.jp",
"office.com",
"imdb.com",
"msn.com",
"samsung.com",
"huawei.com",
"ztedevices.com",
"godaddy.com",
"w3.org",
"gravatar.com",
"creativecommons.org",
"hatena.ne.jp",
"adobe.com",
"opera.com",
"apache.org",
"rambler.ru",
"one.com",
"nationalgeographic.com",
"networksolutions.com",
"php.net",
"python.org",
"phoca.cz",
"debian.org",
"ubuntu.com",
"nazwa.pl",
"symantec.com"
]
self.openssl_env['CN'] = random.choice(fakedomains)

if os.path.isfile(self.cert_pem) and os.path.isfile(self.key_pem):
return True # Files already exits

import subprocess
cmd = "%s req -x509 -newkey rsa:2048 -sha256 -batch -keyout %s -out %s -nodes -config %s" % helper.shellquote(
# Generate CAcert and CAkey
cmd = "%s req -new -newkey rsa:2048 -days 3650 -nodes -x509 -subj %s -keyout %s -out %s -batch -config %s" % helper.shellquote(
self.openssl_bin,
config.data_dir+"/key-rsa.pem",
config.data_dir+"/cert-rsa.pem",
self.openssl_env["OPENSSL_CONF"]
random.choice(casubjects),
self.cakey_pem,
self.cacert_pem,
self.openssl_env["OPENSSL_CONF"],
)
proc = subprocess.Popen(
cmd.encode(sys.getfilesystemencoding()),
shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=self.openssl_env
)
back = proc.stdout.read().strip()
proc.wait()
logging.debug("Generating RSA cert and key PEM files...%s" % back)
logging.debug("Generating RSA CAcert and CAkey PEM files...%s" % back)

if os.path.isfile("%s/cert-rsa.pem" % config.data_dir) and os.path.isfile("%s/key-rsa.pem" % config.data_dir):
if not (os.path.isfile(self.cacert_pem) and os.path.isfile(self.cakey_pem)):
logging.error("RSA ECC SSL CAcert generation failed, CAcert or CAkey files not exist.")
return False

# Generate certificate key and signing request
cmd = "%s req -new -newkey rsa:2048 -keyout %s -out %s -subj %s -sha256 -nodes -batch -config %s" % helper.shellquote(
self.openssl_bin,
self.key_pem,
self.cert_csr,
"/CN="+self.openssl_env['CN'],
self.openssl_env["OPENSSL_CONF"],
)
proc = subprocess.Popen(
cmd.encode(sys.getfilesystemencoding()),
shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=self.openssl_env
)
back = proc.stdout.read().strip()
proc.wait()
logging.debug("Generating certificate key and signing request...%s" % back)

# Sign request and generate certificate
cmd = "%s x509 -req -in %s -CA %s -CAkey %s -CAcreateserial -out %s -days 730 -sha256 -extensions x509_ext -extfile %s" % helper.shellquote(
self.openssl_bin,
self.cert_csr,
self.cacert_pem,
self.cakey_pem,
self.cert_pem,
self.openssl_env["OPENSSL_CONF"],
)
proc = subprocess.Popen(
cmd.encode(sys.getfilesystemencoding()),
shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=self.openssl_env
)
back = proc.stdout.read().strip()
proc.wait()
logging.debug("Generating RSA cert...%s" % back)

if os.path.isfile(self.cert_pem) and os.path.isfile(self.key_pem):
return True
else:
logging.error("RSA ECC SSL cert generation failed, cert or key files not exist.")
Expand Down
21 changes: 5 additions & 16 deletions src/lib/opensslVerify/openssl.cnf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[ req ]
prompt = no
prompt = yes
default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
Expand Down Expand Up @@ -32,8 +32,8 @@ authorityKeyIdentifier = keyid,issuer

basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
Expand All @@ -46,25 +46,14 @@ subjectKeyIdentifier = hash

basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# extendedKeyUsage = serverAuth, clientAuth

[ alternate_names ]

DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com

# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# DNS.7 = 127.0.0.1

# IPv6 localhost
# DNS.8 = ::1
DNS.1 = $ENV::CN
DNS.2 = www.$ENV::CN