diff options
Diffstat (limited to 'smcc/src/main/java')
5 files changed, 193 insertions, 68 deletions
| diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java index 57925240..c2c62fd8 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -31,6 +31,7 @@ package at.gv.egiz.smcc;  import at.gv.egiz.smcc.util.SMCCHelper;  import java.nio.charset.Charset; +import javax.smartcardio.Card;  import javax.smartcardio.CardChannel;  import javax.smartcardio.CardException;  import javax.smartcardio.CommandAPDU; @@ -334,8 +335,8 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {    }    @Override -  public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException { -     +  protected int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException { +      CardChannel channel = getCardChannel();      ResponseAPDU resp; @@ -343,13 +344,17 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {        if (pin != null) {          resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid, encodePINBlock(pin)), false);        } else { +        //TODO this is not supported          resp = transmit(channel, new CommandAPDU(0x00, 0x20, 0x00, kid), false);        }      } catch (CardException ex) {        log.error("smart card communication failed: " + ex.getMessage());        throw new SignatureCardException("smart card communication failed: " + ex.getMessage(), ex);      } -     + +    //6A 00 (falshe P1/P2) nicht in contextAID +    //69 85 (nutzungsbedingungen nicht erfüllt) in DF_Sig und nicht sigpin +      if (resp.getSW() == 0x63c0) {        throw new LockedException("PIN locked.");      } else if (resp.getSW1() == 0x63 && resp.getSW2() >> 4 == 0xc) { @@ -363,7 +368,6 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {        throw new SignatureCardException("Failed to verify pin: SW="            + Integer.toHexString(resp.getSW()) + ".");      } -    }    private void mseSetDST(int p1, int p2, byte[] dst) throws CardException, SignatureCardException { @@ -432,8 +436,7 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {     * @param pin     * @return a 8 byte pin block      */ -  @Override -  public byte[] encodePINBlock(String pin) { +  private byte[] encodePINBlock(String pin) {      byte[] asciiPIN = pin.getBytes(Charset.forName("ASCII"));      byte[] encodedPIN = new byte[8];      System.arraycopy(asciiPIN, 0, encodedPIN, 0, Math.min(asciiPIN.length, @@ -443,7 +446,72 @@ public class ACOSCard extends AbstractSignatureCard implements SignatureCard {    }    @Override -  public void activatePIN(byte kid, byte[] contextAID, String pin) throws SignatureCardException { +  public void activatePIN(PINSpec pinSpec, String pin) throws SignatureCardException {      throw new SignatureCardException("PIN activation not supported by this card");    } + +  /** +   * SCARD_E_NOT_TRANSACTED inf/dec PIN not active (pcsc crash) +   * @param pinSpec +   * @param oldPIN +   * @param newPIN +   * @throws at.gv.egiz.smcc.LockedException +   * @throws at.gv.egiz.smcc.VerificationFailedException +   * @throws at.gv.egiz.smcc.NotActivatedException +   * @throws at.gv.egiz.smcc.SignatureCardException +   */ +  @Override +  public void changePIN(PINSpec pinSpec, String oldPIN, String newPIN) +          throws LockedException, VerificationFailedException, NotActivatedException, SignatureCardException { +    Card icc = getCard(); +    try { +      icc.beginExclusive(); +      CardChannel channel = icc.getBasicChannel(); + +      if (pinSpec.getContextAID() != null) { +        ResponseAPDU responseAPDU = transmit(channel, +                new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, pinSpec.getContextAID())); +        if (responseAPDU.getSW() != 0x9000) { +          icc.endExclusive(); +          String msg = "Select AID " + SMCCHelper.toString(pinSpec.getContextAID()) + +                  ": SW=" + Integer.toHexString(responseAPDU.getSW()); +          log.error(msg); +          throw new SignatureCardException(msg); +        } +      } + +      byte[] cmd = new byte[16]; +      System.arraycopy(encodePINBlock(oldPIN), 0, cmd, 0, 8); +      System.arraycopy(encodePINBlock(newPIN), 0, cmd, 8, 8); + +      ResponseAPDU responseAPDU = transmit(channel, +              new CommandAPDU(0x00, 0x24, 0x00, pinSpec.getKID(), cmd), false); + +      icc.endExclusive(); + +      log.debug("change pin returned SW=" + Integer.toHexString(responseAPDU.getSW())); + +      if (responseAPDU.getSW() == 0x63c0) { +        log.error(pinSpec.getLocalizedName() + " locked"); +        throw new LockedException(); +      } else if (responseAPDU.getSW1() == 0x63 && responseAPDU.getSW2() >> 4 == 0xc) { +        int retries = responseAPDU.getSW2() & 0x0f; +        log.error("wrong " + pinSpec.getLocalizedName() + ", " + retries + " retries"); +        throw new VerificationFailedException(retries); +      } else if (responseAPDU.getSW() == 0x6983) { +        // sig-pin only (card not transacted for inf/dec pin) +        log.error(pinSpec.getLocalizedName() + " not activated"); +        throw new NotActivatedException(); +      } else if (responseAPDU.getSW() != 0x9000) { +        String msg = "Failed to change " + pinSpec.getLocalizedName() + +                ": SW=" + Integer.toHexString(responseAPDU.getSW()); +        log.error(msg); +        throw new SignatureCardException(msg); +      } +    } catch (CardException ex) { +      log.error("Failed to change " + pinSpec.getLocalizedName() + +              ": " + ex.getMessage()); +      throw new SignatureCardException(ex.getMessage(), ex); +    } +  }  } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java index 63301bd1..39952bb9 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java @@ -37,6 +37,8 @@ import java.util.List;  import java.util.Locale;  import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.Logger;  import javax.smartcardio.ATR;  import javax.smartcardio.Card;  import javax.smartcardio.CardChannel; @@ -117,8 +119,8 @@ public abstract class AbstractSignatureCard implements SignatureCard {    protected abstract ResponseAPDU selectFileFID(byte[] fid) throws CardException,        SignatureCardException; -  // made public -//  protected abstract int verifyPIN(String pin, byte kid) throws CardException, SignatureCardException; +  protected abstract int verifyPIN(String pin, byte kid)  +          throws LockedException, NotActivatedException, SignatureCardException;    protected byte[] readRecord(int recordNumber) throws SignatureCardException, CardException { @@ -321,7 +323,7 @@ public abstract class AbstractSignatureCard implements SignatureCard {          throw new VerificationFailedException(retries);        }      } -     +         return readBinaryTLV(maxLength, (byte) 0x30); @@ -443,53 +445,40 @@ public abstract class AbstractSignatureCard implements SignatureCard {      return pinSpecs;    } -  public void changePIN(byte kid, byte[] contextAID, String oldPIN, String newPIN) throws SignatureCardException, VerificationFailedException { +  @Override +  public int verifyPIN(PINSpec pinSpec, String pin) throws LockedException, NotActivatedException, SignatureCardException { +      Card icc = getCard();      try {        icc.beginExclusive();        CardChannel channel = icc.getBasicChannel(); -      if (contextAID != null) { +      if (pinSpec.getContextAID() != null) {          ResponseAPDU responseAPDU = transmit(channel, -                new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, contextAID)); +                new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, pinSpec.getContextAID()));          if (responseAPDU.getSW() != 0x9000) {            icc.endExclusive(); -          String msg = "Failed to change PIN " + SMCCHelper.toString(new byte[]{kid}) + -                  ": Failed to select AID " + SMCCHelper.toString(contextAID) + +          String msg = "Failed to verify PIN " + +                  SMCCHelper.toString(new byte[]{pinSpec.getKID()}) + +                  ": Failed to verify AID " + +                  SMCCHelper.toString(pinSpec.getContextAID()) +                    ": " + SMCCHelper.toString(responseAPDU.getBytes());            log.error(msg);            throw new SignatureCardException(msg);          }        } +      return verifyPIN(pin, pinSpec.getKID()); -      byte[] cmd = new byte[16]; -      System.arraycopy(encodePINBlock(oldPIN), 0, cmd, 0, 8); -      System.arraycopy(encodePINBlock(newPIN), 0, cmd, 8, 8); - -      ResponseAPDU responseAPDU = transmit(channel, -              new CommandAPDU(0x00, 0x24, 0x00, kid, cmd), false); - -      icc.endExclusive(); - -      if (responseAPDU.getSW1() == 0x63 && responseAPDU.getSW2() >> 4 == 0xc) { -        int retries = responseAPDU.getSW2() & 0x0f; -        log.error("Failed VERIFY PIN, " + retries + " tries left"); -        throw new VerificationFailedException(retries); -      } -      if (responseAPDU.getSW() != 0x9000) { -        String msg = "Failed to change PIN " -                + SMCCHelper.toString(new byte[]{kid}) + ": " -                + SMCCHelper.toString(responseAPDU.getBytes()); -        log.error(msg); -        throw new SignatureCardException(msg); +    } catch (CardException ex) { +      log.error("failed to verify pinspec: " + ex.getMessage(), ex); +      throw new SignatureCardException(ex); +    } finally { +      try { +        icc.endExclusive(); +      } catch (CardException ex) { +        log.trace("failed to end exclusive card access: " + ex.getMessage());        } -    } catch (CardException ex) { -      log.error("Failed to change PIN: " + ex.getMessage()); -      throw new SignatureCardException(ex.getMessage(), ex);      }    } -   -  abstract byte[] encodePINBlock(String pin); -  } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java index b1288f74..3c5f38a2 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java @@ -512,7 +512,7 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard          throw new LockedException();        } else if (resp.getSW() == 0x6984) {          // PIN LCS = "Initialized" (-> not activated) -        throw new NotActivatedException("PIN not set."); +        throw new NotActivatedException();        } else if (resp.getSW() == 0x9000) {          return -1; // success        } else { @@ -552,8 +552,7 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard     * @return a 8 byte pin block consisting of length byte (0x2X),     * the BCD encoded pin and a 0xFF padding     */ -  @Override -  public byte[] encodePINBlock(String pin) { +  private byte[] encodePINBlock(String pin) {      char[] pinChars = pin.toCharArray();      int numDigits = pinChars.length;      int numBytes = (int) Math.ceil(numDigits/2.0); @@ -572,37 +571,108 @@ public class STARCOSCard extends AbstractSignatureCard implements SignatureCard      return pinBlock;    } -  public void activatePIN(byte kid, byte[] contextAID, String pin) throws SignatureCardException { +  @Override +  public void activatePIN(PINSpec pinSpec, String pin) +          throws SignatureCardException {      Card icc = getCard();      try {        icc.beginExclusive();        CardChannel channel = icc.getBasicChannel(); -      if (contextAID != null) { +      if (pinSpec.getContextAID() != null) {          ResponseAPDU responseAPDU = transmit(channel, -                new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, contextAID)); +                new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, pinSpec.getContextAID()));          if (responseAPDU.getSW() != 0x9000) {            icc.endExclusive(); -          String msg = "Failed to activate PIN " + SMCCHelper.toString(new byte[]{kid}) + -                  ": Failed to select AID " + SMCCHelper.toString(contextAID) + -                  ": " + SMCCHelper.toString(responseAPDU.getBytes()); +          String msg = "Select AID " + SMCCHelper.toString(pinSpec.getContextAID()) + +                  ": SW=" + Integer.toHexString(responseAPDU.getSW());            log.error(msg);            throw new SignatureCardException(msg);          }        }        ResponseAPDU responseAPDU = transmit(channel, -              new CommandAPDU(0x00, 0x24, 0x01, kid, encodePINBlock(pin)), false); +              new CommandAPDU(0x00, 0x24, 0x01, pinSpec.getKID(), encodePINBlock(pin)), +              false);        icc.endExclusive(); -      if (responseAPDU.getSW() != 0x9000) { -        String msg = "Failed to activate PIN " + SMCCHelper.toString(new byte[]{kid}) + ": " + SMCCHelper.toString(responseAPDU.getBytes()); +      log.debug("activate pin returned SW=" + Integer.toHexString(responseAPDU.getSW())); + +       if (responseAPDU.getSW() != 0x9000) { +        String msg = "Failed to activate " + pinSpec.getLocalizedName() + +                ": SW=" + Integer.toHexString(responseAPDU.getSW()); +        log.error(msg); +        throw new SignatureCardException(msg); +      } +    } catch (CardException ex) { +      log.error("Failed to activate " + pinSpec.getLocalizedName() + +              ": " + ex.getMessage()); +      throw new SignatureCardException(ex.getMessage(), ex); +    } +  } + +  /** +   * activates pin (newPIN) if not active +   * @param pinSpec +   * @param oldPIN +   * @param newPIN +   * @throws at.gv.egiz.smcc.LockedException +   * @throws at.gv.egiz.smcc.VerificationFailedException +   * @throws at.gv.egiz.smcc.NotActivatedException +   * @throws at.gv.egiz.smcc.SignatureCardException +   */ +  @Override +  public void changePIN(PINSpec pinSpec, String oldPIN, String newPIN) +          throws LockedException, VerificationFailedException, NotActivatedException, SignatureCardException { +    Card icc = getCard(); +    try { +      icc.beginExclusive(); +      CardChannel channel = icc.getBasicChannel(); + +      if (pinSpec.getContextAID() != null) { +        ResponseAPDU responseAPDU = transmit(channel, +                new CommandAPDU(0x00, 0xa4, 0x04, 0x0c, pinSpec.getContextAID())); +        if (responseAPDU.getSW() != 0x9000) { +          icc.endExclusive(); +          String msg = "Select AID " + SMCCHelper.toString(pinSpec.getContextAID()) + +                  ": SW=" + Integer.toHexString(responseAPDU.getSW()); +          log.error(msg); +          throw new SignatureCardException(msg); +        } +      } + +      byte[] cmd = new byte[16]; +      System.arraycopy(encodePINBlock(oldPIN), 0, cmd, 0, 8); +      System.arraycopy(encodePINBlock(newPIN), 0, cmd, 8, 8); + +      ResponseAPDU responseAPDU = transmit(channel, +              new CommandAPDU(0x00, 0x24, 0x00, pinSpec.getKID(), cmd), false); + +      icc.endExclusive(); + +      log.debug("change pin returned SW=" + Integer.toHexString(responseAPDU.getSW())); + +      // activates pin (newPIN) if not active +      if (responseAPDU.getSW() == 0x63c0) { +        log.error(pinSpec.getLocalizedName() + " locked"); +        throw new LockedException(); +      } else if (responseAPDU.getSW1() == 0x63 && responseAPDU.getSW2() >> 4 == 0xc) { +        int retries = responseAPDU.getSW2() & 0x0f; +        log.error("wrong " + pinSpec.getLocalizedName() + ", " + retries + " retries"); +        throw new VerificationFailedException(retries); +      } else if (responseAPDU.getSW() == 0x6983) { +        log.error(pinSpec.getLocalizedName() + " locked"); +        throw new LockedException(); +      } else if (responseAPDU.getSW() != 0x9000) { +        String msg = "Failed to change " + pinSpec.getLocalizedName() + +                ": SW=" + Integer.toHexString(responseAPDU.getSW());          log.error(msg);          throw new SignatureCardException(msg);        }      } catch (CardException ex) { -      log.error("Failed to activate PIN: " + ex.getMessage()); +      log.error("Failed to change " + pinSpec.getLocalizedName() + +              ": " + ex.getMessage());        throw new SignatureCardException(ex.getMessage(), ex);      }    } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java index 57aeb994..d7763be0 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java @@ -394,21 +394,20 @@ public class SWCard implements SignatureCard {    }    @Override -  public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException { -    return -1; -  } - -  @Override    public List<PINSpec> getPINSpecs() {      return new ArrayList<PINSpec>();    }    @Override -  public void changePIN(byte kid, byte[] contextAID, String oldPIN, String newPIN) throws SignatureCardException, VerificationFailedException { +  public int verifyPIN(PINSpec pinSpec, String pin) throws LockedException, NotActivatedException, SignatureCardException { +    return -1;    }    @Override -  public void activatePIN(byte kid, byte[] contextAID, String pin) throws SignatureCardException { +  public void changePIN(PINSpec pinSpec, String oldPIN, String newPIN) throws LockedException, VerificationFailedException, NotActivatedException, SignatureCardException {    } +  @Override +  public void activatePIN(PINSpec pinSpec, String pin) throws SignatureCardException { +  }  } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java index a88593bc..3c2273b9 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java @@ -125,21 +125,20 @@ public interface SignatureCard {    /**     * +   * @param pinSpec descriptor which pin to verify     * @param pin may be null to test the PIN status -   * @param kid     * @return the number of remaining retries or -1     * @throws at.gv.egiz.smcc.LockedException     * @throws at.gv.egiz.smcc.NotActivatedException     * @throws at.gv.egiz.smcc.SignatureCardException     */ -  public int verifyPIN(String pin, byte kid) throws LockedException, NotActivatedException, SignatureCardException; +  public int verifyPIN(PINSpec pinSpec, String pin) +          throws LockedException, NotActivatedException, SignatureCardException; -  public void changePIN(byte kid, byte[] contextAID, -          String oldPIN, String newPIN) -          throws SignatureCardException, VerificationFailedException; +  public void changePIN(PINSpec pinSpec, String oldPIN, String newPIN) +          throws LockedException, VerificationFailedException, NotActivatedException, SignatureCardException; -  public void activatePIN(byte kid, byte[] contextAID, -          String pin) +  public void activatePIN(PINSpec pinSpec, String pin)            throws SignatureCardException;    /** | 
