Showing posts with label identity. Show all posts
Showing posts with label identity. Show all posts

Jun 16, 2013

Novay's NFC Passport Reader

At Novay, as part of a project for EIT ICT Labs on Mobile Security & Privacy, we have been working hard on an Android app, based on JMRTD, to demonstrate how passports (and identity cards) and the passport holder can be validated. The first version of our efforts is now available from the Play Store.



Now the underlying ePassport Java library JMRTD was ported to Android almost two years ago in a proof-of-concept app. The new Novay app focuses on two new features. First, it makes the passport reading experience as user friendly as possible. The UI is up to 4.x standards, and has been better thought out. We're looking at showing the information as soon as possible as it comes in over the (awfully slow) NFC connection, while at the same time making sure that the user understands that the document needs to held in proximity to the device for the couple of seconds that it takes to read all of the information.


Second, and more importantly, the new app uses the security mechanisms of the chip embedded in a passport to their full potential. This means that the authenticity of the contents and of the chip are actually checked, and the results are displayed to the user.

We're working on a next version this app in a second phase of this project. We still see plenty of possibilities to improve the usability. 

People at Novay involved are: Peter Ebben, Ruud Kosman, and myself. Thanks to Atlantic Zeiser for providing the sample document that was used in the screenshots above and in the Play Store.

Oct 27, 2009

RSA Conference Europe 2009

I attended RSA Conference Europe 2009 in London the other week, where I gave a presentation on something I blogged about before (combining ePassports and Information Card, a project sponsored by NLnet). My talk was scheduled for the very last slot on the very last day, which means I had plenty of time to go and listen to the other talks. Some of my impressions are below.



I checked out the booths of the conference's sponsors and noticed a relative large number of authentication factor vendors (G&D, Kobil, smspasscode.com) and of course the big guys (RSA Security, Microsoft, Qualys, CA).

As for the presentations, there were at least 4 different tracks, and all talks had catchy titles. Very difficult to choose from. There were a lot of "securing the cloud" talks. I've heard people claim that 'cloud==deperimeterization'. Others claim that 'cloud==virtualization', and yet others claim that 'cloud==SaaS', and even 'cloud==social networks'. Most of the talks dealt with managing the risks of enterprise cloud computing (sharing resources is risky, you'll need good SLA contracts for that). I especially liked the Collateral Hacking panel session which focused on the risk presented by totally unrelated parties you happen to share services with.

There were a few hacking-presentations. I really enjoyed Björn Brolin and Marcus Murray's Breaking the Windows driver signing model. Great live reversing demo. Bottom line: Running an anti-virus suite with badly engineered (yet Microsoft signed) kernel drivers can actually render your PC less secure from malware.

Talking about anti-virus software vendors. Both McAfee's Anthony Bettini's and Kaspersky labs' Stefan Tanase's presentation focused on threats from social networks (personalized spam, Twitter based C&C, targeted attacks based on synchronization between personal and enterprise information). Anthony had the best sound-bites IMHO: 'open-sourcing one's life', 'keep your enemies closer'. Stefan showed a glimpse of crawler based technology that Kaspersky's R&D team in Romania is working on.

More targeted social network threats came from Brian Honan who introduced the audience to some of the tools of the trade, notable pipl.com and Maltego. Interestingly, in Ireland, anyone can request everyone else's birth certificate (apparently for reasons of genealogical research), and the only thing needed to request a driver's license or passport in Ireland is a birth certificate.

Microsoft's keynote was delivered by Amy Barzdukas. She made some valid points about the perception of privacy and security by the average computer user. The FUD (initially directed at Google: Chrome's auto-completing address bar will send packets to Google, OMG, better stick with IE8) was a little too much for my taste. They're going to make it more difficult to download and install third party software through IE because of the fake virus scanner scams.

The keynote by special agent Mularski of the FBI and Andy Auld of SOCA about the Russian Business Network was so secret that I cannot blog about it. The keynote by Dave Hansen of CA on content-aware extensions of RBAC was pretty interesting and included another secret agent.

Andrew Nash of PayPal gave an insightful presentation on the consumer identity bootstrap problem. After explained the clever big bang/steady state analogy he showed just how big the problem is. What's the most important feature an Identity Provider should offer to its users? Right. Anonymity. The other PayPal presentation was by Hadi Nahari who put forward some requirements (or rather, desirements) for identity in mobile computing. It appears that PayPal is trying to get some of these ideas into the Global Platform specifications.

Ira Winkler went on a one-hour rant over the use of the term information warfare. Funny stuff, except for the one Estonian guy in the audience.

Jun 17, 2009

OpenID with OpenASelect - Part 4

Finally, here's the oa.xml (yes, it's big, I know):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE oa-server
[
  <!ENTITY server "ldap://ldapserver:389">
  <!ENTITY base "OU=Institute,DC=corporate,DC=domain,DC=com">
  <!ENTITY user "user@domain.com">
  <!ENTITY password "changeme">
]>

<oa-server>


  <!-- Server Configuration -->

  <server id="openid.domain.com" friendlyname="Institute OpenID Server">
   <organization id="Institute OpenID" friendlyname="Institute OpenID" />
  </server>


  <!-- Engine Configuration -->

  <crypto>
   <message_digest algorithm="SHA1" />
   <random_generator algorithm="SHA1PRNG" />
  </crypto>

  <sessionfactory class="com.alfaariss.oa.engine.session.memory.MemorySessionFactory">
   <expire>900</expire>
    <interval>60</interval>
    <max>100</max>
  </sessionfactory>

  <tgtfactory class="com.alfaariss.oa.engine.tgt.memory.MemoryTGTFactory">
   <expire>3600</expire>
    <interval>60</interval>
    <max>100</max>
  </tgtfactory>


  <!-- User Provisioning -->

  <userfactory class="com.alfaariss.oa.engine.user.provisioning.ProvisioningFactory">
   <main>
    <translator>standard</translator>
   </main>
   <translator id="standard" class="com.alfaariss.oa.engine.user.provisioning.translator.standard.StandardTranslator">
    <main>
      <externalstorage>ext_jndi</externalstorage>
      <profile>jndi</profile>
    </main>
    <profile id="jndi" class="com.alfaariss.oa.engine.user.provisioning.translator.standard.StandardProfile">
      <account>
       <enabled default="true" field="userPrincipalName" converter="exist" />
       <authentication>
        <method id="JNDIPassword">
          <registered default="true" />
        </method>
       </authentication>
      </account>
      <convertermanager>
       <converter id="exist" class="com.alfaariss.oa.engine.user.provisioning.translator.standard.converter.exist.ExistConverter" />
      </convertermanager>
    </profile>
   </translator>

   <storagemanager>
    <storage id="ext_jndi" class=".external.jndi.JNDIExternalStorage">
      <resource>
       <driver>com.sun.jndi.ldap.LdapCtxFactory</driver>
       <url>&server;</url>
       <ssl>false</ssl>
       <security_principal>
        <dn>&user;</dn>
        <password>&password;</password>
       </security_principal>
       <dn>
        <base>&base;</base>
        <user>userPrincipalName</user>
       </dn>
      </resource>
    </storage>
   </storagemanager>
  </userfactory>

  <attributegatherer id="ax_attribgather" friendlyname="Gatherer" enabled="true">
   <!-- AX axschema.org -->
   <processor id="axschemaorg_jndi" friendlyname="JNDI axschema.org AX Attribute Gatherer"
    class="com.alfaariss.oa.engine.attribute.gather.processor.jndi.JNDIGatherer">
    <resource>
      <driver>com.sun.jndi.ldap.LdapCtxFactory</driver>
      <url>&server;</url>
      <ssl>false</ssl>
      <security_principal>
       <dn>&user;</dn>
       <password>&password;</password>
      </security_principal>
      <dn>
       <base>&base;</base>
       <user>userPrincipalName</user>
      </dn>
    </resource>

    <gather>
      <attribute name="c" />
      <attribute name="company" />
      <attribute name="description" />
      <attribute name="givenName" />
      <attribute name="l" />
      <attribute name="mail" />
      <attribute name="mobile" />
      <attribute name="name" />
      <attribute name="postOfficeBox" />
      <attribute name="postalCode" />
      <attribute name="sAMAccountName" />
      <attribute name="sn" />
      <attribute name="telephoneNumber" />
      <attribute name="title" />
      <attribute name="wWWHomePage" />
    </gather>
    <mapper>
      <map int="http://axschema.org/namePerson/friendly" ext="sAMAccountName" />
      <map int="http://axschema.org/namePerson" ext="name" />
      <map int="http://axschema.org/namePerson/prefix" ext="title" />
      <map int="http://axschema.org/namePerson/first" ext="givenName" />
      <map int="http://axschema.org/namePerson/last" ext="sn" />
      <map int="http://axschema.org/company/name" ext="company" />
      <map int="http://axschema.org/company/title" ext="description" />
      <map int="http://axschema.org/contact/phone/default" ext="telephoneNumber" />
      <map int="http://axschema.org/contact/phone/cell" ext="mobile" />

      <map int="http://axschema.org/contact/postalAddress/business" ext="postOfficeBox" />
      <map int="http://axschema.org/contact/city/business" ext="l" />
      <map int="http://axschema.org/contact/country/business" ext="c" />
      <map int="http://axschema.org/contact/postalCode/business" ext="postalCode" />
      <map int="http://axschema.org/contact/email" ext="mail" />
      <map int="http://axschema.org/contact/web/default" ext="wWWHomePage" />
    </mapper>
   </processor>

   <!-- AX openid.net/schema -->
   <processor id="openidnet_jndi" friendlyname="JNDI axschema.org AX Attribute Gatherer"
    class="com.alfaariss.oa.engine.attribute.gather.processor.jndi.JNDIGatherer">
    <resource>
      <driver>com.sun.jndi.ldap.LdapCtxFactory</driver>
      <url>&server;</url>
      <ssl>false</ssl>
      <security_principal>
       <dn>&user;</dn>
       <password>&password;</password>
      </security_principal>
      <dn>
       <base>&base;</base>
       <user>userPrincipalName</user>
      </dn>
    </resource>

    <gather>
      <attribute name="c" />
      <attribute name="company" />
      <attribute name="description" />
      <attribute name="givenName" />
      <attribute name="l" />
      <attribute name="mail" />
      <attribute name="mobile" />
      <attribute name="name" />
      <attribute name="postOfficeBox" />
      <attribute name="postalCode" />
      <attribute name="sAMAccountName" />
      <attribute name="sn" />
      <attribute name="telephoneNumber" />
      <attribute name="title" />
      <attribute name="wWWHomePage" />
    </gather>
    <mapper>
      <map int="http://openid.net/schema/namePerson/prefix" ext="title" />
      <map int="http://openid.net/schema/namePerson/first" ext="givenName" />
      <map int="http://openid.net/schema/namePerson/last" ext="sn" />
      <map int="http://openid.net/schema/namePerson/friendly" ext="sAMAccountName" />
      <map int="http://openid.net/schema/contact/phone/default" ext="telephoneNumber" />
      <map int="http://openid.net/schema/contact/postaladdress/business" ext="postOfficeBox" />
      <map int="http://openid.net/schema/contact/city/business" ext="l" />
      <map int="http://openid.net/schema/contact/country/business" ext="c" />
      <map int="http://openid.net/schema/contact/postalcode/business" ext="postalCode" />
      <map int="http://openid.net/schema/contact/internet/email" ext="mail" />
      <map int="http://openid.net/schema/contact/web/default" ext="wWWHomepage" />
      <map int="http://openid.net/schema/company/name" ext="company" />
      <map int="http://openid.net/schema/company/title" ext="description" />
    </mapper>
   </processor>

   <!-- AX schema.openid.net -->
   <processor id="schemaopenidnet_jndi" friendlyname="JNDI axschema.org AX Attribute Gatherer"
    class="com.alfaariss.oa.engine.attribute.gather.processor.jndi.JNDIGatherer">
    <resource>
      <driver>com.sun.jndi.ldap.LdapCtxFactory</driver>
      <url>&server;</url>
      <ssl>false</ssl>
      <security_principal>
       <dn>&user;</dn>
       <password>&password;</password>
      </security_principal>
      <dn>
       <base>&base;</base>
       <user>userPrincipalName</user>
      </dn>
    </resource>

    <gather>
      <attribute name="c" />
      <attribute name="company" />
      <attribute name="description" />
      <attribute name="givenName" />
      <attribute name="l" />
      <attribute name="mail" />
      <attribute name="mobile" />
      <attribute name="name" />
      <attribute name="postOfficeBox" />
      <attribute name="postalCode" />
      <attribute name="sAMAccountName" />
      <attribute name="sn" />
      <attribute name="telephoneNumber" />
      <attribute name="title" />
      <attribute name="wWWHomePage" />
    </gather>

    <mapper>
      <map int="http://schema.openid.net/namePerson/prefix" ext="title" />
      <map int="http://schema.openid.net/namePerson/first" ext="givenName" />
      <map int="http://schema.openid.net/namePerson/last" ext="sn" />
      <map int="http://schema.openid.net/namePerson/friendly" ext="sAMAccountName" />
      <map int="http://schema.openid.net/contact/phone/default" ext="telephoneNumber" />
      <map int="http://schema.openid.net/contact/postaladdress/business" ext="postOfficeBox" />
      <map int="http://schema.openid.net/contact/city/business" ext="l" />
      <map int="http://schema.openid.net/contact/country/business" ext="c" />
      <map int="http://schema.openid.net/contact/postalcode/business" ext="postalCode" />
      <map int="http://schema.openid.net/contact/internet/email" ext="mail" />
      <map int="http://schema.openid.net/contact/web/default" ext="wWWHomepage" />
      <map int="http://schema.openid.net/company/name" ext="company" />
      <map int="http://schema.openid.net/company/title" ext="description" />
    </mapper>
   </processor>

   <!-- AX verify.sxip.com -->
   <processor id="sxip_jndi" friendlyname="JNDI axschema.org AX Attribute Gatherer"
    class="com.alfaariss.oa.engine.attribute.gather.processor.jndi.JNDIGatherer">
    <resource>
      <driver>com.sun.jndi.ldap.LdapCtxFactory</driver>
      <url>&server;</url>
      <ssl>false</ssl>
      <security_principal>
       <dn>&user;</dn>
       <password>&password;</password>
      </security_principal>
      <dn>
       <base>&base;</base>
       <user>userPrincipalName</user>
      </dn>
    </resource>

    <gather>
      <attribute name="mail" />
    </gather>
    <mapper>
      <map int="http://verify.sxip.com/schema/verifiedEmail" ext="mail" />
    </mapper>
   </processor>

   <!-- SREG -->
   <processor id="sreg_jndi" friendlyname="JNDI SREG Attribute Gatherer"
    class="com.alfaariss.oa.engine.attribute.gather.processor.jndi.JNDIGatherer">
    <resource>
      <driver>com.sun.jndi.ldap.LdapCtxFactory</driver>
      <url>&server;</url>
      <ssl>false</ssl>
      <security_principal>
       <dn>&user;</dn>
       <password>&password;</password>
      </security_principal>
      <dn>
       <base>&base;</base>
       <user>userPrincipalName</user>
      </dn>
    </resource>
    <gather>
      <attribute name="c" />
      <attribute name="mail" />
      <attribute name="name" />
      <attribute name="postalCode" />
      <attribute name="sAMAccountName" />
    </gather>
    <mapper>
      <map int="nickname" ext="sAMAccountName" />
      <map int="email" ext="mail" />
      <map int="fullname" ext="name" />
      <map int="postcode" ext="postalCode" />
      <map int="country" ext="c" />
    </mapper>
   </processor>
  </attributegatherer>

  <attributerelease class="com.alfaariss.oa.engine.attribute.release.configuration.ConfigurationFactory">
   <policy id="releasepolicy.1" friendlyname="Release Policy" enabled="true">
    <attribute name="*" />
   </policy>
  </attributerelease>


  <!-- Business Logic -->

  <requestorpoolfactory class="com.alfaariss.oa.engine.requestor.configuration.ConfigurationFactory">
   <pool id="requestorpool.1" friendlyname="OpenID Requestor Pool" enabled="true">
    <authentication forced="false">
      <profile id="authentication.openid" />
    </authentication>
    <attributerelease policy="releasepolicy.1" />
    <requestors type="sp">
      <requestor id="openid" friendlyname="OpenID requestor" enabled="true" />
    </requestors>
   </pool>
  </requestorpoolfactory>

  <authentication class="com.alfaariss.oa.engine.authentication.configuration.ConfigurationFactory">
   <profile id="authentication.openid" friendlyname="Login" enabled="true">
    <method id="JNDIPassword" />
   </profile>
  </authentication>


  <!-- Web SSO -->

  <websso single_sign_on="true">
   <cookie domain="domain.com" />
   <view>
    <profile_selection path="/ui/sso/select.jsp" />
    <user_info path="/ui/sso/user_info.jsp" />
    <logged_out path="/ui/sso/logged_out.jsp" />
   </view>
   <authentication always_show_select_form="false">
    <methods>

      <method id="JNDIPassword" friendlyname="Password Authentication"
           class="com.alfaariss.oa.authentication.password.PasswordAuthenticationMethod">
       <template path="/ui/sso/authn/password/password.jsp" />
       <retries>3</retries>
       <password_handler class="com.alfaariss.oa.authentication.password.jndi.JNDIPasswordHandler">
        <resource realm="@domain.com">
          <full_uid>true</full_uid>
          <driver>com.sun.jndi.ldap.LdapCtxFactory</driver>
          <url>&server;</url>
          <ssl>false</ssl>
          <security_principal>
           <dn>&user;</dn>
           <password>&password;</password>
          </security_principal>
          <dn>
           <base>&base;</base>
           <user>userPrincipalName</user>
          </dn>
        </resource>
       </password_handler>
      </method>

    </methods>
   </authentication>
  </websso>


  <!-- IdP Profiles -->

  <profiles>

   <profile id="openid" class="com.alfaariss.oa.profile.openid.OpenIDProcessor">
    <privatestore>memory</privatestore>
    <sharedstore>memory</sharedstore>
    <usermapping>simple</usermapping>
    <interval>86400</interval>
    <expirytime>1800</expirytime>
    <endpoint>https://openid.domain.com/openaselect/profiles/openid/</endpoint>
    <confirmationpage>/ui/profiles/openid/authz_consumer.jsp</confirmationpage>
    <xrdsdocument>/ui/users/xrds/xrds.jsp</xrdsdocument>
    <userdocument>/ui/users/user.jsp</userdocument>
    <error>
      <jsp path="/ui/profiles/openid/error.jsp" />
    </error>
    <websso>
      <path>/sso/web</path>
    </websso>
    <associationstores>
      <associationstore id="memory" class="org.openid4java.server.InMemoryServerAssociationStore"/>
    </associationstores>
    <mappings>
      <mapping id="simple" class="com.alfaariss.oa.profile.openid.mapping.SimpleMapping">
       <config>
        <idtemplate>https://openid.domain.com/[username]</idtemplate>
       </config>
      </mapping>
    </mappings>
    <extensions>
      <extension id="http://openid.net/extensions/sreg/1.0"
      class="com.alfaariss.oa.profile.openid.extension.sreg.SimpleRegistrationProcessor" param_signing="true" enabled="true" />
      <extension id="http://openid.net/extensions/sreg/1.1"
      class="com.alfaariss.oa.profile.openid.extension.sreg.SimpleRegistrationProcessor" param_signing="true" enabled="true" />
      <extension id='http://openid.net/srv/ax/1.0'
      class="com.alfaariss.oa.profile.openid.extension.ax.AttributeExchangeProcessor" param_signing="true" enabled="true" />
    </extensions>
   </profile>

  </profiles>


  <!-- Helpers -->

  <helpers>
   <helper id="stylesheet" enabled="true"
    class="com.alfaariss.oa.helper.stylesheet.StyleSheetHelper">
    <default location="http://openid.domain.com/css/style.css" />
   </helper>
  </helpers>

</oa-server>

Jun 1, 2009

OpenID with OpenASelect - Part 3


Now that my OpenASelect server is running it's time to make it a bit more attractive and robust. Apart from creating flashy JSPs based on our corporate CSS style this means:
  • Make the user URL as short as possible, something like openid.domain.com/username
  • Better yet, instead of the full User Principal Name (UPN) (which includes as a domain @domain.com) I want users to be able to use firstname.lastname
  • Allow users to also use firstname.lastname (without the domain) when they use openid.domain.com as URL (the OAS server asks the user to enter both the user name and the password in that case)
  • Secure the server with a certificate (our authentication is password based, after all)
Most of these issues can be resolved by placing a regular httpd server in front of the Tomcat server (using mod_proxy). The advantage is that mod_rewrite can then be used to allow user to be sloppy with their UPN in omnidirectional identifiers.

The regular httpd server accepts connections on port 80 and proxies these to the Tomcat server which has an AJP connector on port 8009:
ProxyPassReverse /openaselect/ ajp://localhost:8009/openaselect/
ProxyPass /openaselect/ ajp://localhost:8009/openaselect/

Clients can remain unaware of the fact that pages under openaselect/ are actually served by the Tomcat server and not by the httpd server they are connected to. On top of that I used mod_rewrite to get prettier URLs:
RewriteRule ^/([A-Za-z0-9]+\.[A-Za-z0-9]+)$ http://openid.novay.nl/openaselect/profiles/openid/users/$1@domain.com [P,L]
The rewriting trick works well for omnidirectional identifiers in which the username is part of the OpenID URL. When the user merely enters http://openid.novay.nl at an RP and the actual OpenID URL is established through discovery things get a bit more complex. The rewriting needs to be done at a slightly deeper level. The configuration file links to Java classes for many of the sub-processes. In my oa.xml most of these classes are standard Alfa & Ariss classes, for example I used a StandardTranslator inside the user provisioning process. I replaced the reference to this class with my own SloppyUPNTranslator so that users can leave out the domain part of their UPN. Deploying is done by adding the class to a jar file and dropping it inside the lib/ directory within WEB-INF. My translator simply wraps a StandardTranslator and overrides the translate(String) method by adding a "@novay.nl" to the argument before calling the wrapped translator.

Am I finished playing with OAS as OpenID provider? For now. But there are plenty of loose ends that I intend to investigate later on:
  • Session identifiers when the user merely uses https://openid.novay.nl with an RP, the discovered URL can be used to track the user. I'd like to see if OAS can be tweaked to use a per-RP, or even per-session, pseudonym here.
  • Other, innovative, authentication methods. Perhaps smart card based.
  • Deploy OAS in Google App Engine. Not connected to our AD, of course. Just to see if it's possible: Looks like the server uses some threads, not sure if these are necessary.
Acknowledgment: Joost Reede of Alfa & Ariss was of invaluable help configuring the server and explaining OpenASelect basics. Thanks!

May 28, 2009

OpenID with OpenASelect - Part 2


The OpenID profile is configured from the main OpenASelect oa.xml configuration file. The default OpenID profile (from the OpenASelect site) only needed minor changes. There are two parameters which need to be set:
  • The <endpoint>: http://localhost:8080/openaselect/profiles/openid/
  • The <idtemplate>: http://localhost:8080/openaselect/profiles/openid/users/[username]
They both look too ugly to be used by actual users, but changing them requires hiding the Tomcat server behind a regular httpd, which I'll cover in part 3 of this post. For testing I left them as they are since my Tomcat runs at port 8080.

I first tried to get OpenID to work with the identifying authentication method and file based user provisioning. This basically means that when the user goes to the RP and enters an OpenID with a user name that is present in users.xml then this should result in an authentication that is accepted by the RP. If he enters a user name that is not present in the file then it should fail.

Next step was to replace the user provisioning and the identifying authentication method with something that actually checks with our corporate AD server to see if a user can present valid credentials. For testing I configured OpenASelect to use my personal credentials to get access to LDAP (in an actual deployment one would probably create a dedicated user, called Security Principal in oa.xml, for this). The settings I needed to know were:
  • The server, something like "ldap://host:389"
  • The base, something like "OU=Intitute,DC=Corporate,DC=domain,DC=com"
  • The user name and the password of the security principal
There are several sections in oa.xml where these credentials have to be repeated, so it's a good idea to define them as <!ENTITY> elements somewhere near the top of the file.

I introduced JNDI authentication in two steps: first, change the user provisioning to use JNDI (JNDI is the Java interface to LDAP) and keep the identifying authentication method, although replacing the identifying authentication method with a JNDI password authentication method actually proved to be completely trivial. The userPrincipalName field with a so-called "exist-converter" is what I used in the translator part of the userfactory. This means that the identifiers for users look something like firstname.lastname@domain.com. You can get rid of the @domain.com part in several ways. I'll cover this in part 3.

Now that authentication works, it's time to look at attribute release. OpenID has two extensions which deal with this: SREG and AX. I wanted support for both of them.
Then AX. There's an <extensions> section in the OpenID profile bit of oa.xml. I needed to set param_signing to true.

The attribute gathering process is configured in the <attributegatherer> section of oa.xml. I made a processor for SREG (SREG uses a fixed set of attribute names: nickname, email, fullname, postcode, country are the names for which I found an equivalent in our AD) and several processors for AX (AX attribute names are identified using schema URLs, there are actually a couple of schemas with good RP support, so I included a processor for each of: http://axschema.org, http://openid.net/schema, http://schema.openid.net, and http://verify.sxip.com/schema). Each processor maps LDAP attributes (the external name) to SREG or AX attributes (the internal name). A small problem I ran into here is that the mapping characteristic of this part of the configuration makes it rather hard to export, for example, the telephone number found in our AD to two distinct AX attribute names (default and business phone number).

The result, besides a rather lengthy configuration file is an OpenASelect server that talks to our AD and acts as an OP. The PHP based OpenID RP I had running locally can be used to test the authentication and SREG functionality (it doesn't seem to support AX yet).

In part 3 I'll hide tomcat behind a regular httpd and try to improve the overall end-user experience.

May 26, 2009

OpenID with OpenASelect - Part 1


OpenID is a popular online identity management framework (standard?). In an attempt to get some hands-on experience with it I decided to see if I could provide our company's Active Directory server (an LDAP like service which authenticates users for access to their Windows desktops and also contains identity attributes available to email clients such as Outlook) with an OpenID interface so that it can be used as an OP towards external RPs. Sort of like Sun's OP, but for Novay employees.

How to become an OP? There's a list of open source APIs and libraries for different languages and servers. Alfa & Ariss' OpenASelect server seemed appropriate for my purposes as it can talk OpenID and LDAP and runs on top of Tomcat. Also, since Alfa & Ariss is just around the corner from our office it's easy to ask for help (thanks Joost!).

I set up a box with Fedora, postgreSQL, and Tomcat and deployed the OpenASelect war based app. After restarting Tomcat I ran the database creation scripts and my OpenASelect server was up and running.

Configuring is done by editing the oa.xml file whose format is described extensively on the OpenASelect website. The configuration file roughly consists of three sections (roughly, because these do not correspond logically one-to-one with the top-level elements in the file):
  • User (and attribute) provisioning
  • Authentication method
  • Protocol profiles (such as OpenID)
Obviously, I wanted to start with a minimal configuration file. I was thinking of using the file based user provisioning (which uses a users.xml file containing user names and additional attributes) with htpasswd based password authentication (which, yes, uses a htpasswd file). Get that to work first and add OpenID and LDAP later.

A problem I ran into at that point: there's no other way to test the freshly installed OpenASelect server than to have some external service (the RP) use the identity server. So, it actually turned out to be easier to install the OpenID profile (a seperate download, unzip it on top of the deployed OpenASelect, run some database creation scripts, restart). Since our AD server is behind the corporate firewall I had to install an OpenID RP locally to test against (OpenID, though user-centric, apparently needs the RP to be able to communicate directly with the OP). The simple PHP OpenID RP is great for this purpose.

Also, there's an authentication method called identifying method which is much easier for testing than password based authentication.

Part 2 describes how I got OpenID to work and how I connected the OpenASelect server to the AD back-end.

Mar 31, 2009

Security in the workspace - Part 3


It seems that we will have to learn to live and work in a de-perimeterized world. Acceptance of the problem is often the first step towards a solution. So, what alternatives to perimeter defense are there? And what is the impact of these alternatives on the future workspace and vice versa? Below are some thoughts. I hesitate to call these conclusions. Please consider these as starting points for a discussion.
  • Defense in depth is the complete opposite of perimeter defense (when considering the location where controls are implemented). This security principle advises to apply multiple layers of security controls, so that if one layer fails other layers take over.
    • Unfortunately, complete defense in depth is increasingly expensive as it is difficult to maintain,
    • and because too many layers of security get in the way. (Is there a usabilty vs security trade-off? I'm not sure. But usability is probably not helped with adding multiple layers of security.)

  • Most experts see a shift from perimeter defense (and other location based defenses) to data oriented security. (Perhaps that should be information oriented security?)
    • Because of the multiple contexts in which employees now process data, this requires some sort of watermarking of sensitive and valuable data. If, for example, lost information can be tracked back to employees responsible for that information than those employees can be held accountable for the loss. But wasn't DRM declared dead?
    • Moreover, data oriented security makes valuation of information necessary: relative sensitivity and value to the organization should be made explicit. Valuation of assets should be done anyway (as part of information risk management), but that doesn't mean that it is easy, cheap or common practice today!
    • Related to the above point: information should be stored and processed with a clear goal in mind (for reasons of Governance, Regulations, Complicance). This is at least as difficult as valuation.

  • Accountability (the other A-word) may be an alternative to access control. Access control is somewhat problematic in the absence of a perimeter after all. Access control is expensive in the future workspace since employees join and leave the organization on a more regular basis (access credentials management is costly). Accountability certainly seems to be more compatible with the greater responsibility given to employees as part of the future workspace trends.

  • Identity management is necessary, as accountability usually means a great deal of logging (of actions of employees). Logging obviously requires the capability to distinguish between employees (try holding individuals accountable for their actions when you can't tell them apart). However, since we left the perimeter behind us, we can't rely on the classical identity management process which involves provisioning, authentication, and authorization.
    • The provisioning problem could be overcome if we could use an established identity provider's infrastructure which extends beyond the bounds of the organization. The existing identity provider (I'm thinking of national governments) has the infrastructure for issuing authentication means to individuals already in place. If such a global identity provider is not (yet) possible, federated identity management and user-centric identity management may be alternatives (in the mean time).
    • Authentication has to be done decentralized (in absense of a perimeter with check points) and preferably as often as possible yet also as unobtrusive as possible. Perhaps context-information could help here?
    • Authorization, on the other hand, is better done centralized so as to achieve consistent rules which are easy to manage. Well-defined roles could be useful here
Other points? Leave a comment!

Feb 2, 2009

The ePassport helps fight online identity fraud


This translation of an article in Dutch newspaper het Financiƫle Dagblad, 2 februari 2009, pp. 7 was created by Google translate (with only slight modifications by hand). The Dutch version also appears elsewhere on the interwebs.

A new tool in the fight against identity fraud has arrived. The Dutch ePassport with chip can be used as additional identification technology for Internet transactions. Without loss of privacy.

This is evident from NLnet Foundation funded research Martijn Oostdijk and Dirk-Jan van Dijk of the Telematica Institute have done. Using a simple card reader, the chip can be read on any PC. The standards to do this are public. The researchers developed software for an identity provider - a trusted party that creates digital identities and provides these to other parties - which they run on a server at the institute. Furthermore, the duo developed software that must be installed on the client's PC.

With passport in hand, the user may enter a web shop. The shop might need to know if the buyer is older than 18. The identity provider filters out only the information from the passport required for the purchase, and forwards that information to the shop. The buyer remains in charge of his own data and can terminate the transaction at any moment. The process is intended as additional evidence. Often, a user needs various account names and passwords to use various online services. But such credentials, also credit cards, etc. may fall into the wrong hands. Of course, a passport can also be stolen. "This is why the passport by itself should not be used as identification. But in combination with other authentication means it could stop simple forms of identity theft", said Michiel Leenaars, strategy director of Stichting NLnet. According to Martijn Oostdijk, the system is suitable for all forms of identification. "It's not just for online purchases. The system might play a role in safe surfing by children or patient access to electronic health records, etc."

Identity fraud is costing society billions of euros per year. In the U.S., the damage last year was 31 billion euro. At present, slightly less than half of all Dutch citizens have a passport or identity card with chip. In 2011, that will be the case for all citizens.

NLnet Foundation is committed to an open information society and supports projects that contribute financially. Software developed within the projects are published as "open source" and is freely available for parties who wish to further develop it. The Telematica Institute combines innovation power and knowledge of IT to achieve breakthroughs in how we live.