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)
downloadopenssh-git-3133dbbdba20943f283f818f42265d956722e884.tar.gz
- (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 aa734bcd..f7e59736 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -130,7 +130,8 @@
stop listening to channels, detach channel users (e.g. sessions).
wait for children (i.e. dying sessions), send exit messages,
cleanup all channels.
-
+ - (bal) forget a few new files in sync up.
+
20010629
- (bal) Removed net_aton() since we don't use it any more
- (bal) Fixed _DISABLE_VPOSIX in readpassphrase.c.
@@ -5957,4 +5958,4 @@
- Wrote replacements for strlcpy and mkdtemp
- Released 1.0pre1
-$Id: ChangeLog,v 1.1376 2001/07/04 05:26:06 mouring Exp $
+$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 00000000..4f038dda
--- /dev/null
+++ b/scard.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef SMARTCARD
+#include "includes.h"
+RCSID("$OpenBSD: scard.c,v 1.4 2001/07/02 22:40:17 markus Exp $");
+
+#include <openssl/engine.h>
+#include <sectok.h>
+
+#include "key.h"
+#include "log.h"
+#include "xmalloc.h"
+#include "scard.h"
+
+#define CLA_SSH 0x05
+#define INS_DECRYPT 0x10
+#define INS_GET_KEYLENGTH 0x20
+#define INS_GET_PUBKEY 0x30
+#define INS_GET_RESPONSE 0xc0
+
+#define MAX_BUF_SIZE 256
+
+static int sc_fd = -1;
+static int sc_reader_num = 0;
+static int cla = 0x00; /* class */
+
+/* interface to libsectok */
+
+static int
+sc_open(int num)
+{
+ u_char atr[256];
+ int sw;
+
+ if (sc_fd >= 0)
+ return sc_fd;
+ sc_reader_num = num;
+
+ sc_fd = sectok_open(sc_reader_num, 0, NULL);
+ if (sc_fd < 0) {
+ error("sectok_open failed %d", sc_fd);
+ return sc_fd;
+ }
+ if (sectok_reset(sc_fd, 0, atr, &sw) <= 0) {
+ error("sectok_reset failed: %s", sectok_get_sw(sw));
+ sc_fd = -1;
+ return sc_fd;
+ }
+ debug("sc_open ok %d", sc_fd);
+ return sc_fd;
+}
+
+static int
+sc_enable_applet(void)
+{
+ u_char contID[2], aid[MAX_BUF_SIZE];
+ int i, len, sw, aid_len;
+
+ len = sw = 0;
+ contID[0] = 0x77;
+ contID[1] = 0x78;
+
+ if (sectok_selectfile(sc_fd, cla, root_fid, &sw) < 0) {
+ error("sectok_selectfile root_fid failed: %s",
+ sectok_get_sw(sw));
+ return -1;
+ }
+ if (sectok_selectfile(sc_fd, cla, contID, &sw) < 0) {
+ error("sectok_selectfile failed: %s", sectok_get_sw(sw));
+ return -1;
+ }
+ /* send appled id */
+ for (i = 0; i < sizeof(aid); i++)
+ aid[i] = 0x77;
+ aid_len = 5;
+ sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, aid_len, aid, 0, NULL, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sectok_apdu failed: %s", sectok_get_sw(sw));
+ return -1;
+ }
+ return 0;
+}
+
+static int
+sc_read_pubkey(Key * k)
+{
+ u_char buf[2], *n;
+ char *p;
+ int len, sw;
+
+ len = sw = 0;
+
+ /* get key size */
+ sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
+ sizeof(buf), buf, &sw);
+ if (!sectok_swOK(sw)) {
+ error("could not obtain key length: %s", sectok_get_sw(sw));
+ return -1;
+ }
+ len = (buf[0] << 8) | buf[1];
+ len /= 8;
+ debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
+
+ n = xmalloc(len);
+ /* get n */
+ sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
+ if (!sectok_swOK(sw)) {
+ error("could not obtain public key: %s", sectok_get_sw(sw));
+ xfree(n);
+ return -1;
+ }
+ debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
+
+ if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
+ error("c_read_pubkey: BN_bin2bn failed");
+ xfree(n);
+ return -1;
+ }
+ xfree(n);
+
+ /* currently the java applet just stores 'n' */
+ if (!BN_set_word(k->rsa->e, 35)) {
+ error("c_read_pubkey: BN_set_word(e, 35) failed");
+ return -1;
+ }
+
+ p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
+ debug("fingerprint %d %s", key_size(k), p);
+ xfree(p);
+
+ return 0;
+}
+
+/* private key operations */
+
+static int
+sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
+{
+ u_char *padded = NULL;
+ int sw, len, olen;
+
+ debug("sc_private_decrypt called");
+
+ olen = len = sw = 0;
+ if (padding != RSA_PKCS1_PADDING)
+ goto err;
+
+ len = BN_num_bytes(rsa->n);
+ padded = xmalloc(len);
+
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, 0, NULL, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sc_private_decrypt: INS_DECRYPT failed: %s",
+ sectok_get_sw(sw));
+ goto err;
+ }
+ sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
+ len, padded, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
+ sectok_get_sw(sw));
+ goto err;
+ }
+ olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
+ len);
+err:
+ if (padded)
+ xfree(padded);
+ return olen;
+}
+
+static int
+sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
+{
+ u_char *padded = NULL;
+ int sw, len;
+
+ len = sw = 0;
+ if (padding != RSA_PKCS1_PADDING)
+ goto err;
+
+ debug("sc_private_encrypt called");
+ len = BN_num_bytes(rsa->n);
+ padded = xmalloc(len);
+
+ if (RSA_padding_add_PKCS1_type_1(padded, len, from, flen) <= 0) {
+ error("RSA_padding_add_PKCS1_type_1 failed");
+ goto err;
+ }
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, 0, NULL, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sc_private_decrypt: INS_DECRYPT failed: %s",
+ sectok_get_sw(sw));
+ goto err;
+ }
+ sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
+ len, to, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
+ sectok_get_sw(sw));
+ goto err;
+ }
+err:
+ if (padded)
+ xfree(padded);
+ return len;
+}
+
+/* engine for overloading private key operations */
+
+static ENGINE *smart_engine = NULL;
+static RSA_METHOD smart_rsa =
+{
+ "sectok",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+};
+
+ENGINE *
+sc_get_engine(void)
+{
+ RSA_METHOD *def;
+
+ def = RSA_get_default_openssl_method();
+
+ /* overload */
+ smart_rsa.rsa_priv_enc = sc_private_encrypt;
+ smart_rsa.rsa_priv_dec = sc_private_decrypt;
+
+ /* just use the OpenSSL version */
+ smart_rsa.rsa_pub_enc = def->rsa_pub_enc;
+ smart_rsa.rsa_pub_dec = def->rsa_pub_dec;
+ smart_rsa.rsa_mod_exp = def->rsa_mod_exp;
+ smart_rsa.bn_mod_exp = def->bn_mod_exp;
+ smart_rsa.init = def->init;
+ smart_rsa.finish = def->finish;
+ smart_rsa.flags = def->flags;
+ smart_rsa.app_data = def->app_data;
+ smart_rsa.rsa_sign = def->rsa_sign;
+ smart_rsa.rsa_verify = def->rsa_verify;
+
+ smart_engine = ENGINE_new();
+
+ ENGINE_set_id(smart_engine, "sectok");
+ ENGINE_set_name(smart_engine, "libsectok");
+ ENGINE_set_RSA(smart_engine, &smart_rsa);
+ ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
+ ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
+ ENGINE_set_RAND(smart_engine, RAND_SSLeay());
+ ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
+
+ return smart_engine;
+}
+
+Key *
+sc_get_key(int sc_reader_num)
+{
+ Key *k;
+
+ if (sc_open(sc_reader_num) < 0) {
+ error("sc_open failed");
+ return NULL;
+ }
+ if (sc_enable_applet() < 0) {
+ error("sc_enable_applet failed");
+ return NULL;
+ }
+ k = key_new(KEY_RSA);
+ if (k == NULL) {
+ return NULL;
+ }
+ if (sc_read_pubkey(k) < 0) {
+ error("sc_read_pubkey failed");
+ key_free(k);
+ return NULL;
+ }
+ return k;
+}
+#endif
diff --git a/scard.h b/scard.h
new file mode 100644
index 00000000..480be076
--- /dev/null
+++ b/scard.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* $OpenBSD: scard.h,v 1.3 2001/06/26 17:27:24 markus Exp $ */
+
+#include <openssl/engine.h>
+
+#ifndef SCARD_H
+#define SCARD_H
+
+Key *sc_get_key(int);
+ENGINE *sc_get_engine(void);
+
+#endif
diff --git a/scard/Ssh.bin.uu b/scard/Ssh.bin.uu
new file mode 100644
index 00000000..9af0adf0
--- /dev/null
+++ b/scard/Ssh.bin.uu
@@ -0,0 +1,17 @@
+begin 644 Ssh.bin
+M`P)!#``:01\`A``!`F@"`$$,014!_F#P!0!!#$$?`4$,01X!00Q!'0%!#$$<
+M`4$,01L!00Q!&@'^H?`%`$$,01@!_J#P!0!!#$$7`?YX\P$!00Q!&0'^<]4`
+M`OYP\Q<!_D/3$0'^8/`4`$$,L`4`_F'3``!!#$$6`?YATP4`_G/5"P7^8=,'
+M`OZAT`$!_J#0$@0``$$,"@$$`/Y@`=```$$5\`H(`$$6\`H``$$7\@\``$$8
+M\B$``$$9\A```$$:__0"`$$;__8"`$$<__8"`$$=__8"`$$>__8"`$$?__8"
+M`/`0__(#`@8!`,H``!-@`%]=`&037`!D!!D)I$L`"0J0`&``4!-<`&0$&58`
+M````H@````3____`````H0```!`````J````(````(T````P````:A-<`&0#
+M&0A*``D*;@!@`%`37`!D!QD*`/\](&``:1%*``D*9P!@`%`37`!!$UP`9`@1
+M$UP`9`A>`&X($6``<UD*/P!@`'@K"G-H8`!X*Q-<`&0#`PH`@&``?2L#"@"`
+M8`!S61-<`&0#!R@37`!D!`,H`P5@`'-960IM`&``4%D```#P$__R`0$!"0`(
+M``!B00Q?`%I9`+`%__(!`00"`&P``!-?``43"%T`"A,)$%T`#Q,)(%T`%!,)
+M,%T`&1,)P%T`'A,*!`!=`",38OZA+5\`*%T`+1-B_J`M7P`R70`W$V+^>"T*
+M!`!?`#Q=`$$37`!!"@#("1!>`$8*!`!@`$M%``D*9P!@`%`37@!56?`&__(`
+?``0(`!0```9C""T#"<(H+00$*"T%""A;``!9``````!@
+`
+end
diff --git a/scard/Ssh.java b/scard/Ssh.java
new file mode 100644
index 00000000..05e2b487
--- /dev/null
+++ b/scard/Ssh.java
@@ -0,0 +1,156 @@
+/*
+ * copyright 1997, 2000
+ * the regents of the university of michigan
+ * all rights reserved
+ *
+ * permission is granted to use, copy, create derivative works
+ * and redistribute this software and such derivative works
+ * for any purpose, so long as the name of the university of
+ * michigan is not used in any advertising or publicity
+ * pertaining to the use or distribution of this software
+ * without specific, written prior authorization. if the
+ * above copyright notice or any other identification of the
+ * university of michigan is included in any copy of any
+ * portion of this software, then the disclaimer below must
+ * also be included.
+ *
+ * this software is provided as is, without representation
+ * from the university of michigan as to its fitness for any
+ * purpose, and without warranty by the university of
+ * michigan of any kind, either express or implied, including
+ * without limitation the implied warranties of
+ * merchantability and fitness for a particular purpose. the
+ * regents of the university of michigan shall not be liable
+ * for any damages, including special, indirect, incidental, or
+ * consequential damages, with respect to any claim arising
+ * out of or in connection with the use of the software, even
+ * if it has been or is hereafter advised of the possibility of
+ * such damages.
+ *
+ * SSH / smartcard integration project, smartcard side
+ *
+ * Tomoko Fukuzawa, created, Feb., 2000
+ * Naomaru Itoi, modified, Apr., 2000
+ */
+
+import javacard.framework.*;
+import javacardx.framework.*;
+import javacardx.crypto.*;
+
+public class Ssh extends javacard.framework.Applet
+{
+ /* constants declaration */
+ // code of CLA byte in the command APDU header
+ private final byte Ssh_CLA =(byte)0x05;
+
+ // codes of INS byte in the command APDU header
+ private final byte DECRYPT = (byte) 0x10;
+ private final byte GET_KEYLENGTH = (byte) 0x20;
+ private final byte GET_PUBKEY = (byte) 0x30;
+ private final byte GET_RESPONSE = (byte) 0xc0;
+
+ /* instance variables declaration */
+ private final short keysize = 1024;
+
+ //RSA_CRT_PrivateKey rsakey;
+ AsymKey rsakey;
+ CyberflexFile file;
+ CyberflexOS os;
+
+ byte buffer[];
+ //byte pubkey[];
+
+ static byte[] keyHdr = {(byte)0xC2, (byte)0x01, (byte)0x05};
+
+ private Ssh()
+ {
+ file = new CyberflexFile();
+ os = new CyberflexOS();
+
+ rsakey = new RSA_CRT_PrivateKey (keysize);
+ rsakey.setKeyInstance ((short)0xc8, (short)0x10);
+
+ if ( ! rsakey.isSupportedLength (keysize) )
+ ISOException.throwIt (ISO.SW_WRONG_LENGTH);
+
+ /*
+ pubkey = new byte[keysize/8];
+ file.selectFile((short)(0x3f<<8)); // select root
+ file.selectFile((short)(('s'<<8)|'h')); // select public key file
+ os.readBinaryFile (pubkey, (short)0, (short)0, (short)(keysize/8));
+ */
+ register();
+ } // end of the constructor
+
+ public static void install(APDU apdu)
+ {
+ new Ssh(); // create a Ssh applet instance (card)
+ } // end of install method
+
+ public void process(APDU apdu)
+ {
+ // APDU object carries a byte array (buffer) to
+ // transfer incoming and outgoing APDU header
+ // and data bytes between card and CAD
+ buffer = apdu.getBuffer();
+
+ // verify that if the applet can accept this
+ // APDU message
+ // NI: change suggested by Wayne Dyksen, Purdue
+ if (buffer[ISO.OFFSET_INS] == ISO.INS_SELECT)
+ ISOException.throwIt(ISO.SW_NO_ERROR);
+
+ switch (buffer[ISO.OFFSET_INS]) {
+ case DECRYPT:
+ if (buffer[ISO.OFFSET_CLA] != Ssh_CLA)
+ ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED);
+ //decrypt (apdu);
+ short size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
+
+ if (apdu.setIncomingAndReceive() != size)
+ ISOException.throwIt (ISO.SW_WRONG_LENGTH);
+
+ rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size,
+ buffer, (short) ISO.OFFSET_CDATA);
+ apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size);
+ return;
+ case GET_PUBKEY:
+ file.selectFile((short)(0x3f<<8)); // select root
+ file.selectFile((short)(('s'<<8)|'h')); // select public key file
+ os.readBinaryFile (buffer, (short)0, (short)0, (short)(keysize/8));
+ apdu.setOutgoingAndSend((short)0, (short)(keysize/8));
+ /*
+ apdu.setOutgoing();
+ apdu.setOutgoingLength((short)(keysize/8));
+ apdu.sendBytesLong(pubkey, (short)0, (short)(keysize/8));
+ */
+ return;
+ case GET_KEYLENGTH:
+ buffer[0] = (byte)((keysize >> 8) & 0xff);
+ buffer[1] = (byte)(keysize & 0xff);
+ apdu.setOutgoingAndSend ((short)0, (short)2);
+ return;
+ case GET_RESPONSE:
+ return;
+ default:
+ ISOException.throwIt (ISO.SW_INS_NOT_SUPPORTED);
+ }
+
+ } // end of process method
+
+ /*
+ private void decrypt (APDU apdu)
+ {
+ short size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
+
+ if (apdu.setIncomingAndReceive() != size)
+ ISOException.throwIt (ISO.SW_WRONG_LENGTH);
+
+ //short offset = (short) ISO.OFFSET_CDATA;
+
+ rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size, buffer,
+ (short) ISO.OFFSET_CDATA);
+ apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size);
+ }
+ */
+} // end of class Ssh