aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'OpenKeychain/src/main')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/PinException.java7
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/PinType.java16
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/SmartcardDevice.java40
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java54
4 files changed, 24 insertions, 93 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/PinException.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/PinException.java
deleted file mode 100644
index 58a7a31c9..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/PinException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.sufficientlysecure.keychain.smartcard;
-
-public class PinException extends CardException {
- public PinException(final String detailMessage, final short responseCode) {
- super(detailMessage, responseCode);
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/PinType.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/PinType.java
deleted file mode 100644
index 7601edcf3..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/PinType.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.sufficientlysecure.keychain.smartcard;
-
-public enum PinType {
- BASIC(0x81),
- ADMIN(0x83),;
-
- private final int mMode;
-
- PinType(final int mode) {
- this.mMode = mode;
- }
-
- public int getmMode() {
- return mMode;
- }
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/SmartcardDevice.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/SmartcardDevice.java
index 7bc53a10a..a9358ee84 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/SmartcardDevice.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/smartcard/SmartcardDevice.java
@@ -17,6 +17,11 @@ import java.security.interfaces.RSAPrivateCrtKey;
import nordpol.Apdu;
+/**
+ * This class provides a communication interface to OpenPGP applications on ISO SmartCard compliant
+ * NFC devices.
+ * For the full specs, see http://g10code.com/docs/openpgp-card-2.0.pdf
+ */
public class SmartcardDevice {
// Fidesmo constants
private static final String FIDESMO_APPS_AID_PREFIX = "A000000617";
@@ -30,7 +35,6 @@ public class SmartcardDevice {
private boolean mPw1ValidatedForSignature;
private boolean mPw1ValidatedForDecrypt; // Mode 82 does other things; consider renaming?
private boolean mPw3Validated;
- private boolean mTagHandlingEnabled;
protected SmartcardDevice() {
}
@@ -39,6 +43,10 @@ public class SmartcardDevice {
return LazyHolder.mSmartcardDevice;
}
+ private static String getHex(byte[] raw) {
+ return new String(Hex.encode(raw));
+ }
+
private String getHolderName(String name) {
try {
String slength;
@@ -59,10 +67,6 @@ public class SmartcardDevice {
}
}
- private static String getHex(byte[] raw) {
- return new String(Hex.encode(raw));
- }
-
public Passphrase getPin() {
return mPin;
}
@@ -79,7 +83,6 @@ public class SmartcardDevice {
this.mAdminPin = adminPin;
}
- // NEW MY METHOD
public void changeKey(CanonicalizedSecretKey secretKey, Passphrase passphrase) throws IOException {
long keyGenerationTimestamp = secretKey.getCreationTime().getTime() / 1000;
byte[] timestampBytes = ByteBuffer.allocate(4).putInt((int) keyGenerationTimestamp).array();
@@ -90,8 +93,9 @@ public class SmartcardDevice {
}
// Slot is empty, or contains this key already. PUT KEY operation is safe
- boolean canPutKey = !containsKey(keyType)
+ boolean canPutKey = isSlotEmpty(keyType)
|| keyMatchesFingerPrint(keyType, secretKey.getFingerprint());
+
if (!canPutKey) {
throw new IOException(String.format("Key slot occupied; card must be reset to put new %s key.",
keyType.toString()));
@@ -102,8 +106,12 @@ public class SmartcardDevice {
putData(keyType.getTimestampObjectId(), timestampBytes);
}
- private boolean containsKey(KeyType keyType) throws IOException {
- return !keyMatchesFingerPrint(keyType, BLANK_FINGERPRINT);
+ private boolean isSlotEmpty(KeyType keyType) throws IOException {
+ // Note: special case: This should not happen, but happens with
+ // https://github.com/FluffyKaon/OpenPGP-Card, thus for now assume true
+ if (getMasterKeyFingerprint(keyType.getIdx()) == null) return true;
+
+ return keyMatchesFingerPrint(keyType, BLANK_FINGERPRINT);
}
public boolean keyMatchesFingerPrint(KeyType keyType, byte[] fingerprint) throws IOException {
@@ -248,7 +256,6 @@ public class SmartcardDevice {
* @param mode For PW1, this is 0x81 for signing, 0x82 for everything else.
* For PW3 (Admin PIN), mode is 0x83.
*/
- // METHOD UPDATED [OK]
private void verifyPin(int mode) throws IOException {
if (mPin != null || mode == 0x83) {
@@ -285,7 +292,7 @@ public class SmartcardDevice {
* @param dataObject The data object to be stored.
* @param data The data to store in the object
*/
- public void putData(int dataObject, byte[] data) throws IOException {
+ private void putData(int dataObject, byte[] data) throws IOException {
if (data.length > 254) {
throw new IOException("Cannot PUT DATA with length > 254");
}
@@ -319,7 +326,7 @@ public class SmartcardDevice {
* 0xB8: Decipherment Key
* 0xA4: Authentication Key
*/
- public void putKey(int slot, CanonicalizedSecretKey secretKey, Passphrase passphrase)
+ private void putKey(int slot, CanonicalizedSecretKey secretKey, Passphrase passphrase)
throws IOException {
if (slot != 0xB6 && slot != 0xB8 && slot != 0xA4) {
throw new IOException("Invalid key slot");
@@ -577,6 +584,10 @@ public class SmartcardDevice {
return mTransport;
}
+ public void setTransport(Transport mTransport) {
+ this.mTransport = mTransport;
+ }
+
public boolean isFidesmoToken() {
if (isConnected()) { // Check if we can still talk to the card
try {
@@ -636,7 +647,6 @@ public class SmartcardDevice {
return output.substring(0, output.length() - 4);
}
- // NEW METHOD [OK]
private String tryPin(int mode, byte[] pin) throws IOException {
// Command APDU for VERIFY command (page 32)
String login =
@@ -709,10 +719,6 @@ public class SmartcardDevice {
return fp;
}
- public void setTransport(Transport mTransport) {
- this.mTransport = mTransport;
- }
-
public boolean isPersistentConnectionAllowed() {
return mTransport != null && mTransport.isPersistentConnectionAllowed();
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java
index ed6e3faf3..12843cbcd 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/SecurityTokenOperationActivity.java
@@ -69,8 +69,6 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenNfcActivity
private RequiredInputParcel mRequiredInput;
- private static final byte[] BLANK_FINGERPRINT = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
private CryptoInputParcel mInputParcel;
@Override
@@ -226,10 +224,6 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenNfcActivity
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[] tokenSerialNumber = Arrays.copyOf(mSmartcardDevice.getAid(), 16);
Passphrase passphrase;
@@ -240,33 +234,7 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenNfcActivity
throw new IOException("Unable to get cached passphrase!");
}
- if (key.canSign() || key.canCertify()) {
- if (shouldPutKey(key.getFingerprint(), 0)) {
- mSmartcardDevice.putKey(0xB6, key, passphrase);
- mSmartcardDevice.putData(0xCE, timestampBytes);
- mSmartcardDevice.putData(0xC7, key.getFingerprint());
- } else {
- throw new IOException("Key slot occupied; token must be reset to put new signature key.");
- }
- } else if (key.canEncrypt()) {
- if (shouldPutKey(key.getFingerprint(), 1)) {
- mSmartcardDevice.putKey(0xB8, key, passphrase);
- mSmartcardDevice.putData(0xCF, timestampBytes);
- mSmartcardDevice.putData(0xC8, key.getFingerprint());
- } else {
- throw new IOException("Key slot occupied; token must be reset to put new decryption key.");
- }
- } else if (key.canAuthenticate()) {
- if (shouldPutKey(key.getFingerprint(), 2)) {
- mSmartcardDevice.putKey(0xA4, key, passphrase);
- mSmartcardDevice.putData(0xD0, timestampBytes);
- mSmartcardDevice.putData(0xC9, key.getFingerprint());
- } else {
- throw new IOException("Key slot occupied; token must be reset to put new authentication key.");
- }
- } else {
- throw new IOException("Inappropriate key flags for Security Token key.");
- }
+ mSmartcardDevice.changeKey(key, passphrase);
// TODO: Is this really used anywhere?
mInputParcel.addCryptoData(subkeyBytes, tokenSerialNumber);
@@ -357,24 +325,4 @@ public class SecurityTokenOperationActivity extends BaseSecurityTokenNfcActivity
PassphraseCacheService.clearCachedPassphrase(
this, mRequiredInput.getMasterKeyId(), mRequiredInput.getSubKeyId());
}
-
- private boolean shouldPutKey(byte[] fingerprint, int idx) throws IOException {
- byte[] tokenFingerprint = mSmartcardDevice.getMasterKeyFingerprint(idx);
-
- // Note: special case: This should not happen, but happens with
- // https://github.com/FluffyKaon/OpenPGP-Card, thus for now assume true
- if (tokenFingerprint == null) {
- return true;
- }
-
- // Slot is empty, or contains this key already. PUT KEY operation is safe
- if (Arrays.equals(tokenFingerprint, BLANK_FINGERPRINT) ||
- Arrays.equals(tokenFingerprint, fingerprint)) {
- return true;
- }
-
- // Slot already contains a different key; don't overwrite it.
- return false;
- }
-
}
mi">1>; ath,pci-slot = <14>; ath,eep-endian; }; }; gpio: pinmux@E100B10 { pinctrl-names = "default"; pinctrl-0 = <&state_default>; state_default: pinmux { ebu { lantiq,groups = "ebu cs1"; lantiq,function = "ebu"; }; pci_in { lantiq,groups = "req1"; lantiq,function = "pci"; lantiq,open-drain = <1>; lantiq,pull = <2>; lantiq,output = <0>; }; pci_out { lantiq,groups = "gnt1"; lantiq,function = "pci"; lantiq,pull = <0>; lantiq,output = <1>; }; pci_rst { lantiq,pins = "io21"; lantiq,pull = <2>; lantiq,output = <1>; }; leds { lantiq,pins = "io2", "io4", "io5", "io6", "io7", "io8", "io19"; lantiq,output = <1>; }; keys { lantiq,pins = "io28", "io30"; lantiq,output = <0>; lantiq,pull = <2>; lantiq,open-drain = <1>; }; }; }; etop@E180000 { phy-mode = "mii"; }; ifxhcd@E101000 { status = "okay"; gpios = <&gpio 14 0>; }; pci@E105400 { status = "okay"; lantiq,external-clock; gpio-reset = <&gpio 21 0>; req-mask = <0xf>; }; }; /* #define SWITCH_RESET 13 */ gpio-keys-polled { compatible = "gpio-keys-polled"; #address-cells = <1>; #size-cells = <0>; poll-interval = <100>; rfkill { label = "rfkill"; gpios = <&gpio 28 1>; linux,code = <0xf7>; }; reset { label = "reset"; gpios = <&gpio 30 1>; linux,code = <0x198>; }; }; gpio-leds { compatible = "gpio-leds"; power_green: power { label = "arv7518pw:green:power"; gpios = <&gpio 2 1>; default-state = "keep"; }; dsl: dsl { label = "arv7518pw:green:dsl"; gpios = <&gpio 4 1>; }; online_green: online { label = "arv7518pw:green:internet"; gpios = <&gpio 5 1>; }; wifi: wifi { label = "arv7518pw:green:wlan"; gpios = <&gpio 6 1>; }; power_red: power2 { label = "arv7518pw:red:power"; gpios = <&gpio 7 1>; }; online2 { label = "arv7518pw:red:internet"; gpios = <&gpio 8 1>; }; usb: usb { label = "arv7518pw:green:usb"; gpios = <&gpio 19 1>; }; voice { label = "arv7518pw:green:voip"; gpios = <&gpiomm 0 1>; }; fxs1 { label = "arv7518pw:green:phone1"; gpios = <&gpiomm 1 1>; }; fxs2 { label = "arv7518pw:green:phone2"; gpios = <&gpiomm 2 1>; }; unlabeled { label = "arv7518pw:amber:unlabeled"; gpios = <&gpiomm 3 1>; }; wps { label = "arv7518pw:amber:wps"; gpios = <&gpiomm 4 1>; }; wps2 { label = "arv7518pw:green:wps"; gpios = <&gpiomm 5 1>; }; wps3 { label = "arv7518pw:red:wps"; gpios = <&gpiomm 6 1>; }; }; };