1
0
mirror of https://github.com/certbot/certbot.git synced 2026-01-26 07:41:33 +03:00

Adding sni_challenge verification

This commit is contained in:
James Kasten
2012-06-26 20:01:52 -04:00
parent deb9ce0a4e
commit abb4673fd8
5 changed files with 126 additions and 0 deletions

9
ca/sni_challenge/make.sh Normal file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
#Quick script to compile/load sni_support
#Will change to something more appropriate in the future
#Modify python path
swig -python sni_support.i
gcc -fpic -I/home/james/virtualenvs/chocolate/include/python2.7 -c sni_support_wrap.c sni_support.c
gcc -shared sni_support_wrap.o sni_support.o -o _sni_support.so

View File

@@ -0,0 +1,19 @@
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
#include "sni_support.h"
void set_sni_ext(SSL *ctx, char *servername) {
SSL_set_tlsext_host_name(ctx, servername);
}
int get_nid(X509_EXTENSION *ext) {
return OBJ_obj2nid(X509_EXTENSION_get_object(ext));
}
binary_data_t get_unknown_value(X509_EXTENSION *ext) {
binary_data_t result;
result.size = ext->value->length;
result.data = (unsigned char *)ext->value->data;
return result;
}

View File

@@ -0,0 +1,13 @@
#ifndef SNI_SUPPORT_H
#define SNI_SUPPORT_H
typedef struct binary_data {
int size;
unsigned char* data;
} binary_data_t;
void set_sni_ext(SSL *ctx, char *servername);
int get_nid(X509_EXTENSION *ext);
binary_data_t get_unknown_value(X509_EXTENSION *ext);
#endif

View File

@@ -0,0 +1,13 @@
%module sni_support
%{
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#include "sni_support.h"
%}
%typemap(out) binary_data_t {
$result = PyString_FromStringAndSize($1.data,$1.size);
}
%include "sni_support.h"

View File

@@ -0,0 +1,72 @@
import M2Crypto
import sni_support
import hmac
import hashlib
S_SIZE = 20
def check(one, two, three, four, five):
print "done"
return 0
def byteToHex(byteStr):
return ''.join(["%02X" % ord(x) for x in byteStr]).strip()
def check_challenge_value(ext_value, sharedSecret):
s = ext_value[0:S_SIZE]
mac = ext_value[S_SIZE:]
expected_mac = hmac.new(sharedSecret, str(s), hashlib.sha256).digest()
#print "s: ", byteToHex(s)
#print "mac: ", byteToHex(mac)
#print "expected_mac: ", byteToHex(expected_mac)
#print type(mac)
#print type(expected_mac)
if mac == expected_mac:
return True
return False
def verify_challenge(address, sharedSecret, encryptedValue):
sni_name = byteToHex(encryptedValue[0]) + ".com"
context = M2Crypto.SSL.Context()
context.set_allow_unknown_ca(True)
context.set_verify(M2Crypto.SSL.verify_none, 4)
conn = M2Crypto.SSL.Connection(context)
sni_support.set_sni_ext(conn.ssl, sni_name)
conn.connect((address, 443))
cert_chain = conn.get_peer_cert_chain()
#Ensure certificate chain form is correct
if len(cert_chain) != 1:
return False, "Incorrect number of certificates in chain"
for i in range(0,cert_chain[0].get_ext_count()):
ext = cert_chain[0].get_ext_at(i)
if sni_support.get_nid(ext.x509_ext) == 0:
valid = check_challenge_value(sni_support.get_unknown_value(ext.x509_ext), sharedSecret)
if valid:
return True, "Challenge completed successfully"
else:
return False, "Certificate extension does not check out"
def main():
#Testing the example sni_challenge
from Crypto.PublicKey import RSA
testkey = RSA.importKey(open("/home/james/Documents/apache_choc/testing.key").read())
#the second parameter is ignored
#https://www.dlitz.net/software/pycrypto/api/current/
encryptedValue = testkey.encrypt('0x12345678', 0)
valid, response = verify_challenge("127.0.0.1", '0x12345678', encryptedValue)
print response
if __name__ == "__main__":
main()