Version 5, last updated by tzangerl at November 15, 2010 UTC
Using the automatic revocation interface
Motivation
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.
Automatic revocation interface explained in 20 seconds
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.
Automatic revocation interface step by step
Uploading a certificate identifying the client to the portal
- Get a certificate for the client. If you can't get a certificate for your client elsewhere, you can create a self-signed one. One way to achieve this is by doing something like
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 - Upload the certificate to Confusa. You can find the section for uploading certificates in "subscriber admin" -> "Certificates" -> "Robot"
- If uploading the certificate was successful you should be able to see the certificate in "Subscriber-Admin" -> "Certificates" -> "Robot" -> "List":
Using the revocation functions from a client
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.
- List all users with valid certificates (HTTPS POST to host, include one parameter)
POST (URL) https://confusahost.example.org/ri.php (param1) action=cert_list - Revoke certificates of certain users (HTTPS POST to host, include two POST parameters)
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>
Simple example code (python)
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.
Why isn't this part of Confusa's REST-API?
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.