upgrade JSch to 0.1.54, closes #48. Upgrade ADAL.

This commit is contained in:
Philipp Crocoll
2018-04-02 05:52:37 +02:00
parent 39ef4a4711
commit 409228285e
139 changed files with 3199 additions and 1054 deletions

Binary file not shown.

View File

@@ -60,6 +60,7 @@
</LibraryProjectZip> </LibraryProjectZip>
<None Include="Jars\AboutJars.txt" /> <None Include="Jars\AboutJars.txt" />
<None Include="Additions\AboutAdditions.txt" /> <None Include="Additions\AboutAdditions.txt" />
<LibraryProjectZip Include="Jars\adal-1.14.0.aar" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<TransformFile Include="Transforms\Metadata.xml" /> <TransformFile Include="Transforms\Metadata.xml" />
@@ -92,9 +93,6 @@
<ItemGroup> <ItemGroup>
<EmbeddedReferenceJar Include="Jars\onedrive-sdk-android-1.2.2\classes-onedrive-sdk.jar" /> <EmbeddedReferenceJar Include="Jars\onedrive-sdk-android-1.2.2\classes-onedrive-sdk.jar" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\adal-1.1.19\classes-adal.jar" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\commons-logging-1.1.1.jar" /> <EmbeddedReferenceJar Include="Jars\gdrive\commons-logging-1.1.1.jar" />
</ItemGroup> </ItemGroup>

View File

@@ -32,11 +32,11 @@ dependencies {
compile 'com.google.apis:google-api-services-drive:v2-rev102-1.16.0-rc' compile 'com.google.apis:google-api-services-drive:v2-rev102-1.16.0-rc'
compile 'com.dropbox.core:dropbox-core-sdk:3.0.3' compile 'com.dropbox.core:dropbox-core-sdk:3.0.3'
//onedrive: //onedrive:
compile('com.onedrive.sdk:onedrive-sdk-android:1.2+') { compile('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
transitive = false transitive = false
} }
compile 'com.google.code.gson:gson:2.3.1' compile 'com.google.code.gson:gson:2.3.1'
compile 'com.microsoft.services.msa:msa-auth:0.8.+' compile 'com.microsoft.services.msa:msa-auth:0.8.6'
compile 'com.microsoft.aad:adal:1.1.+' compile 'com.microsoft.aad:adal:1.14.0'
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -213,8 +213,11 @@ public class Buffer{
} }
void checkFreeSize(int n){ void checkFreeSize(int n){
if(buffer.length<index+n){ int size = index+n+Session.buffer_margin;
byte[] tmp = new byte[buffer.length*2]; if(buffer.length<size){
int i = buffer.length*2;
if(i<size) i = size;
byte[] tmp = new byte[i];
System.arraycopy(buffer, 0, tmp, 0, index); System.arraycopy(buffer, 0, tmp, 0, index);
buffer = tmp; buffer = tmp;
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -192,29 +192,38 @@ public abstract class Channel implements Runnable{
io.setExtOutputStream(out, dontclose); io.setExtOutputStream(out, dontclose);
} }
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
int max_input_buffer_size = 32*1024;
try {
max_input_buffer_size =
Integer.parseInt(getSession().getConfig("max_input_buffer_size"));
}
catch(Exception e){}
PipedInputStream in = PipedInputStream in =
new MyPipedInputStream( new MyPipedInputStream(
32*1024 // this value should be customizable. 32*1024, // this value should be customizable.
max_input_buffer_size
); );
io.setOutputStream(new PassiveOutputStream(in), false); boolean resizable = 32*1024<max_input_buffer_size;
io.setOutputStream(new PassiveOutputStream(in, resizable), false);
return in; return in;
} }
public InputStream getExtInputStream() throws IOException { public InputStream getExtInputStream() throws IOException {
int max_input_buffer_size = 32*1024;
try {
max_input_buffer_size =
Integer.parseInt(getSession().getConfig("max_input_buffer_size"));
}
catch(Exception e){}
PipedInputStream in = PipedInputStream in =
new MyPipedInputStream( new MyPipedInputStream(
32*1024 // this value should be customizable. 32*1024, // this value should be customizable.
max_input_buffer_size
); );
io.setExtOutputStream(new PassiveOutputStream(in), false); boolean resizable = 32*1024<max_input_buffer_size;
io.setExtOutputStream(new PassiveOutputStream(in, resizable), false);
return in; return in;
} }
public OutputStream getOutputStream() throws IOException { public OutputStream getOutputStream() throws IOException {
/*
PipedOutputStream out=new PipedOutputStream();
io.setInputStream(new PassiveInputStream(out
, 32*1024
), false);
return out;
*/
final Channel channel=this; final Channel channel=this;
OutputStream out=new OutputStream(){ OutputStream out=new OutputStream(){
@@ -317,15 +326,24 @@ public abstract class Channel implements Runnable{
} }
class MyPipedInputStream extends PipedInputStream{ class MyPipedInputStream extends PipedInputStream{
private int BUFFER_SIZE = 1024;
private int max_buffer_size = BUFFER_SIZE;
MyPipedInputStream() throws IOException{ super(); } MyPipedInputStream() throws IOException{ super(); }
MyPipedInputStream(int size) throws IOException{ MyPipedInputStream(int size) throws IOException{
super(); super();
buffer=new byte[size]; buffer=new byte[size];
BUFFER_SIZE = size;
max_buffer_size = size;
}
MyPipedInputStream(int size, int max_buffer_size) throws IOException{
this(size);
this.max_buffer_size = max_buffer_size;
} }
MyPipedInputStream(PipedOutputStream out) throws IOException{ super(out); } MyPipedInputStream(PipedOutputStream out) throws IOException{ super(out); }
MyPipedInputStream(PipedOutputStream out, int size) throws IOException{ MyPipedInputStream(PipedOutputStream out, int size) throws IOException{
super(out); super(out);
buffer=new byte[size]; buffer=new byte[size];
BUFFER_SIZE=size;
} }
/* /*
@@ -343,12 +361,66 @@ public abstract class Channel implements Runnable{
buffer[in++] = 0; buffer[in++] = 0;
read(); read();
} }
private int freeSpace(){
int size = 0;
if(out < in) {
size = buffer.length-in;
}
else if(in < out){
if(in == -1) size = buffer.length;
else size = out - in;
}
return size;
}
synchronized void checkSpace(int len) throws IOException {
int size = freeSpace();
if(size<len){
int datasize=buffer.length-size;
int foo = buffer.length;
while((foo - datasize) < len){
foo*=2;
}
if(foo > max_buffer_size){
foo = max_buffer_size;
}
if((foo - datasize) < len) return;
byte[] tmp = new byte[foo];
if(out < in) {
System.arraycopy(buffer, 0, tmp, 0, buffer.length);
}
else if(in < out){
if(in == -1) {
}
else {
System.arraycopy(buffer, 0, tmp, 0, in);
System.arraycopy(buffer, out,
tmp, tmp.length-(buffer.length-out),
(buffer.length-out));
out = tmp.length-(buffer.length-out);
}
}
else if(in == out){
System.arraycopy(buffer, 0, tmp, 0, buffer.length);
in=buffer.length;
}
buffer=tmp;
}
else if(buffer.length == size && size > BUFFER_SIZE) {
int i = size/2;
if(i<BUFFER_SIZE) i = BUFFER_SIZE;
byte[] tmp = new byte[i];
buffer=tmp;
}
}
} }
void setLocalWindowSizeMax(int foo){ this.lwsize_max=foo; } void setLocalWindowSizeMax(int foo){ this.lwsize_max=foo; }
void setLocalWindowSize(int foo){ this.lwsize=foo; } void setLocalWindowSize(int foo){ this.lwsize=foo; }
void setLocalPacketSize(int foo){ this.lmpsize=foo; } void setLocalPacketSize(int foo){ this.lmpsize=foo; }
synchronized void setRemoteWindowSize(long foo){ this.rwsize=foo; } synchronized void setRemoteWindowSize(long foo){ this.rwsize=foo; }
synchronized void addRemoteWindowSize(int foo){ synchronized void addRemoteWindowSize(long foo){
this.rwsize+=foo; this.rwsize+=foo;
if(notifyme>0) if(notifyme>0)
notifyAll(); notifyAll();
@@ -384,12 +456,15 @@ public abstract class Channel implements Runnable{
if(eof_local)return; if(eof_local)return;
eof_local=true; eof_local=true;
int i = getRecipient();
if(i == -1) return;
try{ try{
Buffer buf=new Buffer(100); Buffer buf=new Buffer(100);
Packet packet=new Packet(buf); Packet packet=new Packet(buf);
packet.reset(); packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF); buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF);
buf.putInt(getRecipient()); buf.putInt(i);
synchronized(this){ synchronized(this){
if(!close) if(!close)
getSession().write(packet); getSession().write(packet);
@@ -445,12 +520,15 @@ public abstract class Channel implements Runnable{
close=true; close=true;
eof_local=eof_remote=true; eof_local=eof_remote=true;
int i = getRecipient();
if(i == -1) return;
try{ try{
Buffer buf=new Buffer(100); Buffer buf=new Buffer(100);
Packet packet=new Packet(buf); Packet packet=new Packet(buf);
packet.reset(); packet.reset();
buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE); buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE);
buf.putInt(getRecipient()); buf.putInt(i);
synchronized(this){ synchronized(this){
getSession().write(packet); getSession().write(packet);
} }
@@ -561,8 +639,25 @@ public abstract class Channel implements Runnable{
} }
} }
class PassiveOutputStream extends PipedOutputStream{ class PassiveOutputStream extends PipedOutputStream{
PassiveOutputStream(PipedInputStream in) throws IOException{ private MyPipedInputStream _sink=null;
PassiveOutputStream(PipedInputStream in,
boolean resizable_buffer) throws IOException{
super(in); super(in);
if(resizable_buffer && (in instanceof MyPipedInputStream)) {
this._sink=(MyPipedInputStream)in;
}
}
public void write(int b) throws IOException {
if(_sink != null) {
_sink.checkSpace(1);
}
super.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
if(_sink != null) {
_sink.checkSpace(len);
}
super.write(b, off, len);
} }
} }
@@ -636,7 +731,7 @@ public abstract class Channel implements Runnable{
Packet packet = genChannelOpenPacket(); Packet packet = genChannelOpenPacket();
_session.write(packet); _session.write(packet);
int retry=10; int retry=2000;
long start=System.currentTimeMillis(); long start=System.currentTimeMillis();
long timeout=connectTimeout; long timeout=connectTimeout;
if(timeout!=0L) retry = 1; if(timeout!=0L) retry = 1;
@@ -651,7 +746,7 @@ public abstract class Channel implements Runnable{
} }
} }
try{ try{
long t = timeout==0L ? 5000L : timeout; long t = timeout==0L ? 10L : timeout;
this.notifyme=1; this.notifyme=1;
wait(t); wait(t);
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2006-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -120,8 +120,17 @@ public class ChannelDirectTCPIP extends Channel{
} }
} }
catch(Exception e){ catch(Exception e){
// Whenever an exception is thrown by sendChannelOpen(),
// 'connected' is false.
if(!connected){
connected=true;
} }
disconnect(); disconnect();
return;
}
eof();
disconnect();
} }
public void setInputStream(InputStream in){ public void setInputStream(InputStream in){

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -648,7 +648,6 @@ public class ChannelSftp extends ChannelSession{
if((seq-1)==startid || if((seq-1)==startid ||
((seq-startid)-ackcount)>=bulk_requests){ ((seq-startid)-ackcount)>=bulk_requests){
while(((seq-startid)-ackcount)>=bulk_requests){ while(((seq-startid)-ackcount)>=bulk_requests){
if(this.rwsize>=foo) break;
if(checkStatus(ackid, header)){ if(checkStatus(ackid, header)){
int _ackid = ackid[0]; int _ackid = ackid[0];
if(startid>_ackid || _ackid>seq-1){ if(startid>_ackid || _ackid>seq-1){
@@ -666,7 +665,16 @@ public class ChannelSftp extends ChannelSession{
} }
} }
} }
if(dontcopy){
foo-=sendWRITE(handle, offset, data, 0, foo); foo-=sendWRITE(handle, offset, data, 0, foo);
if(data!=obuf.buffer){
data=obuf.buffer;
_datalen=obuf.buffer.length-_s-Session.buffer_margin;
}
}
else {
foo-=sendWRITE(handle, offset, data, _s, foo);
}
} }
offset+=count; offset+=count;
if(monitor!=null && !monitor.count(count)){ if(monitor!=null && !monitor.count(count)){
@@ -736,6 +744,12 @@ public class ChannelSftp extends ChannelSession{
} }
} }
if(monitor!=null){
monitor.init(SftpProgressMonitor.PUT,
"-", dst,
SftpProgressMonitor.UNKNOWN_SIZE);
}
if(mode==OVERWRITE){ sendOPENW(dstb); } if(mode==OVERWRITE){ sendOPENW(dstb); }
else{ sendOPENA(dstb); } else{ sendOPENA(dstb); }
@@ -923,6 +937,15 @@ public class ChannelSftp extends ChannelSession{
if(i==-1) dstsb.append(_src); if(i==-1) dstsb.append(_src);
else dstsb.append(_src.substring(i + 1)); else dstsb.append(_src.substring(i + 1));
_dst=dstsb.toString(); _dst=dstsb.toString();
if(_dst.indexOf("..")!=-1){
String dstc = (new java.io.File(dst)).getCanonicalPath();
String _dstc = (new java.io.File(_dst)).getCanonicalPath();
if(!(_dstc.length()>dstc.length() &&
_dstc.substring(0, dstc.length()+1).equals(dstc+file_separator))){
throw new SftpException(SSH_FX_FAILURE,
"writing to an unexpected file "+_src);
}
}
dstsb.delete(dst.length(), _dst.length()); dstsb.delete(dst.length(), _dst.length());
} }
else{ else{
@@ -1375,7 +1398,10 @@ public class ChannelSftp extends ChannelSession{
len=1024; len=1024;
} }
if(rq.count()==0) { if(rq.count()==0
|| true // working around slow transfer speed for
// some sftp servers including Titan FTP.
) {
int request_len = buf.buffer.length-13; int request_len = buf.buffer.length-13;
if(server_version==0){ request_len=1024; } if(server_version==0){ request_len=1024; }
@@ -1782,10 +1808,17 @@ public class ChannelSftp extends ChannelSession{
try{ try{
((MyPipedInputStream)io_in).updateReadSide(); ((MyPipedInputStream)io_in).updateReadSide();
oldpath=remoteAbsolutePath(oldpath); String _oldpath=remoteAbsolutePath(oldpath);
newpath=remoteAbsolutePath(newpath); newpath=remoteAbsolutePath(newpath);
oldpath=isUnique(oldpath); _oldpath=isUnique(_oldpath);
if(oldpath.charAt(0)!='/'){ // relative path
String cwd=getCwd();
oldpath=_oldpath.substring(cwd.length()+(cwd.endsWith("/")?0:1));
}
else {
oldpath=_oldpath;
}
if(isPattern(newpath)){ if(isPattern(newpath)){
throw new SftpException(SSH_FX_FAILURE, newpath); throw new SftpException(SSH_FX_FAILURE, newpath);
@@ -1827,10 +1860,17 @@ public class ChannelSftp extends ChannelSession{
try{ try{
((MyPipedInputStream)io_in).updateReadSide(); ((MyPipedInputStream)io_in).updateReadSide();
oldpath=remoteAbsolutePath(oldpath); String _oldpath=remoteAbsolutePath(oldpath);
newpath=remoteAbsolutePath(newpath); newpath=remoteAbsolutePath(newpath);
oldpath=isUnique(oldpath); _oldpath=isUnique(_oldpath);
if(oldpath.charAt(0)!='/'){ // relative path
String cwd=getCwd();
oldpath=_oldpath.substring(cwd.length()+(cwd.endsWith("/")?0:1));
}
else {
oldpath=_oldpath;
}
if(isPattern(newpath)){ if(isPattern(newpath)){
throw new SftpException(SSH_FX_FAILURE, newpath); throw new SftpException(SSH_FX_FAILURE, newpath);

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2005-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2013 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2013-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -36,4 +36,8 @@ public interface DH{
byte[] getE() throws Exception; byte[] getE() throws Exception;
void setF(byte[] f); void setF(byte[] f);
byte[] getK() throws Exception; byte[] getK() throws Exception;
// checkRange() will check if e and f are in [1,p-1]
// as defined at https://tools.ietf.org/html/rfc4253#section-8
void checkRange() throws Exception;
} }

View File

@@ -0,0 +1,37 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public class DHEC256 extends DHECN {
public DHEC256(){
sha_name="sha-256";
key_size=256;
}
}

View File

@@ -0,0 +1,37 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public class DHEC384 extends DHECN {
public DHEC384(){
sha_name="sha-384";
key_size=384;
}
}

View File

@@ -0,0 +1,37 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public class DHEC521 extends DHECN {
public DHEC521(){
sha_name="sha-512";
key_size=521;
}
}

View File

@@ -0,0 +1,187 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public abstract class DHECN extends KeyExchange{
private static final int SSH_MSG_KEX_ECDH_INIT = 30;
private static final int SSH_MSG_KEX_ECDH_REPLY= 31;
private int state;
byte[] Q_C;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
byte[] e;
private Buffer buf;
private Packet packet;
private ECDH ecdh;
protected String sha_name;
protected int key_size;
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.session=session;
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class c=Class.forName(session.getConfig(sha_name));
sha=(HASH)(c.newInstance());
sha.init();
}
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_ECDH_INIT);
try{
Class c=Class.forName(session.getConfig("ecdh-sha2-nistp"));
ecdh=(ECDH)(c.newInstance());
ecdh.init(key_size);
Q_C = ecdh.getQ();
buf.putString(Q_C);
}
catch(Exception e){
if(e instanceof Throwable)
throw new JSchException(e.toString(), (Throwable)e);
throw new JSchException(e.toString());
}
if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-(
return;
}
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_ECDH_INIT sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_ECDH_REPLY");
}
state=SSH_MSG_KEX_ECDH_REPLY;
}
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEX_ECDH_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_ECDH_REPLY
// string K_S, server's public host key
// string Q_S, server's ephemeral public key octet string
// string the signature on the exchange hash
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=31){
System.err.println("type: must be 31 "+j);
return false;
}
K_S=_buf.getString();
byte[] Q_S=_buf.getString();
byte[][] r_s = KeyPairECDSA.fromPoint(Q_S);
// RFC 5656,
// 4. ECDH Key Exchange
// All elliptic curve public keys MUST be validated after they are
// received. An example of a validation algorithm can be found in
// Section 3.2.2 of [SEC1]. If a key fails validation,
// the key exchange MUST fail.
if(!ecdh.validate(r_s[0], r_s[1])){
return false;
}
K = ecdh.getSecret(r_s[0], r_s[1]);
K=normalize(K);
byte[] sig_of_H=_buf.getString();
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, client's identification string (CR and LF excluded)
// string V_S, server's identification string (CR and LF excluded)
// string I_C, payload of the client's SSH_MSG_KEXINIT
// string I_S, payload of the server's SSH_MSG_KEXINIT
// string K_S, server's public host key
// string Q_C, client's ephemeral public key octet string
// string Q_S, server's ephemeral public key octet string
// mpint K, shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putString(Q_C); buf.putString(Q_S);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result = verify(alg, K_S, i, sig_of_H);
state=STATE_END;
return result;
}
return false;
}
public int getState(){return state; }
}

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -55,25 +55,15 @@ public class DHG1 extends KeyExchange{
private static final int SSH_MSG_KEXDH_INIT= 30; private static final int SSH_MSG_KEXDH_INIT= 30;
private static final int SSH_MSG_KEXDH_REPLY= 31; private static final int SSH_MSG_KEXDH_REPLY= 31;
static final int RSA=0;
static final int DSS=1;
private int type=0;
private int state; private int state;
DH dh; DH dh;
// HASH sha;
// byte[] K;
// byte[] H;
byte[] V_S; byte[] V_S;
byte[] V_C; byte[] V_C;
byte[] I_S; byte[] I_S;
byte[] I_C; byte[] I_C;
// byte[] K_S;
byte[] e; byte[] e;
private Buffer buf; private Buffer buf;
@@ -87,8 +77,6 @@ public class DHG1 extends KeyExchange{
this.I_S=I_S; this.I_S=I_S;
this.I_C=I_C; this.I_C=I_C;
// sha=new SHA1();
// sha.init();
try{ try{
Class c=Class.forName(session.getConfig("sha-1")); Class c=Class.forName(session.getConfig("sha-1"));
sha=(HASH)(c.newInstance()); sha=(HASH)(c.newInstance());
@@ -155,24 +143,14 @@ public class DHG1 extends KeyExchange{
} }
K_S=_buf.getString(); K_S=_buf.getString();
// K_S is server_key_blob, which includes ....
// string ssh-dss
// impint p of dsa
// impint q of dsa
// impint g of dsa
// impint pub_key of dsa
//System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
byte[] f=_buf.getMPInt(); byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString(); byte[] sig_of_H=_buf.getString();
/*
for(int ii=0; ii<sig_of_H.length;ii++){
System.err.print(Integer.toHexString(sig_of_H[ii]&0xff));
System.err.print(": ");
}
System.err.println("");
*/
dh.setF(f); dh.setF(f);
dh.checkRange();
K=normalize(dh.getK()); K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the //The hash H is computed as the HASH hash of the concatenation of the
@@ -206,105 +184,13 @@ System.err.println("");
String alg=Util.byte2str(K_S, i, j); String alg=Util.byte2str(K_S, i, j);
i+=j; i+=j;
boolean result=false; boolean result = verify(alg, K_S, i, sig_of_H);
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
// SignatureRSA sig=new SignatureRSA();
// sig.init();
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
byte[] p;
byte[] g;
type=DSS;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
// SignatureDSA sig=new SignatureDSA();
// sig.init();
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else{
System.err.println("unknown alg");
}
state=STATE_END; state=STATE_END;
return result; return result;
} }
return false; return false;
} }
public String getKeyType(){
if(type==DSS) return "DSA";
return "RSA";
}
public int getState(){return state; } public int getState(){return state; }
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -71,10 +71,6 @@ public class DHG14 extends KeyExchange{
private static final int SSH_MSG_KEXDH_INIT= 30; private static final int SSH_MSG_KEXDH_INIT= 30;
private static final int SSH_MSG_KEXDH_REPLY= 31; private static final int SSH_MSG_KEXDH_REPLY= 31;
static final int RSA=0;
static final int DSS=1;
private int type=0;
private int state; private int state;
DH dh; DH dh;
@@ -166,17 +162,14 @@ public class DHG14 extends KeyExchange{
} }
K_S=_buf.getString(); K_S=_buf.getString();
// K_S is server_key_blob, which includes ....
// string ssh-dss
// impint p of dsa
// impint q of dsa
// impint g of dsa
// impint pub_key of dsa
//System.err.print("K_S: "); //dump(K_S, 0, K_S.length);
byte[] f=_buf.getMPInt(); byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString(); byte[] sig_of_H=_buf.getString();
dh.setF(f); dh.setF(f);
dh.checkRange();
K=normalize(dh.getK()); K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the //The hash H is computed as the HASH hash of the concatenation of the
@@ -210,101 +203,13 @@ public class DHG14 extends KeyExchange{
String alg=Util.byte2str(K_S, i, j); String alg=Util.byte2str(K_S, i, j);
i+=j; i+=j;
boolean result=false; boolean result = verify(alg, K_S, i, sig_of_H);
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
byte[] p;
byte[] g;
type=DSS;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else{
System.err.println("unknown alg");
}
state=STATE_END; state=STATE_END;
return result; return result;
} }
return false; return false;
} }
public String getKeyType(){
if(type==DSS) return "DSA";
return "RSA";
}
public int getState(){return state; } public int getState(){return state; }
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -37,21 +37,11 @@ public class DHGEX extends KeyExchange{
private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34; private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34;
static int min=1024; static int min=1024;
// static int min=512;
static int preferred=1024; static int preferred=1024;
static int max=1024; int max=1024;
// static int preferred=1024;
// static int max=2000;
static final int RSA=0;
static final int DSS=1;
private int type=0;
private int state; private int state;
// com.jcraft.jsch.DH dh;
DH dh; DH dh;
byte[] V_S; byte[] V_S;
@@ -65,7 +55,8 @@ public class DHGEX extends KeyExchange{
private byte[] p; private byte[] p;
private byte[] g; private byte[] g;
private byte[] e; private byte[] e;
//private byte[] f;
protected String hash="sha-1";
public void init(Session session, public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
@@ -76,7 +67,7 @@ public class DHGEX extends KeyExchange{
this.I_C=I_C; this.I_C=I_C;
try{ try{
Class c=Class.forName(session.getConfig("sha-1")); Class c=Class.forName(session.getConfig(hash));
sha=(HASH)(c.newInstance()); sha=(HASH)(c.newInstance());
sha.init(); sha.init();
} }
@@ -89,11 +80,13 @@ public class DHGEX extends KeyExchange{
try{ try{
Class c=Class.forName(session.getConfig("dh")); Class c=Class.forName(session.getConfig("dh"));
// Since JDK8, SunJCE has lifted the keysize restrictions
// from 1024 to 2048 for DH.
preferred = max = check2048(c, max);
dh=(com.jcraft.jsch.DH)(c.newInstance()); dh=(com.jcraft.jsch.DH)(c.newInstance());
dh.init(); dh.init();
} }
catch(Exception e){ catch(Exception e){
// System.err.println(e);
throw e; throw e;
} }
@@ -131,18 +124,9 @@ public class DHGEX extends KeyExchange{
p=_buf.getMPInt(); p=_buf.getMPInt();
g=_buf.getMPInt(); g=_buf.getMPInt();
/*
for(int iii=0; iii<p.length; iii++){
System.err.println("0x"+Integer.toHexString(p[iii]&0xff)+",");
}
System.err.println("");
for(int iii=0; iii<g.length; iii++){
System.err.println("0x"+Integer.toHexString(g[iii]&0xff)+",");
}
*/
dh.setP(p); dh.setP(p);
dh.setG(g); dh.setG(g);
// The client responds with: // The client responds with:
// byte SSH_MSG_KEX_DH_GEX_INIT(32) // byte SSH_MSG_KEX_DH_GEX_INIT(32)
// mpint e <- g^x mod p // mpint e <- g^x mod p
@@ -181,18 +165,14 @@ System.err.println("0x"+Integer.toHexString(g[iii]&0xff)+",");
} }
K_S=_buf.getString(); K_S=_buf.getString();
// K_S is server_key_blob, which includes ....
// string ssh-dss
// impint p of dsa
// impint q of dsa
// impint g of dsa
// impint pub_key of dsa
//System.err.print("K_S: "); dump(K_S, 0, K_S.length);
byte[] f=_buf.getMPInt(); byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString(); byte[] sig_of_H=_buf.getString();
dh.setF(f); dh.setF(f);
dh.checkRange();
K=normalize(dh.getK()); K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the //The hash H is computed as the HASH hash of the concatenation of the
@@ -236,105 +216,30 @@ System.err.println("0x"+Integer.toHexString(g[iii]&0xff)+",");
String alg=Util.byte2str(K_S, i, j); String alg=Util.byte2str(K_S, i, j);
i+=j; i+=j;
boolean result=false; boolean result = verify(alg, K_S, i, sig_of_H);
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
// SignatureRSA sig=new SignatureRSA();
// sig.init();
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
type=DSS;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
// SignatureDSA sig=new SignatureDSA();
// sig.init();
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else{
System.err.println("unknown alg");
}
state=STATE_END; state=STATE_END;
return result; return result;
} }
return false; return false;
} }
public String getKeyType(){
if(type==DSS) return "DSA";
return "RSA";
}
public int getState(){return state; } public int getState(){return state; }
protected int check2048(Class c, int _max) throws Exception {
DH dh=(com.jcraft.jsch.DH)(c.newInstance());
dh.init();
byte[] foo = new byte[257];
foo[1]=(byte)0xdd;
foo[256]=0x73;
dh.setP(foo);
byte[] bar = {(byte)0x02};
dh.setG(bar);
try {
dh.getE();
_max=2048;
}
catch(Exception e){ }
return _max;
}
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -29,312 +29,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.jcraft.jsch; package com.jcraft.jsch;
public class DHGEX256 extends KeyExchange{ public class DHGEX256 extends DHGEX {
DHGEX256(){
private static final int SSH_MSG_KEX_DH_GEX_GROUP= 31; hash="sha-256";
private static final int SSH_MSG_KEX_DH_GEX_INIT= 32;
private static final int SSH_MSG_KEX_DH_GEX_REPLY= 33;
private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34;
static int min=1024;
// static int min=512;
static int preferred=1024;
static int max=1024;
// static int preferred=1024;
// static int max=2000;
static final int RSA=0;
static final int DSS=1;
private int type=0;
private int state;
// com.jcraft.jsch.DH dh;
DH dh;
byte[] V_S;
byte[] V_C;
byte[] I_S;
byte[] I_C;
private Buffer buf;
private Packet packet;
private byte[] p;
private byte[] g;
private byte[] e;
//private byte[] f;
public void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
this.session=session;
this.V_S=V_S;
this.V_C=V_C;
this.I_S=I_S;
this.I_C=I_C;
try{
Class c=Class.forName(session.getConfig("sha-256"));
sha=(HASH)(c.newInstance());
sha.init();
} }
catch(Exception e){
System.err.println(e);
}
buf=new Buffer();
packet=new Packet(buf);
try{
Class c=Class.forName(session.getConfig("dh"));
dh=(com.jcraft.jsch.DH)(c.newInstance());
dh.init();
}
catch(Exception e){
// System.err.println(e);
throw e;
}
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_DH_GEX_REQUEST);
buf.putInt(min);
buf.putInt(preferred);
buf.putInt(max);
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_DH_GEX_GROUP");
}
state=SSH_MSG_KEX_DH_GEX_GROUP;
}
public boolean next(Buffer _buf) throws Exception{
int i,j;
switch(state){
case SSH_MSG_KEX_DH_GEX_GROUP:
// byte SSH_MSG_KEX_DH_GEX_GROUP(31)
// mpint p, safe prime
// mpint g, generator for subgroup in GF (p)
_buf.getInt();
_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_DH_GEX_GROUP){
System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j);
return false;
}
p=_buf.getMPInt();
g=_buf.getMPInt();
/*
for(int iii=0; iii<p.length; iii++){
System.err.println("0x"+Integer.toHexString(p[iii]&0xff)+",");
}
System.err.println("");
for(int iii=0; iii<g.length; iii++){
System.err.println("0x"+Integer.toHexString(g[iii]&0xff)+",");
}
*/
dh.setP(p);
dh.setG(g);
// The client responds with:
// byte SSH_MSG_KEX_DH_GEX_INIT(32)
// mpint e <- g^x mod p
// x is a random number (1 < x < (p-1)/2)
e=dh.getE();
packet.reset();
buf.putByte((byte)SSH_MSG_KEX_DH_GEX_INIT);
buf.putMPInt(e);
session.write(packet);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"SSH_MSG_KEX_DH_GEX_INIT sent");
JSch.getLogger().log(Logger.INFO,
"expecting SSH_MSG_KEX_DH_GEX_REPLY");
}
state=SSH_MSG_KEX_DH_GEX_REPLY;
return true;
//break;
case SSH_MSG_KEX_DH_GEX_REPLY:
// The server responds with:
// byte SSH_MSG_KEX_DH_GEX_REPLY(33)
// string server public host key and certificates (K_S)
// mpint f
// string signature of H
j=_buf.getInt();
j=_buf.getByte();
j=_buf.getByte();
if(j!=SSH_MSG_KEX_DH_GEX_REPLY){
System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j);
return false;
}
K_S=_buf.getString();
// K_S is server_key_blob, which includes ....
// string ssh-dss
// impint p of dsa
// impint q of dsa
// impint g of dsa
// impint pub_key of dsa
//System.err.print("K_S: "); dump(K_S, 0, K_S.length);
byte[] f=_buf.getMPInt();
byte[] sig_of_H=_buf.getString();
dh.setF(f);
K=normalize(dh.getK());
//The hash H is computed as the HASH hash of the concatenation of the
//following:
// string V_C, the client's version string (CR and NL excluded)
// string V_S, the server's version string (CR and NL excluded)
// string I_C, the payload of the client's SSH_MSG_KEXINIT
// string I_S, the payload of the server's SSH_MSG_KEXINIT
// string K_S, the host key
// uint32 min, minimal size in bits of an acceptable group
// uint32 n, preferred size in bits of the group the server should send
// uint32 max, maximal size in bits of an acceptable group
// mpint p, safe prime
// mpint g, generator for subgroup
// mpint e, exchange value sent by the client
// mpint f, exchange value sent by the server
// mpint K, the shared secret
// This value is called the exchange hash, and it is used to authenti-
// cate the key exchange.
buf.reset();
buf.putString(V_C); buf.putString(V_S);
buf.putString(I_C); buf.putString(I_S);
buf.putString(K_S);
buf.putInt(min); buf.putInt(preferred); buf.putInt(max);
buf.putMPInt(p); buf.putMPInt(g); buf.putMPInt(e); buf.putMPInt(f);
buf.putMPInt(K);
byte[] foo=new byte[buf.getLength()];
buf.getByte(foo);
sha.update(foo, 0, foo.length);
H=sha.digest();
// System.err.print("H -> "); dump(H, 0, H.length);
i=0;
j=0;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
String alg=Util.byte2str(K_S, i, j);
i+=j;
boolean result=false;
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
// SignatureRSA sig=new SignatureRSA();
// sig.init();
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
type=DSS;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
// SignatureDSA sig=new SignatureDSA();
// sig.init();
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else{
System.err.println("unknown alg");
}
state=STATE_END;
return result;
}
return false;
}
public String getKeyType(){
if(type==DSS) return "DSA";
return "RSA";
}
public int getState(){return state; }
} }

View File

@@ -0,0 +1,37 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface ECDH {
void init(int size) throws Exception;
byte[] getSecret(byte[] r, byte[] s) throws Exception;
byte[] getQ() throws Exception;
boolean validate(byte[] r, byte[] s) throws Exception;
}

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2004-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2004-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -30,13 +30,22 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.jcraft.jsch; package com.jcraft.jsch;
public class HostKey{ public class HostKey{
private static final byte[] sshdss=Util.str2byte("ssh-dss");
private static final byte[] sshrsa=Util.str2byte("ssh-rsa"); private static final byte[][] names = {
Util.str2byte("ssh-dss"),
Util.str2byte("ssh-rsa"),
Util.str2byte("ecdsa-sha2-nistp256"),
Util.str2byte("ecdsa-sha2-nistp384"),
Util.str2byte("ecdsa-sha2-nistp521")
};
protected static final int GUESS=0; protected static final int GUESS=0;
public static final int SSHDSS=1; public static final int SSHDSS=1;
public static final int SSHRSA=2; public static final int SSHRSA=2;
static final int UNKNOWN=3; public static final int ECDSA256=3;
public static final int ECDSA384=4;
public static final int ECDSA521=5;
static final int UNKNOWN=6;
protected String marker; protected String marker;
protected String host; protected String host;
@@ -60,6 +69,9 @@ public class HostKey{
if(type==GUESS){ if(type==GUESS){
if(key[8]=='d'){ this.type=SSHDSS; } if(key[8]=='d'){ this.type=SSHDSS; }
else if(key[8]=='r'){ this.type=SSHRSA; } else if(key[8]=='r'){ this.type=SSHRSA; }
else if(key[8]=='a' && key[20]=='2'){ this.type=ECDSA256; }
else if(key[8]=='a' && key[20]=='3'){ this.type=ECDSA384; }
else if(key[8]=='a' && key[20]=='5'){ this.type=ECDSA521; }
else { throw new JSchException("invalid key type");} else { throw new JSchException("invalid key type");}
} }
else{ else{
@@ -71,10 +83,23 @@ public class HostKey{
public String getHost(){ return host; } public String getHost(){ return host; }
public String getType(){ public String getType(){
if(type==SSHDSS){ return Util.byte2str(sshdss); } if(type==SSHDSS ||
if(type==SSHRSA){ return Util.byte2str(sshrsa);} type==SSHRSA ||
type==ECDSA256 ||
type==ECDSA384 ||
type==ECDSA521){
return Util.byte2str(names[type-1]);
}
return "UNKNOWN"; return "UNKNOWN";
} }
protected static int name2type(String name){
for(int i = 0; i < names.length; i++){
if(Util.byte2str(names[i]).equals(name)){
return i + 1;
}
}
return UNKNOWN;
}
public String getKey(){ public String getKey(){
return Util.byte2str(Util.toBase64(key, 0, key.length)); return Util.byte2str(Util.toBase64(key, 0, key.length));
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2004-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2004-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -34,11 +34,61 @@ public interface HostKeyRepository{
final int NOT_INCLUDED=1; final int NOT_INCLUDED=1;
final int CHANGED=2; final int CHANGED=2;
/**
* Checks if <code>host</code> is included with the <code>key</code>.
*
* @return #NOT_INCLUDED, #OK or #CHANGED
* @see #NOT_INCLUDED
* @see #OK
* @see #CHANGED
*/
int check(String host, byte[] key); int check(String host, byte[] key);
/**
* Adds a host key <code>hostkey</code>
*
* @param hostkey a host key to be added
* @param ui a user interface for showing messages or promping inputs.
* @see UserInfo
*/
void add(HostKey hostkey, UserInfo ui); void add(HostKey hostkey, UserInfo ui);
/**
* Removes a host key if there exists mached key with
* <code>host</code>, <code>type</code>.
*
* @see #remove(String host, String type, byte[] key)
*/
void remove(String host, String type); void remove(String host, String type);
/**
* Removes a host key if there exists a matched key with
* <code>host</code>, <code>type</code> and <code>key</code>.
*/
void remove(String host, String type, byte[] key); void remove(String host, String type, byte[] key);
/**
* Returns id of this repository.
*
* @return identity in String
*/
String getKnownHostsRepositoryID(); String getKnownHostsRepositoryID();
/**
* Retuns a list for host keys managed in this repository.
*
* @see #getHostKey(String host, String type)
*/
HostKey[] getHostKey(); HostKey[] getHostKey();
/**
* Retuns a list for host keys managed in this repository.
*
* @param host a hostname used in searching host keys.
* If <code>null</code> is given, every host key will be listed.
* @param type a key type used in searching host keys,
* and it should be "ssh-dss" or "ssh-rsa".
* If <code>null</code> is given, a key type type will not be ignored.
*/
HostKey[] getHostKey(String host, String type); HostKey[] getHostKey(String host, String type);
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -42,6 +42,7 @@ class IdentityFile implements Identity{
} }
static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{ static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{
KeyPair kpair = KeyPair.load(jsch, prvkey, pubkey); KeyPair kpair = KeyPair.load(jsch, prvkey, pubkey);
return new IdentityFile(jsch, name, kpair); return new IdentityFile(jsch, name, kpair);
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2012-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -36,17 +36,16 @@ public class JSch{
/** /**
* The version number. * The version number.
*/ */
public static final String VERSION = "0.1.50"; public static final String VERSION = "0.1.54";
static java.util.Hashtable config=new java.util.Hashtable(); static java.util.Hashtable config=new java.util.Hashtable();
static{ static{
config.put("kex", "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1"); config.put("kex", "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1");
config.put("server_host_key", "ssh-rsa,ssh-dss"); config.put("server_host_key", "ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521");
config.put("cipher.s2c", config.put("cipher.s2c",
"aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc"); "aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc");
config.put("cipher.c2s", config.put("cipher.c2s",
"aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc"); "aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc");
config.put("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96"); config.put("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96");
config.put("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96"); config.put("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96");
@@ -63,9 +62,19 @@ public class JSch{
config.put("diffie-hellman-group1-sha1", config.put("diffie-hellman-group1-sha1",
"com.jcraft.jsch.DHG1"); "com.jcraft.jsch.DHG1");
config.put("diffie-hellman-group14-sha1", config.put("diffie-hellman-group14-sha1",
"com.jcraft.jsch.DHG14"); "com.jcraft.jsch.DHG14"); // available since JDK8.
config.put("diffie-hellman-group-exchange-sha256", config.put("diffie-hellman-group-exchange-sha256",
"com.jcraft.jsch.DHGEX256"); // avaibale since JDK1.4.2. "com.jcraft.jsch.DHGEX256"); // available since JDK1.4.2.
// On JDK8, 2048bits will be used.
config.put("ecdsa-sha2-nistp256", "com.jcraft.jsch.jce.SignatureECDSA");
config.put("ecdsa-sha2-nistp384", "com.jcraft.jsch.jce.SignatureECDSA");
config.put("ecdsa-sha2-nistp521", "com.jcraft.jsch.jce.SignatureECDSA");
config.put("ecdh-sha2-nistp256", "com.jcraft.jsch.DHEC256");
config.put("ecdh-sha2-nistp384", "com.jcraft.jsch.DHEC384");
config.put("ecdh-sha2-nistp521", "com.jcraft.jsch.DHEC521");
config.put("ecdh-sha2-nistp", "com.jcraft.jsch.jce.ECDHN");
config.put("dh", "com.jcraft.jsch.jce.DH"); config.put("dh", "com.jcraft.jsch.jce.DH");
config.put("3des-cbc", "com.jcraft.jsch.jce.TripleDESCBC"); config.put("3des-cbc", "com.jcraft.jsch.jce.TripleDESCBC");
@@ -80,11 +89,15 @@ public class JSch{
config.put("hmac-md5-96", "com.jcraft.jsch.jce.HMACMD596"); config.put("hmac-md5-96", "com.jcraft.jsch.jce.HMACMD596");
config.put("sha-1", "com.jcraft.jsch.jce.SHA1"); config.put("sha-1", "com.jcraft.jsch.jce.SHA1");
config.put("sha-256", "com.jcraft.jsch.jce.SHA256"); config.put("sha-256", "com.jcraft.jsch.jce.SHA256");
config.put("sha-384", "com.jcraft.jsch.jce.SHA384");
config.put("sha-512", "com.jcraft.jsch.jce.SHA512");
config.put("md5", "com.jcraft.jsch.jce.MD5"); config.put("md5", "com.jcraft.jsch.jce.MD5");
config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA"); config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA");
config.put("signature.rsa", "com.jcraft.jsch.jce.SignatureRSA"); config.put("signature.rsa", "com.jcraft.jsch.jce.SignatureRSA");
config.put("signature.ecdsa", "com.jcraft.jsch.jce.SignatureECDSA");
config.put("keypairgen.dsa", "com.jcraft.jsch.jce.KeyPairGenDSA"); config.put("keypairgen.dsa", "com.jcraft.jsch.jce.KeyPairGenDSA");
config.put("keypairgen.rsa", "com.jcraft.jsch.jce.KeyPairGenRSA"); config.put("keypairgen.rsa", "com.jcraft.jsch.jce.KeyPairGenRSA");
config.put("keypairgen.ecdsa", "com.jcraft.jsch.jce.KeyPairGenECDSA");
config.put("random", "com.jcraft.jsch.jce.Random"); config.put("random", "com.jcraft.jsch.jce.Random");
config.put("none", "com.jcraft.jsch.CipherNone"); config.put("none", "com.jcraft.jsch.CipherNone");
@@ -111,13 +124,16 @@ public class JSch{
config.put("zlib", "com.jcraft.jsch.jcraft.Compression"); config.put("zlib", "com.jcraft.jsch.jcraft.Compression");
config.put("zlib@openssh.com", "com.jcraft.jsch.jcraft.Compression"); config.put("zlib@openssh.com", "com.jcraft.jsch.jcraft.Compression");
config.put("pbkdf", "com.jcraft.jsch.jce.PBKDF");
config.put("StrictHostKeyChecking", "ask"); config.put("StrictHostKeyChecking", "ask");
config.put("HashKnownHosts", "no"); config.put("HashKnownHosts", "no");
config.put("PreferredAuthentications", "gssapi-with-mic,publickey,keyboard-interactive,password"); config.put("PreferredAuthentications", "gssapi-with-mic,publickey,keyboard-interactive,password");
config.put("CheckCiphers", "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256"); config.put("CheckCiphers", "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,3des-ctr,arcfour,arcfour128,arcfour256");
config.put("CheckKexes", "diffie-hellman-group14-sha1"); config.put("CheckKexes", "diffie-hellman-group14-sha1,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521");
config.put("CheckSignatures", "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521");
config.put("MaxAuthTries", "6"); config.put("MaxAuthTries", "6");
config.put("ClearAllForwardings", "no"); config.put("ClearAllForwardings", "no");
@@ -171,7 +187,9 @@ public class JSch{
static Logger logger=DEVNULL; static Logger logger=DEVNULL;
public JSch(){ public JSch(){
/*
// The JCE of Sun's Java5 on Mac OS X has the resource leak bug
// in calculating HMAC, so we need to use our own implementations.
try{ try{
String osname=(String)(System.getProperties().get("os.name")); String osname=(String)(System.getProperties().get("os.name"));
if(osname!=null && osname.equals("Mac OS X")){ if(osname!=null && osname.equals("Mac OS X")){
@@ -183,7 +201,7 @@ public class JSch{
} }
catch(Exception e){ catch(Exception e){
} }
*/
} }
/** /**

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -70,19 +70,24 @@ public abstract class KeyExchange{
public abstract void init(Session session, public abstract void init(Session session,
byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception; byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception;
public abstract boolean next(Buffer buf) throws Exception; public abstract boolean next(Buffer buf) throws Exception;
public abstract String getKeyType();
public abstract int getState(); public abstract int getState();
/* protected final int RSA=0;
void dump(byte[] foo){ protected final int DSS=1;
for(int i=0; i<foo.length; i++){ protected final int ECDSA=2;
if((foo[i]&0xf0)==0)System.err.print("0"); private int type=0;
System.err.print(Integer.toHexString(foo[i]&0xff)); private String key_alg_name = "";
if(i%16==15){System.err.println(""); continue;}
if(i%2==1)System.err.print(" "); public String getKeyType() {
if(type==DSS) return "DSA";
if(type==RSA) return "RSA";
return "ECDSA";
} }
public String getKeyAlgorithName() {
return key_alg_name;
} }
*/
protected static String[] guess(byte[]I_S, byte[]I_C){ protected static String[] guess(byte[]I_S, byte[]I_C){
String[] guess=new String[PROPOSAL_MAX]; String[] guess=new String[PROPOSAL_MAX];
@@ -176,8 +181,145 @@ public abstract class KeyExchange{
secret[0] == 0 && (secret[1]&0x80) == 0) { secret[0] == 0 && (secret[1]&0x80) == 0) {
byte[] tmp=new byte[secret.length-1]; byte[] tmp=new byte[secret.length-1];
System.arraycopy(secret, 1, tmp, 0, tmp.length); System.arraycopy(secret, 1, tmp, 0, tmp.length);
secret=tmp; return normalize(tmp);
} }
else {
return secret; return secret;
} }
} }
protected boolean verify(String alg, byte[] K_S, int index,
byte[] sig_of_H) throws Exception {
int i,j;
i=index;
boolean result=false;
if(alg.equals("ssh-rsa")){
byte[] tmp;
byte[] ee;
byte[] n;
type=RSA;
key_alg_name=alg;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
ee=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
n=tmp;
SignatureRSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.rsa"));
sig=(SignatureRSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(ee, n);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_rsa_verify: signature "+result);
}
}
else if(alg.equals("ssh-dss")){
byte[] q=null;
byte[] tmp;
byte[] p;
byte[] g;
byte[] f;
type=DSS;
key_alg_name=alg;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
p=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
q=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
g=tmp;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
f=tmp;
SignatureDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.dss"));
sig=(SignatureDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(f, p, q, g);
sig.update(H);
result=sig.verify(sig_of_H);
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"ssh_dss_verify: signature "+result);
}
}
else if(alg.equals("ecdsa-sha2-nistp256") ||
alg.equals("ecdsa-sha2-nistp384") ||
alg.equals("ecdsa-sha2-nistp521")) {
byte[] tmp;
byte[] r;
byte[] s;
// RFC 5656,
type=ECDSA;
key_alg_name=alg;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j;
j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
i++;
tmp=new byte[(j-1)/2];
System.arraycopy(K_S, i, tmp, 0, tmp.length); i+=(j-1)/2;
r=tmp;
tmp=new byte[(j-1)/2];
System.arraycopy(K_S, i, tmp, 0, tmp.length); i+=(j-1)/2;
s=tmp;
SignatureECDSA sig=null;
try{
Class c=Class.forName(session.getConfig("signature.ecdsa"));
sig=(SignatureECDSA)(c.newInstance());
sig.init();
}
catch(Exception e){
System.err.println(e);
}
sig.setPubKey(r, s);
sig.update(H);
result=sig.verify(sig_of_H);
}
else{
System.err.println("unknown alg");
}
return result;
}
}

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -38,11 +38,13 @@ public abstract class KeyPair{
public static final int ERROR=0; public static final int ERROR=0;
public static final int DSA=1; public static final int DSA=1;
public static final int RSA=2; public static final int RSA=2;
public static final int UNKNOWN=3; public static final int ECDSA=3;
public static final int UNKNOWN=4;
static final int VENDOR_OPENSSH=0; static final int VENDOR_OPENSSH=0;
static final int VENDOR_FSECURE=1; static final int VENDOR_FSECURE=1;
static final int VENDOR_PUTTY=2; static final int VENDOR_PUTTY=2;
static final int VENDOR_PKCS8=3;
int vendor=VENDOR_OPENSSH; int vendor=VENDOR_OPENSSH;
@@ -55,6 +57,7 @@ public abstract class KeyPair{
KeyPair kpair=null; KeyPair kpair=null;
if(type==DSA){ kpair=new KeyPairDSA(jsch); } if(type==DSA){ kpair=new KeyPairDSA(jsch); }
else if(type==RSA){ kpair=new KeyPairRSA(jsch); } else if(type==RSA){ kpair=new KeyPairRSA(jsch); }
else if(type==ECDSA){ kpair=new KeyPairECDSA(jsch); }
if(kpair!=null){ if(kpair!=null){
kpair.generate(key_size); kpair.generate(key_size);
} }
@@ -338,6 +341,22 @@ public abstract class KeyPair{
return index; return index;
} }
int writeOCTETSTRING(byte[] buf, int index, byte[] data){
buf[index++]=0x04;
index=writeLength(buf, index, data.length);
System.arraycopy(data, 0, buf, index, data.length);
index+=data.length;
return index;
}
int writeDATA(byte[] buf, byte n, int index, byte[] data){
buf[index++]=n;
index=writeLength(buf, index, data.length);
System.arraycopy(data, 0, buf, index, data.length);
index+=data.length;
return index;
}
int countLength(int len){ int countLength(int len){
int i=1; int i=1;
if(len<=0x7f) return i; if(len<=0x7f) return i;
@@ -474,8 +493,8 @@ public abstract class KeyPair{
this.passphrase=passphrase; this.passphrase=passphrase;
} }
private boolean encrypted=false; protected boolean encrypted=false;
private byte[] data=null; protected byte[] data=null;
private byte[] iv=null; private byte[] iv=null;
private byte[] publickeyblob=null; private byte[] publickeyblob=null;
@@ -563,7 +582,8 @@ public abstract class KeyPair{
if(pubkey==null && if(pubkey==null &&
prvkey!=null && prvkey!=null &&
(prvkey.length>11 && (prvkey.length>11 &&
prvkey[0]==0 && prvkey[1]==0 && prvkey[2]==0 && prvkey[3]==7)){ prvkey[0]==0 && prvkey[1]==0 && prvkey[2]==0 &&
(prvkey[3]==7 || prvkey[3]==19))){
Buffer buf=new Buffer(prvkey); Buffer buf=new Buffer(prvkey);
buf.skip(prvkey.length); // for using Buffer#available() buf.skip(prvkey.length); // for using Buffer#available()
@@ -577,6 +597,11 @@ public abstract class KeyPair{
else if(_type.equals("ssh-dss")){ else if(_type.equals("ssh-dss")){
kpair=KeyPairDSA.fromSSHAgent(jsch, buf); kpair=KeyPairDSA.fromSSHAgent(jsch, buf);
} }
else if(_type.equals("ecdsa-sha2-nistp256") ||
_type.equals("ecdsa-sha2-nistp384") ||
_type.equals("ecdsa-sha2-nistp512")){
kpair=KeyPairECDSA.fromSSHAgent(jsch, buf);
}
else{ else{
throw new JSchException("privatekey: invalid key "+new String(prvkey, 4, 7)); throw new JSchException("privatekey: invalid key "+new String(prvkey, 4, 7));
} }
@@ -612,10 +637,29 @@ public abstract class KeyPair{
throw new JSchException("invalid privatekey: "+prvkey); throw new JSchException("invalid privatekey: "+prvkey);
if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSA; } if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSA; }
else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; } else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; }
else if(buf[i]=='E'&& buf[i+1]=='C'){ type=ECDSA; }
else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H'){ // FSecure else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H'){ // FSecure
type=UNKNOWN; type=UNKNOWN;
vendor=VENDOR_FSECURE; vendor=VENDOR_FSECURE;
} }
else if(i+6 < len &&
buf[i]=='P' && buf[i+1]=='R' &&
buf[i+2]=='I' && buf[i+3]=='V' &&
buf[i+4]=='A' && buf[i+5]=='T' && buf[i+6]=='E'){
type=UNKNOWN;
vendor=VENDOR_PKCS8;
encrypted=false;
i+=3;
}
else if(i+8 < len &&
buf[i]=='E' && buf[i+1]=='N' &&
buf[i+2]=='C' && buf[i+3]=='R' &&
buf[i+4]=='Y' && buf[i+5]=='P' && buf[i+6]=='T' &&
buf[i+7]=='E' && buf[i+8]=='D'){
type=UNKNOWN;
vendor=VENDOR_PKCS8;
i+=5;
}
else{ else{
throw new JSchException("invalid privatekey: "+prvkey); throw new JSchException("invalid privatekey: "+prvkey);
} }
@@ -689,6 +733,7 @@ public abstract class KeyPair{
} }
if(!inheader){ if(!inheader){
i++; i++;
if(vendor!=VENDOR_PKCS8)
encrypted=false; // no passphrase encrypted=false; // no passphrase
break; break;
} }
@@ -724,12 +769,8 @@ public abstract class KeyPair{
while(i<_len){ while(i<_len){
if(_buf[i]==0x0a){ if(_buf[i]==0x0a){
boolean xd=(_buf[i-1]==0x0d); boolean xd=(_buf[i-1]==0x0d);
// move 0x0a (or 0x0d0x0a) to the end of '_buf'. // ignore 0x0a (or 0x0d0x0a)
System.arraycopy(_buf, i+1, System.arraycopy(_buf, i+1, _buf, i-(xd ? 1 : 0), _len-(i+1));
_buf,
i-(xd ? 1 : 0),
_len-i-1-(xd ? 1 : 0)
);
if(xd)_len--; if(xd)_len--;
_len--; _len--;
continue; continue;
@@ -841,7 +882,28 @@ public abstract class KeyPair{
if(i++<len){ if(i++<len){
int start=i; int start=i;
while(i<len){ if(buf[i]=='\n')break; i++;} while(i<len){ if(buf[i]=='\n')break; i++;}
if(i>0 && buf[i-1]==0x0d) i--;
if(start<i){
publicKeyComment = new String(buf, start, i-start);
}
}
}
else if(buf[0]=='e'&& buf[1]=='c'&& buf[2]=='d' && buf[3]=='s'){
if(prvkey==null && buf.length>7){
type=ECDSA;
}
i=0;
while(i<len){ if(buf[i]==' ')break; i++;} i++;
if(i<len){ if(i<len){
int start=i;
while(i<len){ if(buf[i]==' ')break; i++;}
publickeyblob=Util.fromBase64(buf, start, i-start);
}
if(i++<len){
int start=i;
while(i<len){ if(buf[i]=='\n')break; i++;}
if(i>0 && buf[i-1]==0x0d) i--;
if(start<i){
publicKeyComment = new String(buf, start, i-start); publicKeyComment = new String(buf, start, i-start);
} }
} }
@@ -862,6 +924,8 @@ public abstract class KeyPair{
KeyPair kpair=null; KeyPair kpair=null;
if(type==DSA){ kpair=new KeyPairDSA(jsch); } if(type==DSA){ kpair=new KeyPairDSA(jsch); }
else if(type==RSA){ kpair=new KeyPairRSA(jsch); } else if(type==RSA){ kpair=new KeyPairRSA(jsch); }
else if(type==ECDSA){ kpair=new KeyPairECDSA(jsch); }
else if(vendor==VENDOR_PKCS8){ kpair = new KeyPairPKCS8(jsch); }
if(kpair!=null){ if(kpair!=null){
kpair.encrypted=encrypted; kpair.encrypted=encrypted;
@@ -1101,4 +1165,91 @@ public abstract class KeyPair{
return (key != null && value != null); return (key != null && value != null);
} }
void copy(KeyPair kpair){
this.publickeyblob=kpair.publickeyblob;
this.vendor=kpair.vendor;
this.publicKeyComment=kpair.publicKeyComment;
this.cipher=kpair.cipher;
}
class ASN1Exception extends Exception {
}
class ASN1 {
byte[] buf;
int start;
int length;
ASN1(byte[] buf) throws ASN1Exception {
this(buf, 0, buf.length);
}
ASN1(byte[] buf, int start, int length) throws ASN1Exception {
this.buf = buf;
this.start = start;
this.length = length;
if(start+length>buf.length)
throw new ASN1Exception();
}
int getType() {
return buf[start]&0xff;
}
boolean isSEQUENCE() {
return getType()==(0x30&0xff);
}
boolean isINTEGER() {
return getType()==(0x02&0xff);
}
boolean isOBJECT() {
return getType()==(0x06&0xff);
}
boolean isOCTETSTRING() {
return getType()==(0x04&0xff);
}
private int getLength(int[] indexp) {
int index=indexp[0];
int length=buf[index++]&0xff;
if((length&0x80)!=0) {
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(buf[index++]&0xff); }
}
indexp[0]=index;
return length;
}
byte[] getContent() {
int[] indexp=new int[1];
indexp[0]=start+1;
int length = getLength(indexp);
int index=indexp[0];
byte[] tmp = new byte[length];
System.arraycopy(buf, index, tmp, 0, tmp.length);
return tmp;
}
ASN1[] getContents() throws ASN1Exception {
int typ = buf[start];
int[] indexp=new int[1];
indexp[0]=start+1;
int length = getLength(indexp);
if(typ == 0x05){
return new ASN1[0];
}
int index=indexp[0];
java.util.Vector values = new java.util.Vector();
while(length>0) {
index++; length--;
int tmp=index;
indexp[0]=index;
int l=getLength(indexp);
index=indexp[0];
length-=(index-tmp);
values.addElement(new ASN1(buf, tmp-1, 1+(index-tmp)+l));
index+=l;
length-=l;
}
ASN1[] result = new ASN1[values.size()];
for(int i = 0; i <values.size(); i++) {
result[i]=(ASN1)values.elementAt(i);
}
return result;
}
}
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -0,0 +1,391 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public class KeyPairECDSA extends KeyPair{
private static byte[][] oids = {
{(byte)0x06, (byte)0x08, (byte)0x2a, (byte)0x86, (byte)0x48, // 256
(byte)0xce, (byte)0x3d, (byte)0x03, (byte)0x01, (byte)0x07},
{(byte)0x06, (byte)0x05, (byte)0x2b, (byte)0x81, (byte)0x04, // 384
(byte)0x00, (byte)0x22},
{(byte)0x06, (byte)0x05, (byte)0x2b, (byte)0x81, (byte)0x04, //521
(byte)0x00, (byte)0x23},
};
private static String[] names = {
"nistp256", "nistp384", "nistp521"
};
private byte[] name=Util.str2byte(names[0]);
private byte[] r_array;
private byte[] s_array;
private byte[] prv_array;
private int key_size=256;
public KeyPairECDSA(JSch jsch){
this(jsch, null, null, null, null);
}
public KeyPairECDSA(JSch jsch,
byte[] name,
byte[] r_array,
byte[] s_array,
byte[] prv_array){
super(jsch);
if(name!=null)
this.name = name;
this.r_array = r_array;
this.s_array = s_array;
this.prv_array = prv_array;
if(prv_array!=null)
key_size = prv_array.length>=64 ? 521 :
(prv_array.length>=48 ? 384 : 256);
}
void generate(int key_size) throws JSchException{
this.key_size=key_size;
try{
Class c=Class.forName(jsch.getConfig("keypairgen.ecdsa"));
KeyPairGenECDSA keypairgen=(KeyPairGenECDSA)(c.newInstance());
keypairgen.init(key_size);
prv_array=keypairgen.getD();
r_array=keypairgen.getR();
s_array=keypairgen.getS();
name=Util.str2byte(names[prv_array.length>=64 ? 2 :
(prv_array.length>=48 ? 1 : 0)]);
keypairgen=null;
}
catch(Exception e){
if(e instanceof Throwable)
throw new JSchException(e.toString(), (Throwable)e);
throw new JSchException(e.toString());
}
}
private static final byte[] begin =
Util.str2byte("-----BEGIN EC PRIVATE KEY-----");
private static final byte[] end =
Util.str2byte("-----END EC PRIVATE KEY-----");
byte[] getBegin(){ return begin; }
byte[] getEnd(){ return end; }
byte[] getPrivateKey(){
byte[] tmp = new byte[1]; tmp[0]=1;
byte[] oid = oids[
(r_array.length>=64) ? 2 :
((r_array.length>=48) ? 1 : 0)
];
byte[] point = toPoint(r_array, s_array);
int bar = ((point.length+1)&0x80)==0 ? 3 : 4;
byte[] foo = new byte[point.length+bar];
System.arraycopy(point, 0, foo, bar, point.length);
foo[0]=0x03; // BITSTRING
if(bar==3){
foo[1]=(byte)(point.length+1);
}
else {
foo[1]=(byte)0x81;
foo[2]=(byte)(point.length+1);
}
point = foo;
int content=
1+countLength(tmp.length) + tmp.length +
1+countLength(prv_array.length) + prv_array.length +
1+countLength(oid.length) + oid.length +
1+countLength(point.length) + point.length;
int total=
1+countLength(content)+content; // SEQUENCE
byte[] plain=new byte[total];
int index=0;
index=writeSEQUENCE(plain, index, content);
index=writeINTEGER(plain, index, tmp);
index=writeOCTETSTRING(plain, index, prv_array);
index=writeDATA(plain, (byte)0xa0, index, oid);
index=writeDATA(plain, (byte)0xa1, index, point);
return plain;
}
boolean parse(byte[] plain){
try{
if(vendor==VENDOR_FSECURE){
/*
if(plain[0]!=0x30){ // FSecure
return true;
}
return false;
*/
return false;
}
else if(vendor==VENDOR_PUTTY){
/*
Buffer buf=new Buffer(plain);
buf.skip(plain.length);
try {
byte[][] tmp = buf.getBytes(1, "");
prv_array = tmp[0];
}
catch(JSchException e){
return false;
}
return true;
*/
return false;
}
int index=0;
int length=0;
if(plain[index]!=0x30)return false;
index++; // SEQUENCE
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
if(plain[index]!=0x02)return false;
index++; // INTEGER
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
index+=length;
index++; // 0x04
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
prv_array=new byte[length];
System.arraycopy(plain, index, prv_array, 0, length);
index+=length;
index++; // 0xa0
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
byte[] oid_array=new byte[length];
System.arraycopy(plain, index, oid_array, 0, length);
index+=length;
for(int i = 0; i<oids.length; i++){
if(Util.array_equals(oids[i], oid_array)){
name = Util.str2byte(names[i]);
break;
}
}
index++; // 0xa1
length=plain[index++]&0xff;
if((length&0x80)!=0){
int foo=length&0x7f; length=0;
while(foo-->0){ length=(length<<8)+(plain[index++]&0xff); }
}
byte[] Q_array=new byte[length];
System.arraycopy(plain, index, Q_array, 0, length);
index+=length;
byte[][] tmp = fromPoint(Q_array);
r_array = tmp[0];
s_array = tmp[1];
if(prv_array!=null)
key_size = prv_array.length>=64 ? 521 :
(prv_array.length>=48 ? 384 : 256);
}
catch(Exception e){
//System.err.println(e);
//e.printStackTrace();
return false;
}
return true;
}
public byte[] getPublicKeyBlob(){
byte[] foo = super.getPublicKeyBlob();
if(foo!=null) return foo;
if(r_array==null) return null;
byte[][] tmp = new byte[3][];
tmp[0] = Util.str2byte("ecdsa-sha2-"+new String(name));
tmp[1] = name;
tmp[2] = new byte[1+r_array.length+s_array.length];
tmp[2][0] = 4; // POINT_CONVERSION_UNCOMPRESSED
System.arraycopy(r_array, 0, tmp[2], 1, r_array.length);
System.arraycopy(s_array, 0, tmp[2], 1+r_array.length, s_array.length);
return Buffer.fromBytes(tmp).buffer;
}
byte[] getKeyTypeName(){
return Util.str2byte("ecdsa-sha2-"+new String(name));
}
public int getKeyType(){
return ECDSA;
}
public int getKeySize(){
return key_size;
}
public byte[] getSignature(byte[] data){
try{
Class c=Class.forName((String)jsch.getConfig("signature.ecdsa"));
SignatureECDSA ecdsa=(SignatureECDSA)(c.newInstance());
ecdsa.init();
ecdsa.setPrvKey(prv_array);
ecdsa.update(data);
byte[] sig = ecdsa.sign();
byte[][] tmp = new byte[2][];
tmp[0] = Util.str2byte("ecdsa-sha2-"+new String(name));
tmp[1] = sig;
return Buffer.fromBytes(tmp).buffer;
}
catch(Exception e){
//System.err.println("e "+e);
}
return null;
}
public Signature getVerifier(){
try{
Class c=Class.forName((String)jsch.getConfig("signature.ecdsa"));
final SignatureECDSA ecdsa=(SignatureECDSA)(c.newInstance());
ecdsa.init();
if(r_array == null && s_array == null && getPublicKeyBlob()!=null){
Buffer buf = new Buffer(getPublicKeyBlob());
buf.getString(); // ecdsa-sha2-nistp256
buf.getString(); // nistp256
byte[][] tmp = fromPoint(buf.getString());
r_array = tmp[0];
s_array = tmp[1];
}
ecdsa.setPubKey(r_array, s_array);
return ecdsa;
}
catch(Exception e){
//System.err.println("e "+e);
}
return null;
}
static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException {
byte[][] tmp = buf.getBytes(5, "invalid key format");
byte[] name = tmp[1]; // nistp256
byte[][] foo = fromPoint(tmp[2]);
byte[] r_array = foo[0];
byte[] s_array = foo[1];
byte[] prv_array = tmp[3];
KeyPairECDSA kpair = new KeyPairECDSA(jsch,
name,
r_array, s_array,
prv_array);
kpair.publicKeyComment = new String(tmp[4]);
kpair.vendor=VENDOR_OPENSSH;
return kpair;
}
public byte[] forSSHAgent() throws JSchException {
if(isEncrypted()){
throw new JSchException("key is encrypted.");
}
Buffer buf = new Buffer();
buf.putString(Util.str2byte("ecdsa-sha2-"+new String(name)));
buf.putString(name);
buf.putString(toPoint(r_array, s_array));
buf.putString(prv_array);
buf.putString(Util.str2byte(publicKeyComment));
byte[] result = new byte[buf.getLength()];
buf.getByte(result, 0, result.length);
return result;
}
static byte[] toPoint(byte[] r_array, byte[] s_array) {
byte[] tmp = new byte[1+r_array.length+s_array.length];
tmp[0]=0x04;
System.arraycopy(r_array, 0, tmp, 1, r_array.length);
System.arraycopy(s_array, 0, tmp, 1+r_array.length, s_array.length);
return tmp;
}
static byte[][] fromPoint(byte[] point) {
int i = 0;
while(point[i]!=4) i++;
i++;
byte[][] tmp = new byte[2][];
byte[] r_array = new byte[(point.length-i)/2];
byte[] s_array = new byte[(point.length-i)/2];
// point[0] == 0x04 == POINT_CONVERSION_UNCOMPRESSED
System.arraycopy(point, i, r_array, 0, r_array.length);
System.arraycopy(point, i+r_array.length, s_array, 0, s_array.length);
tmp[0] = r_array;
tmp[1] = s_array;
return tmp;
}
public void dispose(){
super.dispose();
Util.bzero(prv_array);
}
}

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -0,0 +1,37 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface KeyPairGenECDSA{
void init(int key_size) throws Exception;
byte[] getD();
byte[] getR();
byte[] getS();
}

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -0,0 +1,363 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2013-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
import java.util.Vector;
import java.math.BigInteger;
public class KeyPairPKCS8 extends KeyPair {
private static final byte[] rsaEncryption = {
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86,
(byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01, (byte)0x01
};
private static final byte[] dsaEncryption = {
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0xce,
(byte)0x38, (byte)0x04, (byte)0x1
};
private static final byte[] pbes2 = {
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7,
(byte)0x0d, (byte)0x01, (byte)0x05, (byte)0x0d
};
private static final byte[] pbkdf2 = {
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7,
(byte)0x0d, (byte)0x01, (byte)0x05, (byte)0x0c
};
private static final byte[] aes128cbc = {
(byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65,
(byte)0x03, (byte)0x04, (byte)0x01, (byte)0x02
};
private static final byte[] aes192cbc = {
(byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65,
(byte)0x03, (byte)0x04, (byte)0x01, (byte)0x16
};
private static final byte[] aes256cbc = {
(byte)0x60, (byte)0x86, (byte)0x48, (byte)0x01, (byte)0x65,
(byte)0x03, (byte)0x04, (byte)0x01, (byte)0x2a
};
private static final byte[] pbeWithMD5AndDESCBC = {
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7,
(byte)0x0d, (byte)0x01, (byte)0x05, (byte)0x03
};
private KeyPair kpair = null;
public KeyPairPKCS8(JSch jsch){
super(jsch);
}
void generate(int key_size) throws JSchException{
}
private static final byte[] begin=Util.str2byte("-----BEGIN DSA PRIVATE KEY-----");
private static final byte[] end=Util.str2byte("-----END DSA PRIVATE KEY-----");
byte[] getBegin(){ return begin; }
byte[] getEnd(){ return end; }
byte[] getPrivateKey(){
return null;
}
boolean parse(byte[] plain){
/* from RFC5208
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL
}
Version ::= INTEGER
PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
PrivateKey ::= OCTET STRING
Attributes ::= SET OF Attribute
}
*/
try{
Vector values = new Vector();
ASN1[] contents = null;
ASN1 asn1 = new ASN1(plain);
contents = asn1.getContents();
ASN1 privateKeyAlgorithm = contents[1];
ASN1 privateKey = contents[2];
contents = privateKeyAlgorithm.getContents();
byte[] privateKeyAlgorithmID = contents[0].getContent();
contents = contents[1].getContents();
if(contents.length>0){
for(int i = 0; i < contents.length; i++){
values.addElement(contents[i].getContent());
}
}
byte[] _data = privateKey.getContent();
KeyPair _kpair = null;
if(Util.array_equals(privateKeyAlgorithmID, rsaEncryption)){
_kpair = new KeyPairRSA(jsch);
_kpair.copy(this);
if(_kpair.parse(_data)){
kpair = _kpair;
}
}
else if(Util.array_equals(privateKeyAlgorithmID, dsaEncryption)){
asn1 = new ASN1(_data);
if(values.size() == 0) { // embedded DSA parameters format
/*
SEQUENCE
SEQUENCE
INTEGER // P_array
INTEGER // Q_array
INTEGER // G_array
INTEGER // prv_array
*/
contents = asn1.getContents();
byte[] bar = contents[1].getContent();
contents = contents[0].getContents();
for(int i = 0; i < contents.length; i++){
values.addElement(contents[i].getContent());
}
values.addElement(bar);
}
else {
/*
INTEGER // prv_array
*/
values.addElement(asn1.getContent());
}
byte[] P_array = (byte[])values.elementAt(0);
byte[] Q_array = (byte[])values.elementAt(1);
byte[] G_array = (byte[])values.elementAt(2);
byte[] prv_array = (byte[])values.elementAt(3);
// Y = g^X mode p
byte[] pub_array =
(new BigInteger(G_array)).
modPow(new BigInteger(prv_array), new BigInteger(P_array)).
toByteArray();
KeyPairDSA _key = new KeyPairDSA(jsch,
P_array, Q_array, G_array,
pub_array, prv_array);
plain = _key.getPrivateKey();
_kpair = new KeyPairDSA(jsch);
_kpair.copy(this);
if(_kpair.parse(plain)){
kpair = _kpair;
}
}
}
catch(ASN1Exception e){
return false;
}
catch(Exception e){
//System.err.println(e);
return false;
}
return kpair != null;
}
public byte[] getPublicKeyBlob(){
return kpair.getPublicKeyBlob();
}
byte[] getKeyTypeName(){ return kpair.getKeyTypeName();}
public int getKeyType(){return kpair.getKeyType();}
public int getKeySize(){
return kpair.getKeySize();
}
public byte[] getSignature(byte[] data){
return kpair.getSignature(data);
}
public Signature getVerifier(){
return kpair.getVerifier();
}
public byte[] forSSHAgent() throws JSchException {
return kpair.forSSHAgent();
}
public boolean decrypt(byte[] _passphrase){
if(!isEncrypted()){
return true;
}
if(_passphrase==null){
return !isEncrypted();
}
/*
SEQUENCE
SEQUENCE
OBJECT :PBES2
SEQUENCE
SEQUENCE
OBJECT :PBKDF2
SEQUENCE
OCTET STRING [HEX DUMP]:E4E24ADC9C00BD4D
INTEGER :0800
SEQUENCE
OBJECT :aes-128-cbc
OCTET STRING [HEX DUMP]:5B66E6B3BF03944C92317BC370CC3AD0
OCTET STRING [HEX DUMP]:
or
SEQUENCE
SEQUENCE
OBJECT :pbeWithMD5AndDES-CBC
SEQUENCE
OCTET STRING [HEX DUMP]:DBF75ECB69E3C0FC
INTEGER :0800
OCTET STRING [HEX DUMP]
*/
try{
ASN1[] contents = null;
ASN1 asn1 = new ASN1(data);
contents = asn1.getContents();
byte[] _data = contents[1].getContent();
ASN1 pbes = contents[0];
contents = pbes.getContents();
byte[] pbesid = contents[0].getContent();
ASN1 pbesparam = contents[1];
byte[] salt = null;
int iterations = 0;
byte[] iv = null;
byte[] encryptfuncid = null;
if(Util.array_equals(pbesid, pbes2)){
contents = pbesparam.getContents();
ASN1 pbkdf = contents[0];
ASN1 encryptfunc = contents[1];
contents = pbkdf.getContents();
byte[] pbkdfid = contents[0].getContent();
ASN1 pbkdffunc = contents[1];
contents = pbkdffunc.getContents();
salt = contents[0].getContent();
iterations =
Integer.parseInt((new BigInteger(contents[1].getContent())).toString());
contents = encryptfunc.getContents();
encryptfuncid = contents[0].getContent();
iv = contents[1].getContent();
}
else if(Util.array_equals(pbesid, pbeWithMD5AndDESCBC)){
// not supported
return false;
}
else {
return false;
}
Cipher cipher=getCipher(encryptfuncid);
if(cipher==null) return false;
byte[] key=null;
try{
Class c=Class.forName((String)jsch.getConfig("pbkdf"));
PBKDF tmp=(PBKDF)(c.newInstance());
key = tmp.getKey(_passphrase, salt, iterations, cipher.getBlockSize());
}
catch(Exception ee){
}
if(key==null){
return false;
}
cipher.init(Cipher.DECRYPT_MODE, key, iv);
Util.bzero(key);
byte[] plain=new byte[_data.length];
cipher.update(_data, 0, _data.length, plain, 0);
if(parse(plain)){
encrypted=false;
return true;
}
}
catch(ASN1Exception e){
// System.err.println(e);
}
catch(Exception e){
// System.err.println(e);
}
return false;
}
Cipher getCipher(byte[] id){
Cipher cipher=null;
String name = null;
try{
if(Util.array_equals(id, aes128cbc)){
name="aes128-cbc";
}
else if(Util.array_equals(id, aes192cbc)){
name="aes192-cbc";
}
else if(Util.array_equals(id, aes256cbc)){
name="aes256-cbc";
}
Class c=Class.forName((String)jsch.getConfig(name));
cipher=(Cipher)(c.newInstance());
}
catch(Exception e){
if(JSch.getLogger().isEnabled(Logger.FATAL)){
String message="";
if(name==null){
message="unknown oid: "+Util.toHex(id);
}
else {
message="function "+name+" is not supported";
}
JSch.getLogger().log(Logger.FATAL, "PKCS8: "+message);
}
}
return cipher;
}
}

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -35,12 +35,6 @@ public
class KnownHosts implements HostKeyRepository{ class KnownHosts implements HostKeyRepository{
private static final String _known_hosts="known_hosts"; private static final String _known_hosts="known_hosts";
/*
static final int SSHDSS=0;
static final int SSHRSA=1;
static final int UNKNOWN=2;
*/
private JSch jsch=null; private JSch jsch=null;
private String known_hosts=null; private String known_hosts=null;
private java.util.Vector pool=null; private java.util.Vector pool=null;
@@ -50,26 +44,28 @@ class KnownHosts implements HostKeyRepository{
KnownHosts(JSch jsch){ KnownHosts(JSch jsch){
super(); super();
this.jsch=jsch; this.jsch=jsch;
this.hmacsha1 = getHMACSHA1();
pool=new java.util.Vector(); pool=new java.util.Vector();
} }
void setKnownHosts(String foo) throws JSchException{ void setKnownHosts(String filename) throws JSchException{
try{ try{
known_hosts = foo; known_hosts = filename;
FileInputStream fis=new FileInputStream(Util.checkTilde(foo)); FileInputStream fis=new FileInputStream(Util.checkTilde(filename));
setKnownHosts(fis); setKnownHosts(fis);
} }
catch(FileNotFoundException e){ catch(FileNotFoundException e){
// The non-existing file should be allowed.
} }
} }
void setKnownHosts(InputStream foo) throws JSchException{ void setKnownHosts(InputStream input) throws JSchException{
pool.removeAllElements(); pool.removeAllElements();
StringBuffer sb=new StringBuffer(); StringBuffer sb=new StringBuffer();
byte i; byte i;
int j; int j;
boolean error=false; boolean error=false;
try{ try{
InputStream fis=foo; InputStream fis=input;
String host; String host;
String key=null; String key=null;
int type; int type;
@@ -158,8 +154,10 @@ loop:
if(i==0x20 || i=='\t'){ break; } if(i==0x20 || i=='\t'){ break; }
sb.append((char)i); sb.append((char)i);
} }
if(sb.toString().equals("ssh-dss")){ type=HostKey.SSHDSS; } String tmp = sb.toString();
else if(sb.toString().equals("ssh-rsa")){ type=HostKey.SSHRSA; } if(HostKey.name2type(tmp)!=HostKey.UNKNOWN){
type=HostKey.name2type(tmp);
}
else { j=bufl; } else { j=bufl; }
if(j>=bufl){ if(j>=bufl){
addInvalidLine(Util.byte2str(buf, 0, bufl)); addInvalidLine(Util.byte2str(buf, 0, bufl));
@@ -223,7 +221,6 @@ loop:
key.length()), comment); key.length()), comment);
pool.addElement(hk); pool.addElement(hk);
} }
fis.close();
if(error){ if(error){
throw new JSchException("KnownHosts: invalid format"); throw new JSchException("KnownHosts: invalid format");
} }
@@ -235,6 +232,12 @@ loop:
throw new JSchException(e.toString(), (Throwable)e); throw new JSchException(e.toString(), (Throwable)e);
throw new JSchException(e.toString()); throw new JSchException(e.toString());
} }
finally {
try{ input.close(); }
catch(IOException e){
throw new JSchException(e.toString(), (Throwable)e);
}
}
} }
private void addInvalidLine(String line) throws JSchException { private void addInvalidLine(String line) throws JSchException {
HostKey hk = new HostKey(line, HostKey.UNKNOWN, null); HostKey hk = new HostKey(line, HostKey.UNKNOWN, null);
@@ -249,14 +252,19 @@ loop:
return result; return result;
} }
int type=getType(key); HostKey hk = null;
HostKey hk; try {
hk = new HostKey(host, HostKey.GUESS, key);
}
catch(JSchException e){ // unsupported key
return result;
}
synchronized(pool){ synchronized(pool){
for(int i=0; i<pool.size(); i++){ for(int i=0; i<pool.size(); i++){
hk=(HostKey)(pool.elementAt(i)); HostKey _hk=(HostKey)(pool.elementAt(i));
if(hk.isMatched(host) && hk.type==type){ if(_hk.isMatched(host) && _hk.type==hk.type){
if(Util.array_equals(hk.key, key)){ if(Util.array_equals(_hk.key, key)){
return OK; return OK;
} }
else{ else{
@@ -347,26 +355,28 @@ loop:
} }
public HostKey[] getHostKey(String host, String type){ public HostKey[] getHostKey(String host, String type){
synchronized(pool){ synchronized(pool){
int count=0; java.util.ArrayList v = new java.util.ArrayList();
for(int i=0; i<pool.size(); i++){ for(int i=0; i<pool.size(); i++){
HostKey hk=(HostKey)pool.elementAt(i); HostKey hk=(HostKey)pool.elementAt(i);
if(hk.type==HostKey.UNKNOWN) continue; if(hk.type==HostKey.UNKNOWN) continue;
if(host==null || if(host==null ||
(hk.isMatched(host) && (hk.isMatched(host) &&
(type==null || hk.getType().equals(type)))){ (type==null || hk.getType().equals(type)))){
count++; v.add(hk);
} }
} }
if(count==0)return null; HostKey[] foo = new HostKey[v.size()];
HostKey[] foo=new HostKey[count]; for(int i=0; i<v.size(); i++){
int j=0; foo[i] = (HostKey)v.get(i);
for(int i=0; i<pool.size(); i++){ }
HostKey hk=(HostKey)pool.elementAt(i); if(host != null && host.startsWith("[") && host.indexOf("]:")>1){
if(hk.type==HostKey.UNKNOWN) continue; HostKey[] tmp =
if(host==null || getHostKey(host.substring(1, host.indexOf("]:")), type);
(hk.isMatched(host) && if(tmp.length > 0){
(type==null || hk.getType().equals(type)))){ HostKey[] bar = new HostKey[foo.length + tmp.length];
foo[j++]=hk; System.arraycopy(foo, 0, bar, 0, foo.length);
System.arraycopy(tmp, 0, bar, foo.length, tmp.length);
foo = bar;
} }
} }
return foo; return foo;
@@ -452,11 +462,7 @@ loop:
System.err.println(e); System.err.println(e);
} }
} }
private int getType(byte[] key){
if(key[8]=='d') return HostKey.SSHDSS;
if(key[8]=='r') return HostKey.SSHRSA;
return HostKey.UNKNOWN;
}
private String deleteSubString(String hosts, String host){ private String deleteSubString(String hosts, String host){
int i=0; int i=0;
int hostlen=host.length(); int hostlen=host.length();
@@ -477,7 +483,7 @@ loop:
return hosts; return hosts;
} }
private synchronized MAC getHMACSHA1(){ private MAC getHMACSHA1(){
if(hmacsha1==null){ if(hmacsha1==null){
try{ try{
Class c=Class.forName(jsch.getConfig("hmac-sha1")); Class c=Class.forName(jsch.getConfig("hmac-sha1"));
@@ -503,7 +509,6 @@ loop:
byte[] salt=null; byte[] salt=null;
byte[] hash=null; byte[] hash=null;
HashedHostKey(String host, byte[] key) throws JSchException { HashedHostKey(String host, byte[] key) throws JSchException {
this(host, GUESS, key); this(host, GUESS, key);
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2012-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -50,6 +50,7 @@ class LocalIdentityRepository implements IdentityRepository {
} }
public synchronized Vector getIdentities() { public synchronized Vector getIdentities() {
removeDupulicates();
Vector v = new Vector(); Vector v = new Vector();
for(int i=0; i<identities.size(); i++){ for(int i=0; i<identities.size(); i++){
v.addElement(identities.elementAt(i)); v.addElement(identities.elementAt(i));
@@ -59,6 +60,23 @@ class LocalIdentityRepository implements IdentityRepository {
public synchronized void add(Identity identity) { public synchronized void add(Identity identity) {
if(!identities.contains(identity)) { if(!identities.contains(identity)) {
byte[] blob1 = identity.getPublicKeyBlob();
if(blob1 == null) {
identities.addElement(identity);
return;
}
for(int i = 0; i<identities.size(); i++){
byte[] blob2 = ((Identity)identities.elementAt(i)).getPublicKeyBlob();
if(blob2 != null && Util.array_equals(blob1, blob2)){
if(!identity.isEncrypted() &&
((Identity)identities.elementAt(i)).isEncrypted()){
remove(blob2);
}
else {
return;
}
}
}
identities.addElement(identity); identities.addElement(identity);
} }
} }
@@ -67,7 +85,7 @@ class LocalIdentityRepository implements IdentityRepository {
try{ try{
Identity _identity = Identity _identity =
IdentityFile.newInstance("from remote:", identity, null, jsch); IdentityFile.newInstance("from remote:", identity, null, jsch);
identities.addElement(_identity); add(_identity);
return true; return true;
} }
catch(JSchException e){ catch(JSchException e){
@@ -76,7 +94,13 @@ class LocalIdentityRepository implements IdentityRepository {
} }
synchronized void remove(Identity identity) { synchronized void remove(Identity identity) {
if(identities.contains(identity)) {
identities.removeElement(identity); identities.removeElement(identity);
identity.clear();
}
else {
remove(identity.getPublicKeyBlob());
}
} }
public synchronized boolean remove(byte[] blob) { public synchronized boolean remove(byte[] blob) {
@@ -100,4 +124,28 @@ class LocalIdentityRepository implements IdentityRepository {
} }
identities.removeAllElements(); identities.removeAllElements();
} }
private void removeDupulicates(){
Vector v = new Vector();
int len = identities.size();
if(len == 0) return;
for(int i=0; i<len; i++){
Identity foo = (Identity)identities.elementAt(i);
byte[] foo_blob = foo.getPublicKeyBlob();
if(foo_blob == null) continue;
for(int j=i+1; j<len; j++){
Identity bar = (Identity)identities.elementAt(j);
byte[] bar_blob = bar.getPublicKeyBlob();
if(bar_blob == null) continue;
if(Util.array_equals(foo_blob, bar_blob) &&
foo.isEncrypted() == bar.isEncrypted()){
v.addElement(foo_blob);
break;
}
}
}
for(int i=0; i<v.size(); i++){
remove((byte[])v.elementAt(i));
}
}
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2006-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2013 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2013-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -30,10 +30,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.jcraft.jsch; package com.jcraft.jsch;
import java.io.InputStream; import java.io.InputStream;
import java.io.File; import java.io.Reader;
import java.io.FileInputStream; import java.io.StringReader;
import java.io.ByteArrayInputStream; import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.util.Hashtable; import java.util.Hashtable;
@@ -78,12 +77,12 @@ public class OpenSSHConfig implements ConfigRepository {
* @return an instanceof OpenSSHConfig * @return an instanceof OpenSSHConfig
*/ */
public static OpenSSHConfig parse(String conf) throws IOException { public static OpenSSHConfig parse(String conf) throws IOException {
InputStream in = new ByteArrayInputStream(Util.str2byte(conf)); Reader r = new StringReader(conf);
try { try {
return new OpenSSHConfig(in); return new OpenSSHConfig(r);
} }
finally { finally {
in.close(); r.close();
} }
} }
@@ -94,25 +93,24 @@ public class OpenSSHConfig implements ConfigRepository {
* @return an instanceof OpenSSHConfig * @return an instanceof OpenSSHConfig
*/ */
public static OpenSSHConfig parseFile(String file) throws IOException { public static OpenSSHConfig parseFile(String file) throws IOException {
byte[] conf = Util.fromFile(file); Reader r = new FileReader(Util.checkTilde(file));
InputStream in = new ByteArrayInputStream(conf);
try { try {
return new OpenSSHConfig(in); return new OpenSSHConfig(r);
} }
finally { finally {
in.close(); r.close();
} }
} }
OpenSSHConfig(InputStream in) throws IOException { OpenSSHConfig(Reader r) throws IOException {
_parse(in); _parse(r);
} }
private final Hashtable config = new Hashtable(); private final Hashtable config = new Hashtable();
private final Vector hosts = new Vector(); private final Vector hosts = new Vector();
private void _parse(InputStream in) throws IOException { private void _parse(Reader r) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(in)); BufferedReader br = new BufferedReader(r);
String host = ""; String host = "";
Vector/*<String[]>*/ kv = new Vector(); Vector/*<String[]>*/ kv = new Vector();
@@ -200,12 +198,13 @@ public class OpenSSHConfig implements ConfigRepository {
if(keymap.get(key)!=null) { if(keymap.get(key)!=null) {
key = (String)keymap.get(key); key = (String)keymap.get(key);
} }
key = key.toUpperCase();
String value = null; String value = null;
for(int i = 0; i < _configs.size(); i++) { for(int i = 0; i < _configs.size(); i++) {
Vector v = (Vector)_configs.elementAt(i); Vector v = (Vector)_configs.elementAt(i);
for(int j = 0; j < v.size(); j++) { for(int j = 0; j < v.size(); j++) {
String[] kv = (String[])v.elementAt(j); String[] kv = (String[])v.elementAt(j);
if(kv[0].equals(key)) { if(kv[0].toUpperCase().equals(key)) {
value = kv[1]; value = kv[1];
break; break;
} }
@@ -217,12 +216,13 @@ public class OpenSSHConfig implements ConfigRepository {
} }
private String[] multiFind(String key) { private String[] multiFind(String key) {
key = key.toUpperCase();
Vector value = new Vector(); Vector value = new Vector();
for(int i = 0; i < _configs.size(); i++) { for(int i = 0; i < _configs.size(); i++) {
Vector v = (Vector)_configs.elementAt(i); Vector v = (Vector)_configs.elementAt(i);
for(int j = 0; j < v.size(); j++) { for(int j = 0; j < v.size(); j++) {
String[] kv = (String[])v.elementAt(j); String[] kv = (String[])v.elementAt(j);
if(kv[0].equals(key)) { if(kv[0].toUpperCase().equals(key)) {
String foo = kv[1]; String foo = kv[1];
if(foo != null) { if(foo != null) {
value.remove(foo); value.remove(foo);

View File

@@ -0,0 +1,34 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2013-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface PBKDF {
byte[] getKey(byte[] pass, byte[] salt, int iteration, int size);
}

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2006-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2006-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2005-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -123,7 +123,7 @@ public class Session implements Runnable{
SocketFactory socket_factory=null; SocketFactory socket_factory=null;
static final int buffer_margin = 32 + // maximum padding length static final int buffer_margin = 32 + // maximum padding length
20 + // maximum mac length 64 + // maximum mac length
32; // margin for deflater; deflater may inflate data 32; // margin for deflater; deflater may inflate data
private java.util.Hashtable config=null; private java.util.Hashtable config=null;
@@ -339,9 +339,16 @@ public class Session implements Runnable{
} }
} }
try{ checkHost(host, port, kex); } try{
long tmp=System.currentTimeMillis();
in_prompt = true;
checkHost(host, port, kex);
in_prompt = false;
kex_start_time+=(System.currentTimeMillis()-tmp);
}
catch(JSchException ee){ catch(JSchException ee){
in_kex=false; in_kex=false;
in_prompt = false;
throw ee; throw ee;
} }
@@ -537,19 +544,20 @@ public class Session implements Runnable{
} }
catch(Exception e) { catch(Exception e) {
in_kex=false; in_kex=false;
if(isConnected){
try{ try{
if(isConnected){
String message = e.toString();
packet.reset(); packet.reset();
buf.checkFreeSize(1+4*3+message.length()+2+buffer_margin);
buf.putByte((byte)SSH_MSG_DISCONNECT); buf.putByte((byte)SSH_MSG_DISCONNECT);
buf.putInt(3); buf.putInt(3);
buf.putString(Util.str2byte(e.toString())); buf.putString(Util.str2byte(message));
buf.putString(Util.str2byte("en")); buf.putString(Util.str2byte("en"));
write(packet); write(packet);
disconnect();
}
catch(Exception ee){
} }
} }
catch(Exception ee){}
try{ disconnect(); } catch(Exception ee){ }
isConnected=false; isConnected=false;
//e.printStackTrace(); //e.printStackTrace();
if(e instanceof RuntimeException) throw (RuntimeException)e; if(e instanceof RuntimeException) throw (RuntimeException)e;
@@ -601,7 +609,8 @@ public class Session implements Runnable{
return kex; return kex;
} }
private boolean in_kex=false; private volatile boolean in_kex=false;
private volatile boolean in_prompt=false;
public void rekey() throws Exception { public void rekey() throws Exception {
send_kexinit(); send_kexinit();
} }
@@ -630,6 +639,16 @@ public class Session implements Runnable{
} }
} }
String server_host_key = getConfig("server_host_key");
String[] not_available_shks =
checkSignatures(getConfig("CheckSignatures"));
if(not_available_shks!=null && not_available_shks.length>0){
server_host_key=Util.diffString(server_host_key, not_available_shks);
if(server_host_key==null){
throw new JSchException("There are not any available sig algorithm.");
}
}
in_kex=true; in_kex=true;
kex_start_time=System.currentTimeMillis(); kex_start_time=System.currentTimeMillis();
@@ -653,7 +672,7 @@ public class Session implements Runnable{
random.fill(buf.buffer, buf.index, 16); buf.skip(16); random.fill(buf.buffer, buf.index, 16); buf.skip(16);
} }
buf.putString(Util.str2byte(kex)); buf.putString(Util.str2byte(kex));
buf.putString(Util.str2byte(getConfig("server_host_key"))); buf.putString(Util.str2byte(server_host_key));
buf.putString(Util.str2byte(cipherc2s)); buf.putString(Util.str2byte(cipherc2s));
buf.putString(Util.str2byte(ciphers2c)); buf.putString(Util.str2byte(ciphers2c));
buf.putString(Util.str2byte(getConfig("mac.c2s"))); buf.putString(Util.str2byte(getConfig("mac.c2s")));
@@ -738,7 +757,7 @@ public class Session implements Runnable{
"IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"+ "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"+
"Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"+ "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"+
"It is also possible that the "+key_type+" host key has just been changed.\n"+ "It is also possible that the "+key_type+" host key has just been changed.\n"+
"The fingerprint for the "+key_type+" key sent by the remote host is\n"+ "The fingerprint for the "+key_type+" key sent by the remote host "+chost+" is\n"+
key_fprint+".\n"+ key_fprint+".\n"+
"Please contact your system administrator.\n"+ "Please contact your system administrator.\n"+
"Add correct host key in "+file+" to get rid of this message."; "Add correct host key in "+file+" to get rid of this message.";
@@ -758,7 +777,7 @@ key_fprint+".\n"+
synchronized(hkr){ synchronized(hkr){
hkr.remove(chost, hkr.remove(chost,
(key_type.equals("DSA") ? "ssh-dss" : "ssh-rsa"), kex.getKeyAlgorithName(),
null); null);
insert=true; insert=true;
} }
@@ -796,8 +815,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+
if(i==HostKeyRepository.OK){ if(i==HostKeyRepository.OK){
HostKey[] keys = HostKey[] keys =
hkr.getHostKey(chost, hkr.getHostKey(chost, kex.getKeyAlgorithName());
(key_type.equals("DSA") ? "ssh-dss" : "ssh-rsa"));
String _key= Util.byte2str(Util.toBase64(K_S, 0, K_S.length)); String _key= Util.byte2str(Util.toBase64(K_S, 0, K_S.length));
for(int j=0; j< keys.length; j++){ for(int j=0; j< keys.length; j++){
if(keys[i].getKey().equals(_key) && if(keys[i].getKey().equals(_key) &&
@@ -820,7 +838,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+
if(i==HostKeyRepository.OK && if(i==HostKeyRepository.OK &&
JSch.getLogger().isEnabled(Logger.INFO)){ JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO, JSch.getLogger().log(Logger.INFO,
"Host '"+host+"' is known and mathces the "+key_type+" host key"); "Host '"+host+"' is known and matches the "+key_type+" host key");
} }
if(insert && if(insert &&
@@ -1019,7 +1037,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+
if(c==null){ if(c==null){
} }
else{ else{
c.addRemoteWindowSize(buf.getInt()); c.addRemoteWindowSize(buf.getUInt());
} }
} }
else if(type==UserAuth.SSH_MSG_USERAUTH_SUCCESS){ else if(type==UserAuth.SSH_MSG_USERAUTH_SUCCESS){
@@ -1237,7 +1255,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+
while(true){ while(true){
if(in_kex){ if(in_kex){
if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){ if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){
throw new JSchException("timeout in wating for rekeying process."); throw new JSchException("timeout in waiting for rekeying process.");
} }
try{Thread.sleep(10);} try{Thread.sleep(10);}
catch(java.lang.InterruptedException e){}; catch(java.lang.InterruptedException e){};
@@ -1257,6 +1275,10 @@ key_type+" key fingerprint is "+key_fprint+".\n"+
} }
} }
if(in_kex){
continue;
}
if(c.rwsize>=length){ if(c.rwsize>=length){
c.rwsize-=length; c.rwsize-=length;
break; break;
@@ -1325,8 +1347,11 @@ key_type+" key fingerprint is "+key_fprint+".\n"+
// System.err.println("in_kex="+in_kex+" "+(packet.buffer.getCommand())); // System.err.println("in_kex="+in_kex+" "+(packet.buffer.getCommand()));
long t = getTimeout(); long t = getTimeout();
while(in_kex){ while(in_kex){
if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){ if(t>0L &&
throw new JSchException("timeout in wating for rekeying process."); (System.currentTimeMillis()-kex_start_time)>t &&
!in_prompt
){
throw new JSchException("timeout in waiting for rekeying process.");
} }
byte command=packet.buffer.getCommand(); byte command=packet.buffer.getCommand();
//System.err.println("command: "+command); //System.err.println("command: "+command);
@@ -1494,7 +1519,7 @@ break;
if(channel==null){ if(channel==null){
break; break;
} }
channel.addRemoteWindowSize(buf.getInt()); channel.addRemoteWindowSize(buf.getUInt());
break; break;
case SSH_MSG_CHANNEL_EOF: case SSH_MSG_CHANNEL_EOF:
@@ -1534,26 +1559,22 @@ break;
buf.getShort(); buf.getShort();
i=buf.getInt(); i=buf.getInt();
channel=Channel.getChannel(i, this); channel=Channel.getChannel(i, this);
if(channel==null){
//break;
}
int r=buf.getInt(); int r=buf.getInt();
long rws=buf.getUInt(); long rws=buf.getUInt();
int rps=buf.getInt(); int rps=buf.getInt();
if(channel!=null){
channel.setRemoteWindowSize(rws); channel.setRemoteWindowSize(rws);
channel.setRemotePacketSize(rps); channel.setRemotePacketSize(rps);
channel.open_confirmation=true; channel.open_confirmation=true;
channel.setRecipient(r); channel.setRecipient(r);
}
break; break;
case SSH_MSG_CHANNEL_OPEN_FAILURE: case SSH_MSG_CHANNEL_OPEN_FAILURE:
buf.getInt(); buf.getInt();
buf.getShort(); buf.getShort();
i=buf.getInt(); i=buf.getInt();
channel=Channel.getChannel(i, this); channel=Channel.getChannel(i, this);
if(channel==null){ if(channel!=null){
//break;
}
int reason_code=buf.getInt(); int reason_code=buf.getInt();
//foo=buf.getString(); // additional textual information //foo=buf.getString(); // additional textual information
//foo=buf.getString(); // language tag //foo=buf.getString(); // language tag
@@ -1561,6 +1582,7 @@ break;
channel.close=true; channel.close=true;
channel.eof_remote=true; channel.eof_remote=true;
channel.setRecipient(0); channel.setRecipient(0);
}
break; break;
case SSH_MSG_CHANNEL_REQUEST: case SSH_MSG_CHANNEL_REQUEST:
buf.getInt(); buf.getInt();
@@ -1616,8 +1638,8 @@ break;
tmp.setDaemon(daemon_thread); tmp.setDaemon(daemon_thread);
} }
tmp.start(); tmp.start();
break;
} }
break;
case SSH_MSG_CHANNEL_SUCCESS: case SSH_MSG_CHANNEL_SUCCESS:
buf.getInt(); buf.getInt();
buf.getShort(); buf.getShort();
@@ -2440,11 +2462,17 @@ break;
"CheckCiphers: "+ciphers); "CheckCiphers: "+ciphers);
} }
String cipherc2s=getConfig("cipher.c2s");
String ciphers2c=getConfig("cipher.s2c");
Vector result=new Vector(); Vector result=new Vector();
String[] _ciphers=Util.split(ciphers, ","); String[] _ciphers=Util.split(ciphers, ",");
for(int i=0; i<_ciphers.length; i++){ for(int i=0; i<_ciphers.length; i++){
if(!checkCipher(getConfig(_ciphers[i]))){ String cipher=_ciphers[i];
result.addElement(_ciphers[i]); if(ciphers2c.indexOf(cipher) == -1 && cipherc2s.indexOf(cipher) == -1)
continue;
if(!checkCipher(getConfig(cipher))){
result.addElement(cipher);
} }
} }
if(result.size()==0) if(result.size()==0)
@@ -2517,6 +2545,40 @@ break;
catch(Exception e){ return false; } catch(Exception e){ return false; }
} }
private String[] checkSignatures(String sigs){
if(sigs==null || sigs.length()==0)
return null;
if(JSch.getLogger().isEnabled(Logger.INFO)){
JSch.getLogger().log(Logger.INFO,
"CheckSignatures: "+sigs);
}
java.util.Vector result=new java.util.Vector();
String[] _sigs=Util.split(sigs, ",");
for(int i=0; i<_sigs.length; i++){
try{
Class c=Class.forName((String)jsch.getConfig(_sigs[i]));
final Signature sig=(Signature)(c.newInstance());
sig.init();
}
catch(Exception e){
result.addElement(_sigs[i]);
}
}
if(result.size()==0)
return null;
String[] foo=new String[result.size()];
System.arraycopy(result.toArray(), 0, foo, 0, result.size());
if(JSch.getLogger().isEnabled(Logger.INFO)){
for(int i=0; i<foo.length; i++){
JSch.getLogger().log(Logger.INFO,
foo[i]+" is not available.");
}
}
return foo;
}
/** /**
* Sets the identityRepository, which will be referred * Sets the identityRepository, which will be referred
* in the public key authentication. The default value is <code>null</code>. * in the public key authentication. The default value is <code>null</code>.
@@ -2542,8 +2604,7 @@ break;
} }
/** /**
* Sets the hostkeyRepository, which will be referred * Sets the hostkeyRepository, which will be referred in checking host keys.
* in the host key checking.
* *
* @param hostkeyRepository * @param hostkeyRepository
* @see #getHostKeyRepository() * @see #getHostKeyRepository()

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -108,12 +108,12 @@ public class SftpATTRS {
} }
public String getAtimeString(){ public String getAtimeString(){
SimpleDateFormat locale=new SimpleDateFormat(); Date date= new Date(((long)atime)*1000L);
return (locale.format(new Date(atime))); return (date.toString());
} }
public String getMtimeString(){ public String getMtimeString(){
Date date= new Date(((long)mtime)*1000); Date date= new Date(((long)mtime)*1000L);
return (date.toString()); return (date.toString());
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -35,20 +35,8 @@ import java.util.Date;
public class SftpStatVFS { public class SftpStatVFS {
/* /*
from "man statvfs" It seems data is serializsed according to sys/statvfs.h; for example,
struct statvfs { http://pubs.opengroup.org/onlinepubs/009604499/basedefs/sys/statvfs.h.html
unsigned long f_bsize; // file system block size
unsigned long f_frsize; // fragment size
fsblkcnt_t f_blocks; // size of fs in f_frsize units
fsblkcnt_t f_bfree; // # free blocks
fsblkcnt_t f_bavail; // # free blocks for non-root
fsfilcnt_t f_files; // # inodes
fsfilcnt_t f_ffree; // # free inodes
fsfilcnt_t f_favail; // # free inodes for non-root
unsigned long f_fsid; // file system ID
unsigned long f_flag; // mount flags
unsigned long f_namemax; // maximum filename length
};
*/ */
private long bsize; private long bsize;

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2012-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2012-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -0,0 +1,35 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/*
Copyright (c) 2015-2016 ymnk, JCraft,Inc. 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.
3. The names of the authors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE 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.
*/
package com.jcraft.jsch;
public interface SignatureECDSA extends Signature {
void setPubKey(byte[] r, byte[] s) throws Exception;
void setPrvKey(byte[] s) throws Exception;
}

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2006-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2006-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -66,7 +66,8 @@ class UserAuthPublicKey extends UserAuth{
// string service name ("ssh-connection") // string service name ("ssh-connection")
// string "publickey" // string "publickey"
// boolen FALSE // boolen FALSE
// string plaintext password (ISO-10646 UTF-8) // string public key algorithm name
// string public key blob
packet.reset(); packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username); buf.putString(_username);
@@ -160,7 +161,9 @@ class UserAuthPublicKey extends UserAuth{
// string service name ("ssh-connection") // string service name ("ssh-connection")
// string "publickey" // string "publickey"
// boolen TRUE // boolen TRUE
// string plaintext password (ISO-10646 UTF-8) // string public key algorithm name
// string public key blob
// string signature
packet.reset(); packet.reset();
buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST);
buf.putString(_username); buf.putString(_username);

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2002-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2002-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -43,7 +43,8 @@ class Util{
} }
return 0; return 0;
} }
static byte[] fromBase64(byte[] buf, int start, int length){ static byte[] fromBase64(byte[] buf, int start, int length) throws JSchException {
try {
byte[] foo=new byte[length]; byte[] foo=new byte[length];
int j=0; int j=0;
for (int i=start;i<start+length;i+=4){ for (int i=start;i<start+length;i+=4){
@@ -58,6 +59,10 @@ class Util{
System.arraycopy(foo, 0, bar, 0, j); System.arraycopy(foo, 0, bar, 0, j);
return bar; return bar;
} }
catch(ArrayIndexOutOfBoundsException e) {
throw new JSchException("fromBase64: invalid base64 data", e);
}
}
static byte[] toBase64(byte[] buf, int start, int length){ static byte[] toBase64(byte[] buf, int start, int length){
byte[] tmp=new byte[length*2]; byte[] tmp=new byte[length*2];
@@ -386,7 +391,7 @@ class Util{
} }
tmp.interrupt(); tmp.interrupt();
tmp=null; tmp=null;
throw new JSchException(message); throw new JSchException(message, ee[0]);
} }
return socket; return socket;
} }
@@ -423,6 +428,17 @@ class Util{
return byte2str(str, s, l, "UTF-8"); return byte2str(str, s, l, "UTF-8");
} }
static String toHex(byte[] str){
StringBuffer sb = new StringBuffer();
for(int i = 0; i<str.length; i++){
String foo = Integer.toHexString(str[i]&0xff);
sb.append("0x"+(foo.length() == 1 ? "0" : "")+foo);
if(i+1<str.length)
sb.append(":");
}
return sb.toString();
}
static final byte[] empty = str2byte(""); static final byte[] empty = str2byte("");
/* /*
@@ -469,12 +485,12 @@ class Util{
} }
static String checkTilde(String str){ static String checkTilde(String str){
if(str.indexOf("~") != -1){
try{ try{
if(str.startsWith("~")){
str = str.replace("~", System.getProperty("user.home")); str = str.replace("~", System.getProperty("user.home"));
} }
catch(SecurityException e){
} }
catch(SecurityException e){
} }
return str; return str;
} }

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2005-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -55,11 +55,13 @@ public class AES128CBC implements Cipher{
try{ try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
synchronized(javax.crypto.Cipher.class){
cipher.init((mode==ENCRYPT_MODE? cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE: javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE), javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv)); keyspec, new IvParameterSpec(iv));
} }
}
catch(Exception e){ catch(Exception e){
cipher=null; cipher=null;
throw e; throw e;

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2008-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -55,11 +55,13 @@ public class AES128CTR implements Cipher{
try{ try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
synchronized(javax.crypto.Cipher.class){
cipher.init((mode==ENCRYPT_MODE? cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE: javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE), javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv)); keyspec, new IvParameterSpec(iv));
} }
}
catch(Exception e){ catch(Exception e){
cipher=null; cipher=null;
throw e; throw e;

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2005-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -54,11 +54,13 @@ public class AES192CBC implements Cipher{
try{ try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
synchronized(javax.crypto.Cipher.class){
cipher.init((mode==ENCRYPT_MODE? cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE: javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE), javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv)); keyspec, new IvParameterSpec(iv));
} }
}
catch(Exception e){ catch(Exception e){
cipher=null; cipher=null;
throw e; throw e;

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2008-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -54,11 +54,13 @@ public class AES192CTR implements Cipher{
try{ try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
synchronized(javax.crypto.Cipher.class){
cipher.init((mode==ENCRYPT_MODE? cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE: javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE), javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv)); keyspec, new IvParameterSpec(iv));
} }
}
catch(Exception e){ catch(Exception e){
cipher=null; cipher=null;
throw e; throw e;

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2005-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2005-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -54,11 +54,13 @@ public class AES256CBC implements Cipher{
try{ try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad);
synchronized(javax.crypto.Cipher.class){
cipher.init((mode==ENCRYPT_MODE? cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE: javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE), javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv)); keyspec, new IvParameterSpec(iv));
} }
}
catch(Exception e){ catch(Exception e){
cipher=null; cipher=null;
throw e; throw e;

View File

@@ -1,6 +1,6 @@
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* /*
Copyright (c) 2008-2012 ymnk, JCraft,Inc. All rights reserved. Copyright (c) 2008-2016 ymnk, JCraft,Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
@@ -54,11 +54,13 @@ public class AES256CTR implements Cipher{
try{ try{
SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); SecretKeySpec keyspec=new SecretKeySpec(key, "AES");
cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad);
synchronized(javax.crypto.Cipher.class){
cipher.init((mode==ENCRYPT_MODE? cipher.init((mode==ENCRYPT_MODE?
javax.crypto.Cipher.ENCRYPT_MODE: javax.crypto.Cipher.ENCRYPT_MODE:
javax.crypto.Cipher.DECRYPT_MODE), javax.crypto.Cipher.DECRYPT_MODE),
keyspec, new IvParameterSpec(iv)); keyspec, new IvParameterSpec(iv));
} }
}
catch(Exception e){ catch(Exception e){
cipher=null; cipher=null;
throw e; throw e;

Some files were not shown because too many files have changed in this diff Show More