blob: 00ec79199e80832bdf8ee33183f4efb94af392c6 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.android.v23.services.blessing;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import java.security.interfaces.ECPublicKey;
import io.v.android.v23.V;
import io.v.android.impl.google.services.blessing.BlessingActivity;
import io.v.v23.context.VContext;
/**
* Provides client methods for talking to the android
* {@link io.v.android.impl.google.services.blessing.BlessingActivity BlessingService}.
*/
public class BlessingService {
public static final String EXTRA_ERROR = "ERROR";
public static final String EXTRA_REPLY = "REPLY";
public static final String EXTRA_PUBLIC_KEY = "PUBLIC_KEY";
public static final String EXTRA_GOOGLE_ACCOUNT = "GOOGLE_ACCOUNT";
private static final String ACCOUNT_MANAGER_PACKAGE_NAME = "io.v.android.apps.account_manager";
/**
* Returns the intent used for obtaining a fresh set of credentials from the
* vanadium blessing service.
*
* @param ctx android context
* @param googleAccount google account name to use as the basis of the newly minted credentials
* (e.g., {@code myname@mymail.com}). If empty or {@code null}, user
* will be prompted to select one from the list of installed Google
* accounts
*/
public static Intent newBlessingIntent(Context ctx, String googleAccount) {
VContext vCtx = V.init(ctx);
ECPublicKey key = V.getPrincipal(vCtx).publicKey();
Intent intent = null;
if (isAccountManagerInstalled(ctx)) {
// Get blessings from the account manager installed on the device.
intent = new Intent();
intent.setComponent(new ComponentName(ACCOUNT_MANAGER_PACKAGE_NAME,
ACCOUNT_MANAGER_PACKAGE_NAME + ".LocalBlessingActivity"));
} else {
// Get blessings from the blessing service.
intent = new Intent(ctx, BlessingActivity.class);
intent.setAction("io.v.android.x.ref.services.blessing.BLESSING");
}
intent.putExtra(EXTRA_PUBLIC_KEY, key);
intent.putExtra(EXTRA_GOOGLE_ACCOUNT, googleAccount);
return intent;
}
/**
* Same as {@link #newBlessingIntent(Context, String)}, but without the explicit Google
* account name: the user will be prompted to select one from the list of installed Google
* accounts.
*
* @param ctx android context
*/
public static Intent newBlessingIntent(Context ctx) {
return newBlessingIntent(ctx, "");
}
/**
* Processes the reply from the vanadium blessing serves generated by the
* {@link #newBlessingIntent} intent, returning the credentials stored within.
*
* @param resultCode result code of the reply
* @param data reply data
* @return the credentials stored in the reply
* @throws BlessingCreationException if there was an error generating the credentials
*/
public static byte[] extractBlessingReply(int resultCode, Intent data)
throws BlessingCreationException {
if (data == null) {
throw new BlessingCreationException("NULL blessing response");
}
if (resultCode != Activity.RESULT_OK) {
throw new BlessingCreationException("Error getting blessing: " + data.getStringExtra(EXTRA_ERROR));
}
byte[] blessingsVom = data.getByteArrayExtra(EXTRA_REPLY);
if (blessingsVom == null || blessingsVom.length <= 0) {
throw new BlessingCreationException("Got null blessings.");
}
return blessingsVom;
}
private static boolean isAccountManagerInstalled(Context ctx) {
PackageManager pm = ctx.getPackageManager();
try {
pm.getPackageInfo(ACCOUNT_MANAGER_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
private BlessingService() {}
}