diff options
author | Vincent <valodim@mugenguild.com> | 2015-05-15 12:42:42 +0200 |
---|---|---|
committer | Vincent <valodim@mugenguild.com> | 2015-05-15 12:42:42 +0200 |
commit | 5f6421e82b3875386818c4e7da89f79004695f4c (patch) | |
tree | a97b7a5d71134e46ed735ebe9c5338067f93746c /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java | |
parent | 5c44f8400970de5943fd6c5e804dfa394f3deb01 (diff) | |
parent | 2d3f745c36280fcd0e5c73820cc3e72f41feae2d (diff) | |
download | open-keychain-5f6421e82b3875386818c4e7da89f79004695f4c.tar.gz open-keychain-5f6421e82b3875386818c4e7da89f79004695f4c.tar.bz2 open-keychain-5f6421e82b3875386818c4e7da89f79004695f4c.zip |
Merge pull request #1278 from josecastillo/nfckeytocard
Support for moving RSA keys to Yubikey or NFC smart card
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java | 62 |
1 files changed, 60 insertions, 2 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java index aa66053fa..3d7058ae5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/NfcOperationActivity.java @@ -10,17 +10,24 @@ import android.content.Intent; import android.os.Bundle; import android.view.WindowManager; +import org.spongycastle.util.Arrays; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey; +import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKeyRing; +import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.remote.CryptoInputParcelCacheService; import org.sufficientlysecure.keychain.service.PassphraseCacheService; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.service.input.RequiredInputParcel; import org.sufficientlysecure.keychain.ui.base.BaseNfcActivity; 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; /** * This class provides a communication interface to OpenPGP applications on ISO SmartCard compliant @@ -53,8 +60,9 @@ public class NfcOperationActivity extends BaseNfcActivity { mRequiredInput = data.getParcelable(EXTRA_REQUIRED_INPUT); mServiceIntent = data.getParcelable(EXTRA_SERVICE_INTENT); - // obtain passphrase for this subkey - obtainYubiKeyPin(RequiredInputParcel.createRequiredPassphrase(mRequiredInput)); + if (mRequiredInput.mType != RequiredInputParcel.RequiredInputType.NFC_KEYTOCARD) { + obtainYubiKeyPin(RequiredInputParcel.createRequiredPassphrase(mRequiredInput)); + } } @Override @@ -85,6 +93,56 @@ public class NfcOperationActivity extends BaseNfcActivity { } break; } + case NFC_KEYTOCARD: { + ProviderHelper providerHelper = new ProviderHelper(this); + CanonicalizedSecretKeyRing secretKeyRing; + try { + secretKeyRing = providerHelper.getCanonicalizedSecretKeyRing( + KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(mRequiredInput.getMasterKeyId()) + ); + } catch (ProviderHelper.NotFoundException e) { + throw new IOException("Couldn't find subkey for key to card operation."); + } + + for (int i = 0; i < mRequiredInput.mInputHashes.length; i++) { + byte[] subkeyBytes = mRequiredInput.mInputHashes[i]; + ByteBuffer buf = ByteBuffer.wrap(subkeyBytes); + long subkeyId = buf.getLong(); + + CanonicalizedSecretKey key = secretKeyRing.getSecretKey(subkeyId); + + long keyGenerationTimestampMillis = key.getCreationTime().getTime(); + long keyGenerationTimestamp = keyGenerationTimestampMillis / 1000; + byte[] timestampBytes = ByteBuffer.allocate(4).putInt((int) keyGenerationTimestamp).array(); + byte[] cardSerialNumber = Arrays.copyOf(nfcGetAid(), 16); + + Passphrase passphrase; + try { + passphrase = PassphraseCacheService.getCachedPassphrase(this, + mRequiredInput.getMasterKeyId(), mRequiredInput.getSubKeyId()); + } catch (PassphraseCacheService.KeyNotFoundException e) { + throw new IOException("Unable to get cached passphrase!"); + } + + if (key.canSign() || key.canCertify()) { + nfcPutKey(0xB6, key, passphrase); + nfcPutData(0xCE, timestampBytes); + nfcPutData(0xC7, key.getFingerprint()); + } else if (key.canEncrypt()) { + nfcPutKey(0xB8, key, passphrase); + nfcPutData(0xCF, timestampBytes); + nfcPutData(0xC8, key.getFingerprint()); + } else if (key.canAuthenticate()) { + nfcPutKey(0xA4, key, passphrase); + nfcPutData(0xD0, timestampBytes); + nfcPutData(0xC9, key.getFingerprint()); + } else { + throw new IOException("Inappropriate key flags for smart card key."); + } + + inputParcel.addCryptoData(subkeyBytes, cardSerialNumber); + } + } } if (mServiceIntent != null) { |