anchor/ephemeral_ca/__init__.py
2014-03-21 14:30:23 +00:00

115 lines
2.7 KiB
Python

#!/usr/bin/env python
"""
FlaskCA
"""
import M2Crypto
import fcntl
import os
import sys
import time
import uuid
import yaml
from flask import Flask, request, redirect, Response
CONFIG = {}
app = Flask(__name__)
#ToDo: Write some actual authentication routines.
def auth(secret,user,authtype):
if authtype == 'bypass-backdoor':
if secret=='woot' and user=='woot':
return True
return False
def sign(csr,encoding):
if encoding != 'pem':
return False
with open(CONFIG['serial_file'], 'a+') as f:
f.seek(0)
fcntl.lockf(f, fcntl.LOCK_EX)
serial = int(f.read() or "1")
f.seek(0)
f.truncate(0)
f.write(str(serial+1))
ca = M2Crypto.X509.load_cert(CONFIG["ca_cert"])
key = M2Crypto.EVP.load_key(CONFIG["ca_key"])
req = M2Crypto.X509.load_request_string(csr.encode('ascii'))
new_cert = M2Crypto.X509.X509()
new_cert.set_version(0)
now = int(time.time())
start_time = M2Crypto.ASN1.ASN1_UTCTIME()
start_time.set_time(now)
end_time = M2Crypto.ASN1.ASN1_UTCTIME()
end_time.set_time(now+(CONFIG['valid_hours']*60*60))
new_cert.set_not_before(start_time)
new_cert.set_not_after(end_time)
new_cert.set_pubkey(pkey=req.get_pubkey())
new_cert.set_subject(req.get_subject())
new_cert.set_issuer(ca.get_subject())
new_cert.set_serial_number(serial)
new_cert.sign(key, CONFIG['signing_hash'])
new_cert.save(os.path.join(
CONFIG['certs_directory'],
'%06i-%s.crt' % (serial, new_cert.get_fingerprint(CONFIG['signing_hash']))))
return new_cert.as_pem()
@app.route("/")
def fail():
return 'Nothing to see here\n', 404
@app.route("/robots.txt")
def robots():
txt = "User-agent: *\nDisallow: /\n"
return txt, 200
@app.route("/sign",methods=['POST'])
def sign_request():
"""
for key in ('user','authtype','csr','encoding','secret'):
if not request.args.has_key(key):
print '%s key missing from request:' % key
print request.args.keys()
return 'Request is missing keys!\n', 500
"""
if not auth(request.form['secret'],request.form['user'],request.form['authtype']):
return 'Authentication Failure\n', 403
cert = sign(request.form['csr'],request.form['encoding'])
if not cert:
return 'Signing Failure\n', 500
#TODO: Probably need some nice headers or some other schtuff
return cert, 200
def read_config(path):
global CONFIG
with open(path, 'r') as f:
CONFIG = yaml.load(f)
def run_server():
read_config(sys.argv[1] if len(sys.argv) > 1 else 'config.yaml')
app.run(
debug=CONFIG['flask_debug'],
host=CONFIG['bind_host'],
port=CONFIG['bind_port'])