Dan Griffin's Blog
Comments on security, PKI, smart cards, cryptography, and entrepreneurship.
First Secure Password Storage release is posted
March 31, 2009
See the CodePlex site for this project, which now includes:
- A screenshot and whitepaper draft on the Home tab
- A digitally signed MSI installer with signed binaries at the Releases tab, which we’ve also dropped to the certification testing lab.
- The latest source code (and WiX script for the installer) at the Source Code tab. A few more changes will probably be required before we’re done with certification, but the application is solid at this point.
See our CodePlex page for this project, which now includes:
- A screenshot and draft whitepaper (still needs some work) at the Home tab
- The final code at the Source Control tab
- An archive of that code available at the Releases tab
Disaster recovery and cloud computing
March 25, 2009
We’ve started a new sample code project called Cloud Backup on CodePlex. In summary, the project will allow you to backup and restore large files such as Hyper-V virtual machines to and from Windows Azure.
Although I’ve written on this subject before, I wanted to reiterate the rationale for pursuing this particular project.
There’s a compelling argument to be made that disaster recovery will be the cloud computing killer app/scenario. And it’s not about waiting for bandwidth or speed issues to be solved first. It’s a question of, “are you connected or not?”
I’d like to see the industry in a situation where the small business software platform, whether it’s the next SBS or the next XP or even something browser based, has built-in opt-out offsite archival. And the primary scenario isn’t, “oops, I accidentally deleted my QuickBooks file,” although it should support that, too. Instead, the scenario is “oops, the building burned to the ground.”
Yes, there are small businesses that wouldn’t be able to survive that in any case. But there are also plenty for which such a feature would mean the difference between re-opening and not.
One necessary building block of this is hardware virtualization. In the recovery scenario above, I shouldn’t have to figure out how to rebuild and reinstall those computers, and then figure out how to restore my data files. Instead, I should be able to pick-up a low-end computer from Best Buy, click a button, and presto, my old server is back.
“Presto” is a qualitative term
- but that’s the key point here. It doesn’t matter that I have to wait two days, or more, for that saved server image to download. All that matters is that I know it’ll work. The alternative was game over.
There are security considerations in making this a reality. Not to mention the fact that small businesses are unlikely to want to pay for this capability until it’s too late. But that’s why it should be built into the platform, where everyone can pay a few pennies for it. Again, the internet isn’t a bottleneck, and the technology is ready.
Permalink | Comments (0)Final Bio Approval Workflow code is posted
March 23, 2009
The latest code for Biometric Approval Workflow (aka Secure Purchase Order System) - a WPF client application that implements fingerprint-based authorization for purchase order approval - is posted here. We’ll have a whitepaper up shortly.
Permalink | Comments (0)Check out the !exploitable (referring to a Windows debugger extension) tool on CodePlex. Similarly to the !analyze extension, it looks at crash dumps - in this case, reporting on whether the crash was caused by an exploitable problem.
Permalink | Comments (0)First code drop of EC2 Bootstrapper
March 19, 2009
I’ve decided to change the name of this project from EC2 Console to EC2 Bootstrapper. Why? Well, there are several “EC2 Console” projects out there. But we’re addressing a problem that no one else has - how to remotely (and securely) install software to a Windows machine on EC2 without having to logon to that machine and do it manually (for example, emailing the package to yourself, or posting it somewhere on the internet). That’s the bootstrapping issue, and right now, it’s the biggest hurdle for encouraging ASP.NET developer adoption of that platform, and making this kind of deployment easier than it is on Linux (where the most common approach would just be a question of bootstrapping SSH).
We’ll still have the usual management console basics, including listing, starting, and stopping machines. But “one-click” EC2 Windows application bootstrapping is the major contribution that this is making to the world.
To that end, the first code drop is available here (Codeplex). That drop includes the following things.
First, there’s a script that will run once (on first boot, then remove itself) to initialize the EC2 AMI (Amazon Machine Instance) with a self-signed server SSL certificate. The script uses SelfSSL.exe from the IIS 6.0 resource kit. That tool turns out the be a god-send: creating a self-signed certificate is easy enough with makecert.exe, but the interfaces for automatically configuring IIS with proper SSL defaults aren’t well documented.
The script is part of the solution to another problem as well. Namely, once the new AMI is running, and a new SSL cert is installed, how do we download that cert so the client can trust it? There are probably a number of ways to do that, but a convenient one is to export the cert (the public part; not the private key) on the server (using certutil.exe), copy the cert file to a known location in the default web site, and let the client grab it via HTTP.
Interesting aside about getting what was originally a .cer file to be served by IIS. In short, I couldn’t get it to work (i.e., IIS acted like the file didn’t exist, even though you could see it in the virtual dir listing in the MMC snap-in), even after I realized that there was no registered MIME handler for that extension. But I noticed that there is a handler for .crt, which is equivalent to .cer from a PKI plumbing perspective. Using the .crt extension fixed things. Don’t know why I couldn’t get a .cer MIME handler to work.
In addition to the script, the Codeplex drop includes some fun code. The most important piece is a web service which will be configured to listen on a high port, require Windows authentication, and allow (maybe require; not sure yet) SSL. Clients that can authenticate to the service will be able to upload an MSI file and have it installed on the AMI.
In a nutshell, creating an AMI that automatically starts up with the script and secure web service is our EC2 bootstrapping story.
A few notes about that web service. First, since we can’t count on the Network Service account being able to install an MSI, the service end point routine starts by impersonating the caller. Then it reads in the encoded MSI file data, decodes it, writes it to a temporary file, runs msiexec.exe in silent mode, waits for the result, and returns it (after un-impersonating). Even though we’re impersonating and requiring valid credentials, a good enhancement would probably be to explicitly check that the caller is a member of the local administrators group.
In addition to the service, there’s a test client. I ran into two challenges with that. The first was that, since this code is checked in publicly, I didn’t want to hardcode the admin password for my local test server. And, lamely, .NET doesn’t include a built-in credential prompt dialog. Instead, you have to either write your own or P/Invoke CredUI. I chose the latter approach, but found a P/Invoke signature for CredUIPromptForCredentials on the web that had at least a couple of bugs, not the least of which that it didn’t explicitly specify whether it was using the Ansi or Unicode version of that Win32 API. I had the quickest luck getting the “A” version to work - shouldn’t matter unless you’ve got a user name or password with characters that don’t round-trip correctly (which would be truly brave).
One more comment about CredUIPromptForCredentialsA (or W). The user name and password parameters are actually “In” as well as “Out”. In other words, the API lets the caller pre-populate those fields. Thus, if the marshaller finds garbage in the input string buffers, you’ll see weird characters in the edit fields when the dialog pops up. This is another issue not addressed by P/Invoke wrappers you may find on the web. The fix is to start with a String of the proper length initialized to NULL chars (presumably just at the beginning, although I didn’t try that potential optimization), then build the in/out StringBuilder from that.
The second test client challenge was in figuring out how to get Visual Studio to let me add a web service reference to a console application. In other words, I didn’t want to have to run wsdl.exe myself! The trick was to run the web service project without debugging, so I could leave it running while adjusting the solution/project settings for the console application. Then, under the console project in Solution Explorer, right-click on References | Add service reference | Advanced | Add web reference.
Permalink | Comments (0)Location Platform sensor: lessons learned so far
March 16, 2009
In researching and developing the Laptop LoJack prototype (see blog thread and Codeplex page), I encountered a few gotchas. For posterity:
First, some kudos. The Windows 7 Location Platform sensor driver model uses the User Mode Driver Framework (UMDF). Like any technology, UMDF has a learning curve, and I wasn’t totally over it before I started this project (I’d experimented with some of it previously). That said, UMDF is one of the most important Windows technologies of the past several years: anything that doesn’t have to be in the kernel, shouldn’t be. That’s important for: reliability, security, and time-to-market for IHVs and ISVs who may now be able to avoid the extra cost of kernel-mode development.
The Win 7 Beta DDK (which I believe is unfortunately only available to premium MSDN subscribers right now) includes a sample sensor driver. The second kudos goes to the Microsoft location platform team for the documentation that they included with that driver code, specifically on how to customize it (i.e., how to take the sample and turn it into something real). If every product team at Microsoft included that kind of documentation with their samples (assuming they actually provide those, of course) the company’s dominance would be assured for many years to come …
Second point: as I described in the previous post on this topic, I customized the sample sensor to turn it into the IP geocoding sensor required for Laptop LoJack. I then used the devcon.exe tool (from the DDK, but looks like you can download it separately too) to install the driver. First mistake: I didn’t realize that the WDF helper dlls (e.g., WdfCoInstaller01009.dll), from the DDK redist sub-directory, were required in order for the installation to succeed. Frankly, the error message from devcon.exe is useless. Second mistake: I grabbed the wrong WDF dlls, thinking that I wanted the *_chk versions, since I was installing chk driver binaries.
You can avoid both of those mistakes by noticing which install helper binaries are referenced by the driver INF produced by build.exe.
Third point: Inf2Cat.exe is another useful DDK tool. If your building a driver (even UMDF) that’s going to actually be deployed somewhere, then you should be signing it to avoid the nasty prompt. But building your own CAT file is a pain, which is why Inf2Cat.exe is quite useful. However, remember that the CAT file needs to reference all of the files that are referenced by the INF. Thus, like devcon.exe, Inf2Cat.exe also needs to be able to find the WDF helper dlls. A build script would be the way to go here: copy the necessary files to a temporary location in order to build the CAT, then clean up duplicate files.
Fifth point: once the sensor driver is installed, it needs to be enabled via the Location Platform control panel applet. You can find that by typing “location” into the search field on the Start menu. The Laptop LoJack scenario would actually call for this sensor to be enabled by default, since it’s expected to be a managed laptop and the user shouldn’t be able to disable the sensor in this case. Hopefully, this is just a regkey that we can set via the installer. In fact, there’s a second problem here, which is that, even after the sensor is enabled, there’s a separate prompt asking the user for permission to expose data from that sensor. That strikes me as overkill, even for an un-managed deployment scenario. Again, hopefully there’s a registry override.
Sixth point: once I got this far, my driver still wouldn’t load with the test program (included with Laptop LoJack code; it’s just an adaptation of a Location Platform sample included with the SDK). I had an easy guess why, though. I had disabled these two “GPS sensor type” location properties,
SENSOR_DATA_TYPE_ALTITUDE_SEALEVEL_METERS
SENSOR_DATA_TYPE_ERROR_RADIUS_METERS
since I only have data for latitude and longitude. Turns out those are required. I re-enabled them, and just return hard-coded values for now, and the driver works fine. A better way to handle that? A future version of the driver could take the returned lat & long values and look-up the altitude for that location. Error radius is still problematic, though, since as I mentioned in a previous post, IP geolocation is really a best-guess with regional granularity. I’m guessing it could be off by several hundred miles, unless you live in a city in the northern hemisphere.
Seventh point: I mentioned one potential improvement above in doing a reverse look-up on your altitude. Additional potential improvements:
- The current IP geocoding web-lookup code, since it screen-scrapes Live maps, is fragile. Maybe someone has a better idea. However, what it currently does is convenient for two reasons. (A) we don’t have to do a separate “what’s my public IP address” look-up, since that’s implicit. And (B), the string matching logic for the Live page is pretty simple, even in native C. Still, I’d love to improve on this.
- There’s currently no caching of latitude and longitude data. That’s partly because the sensor driver makes separate queries for those two items, and I’m not yet confident enough in my knowledge of the UMDF sensor architecture to make a caching recommendation. However, because the relevance of the data is really just city to city, as previously stated, caching the data for an hour or more should be fine (even if you’re in a jet!).
The Laptop LoJack sample will be hosted on Codeplex, here. Actually, I’m having problems connecting to their TFS server this morning, so the initial code will be available later in the day.
What does the sample do? It currently consists of two components. The first is a Windows 7 location sensor driver (based on the User-Mode Driver Framework - no kernel-mode code here). The driver uses your public IP address to determine latitude and longitude coordinates.
What does that mean? It means that this project turns your laptop into a GPS, without having to buy an actual GPS - pretty cool! Not only that, but the GPS capability is exposed in the new “proper, platform-compliant” way, so that any Win 7 applications that are location-aware can use it.
Big disclaimer, though: unless you live in a major city, the granularity is regional at best. Why is that? The trick I use to obtain the coordinates is simple: local search on Microsoft Live Maps. That is, when you connect to the default URL for Live Maps, the returned page includes script goop that supports local search. That goop includes default lat & long for wherever the server thinks you are, based on your IP address. (As an aside, there’s another clue that the server is doing a reverse look-up on you, even before you run an actual search: when the default map loads, notice how it’s centered on your region!)
That process of mapping an IP address to a physical location, known as IP geocoding, is imprecise. In fact, it’s only the big technology providers like Google/Microsoft/Yahoo that can afford to maintain the most up-to-date IP geocoding databases; their incentive to do so is competition for search traffic. Once the Laptop LoJack code is live, I’m hoping to get additional user feedback on how accurate your location data is.
So, the sensor driver for Laptop LoJack is screen-scraping its coordinates from Live Maps. This is not an ideal implementation. For example, if Live changes the names, or even just whitespacing, in the script embedded in that default page, the screen-scraping code will break. Plus, since the sensor is UMDF, I really didn’t want to use the .NET framework in-proc, even though loading and robustly parsing the page might be easier that way in the long run (instead, I used WinHttp and some of the string library routines in the CRT).
That said, the code works, and the concept is cool. Next steps? We need to design and implement a cool (WPF-based) viewer application for the location data. We also need to provide a (WiX-based) MSI for this, because installing the UMDF driver by hand is painful. Stay tuned …
Permalink | Comments (1)WM devs: don’t miss the Security Configuration Manager
March 12, 2009
For developers writing applications for, or porting applications to, Windows Mobile - be sure to install the Security Configuration Manager from the tools\security subdirectory of the WM SDK (under Program Files).
It’s a Win32 application that connects to a docked phone and allows you to manage security-related settings such as RAPI policy and trusted certificates.
Regarding the latter - trusted certificates - don’t be surprised, as I was, when your expensive VeriSign codesigning certificate isn’t trusted on WM. Check out the Mobile2Market program to understand why (not saying I agree with it, but there it is).
Permalink | Comments (0)A new sample code project idea has been proposed as part of this series. In summary, the idea is to create a client agent for laptops that periodically phones home with its geographical location. There’d also be management application for viewing the client data, ideally a map showing flags representing each machine.
The client data would be obtained using the Windows 7 Location Platform API. Of course, given that hardly any laptops come equipped with a GPS, we need to write a plug-in that produces that data some other way in order to make the sample more generally accessible. The current proposal is to do this by calling out to one of the various websites that will map the client’s IP address to a geographical region and return a default latitude and longitude for that region.
While I think that would make for a pretty cool sample, there are a couple of drawbacks. First, this being a Windows client demo, the management application needs to be some really sexy WPF. So we need to not spend too much of our budget on the agent and the location sensor plug-in.
Second, I haven’t been able track down a reliable source of IP geocoding that’s packaged as a convenient web interface. Instead, we’d have to screen scrape it, which makes the demo fragile and could shorten its shelf life.
Feedback would be welcome here. Would this make a cool sample despite the potential drawbacks? Is there a better approach?
Permalink | Comments (0)