If institutions have a large number of issued certificates, revocation of certificates for employees who leave the institution can become a cumbersome process. The automatic revocation interface enables institutions to automate that process by integrating employee management with certificate revocation.
If you are a subscriber admin, you can upload a X.509 certificate to the portal that will identify the revocation client. The same X.509 certificate can be used by the revocation client to sign XML revocation requests that it sends to Confusa.
openssl req -new -newkey rsa:2048 -subj "/C=SE/O=KTH/OU=PDC/CN=Confusa Client hawaii.pdc.kth.se" \
-out automatic_revocation.pem -keyout automatic_revocation.key -x509 -days 365
The client is identified by using HTTPS certificate client authentication. On top of a connection with HTTPS client authentication that uses the uploaded certificate your revocation application can send HTTP POST calls to https://confusahost.example.org/ri.php.
POST (URL) https://confusahost.example.org/ri.php
(param1) action=cert_list
POST (URL) https://confusahost.example.org/ri.php
(param1) action=revoke_list
(param2) list=<?xml version="1.0">
<ConfusaRobot date="2010-09-10 15:44:44"
subscriber=""
version="1.0"
elementCount="2">
<revocationList>
<listElement uid="someuid@example.org" />
<listElement uid="someotheruid@example.org" />
</revocationList>
</ConfusaRobot>
import time, xml.sax.handler, urllib, urllib2
import Parser
from Timeout import Timeout, TimeoutException
from HTTPSClient import HTTPSClientAuthHandler
import xml.etree.ElementTree as ET
class Confusa_Client:
def __init__(self, key, cert, url):
"""
Constructor, set the keypair to use for AuthN and the URL to connect to.
"""
self.https_client = HTTPSClientAuthHandler(key, cert)
self.url = url
def get_list(self):
"""
Returns the list of users with valid certificates.
"""
self.data = urllib.urlencode({ 'action' : 'cert_list' })
return self.execute().get_list(True)
def send_revoke_list(self, eppn_list):
"""
Send a list of users for which all certificates should be revoked.
eppn_list is an array, each line with a revokeCert-dictionary entry on the form
{'eppn' : <name>, 'fulllDN' : <dn> , 'count' : <count>}
Only eppn will be used, the rest are optional and will be discarded
"""
# Is list set properly?
if (not eppn_list or not len(eppn_list) > 0):
print "Too short list, aborting"
return
post = { 'action' : 'revoke_list' }
# Construct the XML-message
foundElements = 0
root = ET.Element("ConfusaRobot")
root.set("date", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
root.set("subscriber", "") # not used, determined from certificate
root.set("version", "1.0")
rev = ET.SubElement(root, "revocationList")
list = ""
for i in eppn_list:
if 'uid' in i:
le = ET.SubElement(rev, "listElement")
le.set("uid", i['uid'])
foundElements += 1
if foundElements == 0:
print "No elements found, aborting"
return
if foundElements != len(eppn_list):
print "\nErrors with supplied data, length of list is not equal to number of valid entries"
print "This may prove to be a minor detail, continuing\n"
root.set("elementCount", "%d" % foundElements)
post['list'] = ET.tostring(root)
self.data = urllib.urlencode(post)
return self.execute().get_list(False)
def execute(self, timeout=60):
"""
execute()
Connect to the URL and send POST-data. The returned data will
be passed to ConfusaParser, and either an array of
dictionary-entries or None will be returned.
"""
# Get the result and parse it
opener = urllib2.build_opener(self.https_client)
t = Timeout(timeout)
try:
res = opener.open(self.url, self.data)
except xml.sax._exceptions.SAXParseException:
t.cancel_timeout()
return None
except TimeoutException:
print "Did not receive a timely answer (%s seconds), aborting" % (timeout)
return None
t.cancel_timeout()
return Parser.Parser(res)
The example code is also available in Confusa's Git tree.
Because the automatic revocation interface was part of Confusa before the REST-API, we sometimes discuss too little and there is this general lack of time that is plaguing us.