|
35 | 35 | import javacard.security.KeyPair;
|
36 | 36 | import javacard.security.PrivateKey;
|
37 | 37 | import javacard.security.PublicKey;
|
| 38 | +import javacard.security.RSAPrivateCrtKey; |
38 | 39 | import javacard.security.RSAPublicKey;
|
39 | 40 | import javacardx.crypto.Cipher;
|
40 | 41 | import javacard.security.CryptoException;
|
@@ -426,6 +427,15 @@ public void processGenerateAsymmetricKeypair(APDU apdu) throws ISOException {
|
426 | 427 | break;
|
427 | 428 | }
|
428 | 429 | kp.genKeyPair();
|
| 430 | + |
| 431 | + // special Feitian workaround for A40CR and A22CR cards |
| 432 | + RSAPrivateCrtKey priKey = (RSAPrivateCrtKey) kp.getPrivate(); |
| 433 | + short pLen = priKey.getP(buf, (short) 0); |
| 434 | + priKey.setP(buf, (short) 0, pLen); |
| 435 | + short qLen = priKey.getQ(buf, (short) 0); |
| 436 | + priKey.setQ(buf, (short) 0, qLen); |
| 437 | + // end of workaround |
| 438 | + |
429 | 439 | } catch(CryptoException e) {
|
430 | 440 | if(e.getReason() == CryptoException.NO_SUCH_ALGORITHM) {
|
431 | 441 | ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
|
@@ -766,7 +776,7 @@ private void computeDigitalSignature(APDU apdu) throws ISOException {
|
766 | 776 | if(lc > (short) 247) {
|
767 | 777 | ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
768 | 778 | }
|
769 |
| - |
| 779 | + |
770 | 780 | rsaPkcs1Cipher.init(rsaKey, Cipher.MODE_ENCRYPT);
|
771 | 781 | sigLen = rsaPkcs1Cipher.doFinal(buf, ISO7816.OFFSET_CDATA, lc, ram_buf, (short)0);
|
772 | 782 |
|
@@ -826,57 +836,70 @@ private void importPrivateKey(APDU apdu) throws ISOException {
|
826 | 836 | short recvLen;
|
827 | 837 | short len = 0, pos = 0;
|
828 | 838 | short innerPos = 0, innerLen = 0;
|
829 |
| - byte[] ram_buf = transmitManager.GetRamBuffer(); |
| 839 | + byte[] flash_buf = null; |
830 | 840 | byte privKeyRef = -1;
|
831 | 841 | CRTKeyFile crt = null;
|
832 | 842 |
|
833 | 843 | if( ! DEF_PRIVATE_KEY_IMPORT_ALLOWED) {
|
834 | 844 | ISOException.throwIt(ErrorCode.SW_COMMAND_NOT_ALLOWED_GENERAL);
|
835 | 845 | }
|
836 |
| - |
837 |
| - recvLen = transmitManager.doChainingOrExtAPDU(apdu); |
838 |
| - |
839 |
| - try { |
840 |
| - innerPos = UtilTLV.findTag(ram_buf, (short) 0, recvLen, (byte) 0x70); |
841 |
| - innerLen = UtilTLV.decodeLengthField(ram_buf, (short)(innerPos+1)); |
842 |
| - innerPos += 1 + UtilTLV.getLengthFieldLength(ram_buf, (short)(innerPos+1)); |
843 |
| - } catch (Exception e) { |
844 |
| - ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
845 |
| - } |
846 |
| - |
847 |
| - try { |
848 |
| - pos = UtilTLV.findTag(ram_buf, innerPos, innerLen, (byte) 0x84); |
849 |
| - len = UtilTLV.decodeLengthField(ram_buf, (short)(innerPos+1)); |
850 |
| - if (len != 1) { |
| 846 | + try |
| 847 | + { |
| 848 | + // flash buffer is allocated in the next instruction |
| 849 | + recvLen = transmitManager.doChainingOrExtAPDUFlash(apdu); |
| 850 | + // if these 2 lines are reversed, flash_buf can be null |
| 851 | + flash_buf = transmitManager.GetFlashBuffer(); |
| 852 | + |
| 853 | + try { |
| 854 | + innerPos = UtilTLV.findTag(flash_buf, (short) 0, recvLen, (byte) 0x70); |
| 855 | + innerLen = UtilTLV.decodeLengthField(flash_buf, (short)(innerPos+1)); |
| 856 | + innerPos += 1 + UtilTLV.getLengthFieldLength(flash_buf, (short)(innerPos+1)); |
| 857 | + } catch (Exception e) { |
851 | 858 | ISOException.throwIt(ISO7816.SW_DATA_INVALID);
|
852 | 859 | }
|
853 |
| - privKeyRef = ram_buf[(short) (pos+2)]; |
854 |
| - } catch (Exception e) { |
855 |
| - ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
856 |
| - } |
857 |
| - try { |
858 |
| - pos = UtilTLV.findTag(ram_buf, innerPos, innerLen, (byte) 0xA5); |
859 |
| - len = UtilTLV.decodeLengthField(ram_buf, (short)(innerPos+1)); |
860 |
| - } catch (Exception e) { |
861 |
| - ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
862 |
| - } |
863 |
| - if(privKeyRef == -1) { |
864 |
| - ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
865 |
| - } |
866 |
| - try { |
867 |
| - crt = fs.findKeyCRT(privKeyRef); |
868 |
| - } catch (NotFoundException e) { |
869 |
| - ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
870 |
| - } |
871 |
| - |
872 |
| - crt.CheckPermission(pinManager, File.ACL_OP_KEY_PUTKEY); |
873 |
| - |
874 |
| - try { |
875 |
| - crt.importKey(ram_buf, pos, len); |
876 |
| - } catch (InvalidArgumentsException e) { |
877 |
| - ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
| 860 | + |
| 861 | + try { |
| 862 | + pos = UtilTLV.findTag(flash_buf, innerPos, innerLen, (byte) 0x84); |
| 863 | + len = UtilTLV.decodeLengthField(flash_buf, (short)(innerPos+1)); |
| 864 | + if (len != 1) { |
| 865 | + ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
| 866 | + } |
| 867 | + privKeyRef = flash_buf[(short) (pos+2)]; |
| 868 | + } catch (Exception e) { |
| 869 | + ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
| 870 | + } |
| 871 | + try { |
| 872 | + pos = UtilTLV.findTag(flash_buf, innerPos, innerLen, (byte) 0xA5); |
| 873 | + len = UtilTLV.decodeLengthField(flash_buf, (short)(innerPos+1)); |
| 874 | + } catch (Exception e) { |
| 875 | + ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
| 876 | + } |
| 877 | + if(privKeyRef == -1) { |
| 878 | + ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
| 879 | + } |
| 880 | + try { |
| 881 | + crt = fs.findKeyCRT(privKeyRef); |
| 882 | + } catch (NotFoundException e) { |
| 883 | + ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
| 884 | + } |
| 885 | + |
| 886 | + crt.CheckPermission(pinManager, File.ACL_OP_KEY_PUTKEY); |
| 887 | + |
| 888 | + try { |
| 889 | + crt.importKey(flash_buf, pos, len); |
| 890 | + } catch (InvalidArgumentsException e) { |
| 891 | + ISOException.throwIt(ISO7816.SW_DATA_INVALID); |
| 892 | + } |
| 893 | + // clear ressource and avoid leaking a private key in flash (if the private key is deleted after) |
| 894 | + transmitManager.ClearFlashBuffer(); |
| 895 | + } catch(ISOException e) { |
| 896 | + if (e.getReason() != ISO7816.SW_NO_ERROR) { |
| 897 | + // clear ressource and avoid leaking a private key in flash (if the private key is deleted after) |
| 898 | + transmitManager.ClearFlashBuffer(); |
| 899 | + } |
| 900 | + throw e; |
878 | 901 | }
|
879 |
| - |
| 902 | + |
880 | 903 | }
|
881 | 904 |
|
882 | 905 | } // class GidsApplet
|
0 commit comments