more data in RequiredInputParcel, OperationResult notifications

- pass both masterkeyid and subkeyid though RequiredInputParcel parcel
- fix numeric vales in OperationResult.createNotify()
This commit is contained in:
Vincent Breitmoser 2015-03-21 15:16:32 +01:00
parent 88ca41d555
commit 93c7eb72fb
7 changed files with 110 additions and 36 deletions

View File

@ -81,7 +81,7 @@ public class CertifyOperation extends BaseOperation {
if (!cryptoInput.hasPassphrase()) {
return new CertifyResult(log, RequiredInputParcel.createRequiredPassphrase(
certificationKey.getKeyId(), null));
certificationKey.getKeyId(), certificationKey.getKeyId(), null));
}
// certification is always with the master key id, so use that one
@ -105,7 +105,9 @@ public class CertifyOperation extends BaseOperation {
int certifyOk = 0, certifyError = 0, uploadOk = 0, uploadError = 0;
NfcSignOperationsBuilder allRequiredInput = new NfcSignOperationsBuilder(cryptoInput.getSignatureTime());
NfcSignOperationsBuilder allRequiredInput = new NfcSignOperationsBuilder(
cryptoInput.getSignatureTime(), certificationKey.getKeyId(),
certificationKey.getKeyId());
// Work through all requested certifications
for (CertifyAction action : parcel.mCertifyActions) {

View File

@ -31,13 +31,18 @@ public class EditKeyResult extends OperationResult {
public EditKeyResult(Parcel source) {
super(source);
mMasterKeyId = source.readLong();
mMasterKeyId = source.readInt() != 0 ? source.readLong() : null;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
if (mMasterKeyId != null) {
dest.writeInt(1);
dest.writeLong(mMasterKeyId);
} else {
dest.writeInt(0);
}
}
public static Creator<EditKeyResult> CREATOR = new Creator<EditKeyResult>() {

View File

@ -250,12 +250,20 @@ public abstract class OperationResult implements Parcelable {
public Showable createNotify(final Activity activity) {
Log.d(Constants.TAG, "mLog.getLast()"+mLog.getLast());
Log.d(Constants.TAG, "mLog.getLast().mType"+mLog.getLast().mType);
Log.d(Constants.TAG, "mLog.getLast().mType.getMsgId()"+mLog.getLast().mType.getMsgId());
// Take the last message as string
int msgId = mLog.getLast().mType.getMsgId();
String logText;
LogEntryParcel entryParcel = mLog.getLast();
// special case: first parameter may be a quantity
if (entryParcel.mParameters != null && entryParcel.mParameters.length > 0
&& entryParcel.mParameters[0] instanceof Integer) {
logText = activity.getResources().getQuantityString(entryParcel.mType.getMsgId(),
(Integer) entryParcel.mParameters[0],
entryParcel.mParameters);
} else {
logText = activity.getString(entryParcel.mType.getMsgId(),
entryParcel.mParameters);
}
Style style;
@ -273,10 +281,10 @@ public abstract class OperationResult implements Parcelable {
}
if (getLog() == null || getLog().isEmpty()) {
return Notify.createNotify(activity, msgId, Notify.LENGTH_LONG, style);
return Notify.createNotify(activity, logText, Notify.LENGTH_LONG, style);
}
return Notify.createNotify(activity, msgId, Notify.LENGTH_LONG, style,
return Notify.createNotify(activity, logText, Notify.LENGTH_LONG, style,
new ActionListener() {
@Override
public void onAction() {

View File

@ -58,7 +58,8 @@ public class PgpCertifyOperation {
// get the master subkey (which we certify for)
PGPPublicKey publicKey = publicRing.getPublicKey().getPublicKey();
NfcSignOperationsBuilder requiredInput = new NfcSignOperationsBuilder(creationTimestamp);
NfcSignOperationsBuilder requiredInput = new NfcSignOperationsBuilder(creationTimestamp,
publicKey.getKeyID(), publicKey.getKeyID());
try {
if (action.mUserIds != null) {

View File

@ -409,7 +409,8 @@ public class PgpKeyOperation {
if (!isDivertToCard(masterSecretKey) && !cryptoInput.hasPassphrase()) {
log.add(LogType.MSG_MF_REQUIRE_PASSPHRASE, indent);
return new PgpEditKeyResult(log, RequiredInputParcel.createRequiredPassphrase(
masterSecretKey.getKeyID(), cryptoInput.getSignatureTime()));
masterSecretKey.getKeyID(), masterSecretKey.getKeyID(),
cryptoInput.getSignatureTime()));
}
// read masterKeyFlags, and use the same as before.
@ -431,7 +432,9 @@ public class PgpKeyOperation {
int indent = 1;
NfcSignOperationsBuilder nfcSignOps = new NfcSignOperationsBuilder(cryptoInput.getSignatureTime());
NfcSignOperationsBuilder nfcSignOps = new NfcSignOperationsBuilder(
cryptoInput.getSignatureTime(), masterSecretKey.getKeyID(),
masterSecretKey.getKeyID());
progress(R.string.progress_modify, 0);

View File

@ -18,19 +18,20 @@ public class RequiredInputParcel implements Parcelable {
public final RequiredInputType mType;
public String mNfcPin = "123456";
public final byte[][] mInputHashes;
public final int[] mSignAlgos;
private Long mMasterKeyId;
private Long mSubKeyId;
private RequiredInputParcel(RequiredInputType type, byte[][] inputHashes,
int[] signAlgos, Date signatureTime, Long keyId) {
int[] signAlgos, Date signatureTime, Long masterKeyId, Long subKeyId) {
mType = type;
mInputHashes = inputHashes;
mSignAlgos = signAlgos;
mSignatureTime = signatureTime;
mSubKeyId = keyId;
mMasterKeyId = masterKeyId;
mSubKeyId = subKeyId;
}
public RequiredInputParcel(Parcel source) {
@ -50,6 +51,7 @@ public class RequiredInputParcel implements Parcelable {
}
mSignatureTime = source.readInt() != 0 ? new Date(source.readLong()) : null;
mMasterKeyId = source.readInt() != 0 ? source.readLong() : null;
mSubKeyId = source.readInt() != 0 ? source.readLong() : null;
}
@ -61,19 +63,28 @@ public class RequiredInputParcel implements Parcelable {
public static RequiredInputParcel createNfcSignOperation(
byte[] inputHash, int signAlgo, Date signatureTime) {
return new RequiredInputParcel(RequiredInputType.NFC_SIGN,
new byte[][] { inputHash }, new int[] { signAlgo }, signatureTime, null);
new byte[][] { inputHash }, new int[] { signAlgo },
signatureTime, null, null);
}
public static RequiredInputParcel createNfcDecryptOperation(byte[] inputHash) {
return new RequiredInputParcel(RequiredInputType.NFC_DECRYPT,
new byte[][] { inputHash }, null, null, null);
new byte[][] { inputHash }, null, null, null, null);
}
public static RequiredInputParcel createRequiredPassphrase(long keyId, Date signatureTime) {
public static RequiredInputParcel createRequiredPassphrase(
long masterKeyId, long subKeyId, Date signatureTime) {
return new RequiredInputParcel(RequiredInputType.PASSPHRASE,
null, null, signatureTime, keyId);
null, null, signatureTime, masterKeyId, subKeyId);
}
public static RequiredInputParcel createRequiredPassphrase(
RequiredInputParcel req) {
return new RequiredInputParcel(RequiredInputType.PASSPHRASE,
null, null, req.mSignatureTime, req.mMasterKeyId, req.mSubKeyId);
}
@Override
public int describeContents() {
return 0;
@ -98,6 +109,12 @@ public class RequiredInputParcel implements Parcelable {
} else {
dest.writeInt(0);
}
if (mMasterKeyId != null) {
dest.writeInt(1);
dest.writeLong(mMasterKeyId);
} else {
dest.writeInt(0);
}
if (mSubKeyId != null) {
dest.writeInt(1);
dest.writeLong(mSubKeyId);
@ -121,9 +138,13 @@ public class RequiredInputParcel implements Parcelable {
Date mSignatureTime;
ArrayList<Integer> mSignAlgos = new ArrayList<>();
ArrayList<byte[]> mInputHashes = new ArrayList<>();
long mMasterKeyId;
long mSubKeyId;
public NfcSignOperationsBuilder(Date signatureTime) {
public NfcSignOperationsBuilder(Date signatureTime, long masterKeyId, long subKeyId) {
mSignatureTime = signatureTime;
mMasterKeyId = masterKeyId;
mSubKeyId = subKeyId;
}
public RequiredInputParcel build() {
@ -135,7 +156,7 @@ public class RequiredInputParcel implements Parcelable {
}
return new RequiredInputParcel(RequiredInputType.NFC_SIGN,
inputHashes, signAlgos, mSignatureTime, null);
inputHashes, signAlgos, mSignatureTime, mMasterKeyId, mSubKeyId);
}
public void addHash(byte[] hash, int algo) {

View File

@ -26,6 +26,8 @@ import org.sufficientlysecure.keychain.service.input.CryptoInputParcel;
import org.sufficientlysecure.keychain.service.input.RequiredInputParcel;
import org.sufficientlysecure.keychain.util.Iso7816TLV;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -40,6 +42,8 @@ import java.nio.ByteBuffer;
@TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
public class NfcOperationActivity extends BaseActivity {
public static final int REQUEST_CODE_PASSPHRASE = 1;
public static final String EXTRA_REQUIRED_INPUT = "required_input";
public static final String RESULT_DATA = "result_data";
@ -49,7 +53,8 @@ public class NfcOperationActivity extends BaseActivity {
private NfcAdapter mNfcAdapter;
private IsoDep mIsoDep;
RequiredInputParcel mNfcOperations;
RequiredInputParcel mRequiredInput;
private Passphrase mPin;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -66,8 +71,38 @@ public class NfcOperationActivity extends BaseActivity {
Bundle data = intent.getExtras();
mNfcOperations = data.getParcelable(EXTRA_REQUIRED_INPUT);
mRequiredInput = data.getParcelable(EXTRA_REQUIRED_INPUT);
obtainPassphrase();
}
private void obtainPassphrase() {
Preferences prefs = Preferences.getPreferences(this);
if (prefs.useDefaultYubikeyPin()) {
mPin = new Passphrase("123456");
return;
}
Intent intent = new Intent(this, PassphraseDialogActivity.class);
intent.putExtra(PassphraseDialogActivity.EXTRA_REQUIRED_INPUT,
RequiredInputParcel.createRequiredPassphrase(mRequiredInput));
startActivityForResult(intent, REQUEST_CODE_PASSPHRASE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_PASSPHRASE:
CryptoInputParcel input = data.getParcelableExtra(PassphraseDialogActivity.RESULT_DATA);
mPin = input.getPassphrase();
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
@ -157,7 +192,7 @@ public class NfcOperationActivity extends BaseActivity {
return;
}
String pin = mNfcOperations.mNfcPin;
byte[] pin = new String(mPin.getCharArray()).getBytes();
// Command APDU for VERIFY command (page 32)
String login =
@ -165,8 +200,8 @@ public class NfcOperationActivity extends BaseActivity {
+ "20" // INS
+ "00" // P1
+ "82" // P2 (PW1)
+ String.format("%02x", pin.length()) // Lc
+ Hex.toHexString(pin.getBytes());
+ String.format("%02x", pin.length) // Lc
+ Hex.toHexString(pin);
if ( ! card(login).equals(accepted)) { // login
toast("Wrong PIN!");
setResult(RESULT_CANCELED);
@ -174,23 +209,22 @@ public class NfcOperationActivity extends BaseActivity {
return;
}
CryptoInputParcel resultData = new CryptoInputParcel(mNfcOperations.mSignatureTime);
CryptoInputParcel resultData = new CryptoInputParcel(mRequiredInput.mSignatureTime);
switch (mNfcOperations.mType) {
switch (mRequiredInput.mType) {
case NFC_DECRYPT:
for (int i = 0; i < mNfcOperations.mInputHashes.length; i++) {
byte[] hash = mNfcOperations.mInputHashes[i];
for (int i = 0; i < mRequiredInput.mInputHashes.length; i++) {
byte[] hash = mRequiredInput.mInputHashes[i];
byte[] decryptedSessionKey = nfcDecryptSessionKey(hash);
resultData.addCryptoData(hash, decryptedSessionKey);
}
break;
case NFC_SIGN:
for (int i = 0; i < mNfcOperations.mInputHashes.length; i++) {
byte[] hash = mNfcOperations.mInputHashes[i];
int algo = mNfcOperations.mSignAlgos[i];
for (int i = 0; i < mRequiredInput.mInputHashes.length; i++) {
byte[] hash = mRequiredInput.mInputHashes[i];
int algo = mRequiredInput.mSignAlgos[i];
byte[] signedHash = nfcCalculateSignature(hash, algo);
resultData.addCryptoData(hash, signedHash);
}