Add provisioner CLI and its interface.
Change-Id: If7682c037232844568ba88a0ed38e26924e1c10e
This commit is contained in:
parent
26668f5bc2
commit
ba42dac790
4 changed files with 233 additions and 0 deletions
44
provisioner/Android.bp
Normal file
44
provisioner/Android.bp
Normal file
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// Copyright (C) 2020 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.
|
||||
//
|
||||
|
||||
aidl_interface {
|
||||
name: "android.security.provisioner",
|
||||
unstable: true,
|
||||
local_include_dir: "binder",
|
||||
srcs: [
|
||||
"binder/android/security/provisioner/*.aidl",
|
||||
],
|
||||
backend: {
|
||||
java: {
|
||||
platform_apis: true,
|
||||
},
|
||||
cpp: {
|
||||
enabled: false,
|
||||
},
|
||||
ndk: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
java_binary {
|
||||
name: "provisioner_cli",
|
||||
wrapper: "provisioner_cli",
|
||||
srcs: ["src/com/android/commands/provisioner/**/*.java"],
|
||||
static_libs: [
|
||||
"android.security.provisioner-java",
|
||||
],
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* Copyright (c) 2020, 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.provisioner;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
interface IProvisionerService {
|
||||
byte[] getCertificateRequest(in boolean testMode,
|
||||
in int keyCount,
|
||||
in byte[] endpointEncryptionKey,
|
||||
in byte[] challenge) = 0;
|
||||
}
|
21
provisioner/provisioner_cli
Executable file
21
provisioner/provisioner_cli
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/system/bin/sh
|
||||
#
|
||||
# Copyright (C) 2020 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.
|
||||
#
|
||||
# Script to start "provisioner_cli" on the device.
|
||||
#
|
||||
base=/system
|
||||
export CLASSPATH=$base/framework/provisioner_cli.jar
|
||||
exec app_process $base/bin com.android.commands.provisioner.Cli "$@"
|
141
provisioner/src/com/android/commands/provisioner/Cli.java
Normal file
141
provisioner/src/com/android/commands/provisioner/Cli.java
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright 2020 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 com.android.commands.provisioner;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.security.provisioner.IProvisionerService;
|
||||
|
||||
import com.android.internal.os.BaseCommand;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Contains the implementation of the remote provisioning command-line interface.
|
||||
*/
|
||||
public class Cli extends BaseCommand {
|
||||
/**
|
||||
* Creates an instance of the command-line interface and runs it. This is the entry point of
|
||||
* the tool.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
new Cli().run(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command requested by the invoker. It parses the very first required argument, which
|
||||
* is the command, and calls the appropriate handler.
|
||||
*/
|
||||
@Override
|
||||
public void onRun() throws Exception {
|
||||
String cmd = nextArgRequired();
|
||||
switch (cmd) {
|
||||
case "get-req":
|
||||
getRequest();
|
||||
break;
|
||||
|
||||
case "help":
|
||||
onShowUsage(System.out);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown command: " + cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a 'certificate request' from the provisioning service. The COSE-encoded
|
||||
* 'certificate chain' describing the endpoint encryption key (EEK) to use for encryption is
|
||||
* read from the standard input. The retrieved request is written to the standard output.
|
||||
*/
|
||||
private void getRequest() throws Exception {
|
||||
// Process options.
|
||||
boolean test = false;
|
||||
byte[] challenge = null;
|
||||
int count = 0;
|
||||
String arg;
|
||||
while ((arg = nextArg()) != null) {
|
||||
switch (arg) {
|
||||
case "--test":
|
||||
test = true;
|
||||
break;
|
||||
|
||||
case "--challenge":
|
||||
// TODO: We may need a different encoding of the challenge.
|
||||
challenge = nextArgRequired().getBytes();
|
||||
break;
|
||||
|
||||
case "--count":
|
||||
count = Integer.parseInt(nextArgRequired());
|
||||
if (count < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"--count must be followed by non-negative number");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown argument: " + arg);
|
||||
}
|
||||
}
|
||||
|
||||
// Send the request over to the provisioning service and write the result to stdout.
|
||||
byte[] res = getService().getCertificateRequest(test, count, readAll(System.in), challenge);
|
||||
if (res != null) {
|
||||
System.out.write(res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an implementation of the IProvisionerService interface. It allows the caller to
|
||||
* call into the service via binder.
|
||||
*/
|
||||
private static IProvisionerService getService() throws RemoteException {
|
||||
IBinder binder = ServiceManager.getService("remote-provisioner");
|
||||
if (binder == null) {
|
||||
throw new RemoteException("Provisioning service is inaccessible");
|
||||
}
|
||||
return IProvisionerService.Stub.asInterface(binder);
|
||||
}
|
||||
|
||||
/** Reads all data from the provided input stream and returns it as a byte array. */
|
||||
private static byte[] readAll(InputStream in) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[1024];
|
||||
int read;
|
||||
while ((read = in.read(buf)) != -1) {
|
||||
out.write(buf, 0, read);
|
||||
}
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the usage information to the given stream. This is displayed to users of the tool when
|
||||
* they ask for help or when they pass incorrect arguments to the tool.
|
||||
*/
|
||||
@Override
|
||||
public void onShowUsage(PrintStream out) {
|
||||
out.println(
|
||||
"Usage: provisioner_cli <command> [options]\n" +
|
||||
"Commands: help\n" +
|
||||
" get-req [--count <n>] [--test] [--challenge <v>]");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue