Sunday, December 17, 2006

xmldap as a plugin to perpetual motion

Kevin Miller's new Firefox plugin wraps the native Windows CardSpace identity selector, and in the process provides a great card parsing implementation. Since Kevin was kind enough to implement a plugin framework, I figured I'd take advantage and added plugin support to the xmldap selector.

If you pick up the latest version of the plugin (requires Java 1.5 on your system) you will now find a new Identity Selector option in your preferences. If you have both Kevin and my extension installed, and you're on Windows, you can now flip back and forth between the CardSpace selector, and the xmldap selector at will.




The great news is that people implementing selectors will no longer need to worry about augmenting the browser. Now hopefully we can all quickly agree on a preferences structure to allow any implementation to easily add itself to the list.

If you're interested in writing you're own plugin, it's pretty simple...here's the basics of an XPCOM component that implements the plugin interface:

http://openinfocard.googlecode.com/svn/trunk/firefox/components/Identityselector.js

have fun!

Tuesday, December 12, 2006

Another Firefox Cardspace Extension

Check out this cool extension for Firefox by Kevin Miller

http://www.perpetual-motion.com/

It basically wraps the native CardSpace implementation on Windows so you can use it from Firefox. Very robust looking parsing card detection, and the ability to implement an XPCOM interface to plugin other selectors:

IIdentitySelector..GetBrowserToken(issuer , recipientURL, requiredClaims ,data.optionalClaims , tokenType, privacyPolicy, privacyPolicyVersion , serverCert );

The selector implementation can be determined by the user's preferences, so it should be very simple to adapt the xmldap selector or other cross platform implementations to this model and let user's choose their selector.

Nice work Kevin!

Wednesday, December 06, 2006

Combining CardSpace and OpenID

At IIW I demo'd a little proof-of-concept showing the ability to login to a CardSpace relying-party, using an OpenID based identity. For those who didn't get a chance to see it, I provided a little screen cast here:

How-To Decrypt a CardSpace backup file

Having posted a utility that decrypts CardSpace backup files, I thought I'd take a moment to explain how it works. The backup file format is rather obscure, so hopefully this should help serve as a guide to people looking to import and export cards with non-Windows selectors.

The first thing to do is take a look at the CardSpace backup file format (edited for brevity):

<?xml version="1.0" encoding="utf-8"?>
<EncryptedStore xmlns="http://schemas.xmlsoap.org/ws/2005/05/identity">
<StoreSalt>3BprRlJ6LpWvvLvuGS6hXQ==</StoreSalt>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#">
<CipherData>
<CipherValue>...Base64 Encoded Ciphertext...</CipherValue>
</CipherData>
</EncryptedData>
</EncryptedStore>


Here we have the file format. There are really just two things we care about...the Salt, and the CipherValue. The first thing to do is extract these 2 values.

At this point, it's probably good to get an overview of what you'll be doing. The ciphertext is actually a 16 byte Initialization Vector, 32 bytes of signature data for validating integrity, and then a CardSpace RoamingStore xml document encrypted using a PBE. Specifically, it's a PKCS5v1 derived key and AES with CBC.

As you get started, one thing to be aware of is the byte order mark. Regardless of what it claims, this xml in this file is actually encoded using UTF-16LE. So...it's prefixed with 3 bytes of data. Here's what you should expect for the byte order mark:

byte[] bom = {(byte)0xEF, (byte)0xBB, (byte)0xBF};

You'll also want to know about a couple pieces of static entropy used in the algorithm:

byte[] encKeyEntropy = { (byte)0xd9, (byte)0x59, (byte)0x7b, (byte)0x26, (byte)0x1e, (byte)0xd8, (byte)0xb3, (byte)0x44, (byte)0x93, (byte)0x23, (byte)0xb3, (byte)0x96, (byte)0x85, (byte)0xde, (byte)0x95, (byte)0xfc };

byte[] integrityKeyEntropy = {(byte)0xc4, (byte)0x01, (byte)0x7b, (byte)0xf1, (byte)0x6b, (byte)0xad, (byte)0x2f, (byte)0x42, (byte)0xaf, (byte)0xf4, (byte)0x97, (byte)0x7d, (byte)0x4, (byte)0x68, (byte)0x3, (byte)0xdb};


So - back to business. Once you've extracted the salt and the ciphertext, you can begin to decrypt the backup file. Here are the steps you'll want to take:

  1. Remove the Byte Order Mark, and parse the XML file, extracting the Salt, and the CipherText
  2. Base64 decode the salt, and set it aside
  3. Base64 decode the ciphertext
  4. Copy the first 16 bytes of the ciphertext, and set it aside as your IV
  5. Copy the next 32 bytes of the ciphertext, and set it aside as your integrity check
  6. Concatenate the remaining bytes together with the IV. ( IV + remaining bytes ) Set this aside as your data
  7. Derive your keys using PKCS5v1. Take the bytes of the user's password used to encrypt the data, and concatenate it with the salt bytes. Take a SHA256 hash of those bytes, and then SHA256 hash the output another 999 times.
  8. Generate the encryption key by concatenating the static encryption entropy together with the derived key. Generate a SHA256 byte hash of these bytes, and that is your encryption key
  9. Generate the integrity key by concatenating the static entrgrity entropy together with the derived key. Generate a SHA256 byte hash of these bytes, and that is your integrity key
  10. Decrypt the data using AES/CBC/OAEP with the encryption key you generated
  11. Remove the byte order mark, and you have the decrypted RoamingStore.

So - that's the basics of decryption. If you'd like to encrypt a store, you simply perform that process in reverse.

Next, you'll want to validate the integrity of the data. Here's how:
  1. Concatenate the IV, the integrity check data ( bytes 12-48 that you set aside earlier), and the last block of data (the last 16 bytes)
  2. Sha 256 hash this, and you have the computed integrity check. Compare your computed value to the integrity check...if they match byte for byte, you're in luck.
That's it. Be wary of character encoding, but if you follow these steps, you should be able to encrypt/decrypt backup files

Friday, November 24, 2006

CardSpace Backup viewer

Ever wonder what's inside a CardSpace backup file? Now that the xmldap.org codebase can decrypt the backup files, I thought I'd add a quick tool that allows you to peek inside. Here's a little web app which will decrypt your backup file and return the xml inside:

http://xmldap.org/sts/decrypt

And here's a screencast of how it works:

Tuesday, November 21, 2006

Minor Bug Fixes

I updated the Firefox Selector to fix a few minor bugs introduced in the Managed Cards support update.

Thanks to Axel and to Antoine Galland from Gemalto for trying it out and reporting the bugs.

http://xmldap.org

Sunday, November 19, 2006

Managed Card Support for Firefox

One more important update for the Firefox selector - With this new release, I've added a simple proof-of-concept around Managed Cards.

The Firefox selector now supports importing managed cards, and retrieving tokens from an STS. It only has support for Username/Password authentication over the simple TransportBinding (this means transport security rather than message level security) Also, I've only tested against the xmldap.org STS...it may work against other implementations, but I haven't yet focused on interop.

That being said, this now demonstrates a complete end-to-end exchange without any Microsoft components. An opensource STS issuing a token to an opensource Relying Party, via an opensource selector...all on a Mac.

Here's a screencast of how it works:



As always, the selector and source are available at http://xmldap.org

Saturday, November 18, 2006

Firefox Plugin Updated

Thanks to the hard work of Axel Nennker and his friends, I've posted an update to the Firefox Selector. The selector now has these great features:

1) Support for Firefox 2.0 - the plugin should now work on 1.5+ and 2.0

2) Internationalization Support - Axel added i18n, and has localized to:

  • English
  • German
  • French
  • Norwegian
  • Swedish
  • Turkish
  • Czech
  • Arabic
  • and Chinese


3) There's also initial support for Logotype certificates, so that a website's icon embedded in a certificate can be displayed to the user as part of the verification process



You can download the latest plugin at http://xmldap.org/

Thanks Axel!

Monday, November 06, 2006

STS is finally working

I finally checked in a working copy of the xmldap Security Token Service. It's a simple STS, which only supports the Transport Binding of CardSpace, but it's enough to see managed cards in action.

If you'd like to try it out, go to https://xmldap.org/relyingparty/ There you'll find a link to where you can create managed cards. You'll then be able to install them into CardSpace and use them to login to the Relying Party. Below is a screencast which demos the basic steps you should follow:




As always, it's open source. The code is pretty messy at the moment, but if you're curious you can take a look at http://xmldap.org. Special thanks to the other contributors, and the folks at Arcot who figured out one of the missing pieces.

Tuesday, September 19, 2006

back online

Thanks to Ian, Ebe, and a new router, xmldap.org is back online.

Kim - you owe us $65.00 :-)

identityblog effect

Looks like Kim's two new posts have melted my server. He's the slashdot of the Identity world.

Sorry - the crack sys-admin team has been deployed. Hopefully we're back up soon!

Sunday, September 17, 2006

The Missing Infocard Schema

The Infocard Schema has been notoriously missing since Microsoft published RC1.

Here's the schema for the http://schemas.xmlsoap.org/ws/2005/05/identity namespace

Playing with Managed Cards

I've just checked in code that can create Managed Cards that import into CardSpace RC1.

To allow people to play around, I've also added a quick little web app, which creates cards for you. You can try this out at:

https://xmldap.org/sts/cardmanager




If you'd like to try it out, you can either download the source from http://xmldap.org

Relying Party updated to support RC1

I finally got around to updating the Relying Party to support Cardspace RC1.

Enjoy: https://xmldap.org/relyingparty

Saturday, September 16, 2006

Instructions for the CardSpace FirefFox Extention

It sounds like Craig Burton has been having trouble with the demo Cardspace Selector I put together for Firefox. I'm not sure what trouble he's been having, but I thought I'd toss up some quick instructions, and a screen cast.

Step 1) Make sure you're on Firefox 1.5 or greater.

Step 2) Make sure you've got J2SE 1.4x installed on your machine. The xmldap selector doesn't use any .net or Microsoft code...its a cross platform implementation written from scratch in Java. You can hit http://java.sun.com if you need to download a JDK

Step 3) Go to http://xmldap.org and download the Firefox extension. You may need to allow the popup blocker to trust my site. Restart firefox.

Step 4) Go to a Cardspace enabled site like xmldap, identityblog, or ping

Step 5) Click to login, create a card, and submit.

Note that you'll still get a warning saying: "Additional plugins are required to display all the media on this page" Ignore it...I haven't figured out how to make it go away yet. Please email me or comment if you know!


Craig and others - email me at cmort at xmldap.org if you have questions or issues!

Tuesday, September 12, 2006

Identity Selector for Safari

My good friend Ian Brown has taken the xmldap.org code and created an Identity Selector for Safari. It even integrates with the Apple Address Book for self-asserted cards. If you've got a Mac, check it out...if not, he's got a screen-cast.

Nice work Ian!

Sunday, August 27, 2006

6 screws and a plate!


6 screws and a plate!
Originally uploaded by Phil Hunt.
Phil Hunt from Oracle(OctetString), Ian Brown of SOA (BlueTitan) Phillip Kamps (yet another ex-sxipster), myself, and Phil's wife Wendy rode thigh deep powder at Whistler this year.

In a mad dash to the bottom to meet up with Mara, this happened to Wendy's knee.

She literally just laughed it off.


Update - My memory is off - it was Phillip instead of Ian. As Ian comments we was out with his own knee injury...which was my fault. Sorry Ian.

Catalyst 2006


mortimore, huang, shewchuk

Saturday, August 26, 2006

xmldap.org back online

Thanks to my friends at SOA Software, xmldap.org is back online.

There are a few new things as well:

  • The homepage has a new look, as well as a bunch of handy links: http://xmldap.org
  • The Relying Party has been updated to work with the latest CardSpace release.
  • The FireFox Identity Selector has been updated to get it working with the latest versions of Kim's blog and Ashish/Ping's demo site.
  • The selector also has a number of updates from Axel Nennker to support images for cards, and required fields in cards. Thanks Axel!
  • Axel also just came through with support for optionalClaims. Thanks again!

Thursday, June 15, 2006

Burnin' Down the House

"Chuck...this is Mark...apparently the house is on fire"

Everyone is ok, and the damage is minimal.

Slide show here

Identity Vocabulary Comparison

Here's a nice new overview of schemas across various identity systems by Johannes

Get it here

Discuss it here

Wednesday, June 07, 2006

Microsoft Labs STS

This was briefly available a few weeks ago...looks like it's live again:

http://sts.labs.live.com/

Haven't tried it yet myself, but it looks interesting.

Thursday, May 11, 2006

Even better than the dolphins

This article about dolphins referring to each other by name has been making the rounds in the identity world.

The monkeys are still more human.

I completely agree...

...with Johannes' latest post.

It's too bad rdf is so difficult for people to work with (or even grok)...the simple injection of a predicate into the name/value pair and you'd retain the ability to serialize complex object graphs.

Monday, May 01, 2006

Firefox Identity Selector

I've just posted a prototype identity selector for firefox, which allows you to login to infocard enabled sites, without infocard, or even windows.

You can download it here: http://xmldap.org/xmldap.xpi

In order to get started, download and install the extension, and then browse over to one of the public relying parties. It also requires that you have a JVM installed, which you can pick up from java.com if need be.

Please note that this is of alpha quality. It only supports Self Asserted tokens, and many other desireable features have not been implemented. However, it should provide the based for some interesting discussions at IIW this week.

Enjoy, and please send feedback.

[Update: There seems to be a small bug with selecting cards. If you click on a card to select it, and its values do not fill in on the right side of the screen, then click it again until they do. If you attempt to submit with blank values it won't work]

[Update: Also - keep in mind that I haven't figured out how to make the Firefox warning that a plugin to handle the infocard object isn't installed. Simply ignore this, and please send me a note if you know how to make this go away]

Wednesday, April 19, 2006

Mara's on Flickr

Check out our pics from NYC

Or subscribe to her ATOM feed

Interesting code block...

Here's an interesting block of code for displaying Certificates I found while poking around Firefox this evening...


mapIssuerOrganization: function(name) {

if (!name) return null;

if (name == "RSA Data Security, Inc.")
return "Verisign, Inc.";

// No mapping required
return name;
}

Monday, April 10, 2006

Another Java RP

This time from Ashish at Ping:
https://infocard.pingidentity.com/infocard-sp/

Nice Work!

Sunday, April 09, 2006

Finally...a Windows VM for the Mac

I've got to say, Parallel's workstation rocks. I'ts jsut like VMWare except it runs on OSX. Despite the occasional kernel panic (it's still in beta), I can now play with InfoCard without leaving my Mac. XP is super fast, and my friends at Sun will be glad to know that Solaris x86 is supported.


Here's some screen shots of InfoCard running in a VM (click for bigger shots):


Here, I'm prompting for an InfoCard



InfoCard displays some information about my RP, and asks if I want to send a card.



Since this is my first time using InfoCard, it asks if I'd like to create a card, or perhaps import some existing cards.


Here, I'm creating a new self-asserted card.



InfoCard confirms that I want to send my new card.



And I'm logged into my RP.

Friday, March 31, 2006

How to consume tokens from Infocard

So - if you’ve been wondering how my RP works...here’s an overview. I’m not going to cover declaring Policy or anything, as Mike Jones’ paper seems to have covered it in pretty good detail. I’m assuming here you can get InfoCard to invoke and POST a token.

To get started, you need to get your hands on the XML Token. This should be pretty simple, as your web framework will generally hand back parameters already URL decoded.

Once you’ve got the token, you’ll need to decrypt the token. The token is transmitted as encrypted XML, and will look something like this:


<enc:EncryptedData xmlns:enc="http://www.w3.org/2001/04/xmlenc#"
Type="http://www.w3.org/2001/04/xmlenc#Element">
<enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<enc:EncryptedKey>
<enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
</enc:EncryptionMethod>
<dsig:KeyInfo>
<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">zHXxYr8jTDe/UhznC81ixsQXSpI=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</dsig:KeyInfo>
<enc:CipherData>
<enc:CipherValue>hgBNzEXXnoLNu6DPhXJanirEPOK/ey53RKISJrwvRhQazPBgqcnZPaxNVqZf6TOR1VbryCU6fbGw
jIuuXzTb5Z+0PsRPM4N8CLSBxYxN1BFCNnhW67qJ4zrw72OTIkkTLWvPDpJpAak6X6RGFteaf3zD
uVYU4Ta0sDmMD6lxgjs=</enc:CipherValue>
</enc:CipherData>
</enc:EncryptedKey>
</dsig:KeyInfo>
<enc:CipherData>
<enc:CipherValue>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</enc:CipherValue>
</enc:CipherData>
</enc:EncryptedData>


Basically what you have here is an ephemeral symmetric encryption key, which has itself been encrypted with the Public Key of the SSL Cert for the website InfoCard is interacting with. As you can see from the metadata provided in the KeyInfo fragment, the key is encrypted using RSA with OAEP encoding and SHA1, using the certificate identified in the SecurityTokenReference with the provided fingerprint (the fingerprint is a SHA1 hash of the cert bytes)

Your first job is to decrypt that encryption key. Step one - remove the Base64 encoding. Step 2 - you need to write a function which takes the private key for the cert referenced by the fingerprint, along with the data as input, and decrypts in this manner RSA-OAEP

Once you’ve successfully decrypted the key ( it should be 256 bits), you can use it to decrypt the token. As you can see in the XML, you need to use AES with a ChainedBlockCipher. Decrypt the token (Don’t forget to strip the initialization vectors...thanks Gary ), and you should see something similar to the following:



<saml:Assertion MajorVersion="1" MinorVersion="1"
AssertionID="uuid:d2de97e7-96ac-4bb3-a373-4fc11c914519"
Issuer="http://schemas.microsoft.com/ws/2005/05/identity/issuer/self"
IssueInstant="2006-03-29T20:52:45.312Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:Conditions NotBefore="2006-03-29T20:52:45.312Z" NotOnOrAfter="2006-03-29T21:52:45.312Z" />
<saml:AttributeStatement>
<saml:Subject>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:holder-of-key</saml:ConfirmationMethod>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
</e:EncryptionMethod>
<KeyInfo>
<o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">BCDy8bwQIxTqcoTObIhcvR2KOLw=</o:KeyIdentifier>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>XjkCVuQZ19sYbSnEeKYQ7wD/+bKvGL6kkS2yuVjQX4y3N7U86zRJ66njNPdFNdh8k/x+5CNF1rpjq/Be75a1skO9ePjLgik/UA1DlDo9jaFoYvRlEj0BN/TPJaMZ24kcmcG+QeU89rdg0S4+bqxytHyh14m6IaIaX4aj88RRVq4=</e:CipherValue>
</e:CipherData>
</e:EncryptedKey>
</KeyInfo>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Attribute AttributeName="GivenName" AttributeNamespace="http://schemas.microsoft.com/ws/2005/05/identity/claims">
<saml:AttributeValue>Mister</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute AttributeName="Surname" AttributeNamespace="http://schemas.microsoft.com/ws/2005/05/identity/claims">
<saml:AttributeValue>Milo</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute AttributeName="EmailAddress" AttributeNamespace="http://schemas.microsoft.com/ws/2005/05/identity/claims">
<saml:AttributeValue>milo@xmldap.org</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#uuid:d2de97e7-96ac-4bb3-a373-4fc11c914519">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>leav91ZV/KJpwumP/j+4XtlEvJg=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>gEVmREMwNiE67hMdOf7uuC4jnhG4f9y3WYL2pL6d9F3Nblf3qddMe6K+d/b6ucePKS3Q9XXBmBu2tWtmZlwTzldVjx8IYZb5u5jcQByAp2GrTJb/XxHA/3BkE073zdFRlmHje467kVd4Mcg6X2qNsV1N+euZqCUfmrXyf3cs5n4u6A9A1CTuQhCOGhE7jjDUGPmyChJa2YfHqpiVPEXgqN+RYOTLUFbA2kKj1Jyi8+FJD7vHP/5/kblge82waNFOOaA6d7lXDhr4lBDDhr5vKoNWy91bDMStn+nKN7Nzj7zPjxjynp7CisSewyWxAjcD9XDl/I9Va2UVDmPr4JC4bw==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>rCOb7lDap18tsTurz6j/fSYnO+ck5or10hn9tZhCDwXfJip2lqjIFcj3fYv1cyP96dl4++x8QGXSB5WAu3NNtjZkVxTDO4sOk+IpkLOlE5vM6ClMSV46tx9fo6tbQ9EhJTy7vXAbCH6hQnowxdmUEVKJudCtlMeHSotix98T5zJXYMjeLvmDPmSK8pG/t+kBmRjsgSZGqjD4VFlnDBpYOZ4R+nH2ESudyvZUwAkgPAEtGuBcc+nXVUEbs+O1xOkzcTRCm9FCoww1oNSi2maRGontD14Cbyy3DuNRxqPSxEc8rN7KBoq5w2y+Q5YTVYBB+qn2rXbO0aQlYHXIZOATpw==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</saml:Assertion>



The next step would be to quickly check the validity period on this Assertion to make sure it’s still fresh. You might also want to check the AssertionID against a table of previously seen assertions to prevent replay...depends on your level of paranoia.

On to signature validation...you should follow the steps outlined in XML-DSIG, but to paraphrase, check the digest of the canonicalized assetion against the digest in the SignedInfo block, and then valhttp://www.blogger.com/img/gl.link.gifidate the signature of the canonicalized SignedInfo using a PublicKey constructed from the provided KeyInfo.

Now, what’s bugging me is the use for the Symmetric Proof key provided in the Subject of the Assertion. Super Pat and I discussed this for awhile, and since it’s not used immediately in this protocol exchange, our best guess is that it’s used in subsequent interactions with the service, although I must admit the InfoCard docs are a little fuzzy on this subject. If anyone can fill me in, I’d appreciate it!

Finally, if your signature validation worked, extract the claims, enforce any policy you’d like, create a session, set a cookie, etc...

good luck!

Thursday, March 30, 2006

Make your own security tokens without InfoCard

Once you can consume security tokens from InfoCards, it's not too difficult to make them. Since most people don't have the time to try out InfoCard for real, I thought I'd add a quick utility to make your own tokens, and submit them to my RP. This should allow you to at least learn about the format and protocol for using InfoCard over the web.

Try the updated Java RP

Wednesday, March 29, 2006

Simple Java Based Relying Party

I've just turned on an InfoCard Relying Party, implemented from the ground up in Java. If you've got InfoCard up and running, please login and send me a comment.

Java Based RP

I'll follow up soon with details, as well as an overview of how it works.

[Update: I've had some complaints that this isn't working with the latest and greatest IE ( due to an issue with IE according to Kim ) I suggest build 7.0.5296.0 for now. ]