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: wwdc2003-109
$eventId
ID of event: wwdc2003
$eventContentId
ID of session without event part: 109
$eventShortId
Shortened ID of event: wwdc03
$year
Year of session: 2003
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC03 • Session 109

Security: Certificate APIs

Core OS • 1:03:16

This session discusses the collection of routines used to import, export, and display digital certificates. These routines are used in conjunction with the other APIs that make use of certificates, such as Secure Transport, SSL, and Keychain storage operations.

Speakers: Craig Keithley, Michael Brouwer, Ken McLeod

Unlisted on Apple Developer site

Transcript

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

I'm Craig Keithley. I'm Apple's Security Technology Evangelist in Apple's Worldwide Developer Relations Group. My job is to work with security developers. It also includes, as it happens, it's not shown here, that I'm Apple's I/O Technology Evangelist. So if you're working on smart cards or other security devices that are connected via the USB bus or Bluetooth, I'd be happy to talk to you as well.

So today we're going to talk about certificates and how they're used. We'll discuss security management. If you're not familiar with it, we are adding new security APIs to Panther. So we'll go into what's in certificates, their identities, how you store and retrieve them, and the issue of establishing trust is an important one when you're dealing with certificates, so we'll talk about that. We'll certainly reveal or show you on a demo some of our new functions to display certificates, and we'll discuss secure transport. So, to get started, Michael.

I'd like to, I'm going to talk a little bit about the security framework, which is basically where most of our security APIs live. The security framework is actually part of Darwin, so all the sources for the security framework are available for download at Apple's website. In particular, I'm going to cover a couple areas. SecKeychain, for as far as, we use keychains to store certificates, and that's where we want you to store your certificates as well. So, I'm going to cover that, you know, not in depth.

We've had plenty of keychain sessions in the past, and if you have questions on that, there's documentation online. But I'm just going to cover the part of that that's relevant to our certificate APIs. SecCertificate, which is basically an object that represents a certificate. It contains the actual raw data of the certificate and a couple of higher level operations. It's mainly used to pass around certificates between our different APIs. Then there's SecIdentity, which I'll go into, which actually represents a certificate and a private key. So, this is actually a certificate that the user on that machine can do something with, because this represents the user's identity.

Or, one of his identities. So, that's actually something that you can sign with or decrypt with, etc. Whereas, just a plain certificate really could be anyone's certificate. A certificate from some other person. And finally, SecTrust is our, it's like a workflow object that lets you evaluate whether or not a certificate or a group of certificates can be trusted.

In addition to the security framework, there are two new frameworks being introduced in Panther called Security Foundation and Security Interface. For those of you familiar with Cocoa, these are analogous with Foundation and AppKit at the Cocoa level. Security Foundation contains our low-level, non-GUI Cocoa APIs for dealing with some of the certificate and authorization and other security-related things.

Whereas Security Interface actually contains views and dialogues and things like that to have to do with displaying certificates and displaying other security-related information. Previously, some of the things that are in Security Interface and Security Foundation were: Security HI Cocoa, which was a private framework. But since it was Cocoa, I'm sure that some of you in this room must have reverse-engineered our APIs and figured out what was there. Unfortunately, Security HI Cocoa is going away, and it's being superseded by Security Interface and Security Foundation. The good news is that those two are public, so we're committed to supporting them.

Let's see if the... There we go. So, I'll start with a quick overview of CDSA, which stands for Common Data Security Architecture. And that's basically... It's an open group standard. It's the foundation on which all of our security APIs are built. CDNA is somewhat analogous to, let's say, Microsoft's CAPI or OpenSSL, which some of you might be aware of. And some of the key differences between those are that CDSA is pluggable.

In essence, it's a plug-in architecture. It's an empty shell, and you have different module types that perform different tasks. I'll go into more detail about that later. I'll cover some of the basic functionality provided by the security framework in addition to CDSA. Then we'll talk a little bit how you can use certificates to establish trust and what APIs we provide to help you do that and show you how to store and retrieve certificates from keychains.

So I have a quick question. How many of you know what a certificate is?

[Transcript missing]

So we have a number of different modules we provide. Now, the two modules that are more relevant to this session are at the Certificate Library Module, which the Certificate Library Module, or CL, is used to syntactically peel apart a certificate.

So a certificate consists of a number of attributes and potentially a number of extensions. And the Certificate Library Module can take this bob of binary data and peel it apart so you can actually get these attributes and extensions in C structures or different formats that your application can work with.

In contrast to the CL, we have the Trust Policy Module, which doesn't actually operate on the low level on the certificates, but it operates on groups of certificates and can construct a chain of trust in the case of X.509. Craig Keithley, Michael Brouwer, Ken McLeod The Trust Policy Module is a tool that allows you to have a trust policy module that is based on the trust policy that you have in your system.

If you were to have, let's say, a PGP trust policy module, you take a bag of certificates and you could determine whether the certificate that you're looking for is, or that you want to evaluate, is actually trusted due to whatever relationships are needed. So Trust Policy Modules, we currently provide one Trust Policy Module and it has five or six different policies.

There's a policy for SMIME, there's a policy for SSL clients for SSL servers, and there's a number of different policies because there are slight differences in what fields and extensions and attributes need to be there in a certificate chain for it to be trusted for a particular operation. So that's what Trust Policy Modules is for.

And again, all these modules are pluggable, so as a developer, if you find that we don't provide the exact service you need, you can actually write an additional plug-in module that provides, you know, a different trust policy. So if you're looking for a specific type of service, you can write an additional plug-in module. And again, you can do that by adding your own Trust Policy Module. And since ours are open source, you have a nice starting point.

So here's a little picture of our entire security stack. The CDSA part of that is the lower two blocks. So there's the Common Security Services Manager and then the add-in modules. So that's really the part we just covered. So, some functionality that CDSA has through the CSP. You can do key generation, generate symmetric keys, asymmetric keys, HMAC signing keys, you name it, it's there. Encryption and decryption, we support AES in the form of, well, Raindell, the algorithm.

We support triple DAS, DAS, RC2, RC4, RC5, all the common algorithms. Support different types of digests, MD5, SHA1, there's a couple others in there too. Data Storage and Retrieval through the DL, so for storing security-related things like keys or certificates or whatnot.

[Transcript missing]

Finally, there's certificate parsing and evaluation and determination of trust through the CLNTP modules.

So, back to the step up to the security framework. So one of the things it does, it implements CDSA. Actually, all the plugin modules that we ship are actually built into the framework. They're not actual plugins. That's really just a performance hack or performance implementation detail. From the developer's point of view, they still look like plugins. It's just we don't have to actually load them.

So we provide, in addition to CDSA, we also provide the higher level security interfaces like Sec Keychain APIs and some of the other APIs I talked about in the introduction, Sec Certificate, Sec Trust. There's a whole suite of APIs. There's authorization APIs in there. There's a bunch of other things.

There is no user interface in the security framework. The security framework depends on the system framework, and that's it. It's part of Darwin, but it doesn't have any other dependencies than the system framework. So, no Carbon, no Cocoa, nothing. So, your app command line tool could link against the security framework, and in fact, many command line tools should, probably, if they are anything related to security. And, as I said before, it's part of Darwin open source. You can go to opensource.apple.com, I think, or developer.apple.com/opensource, and just download the latest version of the security framework, which is what you have on your machines right now on Panther.

The only difference between the open source version of security framework and what's on your machine in Panther is that there are two algorithms in the CSP that are used to create the security framework. There are two algorithms that are patented by Apple and still considered proprietary, which are FEE, which is a fast elliptic curve implementation, and ASC, which is Apple secure compression. Neither of those are actually used in any of the default software we ship.

So, if you were to take the open source version and build it, you wouldn't get these two algorithms. But you have to be aware, if you're planning to actually use these algorithms, they're not part of the open source distribution. So, if you're planning to use these two algorithms in your application, you can't use a security framework that you built yourself.

So now on to the Sec APIs, which Sec is short for security. It's not French for dry. I mean, it is, but that wasn't our intention.

[Transcript missing]

So if you're in a Cocoa app, that might benefit you. Be aware of copy versus get. You know, that's the, if you call a method that, or a function that has copy in its name, that means that the object returned by it is being copied, which means that you as a developer are responsible for calling cfrelease on its result. Whereas if it has get in its name, you shouldn't call cfrelease unless you call cfretain before.

So if you want to actually keep that object around, you better cfretain it. And in fact, in some of our APIs where, that are named get, it'll be clear from the documentation that the lifetime of the object you're getting is most likely tied to the lifetime of the object that you're getting it from.

So, for example, if you were to get a, we have, for example, if you have a certificate object, you can actually get a CL handle, which lets you operate at the CDSA level with that certificate. That CL handle is only guaranteed to be valid for as long as that SEC certificate object is valid. So, it might be valid after that, but we don't guarantee it. And the CL handle happens to not be a SEC object, so you can't retain it. It's just a CDSA level handle.

Which brings me to the last point, which is bridge functions to CSSM. So we didn't try to make the Sec layer complete. We tried to make it, you know, have most of the high-level functionality that you would wanna use. Now, in most applications, it's sufficient to have the SecLayer.

Now, SecCertificate, as an example, does not have actual APIs to decompose a certificate and get all the different fields out of there. If you wanna actually go down to that level and really peel apart the certificate and see what's in there, you can get the CL handle out from there, and you can call the CL functions to basically parse the certificate and figure out what's in it.

So if your application has the need to do its own custom display of certificates, you could do that. Now, normally, you probably wouldn't need that because we provide a SF certificate view class, which actually can display a certificate and does all this work for you. Again, if you wanted to customize this, we do provide a way to bridge down to CSSM.

So here's where the Sec APIs are in the big picture. So there's CDSA below, and the Sec APIs sit right on top of that. In addition to the Sec APIs, that same layer, we have Secure Transport, which is our SSL implementation. The Authorization APIs, which aren't covered in this session today, but if you have any questions at all about authorization, about how to use them, there's actually some really cool new stuff we've added to authorization that many of you have been asking us for years, which is we now allow you to customize the dialogs in authorization.

That's actually not on the CDs you have, but in the authorization lab downstairs in the, I think it's the Marina conference room, we have an updated version of the security agent, which actually supports the customizable dialogs. And we also let you now add and manipulate authorization rules, so as a developer, you can now actually do a lot of new, cool stuff with authorization. So be sure to come down to our lab any time this week to check that out. Thank you. Thank you. Learn more about that.

So, I just want to do a quick thing on Keychain APIs, because some of you might have come from OS 9, and we're really thankful because you've been with us for a long time, and you might have been early adopters of the Keychain APIs, and going, "Well, what's all this new Sec API stuff? Do I really care?" Well, the good news is the Keychain Manager APIs that have been around since OS 8.6 or 8.5 are staying. They're here to stay. They're part of Carbon. They're not changing, which also means they're not evolving.

But they do everything that most apps would need to do for manipulating Keychain objects. Now, in addition to the Keychain Manager APIs, back in Jaguar, we introduced the Sec Keychain APIs. And the advantage of the Sec APIs versus the Keychain Manager APIs is they're not in Carbon. So, the Sec APIs would be usable from a Cocoa app without you having to pull in the entire Carbon stack. There's a couple other things, so I'll get to that. So, like I said, both APIs are supported. They're going to be supported in the future.

And, in fact, a Sec Keychain Ref is the same as a KC Ref, and a Sec Keychain Item Ref is the same as a KC Item Ref. So, that's not documented anywhere, but, you know, you can actually use those APIs interchangeably, because the core implementation of them is actually exactly the same.

Both these APIs might bring up UI. You might be wondering, I just said, you know, security framework doesn't do any UI. What are you talking about? Well, the security framework itself doesn't actually depend on any UI framework, so linking against the security framework doesn't pull in UI code into your application if it didn't already have it. But if you're calling into security framework calls, we might bring up UI through this application that gets run in the background called the security agent, which basically is our way of doing secure interaction with the user.

So we, the security framework actually talks to the security server, which is a background process that's always running on your machine, which manages any persistent state about, you know, your keychains and things like that. So you can actually run it. And the security server can launch the security agent on behalf of the user if your application is part of a GUI-enabled session.

So the security server knows this magically. Basically, if you SSH into your machine and you do something that would normally require a UI, it won't happen because, you know, that SSH session is not part of a login session that can put up GUI. So if your process was launched by system startup, you could do that.

But if it was launched by system starter or by some low-level demon, it's not going to put up UI. The only way it's going to put up UI is if it was launched somehow by the Windows server or a child of the Windows server like the Finder or if you launched it from terminal, it would still bring up UI in that session. And now with multiple users in Panther, which are the fast user switching, you know, there can be multiple GUI sessions at a given point in time, but it'll bring up the UI in the appropriate user session.

Unless you turn off user interaction, which there's a call at both in the Keychain Manager layer and in the Sec layer to turn that on and off. And if you're using authorization API, it's actually every time you call an authorization call, there's a flag saying, you know, do I want to allow user interaction this time? So as a developer, you still have the option to override to turn it off, but you can't turn it on in a session that wouldn't otherwise be able to do UI.

Some of the advantages of a Sec Keychain: If you have an app using Keychain Manager, it's all good. You probably don't have to transition. But if you're writing a new app, I'd highly recommend you actually use the Sec Keychain interfaces versus the Keychain Manager interfaces, and here's why.

The Sec Keychain interfaces support all different application environments. So you can use it in a Carbon app, you can use it in a Cocoa app, you can use it in a tool, in a command line tool, you can use it in a system daemon, you can use it in just about anything. Because there's so little dependencies, you're not dependent on any additional frameworks. Also, the Sec Keychain API is more flexible.

You can get and set all the attributes of a single application. With the Keychain Manager layer, you're doing that as individual calls. One of the downsides is if for some reason two apps would be manipulating an item at the same time, you might not get a coherent snapshot of that item.

Because app A might change one attribute and app B might change another attribute. You'd end up with an item that doesn't make sense. If you're using the Sec APIs when you're manipulating an object, you can do it all in one call. So it's an atomic modification or an atomic add or remove.

And finally, well actually not finally, but one more important thing is that both APIs have access control support as far as the user will be prompted to update the ACL of the item if the current access controller doesn't let a particular application access that item. The Sec layer lets you specify an initial access control list that's different from the default. The default access control list that we put in every item you create using the Keychain API is the current application can modify and access that item without warning.

If you, for example, had an application and you have some background process that runs that also needs to access that same item, using the Sec layer, you can actually set up an access control list that allows both of those to access the item without warning initially. So the user would never get a dialogue in his face saying, you know, do you want to allow application X or, you know, my background faceless process X to access this item. So that's an advantage of the Sec APIs is that you can actually do that.

And last but not least, system keychain support, which is new in Panther, and internally at least a lot of people have been asking us for this. And I'm sure that some of you might find a need for this too, which is basically, rather than, if you have a system service that somehow needs a password, for example, PPP, if it's not configured for a particular user but for your machine as a whole, when your machine boots, it needs to make, let's say, a VPN connection to somewhere, but you want to store that password for the VPN connection somewhere.

Well, if there's no user logged in, you don't have a keychain unlocked yet. Well, that's where we introduced system keychains. So this is a way that you can use the same keychain APIs that we've always had from a system daemon, and it actually, we automatically detect whether your system is logged in or not. So this is a way that you can use the same keychain APIs that we've always had from a system daemon, and it actually, we automatically detect whether your system is logged in or not.

a user processor system daemon, and there are APIs you can override it, so you can actually switch explicitly to be a system daemon. If you were started from a regular user session, you can say, "Well, no, I'd want to be -- I want to access the system keychains instead." But it lets you store secrets that are available as soon as the machine boots.

The way the system keychain is locked and unlocked is currently there's basically a root-only readable file containing a random generated key that unlocks the system keychain. So you need root access to the machine to gain access to the secrets in this file. In the future, we might improve this mechanism and add support for things like you have to have a hardware key in the machine when you boot to unlock the system keychain or whatnot. The main thing is you as an app writer don't have to worry about it, and it sure is a lot better than just, you know, XORing your password with FF and writing it to some file on the disk.

So, it's there. If you need it, you should probably be using it. Basically, if your app does anything with a password, you should give the user the option to store that password in the Keychain. That's pretty much the deal on that. So, back to the main meat of the session, which are certificates.

So, I guess I already asked this question. Most of you already know what an X5 and insert is, so I'll kind of skip through this quickly. Certificate consists of a public key and a number of fixed attributes, the most important one being the subject, which is, you know, who does this certificate pertain to, and that contains a number of fields like X500 name, which is this name based out of different components, which can contain your common name, your organization, all these different fields.

And an issuer, which is just like the subject, is an X500 name, which is, well, who is the issuer? And an issuer is the person who issued this certificate to this person. And in addition to the issuer, there's a serial number and some other things, and there's some validity information in the cert, like from when to when is it valid, and there's a couple other attributes.

In addition to attributes, there can be one or more extensions in a certificate, and the extensions fall apart into two categories. There's a flag in an extension that says whether it's critical or non-critical. If you're somehow processing certificates and you run across a non-critical extension and you have no clue what it is, you just, you know, "Oh well, I don't know what it is, that's fine." However, if you run across an extension marked as critical and you have no clue what it is, you're supposed to not continue processing that certificate. You should say, "Well, this is a critical extension, but I don't understand how to parse it, so I can't deal with this." Now fortunately, our CL module actually supports, as far as we know, all the known, currently documented critical and non-critical extensions out there.

If you find any, you know, weird or new extensions that you think we need to support, please let us know again in the feedback forum or on our mailing list, and we'll be sure to add support for that in a future release. And then finally, a public key certificate contains a signature of all of the above fields, and that signature is made using the issuer's private key. So the issuing certificate actually signs the subject certificate in question.

So, like I said, each certificate is signed by its issuer, which basically means you can have a chain of certificates. You have a certificate, a leaf certificate, the leaf certificate is signed by its issuer, the issuing certificate might be signed by its issuer, and that keeps going forever.

Well, no. It actually stops at some point because you end up with a certificate that has itself as its issuer. So it's signed by itself. Well, that signature doesn't really mean much because anyone can make a certificate signed by itself. Because I can just generate a public key or in a private key, create a certificate, and sign it.

Well, what's the problem there? Well, the only way to trust a self-signed certificate is by predetermining trust for it, or by trusting it by prior arrangement. And we do that through this thing called the RIDCERT database. On Mac OS X, the RIDCERT database is in a file called System Library X509 Anchors, which, incidentally, is a keychain file. Or, if you want to look at it at a lower level, it's actually a CSSM DB file managed by the Datastore library.

So that's the Root Certificate Database, and that basically contains all the root certificates that are commonly used today by Verisign, Thought, all the different root certs that are needed. Now, if for some reason you have your own local CA at your institution or whatever it is you have, you can add new root certs to the Root Cert Database.

To do that, you can actually use just Keychain Access or our command line tool, which is new in New in Panther, called Security, which actually lets you manipulate keychains and other CDSA functionality. And normally you'd need administrator access to do that. So if you're using Keychain access, you'll get a dialog asking you to authenticate as administrator.

If you're using the command line tool, you'd have to run it as root. So the RootCert database is actually machine-wide, so that's like all the RootCerts that all the users in that machine would trust. As of today, we don't have support yet for per-user RootCerts, but that's definitely something we're looking into for the future.

So, I want to give a quick example of how SSL uses certificates, and I'm not going to go, to make it not too complicated, I'm just going to do authenticating the server to the client, not authenticating the client to the server, which is something we support. So first the client connects to the server. Server responds with a bunch of stuff, which one of the things that's included in that response is one or more certificates.

The client then verifies and constructs a certificate chain. So it takes a certificate, looks for the issuer of the certificate, and it's either in the list of certificates provided by the server, or it's in one of the user's keychains already, or somewhere on the machine, my quad to LDAP databases or whatever, to figure out where those certificates are.

So it builds this chain, and then if the chain itself is valid, the final step is to actually see if the root of that chain is already trusted. And the way we do that is to check if it's actually in this X.509 anchors file, or a root cert database, and if it's not, then well, unfortunately the chain can't be trusted, because you can't trust a cert that's self-signed unless you've previously agreed to trust it.

[Transcript missing]

So, depending on what you're using the certificate for, the policy might state some additional requirements on that certificate. And this is exactly what our trust policy modules encapsulate. So they'll actually go and do this additional check for you. Now obviously the application has to know what additional information to provide. So, a browser, or actually something using Secure Transport, will actually provide the URL to the trust layer to say, well, you know, check this field as well.

So... So, talk about Sec Certificate itself, which is the Sec or security low-level wrapper for a certificate. It's like all the other Sec things, they're, you know, C objects, just like CF things, so it has a number of operations. You can import and export raw certificate data. Currently, Sec Certificate only supports X509 certificates, but that's because all the, the only CL and TP we ship are X509. But if you were to write a CL or TP supporting different certificate formats, then that would automatically start being supported because of the plugin architecture of CDSA.

You can store and retrieve Sec certificates from a Keychain if you Sec certificate has an add to Keychain method that you can call. You can use a CL module to parse the certificate if you wanted to syntactically pull it apart, because you can use the bridging down to CSSM to actually get a certificate library module and pull apart the certificate in fields. And you can display it using an SF certificate view, which is part of the security interface.

And finally, rather than calling directly into the TP, which you can do if you really want to, we actually recommend you use SecTrust for that. SecTrust actually behaves as a wrapper for using the trust policy module to evaluate the certificate, but it adds some additional functionality, which I'll go into a little bit later.

Secure Transport expects you to pass in certificates and let you get at the certificates that are a result of the connection, which we'll show you a little bit later how that works. They're used in SecTrust, obviously, because SecTrust deals with trust of certificates. And they're actually used in identities, which, if you don't remember what those were, an identity is actually an object that represents a certificate and a private key. So the certificate component of the identity is represented by SecCertificate.

Certificates don't have access control. Wait, isn't that a bad thing? Well, no, because certificates are public. They're public key certificates, and there's nothing in a certificate that's secret. And in fact, you know, you can't tamper with a certificate and still have it be, still have it verified correctly. So you don't need to protect certificates. The only thing you can do by not having access control on them is delete a certificate. So, but that level of access control is provided by the file system.

Secure Transport, SSL, and Keychain storage operations. So, Secure Identity is not an object that exists in a Keychain database in and of itself. It's actually constructed on the fly by looking for a certificate and a key that match. And the construction of Sec Identity is done by looking for a certificate through all your Keychains and looking for a key through all your Keychains. So that actually means that the certificate and the key don't even have to be in the same Keychain or in the same place for them to form an identity.

[Transcript missing]

But if you get multiple matches, you should probably let the user pick which one he wants to use. And rely on us to do access control, because the user can set his preferences any way he wants in Keychain Access as to how much, which apps and how can access the private key, so you don't need to worry about that part.

Some uses of Sec identities. Secure Transport uses identities in the client-side authentication. 802.1X is actually new in Panther, which I'm sure you've all seen the big new session. It's like, "Yay, we're adding 802.1X." Well, that's actually authentication over IP, which is both for airport and for wired networks. And one of the ways of authenticating to the server with 802.1X is using identities.

And there's future applications coming, one being, for example, S/MIME, secure email. The S/MIME, we have an S/MIME SPI, which it is an API yet that we're working on, and we encourage you to take a look at it if you're planning on using our S/MIME APIs in the future and give us feedback, what you think.

And the SPI code is actually open source, so you can go to the Darwin website and download that. The project is Security NSS S/MIME. It's actually based on the Netscape S/MIME code, but we're using our CDSA-based crypto stack instead of what Netscape was using themselves. So you get all the advantage of access control lists and all these things that we have.

So, going to policies, I talked a bit about trust policy modules. And so a trust policy module can actually support one or more policies. And I've mentioned this a couple of times before, and policy basically is the set of rules that decides whether or not a particular chain of certificates will be trusted.

And like I said before, there's an SSL policy, there's S/MIME signing policy, there will be an encryption policy. There's a separate policy in SSL actually for client versus server auth. You could have a code signing policy, which might have different requirements on the leaf certificate. It can't just be a random email certificate someone got, but it might have to be, in the case of, for example, VeriSign, they have class 1, class 2, class 3.

They have different certificates, which for them to issue that certificate to you, you have to provide different levels of proof of who you are before they'll issue that certificate. Well, for a cert to be valid for code signing, you probably want to require a higher level of proof that this developer really is who they claim to be.

And unlike an SSL or an SMIME cert, there should probably never be an automated way of trusting a code signing cert without at least having shown it once to the user. Because even if this developer is registered and it's a real developer, the user still might want to decide whether or not he wants to install software from this developer. So, some policies take parameters like SSL and SMIME, and the parameters depend on what the policy is. And typically your application should know what that parameter is, like in SMIME it's the email address, in SSL it's the URL.

So, SecTrust deals with policies and certificates and all these different things and kind of wraps it up in this neat little object that really makes your life a lot easier when trying to determine whether a certificate is trusted. So it validates the certificate, it validates the certificate using the policy. Now in addition to that, it established the user trust. So go back to the code signing example.

The first time the user sees code from a particular developer, they might not-- you'd preferably like to display the certificate to the user and say, well, do you really want to trust this thing? You're installing Flash. Do you really want to trust the software signed by company XYZ? The user can then decide, "Well, sure, go ahead, do it.

I'm fine with installing the software." The user can actually say, "Well, no, I don't want to, and I never want to install any software signed by this company because I don't trust them, and I think there's probably a virus or something." Or they might say, "Yeah, sure, go ahead. It's Apple. It's all good. Apple software updates signed by Apple. It's good. Sign them, install them. That's fine." That decision that the user makes is stored as a user trust setting, and SecTrust actually manages these user trust settings in addition to doing the regular certificate evaluation.

SecTrust isn't an actual object that represents some real world thing, it's a workflow object. You create one, stick in the certificates, set what policies you want to use, set some additional parameters, attributes, and evaluate it. That's pretty much what you do with it. In addition to that, you can actually use it to set these user trust parameters and inspect the user trust parameters on the cert.

So, when you evaluate SecTrust, there's a couple of different outcomes. It could be, you know, the certificate's valid, it's all good, and if it's valid, there's actually three possible answers. The answer could be denied, which means the certificate was valid, but the user didn't want to trust it. Or it could be, yep, go ahead, proceed, it's all good, the certificate's valid, and the user actually has previously seen this and they decided that they want to always, you know, continue without bothering them when they see the certificate.

Or it could be, well, we don't know yet. We haven't actually displayed this to the user and, you know, he never really decided. And finally, it could be the user decided to, you know, always ask me when you get this certificate because I want to see each time something happens that uses this.

There can also be errors during the evaluation. Now, those errors are actually divided into two categories. You have recoverable errors and fatal errors. Fatal errors means, you know, something was wrong and there's no way to fix it. You know, root cert was missing. There was like, you know, there were actually invalid signatures in the chain or something like that.

Well, recoverable errors are something we've had to add because people using certs for servers didn't really update their certs in time. Remember earlier on we talked about what's in a cert. Well, one of the things is the validity date. Well, it turns out that, you know, 20 or 30% of the websites out there that use SSL use expired root certs. And it's like, well, according to X509, if you, you know, read these books, it's like, well, okay, root certs expired. Sorry, you can't connect. Well, it's kind of annoying if you can't connect to Amazon.com with Apple's browser, so.

There needs to be a way for you to say, "Well, okay, the root cert was expired, but that's okay. Go ahead anyway." And that's what a recoverable error is. It's basically, if you get a recoverable failure, you can actually tell SecTrust, "Well, you know what? If root certs are expired, that's okay.

Go ahead." So you set this parameter, you devaluate it again, and if that was the only thing wrong, it would say, "Okay, now it's good." We do encourage you to not just go and, you know, let's always set these things. We do encourage you to actually, you know, tell the user or warn somewhere there is something wrong.

But, you know, okay, from now on we'll just go on and, you know, not worry about the fact that it's expired. But you shouldn't just blindly turn off all these things because there are a couple of different options and you shouldn't, you should, in your app, try and be as strict as possible, but allow for, you know, real world use.

There are some additional results on the side. If something goes wrong during the evaluation, you can actually get a detailed structure of the entire evaluation. It will show you details about each cert in the chain and what was right or wrong with those. As it happens, we actually have a UI object to display that in a nice way to the user, because that information can be fairly complicated. There's actually a UI object that lets you display these trust results coming from a SecTrust object.

Some of the ingredients you can stick in to SecTrust before you evaluate it: policies, parameters. Obviously you have to put in the certificate you're actually evaluating, and you can, in addition to that certificate, add a bunch of helpful certificates that might not be available to the system otherwise.

They're optional. If they're already there in some keychain or some other place where the system can find it, they're not needed. But typically, like if you connect to a server, it'll send you a bunch of certificates. You just drop them all in, and SecTrust will do whatever it needs to do with them.

and like I said, it'll search any keychains for more certificates. Now, if you have a very custom application and you don't want to use the system anchor certificate or root cert database, SecTrust actually lets you specify your own list of anchors. So for a particular application, you only want to trust this one root, you can actually pass that in in SecTrust and say, "Well, just only trust this root or this list of roots." So that's possible.

The user trust settings are actually part of SecTrust, and that lets you manage the user trust settings for a particular certificate. They're really only useful for administrative applications. You normally don't really need to manipulate those because the normal way you would do it is you'd bring up this user trust dialog and that actually lets the user change their trust settings on the fly while displaying the certificate.

These trust settings are actually per certificate per operation, or really per certificate per policy is what it is. So if a certificate is valid for multiple policies, each of those policies could have a different user trust setting. And the four different values for trust are: It's not set, which is the default. It can be always ask, always deny, or always proceed without asking.

This is what the Edit User Trust dialog looks like, more or less. So there's a view of the certificate in there, and you can change all these different trust settings. And now we'd like to demo, invite Ken up on stage, and he's going to show you exactly how all this works.

Thanks, Michael. The first thing I want to show you is a brand new web browser that was just released this week, and it's not Safari.

[Transcript missing]

That's all well and good, but as Michael said, there's a lot of sites out there that have some kind of problem. So these bad SSL sites, what happens when you go there? Here's one: digitalidverisign.com.

So I tried to connect to this, and there's a problem. So what I can do is just put up this panel that tells me what the problem is. In this case, there's an untrusted root. So why is this root untrusted? Oh, it expired in 1999. Whoops. So I can give the user the option to go ahead and connect or not. In this case, you know, I don't trust that, so I won't connect. Here's another example: authorized.net.

And there's a problem there, too. Let's see. Certificate chain not verified because the root was not found. So Michael explained to me that. Michael explained that the only roots that are trusted are in that system-wide database, X509 anchors. So let's go and see if I can. Add that to my Anchor database. I downloaded the cert. I've got it sitting out on the desktop. So I'll just double click it here.

And Keychain Access is launched, and it asked me if I want to add this cert to a keychain. And I've got a couple different keychains, but again, X.509 Anchors is the root certificate database, so I'll stick it in there. Now, because that's managed as it's owned by root, I have to be an admin user on the system to change that database. So I'll go ahead and type in my password to import it.

And actually, let's look at the contents of this keychain. We can see all the different root certs that are in there. And sure enough, there's my Entrust cert. And I can look at it, and I can verify the fingerprint, and I can see all the fields in it.

and all the extensions and its CRL distribution points and verify it myself. Keychain Access is using that same view that is available on security interface to display the contents of the cert. It's just inserted in the window, much as you'd put it in your own application. So now that that route is in there, let's go back here to the web browser.

Let's try to reload this. Well, actually, let's start fresh and try to go to that site. And this time, I can get there. And when I look at the actual cert chain, I see now that it's actually verified all the way back to the root, and it's in there.

So, how much work was it for me to just take that sample app and put the certificate trust management into it? Well, let me show you the actual source code here. I added a method called Evaluate Trust, and it gets called whenever a URL is loaded. So I can go off and evaluate the trust.

I start, what I want to do is make a trust object, a SecTrustRef. As Michael explained, it's a workflow object, so I'll be just sort of putting stuff into it to encapsulate what the trust means for this connection. I can get a policy ref. I've written some code to give me back the policy for SSL, because that's the one I'm interested in here.

And then I call SecTrustCreateWithCertificates. So I take the certificates that I got back from that connection in server certs, and I take the policy that I'm interested in, which is SSL, and I feed them into that, and it gives me back a trust object for that particular policy.

So once I have the trust object, I want to evaluate the trust. I want to actually make sure that it verifies to a trusted root and that there's no problems with it. And the call I made to do that is SecTrustEvaluate. I just pass in the trust object and I get the trust result back. So then I can look at what that trust result was. One of the possible values that it can return is KSEC trust result deny, which means, no, it's just denied. The user has said, "Don't ever trust this cert." So I bail out.

But if not, they may have also said, "KSEC, trust, result, proceed." So they may have said, "Always trust this cert, no matter what." For that particular policy, for that trust. In that case, I can return and go ahead and load the page. In the case that's interesting, when we get a recoverable trust failure from the evaluation, we can ask the user what to do, and that's real easy. Cook up my own message telling the user what the situation is and why they might care, and then I get a SF certificate trust panel.

This is just a singleton object that I can grab and then put up a sheet. The parameters to put up the sheet are the window I want to put it up on and a selector for what happens when the user puts it away. I pass in the URL so that I can display it, and I pass in the trust because that's what gets displayed. It's got the certificate chain, and it has all the things that will be displayed to the user, and then my own custom message.

And if the result was some other kind of error, I can... return the flag that says, "No, don't load the page. There was an error." And otherwise, the page loads and everything's fine. So that was basically all it took to implement Certificate Trust in that web browser. So with that, I'd like to hand it back to Michael, and thank you.

Thank you, Ken. Well, so just to summarize what we've done today, or we talked about today. So there's new and improved APIs for your development pleasure. Most of them have been available since Jaguar. Some of them are new in Panther. If you need your app to run on Mac OS 10.1 or earlier, you should stick to the Carbon Keychain Manager APIs, which I doubt very many of you are still developing for 10.1, but if you are, then that's what you can do, and it's there.

The Sec APIs are easier to use than the CSSM layer. The CSSM layer is fairly complicated to use, but it's very, very flexible. And because of our toll-free bridging to CDSA, you can bridge down to that when you do need the extra flexibility. But you don't have to always deal with the complexity in the simple cases.

[Transcript missing]

And avoid micromanaging. That's basically what I just said. Just use the APIs you need and use them appropriately. And with that, I'd like to bring... Craig back on stage.

We'll go through these little road map thingies and we'll get to Q&A. So the reason why we put roadmap things on for things that have already happened is because you'll get the DVDs, and we wanted you to be able to go back in time, even though we don't give you time machines here at WWDC. I'm going to skip past these. I'll bring them back up on the screen while we're doing Q&A because we're running long.