Mac OS X Essentials • 1:00:07
Leopard's code signing feature allows the Keychain and other system software to verify your application's ownership without prompting the user'even after you've updated the program. Find out how digitally signing an application ensures the integrity of your code and enables the system to recognize unauthorized changes and alert the user. Learn how signed applications work, how signing improves security and your customers' experience, and how to sign your applications.
Speaker: Perry "the Cynic" Kiehtreiber
Unlisted on Apple Developer site
Transcript
This transcript has potential transcription errors. We are working on an improved version.
Hello, welcome; I'm Perry Kietreiber usually called Perry the Cynic and this is if I recall something like, "Sign your applications to make the world a better place" and oh a very long title but what it really is about is code signing.
( Pause )
Yea, that's me. So what am I going to tell you? What code signing is, how we're using it in Leopard and what you need to get your application signed and well how to stay out of trouble while you get your application signed.
Those of you who've been here last year, this is about the same thing and you'll definitely notice that I'm telling you the same thing again because the technology itself hasn't changed; the only difference is that it's really here; so what we promised we pretty much did and a little bit more.
So what is code signing? It's actually about you; it's about the developer; you get something that you haven't had before. You get to define an identity for your code; you get to give it a real identity and the system from that point on forward takes care of finding out if somebody mucked with your program, changed it and conversely if there's a change that happens to your program that you meant to happen because you shipped a software update the system is smart enough to realize that that's okay.
Once you got your code off on the user system there is functionality for checking the stuff right there on disk to see if its changed, it its still intact, if it's really yours and more importantly running code once your application has launched the system can check that running code and see if it's still what you shipped or if there was a change...and following the old tradition, so what doesn't it do other than save the universe just like other technologies in the security arena that the authorization subsystem.
It doesn't actually give you any privileges by itself that you don't already have; so just because your application is signed doesn't mean that it suddenly gets root access or get to do all kinds of special things although there are system components that will look at your code signature to decide whether to let you have stuff.
Code signing is not about your program having bugs or not; if you write a buggy application and you sign it, it will be a signed buggy application and it'll have your name on it saying, "We made this." The bug will still be there and it can still erase the users hard drive if that's your bug; I recommend against it personally. The other thing that code signing doesn't protect the user from is to trust somebody they shouldn't be trusting because this is all about whether the user trusts the developer.
If a user says, "I trust Mr. Hackers mail application" and Mr. Hackers mail application (inaudible) up all of the passwords and e-mail addresses and mails them to him code signing says, "Okay, you said you wanted to." So code signing itself does not decide for the user who to trust; it just lets the user express who to trust and who not to trust and they always ask me to say this is not a copy protection facility so if you're making copy protection software this is not here to put you out of business.
It does help you figure out whether somebody mucked with your program; so whether you are doing copy protection or not that it will do for you but it doesn't do anything about somebody copying a program to another system and running it there; that's not its job. So, last year I told we were just starting to put this into Leopard; well we have put it into Leopard and it's actually in a number of places now.
The Keychain subsystem uses code signing to identify clients so every time you make a Keychain call and you say, "I want this password because I'm me" code signatures will get checked and you will have extra problems if your signature isn't there or isn't intact. Anytime the security server daemon deals with a client and that includes you if you're making authorization calls it will use code signing to determine who you are, what your name is, what your identity is; again there's this identity thing but you're putting on your code.
If the administrator turns on parental controls code signing will be used to determine whether a particular application that's on a list of allowed things to run really is what he claims to be so no more just mucking with info P lists to pretend that Walter Farcraft really is mail dot application.
There is a new feature in Leopard called the automatic firewall, you may have heard of it as the outgoing firewall or application firewall; that uses code signing in a limited fashion to decide whether to put up a big dialog saying, "Do you really want that application: or if you're validly signed it won't; it'll just go, Oh, okay, you may and those of you who call an obscure system called call task for PID you pretty much need to be code signed in order to make that call in Leopard unless you want to rely on a legacy facility and nobody here wants to rely on a legacy facility, right, good; so all of that is yours if you sign your code; so you want to sign your code. I'll tell you that 3 times and then another 3 times because you really want to sign your code. No excuses this time.
Let me give you sort of the brief flow of data for how this code signing thing works. The vendor on the left that's you; you build your program like you always do; you take your code, your info P list, your resources, whatever else goes in there and you assemble it in Xcode or with meg files, whichever way you want and the extra step is that you take a code signing identity which is one of those script-o-graphic identity things and it gets stored in Keychains because this is Mac OS X and you feed it into a command line call sign that's one of those command line commands and out pops the modified version of your signed code that actually has a signature embedded in it. What it will actually do is modify it in place by just sticking the signature in.
You take that signed code instead of the original and you ship it anyway you want; you know, we don't care how you do that, Apple installer, third party installer, Dragon install, you know Magical network, transfer mechanisms, we don't care as long as the thing on the user system when you're all done is exactly the signed code that you started with and we really pretty much mean byte for byte the same application and the user runs it and through the miracle of code signing if anybody is interested in the identity of that running code they call our verification API and the system basically says, "Yea that's it or No that's not it and that's why" and that's all there is; it's really simple unless you have to implement it.
( Laughter )
Okay, so as I said, we have the stuff that's sitting on disk, that's what you're signing, you know, your application or your tool or whatever that code is of yours; that's what carries the signature once you sign it; that's what you ship and because that is what we're protecting against modification it better be immutable and that's another one of those, "I'll tell you 3 times things." You will get in trouble if you change your code after it's signed and it increasingly doesn't matter which part of it; obviously the code itself, you know, the Mach-O, instructions but now it also means the info P list because it describes to the system things about your code and I'm also talking about your resources. If you have a habit of mucking with the resources in your programs after they've been installed, listen up, I'll tell him what he tells later.
Obviously code is, you know, tools, Mach-0 binaries, bundles with Mach-0 binaries but code in the sense of code signing also includes a bit more surprising things like libraries and frameworks and plug ins and potentially also scripts, you know, Ruby scripts, Perl scripts, whatever; in principle scripts are code and code signing understands that scripts are code and in fact code signings notion of what is code is extensible; so over time more things will become recognized as code and become signed and verified as code.
( Pause )
Now code signings primary interest isn't actually on this stuff sitting on disk; as long as it sits on disk it's harmless; once it's running it's dangerous and once its running and you know make system calls and RPC calls and ask for all kinds of stuff like your Keychain password for your mail account then it's dangerous.
So code signing is primarily focused from a verification point of view; it's actually on running code. This is sort of an important point. You can run verifications on stuff on disk and it'll work and it'll give you useful information but that's almost sort of a side effect of what this is really about.
At runtime the system keeps essentially a bit with every running process; we call it the valid bit and it basically says, "As far as we know so far this thing is okay." There are things that flip this validate off, basically make the identity of this code invalid and once it's off it will never come back on; it's a sticky bit; so when something bad happens to your program and it loses it's identity the valid bit goes off; it's invalid until it dies; if you re-launch it, it starts valid again until it does that bad thing again that made it lose it's validity and then there's additional stuff that the system also keeps, like there is a bit called KILL bit which basically says, "If I ever lose my identity just shoot me."
( Laughter )
Yea, that's exactly it. That is sticky too; once you set it, it won't ever clear again for that process.
That's a useful combination because if you ever see a process that's valid and has the KILL bit set you know it will always be valid because if it ever loses it's validity it'll be dead; so as long as it's alive it's valid. Cool feature. There's another one called HARD that is occasionally useful; it basically means "Please if I ever have a choice I'd rather not get my resources than lose my identity because my resources are bad." It's sometimes useful, not terribly.
So, I said this is really about running code and well there's a lot more stuff executing in the system than just processes. I mean, every time you run a script; I mean you run, I don't know, Ruby but what you're really running it the Ruby script. Ruby the program is just there because it's necessary to help running the script. If you're running a PowerPC binary on an Intel machine it's actually the Rosetta system that's executing the program in very magic and highly patented ways.
So from the kernels point of view it's dealing with this thing called translate which is part of Rosetta but from you point of view, from the user's point of view they don't want to know. If you've played with the earlier version of the beta once in a while programs would pop up these odd dialogs that say, "Translate wants access to your Keychain password." Well, that's actually Rosetta because you were running a PowerPC binary and at that point in time things haven't been hooked up yet, now they are; so welcome to the beta where this all works.
So when you were looking at running code things are a lot more complicated than just processes and just, you know, files on disk and the way code signing deals with that and this is the really, really high level explanation, is code signing understands that code is run by other code; processes are run by the kernel and scripts are run by the script interpreter and PowerPC binaries are run by this Rosetta machinery and hey, CFM binaries, yes we still support them, are run by this launch CFM app thing and so on.
To which if you're on Intel as the good gentleman in the front row says, "Yea; so these mechanisms stack; you can actually build this theoretically very long chain of host codes that on guest codes that are in turn host codes and we call that the hosting chain; so even in a general situation you end up with this fairly complicated stack relationship of running codes, managing other running codes and it works; it really does.
So here's a couple of graphical depictions. This is the trivial and obvious case where the kernel is running a process that it fetched from the disk.
( Pause )
Here is one that is actually from real life...that had the kernel using Rosetta to run a PowerPC binary that happens to be the launch CFM application helper which actually manages to run an old CFM program like Microsoft Word, until they finally come out with the new version.
So this ones real; that happens today if you want to run Word or anything else that's a CFM app on your Intel machine. Here's a hypothetical one where...yep, where you have Ruby the interpreter...okay somebody messed this slide up. I apologize sincerely. I hope it wasn't me; oh, anyway...imagine Ruby running a Ruby script, that's hypothetical because at this point in time we haven't hooked up the API calls in the Ruby interpreter; eventually we will or you know, it's something like 5 lines of C code; it's really pretty easy; it just requires that...whoever manages that particular program knows where the paths are coming from and when things happen.
Okay, so here's sort of a bonus that comes along with code signing; it's there because code signing uses it internally. There is this requirement language; it's sort of this small interpreted programming language that is solely there so you can express in a formal way constraints or restrictions on pieces of code.
That's there and it's used internally in code signing and if you're using the verification APIs you can write one of those requirements and pass them in and say, "This is code, satisfy this requirement." That's all I'm going to tell you about it because unfortunately that's not in API and Leopard so consider yourself tantalized.
( Laughter )
When your signing code you use a cryptographic signing identity and I've been warned because we've got 2 identity words in here; we have the identity that you assign your code which is essentially a name you're giving to you code and then you put your stamp on and say, "We made this and therefore you can believe us" and then there is this cryptographic identities which are, you know, cryptographic keys and digital certificates; those you use to actually find your code.
So these are the signing identities that you use to sign. We using an industry standard format; there're signed X5 certificates if you happen to know what that is and it's using the standard code signing extension that's been in that RFC for pretty much forever; you can get those by buying them from commercial certificate authorities, that's perfectly fine; that has certain advantages. You can make your own; Keychain access the utility application has a little helper built in called the certificate assistant and as of, you know, a couple of betas ago it can make you a code signing certificate fairly painlessly.
( Laughter )
Hey, nothings free...and if you happen to have a Microsoft style authentic code certificate or identity that you're using for code signing on that operating system that shall not be named they will work because, you know, at least as far as we know they're following the standard and so do we.
Signing identities are stored in Keychains, you don't get a choice here; so if somebody hands it to you in a different format you will have to import it into your Keychain but then everybody has a Keychain whether you want it or not so you might as well use it.
Speaking of Keychains...the access control mechanism that Keychain items have a major improvement based on code signing; you've always been able to say that say this mail password only can be accessed by mail dot application but not anybody else except, you know, it pops up a dialog and asks you whether you want to; anyway if it's not pre-approved.
That used to be an okay mechanism based on essentially what bytes are in the executable but now its based on the code signing identity of programs that are signed and that's a heck of a lot more flexible because among other things it automatically figures out whether the new version of your program is an update to an old version; so certain dialogs that I'm sure you've all come to love will just not happen if your application is properly signed. So there's another reason, sign your applications, thank you.
If you've already shipped an application in Tiger obviously it's not going to be signed and people have used it and made Keychain items that are accessible to that application; if you ship and update of that application in Leopard that is signed the system actually has an upgrade path that it takes automatically where it basically edits ccess control list of the agent to put a method of extra information in so it understands that the signed version of your program is a continuation of the unsigned version; so you will in most circumstances see one last one of those dialogs that basically says, "This is really an upgrade to the previous one" and then it'll shut up as long as you don't keep flipping back and forth between Leopard and Tiger where of course Tiger doesn't understand any of this and you know, introduces new things that Leopard needs to think about; so if your users make a transition strictly from Tiger to Leopard and then stay there after that last instance of those dialogs things will just shut up.
If you use the SecAccess or SecTrusted application APIs to make custom access control list the really good news is that those APIs are still there and they're unchanged and they still work and your code is going to continue to work without you having to make any changes to it and it'll use code signing if your application is signed. So you'll get all of the extra super benefits without having to change any codes; we're rather proud of that one.
Gee, time for a demo. Okay I hope nobody is afraid of command line commands. I made this really small test program called CS Test for code signing testing and let's just take a look at what happens with unsigned programs; one of the few things CS Test knows how to do is it can make a Keychain item and having made the Keychain item it can retrieve it again; since it made the item it has free access to the item, that's fine; now if you've ever made Keychain calls you know what happens if you make a change to your program.
Let's say...we make a new version of this with a trivial change in it...and well the system doesn't really know that that new CS Test is a genuine approved by you the developer real new version of CS Test so you get this dialog that basically says, "Hey user I can't figure this out. Is this the same kind of CS Test that you had before" and people say always allow and then you get access to your Keychain item again until you change it.
People hate those dialogs; you hate those dialogs, admit it. Okay so this is a command called code sign in user bin; it's a command line command, sorry about that, and you can tell it to sign say CS Test. The signing identity is in the Keychain so we have to unlock it and...now CS Test is signed.
Dash V for verify and you know dash V for give me more verbose information; it's a classic Unix thing again if you're wondering there's a man page, go read it; it's actually your best preference to the command. Okay...so CS Test, still in the same program of course, this was the automatic upgrade I was talking about; if this was your signing identity you'd get a confirmation dialog because Apple gets certain privileges here.
So, let's try this again. You know, management comes to you and says, "You shall put a strict disclaimer into our program because our lawyers are sorely afraid." So CS Test of course since we just, we built it, isn't signed so we need to sign it again...and now...it's signed.
Think about what we just did. If this is you, what you just did. You basically said, "This is my program; it's called CS Test and I vouch with my digital identity that I really made this." This is the same statement you made about the previous version. So rather than the system having to think about what bytes are in the file and what does this all mean now the system can look at this and go, "Oh, the developer who made the original said that this is the same program; so no problem, he said so. I mean if you can't trust the developer about the identity of his program who can you trust?" So if we run that thing again, no dialogs because everybody knows what's going on.
So... ( Applause ) Well, thank you. In a sense this is sort of the crust of the matter, you know, it's the absence of dialog isn't just that we got tired of putting dialogs in everybody's face and now we're shutting up, it's that we don't need the dialogs anymore because now the system actually knows what's going on; that's the big change.
Okay, well for those of you who would never be caught dead with a command line tool I made a version of CS Test that's an application. It basically does the same thing; it just checks itself so it can report on what's going on and right now since we just made it, it says that it's not signed; so let's sign it.
( Pause )
You'll notice we're signing a bundle here and the signing mechanism understands what it means to sign a bundle so when we run the program now it's valid and particularly here the dynamic validity of the program is on because we haven't done anything to invalidate it; so let's ask CS Test to access that test item; CS the application is a different program from CS Test the command line tool so you'll get this dialog as you should because, Hey it's a new program that wants access to the Keychain items so let's say okay and at this point...yep, now both of them have access to the Keychain item.
Now let's turn the dynamic validity of this thing off; the code is still statically valid; the thing on disk is just fine but something happened to this running program and if it's now trying to get access to this Keychain item you're getting a new dialog that basically says, "You know, something is not right with that program as it's running here; you know, something changed it and do you still want to allow access because the pre-approved entry doesn't apply anymore?" You also won't be able to say all was allowed because at this point it's quite unclear what the identity of this program would be since something has mucked with it. You can still allow on a one time basis, the user can, and if you quit it and re-launch it since there's nothing wrong with the version on disk it gets access to the item just fine.
So, you may wonder what happens if we make a change to the program. I have a little hacking program that let's us change code but I'm not going to daemonstrate that; let's just crawl in here...and...oh, I don't know, change the info P list; that's how in Tiger the smart kids get around parental controls because parental controls just looks at the CF bundle identifier and what ever that says it believes so if you take Walter Farcraft and you say it's com dot Apple dot mail...let's try that...see, easy change.
Oh, wait, the code signing system actually looks at the info P list; it basically thinks of it as an extension of the code and it notices that that file has been modified; so at this point this time the dynamic validity hasn't been affected but the thing on disk is wrong. In that effect it's pretty much the same...you can't get at the Keychain item.
If you undo the change since, you know, you're back petting the thing on disk okay remember how I told you it doesn't matter how you ship your code, how you install your code; all that matters is what's there on disk when the thing is running and if it's intact we're fine.
Same thing happens to resources; there isn't much resources in this program of course but let's just add a new resource.
( Pause )
( Pause )
And the system is looking at the resources too; when you sign a program with, that is a bundle that has resources, this has actually built something called a resource directory that collects information about all of these resource files and builds little cryptographic signatures for each of them; so not only does it tell if a file has been modified it can also tell where the files got edited or removed.
So in this case we added a resource that wasn't there; just think about it, it could have been a nib or it could have been something that changes the behavior of the program and well we figured it out and again if you remove this you're back into the good, the valid state of things and you know, we're back.
( Pause )
Let's see, alright just as a small bonus daemonstration, one of the other things that CS Test, the command line tool can do is it can actually simulate being a code host. I mean, not simulate, it can be a code host. I've got these little scripts called A and B just to show you what it is; it's a text file; it's just a simple text file; there's nothing executable about it per say but you can teach CS Test to be a code host for say A...and access a Keychain item and what we get is this.
What happened here is that CS Test called an API that said, "Hey I'm code host and I'm now acting on behalf of this A dot CS Test file over there" and the system said, "Okay" and then when CS Test the program made the Keychain call the system said, "Yea but you're not really you; you're acting on behalf of this A." The security daemon got told that the identity of the requester isn't CS Test, it's A and so the security dialog that you're getting is about A dot CS Test; even though CS Test the tool has pre-approved access to the Keychain item it doesn't apply here because it's not CS Test making the request; it's A making the request.
So the code signing system in (inaudible) can deal with things that aren't on process boundaries that aren't really processes, they are something else. You know, this could be your Ruby script; this will in fact your program if it's a PowerPC version running on Intel with CSF's role being played by Rosetta and there we are. Okay...end of demo.
( Applause )
There is a lot more to this but this is a one hour session and I'm also somewhat constrained by the fact that most of the APIs aren't going to be APIs in Leopard. So primarily what you get to do this time around is sign your code and watch the show. And now the second part of the presentation; I've tried to sort of explain to you in first part what this is all about and now I'll talk about what it all means to you.
This is one slide if you've been here last year that you looked at and basically it says, "What should you be doing a year ago and well get ready because it's coming." Alright it's a year later it's here, hope you're ready. If you're not, if you just thought, "You know they always talk about this and I'll deal with it when it's really here;" it's really here so what do you do. There's a set of things you have to do once, just to set yourself up for that code signing gig.
You have to figure out who in your outfit, in your company gets to do the signing. If you're a garage shop; if it's just you and a friend, not a problem, it's you. You know who you are, you trust yourself, cool. If you're a large company and you have a legal department or an IT department you want to start talking to those folks now; particularly the legal departments because they usually take months to get back to you.
The question is, "Who in your company has the authority to sign your code" because when they put their signature on the code they're speaking for your company as a whole. They say, "We, Adobe; we Microsoft; we Joe's Garage Shop, say that this is our code and we're proud to call it our code." So you don't want to put that sign on some stupid little hack that somebody in your company cooked up in a corner and you definitely don't want to put it on something that somebody else made that you don't even know.
So, it is important to figure out who has the authority to sign your programs; then you need to decide what kind of digital identity you want to use. I told you, you have a choice; you can buy one from a certificate authority or you can make your own and there's good sides and bad sides on both sided of this; so there's trade offs and I can't really go to much into, you know, the general nature of cryptographic signatures and all that because, you know, that's another 2 hours but if you're a large company you'll probably have folks who know about these things and if you're a small company you can always start with one you make yourself and then worry about it later.
Then you need to set up your signing process. You know, you have your work flow; you've got your Xcode build so you make files or whatever it is that you do to build your programs and then typically after that you package them up together in some way; you're mastering them, is the big word, getting it ready to be shipped out, you know, over the network, burn it on CDs, whatever you do and in between there after you finish building and before you start mastering, that's where you sign.
So basically you're add a signing step in there and depending on how automatic you want to be about this; we're talking about either adding a shell script phase into your Xcode builds or having something a little bit more official where people sit down with a glass of wine and you know say, "Yea, this ones good here, I'll sign it." So set up the process and then test it.
Not much to test; you set up to sign; you do the signing; you ship it to your friend who installs it and checks out if it's okay; you make an update, you ship it again and you see if it's still okay. If you pass those 2 steps you're pretty much okay.
I talked about that one so let's just say that it's your choice. Apple doesn't tell you to go buy one; Apple doesn't tell you not to go buy one; we support both types of signing identities with the same enthusiasm. Apple itself we will not sell you or give you signing identities; that's not our business; there isn't really anything we're adding to that game that other companies can do at least as good; so don't look to us for giving you identities although, you know, we can always try to give you advice.
This is what you do every time that you build code that you really want to sign. I highlighted the 2 steps, the signing one obviously that's running code sign with the identity that you built yourself or bought yourself; the first highlighted step is maybe not totally obvious; anytime you sign code you are saying, "I made this and I'm proud of it;" so you may want to think a little bit about what hoops your code needs to jump through before you put that stamp on it that says we're proud of this. I wouldn't advise you signing everything that you build all the time. You know, development builds, debug builds, because if those get out and they're signed your signature still says we're proud of this even though it removes the user's hard drive.
So...put a little bit of thought in there. You know, maybe you only want to sign your GM releases; maybe you only want to sign your Betas; maybe you only want to sign stuff that at least, you know, one of you has lived on for a week. It's your decision; I'm not telling you what to do but think about it a bit because it's worthwhile spending a bit of time thinking about it.
The inquisitive ones among you will by now wonder, "What the hell does this code signing thing do to my program anyway and what is it going break?" If your program is a Mach-O binary either directly or because it's a bundle with the Mach-O binary in it, most of the signing information will actually go right in there; so we're going to modify your executable by adding a section that contains a bunch of data in it. That happens to be a section that nobody accept the code signing system looks at so your program will function the same, just you know, understand that there's extra stuff in there.
If your code is not a (inaudible) binary, I told you we do scripts and all kinds of other stuff and then there really isn't any structured way of sticking this directly into your files so what we do instead is we stick it in an extended attributes; so if you do make code that isn't a file do note that we're adding extended attributes to your executable file and don't use some installer that doesn't understand what an extended attribute is because it'll probably just leave it behind...that's not good.
If you have a bundle then we will also add a file or 2 to the contents directory of your bundle; that's the resource directory; that's the list of all of your resources and enough information to figure out if they have changed; so don't be surprised if there's a file in your bundle that wasn't there when you built your program; if it's called code resources, that's fine.
If you are really curious, the code sign command has an option for "Show me all the files that we added and modified when we signed this." That'll just give you a list of files so you know what it did to your code and there's one last note...most of you won't have a problem with this but I'll mention it anyway.
When some other program is trying to establish whether your code that is running is valid or not it is going to go and read the code signing information in your code, in your bundle and your executable because it will need to in order to figure out who signed this and what it looks like. If you're installing your program in such a way that the verifier can't read it he won' t be able to verify you; so if you make your program not world readable then there will be some users on the system who can't verify your code.
That's not a problem for things like the Keychain system because the security daemon runs this route and it can pretty much see no matter how much you try to hide but as time passes on and as more and more daemons start using code signing validation to figure out whether to give you services a lot of those don't run as route for security reasons, they run as some harmless user that doesn't do anything else and that harmless user that doesn't do anything else needs to be able to read your code; so my advice would be to make sure that your code is world readable. You don't get any extra security not being world readable as far as your code is concerned anyway. So just to make sure you don't get hassles and weird bug reports of stuff that only happens to some people out there; keep your code world readable.
What does this all mean about suffer updates you send out? Not much actually if you do it right. Again I told you; it doesn't matter how your code gets there as long as what's actually there on the disk on the user system is what you signed. So if you make a new version of your program, build your new program, sign it and then ship that to the user system somehow; obviously if you're sending out a drag install and you know the idea is that the user just replaces the program you don't have a problem; if you're using the Apple installer or third party installer for that matter it's not going to be a problem either; it will just override the changed parts on the user system. If you're using some kind of incremental updater where you're carefully only shipping the parts that changed, that's fine too; just make sure that what you're comparing in the sense of what has changed is the signed old version of the signed new version.
Signature obviously will change so you're shipping the new signature; you'll end up with your new program on the disk, everything will be fine. The last entry again, this is sort of a geeks kind of notice; if you replace your main executable during an update you should be doing it by replacing the file, not by overriding it. This isn't really...if you're doing drag installs that'll just be fine; if you're using the Apple installer you'll be just fine because it does the right thing; if you're using a third party installer you may want to give those folks a call and ask them what they do.
The problem potentially is that if that program is running at the time you are updating it the system, the kernel, may have the old verification information on that file attached as information in the kernel and if you are overriding the file instead of replacing it, it may still have it when you're done with the updates; so you may end applying the old verification information to the new file and that, you know, is not good; just a little implementation note here.
So what do you sign? Well you want to sign all of your code; that obviously means you're going to sign your beautiful application or your nifty tool; if you have a helper tool or a helper application inside of your application, you know, one of those things that the security folks told you to do because on the little tool does the root things; if you have helpers you need to sign the helpers separately; so that means running code sign more than once; once for the bundle itself, once for the helper inside of the bundle.
You can sign frameworks and libraries and plug ins at this point; it works; it's probably a good idea. Leopard comes out as a GM will not actually verify libraries and frameworks and plug ins but doing so if your product is one of those or includes one of those, gives you a leg up because eventually Leopard will start verifying those and then if you're already doing it you're fine and if you're not then you have another deadline to worry about. So if it's not too much of a problem for you just sign those now.
Anything that is meant to change on the users system shouldn't be code signed; now that includes obviously documents that your application makes but it also includes things like preference and configuration data that the user is meant to change. Those things are not code and while the code sign command will sign just about anything it's not meaningful; so don't do that.
So how do you test all of this? Well the code sign command is the Swiss army knife of code signing. It can sign but it can also verify; it can display the contents of a signature; it can tell you about hosting chains; it can do almost anything you want to know.
So read the man page and knock yourself out; once you follow your signing process, you're mastering process you can just hand run code sign dash V with your path and it will tell you if you accidentally broke the signature because you did something to your program after you signed it.
If you don't just want to play around with the command line tool you can instead use one of the system facilities that actually uses code signing to give you access to it. Parental controls is the obvious one because parental controls will simply not let you launch a program unless you've approved it and it's code signature is intact; so make yourself a user account, an administrative account, say you want parental controls on it, approve the use of your program and then launch it. If your code signature is somehow damaged parental controls will not let you; so that's an easy test.
Obviously if you're making Keychain calls you can just look for the dialogs and see if you get one of those nasty worded dialogs about how the identity of your program has been modified; that would be a bad sign.
( Pause )
I made a small list of things that we at Apple ran into as we started wrapping this up and I figured I'd tell you so you don't have to run into it yourself.
Xcode makes it really easy to stuff things into the resources directory of a bundle; so easy that people have gotten into the habit of putting things there that really shouldn't necessarily be there. If you find that you have helper tools and helper applications that you are shipping in the resources directory of the main application, put the elsewhere, they don't belong there.
There's perfectly nice places for them, the contents directory is one of them, the contents Mac OS directory is another; code signing really doesn't care where as long as it's not in the resources directory because everything in the resources directory is suppose to be a resource and that means that if it changes for any reason, like for example you're issuing a software update for your helper then the main bundle will look invalid and you don't want to go there.
Localizations are contents of your resources; localizations are resources so make sure that all of your localizations are in before you sign because the signature will actually lock down what localizations you have and if you add a localization later it will not be part of the signature data and it will look invalid.
If you farm out localization to some third party then you pretty much have to get the result back, stick it into your bundle and then sign it. There's nothing wrong with re-signing your application. You'll sign it once with just English and then sign it again with all kinds of other languages in it but you know, don't ship it before you're done with that.
If your idea of installing your product is having multiple installation packages...there's nothing intrinsically wrong with that as long as you're actually installing them all. If you're offering the user the option to install some of your product but not some other part of your product and the user actually ends up doing that, then...if you actually end up with a half installed product on the users hard drive it will probably be violating the signature because the signature is based on, "I know what's here and that file is missing here." There is one important special case that code signing deals with automatically.
It's alright to strip language resources; so if you build you program with English, French, and German and then you yank the French out after signing that's okay because well code signing knows that people strip language resources all the time. That is strictly about stripping them out; adding them in after the fact is still a violation of the signature.
There are people who make installers whose post install script does unpleasant things to the program that just got installed like editing the info P list; don't do that; that's a 100 percent dis-qualifier; your signature will blown immediately. There's also people who still think that inside of the bundle is a really great way to store things like preferences; that has never been a good idea and we've been telling you for about 5 years not to do that but now it will actually hurt you; so if you're still doing that now is an excellent time to stop doing that; preferences belong into the library preferences, not into your bundle. Well, if you write self modifying code, I mean the kind that actually modifies the executable on disk, I feel sorry for you.
( Laughter )
And here's a few questions that I've gotten more than 3 times so I'll answer them before we go to real questions. No, Apple does not decide whether your code is any good or not, that is not what code signing is about; so if you're used to something called code signing or something similar on other operating systems that shall remain nameless this is not like that. This is not about Apple approving your codes; this is not about Apple saying that your code is not good unless you paid for us to sign it; nothing like that.
Code signing is about a relationship that you have with the user. You promise that this is really your code, the user says, "Okay, I'll believe you." That's what this is about. Obviously when we're talking about code that Apple wrote Apple plays the role of the developer and you know Apple says, "We make this and we're proud of that" but your code is your code and we're just here to help facilitate your interaction with the user.
Mac OS X will run your program just fine if it's unsigned; there's nothing in the kernel that says that code has to be signed to be run as you all have probably have noticed because you have Betas or early releases and your programs didn't mysteriously suddenly die because you haven't signed them yet.
As a matter of fact, your program can live a full life without ever noticing anything bad about not being signed unless it calls a system facility that is interested in code identity like the Keychain system or parental controls or developer access like task for (inaudible) or the firewall, you saw all this. So the system itself will run your code just fine and if you lose your identity halfway through because your code does something weird it will still not get killed unless that kill flag is on that I told you about.
( Pause )
The third one, well, I got that twice...you know, what "You're telling me I have to go to one of those CAs and buy myself a certificate, why do you make me spend my money?" We don't; we have this free tool called a certificate assistant; it's included with your version of Mac OS X which isn't quite free; you can make your own certificates, your own signing identities and they are just as good for the most part as the ones made by Verisign or Thawte or a long list of other companies I've been told not to neglect. So the choice is yours; we're not forcing you to spend any money on these certificates although if you want to, if you think it's a good idea go right ahead. We're not telling you not to spend your money on those companies either.
If you ship codes that suppose to run both on Tiger and Leopard, that's just fine. Tiger has no idea what a code signature is and it will happily ignore all of this stuff and run it like you'd expect it to run it; the only constraint is that in order to actually sign code the signing step has to be done on Leopard because Tiger doesn't know how to sign code either. So, you know, if you want to ship a program that runs on both systems the easiest way is to build it on Leopard, use the Tiger SDK and sign it, works fine.
Code signing is a really big feature and it's not done in Leopard but we've concentrated on the infrastructure, we've concentrated on getting the big pieces in but there is a lot of work left for the next big cat, whatever we end up calling it. We are definitely going to...automatically check more and more of the pieces of your code like resources, like libraries, like plug-ins so in Leopard, as I told you, libraries aren't automatically checked even if you sign them but that will just get added on the way, I can't tell you when but that will definitely go in.
We're definitely going to add a lot more code host, probably a lot of script interpreters, you know, little things like the widget runner; widgets are not supported in Leopard because they're kind of complicated little beasties and we're also going to, well, support more interesting code types; kernel extension we actually ended up supporting in Leopard but there's other pieces of code that have their own interesting features and we are definitely thinking about making the various APIs officially, publically available; if you have a particular preference as to which ones you want first let us know, loudly, often.
There's also some new system features that could really, God I can't say I use this word, leverage code signing; one obvious one that pretty much everybody comes up with after they hear about this is "Does this mean you can just run over the hard drive and find all the code and see if it's still okay?" Yea, that would be a cool facility so we're definitely thinking about doing that. Another obvious application is if your code, if your application is loading plug-ins wouldn't it be nice if the user could say, "These are the kinds of plug-ins I'm okay with you loading" and the code signing requirement machinery is the perfect tool for expressing that.
And there's outfits, both parts of Apple and third parties whose rather lucrative business is to ship specialized versions of Mac OS X, you know, either by adding stuff or by pre-configuring it and their customers tend to have a strong interest in making sure that what they get, what they end up with on their hard drive is really what that pre-configuration service wanted them to have. Well code signing can do that; it's basically born for doing that kind of thing. So that's also something that we're definitely looking into adding.
Here is the where else to get information; Craig Keithley is the technology evangelist of security technology evangelist so he wants you all to have his e-mail address. The man page for code sign is really pretty large and pretty complete so please do read it even those of you who don't like man pages because there is a lot of information in there that you won't find anywhere else at this point.
There is a preliminary code signing guide in the reference library that's on your Beta; that's not on the web site yet because, you know, it's not a released feature but if you use Xcode to read the preliminary documentation there it is, just look for code signing...and if you're ever wondering exactly what the requirements are placed on, you know, a code signing identity RFC 2459 describes theY extended key user extension called code signings and you or the geekish friends of yours can figure out whether a particular signing identity will work for code signing or not.
Summary; they told me to have a summary. It's here. Really; there's not evading it; sign your applications, really. Your users will be happy particularly if you're using key chains because a lot of these annoying dialogs used to be, "Well the system really doesn't quite know what's going on so let's ask the user" and now the system does know what's going on and it doesn't have to ask the user. I mean it's a win for everybody around, if you sign your code, which you will, right.