]>
Commit | Line | Data |
---|---|---|
0fd6c7a9 | 1 | // $Id$ |
2 | // | |
3 | // Ssh.java | |
4 | // SSH / smartcard integration project, smartcard side | |
5 | // | |
6 | // Tomoko Fukuzawa, created, Feb., 2000 | |
7 | // | |
8 | // Naomaru Itoi, modified, Apr., 2000 | |
9 | // | |
10 | ||
11 | // copyright 2000 | |
12 | // the regents of the university of michigan | |
13 | // all rights reserved | |
14 | // | |
15 | // permission is granted to use, copy, create derivative works | |
16 | // and redistribute this software and such derivative works | |
17 | // for any purpose, so long as the name of the university of | |
18 | // michigan is not used in any advertising or publicity | |
19 | // pertaining to the use or distribution of this software | |
20 | // without specific, written prior authorization. if the | |
21 | // above copyright notice or any other identification of the | |
22 | // university of michigan is included in any copy of any | |
23 | // portion of this software, then the disclaimer below must | |
24 | // also be included. | |
25 | // | |
26 | // this software is provided as is, without representation | |
27 | // from the university of michigan as to its fitness for any | |
28 | // purpose, and without warranty by the university of | |
29 | // michigan of any kind, either express or implied, including | |
30 | // without limitation the implied warranties of | |
31 | // merchantability and fitness for a particular purpose. the | |
32 | // regents of the university of michigan shall not be liable | |
33 | // for any damages, including special, indirect, incidental, or | |
34 | // consequential damages, with respect to any claim arising | |
35 | // out of or in connection with the use of the software, even | |
36 | // if it has been or is hereafter advised of the possibility of | |
37 | // such damages. | |
637b033d | 38 | |
39 | import javacard.framework.*; | |
40 | import javacardx.framework.*; | |
41 | import javacardx.crypto.*; | |
42 | ||
43 | public class Ssh extends javacard.framework.Applet | |
0fd6c7a9 | 44 | { |
2880ad5e | 45 | // Change this when the applet changes; hi byte is major, low byte is minor |
46 | static final short applet_version = (short)0x0102; | |
47 | ||
0fd6c7a9 | 48 | /* constants declaration */ |
49 | // code of CLA byte in the command APDU header | |
50 | static final byte Ssh_CLA =(byte)0x05; | |
51 | ||
637b033d | 52 | // codes of INS byte in the command APDU header |
0fd6c7a9 | 53 | static final byte DECRYPT = (byte) 0x10; |
54 | static final byte GET_KEYLENGTH = (byte) 0x20; | |
55 | static final byte GET_PUBKEY = (byte) 0x30; | |
2880ad5e | 56 | static final byte GET_VERSION = (byte) 0x32; |
0fd6c7a9 | 57 | static final byte GET_RESPONSE = (byte) 0xc0; |
637b033d | 58 | |
0fd6c7a9 | 59 | static final short keysize = 1024; |
2880ad5e | 60 | static final short root_fid = (short)0x3f00; |
61 | static final short privkey_fid = (short)0x0012; | |
62 | static final short pubkey_fid = (short)(('s'<<8)|'h'); | |
637b033d | 63 | |
2880ad5e | 64 | /* instance variables declaration */ |
637b033d | 65 | AsymKey rsakey; |
66 | CyberflexFile file; | |
67 | CyberflexOS os; | |
0fd6c7a9 | 68 | |
637b033d | 69 | private Ssh() |
70 | { | |
71 | file = new CyberflexFile(); | |
72 | os = new CyberflexOS(); | |
0fd6c7a9 | 73 | |
637b033d | 74 | rsakey = new RSA_CRT_PrivateKey (keysize); |
637b033d | 75 | |
76 | if ( ! rsakey.isSupportedLength (keysize) ) | |
77 | ISOException.throwIt (ISO.SW_WRONG_LENGTH); | |
78 | ||
0fd6c7a9 | 79 | register(); |
80 | } // end of the constructor | |
81 | ||
82 | public boolean select() { | |
83 | if (!rsakey.isInitialized()) | |
84 | rsakey.setKeyInstance ((short)0xc8, (short)0x10); | |
85 | ||
86 | return true; | |
87 | } | |
637b033d | 88 | |
89 | public static void install(APDU apdu) | |
90 | { | |
0fd6c7a9 | 91 | new Ssh(); // create a Ssh applet instance (card) |
637b033d | 92 | } // end of install method |
93 | ||
0fd6c7a9 | 94 | public static void main(String args[]) { |
95 | ISOException.throwIt((short) 0x9000); | |
96 | } | |
97 | ||
637b033d | 98 | public void process(APDU apdu) |
0fd6c7a9 | 99 | { |
100 | // APDU object carries a byte array (buffer) to | |
101 | // transfer incoming and outgoing APDU header | |
637b033d | 102 | // and data bytes between card and CAD |
2880ad5e | 103 | byte buffer[] = apdu.getBuffer(); |
104 | short size, st; | |
637b033d | 105 | |
106 | // verify that if the applet can accept this | |
0fd6c7a9 | 107 | // APDU message |
637b033d | 108 | // NI: change suggested by Wayne Dyksen, Purdue |
109 | if (buffer[ISO.OFFSET_INS] == ISO.INS_SELECT) | |
110 | ISOException.throwIt(ISO.SW_NO_ERROR); | |
0fd6c7a9 | 111 | |
637b033d | 112 | switch (buffer[ISO.OFFSET_INS]) { |
113 | case DECRYPT: | |
114 | if (buffer[ISO.OFFSET_CLA] != Ssh_CLA) | |
115 | ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED); | |
116 | //decrypt (apdu); | |
2880ad5e | 117 | size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF); |
0fd6c7a9 | 118 | |
637b033d | 119 | if (apdu.setIncomingAndReceive() != size) |
120 | ISOException.throwIt (ISO.SW_WRONG_LENGTH); | |
0fd6c7a9 | 121 | |
2880ad5e | 122 | // check access; depends on bit 2 (x/a) |
123 | file.selectFile(root_fid); | |
124 | file.selectFile(privkey_fid); | |
125 | st = os.checkAccess(ACL.EXECUTE); | |
126 | if (st != ST.ACCESS_CLEARED) { | |
127 | CyberflexAPDU.prepareSW1SW2(st); | |
128 | ISOException.throwIt(CyberflexAPDU.getSW1SW2()); | |
129 | } | |
130 | ||
637b033d | 131 | rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size, |
132 | buffer, (short) ISO.OFFSET_CDATA); | |
0fd6c7a9 | 133 | |
637b033d | 134 | apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size); |
2880ad5e | 135 | break; |
637b033d | 136 | case GET_PUBKEY: |
2880ad5e | 137 | file.selectFile(root_fid); // select root |
138 | file.selectFile(pubkey_fid); // select public key file | |
139 | size = (short)(file.getFileSize() - 16); | |
140 | st = os.readBinaryFile(buffer, (short)0, (short)0, size); | |
141 | if (st == ST.SUCCESS) | |
142 | apdu.setOutgoingAndSend((short)0, size); | |
143 | else { | |
144 | CyberflexAPDU.prepareSW1SW2(st); | |
145 | ISOException.throwIt(CyberflexAPDU.getSW1SW2()); | |
146 | } | |
147 | break; | |
637b033d | 148 | case GET_KEYLENGTH: |
2880ad5e | 149 | Util.setShort(buffer, (short)0, keysize); |
150 | apdu.setOutgoingAndSend ((short)0, (short)2); | |
151 | break; | |
152 | case GET_VERSION: | |
153 | Util.setShort(buffer, (short)0, applet_version); | |
637b033d | 154 | apdu.setOutgoingAndSend ((short)0, (short)2); |
2880ad5e | 155 | break; |
637b033d | 156 | case GET_RESPONSE: |
2880ad5e | 157 | break; |
637b033d | 158 | default: |
0fd6c7a9 | 159 | ISOException.throwIt (ISO.SW_INS_NOT_SUPPORTED); |
160 | } | |
637b033d | 161 | |
162 | } // end of process method | |
163 | ||
0fd6c7a9 | 164 | } // end of class Ssh |