Windows Mobile 5.0 Local Authentication Sub System (LASS) - Part 2

In Part 1 we looked at the power-on-password replacement options for Windows Mobile 2003. In this blog I want to take you through the new Local Authentication Sub System (LASS).

 

This new architecture can be found in Windows CE 5.0 and Windows Mobile 5.0 devices and brings a uniform authentication system to both Smartphone and Pocket PC - prior to Windows Mobile 5.0 it was not possible to replace the PIN lock screen for Smartphone, but with the unified LASS architecture found on both Pocket PC and Smartphone its now (although I haven’t proved it with code yet J) possible.

 

The MSDN docs for LASS are here.

Architechture

The LASS architecture looks a bit like this:

 

 

 

Taking each of the key components:

LASS:

This is the system module responsible for joining user applications to a specific authentication plug-in. It doesn’t provide any authentication stuff in its own right but relies on the LAP to do the work of capturing and verifying credentials. The LASS module exposes a number of API’s:

 

LASSReloadConfig

Causes the LASS module to reload registry information.

CreateEnrollmentConfigDialog

Call’s to this API are forwarded to the active LAP to display the enrolment dialog. If you click the Password applet in settings on Pocket PC 2005 this API is called.

VerifyUser

Call’s to this API are forwarded to the active LAP to capture and verify the user credential.

 

Header file: lass.h

Lib: coredll.lib

 

LAP:

This module is responsible for capturing and verifying user credentials, either by displaying a form for input or integrating with hardware. A custom LAP must export the following methods:

LAPCreateEnrollmentConfigDialog

Display and capture initialization information – replacement for password control panel app.

VerifyUser

Called to capture and verify credentials.

InitLAP

Called when the LAP is loaded.

DeinitLAP

Called when the LAP is unloaded

 

The following are optional exports:

VerifyUserStart

Called before verification takes place – can be used to spin up hardware that might be used during the verification process.

VerifyUserStop

Called after verification has completed – use it to close down hardware ect.

VerifyUserToTop

Move the credentials capture to top in the Z-order (I’ve never seen this called on my LAP).

Authentication Events:

These are registry entries identified with a GUID that define certain parameters about how to verify the user through a LAP. For example if the user only needs to enter a password when the device has been unused for a certain period of time.

Values that can be set:

AEFrequencyValue

AEFrequencyType

DisplayText

 

How it all fits together:

Let’s start with power on. When a password has been configured the shell will check the registry to see which LAP dll is set as active and load the DLL. First InitLAP is called, then VerifyUserStart (if available) and then VerifyUser. The LAP is handed an AE GUID, a tile and a number of options. Based on the options and the AE settings the LAP will then capture and validate the user before returning success or failure. If authentication is successful VerifyUserStop is called, otherwise the LASS will update the Lockout registry information and rerun the LAP appropriately.

 

The shell still uses the old password registry settings [HKCU\ControlPanel\owner\PowrPass] to decide if authentication is required at power on, and desktop ActiveSync password protection operates in the same way as before using the password string stored in the OS.

 

Replacing the password control panel application is no longer necessary because the new CPL application simply calls the exported LAPCreateEnrollmentConfigDialog on the active LAP.

 

Replacing the Active LAP

It’s pretty straight forward although requires native code – you can’t do this in managed code. The one step that caught me out is the signing step: remember Windows Mobile 5.0 brings a one tier security model to Pocket PC, and part of that security means a trusted application can’t load an un-trusted DLL. The LASS components are running trusted so any LAP dll must be signed with a trusted cert.

 

Here are the basic steps for creating and registering a custom LAP:

  • Create a C++ DLL that exports at least LAPCreateEnrollmentConfigDialog, VerifyUser, InitLAP and DeinitLAP. Here is about the most basic one I could come up with .
  • Sign it with a cert derived from something that’s in privileged store on the device – the simplest way to do this is to select a cert in VS2005 signing tab and select ‘provision the device’
  • Deploy the dll to the windows directory
  • Update the registry of the device:
    • Create a new key [HKLM\Comm\Security\LASSD\LAP\<mylap>]
    • Create a string value under that key: dll=<name of LAP dll>.dll
    • Update the default LAP setting  [HKLM\Comm\Security\LASSD\LAP] ActiveLap=<mylap>
  • Soft reset the device

To test it’s all working go into Settings and select Password to see the LAP enroller display.

 

SimpleLAP

Here is the code for a very simple LAP I created for Pocket PC. You will need to have Visual Studio 2005 (standard or above) and Windows Mobile 5.0 Pocket PC SDK installed.

 

This C++ project includes a DEF file exporting the required API’s:

LIBRARY "SimpleLAP"

EXPORTS

      LAPCreateEnrollmentConfigDialog

      VerifyUser

      InitLAP

      DeinitLAP

 

The implementation of each is very simple:

BOOL InitLAP(

        InitLap* il

        )

{

   return TRUE;

}

void DeinitLAP()

{

    return;

}

BOOL VerifyUser(const GUID *AEKey,

                LPCWSTR pwszAEDisplayText,

                HWND hwndParent,

                DWORD dwOptions,

                PVOID pExtended)

{

      return DialogBoxParam( g_hInstance, MAKEINTRESOURCE(IDD_VERIFY_SQUARE), hwndParent,

            Verify_DlgProc, (LPARAM)false );

}

BOOL LAPCreateEnrollmentConfigDialog(HWND hwndParent,DWORD dwOptions)

{

      DialogBoxParam( g_hInstance, MAKEINTRESOURCE(IDD_ENROLE_SQUARE), hwndParent,

            Enrole_DlgProc, (LPARAM)false );

      return true;

}

 

Two dialogs are displayed, one for enrolment:

 

 

And one for password validation:

 

 

The interesting bits are in the dialog handler routines:

case IDC_ENABLE: // Enabling the password

{

// Is a password active? Check with OS

      if (GetPasswordActive())

      {

            // Password is set, change value

            // Now check the old password is OK with the system

            if (CheckPassword(OldPwd))

            {

                  // Change password values

                  if (!SetPassword( OldPwd, NewPwd))

                  {… error handling}

}

}

// Enable for the first time - set OS password

else

      {

            // Change password value to the new entry

            if (!SetPassword( NULL, NewPwd))

            {… error handling}

// Now make it active

            if (!SetPasswordActive( TRUE, NewPwd ))

            {… error handling}

// Now tell OS to use password on power up

            HKEY hkey;

      RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("ControlPanel\\Owner"), 0, 0, 0, 0, 0, &hkey, 0 );

            RegSetValueEx( hkey, TEXT("PowrPass"), 0, REG_BINARY, (CONST BYTE*)"\x01", 1 );

            RegCloseKey( hkey );

      }

}

break;

case IDC_DISSABLE: // Dissabling password

{

// Check the OLD password is correct

if (CheckPassword(ItemText))

{

      // Turn it off

      if (!SetPasswordActive(FALSE,ItemText))

            {… error handling}

// Change pwd value to null

if (!SetPassword(ItemText,NULL))

            {… error handling}

            HKEY hkey;

      // Dissable power-on dialog.

            RegCreateKeyEx( HKEY_CURRENT_USER, TEXT("ControlPanel\\Owner"), 0, 0, 0, 0, 0, &hkey, 0 );

RegSetValueEx( hkey, TEXT("PowrPass"), 0, REG_BINARY, (CONST BYTE*)"\x00", 1 );

      RegCloseKey( hkey );

      }

      EndDialog( hDlg, 1 );

}

 

Registering and Enabling a new LAP

I’ve been working with the emulator to build my LAP modules as its much easier to hard reset the emulator than a real device when it all goes horribly wrong (which has happened several times!). However the one thing the emulator is not quick at is a soft reset which is a complete pain when that’s what’s needed to update an active LAP.

 

The good news: there is another way. LASS supports an API LASSReloadConfig that causes the registry information to be reloaded and the active LAP to be unloaded and allow the dll to be updated. So I also built a test hardness to set up the reg key and call the reload api. It’s in C# and requires CF 2.0 to be on the device. Grab the project here.

 

The UI isn’t pretty but it gets the job done:

 

These are the important bits of code:

Three imports are used to interact with LASS:

[DllImport("coredll.dll")]

private static extern int LASSReloadConfig();

[DllImport("coredll.dll")]

private static extern int VerifyUser(IntPtr AEKey, string DisplayText, IntPtr ParentWindow, int Options, IntPtr Extended);

[DllImport("coredll.dll")]

private static extern int CreateEnrollmentConfigDialog(IntPtr ParentWindow);

Reload just calls the OS api:

private void Reload_Click(object sender, EventArgs e)

{

bool ok = (0!=LASSReloadConfig());

      MessageBox.Show("Reload " + (ok ? "Succeeded" : "Failed"));

}

Reg Clear sets the active LAP back to the default value (for the emulator) and deletes the key used for the custom LAP.

private void ClearReg_Click(object sender, EventArgs e)

{

// Clear the info from HKLM\Comm\Security\LASSD\LAP\ActiveLAP

Registry.SetValue(@"HKEY_LOCAL_MACHINE\comm\Security\LASSD\LAP", "ActiveLAP", "lap_pw");

Registry.LocalMachine.DeleteSubKey(@"Comm\Security\LASSD\LAP\" + DLLName.Text);

}

Set Reg creates the new LAP sub key and sets the active lap to point at it.

private void SetReg_Click(object sender, EventArgs e)

{

Registry.LocalMachine.CreateSubKey(@"Comm\Security\LASSD\LAP\" + DLLName.Text);

Registry.SetValue(@"HKEY_LOCAL_MACHINE\comm\Security\LASSD\LAP\" + DLLName.Text, "Dll", DLLName.Text +".dll");

Registry.SetValue(@"HKEY_LOCAL_MACHINE\comm\Security\LASSD\LAP", "ActiveLAP", DLLName.Text);

}

Verify calls through to the LASS and requests validation from the active LAP

private void CallVerify_Click(object sender, EventArgs e)

{

VerifyUser(IntPtr.Zero, "Called from tool", this.Handle, 0, IntPtr.Zero);

}

Enrole calls through to the active LAP and shows the enrolement dialog.

private void CallEnrole_Click(object sender, EventArgs e)

{

CreateEnrollmentConfigDialog(this.Handle);

}

I think that’s probably enough for this post. In part 3 we will look at porting the LetMeIn SDK sample from Windows Mobile 2003 to WM5.0

Marcus