Sanic: How to reach SSL context inside a handler

Created on 22 Mar 2017  路  5Comments  路  Source: sanic-org/sanic

So I am trying to build a system where clients can optionally provide client side certificates. These client side certificates need to be accessible from the request handler, does anyone have any advice of how I can intercept the SSL processing for client certificates or is this impossible.

Most helpful comment

Hello @jkbbwr , I found peer certificate in request's transport:

@app.route("/")
async def test(request):
    peer_cert = request.transport._ssl_protocol._extra.get('peercert')
    subject = dict([x[0] for x in peer_cert.get('subject')])
    return json({"hello": subject.get('commonName')})

All 5 comments

Hello @jkbbwr , I found peer certificate in request's transport:

@app.route("/")
async def test(request):
    peer_cert = request.transport._ssl_protocol._extra.get('peercert')
    subject = dict([x[0] for x in peer_cert.get('subject')])
    return json({"hello": subject.get('commonName')})

@hedin What settings did you set for the SSL context to get the certificate, I get None or Protocol error no matter what I try

@jkbbwr Maybe its because I use CERT_REQUIRED in my project, so I'm sure peer cert will always be in a context
The whole code I used for testing looks like:

import os
import ssl
from sanic import Sanic
from sanic.response import json

PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
CERT_DIR = os.path.join(PROJECT_ROOT, 'certificates')

ctx = ssl.SSLContext(protocol=ssl.PROTOCOL_TLSv1_2)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.load_verify_locations(os.path.join(CERT_DIR, 'CA.crt'))
ctx.load_cert_chain(
    certfile=os.path.join(CERT_DIR, 'webserver.crt'),
    keyfile=os.path.join(CERT_DIR, 'webserver.key')
)

app = Sanic()


@app.route("/")
async def test(request):
    peer_cert = request.transport._ssl_protocol._extra['peercert']
    subject = dict([x[0] for x in peer_cert.get('subject')])
    return json({"hello": subject.get('commonName')})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000, ssl=ctx)

Can I ask how you generated all the certificates. I must be doing something wrong because everything gives me curl: (35) Unknown SSL protocol error in connection

Here is my recent post about TLS mutual auth. Its in russian but you can copy code from there, or even download certs using links at the end.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ubergarm picture ubergarm  路  4Comments

Souldat picture Souldat  路  3Comments

geekpy picture geekpy  路  4Comments

eseglem picture eseglem  路  4Comments

litelife picture litelife  路  3Comments