diff options
| -rw-r--r-- | smcc/pom.xml | 4 | ||||
| -rw-r--r-- | smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java | 62 | ||||
| -rw-r--r-- | smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java | 11 | 
3 files changed, 69 insertions, 8 deletions
| diff --git a/smcc/pom.xml b/smcc/pom.xml index 2510145f..6f0b1ae1 100644 --- a/smcc/pom.xml +++ b/smcc/pom.xml @@ -32,11 +32,11 @@        <artifactId>junit</artifactId>        <scope>test</scope>      </dependency> -    <!-- dependency> +    <dependency>        <groupId>iaik</groupId>        <artifactId>iaik_jce_full_signed</artifactId>        <scope>test</scope> -    </dependency--> +    </dependency>      <dependency>        <groupId>iaik</groupId>        <artifactId>iaik_jce_me4se</artifactId>     diff --git a/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java b/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java index f8ba8643..b5ffa267 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/LIEZertifikatCard.java @@ -36,6 +36,8 @@ import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import at.gv.egiz.smcc.util.SMCCHelper; +import iaik.me.asn1.ASN1; +import java.util.Arrays;  import javax.smartcardio.Card;  import javax.smartcardio.CardTerminal; @@ -54,7 +56,7 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur      (byte) 0x50, (byte) 0x4B, (byte) 0x43, (byte) 0x53, (byte) 0x2D,      (byte) 0x31, (byte) 0x35 }; -  public static final byte[] EF_QCERT = new byte[] { (byte) 0x0c, (byte) 0x02}; +  public static final byte[] EF_CD = new byte[] { (byte) 0x44, (byte) 0x04};    public static final byte[] CRT_AT = new byte[] {      // key 0x81??? (EF.PrKD defines 0x84 and 0x85) @@ -103,8 +105,13 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur        CardChannel channel = getCardChannel();        // SELECT DF.CIA        execSELECT_AID(channel, AID_SIG); +      byte[] ef_qcert = getFID_QCERT(channel); +      if (ef_qcert == null) { +        throw new NotActivatedException(); +      } +        // SELECT CERT -      execSELECT_EF(channel, EF_QCERT); +      execSELECT_EF(channel, ef_qcert);        // READ BINARY        byte[] certificate = ISO7816Utils.readTransparentFileTLV(channel, -1, (byte) 0x30); @@ -288,11 +295,58 @@ public class LIEZertifikatCard extends AbstractSignatureCard implements Signatur    } -  protected byte[] execSELECT_EF(CardChannel channel, byte[] fid) +  protected byte[] getFID_QCERT(CardChannel channel)    throws SignatureCardException, CardException { +    execSELECT_EF(channel, EF_CD); +    byte[] cio_cd = ISO7816Utils.readTransparentFile(channel, -1); + +    //assume first 'record' is qcert +    int length = 0; +    if ((cio_cd[1] & 0xf0) == 0x80) { +        int ll = cio_cd[1] & 0x7f; +        for (int i= 0; i < ll; i++) { +            length = (length << 8) + (cio_cd[2+i] & 0xff); +        } +        length += ll + 2; +    } else { +        length = (cio_cd[1] & 0xff) + 2; +    } +     +    log.trace("reading CIO.CD[0-{}]", length-1); + +    try { +        ASN1 certificateObj = new ASN1(Arrays.copyOfRange(cio_cd, 0, length)); +        byte[] contextSpecific = certificateObj.getElementAt(2).getEncoded(); +        if ((contextSpecific[0] & 0xff) != 0xa1) { +            log.warn("expected X509CertificateAttributes (CONTEXTSPECIFIC 0xa1), got {}", +                    (contextSpecific[0] & 0xff)); +        } +        int ll = ((contextSpecific[1] & 0xf0) == 0x80) +                ? (contextSpecific[1] & 0x7f) + 2 : 2; + +        ASN1 x509CertificateAttributes = new ASN1( +                Arrays.copyOfRange(contextSpecific, ll, contextSpecific.length)); + +        byte[] fid = x509CertificateAttributes.getElementAt(0).getElementAt(0) +                .gvByteArray(); +         +        log.debug("reading certificate {} from file {}", +                certificateObj.getElementAt(0).getElementAt(0).gvString(), +                toString(fid)); +         +        return fid; +    } catch (IOException ex) { +        log.error("failed to get certificate path: " + ex.getMessage(), ex); +        return null; +    } +  } + +  protected byte[] execSELECT_EF(CardChannel channel, byte[] fid) +          throws SignatureCardException, CardException { +      ResponseAPDU resp = channel.transmit( -        new CommandAPDU(0x00, 0xA4, 0x02, 0x00, fid, 256)); +      new CommandAPDU(0x00, 0xA4, 0x02, 0x00, fid, 256));      if (resp.getSW() == 0x6A82) {        String msg = "File or application not found FID=" diff --git a/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java b/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java index 2979bd03..3f5343a6 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/reader/PinpadCardReader.java @@ -59,7 +59,8 @@ public class PinpadCardReader extends DefaultCardReader {    protected byte bTimeOut2 = 0x00;                  // default (attention with SCM)    protected byte wPINMaxExtraDigitMin = 0x00;         // min pin length zero digits    protected byte wPINMaxExtraDigitMax = 0x0c;         // max pin length 12 digits - +  protected byte bNumberMessage = 0x01; +      /**     * supported features and respective control codes     */ @@ -99,6 +100,12 @@ public class PinpadCardReader extends DefaultCardReader {        //Snow Leopard: Reiner-SCT cyberJack pinpad(a) 00 00        //display: REINER SCT CyberJack 00 00        if(name.startsWith("gemplus gempc pinpad") || name.startsWith("gemalto gempc pinpad")) { +          // win7(microsoft driver) GemPlus USB GemPC Pinpad Smartcardreader 0 -> no pinpad +          // win7(gemalto4.0.7.5) Gemalto GemPC Pinpad USB Smart Card Read 0 -> transmitContorlCommand failed (0x7a) +          //     (same with timeouts set to 0000 and 3c0f) +          // winXP (verify failed, sw=d2(ecard) sw=92(acos), cf. wiki): +          // winXP (without setting wPINMax: sw=6b:80) +          // linux (ok): Gemplus GemPC Pinpad 00 00          log.trace("Setting custom wPINMaxExtraDigitH (0x04) for {}.", name);          wPINMaxExtraDigitMin = 0x04;          log.trace("Setting custom wPINMaxExtraDigitL (0x08) for {}.", name); @@ -539,7 +546,7 @@ public class PinpadCardReader extends DefaultCardReader {      // bEntryValidationCondition      s.write(bEntryValidationCondition);      // bNumberMessage -    s.write(0x01); +    s.write(bNumberMessage);      // wLangId (little endian)      s.write(0x09);      s.write(0x04); | 
