Archive for ‘Coding’

October 11, 2013

Service Manager

The Service Manager is like an information director. It is the Yellow Pages of all services available. It has a very close relationship with the Binder. In the Binder post you can see a picture with the Service Manager, and you can see that when an application wants to instantiate a service they first have to get a handler. That is, they have to ask the Service Manager for that handler, and they do it through the Binder.

It make sense then that the Service Manager is started before any other service. It is actually started by Init. At that time, the Service Manager request the Binder to be the “Binder Context Manager”, which is like to say I want to be the secretary of the boss. It does this through an ioctl() call. As we saw in the System Services the System Server will add all the spawn services to the Service Manager.

As you can imagine the Service Manager is not really visible by the developer, and most are unaware of it’s existence, but it is there to find your service. If Service Manager is the index to all the other System Service it makes sense that is tarted before any other. For that to happen there is only one place for this to happen, and that is in *init.rc*.  After it, follow Zygote, meda, surfaceflinger and drm. These are the first and most basic services started and they are natively implemented. The reason as we said in the first post, they have to be highly CPU efficient.

service servicemanager /system/bin/servicemanager class core user system group system critical
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm

You can see here ServiceManager.java, interface which implements the Java IServiceManager.java Interface. These are the method implemented at the Service Manager. You can find here IServiceManager.cpp the native code for this service, that is, the real service. It might look confusing. You should get familiar with Java Interfaces if you are not. It is very normal in Android. Each service has normally an Interface which is implemented in a class. The class can be the Java interface of a native service or a Java implemented service. Following you can see the Interface (you can not instantiate) of the ServiceManager to illustrate the methods implemented by the service.

public interface IServiceManager extends IInterface
{
/**
* Retrieve an existing service called @a name from the
* service manager.  Blocks for a few seconds waiting for it to be
* published if it does not already exist.
*/
public IBinder getService(String name) throws RemoteException;

/**
* Retrieve an existing service called @a name from the
* service manager.  Non-blocking.
*/
public IBinder checkService(String name) throws RemoteException;
/**
* Place a new @a service called @a name into the service
* manager.
*/
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException;
/**
* Return a list of all currently running services.
*/
public String[] listServices() throws RemoteException;
/**
* Assign a permission controller to the service manager.  After set, this
* interface is checked before any services are added.
*/
public void setPermissionController(IPermissionController controller)
throws RemoteException;

static final String descriptor = "android.os.IServiceManager";
int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;
int LIST_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+3;
int CHECK_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+4;
int SET_PERMISSION_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+5;
}
October 3, 2013

System Services

The System Services is a set of about 60-80 services that provide the user applications with the information and capabilities necessary to work. All these services relay on the Binder to communicate and collaborate with each other. Also, applications can instantiate these services through Binder. Most are written in Java except for a couple of them, which are written in C/C++. The reason is that those C/C++ services relay on hardware acceleration or are in need or a high performance implementation. A good example is the sensor service or the surface flinger. Other services like camera service or media player, make an extensive use of Native Code through JNI calls.

System Server

Among all the services we have to highlight one of them, the System Server. What does make so special to this guy? This guy is the ruler, I like to call it, the Darth Vader of the System. This service starts all the other services, but not only that, it also bootstraps the file infrastructure, with critical directories like /data/user. It creates each service and add it to the Service Manager. Most of those services are Java-built as you can see in the picture below. This services are JNI friendly 🙂 , so don’t be surprise to find JNI calls to Native code.

System Services

System Services (from Embedded Android)

If you want your android to boot faster, you only have to comment out some of those services. Also, you might want to substitute some of those services for your own implementation. If you want your own Wallpaper Service for example, you can modify the service itself or substitute the whole thing. Modify it would be easer, though. You can also make some Java service Native.

Following is a little snippet of actions that take place in System Server (SystemServer.java)

class ServerThread extends Thread {
    private static final String TAG = "SystemServer";
    private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
    private static final String ENCRYPTED_STATE = "1";

    ContentResolver mContentResolver;

    void reportWtf(String msg, Throwable e) {
        Slog.w(TAG, "***********************************************");
        Log.wtf(TAG, "BOOT FAILURE " + msg, e);
    }

    @Override
    public void run() {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
        SystemClock.uptimeMillis());

        Looper.prepareMainLooper();

        android.os.Process.setThreadPriority(
        android.os.Process.THREAD_PRIORITY_FOREGROUND);

...

        Slog.i(TAG, "Battery Service");
        battery = new BatteryService(context, lights);
        ServiceManager.addService("battery", battery);

        Slog.i(TAG, "Vibrator Service");
        vibrator = new VibratorService(context);
        ServiceManager.addService("vibrator", vibrator);

...

        Slog.i(TAG, "Window Manager");
        wm = WindowManagerService.main(context, power, display, inputManager, uiHandler, wmHandler,
                               factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                               !firstBoot, onlyCore);

        ServiceManager.addService(Context.WINDOW_SERVICE, wm);
        ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

        ActivityManagerService.self().setWindowManager(wm);

        inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
        inputManager.start();

        display.setWindowManager(wm);
        display.setInputManager(inputManager);

...

I will not talk about Media Service by now, that requires an extensive posts and I don’t want to make this too heavy.
Next day we will talk about the Services Manager.

October 1, 2013

Android root Certificates Management

This post is not about root certificates. It is not analyzing the different formats of security certificates neither how to generate those.

This post is about how Android deals with security certificates and how to change it to make it more secure. Android v4.1+

There are mainly two source files you want to check to understand this better (NativeCrypto.java and TrustedCertificateStore.java). This is all part of the Apache Harmony for Android Open Source Project.

Android, as any other mobile operating system has a CA root security certificates store that uses to validate the identity of remote peers. It is the same way as an internet browsers does. There is a directory (/etc/security/cacerts), where Android stores the root certificates. This is called the Certificates Store. When an application contacts a remote server, this sends it’s identity to the Android device. Then Android validates it or rejects it based on the trusted certificates stored in the Certificates Store.

Root Certificates are formatted in PEM. They include also the human readable version of it. The way Android name these certificates is by using an MD5 hash, based on the unique subject name field of the certificate. This means that the name of the file for the certificate with Subject field equals to “C=US, O=GeoTrust Inc., CN=GeoTrust Global CA” is 7999be0d.0

As we can see in the next code from TrustedCertificateStore.java, the search method will first request the MD5 hash and then will perform the search on the Certificates Store.


private String hash(X500Principal name) {
    int hash = NativeCrypto.X509_NAME_hash_old(name);
    return IntegralToString.intToHexString(hash, false, 8);
}

How to make this more safe

There are some things you can do if you want your Android to be more safe. And there are reasons for this.

MD5 hash algorithm is broken. It is surprising that Google still uses this MD5 hash algorithm. This is something that is totally broken and nobody should use it anymore. Apache Harmony provides another method to calculate the SHA1 instead of MD5.  To do this:

  1. Use NativeCrypto.X509_NAME_hash(name); instead of NativeCrypto.X509_NAME_hash_old(name);
  2. Rename all your certificates to use a SHA1 based name. Watch out here if you use openssl to do this. Openssl generates a different SHA1 hash than the Apache Harmony framework. Why? Apache Harmony bases the MD5 and SHA1 hash in the Subject name of the certificate. Before computing the hash, it transform that subject string into a ASN1 DER format. This is done for both MD5 and SHA1 and is pretty standard across different frameworks.

The openssl command line tool does not behaves like that. Encryption is like money laundry, the more hands you can pass the money through, the harder in theory to track it back to the originator. Openssl folks correctly believed that SHA1 was not safe enough so they decided to pass it through one more filter. It first calculates the CANONICAL format of the string. Then you take that String and generate the ASN1 DER format of it. Then it passes the encoded string to the SHA1 algorithm to calculate the digest. Yeap, pretty nasty. I believed that openssl.1.0.1e libraries already include all these changes. But if you are using older ones you will have to modify them to be able to programmatically calculate the SHA1 of a certificate. You can read a little bit more about how to do this in this thread from the openssl mailing list

I hope that eventually, better sooner than later, Google decides to go for at least SHA1. At this point SHA1 is no safe either but hey, it’s better than MD5.