diff --git a/src/JavaFileStorageBindings/Jars/adal-1.14.0.aar b/src/JavaFileStorageBindings/Jars/adal-1.14.0.aar new file mode 100644 index 00000000..e3e4c25e Binary files /dev/null and b/src/JavaFileStorageBindings/Jars/adal-1.14.0.aar differ diff --git a/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj b/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj index 636cef20..8646b9f2 100644 --- a/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj +++ b/src/JavaFileStorageBindings/JavaFileStorageBindings.csproj @@ -60,6 +60,7 @@ + @@ -92,9 +93,6 @@ - - - diff --git a/src/java/JavaFileStorage/app/build.gradle b/src/java/JavaFileStorage/app/build.gradle index ba1bbfcf..602be402 100644 --- a/src/java/JavaFileStorage/app/build.gradle +++ b/src/java/JavaFileStorage/app/build.gradle @@ -32,11 +32,11 @@ dependencies { compile 'com.google.apis:google-api-services-drive:v2-rev102-1.16.0-rc' compile 'com.dropbox.core:dropbox-core-sdk:3.0.3' //onedrive: - compile('com.onedrive.sdk:onedrive-sdk-android:1.2+') { + compile('com.onedrive.sdk:onedrive-sdk-android:1.2.0') { transitive = false } compile 'com.google.code.gson:gson:2.3.1' - compile 'com.microsoft.services.msa:msa-auth:0.8.+' - compile 'com.microsoft.aad:adal:1.1.+' + compile 'com.microsoft.services.msa:msa-auth:0.8.6' + compile 'com.microsoft.aad:adal:1.14.0' } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Buffer.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Buffer.java index 4dbb64b7..4db2e89e 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Buffer.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Buffer.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -213,8 +213,11 @@ public class Buffer{ } void checkFreeSize(int n){ - if(buffer.length 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(i0) notifyAll(); @@ -384,12 +456,15 @@ public abstract class Channel implements Runnable{ if(eof_local)return; eof_local=true; + int i = getRecipient(); + if(i == -1) return; + try{ Buffer buf=new Buffer(100); Packet packet=new Packet(buf); packet.reset(); buf.putByte((byte)Session.SSH_MSG_CHANNEL_EOF); - buf.putInt(getRecipient()); + buf.putInt(i); synchronized(this){ if(!close) getSession().write(packet); @@ -445,12 +520,15 @@ public abstract class Channel implements Runnable{ close=true; eof_local=eof_remote=true; + int i = getRecipient(); + if(i == -1) return; + try{ Buffer buf=new Buffer(100); Packet packet=new Packet(buf); packet.reset(); buf.putByte((byte)Session.SSH_MSG_CHANNEL_CLOSE); - buf.putInt(getRecipient()); + buf.putInt(i); synchronized(this){ getSession().write(packet); } @@ -561,8 +639,25 @@ public abstract class Channel implements Runnable{ } } class PassiveOutputStream extends PipedOutputStream{ - PassiveOutputStream(PipedInputStream in) throws IOException{ + private MyPipedInputStream _sink=null; + PassiveOutputStream(PipedInputStream in, + boolean resizable_buffer) throws IOException{ 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(); _session.write(packet); - int retry=10; + int retry=2000; long start=System.currentTimeMillis(); long timeout=connectTimeout; if(timeout!=0L) retry = 1; @@ -651,7 +746,7 @@ public abstract class Channel implements Runnable{ } } try{ - long t = timeout==0L ? 5000L : timeout; + long t = timeout==0L ? 10L : timeout; this.notifyme=1; wait(t); } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java index 6a77c374..d93a0058 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelAgentForwarding.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java index aecd1889..f5d8f4ab 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectTCPIP.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -120,7 +120,16 @@ public class ChannelDirectTCPIP extends Channel{ } } catch(Exception e){ + // Whenever an exception is thrown by sendChannelOpen(), + // 'connected' is false. + if(!connected){ + connected=true; + } + disconnect(); + return; } + + eof(); disconnect(); } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelExec.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelExec.java index 45322b63..8f6be684 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelExec.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelExec.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java index 1eba4998..32dcb5db 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelForwardedTCPIP.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSession.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSession.java index 801be76f..ce44f839 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSession.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSession.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSftp.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSftp.java index fca709c7..0711f9e7 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSftp.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSftp.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -648,7 +648,6 @@ public class ChannelSftp extends ChannelSession{ if((seq-1)==startid || ((seq-startid)-ackcount)>=bulk_requests){ while(((seq-startid)-ackcount)>=bulk_requests){ - if(this.rwsize>=foo) break; if(checkStatus(ackid, header)){ int _ackid = ackid[0]; if(startid>_ackid || _ackid>seq-1){ @@ -666,7 +665,16 @@ public class ChannelSftp extends ChannelSession{ } } } - foo-=sendWRITE(handle, offset, data, 0, foo); + if(dontcopy){ + 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; 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); } else{ sendOPENA(dstb); } @@ -923,6 +937,15 @@ public class ChannelSftp extends ChannelSession{ if(i==-1) dstsb.append(_src); else dstsb.append(_src.substring(i + 1)); _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()); } else{ @@ -1375,7 +1398,10 @@ public class ChannelSftp extends ChannelSession{ 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; if(server_version==0){ request_len=1024; } @@ -1782,10 +1808,17 @@ public class ChannelSftp extends ChannelSession{ try{ ((MyPipedInputStream)io_in).updateReadSide(); - oldpath=remoteAbsolutePath(oldpath); + String _oldpath=remoteAbsolutePath(oldpath); 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)){ throw new SftpException(SSH_FX_FAILURE, newpath); @@ -1827,10 +1860,17 @@ public class ChannelSftp extends ChannelSession{ try{ ((MyPipedInputStream)io_in).updateReadSide(); - oldpath=remoteAbsolutePath(oldpath); + String _oldpath=remoteAbsolutePath(oldpath); 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)){ throw new SftpException(SSH_FX_FAILURE, newpath); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelShell.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelShell.java index eeb24a39..bafcc39a 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelShell.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelShell.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSubsystem.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSubsystem.java index 3f33bf3e..697b9273 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSubsystem.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelSubsystem.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelX11.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelX11.java index 393728c0..c69121c6 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelX11.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelX11.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Cipher.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Cipher.java index cc7084e6..da1e9411 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Cipher.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Cipher.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/CipherNone.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/CipherNone.java index 61f836ab..9d4e530f 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/CipherNone.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/CipherNone.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Compression.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Compression.java index 7ae79220..96cf535c 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Compression.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Compression.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ConfigRepository.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ConfigRepository.java index 9de4a5c3..ca799034 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ConfigRepository.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ConfigRepository.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH.java index 963f13c2..ce79791c 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -36,4 +36,8 @@ public interface DH{ byte[] getE() throws Exception; void setF(byte[] f); 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; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC256.java new file mode 100644 index 00000000..c2a7d054 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC256.java @@ -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; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC384.java new file mode 100644 index 00000000..3fdcb78f --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC384.java @@ -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; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC521.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC521.java new file mode 100644 index 00000000..b9bb0910 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHEC521.java @@ -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; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHECN.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHECN.java new file mode 100644 index 00000000..ecfaa094 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHECN.java @@ -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; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG1.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG1.java index 12955ad1..4829478b 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG1.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG1.java @@ -1,6 +1,6 @@ /* -*-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 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_REPLY= 31; - static final int RSA=0; - static final int DSS=1; - private int type=0; - private int state; DH dh; -// HASH sha; - -// byte[] K; -// byte[] H; byte[] V_S; byte[] V_C; byte[] I_S; byte[] I_C; -// byte[] K_S; - byte[] e; private Buffer buf; @@ -87,8 +77,6 @@ public class DHG1 extends KeyExchange{ this.I_S=I_S; this.I_C=I_C; -// sha=new SHA1(); -// sha.init(); try{ Class c=Class.forName(session.getConfig("sha-1")); sha=(HASH)(c.newInstance()); @@ -155,24 +143,14 @@ public class DHG1 extends KeyExchange{ } 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(); - /* -for(int ii=0; ii "); 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; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ECDH.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ECDH.java new file mode 100644 index 00000000..b1c6a34f --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ECDH.java @@ -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; +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java index 4176aef4..c40e0307 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ForwardedTCPIPDaemon.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/GSSContext.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/GSSContext.java index 23c58ee3..9f4187fb 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/GSSContext.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/GSSContext.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HASH.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HASH.java index 6bfff886..4edb56eb 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HASH.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HASH.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKey.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKey.java index 8a4c6f50..edba4e31 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKey.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKey.java @@ -1,6 +1,6 @@ /* -*-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 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; 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; public static final int SSHDSS=1; 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 host; @@ -60,6 +69,9 @@ public class HostKey{ if(type==GUESS){ if(key[8]=='d'){ this.type=SSHDSS; } 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{ @@ -71,10 +83,23 @@ public class HostKey{ public String getHost(){ return host; } public String getType(){ - if(type==SSHDSS){ return Util.byte2str(sshdss); } - if(type==SSHRSA){ return Util.byte2str(sshrsa);} + if(type==SSHDSS || + type==SSHRSA || + type==ECDSA256 || + type==ECDSA384 || + type==ECDSA521){ + return Util.byte2str(names[type-1]); + } 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(){ return Util.byte2str(Util.toBase64(key, 0, key.length)); } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKeyRepository.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKeyRepository.java index adfe633c..92b236f7 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKeyRepository.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/HostKeyRepository.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -34,11 +34,61 @@ public interface HostKeyRepository{ final int NOT_INCLUDED=1; final int CHANGED=2; + /** + * Checks if host is included with the key. + * + * @return #NOT_INCLUDED, #OK or #CHANGED + * @see #NOT_INCLUDED + * @see #OK + * @see #CHANGED + */ int check(String host, byte[] key); + + /** + * Adds a host key hostkey + * + * @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); + + /** + * Removes a host key if there exists mached key with + * host, type. + * + * @see #remove(String host, String type, byte[] key) + */ void remove(String host, String type); + + /** + * Removes a host key if there exists a matched key with + * host, type and key. + */ void remove(String host, String type, byte[] key); + + /** + * Returns id of this repository. + * + * @return identity in String + */ String getKnownHostsRepositoryID(); + + /** + * Retuns a list for host keys managed in this repository. + * + * @see #getHostKey(String host, String type) + */ HostKey[] getHostKey(); + + /** + * Retuns a list for host keys managed in this repository. + * + * @param host a hostname used in searching host keys. + * If null 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 null is given, a key type type will not be ignored. + */ HostKey[] getHostKey(String host, String type); } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IO.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IO.java index 65535ba3..a354bffb 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IO.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IO.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Identity.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Identity.java index b803dd91..70005a89 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Identity.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Identity.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityFile.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityFile.java index 9127ceb0..e3d5d7b1 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityFile.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityFile.java @@ -1,6 +1,6 @@ /* -*-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 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{ + KeyPair kpair = KeyPair.load(jsch, prvkey, pubkey); return new IdentityFile(jsch, name, kpair); } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepository.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepository.java index 7ec71302..a24bc421 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepository.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepository.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSch.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSch.java index ddca7ffc..3b3e7a1e 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSch.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSch.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -36,17 +36,16 @@ public class JSch{ /** * 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{ - config.put("kex", "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1"); - config.put("server_host_key", "ssh-rsa,ssh-dss"); - + 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,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521"); 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", - "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.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", "com.jcraft.jsch.DHG1"); config.put("diffie-hellman-group14-sha1", - "com.jcraft.jsch.DHG14"); + "com.jcraft.jsch.DHG14"); // available since JDK8. 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("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("sha-1", "com.jcraft.jsch.jce.SHA1"); 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("signature.dss", "com.jcraft.jsch.jce.SignatureDSA"); 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.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("none", "com.jcraft.jsch.CipherNone"); @@ -111,13 +124,16 @@ public class JSch{ config.put("zlib", "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("HashKnownHosts", "no"); 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("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("ClearAllForwardings", "no"); @@ -171,7 +187,9 @@ public class JSch{ static Logger logger=DEVNULL; 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{ String osname=(String)(System.getProperties().get("os.name")); if(osname!=null && osname.equals("Mac OS X")){ @@ -183,7 +201,7 @@ public class JSch{ } catch(Exception e){ } - + */ } /** diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java index 65e71f19..783577de 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAuthCancelException.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchException.java index 1e9056ce..1c8b7f1e 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchException.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchException.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java index aa7ac9e4..72794e8d 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchPartialAuthException.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyExchange.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyExchange.java index e077d4d7..364cd9b4 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyExchange.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyExchange.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -70,19 +70,24 @@ public abstract class KeyExchange{ public abstract void init(Session session, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception; public abstract boolean next(Buffer buf) throws Exception; - public abstract String getKeyType(); + public abstract int getState(); - /* - void dump(byte[] foo){ - for(int i=0; i11 && - 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); buf.skip(prvkey.length); // for using Buffer#available() @@ -577,6 +597,11 @@ public abstract class KeyPair{ else if(_type.equals("ssh-dss")){ 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{ 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); 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]=='E'&& buf[i+1]=='C'){ type=ECDSA; } else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H'){ // FSecure type=UNKNOWN; 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{ throw new JSchException("invalid privatekey: "+prvkey); } @@ -689,7 +733,8 @@ public abstract class KeyPair{ } if(!inheader){ i++; - encrypted=false; // no passphrase + if(vendor!=VENDOR_PKCS8) + encrypted=false; // no passphrase break; } } @@ -724,12 +769,8 @@ public abstract class KeyPair{ while(i<_len){ if(_buf[i]==0x0a){ boolean xd=(_buf[i-1]==0x0d); - // move 0x0a (or 0x0d0x0a) to the end of '_buf'. - System.arraycopy(_buf, i+1, - _buf, - i-(xd ? 1 : 0), - _len-i-1-(xd ? 1 : 0) - ); + // ignore 0x0a (or 0x0d0x0a) + System.arraycopy(_buf, i+1, _buf, i-(xd ? 1 : 0), _len-(i+1)); if(xd)_len--; _len--; continue; @@ -841,11 +882,32 @@ public abstract class KeyPair{ if(i++0 && buf[i-1]==0x0d) i--; + if(start7){ + type=ECDSA; + } + i=0; + while(i0 && buf[i-1]==0x0d) i--; + if(startbuf.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 =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; i0){ 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); + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java index f6507f24..2bd78b21 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenDSA.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenECDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenECDSA.java new file mode 100644 index 00000000..30f00c74 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenECDSA.java @@ -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(); +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java index 3a849074..0d00eef9 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenRSA.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairPKCS8.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairPKCS8.java new file mode 100644 index 00000000..d9a3da19 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairPKCS8.java @@ -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; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairRSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairRSA.java index 45fd70a5..2111cd3b 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairRSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairRSA.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KnownHosts.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KnownHosts.java index 6fd577ea..f9d1eae4 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KnownHosts.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KnownHosts.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -35,12 +35,6 @@ public class KnownHosts implements HostKeyRepository{ 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 String known_hosts=null; private java.util.Vector pool=null; @@ -50,26 +44,28 @@ class KnownHosts implements HostKeyRepository{ KnownHosts(JSch jsch){ super(); this.jsch=jsch; + this.hmacsha1 = getHMACSHA1(); pool=new java.util.Vector(); } - void setKnownHosts(String foo) throws JSchException{ + void setKnownHosts(String filename) throws JSchException{ try{ - known_hosts = foo; - FileInputStream fis=new FileInputStream(Util.checkTilde(foo)); + known_hosts = filename; + FileInputStream fis=new FileInputStream(Util.checkTilde(filename)); setKnownHosts(fis); } catch(FileNotFoundException e){ + // The non-existing file should be allowed. } } - void setKnownHosts(InputStream foo) throws JSchException{ + void setKnownHosts(InputStream input) throws JSchException{ pool.removeAllElements(); StringBuffer sb=new StringBuffer(); byte i; int j; boolean error=false; try{ - InputStream fis=foo; + InputStream fis=input; String host; String key=null; int type; @@ -158,8 +154,10 @@ loop: if(i==0x20 || i=='\t'){ break; } sb.append((char)i); } - if(sb.toString().equals("ssh-dss")){ type=HostKey.SSHDSS; } - else if(sb.toString().equals("ssh-rsa")){ type=HostKey.SSHRSA; } + String tmp = sb.toString(); + if(HostKey.name2type(tmp)!=HostKey.UNKNOWN){ + type=HostKey.name2type(tmp); + } else { j=bufl; } if(j>=bufl){ addInvalidLine(Util.byte2str(buf, 0, bufl)); @@ -223,7 +221,6 @@ loop: key.length()), comment); pool.addElement(hk); } - fis.close(); if(error){ throw new JSchException("KnownHosts: invalid format"); } @@ -235,6 +232,12 @@ loop: throw new JSchException(e.toString(), (Throwable)e); 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 { HostKey hk = new HostKey(line, HostKey.UNKNOWN, null); @@ -249,14 +252,19 @@ loop: return result; } - int type=getType(key); - HostKey hk; + HostKey hk = null; + try { + hk = new HostKey(host, HostKey.GUESS, key); + } + catch(JSchException e){ // unsupported key + return result; + } synchronized(pool){ for(int i=0; i1){ + HostKey[] tmp = + getHostKey(host.substring(1, host.indexOf("]:")), type); + if(tmp.length > 0){ + HostKey[] bar = new HostKey[foo.length + tmp.length]; + System.arraycopy(foo, 0, bar, 0, foo.length); + System.arraycopy(tmp, 0, bar, foo.length, tmp.length); + foo = bar; + } } return foo; } @@ -452,11 +462,7 @@ loop: 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){ int i=0; int hostlen=host.length(); @@ -477,7 +483,7 @@ loop: return hosts; } - private synchronized MAC getHMACSHA1(){ + private MAC getHMACSHA1(){ if(hmacsha1==null){ try{ Class c=Class.forName(jsch.getConfig("hmac-sha1")); @@ -503,7 +509,6 @@ loop: byte[] salt=null; byte[] hash=null; - HashedHostKey(String host, byte[] key) throws JSchException { this(host, GUESS, key); } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java index 3b83f2ef..01a37a4d 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/LocalIdentityRepository.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -50,6 +50,7 @@ class LocalIdentityRepository implements IdentityRepository { } public synchronized Vector getIdentities() { + removeDupulicates(); Vector v = new Vector(); for(int i=0; i*/ kv = new Vector(); @@ -200,12 +198,13 @@ public class OpenSSHConfig implements ConfigRepository { if(keymap.get(key)!=null) { key = (String)keymap.get(key); } + key = key.toUpperCase(); String value = null; for(int i = 0; i < _configs.size(); i++) { Vector v = (Vector)_configs.elementAt(i); for(int j = 0; j < v.size(); j++) { String[] kv = (String[])v.elementAt(j); - if(kv[0].equals(key)) { + if(kv[0].toUpperCase().equals(key)) { value = kv[1]; break; } @@ -217,12 +216,13 @@ public class OpenSSHConfig implements ConfigRepository { } private String[] multiFind(String key) { + key = key.toUpperCase(); Vector value = new Vector(); for(int i = 0; i < _configs.size(); i++) { Vector v = (Vector)_configs.elementAt(i); for(int j = 0; j < v.size(); j++) { String[] kv = (String[])v.elementAt(j); - if(kv[0].equals(key)) { + if(kv[0].toUpperCase().equals(key)) { String foo = kv[1]; if(foo != null) { value.remove(foo); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PBKDF.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PBKDF.java new file mode 100644 index 00000000..6910b568 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PBKDF.java @@ -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); +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Packet.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Packet.java index 9c441577..3b8c50de 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Packet.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Packet.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PortWatcher.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PortWatcher.java index 75ec2688..5f403fde 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PortWatcher.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/PortWatcher.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Proxy.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Proxy.java index 7d05caa8..39b4bcb7 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Proxy.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Proxy.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxyHTTP.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxyHTTP.java index df23114a..432e91ee 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxyHTTP.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxyHTTP.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS4.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS4.java index cb506165..f0b059fa 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS4.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS4.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS5.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS5.java index 7960135a..e37581b2 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS5.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ProxySOCKS5.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Random.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Random.java index 879b7770..9d08767f 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Random.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Random.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Request.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Request.java index 94f9b013..a158b769 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Request.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Request.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java index 66d328cd..0c6edc7f 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestAgentForwarding.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestEnv.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestEnv.java index cccda4df..6925a04f 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestEnv.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestEnv.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestExec.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestExec.java index 318d99ad..3787edbe 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestExec.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestExec.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestPtyReq.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestPtyReq.java index 86bf4f13..b9a2622e 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestPtyReq.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestPtyReq.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSftp.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSftp.java index 483c296b..10eab938 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSftp.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSftp.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestShell.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestShell.java index e037ba9e..125b7fac 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestShell.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestShell.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSignal.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSignal.java index a6926177..84efa8a0 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSignal.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSignal.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSubsystem.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSubsystem.java index b6fee4f4..9926bbf8 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSubsystem.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestSubsystem.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestWindowChange.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestWindowChange.java index 43600ac4..131c2bfd 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestWindowChange.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestWindowChange.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestX11.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestX11.java index 3bdaca9f..03ea7ede 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestX11.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/RequestX11.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ServerSocketFactory.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ServerSocketFactory.java index 682b4c4f..4aaef2d8 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ServerSocketFactory.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ServerSocketFactory.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Session.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Session.java index 8807f5f6..a5f751dc 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Session.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Session.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -123,7 +123,7 @@ public class Session implements Runnable{ SocketFactory socket_factory=null; 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 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){ in_kex=false; + in_prompt = false; throw ee; } @@ -537,19 +544,20 @@ public class Session implements Runnable{ } catch(Exception e) { in_kex=false; - if(isConnected){ - try{ - packet.reset(); - buf.putByte((byte)SSH_MSG_DISCONNECT); - buf.putInt(3); - buf.putString(Util.str2byte(e.toString())); - buf.putString(Util.str2byte("en")); - write(packet); - disconnect(); - } - catch(Exception ee){ - } + try{ + if(isConnected){ + String message = e.toString(); + packet.reset(); + buf.checkFreeSize(1+4*3+message.length()+2+buffer_margin); + buf.putByte((byte)SSH_MSG_DISCONNECT); + buf.putInt(3); + buf.putString(Util.str2byte(message)); + buf.putString(Util.str2byte("en")); + write(packet); + } } + catch(Exception ee){} + try{ disconnect(); } catch(Exception ee){ } isConnected=false; //e.printStackTrace(); if(e instanceof RuntimeException) throw (RuntimeException)e; @@ -601,7 +609,8 @@ public class Session implements Runnable{ return kex; } - private boolean in_kex=false; + private volatile boolean in_kex=false; + private volatile boolean in_prompt=false; public void rekey() throws Exception { 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; kex_start_time=System.currentTimeMillis(); @@ -653,7 +672,7 @@ public class Session implements Runnable{ random.fill(buf.buffer, buf.index, 16); buf.skip(16); } 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(ciphers2c)); 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"+ "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"+ -"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"+ "Please contact your system administrator.\n"+ "Add correct host key in "+file+" to get rid of this message."; @@ -758,7 +777,7 @@ key_fprint+".\n"+ synchronized(hkr){ hkr.remove(chost, - (key_type.equals("DSA") ? "ssh-dss" : "ssh-rsa"), + kex.getKeyAlgorithName(), null); insert=true; } @@ -796,8 +815,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ if(i==HostKeyRepository.OK){ HostKey[] keys = - hkr.getHostKey(chost, - (key_type.equals("DSA") ? "ssh-dss" : "ssh-rsa")); + hkr.getHostKey(chost, kex.getKeyAlgorithName()); String _key= Util.byte2str(Util.toBase64(K_S, 0, K_S.length)); for(int j=0; j< keys.length; j++){ if(keys[i].getKey().equals(_key) && @@ -820,7 +838,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ if(i==HostKeyRepository.OK && JSch.getLogger().isEnabled(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 && @@ -1019,7 +1037,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ if(c==null){ } else{ - c.addRemoteWindowSize(buf.getInt()); + c.addRemoteWindowSize(buf.getUInt()); } } else if(type==UserAuth.SSH_MSG_USERAUTH_SUCCESS){ @@ -1237,7 +1255,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ while(true){ if(in_kex){ 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);} 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){ c.rwsize-=length; break; @@ -1325,8 +1347,11 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ // System.err.println("in_kex="+in_kex+" "+(packet.buffer.getCommand())); long t = getTimeout(); while(in_kex){ - if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){ - throw new JSchException("timeout in wating for rekeying process."); + if(t>0L && + (System.currentTimeMillis()-kex_start_time)>t && + !in_prompt + ){ + throw new JSchException("timeout in waiting for rekeying process."); } byte command=packet.buffer.getCommand(); //System.err.println("command: "+command); @@ -1494,7 +1519,7 @@ break; if(channel==null){ break; } - channel.addRemoteWindowSize(buf.getInt()); + channel.addRemoteWindowSize(buf.getUInt()); break; case SSH_MSG_CHANNEL_EOF: @@ -1534,33 +1559,30 @@ break; buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); - if(channel==null){ - //break; - } int r=buf.getInt(); long rws=buf.getUInt(); int rps=buf.getInt(); - - channel.setRemoteWindowSize(rws); - channel.setRemotePacketSize(rps); - channel.open_confirmation=true; - channel.setRecipient(r); + if(channel!=null){ + channel.setRemoteWindowSize(rws); + channel.setRemotePacketSize(rps); + channel.open_confirmation=true; + channel.setRecipient(r); + } break; case SSH_MSG_CHANNEL_OPEN_FAILURE: buf.getInt(); buf.getShort(); i=buf.getInt(); channel=Channel.getChannel(i, this); - if(channel==null){ - //break; - } - int reason_code=buf.getInt(); - //foo=buf.getString(); // additional textual information - //foo=buf.getString(); // language tag - channel.setExitStatus(reason_code); - channel.close=true; - channel.eof_remote=true; - channel.setRecipient(0); + if(channel!=null){ + int reason_code=buf.getInt(); + //foo=buf.getString(); // additional textual information + //foo=buf.getString(); // language tag + channel.setExitStatus(reason_code); + channel.close=true; + channel.eof_remote=true; + channel.setRecipient(0); + } break; case SSH_MSG_CHANNEL_REQUEST: buf.getInt(); @@ -1616,8 +1638,8 @@ break; tmp.setDaemon(daemon_thread); } tmp.start(); - break; } + break; case SSH_MSG_CHANNEL_SUCCESS: buf.getInt(); buf.getShort(); @@ -2440,11 +2462,17 @@ break; "CheckCiphers: "+ciphers); } + String cipherc2s=getConfig("cipher.c2s"); + String ciphers2c=getConfig("cipher.s2c"); + Vector result=new Vector(); String[] _ciphers=Util.split(ciphers, ","); for(int i=0; i<_ciphers.length; i++){ - if(!checkCipher(getConfig(_ciphers[i]))){ - result.addElement(_ciphers[i]); + String cipher=_ciphers[i]; + if(ciphers2c.indexOf(cipher) == -1 && cipherc2s.indexOf(cipher) == -1) + continue; + if(!checkCipher(getConfig(cipher))){ + result.addElement(cipher); } } if(result.size()==0) @@ -2517,6 +2545,40 @@ break; 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; inull. @@ -2542,8 +2604,7 @@ break; } /** - * Sets the hostkeyRepository, which will be referred - * in the host key checking. + * Sets the hostkeyRepository, which will be referred in checking host keys. * * @param hostkeyRepository * @see #getHostKeyRepository() diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpATTRS.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpATTRS.java index b3a86ba0..96165d50 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpATTRS.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpATTRS.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -108,12 +108,12 @@ public class SftpATTRS { } public String getAtimeString(){ - SimpleDateFormat locale=new SimpleDateFormat(); - return (locale.format(new Date(atime))); + Date date= new Date(((long)atime)*1000L); + return (date.toString()); } public String getMtimeString(){ - Date date= new Date(((long)mtime)*1000); + Date date= new Date(((long)mtime)*1000L); return (date.toString()); } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpException.java index 6a6c1ff8..6f644750 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpException.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpException.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpProgressMonitor.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpProgressMonitor.java index bd91688d..0fd124ad 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpProgressMonitor.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpProgressMonitor.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpStatVFS.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpStatVFS.java index 4433bf6a..04dcd402 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpStatVFS.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SftpStatVFS.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -35,20 +35,8 @@ import java.util.Date; public class SftpStatVFS { /* - from "man statvfs" - struct statvfs { - 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 - }; + It seems data is serializsed according to sys/statvfs.h; for example, + http://pubs.opengroup.org/onlinepubs/009604499/basedefs/sys/statvfs.h.html */ private long bsize; diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Signature.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Signature.java index 9b7d85d8..711f01d7 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Signature.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Signature.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureDSA.java index 5b253fdc..2cbe0acf 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureDSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureDSA.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureECDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureECDSA.java new file mode 100644 index 00000000..7e14d5d5 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureECDSA.java @@ -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; +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureRSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureRSA.java index 715bc575..e51d8a6d 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureRSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureRSA.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SocketFactory.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SocketFactory.java index aaac0dce..d0519851 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SocketFactory.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SocketFactory.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UIKeyboardInteractive.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UIKeyboardInteractive.java index 23af9c31..8ada1a9a 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UIKeyboardInteractive.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UIKeyboardInteractive.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuth.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuth.java index 085a9508..26836317 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuth.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuth.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java index 15856cbc..4325955b 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthGSSAPIWithMIC.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java index 1274d78c..8331b17e 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthKeyboardInteractive.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthNone.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthNone.java index b3b0b077..a2bf63af 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthNone.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthNone.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPassword.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPassword.java index 9b5837f5..7bc1a283 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPassword.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPassword.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java index a4d38be5..40c1fa0a 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserAuthPublicKey.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -66,7 +66,8 @@ class UserAuthPublicKey extends UserAuth{ // string service name ("ssh-connection") // string "publickey" // boolen FALSE - // string plaintext password (ISO-10646 UTF-8) + // string public key algorithm name + // string public key blob packet.reset(); buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); @@ -154,13 +155,15 @@ class UserAuthPublicKey extends UserAuth{ if(pubkeyblob==null) continue; - // send - // byte SSH_MSG_USERAUTH_REQUEST(50) - // string user name - // string service name ("ssh-connection") - // string "publickey" - // boolen TRUE - // string plaintext password (ISO-10646 UTF-8) + // send + // byte SSH_MSG_USERAUTH_REQUEST(50) + // string user name + // string service name ("ssh-connection") + // string "publickey" + // boolen TRUE + // string public key algorithm name + // string public key blob + // string signature packet.reset(); buf.putByte((byte)SSH_MSG_USERAUTH_REQUEST); buf.putString(_username); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserInfo.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserInfo.java index 22552ede..e1b2a32a 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserInfo.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UserInfo.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Util.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Util.java index 6a5354b0..f990b5de 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Util.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Util.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: @@ -43,20 +43,25 @@ class Util{ } return 0; } - static byte[] fromBase64(byte[] buf, int start, int length){ - byte[] foo=new byte[length]; - int j=0; - for (int i=start;i>>4)); - if(buf[i+2]==(byte)'='){ j++; break;} - foo[j+1]=(byte)(((val(buf[i+1])&0x0f)<<4)|((val(buf[i+2])&0x3c)>>>2)); - if(buf[i+3]==(byte)'='){ j+=2; break;} - foo[j+2]=(byte)(((val(buf[i+2])&0x03)<<6)|(val(buf[i+3])&0x3f)); - j+=3; + static byte[] fromBase64(byte[] buf, int start, int length) throws JSchException { + try { + byte[] foo=new byte[length]; + int j=0; + for (int i=start;i>>4)); + if(buf[i+2]==(byte)'='){ j++; break;} + foo[j+1]=(byte)(((val(buf[i+1])&0x0f)<<4)|((val(buf[i+2])&0x3c)>>>2)); + if(buf[i+3]==(byte)'='){ j+=2; break;} + foo[j+2]=(byte)(((val(buf[i+2])&0x03)<<6)|(val(buf[i+3])&0x3f)); + j+=3; + } + byte[] bar=new byte[j]; + System.arraycopy(foo, 0, bar, 0, j); + return bar; + } + catch(ArrayIndexOutOfBoundsException e) { + throw new JSchException("fromBase64: invalid base64 data", e); } - byte[] bar=new byte[j]; - System.arraycopy(foo, 0, bar, 0, j); - return bar; } static byte[] toBase64(byte[] buf, int start, int length){ @@ -386,7 +391,7 @@ class Util{ } tmp.interrupt(); tmp=null; - throw new JSchException(message); + throw new JSchException(message, ee[0]); } return socket; } @@ -423,6 +428,17 @@ class Util{ return byte2str(str, s, l, "UTF-8"); } + static String toHex(byte[] str){ + StringBuffer sb = new StringBuffer(); + for(int i = 0; i=64) name="secp521r1"; + else if(r.length>=48) name="secp384r1"; + + AlgorithmParameters param = AlgorithmParameters.getInstance("EC"); + param.init(new ECGenParameterSpec(name)); + ECParameterSpec ecparam = + (ECParameterSpec)param.getParameterSpec(ECParameterSpec.class); + ECPoint w = new ECPoint(new BigInteger(1, r), new BigInteger(1, s)); + PublicKey pubKey = + keyFactory.generatePublic(new ECPublicKeySpec(w, ecparam)); + signature.initVerify(pubKey); + } + + public void setPrvKey(byte[] d) throws Exception{ + + // d must be unsigned value. + d=insert0(d); + + String name="secp256r1"; + if(d.length>=64) name="secp521r1"; + else if(d.length>=48) name="secp384r1"; + + AlgorithmParameters param = AlgorithmParameters.getInstance("EC"); + param.init(new ECGenParameterSpec(name)); + ECParameterSpec ecparam = + (ECParameterSpec)param.getParameterSpec(ECParameterSpec.class); + BigInteger _d = new BigInteger(1, d); + PrivateKey prvKey = + keyFactory.generatePrivate(new ECPrivateKeySpec(_d, ecparam)); + signature.initSign(prvKey); + } + public byte[] sign() throws Exception{ + byte[] sig=signature.sign(); + + // It seems that the output from SunEC is in ASN.1, + // so we have to convert it. + if(sig[0]==0x30 && // in ASN.1 + ((sig[1]+2 == sig.length) || + ((sig[1]&0x80)!=0 && (sig[2]&0xff)+3==sig.length))){// 2bytes for len + + int index=3; + if((sig[1]&0x80)!=0 && (sig[2]&0xff)+3==sig.length) + index=4; + + byte[] r = new byte[sig[index]]; + byte[] s = new byte[sig[index+2+sig[index]]]; + System.arraycopy(sig, index+1, r, 0, r.length); + System.arraycopy(sig, index+3+sig[index], s, 0, s.length); + + r = chop0(r); + s = chop0(s); + + Buffer buf = new Buffer(); + buf.putMPInt(r); + buf.putMPInt(s); + + sig=new byte[buf.getLength()]; + buf.setOffSet(0); + buf.getByte(sig); + } + + return sig; + } + public void update(byte[] foo) throws Exception{ + signature.update(foo); + } + public boolean verify(byte[] sig) throws Exception{ + + // It seems that SunEC expects ASN.1 data, + // so we have to convert it. + if(!(sig[0]==0x30 && // not in ASN.1 + ((sig[1]+2 == sig.length) || + ((sig[1]&0x80)!=0 && (sig[2]&0xff)+3==sig.length)))) { + Buffer b = new Buffer(sig); + + b.getString(); // ecdsa-sha2-nistp256 + b.getInt(); + + byte[] r = b.getMPInt(); + byte[] s = b.getMPInt(); + + r=insert0(r); + s=insert0(s); + + byte[] asn1 = null; + if(r.length<64){ + asn1 = new byte[6+r.length+s.length]; + asn1[0] = (byte)0x30; + asn1[1] = (byte)(4+r.length+s.length); + asn1[2] = (byte)0x02; + asn1[3] = (byte)r.length; + System.arraycopy(r, 0, asn1, 4, r.length); + asn1[r.length+4] = (byte)0x02; + asn1[r.length+5] = (byte)s.length; + System.arraycopy(s, 0, asn1, (6+r.length), s.length); + } + else { + asn1 = new byte[6+r.length+s.length+1]; + asn1[0] = (byte)0x30; + asn1[1] = (byte)0x81; + asn1[2] = (byte)(4+r.length+s.length); + asn1[3] = (byte)0x02; + asn1[4] = (byte)r.length; + System.arraycopy(r, 0, asn1, 5, r.length); + asn1[r.length+5] = (byte)0x02; + asn1[r.length+6] = (byte)s.length; + System.arraycopy(s, 0, asn1, (7+r.length), s.length); + } + sig=asn1; + } + + return signature.verify(sig); + } + + private byte[] insert0(byte[] buf){ + if ((buf[0] & 0x80) == 0) return buf; + byte[] tmp = new byte[buf.length+1]; + System.arraycopy(buf, 0, tmp, 1, buf.length); + bzero(buf); + return tmp; + } + private byte[] chop0(byte[] buf){ + if(buf[0]!=0) return buf; + byte[] tmp = new byte[buf.length-1]; + System.arraycopy(buf, 1, tmp, 0, tmp.length); + bzero(buf); + return tmp; + } + + private void bzero(byte[] buf){ + for(int i = 0; ibsize){ byte[] tmp=new byte[bsize]; System.arraycopy(key, 0, tmp, 0, bsize); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD5.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD5.java index 90960113..c4fcb48f 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD5.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD5.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD596.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD596.java index 95c6f60d..f806962e 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD596.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD596.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA1.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA1.java index ea9eccf1..869c13c4 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA1.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA1.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA196.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA196.java index 86a81b5b..8f8e3276 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA196.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA196.java @@ -1,6 +1,6 @@ /* -*-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 modification, are permitted provided that the following conditions are met: diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jgss/GSSContextKrb5.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jgss/GSSContextKrb5.java new file mode 100644 index 00000000..cf3ca48f --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jgss/GSSContextKrb5.java @@ -0,0 +1,177 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2006-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.jgss; + +import com.jcraft.jsch.JSchException; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.MessageProp; +import org.ietf.jgss.Oid; + +public class GSSContextKrb5 implements com.jcraft.jsch.GSSContext{ + + private static final String pUseSubjectCredsOnly = + "javax.security.auth.useSubjectCredsOnly"; + private static String useSubjectCredsOnly = + getSystemProperty(pUseSubjectCredsOnly); + + private GSSContext context=null; + public void create(String user, String host) throws JSchException{ + try{ + // RFC 1964 + Oid krb5=new Oid("1.2.840.113554.1.2.2"); + // Kerberos Principal Name Form + Oid principalName=new Oid("1.2.840.113554.1.2.2.1"); + + GSSManager mgr=GSSManager.getInstance(); + + GSSCredential crd=null; + /* + try{ + GSSName _user=mgr.createName(user, principalName); + crd=mgr.createCredential(_user, + GSSCredential.DEFAULT_LIFETIME, + krb5, + GSSCredential.INITIATE_ONLY); + } + catch(GSSException crdex){ + } + */ + + String cname=host; + try{ + cname=InetAddress.getByName(cname).getCanonicalHostName(); + } + catch(UnknownHostException e){ + } + GSSName _host=mgr.createName("host/"+cname, principalName); + + context=mgr.createContext(_host, + krb5, + crd, + GSSContext.DEFAULT_LIFETIME); + + // RFC4462 3.4. GSS-API Session + // + // When calling GSS_Init_sec_context(), the client MUST set + // integ_req_flag to "true" to request that per-message integrity + // protection be supported for this context. In addition, + // deleg_req_flag MAY be set to "true" to request access delegation, if + // requested by the user. + // + // Since the user authentication process by its nature authenticates + // only the client, the setting of mutual_req_flag is not needed for + // this process. This flag SHOULD be set to "false". + + // TODO: OpenSSH's sshd does accepts 'false' for mutual_req_flag + //context.requestMutualAuth(false); + context.requestMutualAuth(true); + context.requestConf(true); + context.requestInteg(true); // for MIC + context.requestCredDeleg(true); + context.requestAnonymity(false); + + return; + } + catch(GSSException ex){ + throw new JSchException(ex.toString()); + } + } + + public boolean isEstablished(){ + return context.isEstablished(); + } + + public byte[] init(byte[] token, int s, int l) throws JSchException { + try{ + // Without setting "javax.security.auth.useSubjectCredsOnly" to "false", + // Sun's JVM for Un*x will show messages to stderr in + // processing context.initSecContext(). + // This hack is not thread safe ;-<. + // If that property is explicitly given as "true" or "false", + // this hack must not be invoked. + if(useSubjectCredsOnly==null){ + setSystemProperty(pUseSubjectCredsOnly, "false"); + } + return context.initSecContext(token, 0, l); + } + catch(GSSException ex){ + throw new JSchException(ex.toString()); + } + catch(java.lang.SecurityException ex){ + throw new JSchException(ex.toString()); + } + finally{ + if(useSubjectCredsOnly==null){ + // By the default, it must be "true". + setSystemProperty(pUseSubjectCredsOnly, "true"); + } + } + } + + public byte[] getMIC(byte[] message, int s, int l){ + try{ + MessageProp prop = new MessageProp(0, true); + return context.getMIC(message, s, l, prop); + } + catch(GSSException ex){ + return null; + } + } + + public void dispose(){ + try{ + context.dispose(); + } + catch(GSSException ex){ + } + } + + private static String getSystemProperty(String key){ + try{ return System.getProperty(key); } + catch(Exception e){ + // We are not allowed to get the System properties. + return null; + } + } + + private static void setSystemProperty(String key, String value){ + try{ System.setProperty(key, value); } + catch(Exception e){ + // We are not allowed to set the System properties. + } + } +} diff --git a/src/java/JavaFileStorageTest-AS/app/build.gradle b/src/java/JavaFileStorageTest-AS/app/build.gradle index 2d8e6d03..27e3252e 100644 --- a/src/java/JavaFileStorageTest-AS/app/build.gradle +++ b/src/java/JavaFileStorageTest-AS/app/build.gradle @@ -11,9 +11,6 @@ android { versionCode 1 versionName "1.0" - jackOptions { - enabled true - } } buildTypes { release {