前段时间一直在忙高通项目的需求,同事转给我一个证书安装的bug给我,一直没时间解,给Marvell提case,个把月了还不给回复,囧!求人不如求己正好最近需求做完了,索性就自己跟下代码。
证书安装入口在设置-->安全里,相应代码如下:
android:title="@string/credentials_install"
android:summary="@string/credentials_install_summary"
android:persistent="false">
android:targetPackage=""
android:targetClass=""/>
当我们点击“从存储设备安装证书”时,就会通过intent进入CertInstallerMain。在onCreate里对相应action做处理
if (Credentials.INSTALL_ACTION.equals(action)
|| Credentials.INSTALL_AS_USER_ACTION.equals(action)) {
Bundle bundle = ();//这里获取的bundle为空。
由于bundle未空会执行如下代码:
if (bundle == null
|| ()
|| (() == 1
&& ((KeyChain.EXTRA_NAME)
|| (Credentials.EXTRA_INSTALL_AS_UID)))) {
final Intent openIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
("*/*");
(Intent.EXTRA_MIME_TYPES, ACCEPT_MIME_TYPES);
(DocumentsContract.EXTRA_SHOW_ADVANCED, true);
startActivityForResult(openIntent, REQUEST_OPEN_DOCUMENT);
这里就会弹出一个类似文件管理的界面,选择相应的证书后会自动安装证书。
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_OPEN_DOCUMENT) {
if (resultCode == RESULT_OK) {
startInstallActivity(null, ());
} else {
finish();
}
} else if (requestCode == REQUEST_INSTALL) {
setResult(resultCode);
finish();
} else {
(TAG, "unknown request code: " + requestCode);
}
}
private void startInstallActivity(String mimeType, byte[] value) {
Intent intent = new Intent(this, );
if ("application/x-pkcs12".equals(mimeType)) {
(KeyChain.EXTRA_PKCS12, value);
} else if ("application/x-x509-ca-cert".equals(mimeType)
|| "application/x-x509-user-cert".equals(mimeType)
|| "application/x-x509-server-cert".equals(mimeType)
|| "application/x-pem-file".equals(mimeType)
|| "application/pkix-cert".equals(mimeType)) {
(KeyChain.EXTRA_CERTIFICATE, value);
} else {
throw new IllegalArgumentException("Unknown MIME type: " + mimeType);
}
startActivityForResult(intent, REQUEST_INSTALL);
}
进入CertInstaller后,如果没有设置设置锁屏会先提示设置锁屏
protected void onCreate(Bundle savedStates) {
(savedStates);
mCredentials = createCredentialHelper(getIntent());
mState = (savedStates == null) ? STATE_INIT : STATE_RUNNING;
if (mState == STATE_INIT) {
if (!()) {
toastErrorAndFinish(.no_cert_to_saved);
finish();
} else if (mCredentials.hasPkcs12KeyStore()) {
showDialog(PKCS12_PASSWORD_DIALOG);
} else {
MyAction action = new InstallOthersAction();
if (needsKeyStoreAccess()) {
sendUnlockKeyStoreIntent();
mNextAction = action;
} else {
(this);
}
}
设置完成后在进行证书安装
protected void onResume() {
();
if (mState == STATE_INIT) {
mState = STATE_RUNNING;
} else {
if (mNextAction != null) {
(this);
}
}
}
最终会调用installOthers()方法
if (()) { saveKeyPair(); finish(); } else { X509Certificate cert = (); if (cert != null) { // find matched private key /* modify by yangzhiming 20150803 for bug 60294 start */ String key = null; try{ key = Util.toMd5(().getEncoded()); }catch (RuntimeException ex) { toastErrorAndFinish(.invalid_cert); return; } /* modify by yangzhiming 20150803 for bug 60294 end */ Map map = getPkeyMap(); byte[] privatekey = (key); if (privatekey != null) { (TAG, "found matched key: " + privatekey); (key); savePkeyMap(map); (privatekey); } else { (TAG, "didn't find matched private key: " + key); } } nameCredential(); } CA证书安装的大致流程就是这样了。