Working client and server.
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import requests
|
import requests
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='certclient')
|
parser = argparse.ArgumentParser(description='certclient')
|
||||||
@@ -20,11 +21,6 @@ parser.add_argument(
|
|||||||
dest='client_key',
|
dest='client_key',
|
||||||
action='store',
|
action='store',
|
||||||
required=True)
|
required=True)
|
||||||
parser.add_argument(
|
|
||||||
'--csr',
|
|
||||||
dest='csr',
|
|
||||||
action='store',
|
|
||||||
required=True)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--server',
|
'--server',
|
||||||
dest='server',
|
dest='server',
|
||||||
@@ -35,7 +31,7 @@ FLAGS = parser.parse_args()
|
|||||||
|
|
||||||
class CertClient(object):
|
class CertClient(object):
|
||||||
|
|
||||||
def __init__(self, server, ca_cert, client_cert, client_key, csr):
|
def __init__(self, server, ca_cert, client_cert, client_key):
|
||||||
self._session = requests.Session()
|
self._session = requests.Session()
|
||||||
self._session.verify = ca_cert
|
self._session.verify = ca_cert
|
||||||
self._session.cert = (client_cert, client_key)
|
self._session.cert = (client_cert, client_key)
|
||||||
@@ -43,11 +39,12 @@ class CertClient(object):
|
|||||||
'Content-Type': 'application/x-pem-file',
|
'Content-Type': 'application/x-pem-file',
|
||||||
})
|
})
|
||||||
self._server = server
|
self._server = server
|
||||||
self._csr = csr
|
|
||||||
|
|
||||||
def Request(self):
|
def Request(self, csr):
|
||||||
with open(self._csr, 'r') as fh:
|
resp = self._session.post(self._server, data=csr)
|
||||||
self._session.post(self._server, data=fh.read())
|
assert resp.status_code == requests.codes.ok
|
||||||
|
assert resp.headers['Content-Type'] == 'application/x-pem-file'
|
||||||
|
return resp.text
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@@ -55,9 +52,9 @@ def main():
|
|||||||
FLAGS.server,
|
FLAGS.server,
|
||||||
FLAGS.ca_cert,
|
FLAGS.ca_cert,
|
||||||
FLAGS.client_cert,
|
FLAGS.client_cert,
|
||||||
FLAGS.client_key,
|
FLAGS.client_key)
|
||||||
FLAGS.csr)
|
cert = client.Request(sys.stdin.read())
|
||||||
client.Request()
|
print(cert, end='')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import json
|
||||||
from http import server
|
from http import server
|
||||||
import socket
|
import socket
|
||||||
import ssl
|
import ssl
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='certserver')
|
parser = argparse.ArgumentParser(description='certserver')
|
||||||
@@ -33,6 +35,11 @@ parser.add_argument(
|
|||||||
dest='server_cert',
|
dest='server_cert',
|
||||||
action='store',
|
action='store',
|
||||||
required=True)
|
required=True)
|
||||||
|
parser.add_argument(
|
||||||
|
'--sign-command',
|
||||||
|
dest='sign_command',
|
||||||
|
action='store',
|
||||||
|
required=True)
|
||||||
FLAGS = parser.parse_args()
|
FLAGS = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
@@ -42,15 +49,31 @@ class HTTPServer6(server.HTTPServer):
|
|||||||
|
|
||||||
class CertServer(object):
|
class CertServer(object):
|
||||||
|
|
||||||
def __init__(self, listen_host, listen_port, server_key, server_cert, ca_cert):
|
def __init__(self, listen_host, listen_port, server_key, server_cert, ca_cert, sign_command):
|
||||||
|
|
||||||
class RequestHandler(server.BaseHTTPRequestHandler):
|
class RequestHandler(server.BaseHTTPRequestHandler):
|
||||||
def do_POST(self):
|
def do_POST(self):
|
||||||
|
print('Request from: [%s]:%d' % (self.client_address[0], self.client_address[1]))
|
||||||
|
peer_cert = json.dumps(dict(x[0] for x in self.request.getpeercert()['subject']), sort_keys=True)
|
||||||
|
print('Client cert:\n\t%s' % peer_cert.replace('\n', '\n\t'))
|
||||||
assert self.headers['Content-Type'] == 'application/x-pem-file'
|
assert self.headers['Content-Type'] == 'application/x-pem-file'
|
||||||
size = int(self.headers['Content-Length'])
|
size = int(self.headers['Content-Length'])
|
||||||
print(self.rfile.read(size))
|
cert = self.rfile.read(size)
|
||||||
self.send_response(200)
|
|
||||||
self.end_headers()
|
with subprocess.Popen(sign_command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
|
||||||
|
proc.stdin.write(cert)
|
||||||
|
proc.stdin.close()
|
||||||
|
signed = proc.stdout.read()
|
||||||
|
stderr = proc.stderr.read().decode('ascii')
|
||||||
|
print('OpenSSL output:\n\t%s' % stderr.replace('\n', '\n\t').strip())
|
||||||
|
if proc.wait() == 0:
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-Type', 'application/x-pem-file')
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(signed)
|
||||||
|
else:
|
||||||
|
self.send_response(500)
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
self._httpd = HTTPServer6((listen_host, listen_port), RequestHandler)
|
self._httpd = HTTPServer6((listen_host, listen_port), RequestHandler)
|
||||||
self._httpd.socket = ssl.wrap_socket(
|
self._httpd.socket = ssl.wrap_socket(
|
||||||
@@ -73,7 +96,8 @@ def main():
|
|||||||
FLAGS.listen_port,
|
FLAGS.listen_port,
|
||||||
FLAGS.server_key,
|
FLAGS.server_key,
|
||||||
FLAGS.server_cert,
|
FLAGS.server_cert,
|
||||||
FLAGS.ca_cert)
|
FLAGS.ca_cert,
|
||||||
|
FLAGS.sign_command)
|
||||||
server.Serve()
|
server.Serve()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user