Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e73c0ee authored by Chad Brubaker's avatar Chad Brubaker
Browse files

Make application/client id an object

Having it as a raw byte[] caused issues in keystore because keymaster
handles a null blob differently than a blob with null contents. Make
this explicit in the API.

Change-Id: Ifcf550f438608b8f09fc589d00d06fffa6ee463b
parent 38fcaf40
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.security;
import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterBlob;
import android.security.keymaster.OperationResult;
import android.security.KeystoreArguments;

@@ -61,11 +62,12 @@ interface IKeystoreService {
    int addRngEntropy(in byte[] data);
    int generateKey(String alias, in KeymasterArguments arguments, int uid, int flags,
        out KeyCharacteristics characteristics);
    int getKeyCharacteristics(String alias, in byte[] clientId,
        in byte[] appId, out KeyCharacteristics characteristics);
    int getKeyCharacteristics(String alias, in KeymasterBlob clientId, in KeymasterBlob appId,
        out KeyCharacteristics characteristics);
    int importKey(String alias, in KeymasterArguments arguments, int format,
        in byte[] keyData, int uid, int flags, out KeyCharacteristics characteristics);
    ExportResult exportKey(String alias, int format, in byte[] clientId, in byte[] appId);
    ExportResult exportKey(String alias, int format, in KeymasterBlob clientId,
        in KeymasterBlob appId);
    OperationResult begin(IBinder appToken, String alias, int purpose, boolean pruneable,
        in KeymasterArguments params, out KeymasterArguments operationParams);
    OperationResult update(IBinder token, in KeymasterArguments params, in byte[] input);
+20 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2015, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.security.keymaster;

/* @hide */
parcelable KeymasterBlob;
+55 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2015, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.security.keymaster;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * @hide
 */
public class KeymasterBlob implements Parcelable {
    public byte[] blob;

    public KeymasterBlob(byte[] blob) {
        this.blob = blob;
    }
    public static final Parcelable.Creator<KeymasterBlob> CREATOR = new
            Parcelable.Creator<KeymasterBlob>() {
                public KeymasterBlob createFromParcel(Parcel in) {
                    return new KeymasterBlob(in);
                }

                public KeymasterBlob[] newArray(int length) {
                    return new KeymasterBlob[length];
                }
            };

    protected KeymasterBlob(Parcel in) {
        blob = in.createByteArray();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeByteArray(blob);
    }
}
+4 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.os.ServiceManager;
import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterBlob;
import android.security.keymaster.OperationResult;
import android.util.Log;

@@ -403,7 +404,7 @@ public class KeyStore {
        return generateKey(alias, args, UID_SELF, flags, outCharacteristics);
    }

    public int getKeyCharacteristics(String alias, byte[] clientId, byte[] appId,
    public int getKeyCharacteristics(String alias, KeymasterBlob clientId, KeymasterBlob appId,
            KeyCharacteristics outCharacteristics) {
        try {
            return mBinder.getKeyCharacteristics(alias, clientId, appId, outCharacteristics);
@@ -429,7 +430,8 @@ public class KeyStore {
        return importKey(alias, args, format, keyData, UID_SELF, flags, outCharacteristics);
    }

    public ExportResult exportKey(String alias, int format, byte[] clientId, byte[] appId) {
    public ExportResult exportKey(String alias, int format, KeymasterBlob clientId,
            KeymasterBlob appId) {
        try {
            return mBinder.exportKey(alias, format, clientId, appId);
        } catch (RemoteException e) {
+4 −13
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.security.KeyStore;
import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterBlob;
import android.security.keymaster.KeymasterDefs;
import android.security.keymaster.OperationResult;
import android.test.ActivityUnitTestCase;
@@ -712,8 +713,6 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
        args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA);
        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, null);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_DATA, null);
        args.addBlob(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
                RSAKeyGenParameterSpec.F4.toByteArray());

@@ -744,6 +743,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {

    public void testAppId() throws Exception {
        String name = "test";
        byte[] id = new byte[] {0x01, 0x02, 0x03};
        KeymasterArguments args = new KeymasterArguments();
        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
        args.addInt(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
@@ -751,8 +751,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
        args.addInt(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
        args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, 2048);
        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_ECB);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, new byte[] {0x01, 0x02, 0x03});
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_DATA, null);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, id);
        args.addBlob(KeymasterDefs.KM_TAG_RSA_PUBLIC_EXPONENT,
                RSAKeyGenParameterSpec.F4.toByteArray());

@@ -764,7 +763,7 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
                mKeyStore.getKeyCharacteristics(name, null, null, outCharacteristics));
        assertEquals("getKeyCharacteristics should succeed with application ID",
                KeyStore.NO_ERROR,
                mKeyStore.getKeyCharacteristics(name, new byte[] {0x01, 0x02, 0x03}, null,
                mKeyStore.getKeyCharacteristics(name, new KeymasterBlob(id), null,
                    outCharacteristics));
    }

@@ -789,8 +788,6 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_OCB);
        args.addInt(KeymasterDefs.KM_TAG_CHUNK_LENGTH, 4096);
        args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 16);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, null);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_DATA, null);

        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
        int rc = mKeyStore.generateKey(name, args, 0, outCharacteristics);
@@ -798,8 +795,6 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {

        KeymasterArguments out = new KeymasterArguments();
        args = new KeymasterArguments();
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, null);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_DATA, null);
        OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
                true, args, out);
        IBinder token = result.token;
@@ -888,8 +883,6 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
        args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, KeymasterDefs.KM_MODE_OCB);
        args.addInt(KeymasterDefs.KM_TAG_CHUNK_LENGTH, 4096);
        args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, 16);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, null);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_DATA, null);

        KeyCharacteristics outCharacteristics = new KeyCharacteristics();
        int rc = mKeyStore.generateKey(name, args, 0, outCharacteristics);
@@ -897,8 +890,6 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {

        KeymasterArguments out = new KeymasterArguments();
        args = new KeymasterArguments();
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_ID, null);
        args.addBlob(KeymasterDefs.KM_TAG_APPLICATION_DATA, null);
        OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
                true, args, out);
        assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);