mirror of
https://github.com/certbot/certbot.git
synced 2026-08-01 02:44:21 +02:00
Added testing key, cleaned up some code, added ext conf file
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpQIBAAKCAQEA4INAzUJea4/7KmYQWZJiKnxQ07IWASrgmmX3GwzY62W4WaEh
|
||||||
|
09p+vYO6yHFXzAa7Jelq4VxECsXzCfBzU72XNlTRup/kpy3zlgO4FzhhyuiOXqAb
|
||||||
|
m/ocLIXYSSI9nwI5YbJxNIPMNrd2vlaqy9O9km1rXyMzwTih1V1R82qP/xbarFBb
|
||||||
|
tE3SopmGrKv3jDrUy86AE4zjvzKBDobNMz4iV72B7xoecYq1I2grMsdoOUi0dUBc
|
||||||
|
bii7v8Ob4BKH0TWU5I6JmQkv59eS5JVL1mrnoACXgOdEfnO1F42S4qbjMyra+Gg/
|
||||||
|
A+2XnEq2Z7hakIr1BInqDqZ9E7ffb1vNNzttyQIDAQABAoIBAQCg1OXDJNxG6anf
|
||||||
|
waXMxNSV4uB0BotE4tZrRMg0FIwAdaoOayO0hD1uvcM8fBWNDvVaP1BViKcloJBu
|
||||||
|
elXjk1mTjkeADbLbIEvzF071M2q61MXIe6HLpuwv6OH74g+KrSk2F4KJQDE2sU7b
|
||||||
|
I3LO+SxAjSnxyWH19P/ZvTRLz/a/oOPH3YjCuSKZSLZdNwS9L5xJ8/ScYeawGFOx
|
||||||
|
7CEF1QIRiz14q/TXF93U4iAFtj7Awz1yepd2bQ9gYbJpiUK1kWa3rPcmJLL/tGpQ
|
||||||
|
HgONEMn4SxxrpX+/O+HnrusxWQhsgjt1iWUOjJIvvONqa5kiKXhjMURMm6BC2046
|
||||||
|
pwWy7VwBAoGBAPrRKH7ZeGPERv6TZILlkv3x/yKd/O0RP0JdGZyurkBzD+so61gc
|
||||||
|
qci+STOFlq5j+kqPnfYVhETsBsuMlwqKIHbJdinn9EHopy8wyuAHatQqHN2mWZ5V
|
||||||
|
EsGCfZILuIaYM1uTejqF/u2PRXDZdWPta9B7dhDXaXxvPSNXVAG1FlFhAoGBAOUm
|
||||||
|
8WsKrXIVVZvkmN3pWlXfJwhkn3+UG+yayYtque9smXDNETvg0QSUaIKuZj+blSLI
|
||||||
|
V2xtE6uleERpDjwiLVOgA/FlgZZxnVkZXUz4633I9pEuq1Zv5ZodSrQr0dg5R/Ap
|
||||||
|
B/V8ax2r1Y2Uosh/HmMhZirYck4EA/zc6jHshi1pAoGBAIm0+HTc1ZqBEzGGnzK2
|
||||||
|
9QN0ME5DS7ClPYQkNYGu7oD4K49DQiN4aUeMIgilmdtZjPwO6f1IRvzIUdrD79Gb
|
||||||
|
kMNnTPcpIRRmthPUyC5EJEUkcgDH6oBh2RBhoqviv4c2XUw0JnGnTBYGCWwyGJ+q
|
||||||
|
pP0sK+CHRKVLNdgHhFoDoKNBAoGAdOVg0lIoGMJ5YYVD1jBsPNIRf16VXueXNyPf
|
||||||
|
HJfdMh4cSEbUO8970PJEPiXpUxlzAsNglZcvKajHqV5OPK7SoI5IdKRrbuuWcRVX
|
||||||
|
WyTAPPJ/laBRF08NuYinyzFvYvYVlJXZ0Ykeu4wk7IyeXdk7DybCj6jK5rF1t1Ca
|
||||||
|
x8z4xcECgYEAvAvGL6b1fQkF1ihqVFqnQGpRGEef2POE0fnj13i+RAVWUm9k3b45
|
||||||
|
6losFlqxSNjpVxl5kFTGZcEh2UYqAB+fT7IwR/5IX6i+hXIv5U29Ng6BVNjvu2is
|
||||||
|
tijv/tSN07UvBZ4cFgZUw00aQ4hshCp95I0zYCwTtTIOgSRCJWQwUXY=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
@@ -12,10 +12,10 @@ def check(one, two, three, four, five):
|
|||||||
def byteToHex(byteStr):
|
def byteToHex(byteStr):
|
||||||
return ''.join(["%02X" % ord(x) for x in byteStr]).strip()
|
return ''.join(["%02X" % ord(x) for x in byteStr]).strip()
|
||||||
|
|
||||||
def check_challenge_value(ext_value, sharedSecret):
|
def check_challenge_value(ext_value, r):
|
||||||
s = ext_value[0:S_SIZE]
|
s = ext_value[0:S_SIZE]
|
||||||
mac = ext_value[S_SIZE:]
|
mac = ext_value[S_SIZE:]
|
||||||
expected_mac = hmac.new(sharedSecret, str(s), hashlib.sha256).digest()
|
expected_mac = hmac.new(r, str(s), hashlib.sha256).digest()
|
||||||
|
|
||||||
#print "s: ", byteToHex(s)
|
#print "s: ", byteToHex(s)
|
||||||
#print "mac: ", byteToHex(mac)
|
#print "mac: ", byteToHex(mac)
|
||||||
@@ -27,8 +27,8 @@ def check_challenge_value(ext_value, sharedSecret):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def verify_challenge(address, sharedSecret, encryptedValue):
|
def verify_challenge(address, r, nonce):
|
||||||
sni_name = byteToHex(encryptedValue[0]) + ".com"
|
sni_name = nonce + ".chocolate"
|
||||||
|
|
||||||
context = M2Crypto.SSL.Context()
|
context = M2Crypto.SSL.Context()
|
||||||
context.set_allow_unknown_ca(True)
|
context.set_allow_unknown_ca(True)
|
||||||
@@ -49,23 +49,25 @@ def verify_challenge(address, sharedSecret, encryptedValue):
|
|||||||
|
|
||||||
if sni_support.get_nid(ext.x509_ext) == 0:
|
if sni_support.get_nid(ext.x509_ext) == 0:
|
||||||
|
|
||||||
valid = check_challenge_value(sni_support.get_unknown_value(ext.x509_ext), sharedSecret)
|
valid = check_challenge_value(sni_support.get_unknown_value(ext.x509_ext), r)
|
||||||
if valid:
|
if valid:
|
||||||
return True, "Challenge completed successfully"
|
return True, "Challenge completed successfully"
|
||||||
else:
|
else:
|
||||||
return False, "Certificate extension does not check out"
|
return False, "Certificate extension does not check out"
|
||||||
|
|
||||||
|
return False, "Chocolate extension not included in certificate"
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
#Testing the example sni_challenge
|
#Testing the example sni_challenge
|
||||||
from Crypto.PublicKey import RSA
|
from Crypto.PublicKey import RSA
|
||||||
|
|
||||||
testkey = RSA.importKey(open("/home/james/Documents/apache_choc/testing.key").read())
|
nonce = "nonce"
|
||||||
|
testkey = RSA.importKey(open("testing.key").read())
|
||||||
|
|
||||||
#the second parameter is ignored
|
#the second parameter is ignored
|
||||||
#https://www.dlitz.net/software/pycrypto/api/current/
|
#https://www.dlitz.net/software/pycrypto/api/current/
|
||||||
encryptedValue = testkey.encrypt('0x12345678', 0)
|
encryptedValue = testkey.encrypt('0x12345678', 0)
|
||||||
valid, response = verify_challenge("127.0.0.1", '0x12345678', encryptedValue)
|
valid, response = verify_challenge("127.0.0.1", '0x12345678', nonce)
|
||||||
print response
|
print response
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#
|
||||||
|
# OpenSSL configuration file.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Extra OBJECT IDENTIFIER info:
|
||||||
|
oid_section = new_oids
|
||||||
|
|
||||||
|
[ new_oids ]
|
||||||
|
choc=1.3.3.7
|
||||||
|
|
||||||
|
|
||||||
|
[ v3_ca ]
|
||||||
|
basicConstraints = CA:TRUE
|
||||||
|
subjectKeyIdentifier = hash
|
||||||
|
authorityKeyIdentifier = keyid:always,issuer:always
|
||||||
|
1.3.3.7=DER:C15B2E9D8F49A16C57A66F9E07C18C0B524183C427dae3a76c9c5945ff91c27d28eec5a4cc8e2e42a274f7de42d079bfe413171e
|
||||||
+30
-18
@@ -10,34 +10,41 @@ from shutil import move
|
|||||||
from os import remove, close
|
from os import remove, close
|
||||||
|
|
||||||
CHOC_DIR = "/home/james/Documents/apache_choc/"
|
CHOC_DIR = "/home/james/Documents/apache_choc/"
|
||||||
|
#CHOC_KEY = "../ca/sni_challenge/testing.key"
|
||||||
CHOC_KEY = CHOC_DIR + "testing.key"
|
CHOC_KEY = CHOC_DIR + "testing.key"
|
||||||
SERVER_BASE = "/etc/apache2/"
|
SERVER_BASE = "/etc/apache2/"
|
||||||
CHOC_CERT = CHOC_DIR + "choc.crt"
|
CHOC_CERT = CHOC_DIR + "choc.crt"
|
||||||
CSR = CHOC_DIR + "choc.csr"
|
CSR = CHOC_DIR + "choc.csr"
|
||||||
CHOC_CERT_CONF = CHOC_DIR + "choc_cert_extensions.cnf"
|
CHOC_CERT_CONF = "choc_cert_extensions.cnf"
|
||||||
APACHE_CHALLENGE_CONF = CHOC_DIR + "choc_sni_cert_challenge.conf"
|
APACHE_CHALLENGE_CONF = CHOC_DIR + "choc_sni_cert_challenge.conf"
|
||||||
S_SIZE = 20
|
S_SIZE = 20
|
||||||
|
|
||||||
def findApacheConfigFile():
|
def findApacheConfigFile():
|
||||||
return CHOC_DIR + "demo_apache.conf"
|
#return CHOC_DIR + "demo_apache.conf"
|
||||||
|
#This needs to be fixed to account for multiple httpd.conf files
|
||||||
try:
|
try:
|
||||||
p = subprocess.check_output(['find', '/', '-name', '"httpd.conf"'], stderr=open("/dev/null"))
|
p = subprocess.check_output(["sudo", "find", "/", "-name", "httpd.conf"], stderr=open("/dev/null"))
|
||||||
|
p = p[:len(p)-1]
|
||||||
|
print "Apache Config: ", p
|
||||||
|
return p
|
||||||
except subprocess.CalledProcessError, e:
|
except subprocess.CalledProcessError, e:
|
||||||
print "Not found"
|
print "httpd.conf not found"
|
||||||
|
print "Please include .... in the conf file"
|
||||||
|
return None
|
||||||
|
|
||||||
def modifyApacheConfig(mainConfig, nonce, servername, ip_addr):
|
def modifyApacheConfig(mainConfig, nonce, ip_addr):
|
||||||
configText = "<IfModule mod_ssl.c> \n \
|
configText = "<IfModule mod_ssl.c> \n \
|
||||||
<VirtualHost " + ip_addr + ":443> \n \
|
<VirtualHost " + ip_addr + ":443> \n \
|
||||||
Servername " + nonce + "-choc." + servername + " \n \
|
Servername " + nonce + ".chocolate \n \
|
||||||
UseCanonicalName on \n \
|
UseCanonicalName on \n \
|
||||||
\n \
|
\n \
|
||||||
LimitRequestBody 1048576 \n \
|
LimitRequestBody 1048576 \n \
|
||||||
\n \
|
\n \
|
||||||
Include options-ssl.conf \n \
|
Include " + CHOC_DIR + "options-ssl.conf \n \
|
||||||
SSLCertificateFile " + CHOC_CERT + " \n \
|
SSLCertificateFile " + CHOC_CERT + " \n \
|
||||||
SSLCertificateKeyFile " + CHOC_KEY + " \n \
|
SSLCertificateKeyFile " + CHOC_KEY + " \n \
|
||||||
\n \
|
\n \
|
||||||
DocumentRoot " + CHOC_DIR + "virtual_server/ \n \
|
DocumentRoot " + CHOC_DIR + "challenge_page/ \n \
|
||||||
</VirtualHost> \n \
|
</VirtualHost> \n \
|
||||||
</IfModule>"
|
</IfModule>"
|
||||||
|
|
||||||
@@ -49,14 +56,18 @@ DocumentRoot " + CHOC_DIR + "virtual_server/ \n \
|
|||||||
# Need to add NameVirtualHost IP_ADDR
|
# Need to add NameVirtualHost IP_ADDR
|
||||||
def checkForApacheConfInclude(mainConfig):
|
def checkForApacheConfInclude(mainConfig):
|
||||||
searchStr = "Include " + APACHE_CHALLENGE_CONF
|
searchStr = "Include " + APACHE_CHALLENGE_CONF
|
||||||
conf = open(mainConfig, 'r+')
|
#conf = open(mainConfig, 'r+')
|
||||||
|
conf = open(mainConfig, 'r')
|
||||||
flag = False
|
flag = False
|
||||||
for line in conf:
|
for line in conf:
|
||||||
if line.startswith(searchStr):
|
if line.startswith(searchStr):
|
||||||
flag = True
|
flag = True
|
||||||
break
|
break
|
||||||
if not flag:
|
if not flag:
|
||||||
conf.write(searchStr)
|
#conf.write(searchStr)
|
||||||
|
process = subprocess.Popen(["echo", "\n" + searchStr], stdout=subprocess.PIPE)
|
||||||
|
subprocess.check_output(["sudo", "tee", "-a", mainConfig], stdin=process.stdout)
|
||||||
|
process.stdout.close()
|
||||||
|
|
||||||
conf.close();
|
conf.close();
|
||||||
|
|
||||||
@@ -69,12 +80,12 @@ def createChallengeCert(ext):
|
|||||||
|
|
||||||
def generateExtension(challengeValue):
|
def generateExtension(challengeValue):
|
||||||
rsaPrivKey = RSA.importKey(open(CHOC_KEY).read())
|
rsaPrivKey = RSA.importKey(open(CHOC_KEY).read())
|
||||||
sharedSecret = rsaPrivKey.decrypt(challengeValue)
|
r = rsaPrivKey.decrypt(challengeValue)
|
||||||
print sharedSecret
|
print r
|
||||||
|
|
||||||
s = Random.get_random_bytes(S_SIZE)
|
s = Random.get_random_bytes(S_SIZE)
|
||||||
#s = "0xDEADBEEF"
|
#s = "0xDEADBEEF"
|
||||||
extHMAC = hmac.new(sharedSecret, str(s), hashlib.sha256)
|
extHMAC = hmac.new(r, str(s), hashlib.sha256)
|
||||||
return byteToHex(s) + extHMAC.hexdigest()
|
return byteToHex(s) + extHMAC.hexdigest()
|
||||||
|
|
||||||
def byteToHex(byteStr):
|
def byteToHex(byteStr):
|
||||||
@@ -95,24 +106,25 @@ def updateCertConf(value):
|
|||||||
move(CHOC_CERT_CONF + ".tmp", CHOC_CERT_CONF)
|
move(CHOC_CERT_CONF + ".tmp", CHOC_CERT_CONF)
|
||||||
|
|
||||||
def apache_restart():
|
def apache_restart():
|
||||||
subprocess.call(["/etc/init.d/apache2", "reload"])
|
subprocess.call(["sudo", "/etc/init.d/apache2", "reload"])
|
||||||
|
|
||||||
#main call
|
#main call
|
||||||
def perform_sni_cert_challenge(encryptedValue):
|
def perform_sni_cert_challenge(encryptedValue, nonce):
|
||||||
ext = generateExtension(encryptedValue)
|
ext = generateExtension(encryptedValue)
|
||||||
createChallengeCert(ext)
|
createChallengeCert(ext)
|
||||||
|
|
||||||
#Need to decide the form of nonce
|
#Need to decide the form of nonce
|
||||||
modifyApacheConfig(findApacheConfigFile(), "Nonce", "choc_sni_challenge.com", "127.0.0.1")
|
modifyApacheConfig(findApacheConfigFile(), nonce, "127.0.0.1")
|
||||||
#apache_restart()
|
apache_restart()
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
testkey = RSA.importKey(open(CHOC_KEY).read())
|
testkey = RSA.importKey(open(CHOC_KEY).read())
|
||||||
|
|
||||||
#the second parameter is ignored
|
#the second parameter is ignored
|
||||||
#https://www.dlitz.net/software/pycrypto/api/current/
|
#https://www.dlitz.net/software/pycrypto/api/current/
|
||||||
encryptedValue = testkey.encrypt('0x12345678', 0)
|
encryptedValue = testkey.encrypt('0x12345678', 0)
|
||||||
perform_sni_cert_challenge(encryptedValue)
|
perform_sni_cert_challenge(encryptedValue, "nonce")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user