Add sshauthentication-api v1 support

This commit is contained in:
Christian Hagau
2017-10-05 00:00:00 +00:00
parent 83ab483fc7
commit 2619cb1db3
57 changed files with 3954 additions and 79 deletions

View File

@@ -25,6 +25,7 @@ package org.sufficientlysecure.keychain.ui;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Map;
import android.content.Intent;
import android.os.AsyncTask;
@@ -63,6 +64,8 @@ import org.sufficientlysecure.keychain.util.Passphrase;
*/
public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
public static final String TAG = "SecurityTokenOperationActivity";
public static final String EXTRA_REQUIRED_INPUT = "required_input";
public static final String EXTRA_CRYPTO_INPUT = "crypto_input";
@@ -233,6 +236,24 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenActivity {
}
break;
}
case SECURITY_TOKEN_AUTH: {
long tokenKeyId = KeyFormattingUtils.getKeyIdFromFingerprint(
stConnection.getKeyFingerprint(KeyType.AUTH));
if (tokenKeyId != mRequiredInput.getSubKeyId()) {
throw new IOException(getString(R.string.error_wrong_security_token));
}
for (int i = 0; i < mRequiredInput.mInputData.length; i++) {
byte[] hash = mRequiredInput.mInputData[i];
int algo = mRequiredInput.mSignAlgos[i];
byte[] signedHash = stConnection.calculateAuthenticationSignature(hash, algo);
mInputParcel = mInputParcel.withCryptoData(hash, signedHash);
}
break;
}
case SECURITY_TOKEN_MOVE_KEY_TO_CARD: {
Passphrase adminPin = new Passphrase("12345678");

View File

@@ -18,11 +18,6 @@
package org.sufficientlysecure.keychain.ui;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.ClipData;
@@ -50,13 +45,15 @@ import android.view.animation.AlphaAnimation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import org.openintents.openpgp.util.OpenPgpUtils;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.SshPublicKey;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeyRepository;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.TemporaryFileProvider;
@@ -68,6 +65,11 @@ import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.ui.util.QrCodeUtils;
import org.sufficientlysecure.keychain.util.Log;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class ViewKeyAdvShareFragment extends LoaderFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
@@ -133,6 +135,8 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
View vKeyShareButton = view.findViewById(R.id.view_key_action_key_share);
View vKeyClipboardButton = view.findViewById(R.id.view_key_action_key_clipboard);
ImageButton vKeySafeSlingerButton = (ImageButton) view.findViewById(R.id.view_key_action_key_safeslinger);
View vKeySshShareButton = view.findViewById(R.id.view_key_action_key_ssh_share);
View vKeySshClipboardButton = view.findViewById(R.id.view_key_action_key_ssh_clipboard);
View vKeyUploadButton = view.findViewById(R.id.view_key_action_upload);
vKeySafeSlingerButton.setColorFilter(FormattingUtils.getColorFromAttr(getActivity(), R.attr.colorTertiaryText),
PorterDuff.Mode.SRC_IN);
@@ -152,13 +156,13 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
vKeyShareButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareKey(false);
shareKey(false, false);
}
});
vKeyClipboardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareKey(true);
shareKey(true, false);
}
});
@@ -168,6 +172,18 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
startSafeSlinger(mDataUri);
}
});
vKeySshShareButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareKey(false, true);
}
});
vKeySshClipboardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareKey(true, true);
}
});
vKeyUploadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -192,17 +208,52 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements
startActivityForResult(safeSlingerIntent, 0);
}
private void shareKey(boolean toClipboard) {
private boolean hasAuthenticationKey() {
KeyRepository keyRepository = KeyRepository.create(getContext());
long masterKeyId = Constants.key.none;
long authSubKeyId = Constants.key.none;
try {
masterKeyId = keyRepository.getCachedPublicKeyRing(mDataUri).extractOrGetMasterKeyId();
CachedPublicKeyRing cachedPublicKeyRing = keyRepository.getCachedPublicKeyRing(masterKeyId);
authSubKeyId = cachedPublicKeyRing.getSecretAuthenticationId();
} catch (PgpKeyNotFoundException e) {
Log.e(Constants.TAG, "key not found!", e);
}
return authSubKeyId != Constants.key.none;
}
private String getShareKeyContent(boolean asSshKey)
throws PgpKeyNotFoundException, KeyRepository.NotFoundException, IOException, PgpGeneralException {
KeyRepository keyRepository = KeyRepository.create(getContext());
String content;
long masterKeyId = keyRepository.getCachedPublicKeyRing(mDataUri).extractOrGetMasterKeyId();
if (asSshKey) {
long authSubKeyId = keyRepository.getCachedPublicKeyRing(masterKeyId).getSecretAuthenticationId();
CanonicalizedPublicKey publicKey = keyRepository.getCanonicalizedPublicKeyRing(masterKeyId)
.getPublicKey(authSubKeyId);
SshPublicKey sshPublicKey = new SshPublicKey(publicKey);
content = sshPublicKey.getEncodedKey();
} else {
content = keyRepository.getPublicKeyRingAsArmoredString(masterKeyId);
}
return content;
}
private void shareKey(boolean toClipboard, boolean asSshKey) {
Activity activity = getActivity();
if (activity == null || mFingerprint == null) {
return;
}
KeyRepository keyRepository =
KeyRepository.create(getContext());
if (asSshKey && !hasAuthenticationKey()) {
Notify.create(activity, R.string.authentication_subkey_not_found, Style.ERROR).show();
return;
}
try {
long masterKeyId = keyRepository.getCachedPublicKeyRing(mDataUri).extractOrGetMasterKeyId();
String content = keyRepository.getPublicKeyRingAsArmoredString(masterKeyId);
String content = getShareKeyContent(asSshKey);
if (toClipboard) {
ClipboardManager clipMan = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);

View File

@@ -78,6 +78,7 @@ public class AddSubkeyDialogFragment extends DialogFragment {
private RadioButton mUsageSign;
private RadioButton mUsageEncrypt;
private RadioButton mUsageSignAndEncrypt;
private RadioButton mUsageAuthentication;
private boolean mWillBeMasterKey;
@@ -121,6 +122,7 @@ public class AddSubkeyDialogFragment extends DialogFragment {
mUsageSign = (RadioButton) view.findViewById(R.id.add_subkey_usage_sign);
mUsageEncrypt = (RadioButton) view.findViewById(R.id.add_subkey_usage_encrypt);
mUsageSignAndEncrypt = (RadioButton) view.findViewById(R.id.add_subkey_usage_sign_and_encrypt);
mUsageAuthentication = (RadioButton) view.findViewById(R.id.add_subkey_usage_authentication);
if(mWillBeMasterKey) {
dialog.setTitle(R.string.title_change_master_key);
@@ -296,6 +298,8 @@ public class AddSubkeyDialogFragment extends DialogFragment {
flags |= KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
} else if (mUsageSignAndEncrypt.isChecked()) {
flags |= KeyFlags.SIGN_DATA | KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE;
} else if (mUsageAuthentication.isChecked()) {
flags |= KeyFlags.AUTHENTICATION;
}