Direct Certificate Authority –

Over the past few months Videntity has built a robust, fully-functional certificate authority designed specifically with the Direct Project in mind. (You can find the Direct Project wiki here). The original motivation behind building “The Direct Certificate Authority (CA)” or just “Direct CA” was facilitating Meaningful Use stage 2 testing and specifically health information systems’ compliance with the Direct Applicability Statement. One requirement in particular, testing revocation, required the use of an actual certificate authority that managed CRLs. It also turns out asking for a certificates to support Direct is a tall order with most CA’s because most are unfamiliar with the unique requirements and nuances of the Direct Project. Various CA’s often handle revocation differently, further complicating matters. The other freely available tool for building X509 certificates that will work with Direct is called “certGen”. certGen is a good tool, but lacks support for revocation (i.e. Certificate Revocation Lists (CRLs) and/or OSCP). Hence, Direct CA was born.

Direct CA is a web-based tool so there is no software to install. Its designed around the notion of “Trust Anchors” whereby a “Trust Anchor” acts like a miniature Certificate Authority. Subordinate (i.e child) email-address-bound and domain-bound certificates are created with the Trust Anchor as the parent. Direct CA also publishes all public certificates to the web automatically in common certificate formats (.pem and .der). Certificate Revocation Lists (CRLs) are generated and published on a per-trust-anchor basis get automatically updated every few hours.

Anyone may use Direct CA for free to create certificates for testing purposes. If interested, simply request an invitation code.. We hope this tool makes Direct development and implementation a little easier.

Here are answers to commonly asked questions.

Q: Can I use this software to manage my own organization’s certificate authority or HISP / Trust Anchor)?

A: Yes. Contact sales AT videntity dot com or complete the contact form for more information.

Q: Is Direct CA open source?

A: No. The service is free, but the source code is not public. Contact usfor more information on our shared source options.

Q: I see reference to a file x5c file. What’s that all about?

A: Unlike how certificates work within web browsers, with Direct the Applicability Statement has no requirement to check the certificate chain back to the root CA’s certificate. Direct only requires checking the chain back to the trust anchor. Its debatable on whether or not this is a security issue, but DirectC A creates and publishes the full chain in a convenient JSON format just in case you DO wish to check the validity of the entire chain. The “x5c” file is an “X509 certificate chain” file in JSON format. The format complies with the IETFdraft for JSON Web Key (JWK) for Public Key Infrastructure (X.509) (PKIX) Certificates. Thanks to Josh Mandel for suggesting basing this feature of the work by the Javascript Object Signing and Encryption (JOSE).

DISCLAIMER: Use of this tool by government organizations does not imply recommendation or endorsement. DirectCA is for testing purposes and is provided “as-is” without warranty.


Redirect to another URL in Django urls

Things have changed a bit in Django 1.5 with respect to how redirects work without writing a view. In Django 1.5, you must use “RedirectView”, but what may not be too obvious is that “reverse” does not work with “RedirectView”. You must to use “reverse_lazy” instead. I couldn’t find a complete example of this anywhere and hence it prompted me to write this post and answer this question on Stack Overflow. Hope this is helpful to someone.

Example using RedirectView and reverse_lazy:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4
# Copyright 2013 Videntity  
# Freely reuse under the terms of
# Last Updated: Aug 7 , 2013 

from django.conf.urls import patterns, include, url
from django.views.generic import RedirectView
from django.core.urlresolvers import reverse_lazy

# Uncomment the next two lines to enable the admin:
from django.contrib import admin


urlpatterns = patterns('',
    url(r'^$', 'home', name='website_home'),
    url(r'^redirect-home/$', RedirectView.as_view(url=reverse_lazy('website_home')), name='redirect_home'),


So in the above example, the url “/redirect-home” will redirect to “/”. Hope this helps.


ce – Certificate Examiner

This is a quick command-line utility for displaying information contained in an SSL certificates and CRLs. It is faster and easier to remember than the OpenSSL commands on which it is based. It allows you specify only a certificate’s filename. It guesses the certificate’s type based on the filename extension. This works with most pem, der, and p12 formatted files using common extension conventions.


> ce


        Version: 3 (0x2)
        Serial Number: 4861619212740627522 (0x4377f0ea809e8c42)
    Signature Algorithm: sha1WithRSAEncryption


OpenSSL is a prerequisite. Execute the following commands to ensure that “ce” is on your path and that it executes without invoking Python directly.

> sudo cp ce /usr/bin 
> sudo chmod 755 /usr/bin/ce

Source Code for ce

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4
# Copyright 2013 Videntity  
# Freely reuse under the terms of
# Last Updated: September 10 , 2013 

import os, sys
def certificate_explain(certfile):
    tmplower = certfile.lower()
    if tmplower.endswith("der"):
        certype = "der"
    elif tmplower.endswith("pem") or tmplower.endswith("crt"):
        certype = "pem"
    elif tmplower.endswith("p12") or tmplower.endswith("pfx"):
    elif tmplower.endswith("crl"):
       print "Unrecognized file extension.  The file must end in der, pem, crt, p12, pfx, or crl."
    if certype in ("pem", "der"):
        shellcmd = "openssl x509 -in %s -inform %s -noout -text" % (certfile,
    if certype == "p12":
        shellcmd = "openssl pkcs12 -info -in %s" % (certfile)
    if certype == "crl":
        shellcmd = "openssl crl -in %s -noout -text" % (certfile)
if __name__ == "__main__":
    if len(sys.argv)!=2:
        print "Usage: [CERT_FILENAME]"


A Command-line Utility & Library to Fetch Revoked Serial Numbers from a Certificate Revocation List (CRL)

This functionality is not available in openssl’s comand line utility, so I cooked this up to do the job. The library function returns a Python list and when used as a command-line utility it returns a JSON list. You will need to install pyOpenSSL. One way to do that is “pip install pyOpenSSL”.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4

import OpenSSL
import json, sys

def get_revoked_serials(path_to_crl):
    revoked_list = []
    with open(path_to_crl, 'r') as _crl_file:
        crl = "".join(_crl_file.readlines())
    crl_object = OpenSSL.crypto.load_crl(OpenSSL.crypto.FILETYPE_PEM, crl)
    revoked_objects = crl_object.get_revoked()
    for rvk in revoked_objects:
    return revoked_list

if __name__ == "__main__":
    if len(sys.argv)!=2:
        print "Usage: python [filepath]"
    rs = get_revoked_serials(sys.argv[1])
    print json.dumps(rs)

And here is how you use it.

    > python /opt/ca/crl/videntity-ca-crl.pem

TODO items:

  • Accept a URL or a local file path.
  • Accept an x509 certificate and follow the CRL distribution point URLs.

A Collection of Handy Django Authentication Backends

This blog entry desribes three Django Authenticaon backends you can use instead of the default “django.contrib.auth.backends.ModelBackend”. Below is a brief description of each.

EmailBackend – This allows the user to use wither his or her username or his or her email address to log in. Not you have to make sure that usernames and email addresses are unique across all users in order for this to work properly.

MobilePhoneBackend -This allows the user to login with his or her mobile phone number and password instead of using the user name. This assumes you have a UserProfile model defined with the field “mobile_phone_number”.

HTTPAuthBackend – A standard HTTP Auth backend. Use this for APIs. This one just username and password, but by using this method, it is easy to access you system like a web service.

Here is an example of using the HTTPAuth backend via curl.

curl -u "myuser:mypass" -X GET

Here is the file containing the Authentication Backends

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4

# A collection of handy authentication Backends. Copyright Videntity 2012.
# License: BSD

from django.contrib.auth.models import User
from django.core.validators import email_re
import binascii
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.models import User, AnonymousUser
from django.contrib.auth.decorators import login_required
from django.template import loader
from django.contrib.auth import authenticate
from django.conf import settings
from django.core.urlresolvers import get_callable
from django.core.exceptions import ImproperlyConfigured
from django.shortcuts import render_to_response
from django.template import RequestContext
from models import UserProfile

class BasicBackend:
    def get_user(self, user_id):
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

class EmailBackend(BasicBackend):
    def authenticate(self, username=None, password=None):
        #If username is an email address, then try to pull it up
                user = User.objects.get(email=username)
            except User.DoesNotExist:
                return None
            #We have a non-email address username we should try username
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                return None
        if user.check_password(password):
            return user
class MobilePhoneBackend(BasicBackend):
    def authenticate(self, username=None, password=None):
            up = UserProfile.objects.get(mobile_phone_number=username)
        except UserProfile.DoesNotExist:
            return None
        if up.user.check_password(password):
            return up.user
class HTTPAuthBackend(BasicBackend):
    def __init__(self, auth_func=authenticate, realm='API'):
        self.auth_func = auth_func
        self.realm = realm

    def is_authenticated(self, request):
        auth_string = request.META.get('HTTP_AUTHORIZATION', None)
        if not auth_string:
            return False
            (authmeth, auth) = auth_string.split(" ", 1)

            if not authmeth.lower() == 'basic':
                return False

            auth = auth.strip().decode('base64')
            (username, password) = auth.split(':', 1)
        except (ValueError, binascii.Error):
            return False
        request.user = self.auth_func(username=username, password=password) \
            or AnonymousUser()
        return not request.user in (False, None, AnonymousUser())
    def authenticate(self, request):
        auth_string = request.META.get('HTTP_AUTHORIZATION', None)

        if not auth_string:
            return AnonymousUser
            (authmeth, auth) = auth_string.split(" ", 1)

            if not authmeth.lower() == 'basic':
                return AnonymousUser

            auth = auth.strip().decode('base64')
            (username, password) = auth.split(':', 1)
        except (ValueError, binascii.Error):
            return AnonymousUser
        request.user = self.auth_func(username=username, password=password) \
            or AnonymousUser()
        return not request.user in (False, None, AnonymousUser())
    def challenge(self):
        resp = HttpResponse("Authorization Required")
        resp['WWW-Authenticate'] = 'Basic realm="%s"' % self.realm
        resp.status_code = 401
        return resp

    def __repr__(self):
        return u'<HTTPBasic: realm=%s>' % self.realm

How to Use the Backends in your Application

Define AUTHENTICATION_BACKENS in Note that I have commended out ModelBackend. This is because the EmailBackend checks both the user/password combination and the email/password combinations.

AUTHENTICATION_BACKENDS = (#'django.contrib.auth.backends.ModelBackend',

When attempting to use HTTPAuthBackend when using Apache/mod_wsgi, you’ll need to tell WSGI to pass the authorization to the Django application. You do this in a your Apache2 configuration file. On Ubuntu Linux this file might live at “/etc/apache2/sites-available/default”. In your virtualhost configuration for your Django application, you need to add the line “WSGIPassAuthorization On” right below the “WSGIScriptAlias” line.

Here is an example:

<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www
	<Directory />
		Options FollowSymLinks
                AllowOverride AuthConfig
	<Directory /var/www/>
		Options Indexes FollowSymLinks MultiViews
		AllowOverride None
		Order allow,deny
		allow from all
        WSGIScriptAlias / /home/ubuntu/django-apps/RESTCat/config/apache/django.wsgi
        WSGIPassAuthorization On
        Alias /static/admin/ /var/www/djadminstatic/
        Alias /static/ /home/ubuntu/django-apps/RESTCat/mainstatic/

	ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
	<Directory "/usr/lib/cgi-bin">
		AllowOverride None
		Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
		Order allow,deny
		Allow from all

	ErrorLog ${APACHE_LOG_DIR}/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn

	CustomLog ${APACHE_LOG_DIR}/access.log combined

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from ::1/128


Hope this helps someone.


How to Make Django Se Habla Español

This is a short how-to and checklist for getting Django to server
your app in another langauge. In this case, Spanish.

Modifications to Your Python Code

In views, forms, and models use ugettext_lazy on all strings that will be rendered to the user.

    from django.utils.translation import ugettext_lazy as _ 

Everywhere you have a string, yo need to add _:

#So this...
verbose_name = "This is a model label"
#becomes this...
verbose_name = _("This is a model label")

Modifications to Your Templates

In your templates load the i18n machinery

    {% load i18n %}

and then put all strings that you want to traslate in {% trans %} like so..

{% load i18n %}
{% trans "this is a string to translate"%} 
{% trans "this is another string"%} 

Management Commands in the Console

Now its time to build out the “po” files that can be given to the translator.
In your project’s home directory, create a directory to hold the translations:

mkdir locale

Now make files for spanish.

python makemessages -l es

This will create a file in “yourproject/locale/es/LC_MESSAGES/django.po”.

This is the text file that will contain the translation. The English string is the “key”, called the msgid. You must fill in the msgstr value in spanish for each string.

Now after the translation, you also need to compile to po file. You do this like so.

python compilemessages

Settings File

But wait! Thats not all. We need to make sure we have everything we need in the settings file.

Make sure all this is set in your settings file

USE_I18N = True

Add the middleware class for Locale (not sure this is actually documented)

    'django.middleware.locale.LocaleMiddleware',  #  <-- Add this line

Make sure Django knows where you placed your files.
I also did not find this in the documentation. A friend helped.

    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(BASE_DIR, 'locale'),

Now set your browser’s langauge to spanish “ES”. Now you should be muy bueno.


Calculating BMI in Python

If you ever need to calculate Body Mass Index (BMI) in Python, here’s how…

    def bmi_calc(height, weight):
        # height is in inches
        # weight is in pounds (lbs.)
        bmi=(float(weight) * 703) / (float(height) * float(height))
        bmi="%.1f" %(bmi)
        return bmi



Some HL7 IP will soon be Open Source

We at Videntity are glad to hear that most of the HL7 IP will soon be open source. We hope the spirit of data liberation continues in the health IT industry.


The Problem with Using an HL7-based Format for Blue Button

I’d rather not compete with HL7, but the current state leaves me no choice but to speak up.

Yes it would be a step in the right direction if HL7’s IP was public. I have no issue with the idea of HL7 holding copyrights, charging for memberships, and voting rights. I just have an issue with its closed nature. W3C may be expensive but their standards are public and well adopted through industry. When HL7 adopts this model, I can perhaps embrace HL7 as a workable solution. Until then I’ll continue to beat the drum of using something else that is open source.

Hypothetically speaking if the ABBI content working group used CCDA as its format, then we would be forbidden by HL7 from actually putting the CCDA specification and the ABBI implementation guide out for public comment. In fact, some people within the ABBI working group may not even be able to review the work because they are not members of HL7 and thus forbidden to see the specification. Not a very transparent process.

Another issue with CCDA is the fact there are not complete XSDs (XML schemas) published by HL7. This makes its implementation subject to interpretation, which leads to interoperability problems. They do have a schema, but only a “top level”. The XSD should be exhaustive and it needs at a public URL so that there is one source of truth. This is how XML and XSD are supposed to work.

I’d make the point there is a big difference between an “open source implementation” and an “open source specification”. To paraphrase HTML inventor, Tim Berners Lee, “Regardless if you play your music on a million dollar pipe organ, or on a toddler’s xylophone, everyone should have the right to learn how to read the music and know what the notes mean.” If the meaning of music notes was a closed secret requiring membership, we would have a lot less music in the world wouldn’t you say? I’m all for the rights of businesses and individuals to develop proprietary software, open source software, or something in between. The specification for information interchange, however, should be open and transparent.

I’m not so sure the either XML or JSON is the right format, because neither meet the ABBI goal of human readability without some sort of software transformation. This makes things more complicated for the patient.

I’m thinking it should look a lot closer to the VA’s existing Blue Button format with some tweaks to make it easier to transform into a machine-friendly format. In this way we are still building off what is already done and we are maintaining the goal of human readability.


Get the Latest Object or a 404 in Django : get_latest_object_or_404

The get_object_or_404 is a handy Django shortcut. It keeps my views shorter.

In my case however, I had the need to get the latest object. In my situation I have surveys that can be asked more than one time to the same person. I want to fetch the most recent survey only.

get_object_or_404(Survey, patient_id=1234)  
#this could result in more than one object and may fail.

What I really want to do is soemthing like this:

get_object_or_404(Survey, patient_id=1234, latest=True)
#This does not work

..but alas Django doesn’t let me do that. A quick scan of the Django source code gave me a hint to build a custom function to handle my use case. Below is my utility called “get_latest_object_or_404″, which always gets the latest object and thus ensures that I always only fetch one object and said object is the newest. This of course requires that you have latest defined in your model’s Meta class. So here goes.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4

from django.http import Http404
from django.shortcuts import _get_queryset

def get_latest_object_or_404(klass, *args, **kwargs):
    Uses get().latest() to return object, or raises a Http404 exception if
    the object does not exist.

    klass may be a Model, Manager, or QuerySet object. All other passed
    arguments and keyword arguments are used in the get() query.

    Note: Like with get(), an MultipleObjectsReturned will be raised if more than one
    object is found.
    queryset = _get_queryset(klass)
        return queryset.filter(*args, **kwargs).latest()
    except queryset.model.DoesNotExist:
        raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)

I hope someone else finds this little contribution to the Django community useful. I think it should be added to the django.shortcuts library. Maybe I’ll propose that. Enjoy!