Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2005-502
$eventId
ID of event: wwdc2005
$eventContentId
ID of session without event part: 502
$eventShortId
Shortened ID of event: wwdc05
$year
Year of session: 2005
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC05 • Session 502

Smart Cards in Mac OS X

OS Foundations • 1:03:20

Smart Card support has been greatly expanded in Mac OS X Tiger. Smart Cards offer a great way to store certificates, which can then be used by your applications, as well as by Mail and Safari. Apple's engineers will show you how to access Smart Cards from applications and how to write 'tokend' plug-ins to interface your Smart Card to Mac OS X.

Speakers: Michael Brouwer, John Hurley

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

Good morning. I'm Michael Brouwere, engineer in the Data Security Group. I'm going to talk to you about Smart Cards in Mac OS X today and what the state of Smart Card support is. So first I'd like to cover what this session is going to be about. We're going to cover the use of Smart Cards in OS X.

As of Tiger, we actually have native support for a number of different cards, and we're going to show you where we've gotten since the last time we presented to you. I'm going to talk about what you can do if any of you here are -- how many of you here are application developers? So, I'm going to tell you what you need to do if your application does any security work to have Smart Card support enabled in your applications. And then, how many of you here are developers of Smart Card solutions or Smart Card vendors? Alright, so the majority of the presentation is going to go talking about how to add support for new types of cards to Mac OS X.

For which, if you application developers do the work right, the people writing the support for Smart Cards will have their cards just work with any application. So, first I'd like to show you the progress we've made since last year, and to do that, I'd like to start off with a demo, and I'm going to bring John Hurley up on stage for that.

[Transcript missing]

So one of the things that is different on Tiger is as you plug in the reader, PCS CD, which operates PCS C, will notice that, or

[Transcript missing]

First, I think what I'll do is insert the... This is a Department of Defense common access card. So insert that card. And I'm going to go to Keychain Access.

And you'll see that it just shows up like a keychain. So the really interesting thing about this from the application developer's point of view, what we've been telling developers for actually several years now at WWDC is unless you actually are writing drivers for a reader or you have to support a new type of card, you don't even have to worry about Smart Cards. So what you should do is write to the high-level security APIs, as Michael will talk about, and then everything else should just work.

So here, this is just showing up just like a regular keychain. I have a couple of certificates in there. It's all what you'd expect to see. Okay, now I'm going to remove that one. This is another card that's very similar to the DoD Common Access Card, the Department of Homeland Security card that they're going to be issuing soon.

I'm going to launch Keychain Access again. Now you'll see that card show up. It takes a little bit of time. What it's doing now is actually reading the certificates, but the way things are written, after those certificates are read once, if they're not part of the PIN-protected data, those things are cached. So you'll notice actually quite a good performance improvement over what we had in previous releases.

So here, these are standard certificate dialogues. You can see some of the things that are on the card. Now, okay, keychain access by itself is not particularly interesting. What are some of the other things that we've done We said that we would integrate it into the system, and we've done it. So here is Internet Connect application, right? This is what you'd use to hook up through VPN. And if I... Just create a configuration and click on 'Other'. You'll see that here it's giving me a choice of certificates to choose to use with VPN.

So here would be a certificate. I'm not connected to the network here, so I'm not going to actually show how this part works. But the main point is, the people that wrote the Internet Connect application didn't have to do anything special with Smart Cards either. They just wrote to the high-level security APIs. Okay, so we're going to cancel out of that. Now, let's go to another application.

Before I show you what's going on in Mail, another application that I'm not going to demonstrate but there's built-in support for is Safari. It's worth pointing out that if you need your Smart Card to work with client-side authentication in Safari, the method that Michael is going to describe is the only way that we support to do it. So there's no other way. You just have to act like you're a keychain and then it'll work automatically with Safari. Okay, so here in Mail, let me just compose a message.

And what you'll notice is, over on this side of the screen, there's two icons. There's a little lock icon, which is grayed out, and there's this kind of checkmark icon. That means that I can digitally sign the message. Those icons are just there because it's seen that I have a Smart Card and it realizes that I have a credential on there that I can use to sign with. So it's very, very low key, but it's very tightly integrated into the system.

and I think at this point, Michael's going to come back up and then I have another demo in a minute or two, right? Thank you, John. So, as you've seen, what we have since Mac OS 10.3, we've done a number of things. We support Smart Card login, but not just login.

Actually, if you configure a system that allows Smart Card login, you can also use Smart Cards for authorization dialogues and for unlocking the screen if you have the screen locker enabled. So, anything that normally requires a password and uses the authorization APIs will work with Smart Cards in OS X. In Tiger, sorry.

Email, you can do signing, John demoed that, although he didn't actually send the mail. That does work. You can do encryption, or actually rather decryption, using the Smart Card. So if someone sends you an encrypted message using one of the certificates that have an associated key on your Smart Card, Mail will, if the Smart Card is inserted, Mail will find that key and know how to decrypt the message and ask you for your PIN and it will decrypt the message.

So, SSL client-side auth works in Safari. The VPN example you showed is actually similar, although it's not identical. 802.1X is another thing. There's an option in Internet Connect to use 802.1X. Also supports certificate-based authentication methods. Also works with Smart Cards. What's interesting is that actually Apart from login, none of these other applications actually had any Smart Card related changes during Tiger.

And so the question is, what do you as app developers need to do to get Smart Card support in your app? Well, hopefully the answer is nothing. If you have listened to us for the past, I don't know, five years, if you're using CDSA or you're using the sec. Keychain APIs or higher level APIs, then your application should just work with Smart Cards. And to show you an example of that, I'd like to bring John back up on stage. And he's going to show you how to add Smart Card support to an existing app.

Michael, so he's slightly misstated it. It's not really adding it to an existing app. The demo that I'm going to do now is, I think it was really a great success for what we had done in terms of Smart Cards. So as we've mentioned, we've been talking about, you know, just use the very high level APIs and stuff should just work.

And one of the companies that was interested in having Smart Cards work was Microsoft, the Mac business. And they really wanted to be able to sign emails using Smart Cards in Entourage. And they, it's not an official feature, partly because there's not really big deployments of Smart Cards out there yet.

But when we were talking to them about that, we said, well, okay, we don't actually have any Smart Card support that you can use in Entourage. But if you write to these companies, you can use Smart Cards. So you do things like SecFind Certificate, SecFind Identity, use those high level things. Then when the Smart Card stuff comes out, hopefully it'll all work.

So they released Office 2004 in June of 2004. And in September or October, we had a Smart Card kitchen and they sent somebody with one of their internal Smart Cards. And they spent a day writing their token D. And hooked it up and they said, hey, you're right, it does, it just works. So let me show you what support they have for that in Entourage.

What's particularly interesting about this, you'll notice that there's no Smart Card specific terminology in here at all. So in preferences, account creation, we'll find it there. Okay, so in account settings, There's a tab called 'Security' and you can choose a certificate there. And they didn't change any code.

They just said, "Okay, let's do a find certificate." It's seeing this card in the reader, and it says, "Okay, you can use that certificate to sign things with."

[Transcript missing]

Under the message menu, they have a security thing and we can digitally sign it. So I'm not connected, but I can send it and you'll see it show up.

Well, I'm not sure why that's not sending, but fortunately I'd sent one before when I was trying this out. So here's, this is one that I sent before with the same card and it's just in my outbox and it says that this message has been digitally signed. And if I view the details, it shows all the details about this message. And I can view the sender's certificate.

[Transcript missing]

The existing Mac OS X entourage, an existing Mac OS X application, and it was written well before we actually had Smart Card support, and it just works with Smart Cards. And Microsoft actually didn't have to make any changes at all to entourage. This is just the version that shipped in June of 2004.

John talked a little bit earlier about Microsoft having to write a 'tokend', which is to support a new kind of card, which I'll talk about in a little bit. So, like I said, how do you get this level of integration in your apps? How do you get support for Smart Cards? If you use CDSA or the CDSA-based APIs in Mac OS X, you'll get Smart Card support.

The best thing to do if you're looking for a key is to use SecKeyRef and Friends. Friends being SecCertificateRef, as John already mentioned. And there's a class called SecIdentity. SecIdentities are actually pairs of keys and certificates. So if you just search the system for all available identities that can sign, for example, it'll come up with identities both in user keychains and identities on Smart Cards.

[Transcript missing]

So how do you implement Smart Card support for new Smart Cards in Tiger? We thought about this and we thought about what we wanted and how we got to Smart Card support. And we made a number of choices when we designed this. And those choices were based on some of these goals that I'm listing here.

First, and I think the most important goal was, we wanted zero user configuration. That means that the end user shouldn't have to install any drivers or configuration thingies or whatever. Someone who gets a laptop and has a Smart Card, it should just work. And that is the state of Tiger today.

If you're someone who has one of the supported Smart Cards in Tiger, which today are the CAC cards, which the DoD uses, the Belgian Identity Cards, which John showed, and we also have support for Japanese National Cards, and the National ID Card, which is being rolled out soon.

If you have one of those cards and you plug it into a Tiger machine, Mail and all these other apps that John demoed, and any apps that correctly use the Sec APIs, will just work with that Smart Card. The user doesn't have to configure anything. The only exception is login. You have to configure allowing a particular account to login with a Smart Card.

Another goal was to work with existing Mac OS X applications. For everyone here that's actually followed our advice and used the Sec APIs, we wanted to make sure that those applications could leverage the Smart Card support we put into Tiger. What we explicitly didn't want is for each application to be aware of Smart Cards and have to do specific things to support specific Smart Cards.

And last, and this is something we didn't really show you, but that's actually something we've achieved, is Single Sign-On. The Smart Card solution in Tiger, if you use a card to log in and you use that same card for sending mail and you use that same card for connecting to the VPN, you don't have to enter your PIN in every app that uses the card. You can enter your PIN once and you can use that card in all these different apps.

We examined some of the different options. Given that we're using CDSA, and CDSA is supposed to be this pluggable security architecture, the first and most obvious choice to us was, well, we'll just write a CSPDL, which is a cryptographic service provider and a data store library, for each card and load that into each app.

So that way, each app that wants to talk to a particular Smart Card loads this plug-in and can talk to the card. And obviously, we could abstract that using the higher level APIs to automatically do this. That meets two out of the three goals. What it doesn't meet is the single sign-on goal.

It also means that applications using the lower level CDSA have to be aware of these new CSPDLs, but the biggest problem was the absence of having single sign-on and not having the ability to do that. There's another problem with that, and that's how would you integrate the UI for getting a pin if this application was, let's say, a faceless application, like a background process trying to sign a message for you. That's another thing in our current architecture we solve.

Another option, which I'm sure anyone here doing Smart Cards is familiar with, is PXS 11. We write a PXS 11 driver for each card type and use that. Again, the application would load that PXS 11 driver and talk to the card to do that. It has the same problem as a CSPDL, but in addition, it doesn't mesh with our existing APIs. The APIs we've been telling you as developers to use for all these years have been CDSA.

PXS 11 is similar in functionality to a CSPDL, but with a slightly different API. Given that we never had Smart Card support, we'd be introducing a completely new API for application developers to deal with Smart Cards. Meaning, an application that worked fine with encryption and Mail would have to rev to support Smart Cards. It's actually something we wanted to avoid. Our solution was to use a PXS 11 driver for all of our applications.

Horizontal Smart Card support. We wanted a solution that works across the entire system, not just a vertical app like, let's say, you ship your app that supports just one particular card and it works through the PCSC stack. That's pretty much the solutions we've seen on Windows today. All are fairly vertical solutions. They'll support a card in a particular app through the stack. We wanted it to work with login, authorization, mail, Safari, screen locking, anything using authorization, any apps that correctly use the SEC and CDSA APIs.

We wanted single sign-on, and more importantly, because single sign-on without ACL support would be somewhat insecure. So we wanted ACL support, which is the access control list that CDSA and keychains use. How many of you are familiar with the keychain APIs here? Not a lot? Well, I'll go into a little more detail about ACLs later on in the session.

So, like I said previously, all we had was vertical solutions. There were maybe two or three vendors out there that actually provided a vertical solution, but everyone had to do their own integration with Login Window and their own integration with Mail and their own integration with Safari, which I don't think anyone out here had a product that worked across the board. So we wanted to enable that. So, how did you do this? Well, so rather than actually having a plug-in for... Interesting.

I don't get a mouse. Rather than having a plug-in for each application, we have a single generic plug-in called the SD-CSPDL, whichever application loads, and that's the SecurityD CSPDL. What that does is, to the application, it looks like a regular CDSA plug-in, but what it does in reality is it talks to SecurityD and forwards all the API calls you make into that to SecurityD using Mach RPCs.

SecurityD then will load one or more tokenDs. Each tokenD represents a card or a token. So when someone inserts a token into the system, a tokenD is loaded to support that particular card.

[Transcript missing]

So, each tokend in turn that uses PCSC to talk to the actual reader and then for each reader inserted there will be a reader driver, which is the part on the right.

So, I mentioned 'tokend'. Now, what is 'tokend'? Well, like I said, it's loaded for each card that is inserted in the system. There's a process that knows how to talk to that card. It's actually entirely up to you as a developer that were to develop a 'tokend' how it does that. I mean, typically, it would be using PCSC, but we've had some developers that had solutions that actually use different communication channels. and So, tokend implements an interface that security invokes. It's like a callback interface.

That callback interface is basically driven by security. When a client makes a call to security, security will ask tokend to perform a particular operation. Tokend never initiates anything on its own. For events like token insertion and token removal, SecurityD actually talks directly to PCSCD to listen for those types of events. So SecurityD knows when the token that a particular tokenD represents is removed, and then SecurityD will just tell TokenD to go away.

The interface to 'tokend' is actually part of Darwin, and one of the reasons for that is that we want your feedback into making it better and making it perfect before we make this a fully committed and supported API.

[Transcript missing]

As I mentioned before, there's a single 'tokend' for each token in the system. So if you insert four cards into four different readers, you'll end up with four running 'tokend' processes.

Unlike, let's say, a PKSS 11 library that has to be able to deal with multiple cards and multiple tokens, SecurityD deals with all the multiplexing of tokens to cards to people, etc. 'tokend' has a really simple job. It's just, you know, talk to this one card and deal with it. From the higher-level API's point of view, each token looks like a keychain. So a normal app talking to the Sec keychain APIs or above will actually just see a new keychain that got inserted.

Those keychains actually show up in a search list that is called the dynamic search list. There's a number of different keychain search lists. The most obvious one that you'd see if you launch Keychain Access is the user search list, which typically contains your login keychain by default. If you create additional keychains, those get added to the user search list.

The dynamic search list automatically gets appended to the user search list with any dynamic keychains that are present at that time. The keychains that are inserted into the system get appended to each user search list. That doesn't mean the user has access to the items on them, because to do that they'd need to know the PIN. So even in the context of fast user switching, unless you know the PIN to the token, you still can't access it.

They're, like I said, they're searched after the user's list. So first all the user-configured keychains are searched and then any additional tokens are searched. So because of how that works and because of normally when people make keychain API calls, you just specify the default search list, which is null, you'll automatically end up searching any cards that get inserted.

So, if any of you have applications using the Keychain APIs and you're specifically searching one Keychain, you'll have to change your application to actually do less, which is just not care about which Keychain you're searching and search them all, which is actually the recommended behavior. And doing that, you'll actually find things on Smart Cards as well as any user Keychains that the user has configured.

So, now I'm going to talk about how you could write your own tokend. This is mostly for those of you who are looking to support a new type of card or token, but it could be interesting for the rest of you here as well, just to understand how some of the guts of this work. So like I said, the interface is a C callback interface. It's actually in a header called 'sec_tokend.h' in the Security Token D framework. So to find the C callback interface, you'd have to go to the Security Token D project in Darwin and look for that header.

There's a C++ layer on top of that C interface that we use to implement our own tokenDs. And if you're comfortable with using C++, I definitely recommend you use that because it helps implement a lot of the features that your tokenD needs to support to be a keychain. The C interface is more like a CSPDL interface, which is fairly low level.

In order for a CSPDL to be able to be a keychain, it needs to support a number of different features, which are

[Transcript missing]

and there are source code there both for the CAC tokend and for the Belgian Identity Card tokend. So you have two examples of actual working tokends. There's a third tokend in there which there's sources for, but we don't ship, which is a Muscle Card based tokend, which actually would support any card supported by the Muscle APIs.

So, what does 'tokend' itself look like? Well, on the one hand, it talks to SecurityD, which is not something you have to code for, because the SecurityTokenD framework is basically what you link against as a TokenD. And that framework provides basically the RPC layer between TokenD and SecurityD. On the other hand, on the bottom end, you're most likely to link against PCSC framework, because that's what you need to talk to PCSC, which is the part that lets you talk to different readers without having to worry about which reader your card was inserted into.

and between those two is your custom code, which actually implements 'tokend'. Now if you're using the C++ framework, this picture isn't entirely accurate because the C++ layer is on top of the interface to security as well as on top of PCLC, because there's some abstractions there too that make you deal with the PCLC part easier.

and in this case your code becomes most likely a lot smaller. How do you write a 'tokend' ? What do you start with? Well, every program starts with 'main'. And 'main' in 'tokend' looks something like this. Actually, it probably looks exactly like this, unless you want to add some comments or whatnot. You call a single function in 'main', which is 'sec token d main', and you pass in your own 'argc' and 'argv' to it, and it takes two parameters. One is an input parameter, the other is an output parameter.

Callbacks is the input parameter. It contains basically, it's a struct containing all the callback functions that you need to implement that SecurityD will invoke on your tokenD. Some of them are optional, so you can fill in null and they'll just do the default thing. But most of them are actually required.

And then there's a tokenD support struct that gets filled in when you make this call, which gets filled in immediately before your first callback is invoked. So you can assume that once you're in one of your callbacks that that tokenD support structure is populated. The most important thing in the support structure is there's a function there to get the PCSC slot number for which you are responsible as a tokenD.

Because again, there could be multiple readers in the system, and when the tokenD gets launched, it's launched to serve a card in a particular reader. And so which reader that is, you can get by calling this function in the support structure. There's a number of other functions in the support structure, like allocators that you're supposed to use when you return memory to the system. So you don't just use malloc and free. There's actually a malloc for data and a free for data. And there's a special secure malloc and secure free, which you're supposed to use for keys.

So, there's a number of callbacks listed, and I'm going to walk through the most important ones. There's one called 'initialize', which is called, but none of our tokenies actually use it. 'Initialize' is called after that support structure is filled in, but before probe, and it's basically a chance for you to do any additional initialization you might want to do.

However, just because your token has been launched and you've been told to service a particular slot, doesn't mean you're going to be the token to ultimately talk to that card, because there might be multiple tokenies on the system, and there's a scoring system in place, which basically, each token is asked whether or not they want to support that card, and if they do, what score they give to their level of support. So for example, if there's a generic muscle token D on the system that supports a particular card through muscle, it would probably give a lower score than a token D that was written specifically for that one type of card.

The main job of Probe is to figure out whether you are able to support this card. One thing to note is, before Probe is called, and actually after Probe is called, you are not allowed to talk to PCSC on that slot. You're only allowed to do this during Probe, up until the next call, which I'll go into next.

Besides figuring out whether you support the card, Probe has one other job, and that's to provide a unique ID for a token. That's an optional step, but it's required if you want to leverage the type of caching that John talked about, which is... In a lot of cases, cards allow users to freely read certificates off the card, and in most cases, certificates are immutable.

So if your token is a pre-populated card, like most of the cards that we support today are, then it's kind of pointless to read the certificate off the card over and over again every time the user inserts the card. Because the certificate is small by today's standards, it's only a few K usually, but to read it from a card actually takes a couple of seconds. So if you can make up a unique ID for the token that uniquely identifies your token, then later on you'll be given a cache directory, which will be the same between insertions of that token, to which you can freely store things.

Once the system finishes probing all available tokenDs, one of them is selected, or none. If none of them return a score higher than zero, then the card isn't supported. If one or more of them return a score higher than zero, then the one with the highest score is selected. All the other tokenDs are killed. The one with the highest score gets an established call.

After you return from probe and up until established is called, you're not allowed to talk to the card anymore because the other tokenDs are at this point scanning the card. So you don't own the card until established is called. Once established is called, you are now in full control of the card. SecurityD won't bug you anymore. The system, you own that resource.

Establish has a number of parameters. The most important one being the, well not the most important one, but the cache directory being one of the ones that I talked about earlier, which is if you make a unique ID for the token, and actually even if you don't, the cache directory is a directory in which you can store things that you want, that you read off the token that you don't want to have to read over and over again. If you didn't make up a unique ID for the token in probe, then your cache directory will be empty and different every time the token is inserted.

If you did somehow manage to come up with a unique ID, which in most cases you do by reading, let's say, the chip ID off the card or the serial number or something. Most tokens that we've worked with have some kind of unique ID on them. If you manage to read that off the card, then that cache directory will be the same between insertions.

There's another parameter, which is the print name, which is an output parameter. And the print name is what you get to fill in as the human readable name of the card. If you leave the print name unpopulated, your card will be named by the system, and it will be named Smart Card number something, like you saw with most of the cards we demoed today. Then the other output parameter is the MDS directory.

That one is fairly important in that MDS is the, not to be confused with Spotlight, which also has used the name MDS internally. MDS is the Module Directory Services. It's a part of CDSA, which allows modules to identify their capabilities. Well, during establish, it's your responsibility as tokend to actually build up a list of MDS capabilities for your token. And you'll have to build a capability list both for the datastore library part, for the DL part of your token, and for the CSP part of your token.

So the DL part would look something like, you know, supports queries with AND and OR conjunctives and with equal and less than and greater than operators, etc. So you'd list all the capabilities of your tokend in MDS. That directory is a directory containing the files, which If you don't fill that in, the MDS info files will be pulled out of the resources folder of your tokenD by securityD automatically. So if your tokenD only supports one kind of token, and that token always has the same capabilities, then you just hard code these MDS info files, stick them in the resources folder of your tokenD, and the system will pick them up automatically.

If for some reason you support lots of different tokens in your tokend, and those tokens have varying capabilities, then this is the point where you have to go query the token, figure out what the token's capabilities are, and produce that MDS record. Now, if you're smart and you actually have a unique ID for that token, you can probably cache that information.

So, if for some reason you want info files that aren't in the resources folder, that's when you fill in the MDS directory. Other than that, you get passed in the GUID of the CSP, which is actually used when you return key objects to the caller. You're supposed to fill in the GUID of the key using this GUID. And then the subservice ID, which is essentially the virtual slot number that your token represents in the system. So, once establish has happened, your token's ready to go and the system will most likely start querying your token, etc., etc.

The way to get things off, everything on a token is some form of object. The different types of objects that we support or that are expected to be on a token would be X.509 certificates, different types of keys-- public keys, private keys, symmetric keys. You could have generic objects on there, which generic objects won't be used by the security stack per se.

But you can use CDSA to find those generic objects on your token. And as an example, those common access cards that John demoed actually have a personnel record object on there. There's a specific app we ship called the CAC Viewer, I think, Common Access Card Viewer, that reads those generic records and can display things like your salary scale and your medical benefits and all this other information that's stored on the card but doesn't fall into one of these other categories. Similarly, the Belgian Identity Card has Social Security-type information, has a picture of the person who owns the card, et cetera. Those can all be basically served up to the system as generic records.

Because there's so much variation in what they are, there's no real standardized app at the app level that knows how to deal with those generic records. But if you provide a custom app to view records for that card, you can go through the normal security APIs to get those records off your card. You don't have to directly talk to the card in your app.

and you can have custom types. Usually if you're thinking about doing a custom type, you probably should just use generic. One thing where I could think would maybe be an exception would be, let's say, your card supports PGP certificates. You would want to use a PGP certificate type there and not just generic.

Or if you support some other totally different type of object that wouldn't fall into one of these categories. Pins are actually not objects on our cards. I'll talk a little bit more about that later. We've already had some comments from developers about this, and we're more than willing to take additional comments about this later.

So, now we're actually going to go into some of the other callbacks, and those are the ones to retrieve attributes and data off objects on the card. And there are really only three ways to get attributes and data off the card, and that's either Find First, Find Next, or Find Record Handle. Attributes and data are returned using the allocators in the support call box.

Certificates and keys have to have very specific attributes associated with them in order for the rest of the security stack to recognize them as keychain items. So that the schema for a certificate and the schema for a key item have to have particular attributes that must be there for it to work. And there's also, in the case of a public key and a cert, or a private key and a cert, more importantly, a certificate has an attribute called the hash of the public key.

And a private key also has an attribute called the hash of the public key. Those two have to match in order for the system to recognize that key is associated with that cert. or for that matter, to associate a private key with a public key, because they're two separate objects. By having the same hash, they're paired up as a single key pair.

and Michael Broewer, John Hurley. All of that is a lot of work, and that's actually where the C++ layer helps you a lot. Another type of objects that I didn't talk about yet in the previous section, which the system will also make these calls on, are schema objects. Each object type in a Smart Card has to have a schema describing which attributes it supports. So all the schema information needs to be queryable using the same APIs as the regular data. Again, the C++ layer actually handles all the schema tables for you.

So, first one, find first. Starts a new query, think about it like creating a database cursor or query or whatever. Unlike PCSS 11, there's no limit on how many outstanding queries you can have at one time, and the system will sometimes do nested queries. So you need to make sure that you support that in your tokend.

[Transcript missing]

and Michael Dinklage will show you how to use the C++ layer. The C++ layer actually handles the entire query machinery for you. It supports all the optional features, etc.

So the other argument is the search handle, which is output from this function, and then there's the data itself, which is shown in this structure, which the data contains the attributes, the data, and the record handle and key handle for the record. Normal records only have a record handle.

Keys are special in that they actually return two handles. If you search a token and you find a key object, you'll get back both the key handle and the record handle. and the Key Handle is what you use for cryptographic operations. The Record Handle is what you'd use to retrieve additional attributes and data from the object. Find Next finds the next object in a query that you've started.

Find Record Handle isn't really 'find', it's kind of misnamed, but what it is is it retrieves additional attributes or data from an object for which you already have the handle. Which really the only way to get the handle is either by doing a 'find first' or 'find next'.

So, like I said before, I was going to talk a bit about access control lists. Tokens have to support a number of access control list calls, and access control lists are actually how we've implemented pins. There's get-owner, get-ackle, change-owner, and change-ackle calls, where the star in between is either a database, an object, or a key. This is where we differ from the regular CSPDL spec in that in CSPDL, objects don't have ackles. For tokens, they do, because it turns out a lot of Smart Cards actually have pins protecting generic type objects and not just keys.

An ACL consists of a number of entries. Each entry in an ACL consists of the following three pieces. It consists of a tag, which is really just a string describing the ACL, or label. It has one or more authorizations, which are the operations that that ACL entry authorizes. Which could be, you know, allows read, allows write, allows encrypt, sign, whatever.

And it has a subject. The subject is actually a linked list that can get fairly, fairly complicated. Some examples of subjects would be a protected password or a threshold subject, which is a K of N. It could be an and or an or. or a PreAuth subject. I'll talk a little bit about some other subjects later.

Some subjects can recurse and contain additional subjects. For example, a threshold subject, you could say, here's an ACL that has a 1 of 2, which essentially contains two other subjects, one of which has to evaluate to true in order to satisfy that ACL. Subjects can also contain one or more values. There are public and private values.

Private values can't be retrieved using the get calls, they can only be set using a change call. So an example of a private value would be a pin, where you can set the pin using a change ACL call, and when you get the ACL, you get back the fact that it's a pin ACL, but you don't get back what the value of the pin is, because that would be silly.

So, like I said before, these are the entities that have ACLs. The database itself has an ACL. Each token represents a single database. The database is the card. Each key has an ACL and objects can also have ACLs, which is unique to tokenD because CDSA doesn't otherwise have that.

Pin ACLs, and this is how we've implemented pins. Typically, the entity that represents a pin will be an ACL entry, usually on the database, that has subject type, ACL subject type, preauth, source. Other ACLs, like the object, let's say, so the database would have a preauth source type ACL with the tag pin 1, giving it the name pin 1. Other ACLs, like an ACL on a key, might require, in order to sign with this key, you need to use that ACL over there.

And it can refer to that ACL by using ACL subject type preauth with the same tag as the source ACL. I mentioned pin 1, because in order for an ACL to be a pin ACL, the tag has to start with the letters PIN in caps and be followed by a number.

If your card has a notion of a user pin or a default pin, you'd want to call that pin 1. Because pins aren't first class objects, there are some issues, which is pins can't refer to each other and they're not special. There's no such thing as a supervisor pin, and we currently don't have a way to express that the supervisor pin unblocks some other pin. Pins can just allow or disallow certain operations, and what those operations are, are actually listed in CDSA.

Some tips if you're writing a 'tokend': Before each operation that uses an object from the token, the read authorization is checked on the database ACL. So if you want anyone to read anything from your token at all, then you have to allow read, otherwise you won't be able to get any objects off the token. If there are any objects on the token that don't require authorization, then the read ACL on the database should be subject type any, which means anyone can read.

You can then subsequently, the ACL on the item itself is checked, so if you want to limit access to particular objects and not allow them to be read, you can set an ACL on the object itself. The read ACL on the database actually applies to both the attributes and the data of an object, whereas the read ACL on an object only applies to its data. If you can read the database, you can read all objects' attributes.

and Michael Broewer, John Hurley. So, make sure that you make keys readable. That's a common mistake is to think, "Well, I don't want my keys to be readable. I don't want people to read my keys." Well, readable doesn't apply extractable. Readable means you can read the key at the database level, which actually returns, when you read a key, you get back a CSSM key structure that tells you what the key is.

But it's a reference to the key, not the actual key bits themselves, which you obviously can't read. Finally, wrap up: ACLs. TokenD is responsible for enforcing the ACLs. The system makes assumptions, SecurityD makes assumptions about the ACLs and will pre-flight the UI for you to get all the pins needed to satisfy what you claim in your ACL structure you need.

But it's still ultimately the responsibility of TokenD to enforce the ACL rules. Michael Brouwere, John Hurley So then I got the last part, Crypto Operations. There's three major operations you can do on keys. There's a couple more, but I'm not going to go into them. There's Decrypt, Generate Signature, Unwrap Key. They're very similar to the CSP operations, the same name. So if you look at the CDSA documentation for these calls, that pretty much applies.

RAPKEY and ENKRYPT are also there, but you don't normally have to implement them on a token because they're only meant for public keys. And the way the system is set up, it'll use the built-in CSP for public key operations. It'll extract the public key from the token and then just use the built-in CSP, which is faster.

If you support symmetric keys, then you will have to implement those, most likely. DeCrypt gets a key handle, which is a handle that was obtained through one of those find calls, which is not the object handle but the key handle. The context contains all the additional information like what mode to use, padding, algorithm type, etc.

The rest is and Michael Broewer, John Hurley. Generate signature, very similar to decrypt. Of course, you're not doing any Unwrap key is needed if you want to support SMIME decryption. A lot of tokens that we've supported only support signing. If you need decryption, you're going to have to support unwrap key. And in particular, you'll need to support unwrapping a symmetric key with a private key, according to the way the SMIME standard specifies it.

and Michael Broewer, John Hurley. These three operations will make all the applications we just showed you work with your token. Summary What tokend does is it allows shared access to a Smart Card or token. It's fairly simple to implement, especially with the C++ layer. You can get a token up and running in probably a day or two, because you really only need to implement about five or six commands to talk to your card. It's not PKS 11.

It's possible to implement a tokend on top of PICSS11, except for probe, which is not something PICSS11 normally supports. We don't have any tokend's that we've written on top of PICSS11, because it turns out that the complexity of PICSS11 just makes it more work to write a tokend than just implementing these four or five calls you have to implement. Which is all you have to do when you're using the C++ layer.

So in most cases, it's a lot less work to write a 'tokend' than it is to write a 'Pecosys 11' library. I didn't talk about the SPIs to modify a token, to generate a key or insert a new record, etc. Those callbacks are there and you can look those up, but we don't currently have tokenies that we ship that support that, although it should work.

So, last thing, existing Smart Card solutions, well, existing vertical apps should continue to work. Last year, if any of you were at my presentation, we presented what we thought the Smart Card architecture was going to be. Well, everything we said last year was true, except the part where we said that your vertical apps wouldn't work. It turns out they will.

So, all the other things we promised actually happened, and we managed to do it in such a way that your existing apps should still work and be able to coexist with the tokend system. And the reason is we don't take exclusive access to the card, but we use transactions. So, as long as tokend doesn't--isn't in the middle of a transaction, you should be able to access the card.

And with that, I'd like to bring up the Q&A panel. and I'm sure you've seen this slide before. There's one other session related to this, which is the Security Feedback Forum, and we'd really appreciate to hear your feedback if we run out of time today in the Q&A on token-D issues, etc.