diff options
Diffstat (limited to 'OpenKeychain/src')
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; -    } -  }  | 
