The Sun BabelFish Blog

Don't panic !

Friday Apr 03, 2009

Global Identity in the iPhone browser

Typing user name/passwords on cell phones is extreemly tedious. Here we show how identification & authentication can be done in two clicks. No URL to type in, no changes to the iPhone, just using bog standard SSL technology tied into a distributed global network of trust, which is known as foaf+ssl.

After having installed a foaf+ssl certificate on my phone (which I will explain how to do in my next post), I directed Safari to foaf.me, which is a foaf+ssl enabled web site. This brought up the following screen:

empty foaf.me page

This is a non personalised page. In the top right is a simple foaf+ssl login button. This site was not designed for the iPhone, or it would have been a lot more prominent. (This is easy to change for foaf.me of course). So I the zoomed onto the login link as shown in the following snapshot. Remember that I don't have an account on foaf.me. This could be the first time ever I go there. But nevertheless I can sign up: just click that link.

login link

So clicking on this foaf+ssl enabled link brings up the following window in Safari. Safari warns me first that the site requires a certificate. The link I clicked on sent me to a page that is requesting my details.

certificate warning

As I do in fact want to login, I click the continue button. The iPhone then presents me with an identity selector, asking me which of my two certificates I want to use to log in:

certificate selection

Having selected the second one, the certificate containing my bblfish.net WebId is sent to the server, which authenticates me. The information from my foaf file is then used to personalise my foaf.me experience. Here foaf.me gives me a nice human readable view of my foaf file. I can even explore my social network right there and then, by clicking on the links to my friends. Again, this will work even if you never did go to foaf.me before. All you need is of course a well filled out foaf file, which services such as foafbuilder.qdos.com are making very easy to do. Anyway, here is the foaf.me personalised web page. It really knows a lot about me after just 2 clicks!

personalised foaf.me

The foaf.me site currently has another tab, showing my activity stream of all the chats I have on the web, which it can piece together since I linked all my accounts together in my foaf file, as I explained in the post "Personalising my Blog" a few months ago.

activity stream

Other web sites could use this information very differently. My web server itself may also decide to show selected information to selected servers... Implementing this is it turns out quite easy. More on that on this blog and on the foaf-protocols mailing list.

Friday Mar 20, 2009

Join the foaf+ssl community and get OpenId for free

Toby Inkster today was the first to put up an OpenId authentication service, that uses foaf+ssl certificates as credentials. This means that anyone with a foaf+ssl certificate can now log in not just to all the fun foaf+ssl services that are popping up, but also to the 100's of thousand of other services out there that are using OpenId - making it so much more valuable.

The OpenId service is written in Perl and requires less that 100 lines of code (see source).

From a user's perspective this is what happens, once everything is set up.

  1. Go to an OpenId enabled service - I tried DZone and Identi.ca.
  2. Enter your OpenId - I used http://bblfish.net/ - in the provided field. And click return.
  3. Your browser will open a client cert popup asking which certificate you want to send - (you should set your browser up to ask you). Choose your foaf+ssl enabled cert. Press enter.
  4. You will be logged in.

This has a few advantages:

  • You no longer have to remember a password for the OpenId server. Your browser keeps that information.
  • The OpenId server does not know your password either.
  • You never had to tell the OpenId Server anything about yourself. All the information is available in your foaf file. And you could protect parts of your foaf file with foaf+ssl so that the OpenId service need know just the public stuff. You could then give special access to the service you are logging into to see protected parts.
  • It is very easy to change the OpenId Server: just change the openid.server line in your OpenId page. Since the server maintains no state about you, this is easy to do: you won't have to create a new account, specify your name, address, ... remember another password, etc...
  • No need for attribute exchange - though the server could easily be enhanced to enable it - since the attributes are all in the foaf file, linked to from the OpenId page. See my 2007 post: Foaf and Openid.
  • It takes one less request to do this than in usual OpenId implementations, as the login step is removed. (this is replaced it is true by one more connection from the OpenId server to the foaf file. But this could be cached.)

It is very easy to get going - especially given that we are dealing with the first release software! Here are the steps:

  1. First of course get yourself a foaf+ssl certificate in your browser, and a correspondingly foaf id. There are a number of services listed on the foaf+ssl wiki. Two solutions:
    • You can use the easy to use foafssl.org certificate creation service, but you'll need the foaf file to then point back to the OnlineAccount just created. This would require adding the following triple in geek mode to your foaf file, in order to help verify your identity claim:
      
      <http://you.com/foaf#me> <http://xmlns.com/foaf/0.1/holdsAccount> <http://test.foafssl.org/certs/0xx.rdf#accnt>.
      
      
    • Or you can follow the even more geeky instructions from my original blog to create yourself a certificate.
    We need to work on making the user experience much easier of course. This here is still just a proof of concept.
  2. Next add a link from your OpenId page to the foaf server, and to your foaf file. A good choice for your OpenId page is your home page. Add the following in the <head>...</head> section of your html.
        <link rel="openid.server" 
            href="https://ophelia.g5n.co.uk:10443/openid/provider.cgi?webid=http%3A%2F%2Fbblfish.net%2Fpeople%2Fhenry%2Fcard%23me" 
            title="FOAF+SSL OpenId Server"/>
        <link rel="meta" title="foaf" href="http://bblfish.net/people/henry/card" type="application/rdf+xml" />
    
    You can see an example in the source of my home page at http://bblfish.net/. The pattern to follow for the href attribute is https://ophelia.g5n.co.uk:10443/openid/provider.cgi?webid=W where you replace W by the URL encoded value of your WebId. (You can use an online service such as this devshed one to do the encoding). The encoded WebId helps the OpenId authentication service verify that the person logging in there is really you - the person referred to by your webid. You should also point to your foaf file using the meta link, so that other services on the web can find this information easily.
  3. You need to add a foaf:openid relation from your WebId to your OpenId page in your foaf file. This is so that the OpenId server can identify you in your foaf file. I added the following triple in my foaf.
    <http://bblfish.net/people/henry/card#me> <http://xmlns.com/foaf/0.1/openid> <http://bblfish.net/> .
    
    Which can take a number of different forms in rdf/xml of course.

That is it. This could easily be automated by foaf service providers. I'll update it as soon as we have some easier means of doing this.

Tuesday Mar 03, 2009

The foaf+ssl paradigm shift

passport picture

Foaf+SSL builds on PKI whose paradigmatic example is that of a traveller crossing the frontier and showing his passport. The problem is that this analogy breaks down for foaf+ssl (wiki page) and can make it difficult to understand what is going on. What is required is a paradigm shift, and I will here help walk you through it. (Thanks to a educational exchange with Bruno Harbulot on the foaf-protocols mailing list)

Traditional PKI

So first let us step into the old paradigm. You arrive at a web site. It asks you for your certificate which is somewhat like being asked for a passport at a border. So in this analogy you are playing the role of the traveller who is looking to cross the border (access that resource), and the server is playing the role of border patrol officer, whose job it is to permit you only if you are authorized to do so.

So of course you hand over a certificate. This contains a number of things:

  • Your identifier. This can be the passport number. In X509 it is the Distinguished Name. And with foaf+ssl we have are also making use of the subject alternative name, a WebId.
  • Something to tie the certificate to you. In the case of the passport this would be the photo on the passport which should match your face. In the certificate this role is played by the public key that corresponds to the private key only you posses. The public key that you send is what others see of your face, ie, the photo on the passport, the private key would be your face itself.
  • There may be a few other things written in the passport about you, such as your age, your birthplace, etc...
  • The whole passport is designed to be recogniseable as having been published by the Government which issued it - usually it is also signed by them. And indeed in the certificate space we have the same thing: a Certificate Authority takes the place of the Government and signs your certificate.
By giving over this passport to the officer, or by sending your certificate to the server, you have completed your role in identifying yourself.

The server receiving this certificate, playing the role of the border patrol agent, now himself needs to continue the process:

  • First he must identify you. Ie, his task is given the pasport, to verify the referent of its holder. He can do this simply by verifying that the picture matches your face. In the case of TLS this is done simply through the cryptographic mechanism that established the https connection.
  • Next the officer must verify that the information in the passport is issued by a government agency he trusts. This is the authentication step. (Authentication, from Greek αυθεντικός, real or genuine, from authentes for author) The officer verifies that the passport is genuinely from the government. To do this he verifies the watermarks, checks for signs of tampering, etc... In the case of the server this is very easy to do using encryption. The certificate is signed by the Certificate Authority, in such a way as to make it extremly difficult to tamper with. By verifiying the Certificate integrity and that the signature of the CA matches the one it has on file the server can be confident that the information it is reading was stated by the Authority it trusts. Since it trusts that authority it can believe its contents.
  • Having accepted the contents, it can trust the identifier is of you, and finding that you are not on a blacklist, can authorize you to cross the border.

How the analogy breaks down

The problem with that analogy is that it does not help one to understand foaf+ssl, because with foaf+ssl the certificate presented to the server is self signed, and the identity self created!

self signed certificate

To clearly see how the analogy breaks down, imagine what would happen if we mapped the foaf+ssl back to our border patrol situation. Imagine you arrive happily at the border and the officer asks you for a passport. You give him a piece of paper nicely crafted on your color laser printer at home, with your photo on the right hand side, your self created WebId, a URL you coined a few days before, your name, and your signature below. On the paper you put a nice logo, saying "Issued on 1 Jan 2009 by Me, valid for 1 year."

Now I don't recommend doing this during times of high tension between the countries on either side of the border, or unless you have some serious reason to believe that the officers have a good sense of humor. If they do, you can be certain you will be sent back from where you came from, and not into some more dingy place with bars instead of windows.

A better analogy

So lets leave those dreary, bureaucratic and slow moving border control situations where novelty is frowned upon far behind us. Instead let us try for a different example.

So imagine now you are going to a masked party, where only a preselected group of people were invited, of which you. As you arrive in your RoboCop costume which completely covers your body, and muffles your voice, you present a paper with a note on which is your typewritten ID. Having verified that the person with that ID is indeed authorized to join, the guard at the door asks you to move your right arm up and down three times, which you do. To wiggle your bottom as best you can, which you do. Satisfied that he has identified you, the guard lets you in, and you go party.

According to you, is this guard doing his job correctly? Has he correctly authorized you? Let me add here that the ID you gave him is a public ID and that the list of invited people is also public! What do you think? Because this is really not far from the foaf+ssl solution...

Well it all depends on a how the guard came to ask you to move your hand! Imagine that your ID was the URL <tel:+1.510.931.5491>, and that the guard took out his cell phone and called that number. You, in the depth of your RoboCop costume receive the call. The guard asks: "Hi are you in front of the party now?". You answer "yes", and the guard hears the voice in the phone answer "yes". He asks you to move your right hand up and down three times which you immediately do. He asks you to do the best to wiggle your bottom. Which you do. Now has he not identified you as being <tel:+1.510.931.5491>?

Are you thinking: "well yes, could I - being inside the costume - could I not have just overheard what the guard was saying, even had I not received the call?". If that thought bothers you, then replay the same scenario, but this time change the ID you give over to an email address, and have the guard send you an email, which you receive on your cell phone too. This is something we do all the time when signing up to web sites.

Notice now how this is similar to the foaf+ssl protocol. There you give the guard an https URL, and he queries that URL with an HTTP GET. That returns a response containing your public key, which is the one you used to communicate with the guard, thereby clearly tying you to your ID. Once that link is made, the guard can go straight to the authorization step: are you or are you not in the invited people's list.

The Web of Trust

We have been using email URLs for a long time to identify ourselves on sites. So what does foaf+ssl add that we did not have before? Well it does the same thing in a RESTful manner. REST is the architectural style on which the most successful hypermedia system ever was built. It is designed to make hypermedia easily possible. The advantage of building in this style is that it is very easy to link information together. So just as the original Web made it very easy to link documents together, so by following this style into the hyperdata space, we make it easy to link things together. By making identity RESTful we have layed the basic building blocks to then build a web of trust.

So to illustrate just a little bit more how this works, let us extend the access rules in our example slightly. To be allowed access to the party you either have to be on a list, or you have to be a friend of someone on the list. This just helps regulate the party somewhat, so that there are clear chains of responsibility that can be drawn in case of trouble. This time you are not on the list. You are still in your large RoboCop costume, and the guard calls you to ask you who you know. You say you know <tel:+44-161-275-014>. The skeptical guard, does not of course take everyone at their word automatically, so he does not let you in on this basis alone: you could be lying. But it is easy to verify. The guard checks that <tel:+44-161-275-014> is indeed a core guest of the party, and having checked that just calls that number, ask the person if he knows <tel:+1.510.931.5491>. If he answer yes, you are authorized.

With foaf+ssl we can do the same without requiring direct human intervention. By giving your WebId to the guard, he can "call" the WebId using HTTP GET (clicking on the link) and see what information that link returns. If the information returned identifies you (as it does by returning your public key) then we have, as shown previously, confirmed identification. Now if as we are supposing in this example, your URL is not on the list of directly authorized ones, the guard can check the document returned to find if any of your friends are directly authorized. If anyone of them is, he can 'call them' (with an HTTP GET of course) to find out if they claim you as a friend too. So the parallel with the above phone conversation holds very well. (For more detailed description of this example see "Building a web of Trust without Key Signing parties")

This way of linking between documents works because every object in those relations has a identifying URL, and because the documents are published RESTfully. The REST architecture is very strict about names referring to things independent of who uses them or of any previous state between the client and the server. If it were not, different people would be meaning different things with the same URL, which would be very confusing. By making it easy to link between documents we have the basic elements to grow a web of trust.

Conclusion

So how does foaf+ssl and the usual passport like PKI example compare? Here are a few thoughts:

  • foaf+ssl focuses on identity, as OpenId does, but much more RESTfully. Traditional PKI on the other hand also conceives of itself as certifying extra information: name, age, address...
  • In the passport example we pass a document by value, not by reference. The advantage is that that resource can be updated a lot faster than the passport can. One could easily imagine border control situations working like that. All that you would need would be to cite your passport Id to the officer and he could find your record in the government database and check your identity that way (by looking at your picture or checking your fingerprints).
  • To get something similar to the passport example in foaf+ssl, the government would just have to produce its WebIDs. Then the content of the representation returned by that resource would be the governments view on me. (What remains to be done is to find a way to make clear who is speaking for whom - so to distinguish the case when the WebId is my employers and when it is mine)
  • The WebId can much more easily be self created. This makes it easier to say more about oneself than an official source would ever want to be liable for certifying.
  • WebId's can easily be linked to, so other people can relate to you.

Thursday Feb 12, 2009

sketch of a foaf+ssl+openid service

Discussing foaf+ssl with Melvin Carvalho he pointed out that we need a service to help non https enabled servers to participate in our distributed open secure social network. This discussion led me to sketch out the following simple protocol, where I make use of parts of the OpenId protocol at key points. This results in something that does what OpenId does, but without the need for users to remember their URL, and so without many of the problems that plague that protocol. And all this with minimal protocol invention.

So first here is the UML sequence diagram for what I am calling here tentatively foaf+ssl+openid.

  1. First Romeo arrives on a public page with a login button.
    • On an OpenId server there would be a field for the user to enter their ID, with foaf+ssl this is not needed. So we have a simple login button.
    • That button's action attribute points to some foaf+ssl+openid service that server trusts (it is therefore an https URL). It can be any such service. In OpenId the Id entered by the user points the server to a web page that points the service to an openid server the user (Romeo here) trusts. All of this is no longer needed with this protocol. The html for the login button can be static.
    • The URL has to encode information for the foaf+ssl service to know who to contact back. One should use exactly the same URL format here as OpenId does. (minus the need to encode User's URL since that will be in the X509 certificate)
  2. When Romeo clicks the login button he opens an https request to the foaf+ssl+openid service.
  3. The foaf+ssl+openid service on opening the connection asks for the client's certificate after sending its own. This would contain
    • The User's Public key
            Subject Public Key Info:
                  Public Key Algorithm: rsaEncryption
                  RSA Public Key: (1024 bit)
                      Modulus (1024 bit):
                          00:b6:bd:6c:e1:a5:ef:51:aa:a6:97:52:c6:af:2e:
                          71:94:8a:b6:da:9e:5a:5f:08:6d:ba:75:48:d8:b8:
                          01:50:d3:92:11:7d:90:13:89:48:06:2e:ec:6e:cb:
                          57:45:a4:54:91:ee:a0:3a:46:b0:a1:c2:e6:32:4d:
                          54:14:4f:42:cd:aa:05:ca:39:93:9e:b9:73:08:6c:
                          fe:dc:8e:31:64:1c:f7:f2:9a:bc:58:31:0d:cb:8e:
                          56:d9:e6:da:e2:23:3a:31:71:67:74:d1:eb:32:ce:
                          d1:52:08:4c:fb:86:0f:b8:cb:52:98:a3:c0:27:01:
                          45:c5:d8:78:f0:7f:64:17:af
                      Exponent: 65537 (0x10001)
      
    • The Subject's Alternative Name WebId
              X509v3 extensions:
                 ...
                 X509v3 Subject Alternative Name: 
                                 URI:http://romeo.net/#romeo
      
    The ability for browsers to do this is all part of the standard TLS handshake available in most browsers for a few generations.
  4. The server looks in the client certificate for the Subject Alternative Name in the SSLv3 extensions, and fetches the foaf file at that URL
  5. The service then does a simple match on the information from the foaf file and the information from the certificate. If they match the foaf+ssl+openid service knows that the user <http://romeo.net/#rome> controls <http://romeo.net/> web page. This is enough for simple authentication. (For more on this see Creating a Web of Trust withouth Key Signing Parties )
  6. Depending on the result, the foaf+ssl+openid service can return a redirect with an authentication token to the original service Romeo wanted to log into. This can also be done using the patterns developed in the OpenId community. foaf+ssl+openid sequence diagram
  7. The browser then redirects to the Original service.
  8. The service now has Romeo's URL. But to avoid a man in the middle attack, or replay attacks it follows the OpenId protocol and does a little check with its service on a token sent to it in the redirect in step 6.
    ((Perhaps this step could be avoided if the foaf+ssl+openid service made public it's public key, and encrypted some token sent to by the client to the server. But we could just stick closely to the well trodden OpenId path and just reuse their libraries.))
  9. Having verified the identity of the user, the service could optionally GET the user's foaf file, for public information about him.
  10. Or it could check the relation that user has to it's trusted graph of friends,
  11. and return a presonalised resource

One could also imagine a foaf+ssl+openid server enabled with attribute exchange functionality, which it could get access to simply by reading the foaf file.

I am not sure how much of a problem it really is for servers not to have SSL access. But this could easily fill that gap.

creating a foaf+ssl cert in a few clicks

In a previous blog I showed how to create a foaf+ssl cert manually. I have now put up a simple test server where you can do the same in a few clicks.

The test.foaf-ssl.org/cert service will add a certificate to your browser securely, and create a local acount to which your certificate is pointing. This account will itself point to your Web Id. An account in this scheme is nothing more than an RDF file, such as the ones listed in the certs directory. You can then login in one click, without needing to remember a URL to other foaf+ssl services on the web. There are a few and growing number of prototype implementations listed on the foaf+ssl wiki.

All that remains to be done now is to create more interesting and valuable services using the distributed social networks and foaf+ssl. For some ideas on things to do consult the foaf+ssl Use Cases. The foaf protocols mailing list is a great place to get help on implementations and discuss ideas.

The server is written using Wicket and deployed on a GlassFish Application Server. The code is open source under a BSD licence. Hackers welcome!

Wednesday Jan 21, 2009

Outline of a business model for open distributed social networks

illustration of SN data silos by the Economist

The organisers of the W3C Workshop on the future of social networking had the inspiration to include a track on Business Models. What would be the interest of large players to open up? to play ball in a larger ecosystem of social networks? What would the business model be for new entrants? This question clearly was on many of the attendees minds, and it is one I keep coming across.

First without Linked Social Networks there are a lot of disincentives to create new web services. This is because users of these services need to duplicate the data they have already created elsewhere, and also because the network effect of the data they are using is bound to be much smaller. I have found myself uninterested in trying out many new web 2.0 offerings for just these reasons. It is much more rewarding for developers to create applications for the Facebook platform for example, where the users just need to click a button to try out the application on the data they are already using, and that may yet enrich this data further.

Open Secure Linked Social Networks, such as that made possible by foaf+ssl, give one the benefits enjoyed by application developers of the closed social networks but in a distributed space, which should allow the unleashing of a huge amount of energy. Good for the consumer. But good for the big network players? I will argue that they need consider the opportunities this is opening up.

First of all one should notice that the network effect applies just as much to the big players as to the small ones. A growing distributed social network (SN) is a tide that will lift all boats, and since metcalf's law states that the value of the network grows exponentially with the number of nodes in it, then doubling the number of nodes in the network may just quadruple the value of the network to all. Perhaps the big operators are thinking that they control such a large slice of the market that there is not much doubling that they can do by linking to the smaller players. As it happens most social networks are geographical monopolies, which would go to strengthen that point of view (see slide 8 of the opening presentation at the W3C workshop). [ Nothing stays still, and everyone should watch out for the potential SN controlled by the telecoms.]

But the network effect applies to the big players also in another way. Namely that if they wish to create small networks then the value of those networks will be just as insignificant as those of other smaller players. So let me take a simple example of very valuable smaller networks which have a huge and unsatisfied demand for social networking technologies and the money to pay for tools that could help them quench their need: companies! Companies need to connect their employees to their managers and colleagues inside the same company, to knowledge resources, to paychecks and many other internal resources such as wikis, blogs, etc... Usually companies of a large enough size have software to deal with these. But even in a company such as Sun Microsystems, that is relatively large, the network effect of that information is not interesting enough for people to participate gladly in keeping the information up to date. I often find it easier to go to Facebook to find a picture of someone in Sun. Why? Well there is a very large value in adding one's picture to facebook: 200 million other users to connect to. In Sun Microsystems only 34 thousand people to connect to, and it is true a financial incentive. Clearly the value of 200 million squared is larger than the incentive of being efficient at work.

One thing is clear: it is impossible to imagine that such large software companies can allow their employees to just use the closed SN sites directly to do their work - I mean here: have all their employess just use the tools on facebook.com for example. This would give those SN companies way too much insight into the dealings of the company. Certainly very large sections of industry, including defence contractors, large competitive industries such as car manufacturers, and governments, cannot legally and strategically permit such outsourcing to happen, even though the value of the information in such a large network would be astronomically larger. In some case there are serious privacy and security issues that just cannot be ignored however attractive the value calculation is.

So large SN players would have to enter the Fortune 1000 with Social Networking software that did not leak information. But in that case they won't be in any seriously better position than the software that is already in there, and they won't be able to compete any better than any of the smaller companies that are working in this space, as they will not find it easy to leverage their main advantage, namely the network effect of their core offering.

And even if they did manage to leverage this in some ways, they would find it impossible to leverage that advantage in the ways that really count. Companies don't just want their employees to link up with their colleagues, they need them to link up with people outside their company, be it customers, government agencies, researchers, competitors, external contractors, local governement, insurance or health agencies, etc, etc..... The list is huge. So even if a large Social Network could convince one of these players of the advantage of their offering, they will never be able to convince every single partner of that company - for that would be to convince the whole world. Companies really want global SN, and that is what Emergency Response teams really need.

To make such a globaly linkable platfrom a reality one needs to build at the level of abstraction and clarity at which the only such global network in existence is built: the web itself. By using Linked Data one can create distributed social networks where each player can maintain the information they feel the business need to maintain. With the very simple foaf+ssl protocol we have the lightest possible means to build security into a distributed social network. Simplicity and clarity - mathematical clarity - is essential when developing something that is to grow to a global scale.

Companies therefore that work at providing tools for distributed social networks, will if they play well together, find a huge opportunity opening up in front of them in helping enterprises in every industry segment link up their employees to people in every walk of life.

Friday Jan 16, 2009

The W3C Workshop on the Future of Social Networking Position Papers

picture by Salvadore Dali

I am in Barcelona, Spain (the country of Dali) for the W3C Workshop on the Future of Social Networking. To prepare for this I decided to read through the 75 position papers. This is the conference I have been the best prepared for ever. It really changes the way I can interact with other attendees. :-)

I wrote down a few notes on most paper I read through, to help me remember what I read. This took me close to a week, a good part of which I spent trying to track down the authors on the web, find their pictures, familiarise myself with their work, and fill out my Address Book. Anything I could do to help me find as many connections as possible to help me remember the work. I used delicious to save some subjective notes, which can be found on under the w3csn tag. I was going to publish this on Wednesday, but had not quite finished reading through all the papers. I got back to my hotel this evening to find that Libby Miller, who co-authored the foaf ontology, had beat me to it with the extend and quality of her reviews which she published in a two parts:

Amazing work Libby!

70 papers is more than most people can afford to read. If I were to recommend just a handful of papers that stand out in my mind for now these would be:

  • Paper 36 by Ching-man Au Yeung, Laria Liccardi, Kanghao Lu, Oshani Seneviratne and Tim Berners Lee wrote the must read paper entitled "Decentralization: The Future of Online Social Networking". I completely agree with this outlook. It also mentions my foaf+ssl position paper, which of course gives it full marks :-) I would use "distribution" perhaps over "decentralisation", or some word that better suggests that the social network should be able to be as much of a peer to peer system as the web itself.
  • "Leveraging Web 2.0 Communities in Professional Organisations" really prooves why we need distributed social networks. The paper focuses on the problem faced by Emergency Response organisation. Social Networks can massively improove the effectiveness of such responses, as some recent catastrophes have shown. But ER teams just cannot expect everyone they deal with to be part of just one social network silo. They need to get help from anywhere it can come from. From professional ER teams, from people wherever they are, from infromation wherever it finds itself. Teams need to be formed ad hoc, on the spot. Not all data can be made public. Distributed Open Secure Social Networks are what is needed in such situations. Perhaps the foaf+ssl proposal (wiki page) can help to make this a reality.
  • In "Social networking across devices: opportunity and risk for the disabled and older community", Henni Swan explains how much social networking information could be put to use to help make better user interface for the disabled. Surprisingly enough none of the web sites, so taken by web 2.0 technologies, seem to put any serious, effort in this space. Aparently though this can be done with web 2.0 technologies, as Henny explains in her blog. The semantic Web could help even further I suggested to her at her talk today, by splitting the data from the user interface. Specialised browsers for the disabled could adapt the information for their needs, making it easy for them to navigate the graph.
  • "Trust and Privacy on the Social Web" starts the discussion in this very important space. If there are to be distributed social networks, they have to be secure, and the privacy and trust issues need to be looked at carefully.
  • On a lighter note, Peter Ferne's very entertaining paper "Collaborative Filtering and Social Capital" comes with a lot of great links and is a pleasure to read. Did you know about the Whuffie Index or CELEBDAQ? Find out here.
  • Many of the telecoms papers, of which Telefonica's "The social network behind telecom networks" reveal the elephant in the room that nobody saw in social networking: the telecoms. Who has the most information about everyone's social network? What could they do with this information? How may people have phones, compared to internet access? Something to think about.
  • Nokia's position paper can then be seen in a different light. How can handset manufacturers help put to use the social networking and location information contemporay devices are able to access? The Address Book in cell phones is the most important application in a telephone. But do people want to only connect to other Nokia users? This has to be another reason for distributed social networks.

    I will blog about other posts as the occasion presents itself in future blogs. This is enough for now. I have to get up early and be awake for tomorrow's talks which start at 8:30 am.

    In the mean time you can follow a lively discussion of the ongoing conference on twitter under the w3csn tag.

  • Tuesday Dec 30, 2008

    foaf+ssl, pki and the duck-rabbit

    In part II §xi of the "Philosophical Investigations", Ludwig Wittgenstein introduces the duck-rabbit figure:

    I shall call the following figure derived from Jastrow, the duck-rabbit. It can be seen as a rabbit's head or as a duck's. And I must distinguish between the 'continuous seeing' of an aspect and the 'dawning' of an aspect.

    The picture might have been shewn me, and I never have seen anything but a rabbit in it.

    It is worth stopping here and considering that illustration carefully, making sure you can see it one way then the other. There is no illusion here notice. There is not one correct way to see the line. The figure itself is ambiguous. The duck-rabbit therefore shows very simply how the way we perceive the world can change without any new fact appearing in the world.

    Is that not what magic does?

    Much more complex examples of this phenomenon can be found. In some cases it is much more difficult to switch between meanings. I find this for the Young Woman Old Woman image for example. I really need to work hard there to see the other interpretation, and when I find that interpretation I find switching back very difficult.

    Recently I have felt that the foaf+ssl protocol does something similar to Public Key Cryptography (PKI). We use a tool that was always meant to be used one way, in a completely different way, a way of course that was always permitted, but that nobody saw (or if they did they did not pursue it openly).

    To perceive this different way of using this tool one has to - just as with the duck-rabbit - look at it differently. One has to see it in a new way, or perhaps even use it in a new way. Whereas PKI is used for hierarchical trust, we use it to build a web of trust. Where X509 certs built up a lot on the Distinguished Name hierarchy, we nearly ignore it. Where X509 tried to place information in the certificate, we place it outside at the name location. Even though SSL can request client certificates in the browser, nobody does this, yet we build on this little known feature. Self signed client certificates, which would not have made sense in traditional PKI infrastructure, because they proove nearly nothing about the client, is what we build everything on....

    All the usual X509 and ssl tools work just as they should, but magically it seems they are suddenly found to be doing something completely different.

    Friday Dec 19, 2008

    what does foaf+ssl give you that openid does not?

    Jason Kolb asked on Twitter "what does foaf+ssl give you that openid does not?". I can make the answer short but not short enough for a tweet. So here are my initial thoughts on this.

    • foaf+ssl gives people and other agents a URL for Identification, just like OpenId does. But in the case of foaf+ssl the user does not need to remember the URL, the browser or keychain does. A login button on a foaf+ssl web site is just a button. No need to enter any identifier. Just click the button. Your browser will then ask you what identity you wish to use. The user does not need to remember the password either (except perhaps that of the keychain if the browser requires it).
    • The foaf+ssl protocol requires minum 1 to 2 network connections. Compare this to the much more complex OpenId sequence diagram. In a world of distributed data where each site can point to data on any other site, this can become really important.
    • the description of foaf+ssl holds on one page. A page is required to list the OpenId specs.
    • foaf+ssl builds on well established standards: REST, RDF, SSL, X509. That is why of course it takes much less space to explain. It does not invent anything new.
    • foaf+ssl is clearly RESTful. You can GET your foaf file, and if you needed update it with PUT. You could create it with POST. No need to reinvent those verbs as OpenId has to do in OpenId Attribute Exchange spec
    • It is easy to add new attributes to the rdf file. It is easy to extend, and to give the extensions meaning. Every attribute is a URI, which when clicked on can give you yet more information about the relation, and participate in the Linked Data cloud. New classes can be created. You can add relations to objects, and those objects themselves can have yet more relations (see my foaf file, and how it relates me to an address, which is related to a country). The complex OpenId attribute exchange spec does not offer any of this.
    • You can reason about the foaf. Well that just comes for free with RDF and OWL. (So you can do this too with OpenId, but you'd have to treat it as a special case of RDF for that to work.)
    • Being simpler, it will be easier to
    • With foaf+ssl you get a web of trust. With OpenId you only get trust indirectly if you trust the OpenId provider. So for example you may trust the information gathered by the foaf+ssl attribute exchange mechanism of someone who has an OpenId provider at the url http://openid.sun.com/, because you trust Sun Microsystems. With foaf+ssl you can get trust of some file on some web server you never heard about because all your friends point to his foaf file.
    • Foaf+ssl is distributed. There is no need for a OpenId provider. You just need a web server, ideally your own at your own domain name. Yes you can run your OpenId server locally too, but then you loose the trust that might have been associated with that domain name. Have you ever wondered why there were so many very large OpenId providers, and not many small ones?
    • Foaf+ssl requires no HTTP redirects: these are problematic on many cell phones I am told, in part often because telecoms proxys get in the way.

    OpenId is very well known and widely used now. It has made people aware of the power of a URL for identifying people, and is what helped me find this solution. Furthermore it would be quite easy to create a foaf+openid service as I proposed some time ago, simplifying OpenId in the process. So the two technologies are not incompatible.

    More on foaf+ssl on the esw wiki

    foaf+ssl user story 1: web site personalisation

    In Agile development one creates simple User Stories. Here is the simplest one I can think of for foaf+ssl. It only uses the authentication piece, not the authorization part, so all the steps up to and including 5 in the sequence diagram.

    Prerequisite: A User has a foaf+ssl certificate in his browser and corresponding foaf file.

    The User arrives at a new web site he has never been to before. An https connection is made and the server asks for the client certificate. The User chooses one. The web site fetches the users foaf file at the URI contained in the certificate and uses this to personalise the site. Some things it could do would be

    • Welcome the user by name
    • List friends the user may know on the site
    • List projects the user may be interested in
    • Create an account for the user, ie, some space on the server dedicated to the user.
    What it can do will depend on the site, the information in the foaf file, and the location of the user's URI in the social network known to the web service.

    Thursday Dec 18, 2008

    python and php implementations of foaf+ssl

    We now have two new implementations of foaf+ssl authentication protocol, in addition to the java one I blogged about earlier. If you have followed the procedure there to create your certificate, add it to your browser, and publish a minimal foaf file you can then try out these two servers.

    Melvin Carvhalo, who owns the great domain name foaf.me, has implemented this in PHP in a very nicely layered fashion. In recent mail to the foaf protocols list he published the following end points:

    1. a test ssl resource will from a simple ssl connection that asks for the client certificate:
      • Display the output of the $_SERVER global variable
      • Display the details in the supplied Client Certificate
      • Display the Client Public Key info
      • Function returning the Client Public Key info in HEX
      • Function returning the subjectAltName in the Client Certificate
    2. foaf tester that after getting the URI in your certificate from the X509 v3 extensions section will fetch the foaf at that URL and
      • Convert the FOAF into an array of triples which it displays
      • Find the RSA Key of the declared subject ("owner") within a FOAF file
      • Get the list of friends in a FOAF file
    3. and finally the foaf+ssl tester, which Melvin pointed to in another email to the list, which will use the foaf+ssl protocol to log you into a server in one https connection. The server only does authentication and the minimal authorization: if it can authenticate you, then you are authorized

    These three minimal services are very helpful as they allow us to detect and debug each stage in the protocol carefully. I highly recomment this step by step approach (and will therefore have to add this to my own examples!)

    Ian Jacobi from MIT, has worked on extending authorization more with his python based server to also check your identity in a social network. See his detailed post on this "TAAC in action". Ian was in fact the first to have a running implementation I'd like to point out.

    Keep these coming!

    In the meantime I am working on authorization schemes, and am currently reading a complex paper Vladimir Kolovski, James Hendler, and Bijan Parsia entitled "Formalizing XACML Using Defeasible Description Logics". Clark Kendall is blogging about this under the policy management tag, which contains a less mathematical overview of the paper. I'll report back when I have managed to digest this. Read it if you need an antidote to twitter.

    Tuesday Dec 02, 2008

    foaf+ssl: adding security to open distributed social networks

    For the "W3C Workshop on the Future of Social Networking", taking place in Barcelona January 2009

    Attending:
    Henry Story
    Contributors:
    Bruno Harbulot, Ian Jacobi, Toby Inkster
    Enthusiastic:
    Melvin Carvalho

    Semantic Web vocabularies such as foaf permit distributed hyperlinked social networks to exist. We would like to discuss a group of related ways we are exploring (mailing list) to add information and services protection to such distributed networks.

    One major criticism of open networks is that they seem to have no way of protecting the personal information distributed on the web or limiting access to resources. Few people are willing to make all their personal information public, many would like large pieces to be protected, making it available only to a select group of agents. Giving access to information is very similar to giving access to services. There are many occasions when people would like services to only be accessible to members of a group, such as allowing only friends, family members, colleagues to post a blog, photo or comment on a site. How does one do this in a maximally flexible way, without requiring any central point of access control?

    Using an intuition made popular by OpenID we show how one can tie a User Agent to a URI by proving that he has write access to it. foaf+ssl is architecturally a simpler alternative to OpenID (fewer connections), that uses X.509 certificates to tie a User Agent (Browser) to a Person identified via a URI. However, foaf+ssl can provide additional features, in particular, some trust management, relying on signing FOAF files, in conjunction with set of locally trusted keys, as well as a bridge with traditional PKIs. By using the existing SSL certificate exchange mechanism, foaf+ssl integrates more smoothly with existing browsers (pictures with Firefox) including mobile devices, and permits automated sessions in addition to interactive ones.

    The steps in the protocol can be summarised simply:

    1. A web page points to a protected resources using a https URL, e.g. https://juliette.net/location
    2. The client fetches the secure http URL .
    3. As part of that exchange the server requests the client certificate. The client returns Romeo's (possible self signed) certificate, containing the little known X.509 v3 extensions section:
              X509v3 extensions:
                 ...
                 X509v3 Subject Alternative Name: 
                                 URI:http://romeo.net/#romeo
      
      Because the connection is encrypted, Juliet's server knows that Romeo's client knows the private key of the public key that is also passed in the certificate. Something like:
            Subject Public Key Info:
                  Public Key Algorithm: rsaEncryption
                  RSA Public Key: (1024 bit)
                      Modulus (1024 bit):
                          00:b6:bd:6c:e1:a5:ef:51:aa:a6:97:52:c6:af:2e:
                          71:94:8a:b6:da:9e:5a:5f:08:6d:ba:75:48:d8:b8:
                          01:50:d3:92:11:7d:90:13:89:48:06:2e:ec:6e:cb:
                          57:45:a4:54:91:ee:a0:3a:46:b0:a1:c2:e6:32:4d:
                          54:14:4f:42:cd:aa:05:ca:39:93:9e:b9:73:08:6c:
                          fe:dc:8e:31:64:1c:f7:f2:9a:bc:58:31:0d:cb:8e:
                          56:d9:e6:da:e2:23:3a:31:71:67:74:d1:eb:32:ce:
                          d1:52:08:4c:fb:86:0f:b8:cb:52:98:a3:c0:27:01:
                          45:c5:d8:78:f0:7f:64:17:af
                      Exponent: 65537 (0x10001)
      
    4. Juliet's server dereferences the URI found in the certificate, fetching a document .
    5. The document's log:semantics is queried for information regarding the public key contained in the previously mentioned X.509. This can be done in part with a SPARQL query such as:
      PREFIX cert: <http://www.w3.org/ns/auth/cert#>
      PREFIX rsa: <http://www.w3.org/ns/auth/rsa#>
      SELECT ?modulus ?exp
      WHERE { 
         ?key cert:identity <http://romeo.net/#romeo>;
              a rsa:RSAPublicKey;
              rsa:modulus [ cert:hex ?modulus; ];
              rsa:public_exponent [ cert:decimal ?exp ] .   
      }                   
      
      If the public keys in the certificate is found to be identical to the one published in the foaf file, the server knows that the client has write access over the http://romeo.net/ resource.
    6. Romeo's identity is then checked as to its position in a graph of relations (including frienship ones) in order to determine trust according to some criteria . Juliet's server can get this information by crawling the web starting from her foaf file, or by other means.
    7. Access is granted or denied .

    We have tested this on multiple platforms in a number of different languages, (Java™, Python, ...) and across a number of existing web browsers (Firefox, Safari, more to come).

    foaf+ssl is one protocol that we would like to concentrate on due to its simplicity. But there are a number of other ways of achieving the same thing, by using OpenID for example. All of them require some extra pieces:

    • An ontology to describe what can be done with the data (copied, republished,...) or what obligations incur in using a service .
    • An ontology to describe who has access to the service. This would be useful to help people decide if they should bother trying to access it, or what else they need to do such as become friends with someone, or reveal a bug in the software somewhere .
    • Other things that might come up .

    We will discuss our experience implementing this, the problems we have encountered and where we think this is leading us to next.

    Thursday Nov 20, 2008

    foaf+ssl: a first implementation

    The first very simple implementations for the foaf+ssl protocol are now out: the first step in adding simple distributed security to the global open distributed decentralized social network that is emerging.

    Update Feb 2009: I put up a service to create a foaf+ssl service in a few clicks. Try that out if you are short on time first.

    The foaf+ssl protocol has been discussed in detail in a previous blog: "FOAF & SSL: creating a global decentralised authentication protocol", which goes over the theory of what we have implemented here. For those of you who have more time I also recommend my JavaOne 2008 presentation Building Secure, Open and Distributed Social Network Applications, which explains the need for a protocol such as this, gives some background understanding of the semantic web, and covers the working of this protocol in detail, all in a nice to listen to slideshow with audio.

    In this article we are going to be rather more practical, and less theoretical, but still too technical for the likes of many. I could spend a lot of time building a nice user interface to help make this blog a point and click experience. But we are not looking for point and click users now, but people who feel at home looking at some code, working with abstract security concepts, who can be critical and find solutions to problems too, and are willing to learn some new things. So I have simplified things as much as needs be for people who fall into that category (and made it easy enough for technical managers to follow too, I hope ).

    To try this out yourself you need just download the source code in the So(m)mer repository. This can be done simply with the following command line:

    
    $ svn checkout https://sommer.dev.java.net/svn/sommer/trunk sommer --username guest
    
    (leave the password blank)

    This is downloading a lot more code than is needed by the way. But I don't have time to spend on isolating all the dependencies, bandwidth is cheap, and the rest of the code in there is pretty interesting too, I am sure you will agree. Depending on your connection speed, this will take some time to download, so we can do something else in the meantime, such as have a quick look at the uml diagram of the foaf+ssl protocol:

    foaf+ssl uml sequence diagram

    Let us make clear who is playing what role. You are Romeo. You want your client - a simple web browser such as Firefox or Safari will do - to identify yourself to Juliette's Web server. Juliette as it happens is a semantic web expert and she trusts that if you are able to read through this blog, understand it, create your X509 certificate and set up your foaf file so that it publishes your public key information correctly then you are human, intelligent, avant-garde, and you have enough money to own a web server which is all to your advantage. As a result her semantically enabled server will give you the secret information you were looking for.

    Juliette knows of course that at a later time things won't be that simple anymore, when distributed social networks will be big enough that the proportion of fools will be large enough for their predators to take an interest in this technology, and the tools for putting up a certificate will come packaged with everyone's operating system, embedded in every tool, etc... At that point things will have moved on and Juliette will have added more criteria to give access to her secret file. Not only will your certificate have to match the information in your foaf file as it does now, but given that she knows your URL and what you have published there of your social graph, she will be able to use that and your position in the social graph of her friends to enabling her server to decide how to treat you.

    Creating a certificate and a foaf file

    So the first thing to do is for you to create yourself a certificate and a foaf file. This is quite easy. You just need to do the following in a shell.

    
    $ cd sommer/misc/FoafServer/
    
    $ java -version
    java version "1.5.0_16"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-284)
    Java HotSpot(TM) Client VM (build 1.5.0_16-133, mixed mode, sharing)
    
    $ ant jar
    

    Currently one needs at least Java 5 to run this.

    Before you create your certificate, you need to know what your foaf URL is going to be. If you allready have a foaf file, then that is easy, and the following will get you going:

    
    $ java -cp dist/FoafServer.jar net.java.dev.sommer.foafserver.utils.GenerateKey  -shortfoaf
    
    Enter full URL of the person to identify (no relative urls allowed): 
    for example: http://bblfish.net/people/henry/card#me
    http://bblfish.net/people/henry/card#me
    
    Enter password for new keystore :enterAnewPasswordForNewStore     
    publish the triples expressed by this n3
    # you can use use cwm to merge it into an rdf file
    # or a web service such as http://www.rdfabout.com/demo/validator/ to convert it to rdf/xml
    # Generated by sommer.dev.java.net
    @prefix cert: <http://www.w3.org/ns/auth/cert#> .
    @prefix rsa: <http://www.w3.org/ns/auth/rsa#> .
    @prefix foaf: <http://xmlns.com/foaf/0.1/> .
    <http://bblfish.net/people/henry/card#me> a foaf:Person; 
        is cert:identity of [ 
              a rsa:RSAPublicKey;
              rsa:public_exponent "65537"^cert:decimal ;
              rsa:modulus """b6bd6ce1a5ef51aaa69752c6af2e71948ab6da
    9e5a5f086dba7548d8b80150d392117d90138948062eec6ecb5745a45491eea03a46b0a1c2e6324d
    54144f42cdaa05ca39939eb973086cfedc8e31641cf7f29abc58310dcb8e56d9e6dae2233a317167
    74d1eb32ced152084cfb860fb8cb5298a3c0270145c5d878f07f6417af"""^cert:hex ;
              ] .
    
    the public and private keys are in the stored in cert.p12
    you can list the contents by running the command
    $ openssl pkcs12 -clcerts -nokeys -in cert.p12 | openssl x509 -noout -text
    

    If you do then run the openssl command you will find that the public key components should match the rdf above.

    
    $  openssl pkcs12 -clcerts -nokeys -in cert.p12 | openssl x509 -noout -text
    Enter Import Password:
    MAC verified OK
    Certificate:
        Data:
            Version: 3 (0x2)
            Serial Number: 1 (0x1)
            Signature Algorithm: sha1WithRSAEncryption
            Issuer: CN=http://bblfish.net/people/henry/card#me
            Validity
                Not Before: Nov 19 10:58:50 2008 GMT
                Not After : Nov 10 10:58:50 2009 GMT
            Subject: CN=http://bblfish.net/people/henry/card#me
            Subject Public Key Info:
                Public Key Algorithm: rsaEncryption
                RSA Public Key: (1024 bit)
                    Modulus (1024 bit):
                        00:b6:bd:6c:e1:a5:ef:51:aa:a6:97:52:c6:af:2e:
                        71:94:8a:b6:da:9e:5a:5f:08:6d:ba:75:48:d8:b8:
                        01:50:d3:92:11:7d:90:13:89:48:06:2e:ec:6e:cb:
                        57:45:a4:54:91:ee:a0:3a:46:b0:a1:c2:e6:32:4d:
                        54:14:4f:42:cd:aa:05:ca:39:93:9e:b9:73:08:6c:
                        fe:dc:8e:31:64:1c:f7:f2:9a:bc:58:31:0d:cb:8e:
                        56:d9:e6:da:e2:23:3a:31:71:67:74:d1:eb:32:ce:
                        d1:52:08:4c:fb:86:0f:b8:cb:52:98:a3:c0:27:01:
                        45:c5:d8:78:f0:7f:64:17:af
                    Exponent: 65537 (0x10001)
            X509v3 extensions:
                X509v3 Basic Constraints: critical
                    CA:TRUE
                X509v3 Key Usage: critical
                    Digital Signature, Non Repudiation, Key Encipherment, Key Agreement, Certificate Sign
                Netscape Cert Type: 
                    SSL Client, S/MIME
                X509v3 Subject Key Identifier: 
                    85:CD:66:A3:F7:23:DA:42:4B:F6:44:A1:90:A8:FE:27:9E:55:64:FE
                X509v3 Authority Key Identifier: 
                    keyid:85:CD:66:A3:F7:23:DA:42:4B:F6:44:A1:90:A8:FE:27:9E:55:64:FE
                X509v3 Subject Alternative Name: 
                    URI:http://bblfish.net/people/henry/card#me
        Signature Algorithm: sha1WithRSAEncryption
            a6:e0:3f:7c:cb:78:9b:f1:75:7f:62:ca:20:9e:a3:bb:87:61:
            29:59:3f:b9:bb:70:c5:06:bd:9a:62:fc:98:32:b7:f4:8b:53:
            ca:69:fc:5e:01:6a:4c:d8:85:5c:b3:a1:84:ec:1c:d2:6f:a8:
            0f:dd:c0:ff:9f:88:d2:84:8f:77:48:2e:f0:91:fb:2c:2a:22:
            96:07:be:ce:b2:98:87:ee:40:bd:16:32:fa:11:55:fb:0f:96:
            fb:c4:f8:be:66:3f:98:fa:62:61:0b:2f:b5:02:98:97:53:35:
            b5:46:32:c4:38:01:4c:97:66:aa:79:40:1a:67:45:bd:a0:e1:
            97:72
    

    Notice also that the X509v3 Subject Alternative Name, is your foaf URL. The Issuer Distinguished name (starting with CN= here) could be anything.
    This by the way, is the certificate that you will be adding to your browser in the next section.

    If you don't have a foaf file, then the simplest way to do this is to:

    1. decide where you are going to place the file on your web server
    2. decide what the name of it is
    3. Put a fake file there named cert.rdf
    4. get that file with a browser by typing in the full url there
    5. your foaf url with then be http://yourhost.com/path/cert.rdf#me

    Then you can use the following command to create your foaf file:

    
    $ java -cp dist/FoafServer.jar net.java.dev.sommer.foafserver.utils.GenerateKey
    

    That is the same as the first one but without the -shortfoaf argument. You will be asked for some information to fill up your foaf file, so as to make it a little more realistic -- you might as well get something useful out of this. You can then use either cwm or a web service to convert that N3 into rdf/xml, which you can then publish at the correct location. Now entering your url into a web browser should get your foaf file.

    Adding the certificate to the browser

    The previous procedure will have created a certificate cert.p12, which you now need to import into your browser. The software that creates the certificate could I guess place it in your browser too, but that would require some of work to make it cross platform. Something to do for sure, but not now. On OSX adding certs programmatically to the Keychain application is quite easy.

    So to add the certificate to your browsers store, open up Firefox's preferences and go to the Advanced->Encryption tab as shown here

    Firefox 3.03 Advanced Preferences dialog

    Click on "View Certificates" button, and you will get the Certificate Manager window pictured here.

    Firefox 3.03 Certificate manager

    Click the import button, and import the certificate we created in the previous section. That's it.

    Starting Juliette's server

    In a few days time Ian Jacobi will have a python based server working with the new updated certificate ontology. I will point to that as soon as he has it working. In the mean time you can run Juliette's test server locally like this:

    
    $ ant run
    

    This will start her server on your computer on localhost on port 8843 where it will be listening on a secure socket.

    Connecting your client to Juliette's server

    So now you can just go to https://localhost:8843/servlet/CheckClient in your favorite browser. This is Juliette's protected resource by the way, so we have moved straight to step 2 in the above UML diagram.

    Now because this is a server running locally, and it has a secure port open that emits a certificate that is not signed by a well established security authority things get more complicated than they usually need be. So the following steps appea only because of this and so, to make it clear that this is just a result of this experiment, I have placed the following paragraph in a blue background. You will only need to do this the first time you connect in this experminent, so be weary of the blues.

    Firefox gave me the following warning the first time I tried it.

    Firefox 3.03 certificate error dialog

    This is problematic because it just warns that the server's certificate is not trusted, but does not allow you to specify that you trust it (after all, perhaps you just mailed you the public key in the certificate and you could use that information to decide that you trust the server).

    On trying again, shift reloading perhaps, I am not sure, I finally got Firefox to present me with the following secure connection failed page:

    Firefox 3.03 secure connection failed page

    Safari had done the right things first off. Since we trust localhost:8843 (having just started it and even inspected some of the code ) we just need to click the "Or you can add an exception ..." link, which brings up the dialog below:

    Firefox 3.03 secure add exception page

    They are trying to frighten users here of course. And so they should. Ahh if only we had a localhost signed certificate by a trusted CA, I would not have to write this whole part of the blog!

    So of course you go there and click "Add Exception...", and this brings up the following dialog.

    Firefox 3.03 get Certificate dialog

    So click "Get Certificate" and get the server certificate. When done you can see the certificate

    Firefox 3.03 get Certificate dialog

    And confirm the security Exception.

    Again all of this need not happen. But since it also makes clear what is going on, it can be helpful to show it.

    Choose your certificate

    Having accepted the server's certificate, it will now ask you for yours. As a result of this Firefox opens up the following dialog.

    Firefox 3.03 Server requesting Client Certificate

    Since you only have one client certificate this is an easy choice. If you had a number of them, you could choose which persona to present to the site. When you click Ok, the certificate will be sent back to the server. This is the end of stage 2 in the UML diagram above. At that point Juliette's server ( on localhost ) will go and get your foaf file (step 3), and compare the information about your public key to the one in the certificate you just presented (step 4) by making the following query on your foaf file, as shown in the CheckClient class:

          TupleQuery query = rep.prepareTupleQuery(QueryLanguage.SPARQL,
                                    "PREFIX cert: " +
                                    "PREFIX rsa: " +
                                    "SELECT ?mod ?exp " +
                                    "WHERE {" +
                                    "   ?sig cert:identity ?person ." +
                                    "   ?sig a rsa:RSAPublicKey;" +
                                    "        rsa:modulus [ cert:hex ?mod ] ;" +
                                    "        rsa:public_exponent [ cert:decimal ?exp ] ." +
                                    "}");
           query.setBinding("person", vf.createURI(uri.toString()));
           TupleQueryResult answer = query.evaluate();
    
    If the information in the certificate and the foaf file correspond, then the server will send you Juliette's secret information. In a Tabulator enabled browser this comes out like this:

    Firefox 3.03 displaying Juliette's secret info

    The source code for all that is not far, and you will see that the algorithms used are very simple. This proves that the minimal piece, which is equivalent to what OpenID does, works. Next we will need to build up the server so that it can make decisions based on a web of trust. But by then you will have your foaf file, and filled up your social network a little for this to work.

    Further Work

    Discussions on this and on a number of other protocols in the same space is currently happening on the foaf protocols mailing list. You are welcome to join the sommer project to work on the code and debug it. As I mentioned Ian Jacobi has a public server running which he should be updating soon with the new certificate ontology that we have been using here.

    Clearly it would be really good to have a number of more advanced servers running this in order to experiment with access controls that add social proximity requirements.

    Things to look at:

    • What other browsers does this work with?
    • Can anyone get this to work with Aladdin USB e-Token keys or similar tools?
    • Work on access controls that take social proximity into account
    • Does this remove the need for cookie identifiers on web sites?

    I hope to be able to present this at the W3C Workshop on the Future of Social Networking in January 2009.

    Thursday Sep 04, 2008

    Building Secure, Open and Distributed Social Network Applications

    Current Social Networks don't allow you to have friends outside their network. When on Facebook, you can't point to your friend on LinkedIn. They are data silos. This audio enhanced slide show explains how a distributed decentralized social network is being built, how it works, and how to make is secure using the foaf+ssl protocol (a list of pointers on the esw wiki).

    It is licenced under a CC Attribution ShareAlike Licence.
    My voice is a bit odd on the first slide, but it gets better I think as I go along.

    Building Secure Open & Distributed Social Networks( Viewing this slide show requires a flash plugin. Sorry I only remembered this limitation after having put it online. If you know of a good Java substitute let me know. The other solution would have been to use Slidy. PDF and Annotated Open Document Format versions of this presentation are available below. (why is this text visible in Firefox even when the plugin works?) )

    This is the presentation I gave at JavaOne 2008 and at numerous other venues in the past four months.

    The slidecast works a lot better as a presentation format, than my previous semantic web video RDF: Connecting Software and People which I published as a h.264 video over a couple of years ago, and which takes close to 64MB of disk space. The problem with that format is that it is not easy to skip through the slides to the ones that interest you, or to go back and listen to a passage carefully again. Or at least it feels very clunky. My mp3 sound file only takes 17MB of space in comparison, and the graphics are much better quality in this slide show.

    It is hosted by the excellent slideshare service, which translated my OpenOffice odp document ( once they were cleaned up a little: I had to make sure it had no pointers to local files remaining accessible from the Edit>Links menu (which otherwise choked their service)). I used the Audacity sound editor to create the mp3 file which I then place on my bblfish.net server. Syncing the sound and the slides was then very easy using SlideShare's SlideCast application. I found that the quality of the slides was a lot better once I had created an account on their servers. The only thing missing would be a button in addition to the forward and backward button that would allow one to show the text of the audio, for people with hearing problems - something equivalent to the Notes view in Open Office.

    You can download the OpenOffice Presentation which contains my notes for each slide and the PDF created from it too. These are all published under a Creative Commons Attribution, Share Alike license. If you would like some of the base material for the slides, please contact me. If you would like to present them in my absence feel free to.

    Monday Apr 21, 2008

    FOAF & SSL: creating a global decentralised authentication protocol

    Following on my previous post RDFAuth: sketch of a buzzword compliant authentication protocol, Toby Inkster came up with a brilliantly simple scheme that builds very neatly on top of the Secure Sockets Layer of https. I describe the protocol shortly here, and will describe an implementation of it in my next post.

    Simple global ( passwordless if using a device such as the Aladdin USB e-Token ) authentication around the web would be extremely valuable. I am currently crumbling under the number of sites asking me for authentication information, and for each site I need to remember a new id and password combination. I am not the only one with this problem as the data portability video demonstrates. OpenId solves the problem but the protocol consumes a lot of ssl connections. For hyperdata user agents this could be painfully slow. This is because they may need access to just a couple of resources per server as they jump from service to service.

    As before we have a very simple scenario to consider. Romeo wants to find out where Juliette is. Juliette's hyperdata Address Book updates her location on a regular basis by PUTing information to a protected resource which she only wants her friends and their friends to have access to. Her server knows from her foaf:PersonalProfileDocument who her friends are. She identifies them via dereferenceable URLs, as I do, which themselves usually (the web is flexible) return more foaf:PersonalProfileDocuments describing them, and pointing to further such documents. In this way the list of people able to find out her location can be specified in a flexible and distributed manner. So let us imagine that Romeo is a friend of a friend of Juliette's and he wishes to talk to her. The following sequence diagram continues the story...

    sequence diagram of RDF+SSL

    The stages of the diagram are listed below:

    1. First Romeo's User Agent HTTP GETs Juliette's public foaf file located at http://juliette.net/. The server returns a representation ( in RDFa perhaps ) with the same semantics as the following N3:

      @prefix : <#> . 
      @prefix foaf: <http://xmlns.com/foaf/0.1/> .
      @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
      @prefix todo: <http://eg.org/todo#> .
      @prefix openid: <http://eg.org/openid/todo#> .
      
      <> a foaf:PersonalProfileDocument;
         foaf:primaryTopic :juliette ;
         openid:server <https://aol.com/openid/service>; # see The Openid Sequence Diagram .
      
      :juliette a foaf:Person;
         foaf:name "Juliette";
         foaf:openid <>;
         foaf:blog </blog>;    
         rdfs:seeAlso <https://juliette.net/protected/location>; 
         foaf:knows <http://bblfish.net/people/henry/card#me>,
                    <http://www.w3.org/People/Berners-Lee/card#i> .
      
      <https://juliette.net/protected/location> a todo:LocationDocument .
      

      Romeo's user agent receives this representation and decides to follow the https protected resource because it is a todo:LocationDocument.

    2. The todo:LocationDocument is at an https URL, so Romeo's User Agent connects to it via a secure socket. Juliette's server, who wishes to know the identity of the requestor, sends out a Certificate Request, to which Romeo's user agent responds with an X.509 certificate. This is all part of the SSL protocol.

      In the communication in stage 2, Romeo's user agent also passes along his foaf id. This can be done either by:

      • Sending in the HTTP header of the request an Agent-Id header pointing to the foaf Id of the user. Like this:
        Agent-Id: http://romeo.net/#romeo
        
        This would be similar to the current From: header, but instead of requiring an email address, a direct name of the agent would be required. (An email address is only an indirect identifier of an agent).
      • The Certificate could itself contain the Foaf ID of the Agent in the X509v3 extensions section:
                X509v3 extensions:
                   ...
                   X509v3 Subject Alternative Name: 
                                   URI:http://romeo.net/#romeo
        

        I am not sure if it would be correct use of the X509 Alternative names field. So this would require more standardization work with the X509 community. But it shows a way where the two communities could meet. The advantage of having the id as part of the certificate is that this could add extra weight to the id, depending on the trust one gives the Certificate Authority that signed the Certificate.

    3. At this point Juliette's web server knows of the requestor (Romeo in this case):
      • his alleged foaf Id
      • his Certificate ( verified during the ssl session )

      If the Certificate is signed by a CA that Juliette trusts and the foaf id is part of the certificate, then she will trust that the owner of the User Agent is the entity named by that id. She can then jump straight to step 6 if she knows enough about Romeo that she trusts him.

      Having Certificates signed by CA's is expensive though. The protocol described here will work just as well with self signed certificates, which are easy to generate.

    4. Juliette's hyperdata server then GETs the foaf document associated with the foaf id, namely <http://romeo.net/> . Romeo's foaf server returns a document containing a graph of relations similar to the graph described by the following N3:
      @prefix : <#> . 
      @prefix foaf: <http://xmlns.com/foaf/0.1/> .
      @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
      @prefix wot: <http://xmlns.com/wot/0.1/> .
      @prefix wotodo: <http://eg.org/todo#> .
      
      <> a foaf:PersonalProfileDocument;
          foaf:primaryTopic :romeo .
      
      :romeo a foaf:Person;
          foaf:name "Romeo";
          is wot:identity of [ a wotodo:X509Certificate;
                               wotodo:dsaWithSha1Sig """30:2c:02:14:78:69:1e:4f:7d:37:36:a5:8f:37:30:58:18:5a:
                                                   f6:10:e9:13:a4:ec:02:14:03:93:42:3b:c0:d4:33:63:ae:2f:
                                                   eb:8c:11:08:1c:aa:93:7d:71:01""" ;
                             ] ;
          foaf:knows <http://bblfish.net/people/henry/card#me> .
      
    5. By querying the semantics of the returned document with a SPARQL query such as
      PREFIX wot: <http://xmlns.com/wot/0.1/> 
      PREFIX wotodo: <http://eg.org/todo#> 
      
      SELECT { ?sig }
      WHERE {
          [] a wotodo:X509Certificate;
            wotodo:signature ?sig;
            wot:identity <http://romeo.net/#romeo> .
      }
      

      Juliette's web server can discover the certificate signature and compare it with the one sent by Romeo's user agent. If the two are identical, then Juliette's server knows that the User Agent who has access to the private key of the certificate sent to it, and who claims to be the person identified by the URI http://romeo.net/#romeo, is in agreement as to the identity of the certificate with the person who has write access to the foaf file http://romeo.net/. So by proving that it has access to the private key of the certificate sent to the server, the User Agent has also proven that it is the person described by the foaf file.

    6. Finally, now that Juliette's server knows an identity of the User Agent making the request on the protected resource, it can decide whether or not to return the representation. In this case we can imagine that my foaf file says that
       @prefix foaf: <http://xmlns.com/foaf/0.1/> .
      
       <http://bblfish.net/people/henry/card#me> foaf:knows <http://romeo.net/#romeo> .  
       
      As a result of the policy of allowing all friends of Juliette's friends to be able to read the location document, the server sends out a document containing relations such as the following:
      @prefix contact: <http://www.w3.org/2000/10/swap/pim/contact#> .
      @prefix : <http://juliette.org/#> .
      
      :juliette 
          contact:location [ 
                contact:address [ contact:city "Paris";
                                  contact:country "France";
                                  contact:street "1 Champs Elysees" ]
                           ] .
      

    Todo

    • Create an ontology for X509 certificates.
    • test this. Currently there is some implementation work going on in the so(m)mer repository in the misc/FoafServer directory.
    • Can one use the Subject Alternative name of an X509 certificate as described here?
    • For self signed certificates, what should the X509 Distinguished Name (DN) be? The DN is really being replaced here by the foaf id, since that is where the key information about the user is going to be located. Can one ignore the DN in a X509 cert, as one can in RDF with blank nodes? One could I imagine create a dummy DN where one of the elements is the foaf id. These would at least, as opposed to DN, be guaranteed to be unique.
    • what standardization work would be needed to make this

    Discussion on the Web

    Friday Apr 18, 2008

    The OpenId Sequence Diagram

    OpenId very neatly solves the global identity problem within the constraints of working with legacy browsers. It is a complex protocol though as the following sequence diagram illustrates, and this may be a problem for automated agents that need to jump around the web from hyperlink to hyperlink, as hyperdata agents tend to do.

    The diagram illustrates the following scenario. Romeo wants to find the current location of Juliette. So his semantic web user agent GET's her current foaf file. But Juliette wants to protect information about her current whereabouts and reveal it only to people she trusts, so she configures her server to require the user agent to authenticate itself in order to get more information. If the user agent can prove that is is owned by one of her trusted friends, and Romeo in particular, she will deliver the information to it (and so to him).

    The steps numbered in the sequence diagram are as follows:

    1. A User Agent fetches a web page that requires authentication. OpenId was designed with legacy web browsers in mind, for which it would return a page containing an OpenId login box such as the one to the right. openid login box In the case of a hyperdata agent as in our use case, the agent would GET a public foaf file, which might contain a link to an OpenId authentication endpoint. Perhaps with some rdf such as the following N3:
      <> openid:login </openidAuth.cgi> .
      
      Perhaps some more information would indicate which resources were protected.
    2. In current practice a human user notices the login box and types his identifying URL in it, such as http://openid.sun.com/bblfish This is the brilliant invention of OpenId: getting hundreds of millions of people to find it natural to identify themselves via a URL, instead of an email. The user then clicks the "Login button".
      In our semantic use case the hyperdata agent would notice the above openid link and would deduce that it needs to login to the site to get more information. Romeo's Id ( http://romeo.net/ perhaps ) would then be POSTed to the /openidAuth.cgi authentication endpoint.
    3. The OpenId authentication endpoint then fetches the web page by GETing Romeo's url http://romeo.net/. This returned representation contains a link in the header of the page pointing Romeo's OpenId server url. If the representation returned is html then this would contain the following in the header
       <link rel="openid.server" href="https://openid.sun.com/openid/service" />
      
    4. The representation returned in step 3, could contain a lot of other information too. A link to a foaf file may not be a bad idea as I described in foaf and openid. The returned representation in step 3 could even be RDFa extended html, in which case this step may not even be necessary. For a hyperdata server the information may be useful, as it may suggest a connection Romeo could have to some other people that would allow it to decide whether it wishes to continue the login process.
    5. Juliette's OpenId authentication endpoint then sends a redirect to Romeo's user agent, directing it towards his OpenId Identity Provider. The redirect also contains the URL of the OpenId authentication cgi, so that in step 8 below the Identity Provider can redirect a message back.
    6. Romeo user agent dutifully redirects romeo to the identity provider, which then returns a form with a username and password entry box.
    7. Romeo's user agent could learn to fill the user name password pair in automatically and even skip the previous step 6 . In any case given the user name and password, the Identity Provider then sends back some cryptographic tokens to the User Agent to have it redirect to the OpenId Authentication cgi at http://juliette.net/openidAuth.cgi.
    8. Romeo's Hyperdata user agent then dutifully redirects back to the OpenId authentication endpoint
    9. The authentication endpoint sends a request to the Openid Identity provider to verify that the cryptographic token is authentic. If it is, a conventional answer is sent back.
    10. The OpenId authentication endpoint finally sends a response back with a session cookie, giving access to various resources on Juliette's web site. Perhaps it even knows to redirect the user agent to a protected resource, though that would have required some information concerning this to have been sent in stage 2.
    11. Finally Romeo's user agent can GET Juliette's protected information if Juliette's hyperdata web server permits it. In this case it will, because Juliette loves Romeo.

    All of the steps above could be automatized, so from the user's point of view they may not be complicated. The user agent could even learn to fill in the user name and password required by the Identity Provider. But there are still a very large number of connections between the User Agent and the different services. If these connections are to be secure they would need to protected by SSL (as hinted at by the double line arrows). And SSL connections are not cheap. So the above may be unacceptably slow. On the other hand it would work with a protocol that is growing fast in acceptance.

    It is is certainly worth comparing this sequence diagram with the very light weight one presented in "FOAF & SLL: creating a global decentralised authentication protocol".

    Thanks again to Benjamin Nowack for bringing the discussion on RDFAuth to thinking about using the OpenId protocol directly as described above. See his post on the semantic web mailing list. Benjamin also pointed to the HTTP OpenID Authentication proposal, which shows how some of the above can be simplified if certain assumptions about the capabilities of the client are made. It would be worth making a sequence diagram of that proposal too.

    Friday Mar 28, 2008

    RDFAuth: sketch of a buzzword compliant authentication protocol

    Here is a proposal for an authentication scheme that is even simpler than OpenId ( see sequence diagram ), more secure, more RESTful, with fewer points of failure and fewer points of control, that is needed in order to make Open Distributed Social Networks with privacy controls possible.

    Update

    The following sketch led to the even simpler protocol described in Foaf and SSL creating a global decentralized authentication protocol. It is very close to what is proposed here but builds very closely on SSL, so as to reduce what is new down to nearly nothing.

    Background

    Ok, so now I have your attention, I would like to first mention that I am a great fan of OpenId. I have blogged about it numerous times and enthusiastically in this space. I came across the idea I will develop below, not because I thought OpenId needed improving, but because I have chosen to follow some very strict architectural guidelines: it had to satisfy RESTful, Resource oriented hyperdata constraints. With the Beatnik Address Book I have proven - to myself at least - that the creation of an Open Distributed Social Network (a hot topic at the moment, see the Economist's recent article on Online social network) is feasible and easy to do. What was missing is a way for people to keep some privacy, clearly a big selling point for the large Social Network Providers such as Facebook. So I went on the search of a solution to create a Open Distributed Social Network with privacy controls. And initially I had thought of using OpenId.

    OpenId Limitations

    But OpenId has a few problems:

    • First it is really designed to work with the limitations of current web browsers. It is partly because of this that there is a lot of hopping around from the service to the Identity Provider with HTTP redirects. As the Tabulator, Knowee or Beatnik.
    • Parts of OpenId 2, and especially the Attribute Exchange spec really don't feel very RESTful. There is a method for PUTing new property values in a database and a way to remove them that does not use either the HTTP PUT method or the DELETE method.
    • The OpenId Attribute Exchange is nice but not very flexible. It can keep some basic information about a person, but it does not make use of hyperdata. And the way it is set up, it would only be able to do so with great difficulty. A RESTfully published foaf file can give the same information, is a lot more flexible and extensible, whilst also making use of Linked Data, and as it happens also solves the Social Network Data Silo problems. Just that!
    • OpenId requires an Identity Server. There are a couple of problems with this:
      • This server provides a Dynamic service but not a RESTful one. Ie. the representations sent back and forth to it, cannot be cached.
      • The service is a control point. Anyone owning such a service will know which sites you authenticate onto. True, you can set up your own service, but that is clearly not what is happening. The big players are offering their customers OpenIds tied to particular authentication servers, and that is what most people will accept.
    As I found out by developing what I am here calling RDFAuth, for want of a better name, none of these restrictions are necessary.

    RDFAuth, a sketch

    So following my strict architectural guidelines, I came across what I am just calling RDFAuth, but like everything else here this is a sketch and open to change. I am not a security specialist nor an HTTP specialist. I am like someone who comes to an architect in order to build a house on some land he has, with some sketch of what he would like the house to look like, some ideas of what functionality he needs and what the price he is willing to pay is. What I want here is something very simple, that can be made to work with a few perl scripts.

    Let me first present the actors and the resources they wish to act upon.

    • Romeo has a Semantic Web Address Book, his User Agent (UA). He is looking for the whereabouts of Juliette.
    • Juliette has a URL identifier ( as I do ) which returns a public foaf representation and links to a protected resource.
    • The protected resource contains information she only wants some people to know, in this instance Romeo. It contains information as to her current whereabouts.
    • Romeo also has a public foaf file. He may have a protected one too, but it does not make an entrance in this scene of the play. His public foaf file links to a public PGP key. I described how that is done in Cryptographic Web of Trust.
    • Romeo's Public key is RESTfully stored on a server somewhere, accessible by URL.

    So Romeo wants to find out where Juliette is, but Juliette only wants to reveal this to Romeo. Juliette has told her server to only allow Romeo, identified by his URL, to view the site. She could have also have had a more open policy, allowing any of her or Romeo's friends to have access to this site, as specified by their foaf file. The server could then crawl their respective foaf files at regular intervals to see if it needed to add anyone to the list of people having access to the site. This is what the DIG group did in conjunction with OpenId. Juliette could also have a policy that decides Just In Time, as the person presents herself, whether or not to grant them access. She could use the information in that person's foaf file and relating it to some trust metric to make her decision. How Juliette specifies who gets access to the protected resource here is not part of this protocol. This is completely up to Juliette and the policies she chooses her agent to follow.

    So here is the sketch of the sequence of requests and responses.

    1. First Romeo's user Agent knows that Juliette's foaf name is http://juliette.org/#juliette so it sends an HTTP GET request to Juliette's foaf file located of course at http://juliette.org/
      The server responds with a public foaf file containing a link to the protected resource perhaps with the N3
        <> rdfs:seeAlso <protected/juliette> .
      
      Perhaps this could also contain some relations describing that resource as protected, which groups may access it, etc... but that is not necessary.
    2. Romeo's User Agent then decides it wants to check out protected/juliette. It sends a GET request to that resource but this time receives a variation of the Basic Authentication Scheme, perhaps something like:
      HTTP/1.0 401 UNAUTHORIZED
      Server: Knowee/0.4
      Date: Sat, 1 Apr 2008 10:18:15 GMT
      WWW-Authenticate: RdfAuth realm="http://juliette.org/protected/*" nonce="ILoveYouToo"
      
      The idea is that Juliette's server returns a nonce (in order to avoid replay attacks), and a realm over which this protection will be valid. But I am really making this up here. Better ideas are welcome.
    3. Romeo's web agent then encrypts some string (the realm?) and the nonce with Romeo's private key. Only an agent trusted by Romeo can do this.
    4. The User Agent then sends a new GET request with the encrypted string, and his identifier, perhaps something like this
      GET /protected/juliette HTTP/1.0
      Host: juliette.org
      Authorization: RdfAuth id="http://romeo.name/#romeo" key="THE_REALM_AND_NONCE_ENCRYPTED"
      Content-Type: application/rdf+xml, text/rdf+n3
      
      Since we need an identifier, why not just use Romeos' foaf name? It happens to also point to his foaf file. All the better.
    5. Because Juliette's web server can then use Romeo's foaf name to GET his public foaf file, which contains a link to his public key, as explained in "Cryptographic Web of Trust".
    6. Juliette's web server can then query the returned representation, perhaps meshed with some other information in its database, with something equivalent to the following SPARQL query
      PREFIX wot: <http://xmlns.com/wot/0.1/>
      SELECT ?pgp
      WHERE {
           [] wot:identity <http://romeo.name/#romeo>;
              wot:pubkeyAddress ?pgp .
      } 
      
      The nice thing about working at the semantic layer, is that it decouples the spec a lot from the representation returned. Of course as usage grows those representations that are understood by the most servers will create a de facto convention. Intially I suggest using RDF/XML of course. But it could just as well be N3, RDFa, perhaps even some microformat dialect, or even some GRDDLable XML, as the POWDER working group is proposing to do.
    7. Having found the URL of the PGP key, Juliette's server, can GET it - and as with much else in this protocol cache it for future use.
    8. Having the PGP key, Juliette's server can now decrypt the encrypted string sent to her by Romeo's User Agent. If the decrypted string matches the expected string, Juliette will know that the User Agent has access to Romeo's private key. So she decides this is enough to trust it.
    9. As a result Juliette's server returns the protected representation.
    Now Romeo's User Agent knows where Juliette is, displays it, and Romeo rushes off to see her.

    Advantages

    It should be clear from the sketch what the numerous advantages of this system are over OpenId. (I can't speak of other authentication services as I am not a security expert).

    • The User Agent has no redirects to follow. In the above example it needs to request one resource http://juliette.org/ twice (2 and 4) but that may only be necessary the first time it accesses this resource. The second time the UA can immediately jump to step 3. [but see problem with replay attacks raised in the comments by Ed Davies, and my reply] Furthermore it may be possible - this is a question to HTTP specialists - to merge step 1 and 2. Would it be possible for a request 1. to return a 20x code with the public representation, plus a WWWAuthenticate header, suggesting that the UA can get a more detailed representation of the same resource if authenticated? In any case the redirect rigmarole of OpenId, which is really there to overcome the limitations of current web browsers, in not needed.
    • There is no need for an Attribute Exchange type service. Foaf deals with that in a clear and extensible RESTful manner. This simplifies the spec dramatically.
    • There is no need for an identity server, so one less point of failure, and one less point of control in the system. The public key plays that role in a clean and simple manner
    • The whole protocol is RESTful. This means that all representations can be cached, meaning that steps 5 and 7 need only occur once per individual.
    • As RDF is built for extensibility, and we are being architecturally very clean, the system should be able to grow cleanly.

    Contributions

    I have been quietly exploring these ideas on the foaf and semantic web mailing lists, where I received a lot of excellent suggestions and feedback.

    Finally

    So I suppose I am now looking for feedback from a wider community. PGP experts, security experts, REST and HTTP experts, semantic web and linked data experts, only you can help this get somewhere. I will never have the time to learn these fields in enough detail by myself. In any case all this is absolutely obviously simple, and so completely unpatentable :-)

    Thanks for taking the time to read this

    Tuesday Aug 28, 2007

    My Bloomin' Friends

    Closed Social Networks are blossoming all over the place. They provide a semblance of protection, at a price: lock in. Locked into the social network provider you get convenience in the form of tools to make conversation easier (video, email, chat boards, ...), some form of privacy protection (if you trust the provider), introductions to 'like minded' people, and other niceties.

    Some of us work in the open air: we have to set standards in public view; we stand by what we say; we accept criticism from wherever it comes; and we can't choose our friends based on their social network provider. We describe ourselves in our foaf files where we can specify what we do, how to contact us, our interests, and links to who we know by pointing to their Universal Identifiers. There is no trouble linking between people who are open in this way. We are happy to reference each other: it strenghtens the exposure of our work and the quality of the web. This is how I link to Paul Gearon:

    :me foaf:knows  [ = <http://web.mac.com/thegearons/people/PaulGearon/foaf.rdf#me>; 
                      a foaf:Person;
                      foaf:name "Paul Gearon" ] .
    
    I could just point to his URL, but the little extra duplicate information can make life easier for people/robots browsing the data web. It can help people notice inconcistencies and help me correct them.

    But not everyone lives in the open the same way, and not everyone wants to make the same amount of information about themselves public. There are a number of different ways to deal with this. I want to discuss a few of them here.

    Content Negotition

    How much someone says about themselves is up to them, and so is how they protect their information. The same URL that identifies someone, could return more or less information depending on who is asking. I could set up my foaf file so only friends who log in via openid can see my friends. Others would just get default information about me. I could be even more clever. I could allow any friend of my friend who logs in via their openid to see my full foaf file; others would see information about me, and a select group of open friends. Closed Social Networks could open up by making it convenient to specify these policies, and providing the right infrastructure to do so.

    Indirect Identification

    By directly identifying someone via a URL (as I do) we can leave a lot of the policy of what they make visible up to them. But those that don't have a foaf name, need to be identified indirectly. We can do that by identifying them via some property such as their blog, their home page, their email address, or their openid. I am very open about my email addresses. They are published and visible to all.
     <http://bblfish.net/people/henry/card#me>     <http://xmlns.com/foaf/0.1/mbox> <mailto:henry.story@bblfish.net> .
    
    I value it more that people can contact me easily - living as I do in the middle of nowhere and often living nowhere in particular - than the pain of spammers. Too many people are lazy about security, using virus filled Windoze computers, obvious passwords, cracked software for me to be under any illusion that hiding my email is going to prevent the bad guys from getting it.

    However I can't assume that everyone else will accept me applying this argument to their email address. For this there is a nice mathematical technique: I can encrypt their email address using the SHA1 hash function. This create a close to unique string that cannot be dissasembled. You cannot go from the sha1 sum of an email address back to the email. But you can always calculate the same sha1sum from an email. This is how I identify Simon Phipps, Sun's Open source Officer:

    :me foaf:knows [ a foaf:Person;
                     foaf:mbox_sha1sum "4e377376e6977b765c1e78b2d0157a933ba11167";
                     foaf:name "Simon Phipps";
                     rdfs:seeAlso <http://www.webmink.net/foaf.rdf>
                   ].
    

    If you know Simon's email, then you will know that I know him. "What use is that?" I can hear someone ask. It's all about Working with People on the Internet. Imagine you are reading email on a newsgroup with a foaf enabled mail tool linked to a foaf enabled Address Book (such as Beatnik). You come on an email by Simon saying something interesting about how Sun has changed its stock ticker to JAVA for example. My logo and perhaps that of a couple of other people appears on the mail reader in a way that indicates to you that we know Simon. The post is no longer anonymous for you, and so has more trust value. You feel part of a community.[1]

    So spammers can not use that information to spam. Either they already know your email address, and so they are probably already spamming you, or they don't, and this won't help them. They can only [2] learn about social network claims: who claims to know who. They could use this, it is true to introduce themselves as an aquaintance of a friend of yours. A bit of a risky strategy that could quickly get them on a black list. Currently being black listed may not be an expensive proposition. But in a cryptographic web of trust this will be both much easier to notice, and more damaging for the infringers.

    Fuzzy Identification

    I can directly and indirectly identify a lot of people in my Address Book as described above. This is perfectly acceptable for people who have an open life, like I do, and a large portion of the Open Source community, bloggers, standard setters, etc... But on last count I had over 700 people in my AddressBook. It is a lot of work to identify all of them individuall, and to decide how much visibility I should give them. I may not even want people to know how many people I know this way. Also I may want deniability: there are people one may know, but one may not want to highlight that, and one may want to be able to deny that one knows them to some people. The foaf:sha1sum gives me a way to identify someone, but if some nozy person comes to me and asks me about that person's life after having identified the corresponding email address, there is no escape route other than refusing any conversation, which by itself can easily be taken to be significant. What we need is a way to fuzily identify a group of one's aquaintance.

    Bloom Filters

    This is what Bloom Filters enable one to do. Originally used in times when memory was expensive, they allowed the whole vocabulary of a language to be condensed into a reasonably short string. Here we can use it to group all the email addresses of our friends together in one opaque string. I could express as follows in RDF (bear in mind that the rdf vocabulary has not been settled on):
    :me foaf:bloomMbox [ a bloom:Bloom;
                         bloom:base64String """"
                IAOgQgSAAAICCAADAoQgDABAAiQKgIABgyAIBEhAAAAIUKBACCYAABAAaEkGQAGIEAHRUAgAAQUw 
                hCgwACJNQxQAAggAgCIgAAAAKgICEKAAAABCQiB0JCAAAIkgDASAYiAAAEIQAAIAABDCEAZACOpA 
                ICEEMAGAEGEAxIA=""";
                         bloom:hashNum 4;
                         bloom:length 1000 ] .
    

    Given the above Bloom someone can query it with an email address using the inverse algorithm and the Bloom will answer either that I may know that person, or that it can't tell. The loaf project explains some of the advantages of having this in more detail.

    The best way to get a feel for how it works is to try it. Here I have written a little java applet [3] that allows you to test my Bloom for people I know, and to create your own bloom [4].

    Your browser is completely ignoring the <APPLET> tag! Go to java.com to download the latest.

    Some emails you can try with positive results are tbray attextuality dot C O M, or bill at dehora dot net (suitably transformed of course). The applet lowercases all email addresses when creating and when testing the bloom.

    To create your own bloom just click the "Create Bloom" tab. An easy way to extract all your email addresses from an OSX Address Book is to run the following on the command line:

    hjs@bblfish:0$ osascript -e 'tell application "Address Book" to get the value of every email of every person' | perl -pe 's/,+ /\n/g' | sort | uniq | pbcopy
    

    You should now be able to paste the list of all your contacts in the applet. To restrict the Addresses to on of your groups named "foaf" for example replace the relevant section above with tell application "Address Book" to get the value of every email of every person in foaf.

    You will need to choose the number of hashes and the maximal size of the bucket you wish to fill. The greater the number of hashes and the greater the size of the bucket, the more precision you get and the less deniability.[5]

    Conclusion

    None of the above tools are by themselves the complete solution for creating an Open Social Network that will satisfy everyone. But for people willing to live in the open, the correct and astute use of them should satisfy most of people's requirements. Access Control on URLs can make it possible to reveal more or less information depending on who is looking; indirect identification can allow one to name people even without direct identification; sha1sums allows one to partially hide sensitve identifying information; and Blooms allow one to make fuzzy statements of set membership. All of these can be combined in different ways. So one can make statements about sha1sum identified people on the open web, or one can do so behind an access controlled file that only friends logged in with OpenId can see. There are bound to be more fun things to be discovered here. But this should make clear just how much can be done in this space.

    Notes

    1. For the link from email addresses to sha1sums to work, it helps to canonicalise the emails to all lowercase. This should probably be made more explict in the foaf:mbox_sha1sum definition.
    2. "They can 'only' learn about social network claims", is quite a lot more than some people are willing to accept. See the article by Mark Wahl "Organizing principles for identity systems: Attacks on anonymized social networks and fudging oracles" which contains some very good pointers. For people who want to retain complete anonymity, and this is what people subscribe to when they answer public surveys, any leakage of information is too much leakage. The problem is that because of Metcalf's Law it is nearly impossible to stop information combining itself: Information wants to be linked. So I think, when we are not tied to stringent laws, we should accept this rather than fight it, and use it to our advantage when hunting down spammers: the law holds for them too.
    3. You can get the source code for the applet on the so(m)mer repository in the misc/Bloom subdirectory. I used the pt.tumba.spell.BloomFilter class which I adapted a little for my needs. This was just the first one I found out there. It is probably not the most efficient one, as it uses an array of booleans, when it could use an byte array. If you know of other libraries please let me know.
      The code was put together really quickly and may well contain bugs. Feedback and patches and contributions are welcome.
    4. the advantage of Java Applets over server side code is really obvious here:
      • I don't need a server with a fixed port number to show you this
      • someone can't easily start a denial of service attack to bring the server down
      • You email addresses never leave your computer, so there is no fear of loss of privacy.
      On the last point it would be nice if browser vendors made it easier to get info about the exact restrictions a Java Applet had. I would like to be able to click on an Applet and verify or set it to "no network communication whatever". This would increase trust even more in cases like this.
    5. More info on the load site. Apparently one needs more than 1/4 deniability if one is to preserve some measure of privacy, according to the paper "the price of privacy and the limits of LP decoding" by Cynthia Dwork, Frank McSherry and Kunal Talwar (Microsoft Research) who suggests that
      ... any privacy mechanism, interactive or non-interactive, providing reasonably accurate answers to a 0.761 fraction of randomly generated weighted subset sum queries, and arbitrary answers on the remaining 0.239 fraction, is blatantly non-private.
      Thanks again to Mark Wahl for these references.
    6. Thanks a lot to Dan Brickley for working together with me on this last Friday, and pointing me to many of the important work done here. Dan also wrote a little python script to do something similar. Some of the sites I came across during our discussion: Not having studied bloom filters in detail, I am not sure how compatible the blooms of each of these libraries are. The super simple ruby bloom library does not seem to specify the number of hashes that were used to create a Bloom.
    7. Nick Lothian reminded me in a comment to this that he has written a Bloom Filter demo for facebook. I don't have a facebook account (because I am already on LinkedIn, and I can't really be bothered to move all my information, and because I don't like closed networks), so I was not able to use it. Perhaps I should get a facebook account just for this... Let me know.

    Thursday Aug 09, 2007

    cryptographic web of trust

    As our identity moves more and more onto the Web our ability to have people trust that what we write has not been altered is becoming increasingly important. As our home page becomes our OpenId, linking to our CV, blogs and foaf information, it will become more important for services to be able to trust that the information they see really is what I wrote. Otherwise the following scenario can become all to easy to imagine. Someone breaks into my web server and changes the OpenId link on my home page to point to a server they control. They then go and post comments around the web using my openid as identity. Their server of course always authenticates them. People who receive the posts then click on the OpenId URL which happens to be my home page, read information about me, and seeing that information trust that the comment really came from me.

    What is needed is some way to increase the methods people can have to trust information I state. Here I describe how one can use cryptography to increase that trust level. Starting from my creation of a PGP key, I show how I can describe my public signature in my foaf file, used PGP to sign that file and then link to the signature so that people can detect a tampered file. From this basis I show how one can build a very solid cryptographically enhanced web of trust.

    Creating your PGP public key

    After reading the first part of "SafariBooks Online, and feeling comfortable that I understood the basics, I decided it was high time for me to create myself a Public PGP key. Reading the GPG Manual and a few other HOWTOs on the web, using the gnu GPG library, I managed to make myself one quite easily.

    Linking to the Public Key from your foaf file

    Having this it was just a matter of placing it on my web site and using the Web Of Trust ontology developed by Dan Brickley to point to it and describe it, with the following triples:

    @prefix wot: <http://xmlns.com/wot/0.1/> .
    @prefix : <http://bblfish.net/people/henry/card#> .
    
    :me  is wot:identity of [ a wot:PubKey;
                            wot:pubkeyAddress <http://bblfish.net/people/henry/henry.pubkey.asc>;
                            wot:fingerprint "0DF560B5DADF6D348CC99EA0FD76F60D4CAE10D7";
                            wot:hex_id "4CAE10D7";
                            wot:length 1024 ] .
    

    The is wot:identity of construct is a nice N3 short hand for refering to the inverse relation of wot:identity, without having to name one. This states that my public key can be found at http://bblfish.net/people/henry/henry.pubkey.asc, and describe its fingerprint, key length and its hex id. I am not sure why the wot:PubKey resource has to be a blank node, and can't be the URL of the public key itself, which would make for the following N3:

    :me  is wot:identity of [ = < http://bblfish.net/people/henry/henry.pubkey.asc>
                              a wot:PubKey;
                              wot:fingerprint "0DF560B5DADF6D348CC99EA0FD76F60D4CAE10D7" ] .
    

    Perhaps simply because it is quite likely that one would want to put copies of one's public key in dfiferent places? owl:sameAs could have done the trick there too though...

    Signing your foaf file

    Anyway, once that is done, I want to be able to sign my foaf file. Of course it would be pretty tricky to sign the foaf file and put the signature into the foaf file simultaneously, as that would change the content of the foaf file and make the signature invalid. So the easiest solution is to simply have the foaf file point to the signature with something like this [1]

    <> wot:assurance <card.asc>
    

    The problem with this solution is that my foaf file at http://bblfish.net/people/henry/card currently returns two different representations: a rdf/xml one and an N3 one depending one how it is called. (More on this in I have a Web 2.0 name!). Now a signature is valid only for a sequence of bits, and the rdf sequence of bits is different from the N3 sequence, so they can't both have the same sig. There is a complicated solution developed by Jeremy Carroll in his paper Signing RDF Graphs, which proposes to sign a canonicalised RDF graph. The problem is that the algorithm to create such a graph does take some time to compute, only works on a subset of all RDF graphs, but mostly that no software currently implements that algorithm.
    Luckily there is a simple solution, which I got by inspiration from my work on creating an ontology for Atom, Atom OWL, and that is to link my card explicity to their alternate representation (the <link type="alternate" href="...">) [2] and to sign those alternate representations. This gives me the following triples:

    @prefix iana: <http://www.iana.org/assignments/relation/> .
    @prefix awol: <http://bblfish.net/work/atom-owl/2006-06-06/#> .
    
    <http://bblfish.net/people/henry/card>   a foaf:PersonalProfileDocument;
         iana:alternate <http://bblfish.net/people/henry/card.rdf>,
                        <http://bblfish.net/people/henry/card.n3> .
    
    <http://bblfish.net/people/henry/card.rdf>
           wot:assurance <http://bblfish.net/people/henry/asc.card.rdf.asc> ;
           awol:type "application/rdf+xml" .
    <http://bblfish.net/people/henry/card.n3>
           wot:assurance &lhttp://bblfish.net/people/henry/asc.card.n3.asc> ;
           awol:type "text/rdf+n3" .
    

    Here I am saying that my card has two alternate representations, an rdf and an n3 one, what their mime type is, and where I can find the signature for each. Simple.

    So if I put all of the above together I get the following extract from my N3 file:

    @prefix foaf: <http://xmlns.com/foaf/0.1/>.
    @prefix wot: <http://xmlns.com/wot/0.1/> .
    @prefix awol: <http://bblfish.net/work/atom-owl/2006-06-06/#> .
    @prefix iana: <http://www.iana.org/assignments/relation/> .
    @prefix : <http://bblfish.net/people/henry/card#> .
    
    <http://bblfish.net/people/henry/card>   a foaf:PersonalProfileDocument;
         foaf:maker :me;
         foaf:title "Henry Story's FOAF file";
         foaf:primaryTopic :me ;
         iana:alternate <http://bblfish.net/people/henry/card.rdf>,
                        <http://bblfish.net/people/henry/card.n3> .
    
    <http://bblfish.net/people/henry/card.rdf>
           wot:assurance <http://bblfish.net/people/henry/asc.card.rdf.asc> ;
           awol:type "application/rdf+xml" .
    <http://bblfish.net/people/henry/card.n3>
           wot:assurance <http://bblfish.net/people/henry/asc.card.n3.asc> ;
           awol:type "text/rdf+n3" .
    
    :me    a foaf:Person;
           foaf:title "Mr";
           foaf:family_name "Story";
           foaf:givenname "Henry";
           foaf:openid <http://openid.sun.com/bblfish> ;
           foaf:openid <http://bblfish.videntity.org/> ;
           is wot:identity of [ a wot:PubKey;
                                wot:pubkeyAddress <ttp://bblfish.net/people/henry/henry.pubkey.asc>;
                                wot:fingerprint "0DF560B5DADF6D348CC99EA0FD76F60D4CAE10D7";
                                wot:hex_id "4CAE10D7";
                                wot:length 1024 ];
    

    Which can be graphical represented as follows:

    Building a web of Trust

    From here is is easy to see how I can use the wot ontology to sign other files, link to my friends public signatures, sign their public signatures, how they could sign mine, etc, etc. and thereby create a cryptographically enhanced Web of Trust built on decentralised identity. Of course this is still a little complicated to put together by hand, but it should be really easy to automate, by incorporating it into the Beatnik Address Book for example. To illustrate this I will show I linked up to Dan Brickley and Tim Berners Lee's signature.

    Dan Brickley has a foaf file which links to his public key and to the signature of his file. The relevant part of the graph is:

       <http://danbri.org/foaf.rdf>     a foaf:PersonalProfileDocument;
                   wot:assurance <http://danbri.org/foaf.rdf/foaf.rdf.asc> .
    
       <http://danbri.org/foaf.rdf#danbri> 
                   foaf:pubkeyAddress <http://danbri.org/danbri-pubkey.txt>
    

    (foaf:pubkeyAddress is a relation that is not defined in foaf yet. Dan, one of the co-creators of foaf, is clearly experimenting here) Now with this information I can download Danbri's rdf, the public key and the signature and test that the document has not been tampered with. On the command line I do it like this:

    bblfish$ gpg --import danbri.pubkey.asc
    bblfish$ curl http://danbri.org/foaf.rdf > danbri.foaf.rdf
    bblfish$ curl http://danbri.org/foaf.rdf.asc > danbri.foaf.rdf.asc
    bblfish$ gpg --verify danbri.foaf.rdf.asc danbri.foaf.rdf
    

    Of course this assumes that someone has not broken onto his server and changed all those files. As it happens I chatted with Dan over Skype (which I got from his foaf file!) and he sent me his public key that way. It certainly felt like I had Dan on the other side of the line, so I trust this public key enough. But why not publish what public key I am relying on? Then Dan and others can know what signature I am using and correct me if I am wrong. So I added the following to my foaf file

    :me foaf:knows    [ = <http://danbri.org/foaf.rdf#danbri>;
                        a foaf:Person;
                        foaf:name  "Dan Brickley";
                        is wot:identity of
                              [ a wot:PubKey;
                                wot:pubkeyAddress <http://danbri.org/danbri-pubkey.txt>;
                                wot:hex_id "B573B63A" ]
                      ] .
    

    In the above I am linking to Dan's public key on his server, the one that might have been compromised. Note that I specify the wot:hex_id of the public key though. Finding another public key with the same hex would be tremendously difficult I am told. But who knows. I have not done the maths on this. But I can make it even more difficult by signing his public key with my key, and placing that signature on my server.

    bblfish$ gpg -a --detach-sign danbri.pubkey.asc
    

    Then I can make that signature public by linking to it from my foaf file

    <http://danbri.org/danbri-pubkey.txt> wot:assurance <danbri.pubkey.asc.asc> .
    

    Now people who read my foaf file will know how I verify Dan's information, and detect if something does not fit between what I say and what Dan's says. If they then do the same when linking to my foaf file - that is mention in it where one is to find my public key, it's hash and sign my public key with their signature, placing that on their server - then anyone who would want to compromise any of us consistently to the outside world, would have to compromise all of the information on each of our servers consistently. As more people are added to the network, and link up to each other, the complexity of doing this grows exponentially. As there are more ways to tie information together there are more ways people can find the information, so the information becomes more valuable (as described in RDF and Metcalf's Law), and there are more ways to find inconsistencies, thereby making the information more reliable, thereby making it more valuable, and so on, and so on...

    One can even make things more complicated for a wannabe hacker by placing other people's public keys one one's server, thereby duplicating information. Tim Berners Lee does not link to his public key, but I got it over irc, and published it on my web server. Then I can add that information to my foaf file:

    :me foaf:knows [ = <http://www.w3.org/People/Berners-Lee/card#i>;
                        a foaf:Person;
                        foaf:name "Tim Berners Lee";
                        is wot:identity of
                               [ a wot:Pubkey;
                                 wot:pubkeyAddress <timbl.pubkey.asc> ;
                                 wot:hex_id "9FC3D57E" ];
                      ] .
    

    By making public what public keys I use, I get the following benefits:

    • people can contact me and let me know if I am being taken for a ride,
    • it helps them locate public keys
    • the metadata associated with a public key grows
    • more people link into the cryptography network, making it more likely that more tools will build into this system

    Encrypting parts of one's foaf file

    Now that you have my public signature you can send me encrypted mail or other files using my public signature, verify signatures I place around the web and read files I encrypt with my private key. Of the files that I can encrypt one interesting one is my own foaf file. Of course encrypting the whole foaf file is not so helpful, as it breaks down the web of trust piece. But there may well be pieces of a foaf file that I would like to encrypt for only some people to see. This can be done quite easily as described in "Encrypting Foaf Files" [3]. Note that the encrypted file can be encrypted for a number of different users simultaneously. This would be simple to do, and would be of great help in making current practice available in an intelligent and coherent way to the semantic web. One thing I could do is encrypt it for all of my friend whose public key I know. I am not sure what kind of information I would want to do this with, but well, it's good to know its possible.

    Notes

    1. This is how "PGP Signing FOAF Files" describes the procedure.
    2. The iana alternate (http://www.iana.org/assignments/relation/) relation is not dereferenceable. It would be very helpful if iana made ontologies for each of their relations available.
    3. Thanks to Stephen Livingstone for pointing that way in a reply to this blog post on the openid mailing list.
    4. A huge numbers of resources on the subject can be found on the Semantic Web Trust and Security Resource Guide, which I found via the Wikipedia Web of Trust page.
    5. This can be used to build a very simple but powerful web authentication protocol as described in my March 2008 article RDFAuth: sketch of a buzzword compliant authentication protocol

    Search

    Recent Entries

    Navigation

    Referers