summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-07-04 05:35:00 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-07-04 05:35:00 +0000
commit3133dbbdba20943f283f818f42265d956722e884 (patch)
tree3915ad067294811213aac6e6d3f545cdcbbf2eda
parent809744e9125bb96c7115922bf747dc88c60a199e (diff)
- (bal) forget a few new files in sync up.
-rw-r--r--ChangeLog5
-rw-r--r--scard.c309
-rw-r--r--scard.h35
-rw-r--r--scard/Ssh.bin.uu17
-rw-r--r--scard/Ssh.java156
5 files changed, 520 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index aa734bcd0..f7e597364 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -130,7 +130,8 @@
130 stop listening to channels, detach channel users (e.g. sessions). 130 stop listening to channels, detach channel users (e.g. sessions).
131 wait for children (i.e. dying sessions), send exit messages, 131 wait for children (i.e. dying sessions), send exit messages,
132 cleanup all channels. 132 cleanup all channels.
133 133 - (bal) forget a few new files in sync up.
134
13420010629 13520010629
135 - (bal) Removed net_aton() since we don't use it any more 136 - (bal) Removed net_aton() since we don't use it any more
136 - (bal) Fixed _DISABLE_VPOSIX in readpassphrase.c. 137 - (bal) Fixed _DISABLE_VPOSIX in readpassphrase.c.
@@ -5957,4 +5958,4 @@
5957 - Wrote replacements for strlcpy and mkdtemp 5958 - Wrote replacements for strlcpy and mkdtemp
5958 - Released 1.0pre1 5959 - Released 1.0pre1
5959 5960
5960$Id: ChangeLog,v 1.1376 2001/07/04 05:26:06 mouring Exp $ 5961$Id: ChangeLog,v 1.1377 2001/07/04 05:35:00 mouring Exp $
diff --git a/scard.c b/scard.c
new file mode 100644
index 000000000..4f038ddac
--- /dev/null
+++ b/scard.c
@@ -0,0 +1,309 @@
1/*
2 * Copyright (c) 2001 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#ifdef SMARTCARD
26#include "includes.h"
27RCSID("$OpenBSD: scard.c,v 1.4 2001/07/02 22:40:17 markus Exp $");
28
29#include <openssl/engine.h>
30#include <sectok.h>
31
32#include "key.h"
33#include "log.h"
34#include "xmalloc.h"
35#include "scard.h"
36
37#define CLA_SSH 0x05
38#define INS_DECRYPT 0x10
39#define INS_GET_KEYLENGTH 0x20
40#define INS_GET_PUBKEY 0x30
41#define INS_GET_RESPONSE 0xc0
42
43#define MAX_BUF_SIZE 256
44
45static int sc_fd = -1;
46static int sc_reader_num = 0;
47static int cla = 0x00; /* class */
48
49/* interface to libsectok */
50
51static int
52sc_open(int num)
53{
54 u_char atr[256];
55 int sw;
56
57 if (sc_fd >= 0)
58 return sc_fd;
59 sc_reader_num = num;
60
61 sc_fd = sectok_open(sc_reader_num, 0, NULL);
62 if (sc_fd < 0) {
63 error("sectok_open failed %d", sc_fd);
64 return sc_fd;
65 }
66 if (sectok_reset(sc_fd, 0, atr, &sw) <= 0) {
67 error("sectok_reset failed: %s", sectok_get_sw(sw));
68 sc_fd = -1;
69 return sc_fd;
70 }
71 debug("sc_open ok %d", sc_fd);
72 return sc_fd;
73}
74
75static int
76sc_enable_applet(void)
77{
78 u_char contID[2], aid[MAX_BUF_SIZE];
79 int i, len, sw, aid_len;
80
81 len = sw = 0;
82 contID[0] = 0x77;
83 contID[1] = 0x78;
84
85 if (sectok_selectfile(sc_fd, cla, root_fid, &sw) < 0) {
86 error("sectok_selectfile root_fid failed: %s",
87 sectok_get_sw(sw));
88 return -1;
89 }
90 if (sectok_selectfile(sc_fd, cla, contID, &sw) < 0) {
91 error("sectok_selectfile failed: %s", sectok_get_sw(sw));
92 return -1;
93 }
94 /* send appled id */
95 for (i = 0; i < sizeof(aid); i++)
96 aid[i] = 0x77;
97 aid_len = 5;
98 sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, aid_len, aid, 0, NULL, &sw);
99 if (!sectok_swOK(sw)) {
100 error("sectok_apdu failed: %s", sectok_get_sw(sw));
101 return -1;
102 }
103 return 0;
104}
105
106static int
107sc_read_pubkey(Key * k)
108{
109 u_char buf[2], *n;
110 char *p;
111 int len, sw;
112
113 len = sw = 0;
114
115 /* get key size */
116 sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
117 sizeof(buf), buf, &sw);
118 if (!sectok_swOK(sw)) {
119 error("could not obtain key length: %s", sectok_get_sw(sw));
120 return -1;
121 }
122 len = (buf[0] << 8) | buf[1];
123 len /= 8;
124 debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
125
126 n = xmalloc(len);
127 /* get n */
128 sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
129 if (!sectok_swOK(sw)) {
130 error("could not obtain public key: %s", sectok_get_sw(sw));
131 xfree(n);
132 return -1;
133 }
134 debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
135
136 if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
137 error("c_read_pubkey: BN_bin2bn failed");
138 xfree(n);
139 return -1;
140 }
141 xfree(n);
142
143 /* currently the java applet just stores 'n' */
144 if (!BN_set_word(k->rsa->e, 35)) {
145 error("c_read_pubkey: BN_set_word(e, 35) failed");
146 return -1;
147 }
148
149 p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
150 debug("fingerprint %d %s", key_size(k), p);
151 xfree(p);
152
153 return 0;
154}
155
156/* private key operations */
157
158static int
159sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
160{
161 u_char *padded = NULL;
162 int sw, len, olen;
163
164 debug("sc_private_decrypt called");
165
166 olen = len = sw = 0;
167 if (padding != RSA_PKCS1_PADDING)
168 goto err;
169
170 len = BN_num_bytes(rsa->n);
171 padded = xmalloc(len);
172
173 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, 0, NULL, &sw);
174 if (!sectok_swOK(sw)) {
175 error("sc_private_decrypt: INS_DECRYPT failed: %s",
176 sectok_get_sw(sw));
177 goto err;
178 }
179 sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
180 len, padded, &sw);
181 if (!sectok_swOK(sw)) {
182 error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
183 sectok_get_sw(sw));
184 goto err;
185 }
186 olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
187 len);
188err:
189 if (padded)
190 xfree(padded);
191 return olen;
192}
193
194static int
195sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
196{
197 u_char *padded = NULL;
198 int sw, len;
199
200 len = sw = 0;
201 if (padding != RSA_PKCS1_PADDING)
202 goto err;
203
204 debug("sc_private_encrypt called");
205 len = BN_num_bytes(rsa->n);
206 padded = xmalloc(len);
207
208 if (RSA_padding_add_PKCS1_type_1(padded, len, from, flen) <= 0) {
209 error("RSA_padding_add_PKCS1_type_1 failed");
210 goto err;
211 }
212 sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, 0, NULL, &sw);
213 if (!sectok_swOK(sw)) {
214 error("sc_private_decrypt: INS_DECRYPT failed: %s",
215 sectok_get_sw(sw));
216 goto err;
217 }
218 sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
219 len, to, &sw);
220 if (!sectok_swOK(sw)) {
221 error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
222 sectok_get_sw(sw));
223 goto err;
224 }
225err:
226 if (padded)
227 xfree(padded);
228 return len;
229}
230
231/* engine for overloading private key operations */
232
233static ENGINE *smart_engine = NULL;
234static RSA_METHOD smart_rsa =
235{
236 "sectok",
237 NULL,
238 NULL,
239 NULL,
240 NULL,
241 NULL,
242 NULL,
243 NULL,
244 NULL,
245 0,
246 NULL,
247};
248
249ENGINE *
250sc_get_engine(void)
251{
252 RSA_METHOD *def;
253
254 def = RSA_get_default_openssl_method();
255
256 /* overload */
257 smart_rsa.rsa_priv_enc = sc_private_encrypt;
258 smart_rsa.rsa_priv_dec = sc_private_decrypt;
259
260 /* just use the OpenSSL version */
261 smart_rsa.rsa_pub_enc = def->rsa_pub_enc;
262 smart_rsa.rsa_pub_dec = def->rsa_pub_dec;
263 smart_rsa.rsa_mod_exp = def->rsa_mod_exp;
264 smart_rsa.bn_mod_exp = def->bn_mod_exp;
265 smart_rsa.init = def->init;
266 smart_rsa.finish = def->finish;
267 smart_rsa.flags = def->flags;
268 smart_rsa.app_data = def->app_data;
269 smart_rsa.rsa_sign = def->rsa_sign;
270 smart_rsa.rsa_verify = def->rsa_verify;
271
272 smart_engine = ENGINE_new();
273
274 ENGINE_set_id(smart_engine, "sectok");
275 ENGINE_set_name(smart_engine, "libsectok");
276 ENGINE_set_RSA(smart_engine, &smart_rsa);
277 ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
278 ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
279 ENGINE_set_RAND(smart_engine, RAND_SSLeay());
280 ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
281
282 return smart_engine;
283}
284
285Key *
286sc_get_key(int sc_reader_num)
287{
288 Key *k;
289
290 if (sc_open(sc_reader_num) < 0) {
291 error("sc_open failed");
292 return NULL;
293 }
294 if (sc_enable_applet() < 0) {
295 error("sc_enable_applet failed");
296 return NULL;
297 }
298 k = key_new(KEY_RSA);
299 if (k == NULL) {
300 return NULL;
301 }
302 if (sc_read_pubkey(k) < 0) {
303 error("sc_read_pubkey failed");
304 key_free(k);
305 return NULL;
306 }
307 return k;
308}
309#endif
diff --git a/scard.h b/scard.h
new file mode 100644
index 000000000..480be0764
--- /dev/null
+++ b/scard.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2001 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25/* $OpenBSD: scard.h,v 1.3 2001/06/26 17:27:24 markus Exp $ */
26
27#include <openssl/engine.h>
28
29#ifndef SCARD_H
30#define SCARD_H
31
32Key *sc_get_key(int);
33ENGINE *sc_get_engine(void);
34
35#endif
diff --git a/scard/Ssh.bin.uu b/scard/Ssh.bin.uu
new file mode 100644
index 000000000..9af0adf04
--- /dev/null
+++ b/scard/Ssh.bin.uu
@@ -0,0 +1,17 @@
1begin 644 Ssh.bin
2M`P)!#``:01\`A``!`F@"`$$,014!_F#P!0!!#$$?`4$,01X!00Q!'0%!#$$<
3M`4$,01L!00Q!&@'^H?`%`$$,01@!_J#P!0!!#$$7`?YX\P$!00Q!&0'^<]4`
4M`OYP\Q<!_D/3$0'^8/`4`$$,L`4`_F'3``!!#$$6`?YATP4`_G/5"P7^8=,'
5M`OZAT`$!_J#0$@0``$$,"@$$`/Y@`=```$$5\`H(`$$6\`H``$$7\@\``$$8
6M\B$``$$9\A```$$:__0"`$$;__8"`$$<__8"`$$=__8"`$$>__8"`$$?__8"
7M`/`0__(#`@8!`,H``!-@`%]=`&037`!D!!D)I$L`"0J0`&``4!-<`&0$&58`
8M````H@````3____`````H0```!`````J````(````(T````P````:A-<`&0#
9M&0A*``D*;@!@`%`37`!D!QD*`/\](&``:1%*``D*9P!@`%`37`!!$UP`9`@1
10M$UP`9`A>`&X($6``<UD*/P!@`'@K"G-H8`!X*Q-<`&0#`PH`@&``?2L#"@"`
11M8`!S61-<`&0#!R@37`!D!`,H`P5@`'-960IM`&``4%D```#P$__R`0$!"0`(
12M``!B00Q?`%I9`+`%__(!`00"`&P``!-?``43"%T`"A,)$%T`#Q,)(%T`%!,)
13M,%T`&1,)P%T`'A,*!`!=`",38OZA+5\`*%T`+1-B_J`M7P`R70`W$V+^>"T*
14M!`!?`#Q=`$$37`!!"@#("1!>`$8*!`!@`$M%``D*9P!@`%`37@!56?`&__(`
15?``0(`!0```9C""T#"<(H+00$*"T%""A;``!9``````!@
16`
17end
diff --git a/scard/Ssh.java b/scard/Ssh.java
new file mode 100644
index 000000000..05e2b4872
--- /dev/null
+++ b/scard/Ssh.java
@@ -0,0 +1,156 @@
1/*
2 * copyright 1997, 2000
3 * the regents of the university of michigan
4 * all rights reserved
5 *
6 * permission is granted to use, copy, create derivative works
7 * and redistribute this software and such derivative works
8 * for any purpose, so long as the name of the university of
9 * michigan is not used in any advertising or publicity
10 * pertaining to the use or distribution of this software
11 * without specific, written prior authorization. if the
12 * above copyright notice or any other identification of the
13 * university of michigan is included in any copy of any
14 * portion of this software, then the disclaimer below must
15 * also be included.
16 *
17 * this software is provided as is, without representation
18 * from the university of michigan as to its fitness for any
19 * purpose, and without warranty by the university of
20 * michigan of any kind, either express or implied, including
21 * without limitation the implied warranties of
22 * merchantability and fitness for a particular purpose. the
23 * regents of the university of michigan shall not be liable
24 * for any damages, including special, indirect, incidental, or
25 * consequential damages, with respect to any claim arising
26 * out of or in connection with the use of the software, even
27 * if it has been or is hereafter advised of the possibility of
28 * such damages.
29 *
30 * SSH / smartcard integration project, smartcard side
31 *
32 * Tomoko Fukuzawa, created, Feb., 2000
33 * Naomaru Itoi, modified, Apr., 2000
34 */
35
36import javacard.framework.*;
37import javacardx.framework.*;
38import javacardx.crypto.*;
39
40public class Ssh extends javacard.framework.Applet
41{
42 /* constants declaration */
43 // code of CLA byte in the command APDU header
44 private final byte Ssh_CLA =(byte)0x05;
45
46 // codes of INS byte in the command APDU header
47 private final byte DECRYPT = (byte) 0x10;
48 private final byte GET_KEYLENGTH = (byte) 0x20;
49 private final byte GET_PUBKEY = (byte) 0x30;
50 private final byte GET_RESPONSE = (byte) 0xc0;
51
52 /* instance variables declaration */
53 private final short keysize = 1024;
54
55 //RSA_CRT_PrivateKey rsakey;
56 AsymKey rsakey;
57 CyberflexFile file;
58 CyberflexOS os;
59
60 byte buffer[];
61 //byte pubkey[];
62
63 static byte[] keyHdr = {(byte)0xC2, (byte)0x01, (byte)0x05};
64
65 private Ssh()
66 {
67 file = new CyberflexFile();
68 os = new CyberflexOS();
69
70 rsakey = new RSA_CRT_PrivateKey (keysize);
71 rsakey.setKeyInstance ((short)0xc8, (short)0x10);
72
73 if ( ! rsakey.isSupportedLength (keysize) )
74 ISOException.throwIt (ISO.SW_WRONG_LENGTH);
75
76 /*
77 pubkey = new byte[keysize/8];
78 file.selectFile((short)(0x3f<<8)); // select root
79 file.selectFile((short)(('s'<<8)|'h')); // select public key file
80 os.readBinaryFile (pubkey, (short)0, (short)0, (short)(keysize/8));
81 */
82 register();
83 } // end of the constructor
84
85 public static void install(APDU apdu)
86 {
87 new Ssh(); // create a Ssh applet instance (card)
88 } // end of install method
89
90 public void process(APDU apdu)
91 {
92 // APDU object carries a byte array (buffer) to
93 // transfer incoming and outgoing APDU header
94 // and data bytes between card and CAD
95 buffer = apdu.getBuffer();
96
97 // verify that if the applet can accept this
98 // APDU message
99 // NI: change suggested by Wayne Dyksen, Purdue
100 if (buffer[ISO.OFFSET_INS] == ISO.INS_SELECT)
101 ISOException.throwIt(ISO.SW_NO_ERROR);
102
103 switch (buffer[ISO.OFFSET_INS]) {
104 case DECRYPT:
105 if (buffer[ISO.OFFSET_CLA] != Ssh_CLA)
106 ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED);
107 //decrypt (apdu);
108 short size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
109
110 if (apdu.setIncomingAndReceive() != size)
111 ISOException.throwIt (ISO.SW_WRONG_LENGTH);
112
113 rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size,
114 buffer, (short) ISO.OFFSET_CDATA);
115 apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size);
116 return;
117 case GET_PUBKEY:
118 file.selectFile((short)(0x3f<<8)); // select root
119 file.selectFile((short)(('s'<<8)|'h')); // select public key file
120 os.readBinaryFile (buffer, (short)0, (short)0, (short)(keysize/8));
121 apdu.setOutgoingAndSend((short)0, (short)(keysize/8));
122 /*
123 apdu.setOutgoing();
124 apdu.setOutgoingLength((short)(keysize/8));
125 apdu.sendBytesLong(pubkey, (short)0, (short)(keysize/8));
126 */
127 return;
128 case GET_KEYLENGTH:
129 buffer[0] = (byte)((keysize >> 8) & 0xff);
130 buffer[1] = (byte)(keysize & 0xff);
131 apdu.setOutgoingAndSend ((short)0, (short)2);
132 return;
133 case GET_RESPONSE:
134 return;
135 default:
136 ISOException.throwIt (ISO.SW_INS_NOT_SUPPORTED);
137 }
138
139 } // end of process method
140
141 /*
142 private void decrypt (APDU apdu)
143 {
144 short size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
145
146 if (apdu.setIncomingAndReceive() != size)
147 ISOException.throwIt (ISO.SW_WRONG_LENGTH);
148
149 //short offset = (short) ISO.OFFSET_CDATA;
150
151 rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size, buffer,
152 (short) ISO.OFFSET_CDATA);
153 apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size);
154 }
155 */
156} // end of class Ssh