Dec 7, 2009

SIM security and GSM security


In the old days the SIM was there to control access to the GSM network. A GSM 11.11 compliant handset would forward an authentication request from the network to the SIM by issuing RUN_GSM_ALGORITHM command. And that was it. The threat landscape was clear (unauthenticated access to the network) and security of the solution relied entirely on the security of the SIM.

The SIM application toolkit complicates things, however. A GSM 11.14 compliant handset implements a complex protocol which involves polling multiple Java Card applets and message passing from and to the network and the GUI. If the handset correctly implements this protocol then SIM applets have a trusted interface to the user during so-called proactive SIM sessions. This means, for example that an application on the handset (a MIDlet, say) cannot interfere with the GUI during such sessions. (GSM 11.14 doesn't actually say that, but other ETSI standards such as ETSI 102 206 seem to rely on this.)

Some weeks ago a worm targeting jailbroken iPhones was discovered. The iPhone (besides being a lot of other things) is a GSM handset which implements GSM 11.14 at some level. Big question is: is a jailbroken iPhone still a GSM 11.14 compliant hand set?

With smart phone operating systems becoming more open (and users demanding control over them) this is getting more interesting. Perhaps a hypervised approach is the solution. In any case, it's not as simple as it used to be.

Nov 18, 2009

Variable Road Pricing

We seem to be getting variable road pricing over here in the Netherlands. Which generates a lot of discussion, of course. The Dutch ministry of transport has a nice high level overview including a diagram with some interfaces of the system:


I haven't made a detailed security analysis of this system, obviously. But couldn't one simply block the incoming GPS signal (say, using a GPS jammer). Better yet, why not relay the signal from a stationary GPS receiver at home to your on board unit?

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.

Oct 19, 2009

Two ideas I could have submitted to the SIMagine contest


Here are two ideas I could have submitted to the SIMagine contest, but didn't. ;)
  1. Info Cards securely stored in your SIM: Florian van Keulen, one of Maarten's students did a project on different architectures for implementing Info Card on mobile devices. One of the options that Florian investigated was to store the Info Cards on the SIM. A handset resident application would then facilitate communication between the Card Selector on a different platform (a PC in an Internet cafe) and the SIM through Bluetooth.
  2. Turning an existing contactless smart card into a pre-paid mobile SIM application: You're not supposed to be able to clone an ePassport or contactless creditcard, of course. But you can do something else. You can pre-record some challenge-response pairs using an NFC handset and store these in an application on the secure element (SE, usually the SIM card) of the handset. If the application can authenticate itself to an inspection system (a POS terminal) then the handset can be used instead of the original contactless card. This improves convenience: one device instead of multiple cards, you now have a GUI. As for security: You can limit the number of challenge-response pairs, you can time-stamp the challenge-response pairs (the SE can connect to some trusted time server during enrollment), etc.
Oh well, deadline expired, never mind.

Oct 1, 2009

Mobile PKI


Mobile PKI, also known as Wireless PKI (and a lot of other names such as Mobile Secure Signature Service, Secure Signature Creation Device, ...) is a technology which allows users to place electronic signatures with their cell phone. This can be used for applications that run on the phone, but also for applications that run on other platforms (the user's computer connected to the Internet, for instance). One could use this, for example, as an authentication mechanism at a relying party. In the latter scenario your phone is a "something-you-have" token which provides extra security as an attacker would have to manipulate two separate channels to mount an attack. Before placing a signature, the cell phone will ask the user for his or her PIN.

The SIM card inside the cell phone plays a central role in Mobile PKI. Actually, the obvious way to implement Mobile PKI is through a so-called SIM Application Toolkit (SAT) applet installed on the SIM card. SAT has some really cool features that make things easy, both for the mobile operator and for the user:
  • They can be installed over the air (OTA) to an already deployed SIM by the mobile operator, without disturbing the user
  • They can add extra (basic menu-based) features to the GUI
  • They can react to events such as selection of menus by the user or incoming SMSs sent by the mobile operator
This makes Mobile PKI a pretty secure solution:
  • The application resides on a tamper resistant smart card
  • Most handset manufacturers will make sure that there's a trusted path from the phone's keyboard to SAT applications (the malware problem seems to still be small for the mobile platform)
  • The separate channel advantage was already mentioned above
It's also user-friendlier when compared to other authentication solutions such as smart cards, PKI tokens, and one-time-password SMSs:
  • The PIN is the same for each and every transaction
  • There's no need to install software on the user's PC
  • There's no need to read and type challenges or responses
  • Most users will not forget or leave their cell phone unattended, and most will notice and report a missing or stolen phone
Mobile PKI has been standardized by ETSI around 2002/2003. Also Common Criteria protection profiles for Secure Signature Creation Devices have existed since 2001. So the technology is pretty old. It has found its way to end-customers in some countries, most notably Turkey and more recently to the Nordic countries (in Finland you can apparently even add your government issued eID to a SIM card). Most of the SIM manufacturers and technology providers offer Mobile PKI as an option to their customers (the mobile operators). I wonder why this hasn't caught on here in the Netherlands.

Aug 13, 2009

Anti-skimming measures

Someone glued small pieces of metal to the PIN entry pad at the POS of my local self-service gas station. It must have been one of the good guys, because it says "veiligheidsstrip" at the bottom.

Certainly raises security awareness amongst customers...

(Until they get used to it and the bad guys manage to produce mini cameras that look like small pieces of metal.)

Jun 20, 2009

How to trust Country Signing Certificates

I've collected a number of country signing (public key) certificates of different ePassport issuing countries who have put their certificates online. Most of these were brought to my attention by Google's alert service.

The global ICAO PKI for signing ePassports is actually a forrest of many national PKIs. And each national PKI is only 2 levels deep (depending on where you start counting):
  • CSCA: Country Signing Certificate Authority
  • DSCA: Document Signing Certificate Authority
  • AA: Active Authentication "certificate" (which really is not part of the PKI, as this is not a certificate but a raw public key, signed implicitly in the security document of the ePassport)
All of this becomes more complex now that we are moving towards Extended Access Control, but the fact remains that the lack of a central trusted CA makes it difficult to bootstrap trust. ICAO has proposed two alternatives:
  • The central ICAO Public Key Directory (PKD)
  • Country cross signing of CSCs
The first alternative is really an online facility which issues claims about (document) signers. The usual drawbacks apply: single point of failure, cost of maintaining infrastructure, etc. The second alternative involves having each country (or at least as many countries as possible) sign each other's certificates.

Is it possible to have a central CA instead? Some of the government Web sites where I (or rather, Google) found the CSCA certificates are protected using SSL, at least the Dutch site is (yes, I know, the certificate has expired, but I downloaded the CSCA certificate before the expiration date of the server certificate). I could have recorded the SSL transaction while downloading that CSCA certificate and I could have made that part of the CSCA certificate itself. Unfortunately, the commercial CA (in this case Verisign) which signed the server key doesn't make claims about the validity of certificate files hosted at protected servers. Sometimes the Web is just not semantic enough.

Update (July 2009): The certificate of bprbzk.nl was renewed.

Jun 19, 2009

Intermediate certificates in my local trust store

The trust store used by my Firefox browser (on Windows) contains a lot of root CA certificates, and also some intermediate CA certificates (maybe I imported them, maybe my sysadmin did, maybe they came with my browser, but they're there). The root CA certificates are self-signed, the intermediate CA certificates are signed using another certificate from my trust store.

Other browser's trust stores that I checked: curl's (usually located at /usr/share/curl/curl-ca-bundle.crt) and Java's (usually located at $JRE/lib/security/cacerts and accessed with keytool -keystore cacerts -storepass changeit -list) do not contain intermediate certificates (at least not the one I'm using below). They do contain the usual list of root certificates.

My Web server's SSL certificate is signed using one of those intermediate certificates. Here's what my chain looks like:
  • GTE Cybertrust Global Root is signed by GTE Cybertrust Global Root (I saved this certificate to a file called global.crt)
  • Cybertrust Educational CA is signed by GTE Cybertrust Global Root (I saved this certificate to a file called educational.crt)
  • My server's certificate is signed by Cybertrust Educational CA (I saved this certificate to a file called myserver.crt)
To verify the signature by hand using openssl I can use:
openssl verify -CAfile global.crt -untrusted educational.crt myserver.crt
When I first installed the certificate for my Web server (an Apache httpd 2.0 server), I merely configured my own certificate (and corresponding private key):
SSLCertificateFile myserver.crt
This worked fine in my Firefox, which I used to test this server.

But curl refuses (unless I use the --insecure or the --cacert option with a concatenation of the two Cybertrust certificates). Apparently the Web server needs to send the intermediate CA certificate as well (and possibly also the root CA certificate). Here's the correct setup:
SSLCertificateFile myserver.crt
SSLCertificateChainFile educational.crt
SSLCACertificateFile global.crt
While having intermediate certificates in you local trust store doesn't make you less secure, if you're testing your Web server setup it's a good idea to also test it with a minimal trust store. In fact, I found that the best way to test your server's SSL settings is using openssl:
openssl s_client -host myserver.com -port 443
This doesn't use a trust store at all. It shows the certificate chain and gives either an error 20 (unable to get local issuer certificate, in case the server only send the server and intermediate certificates), or an error 19 (self signed certificate in chain, in case the server also sent the root certificate). (Both errors are expected, other errors indicate something may be wrong.)

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 17, 2009

Security in the workspace - Part 2

The word de-perimeterization is used by security experts both to describe a problem and a solution. The problem is clear: when we rely on perimeter defense, a disappearing perimeter is problematic. The solution says that instead of fighting de-perimeterization, by trying to rebuild parts of the perimeter, we should admit that perimeters will be gone soon and implement our security measures on a different level.

What is causing the problem? Here are three major factors which seem to drive de-perimeterization:
  • Networked Business: Suppliers, customers, and service providers all work with the organization on a much finer grained level than they used to. This is the result of specialization. An example is outsourcing: It can be very cost-effective to outsource certain tasks to more specialized organizations. Outsourcing requires so-called service level agreements: contracts between the organization and service provider about the quality of the services rendered. Security should be a part of such agreements as these parties operate within the perimeter.
  • Governance, Regulations, Compliance: Organizations need to comply with more and more external laws and regulations. Often these call for more transparency towards shareholders, governments and the general public. This means that these parties need to pass the perimeter.
  • Insider Threats: Employees are not the loyal workers they once were. Maybe most of them still are, yet some of them will try to gain access to your most valuable assets for personal gain. If you cannot trust your own employees, who operate within the perimeter, then you might as well get rid of the perimeter.
It is clear that each of these factors impacts the perimeter. Are there more?

The de-perimeterization factors are closely related to trends typically attributed to Future Workspaces. The difference is in the perspective. When I think of securing an organization, I tend to take the perspective of the organization. When I try to imagine what the workspace of the future will look like I tend to take the perspective of employees. We identify the following trends:
  • Relation to employer (or, perhaps, loyalty to the organization)
    • Employees no longer work for one employer for 40 years but switch jobs regularly.
    • Employees work for different employers at the same time (I used to work here and here at the same time, which rarely led to conflicts of interest).
    • Professional social network of most employees is bigger than it used to be, extending well beyond the organization’s borders.
  • Responsibilities
    • Employees are given greater responsibility in representing the organization.
    • Organizations are less hierarchically managed.
    • Employees (are encouraged to) write about their professional lives in blogs.
  • Collaboration
    • Not every organization has experts in every field. Organizations are aware of external experts (thanks to openness of other organizations) and encourage employees to collaborate with them.
  • Work in different contexts
    • Employees can work from home.
    • Employees (especially knowledge workers) travel much more and work while in transit (using mobile devices).
    • Employees work (while outsourced) at client.
    • Employees work irregular hours.
    • Employees work shorter hours, some colleagues may almost never meet in person.
At the very least we can claim that the Future Workspace trends reinforce the de-perimeterization factors. The de-perimeterization problem is made bigger and more urgent for organizations to deal with. In fact, many of the security incidents that organizations are faced with can be explained in terms of security controls which are part of the old perimeter defense interacting with employees' new found freedom.

In part 3 I will look at ways forward in the de-perimeterized future workspace.

Feb 10, 2009

Security in the workspace - Part 1


The workspace is changing. What will mostly be different is the relationship between employees and the organizations they work for. I’m interested in the consequences these changes have for the administration of information security in organizations.

Information security incidents have become part of our lives during the last couple of years. Popular media regularly report on incidents which range from lost pen drives filled with privacy sensitive data to financial fraud by employees costing financial organizations billions. The increase in reported incidents not only shows that security incidents are on the rise but it also indicates a change (yes we can!) in how organizations respond to incidents. Reputation and trust are increasingly important concepts in today’s business world, and organizations need to find ways to deal with security problems.

The openness that organizations are showing lately, both to customers, to employees, to other organizations, and to the general public is interesting. From a security perspective openness is a double edged sword: On the one hand, openness means granting access to parties which may not be trusted yet. This clearly complicates security administration. On the other hand, openness also stands for transparency and open standards which simplify matters. And simple things are easier to secure.

Security researchers who study organizational security associate the new found openness in organizations with de-perimeterization. De-perimeterization means that the perimeters of organizations are disappearing. This is problematic because most security strategies pay a lot of attention to perimeter defense: Concentrate your efforts on the perimeter and the rest of the organization is secure.

Is perimeter defense a bad strategy? Thousands of huddling Emperor penguins can’t be wrong, can they? And if you’ve ever played the board game Risk you know that the best strategy to defend a continent is to move all your armies to the border countries.

In part 2 we will have a closer look at de-perimeterization and see how it interacts with future workspaces.

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.

Feb 1, 2009

A "Game-Theoretic" Analysis of De-perimeterization


De-perimeterization is a word which (despite being impossible to pronounce or spell correctly) is used more and more in discussions about security of organizations. Studying the effects of the disappearing perimeter in practice is difficult because organizations are complex and it is difficult to measure the quality of newly deployed security measures. Instead, let’s describe some of the issues of de-perimeterization here using an analogy with the well known board game Risk.

In Risk players occupy countries by placing armies on them. Given a configuration of the board where every player has a number of countries with armies, players can attack countries owned by other players from a neighboring country. If all armies of the defending player are completely defeated then that country is conquered and the attacker can place a number of armies on it.

Although luck is certainly a factor (the game uses no less than five dice) the general rule is that the more armies you bring to a fight, the bigger the odds that the country will (still) be yours at the end of the attack. When attacking, a great number of armies can be moved on to the newly conquered country. Armies can also be moved from one country to a neighboring country if owned by the same player when not attacking, but the number of movements is limited per turn. Playing Risk demonstrates that logistics is one of the most difficult parts of administering security.

Countries are organized in six continents. Continents are a lot like organizations: they contain assets (countries, armies) and they have a perimeter. A player receives bonus armies at the start of every turn in which a continent was completely owned by that player and was successfully defended.

Countries on the border of a continent form the perimeter of that continent. Perimeter countries need special attention because enemies need to first travel through perimeter countries before they can attack an inner country. Recall that if an attacker occupies any country of a continent held by a player, then the defender will not get his bonus at the beginning of their next turn. For the defender, moving most armies to the border countries seems therefore a good strategy. We will call this strategy Perimeter Defense.

At first, Perimeter Defense seems like a good idea. All players are each other’s enemies, after all. In practice, however, what happens is that players form temporary alliances so as to effectively attack a common enemy. The common enemy is typically the player with the most armies. This means, for example, that the members of an alliance agree to follow a certain attack strategy and agree not to attack each other for a number of turns so that they can keep borders between alliance-owned continents minimally manned. The armies no longer needed to defend alliance-owned borders can be better used to attack the common enemy with greater force.

But there are far more complex forms of cooperation possible within an alliance. A pattern that is often seen is that one player in the alliance allows another player to move troops over territory owned by the first player. The first player creates a corridor of countries occupied with only 1 army on them. The countries in the corridor are easily conquered by the second player when he attacks them with a great number of armies. Since moving armies during an attack is free, this allows a player to move a great number of troops towards the common enemy’s border, circumventing the per-turn troop movement limits. The second player also leaves only 1 army on the countries in the corridor, allowing the first player to easily recover the original countries of his continent later on.

So what are the alternatives to perimeter defense? It is tempting to think of Defense in Depth as the complete opposite of Perimeter Defense. In the Risk analogy naive Defense in Depth means equally distributing one’s armies over every country of a continent, both inner and border countries. Obviously this means that it becomes easier for a single enemy to occupy a border country (which means the defender won’t get his bonus armies). Yet at least the continent is more difficult to completely conquer by attackers. It very much depends on the situation (the agenda of other players, alliance agreements) whether Defense in Depth is a good strategy.

Defense in Depth also makes it more difficult to move armies to specific places, for example to allow a fellow alliance member to move troops across your continent. Yet, if one doesn’t completely trust the other players in the alliance a certain degree of Defense in Depth is actually a good thing. After all, when alliance member are moving troops through our corridors they should not be tempted too much to occupy our complete continent while they’re at it.

The real world consisting of real organizations is in many aspects much more complex than than simple board game world, if only because the goals of organizations are much more complex than simply ‘winning the game’. Still, real organizations also deal with security strategies. Two organizations will work together if it is of benefit to both of them (although usually not to mount an attack on the security perimeter of some competitor). At the same time organizations need to restrict access to their assets from outsiders as much as possible.

The problem is not that the perimeter is disappearing. The problem is that it is continually changing. The quality of a security strategy depends greatly on external forces such as the goals of other organizations. That these external forces change dynamically makes things even more complex.

Perimeter Defense and Defense in Depth are still good concepts to use when defining a mixed security strategy but much more important seems to be the ability to quickly change strategy. If security controls are resilient rather than brittle (see Schneier’s book Beyond Fear for an explanation of these concepts) then they can easily be used as part of a dynamically configurable perimeter.

(Thanks to Tim, Marcella, Victor, Suzana, Dragan, and Georgi for playing numerous games of Risk. Disclaimer: The author lost most of these games.)