From e3ce7fe95a946ef4ba51db86ce579bf9fea8f374 Mon Sep 17 00:00:00 2001 From: Sebastian Ratz Date: Tue, 3 Jan 2023 14:58:23 +0100 Subject: [PATCH] Migrate from com.jcraft:jsch 0.1.55 to com.github.mwiede:jsch 0.2.5 com.jcraft:jsch is not actively maintained anymore and lacks support for modern public key algorithms such as rsa-sha2-256. It only supports ssh-rsa which is disabled in up-to-date environments. com.github.mwiede:jsch was created as a drop-in replacement which works in modern environments [1]. Sources are taken from maven central [2]. The following files were omitted, because they depend on additional 3rd-party libraries which we do not have / do not need: com/jcraft/jsch/JUnixSocketFactory.java com/jcraft/jsch/Log4j2Logger.java com/jcraft/jsch/PageantConnector.java com/jcraft/jsch/Slf4jLogger.java com/jcraft/jsch/SSHAgentConnector.java com/jcraft/jsch/bc/* com/jcraft/jsch/jgss/GSSContextKrb5.java Fixes #1812. [1] https://github.com/mwiede/jsch [2] https://repo1.maven.org/maven2/com/github/mwiede/jsch/0.2.5/jsch-0.2.5-sources.jar --- .../java/com/jcraft/jsch/AgentConnector.java | 36 + .../java/com/jcraft/jsch/AgentIdentity.java | 80 + .../jcraft/jsch/AgentIdentityRepository.java | 75 + .../main/java/com/jcraft/jsch/AgentProxy.java | 256 +++ ...HMACSHA1.java => AgentProxyException.java} | 27 +- .../src/main/java/com/jcraft/jsch/Buffer.java | 10 +- .../main/java/com/jcraft/jsch/Channel.java | 116 +- .../jcraft/jsch/ChannelAgentForwarding.java | 77 +- .../jcraft/jsch/ChannelDirectStreamLocal.java | 71 + .../com/jcraft/jsch/ChannelDirectTCPIP.java | 10 +- .../java/com/jcraft/jsch/ChannelExec.java | 15 +- .../jcraft/jsch/ChannelForwardedTCPIP.java | 38 +- .../java/com/jcraft/jsch/ChannelSession.java | 39 +- .../java/com/jcraft/jsch/ChannelSftp.java | 636 +++--- .../java/com/jcraft/jsch/ChannelShell.java | 8 +- .../com/jcraft/jsch/ChannelSubsystem.java | 22 +- .../main/java/com/jcraft/jsch/ChannelX11.java | 66 +- .../src/main/java/com/jcraft/jsch/Cipher.java | 6 + .../main/java/com/jcraft/jsch/CipherNone.java | 7 +- .../java/com/jcraft/jsch/Compression.java | 7 + .../com/jcraft/jsch/ConfigRepository.java | 6 + .../main/java/com/jcraft/jsch/DH25519.java | 38 + .../src/main/java/com/jcraft/jsch/DH448.java | 38 + .../main/java/com/jcraft/jsch/DHEC256.java | 2 +- .../main/java/com/jcraft/jsch/DHEC384.java | 2 +- .../main/java/com/jcraft/jsch/DHEC521.java | 2 +- .../src/main/java/com/jcraft/jsch/DHECN.java | 36 +- .../src/main/java/com/jcraft/jsch/DHG1.java | 149 +- .../src/main/java/com/jcraft/jsch/DHG14.java | 185 +- .../main/java/com/jcraft/jsch/DHG14224.java | 36 + .../main/java/com/jcraft/jsch/DHG14256.java | 36 + .../src/main/java/com/jcraft/jsch/DHG14N.java | 75 + .../src/main/java/com/jcraft/jsch/DHG15.java | 36 + .../main/java/com/jcraft/jsch/DHG15256.java | 36 + .../main/java/com/jcraft/jsch/DHG15384.java | 36 + .../src/main/java/com/jcraft/jsch/DHG15N.java | 91 + .../src/main/java/com/jcraft/jsch/DHG16.java | 36 + .../main/java/com/jcraft/jsch/DHG16384.java | 36 + .../src/main/java/com/jcraft/jsch/DHG16N.java | 107 + .../src/main/java/com/jcraft/jsch/DHG17.java | 141 ++ .../src/main/java/com/jcraft/jsch/DHG18.java | 173 ++ .../src/main/java/com/jcraft/jsch/DHGEX.java | 72 +- .../{jgss/GSSContextKrb5.java => DHGEX1.java} | 13 +- .../main/java/com/jcraft/jsch/DHGEX224.java | 36 + .../main/java/com/jcraft/jsch/DHGEX256.java | 2 +- .../main/java/com/jcraft/jsch/DHGEX384.java | 36 + .../main/java/com/jcraft/jsch/DHGEX512.java | 36 + .../src/main/java/com/jcraft/jsch/DHGN.java | 184 ++ .../src/main/java/com/jcraft/jsch/DHXEC.java | 200 ++ .../src/main/java/com/jcraft/jsch/HASH.java | 1 + .../main/java/com/jcraft/jsch/HostKey.java | 25 +- .../app/src/main/java/com/jcraft/jsch/IO.java | 11 +- .../main/java/com/jcraft/jsch/Identity.java | 44 +- .../java/com/jcraft/jsch/IdentityFile.java | 33 +- .../com/jcraft/jsch/IdentityRepository.java | 73 +- .../jsch/IdentityRepositoryWrapper.java | 109 + .../src/main/java/com/jcraft/jsch/JSch.java | 268 ++- .../jsch/JSchAlgoNegoFailException.java | 69 + .../jcraft/jsch/JSchAuthCancelException.java | 2 +- .../java/com/jcraft/jsch/JSchException.java | 9 +- .../jcraft/jsch/JSchPartialAuthException.java | 2 +- .../java/com/jcraft/jsch/JavaVersion.java | 8 + .../main/java/com/jcraft/jsch/JulLogger.java | 53 + .../java/com/jcraft/jsch/KeyExchange.java | 175 +- .../main/java/com/jcraft/jsch/KeyPair.java | 650 +++--- .../main/java/com/jcraft/jsch/KeyPairDSA.java | 108 +- .../java/com/jcraft/jsch/KeyPairDeferred.java | 163 ++ .../java/com/jcraft/jsch/KeyPairECDSA.java | 117 +- .../java/com/jcraft/jsch/KeyPairEd25519.java | 68 + .../java/com/jcraft/jsch/KeyPairEd448.java | 68 + .../java/com/jcraft/jsch/KeyPairEdDSA.java | 191 ++ .../java/com/jcraft/jsch/KeyPairGenEdDSA.java | 36 + .../java/com/jcraft/jsch/KeyPairGenXEC.java | 34 + .../java/com/jcraft/jsch/KeyPairPKCS8.java | 49 +- .../main/java/com/jcraft/jsch/KeyPairRSA.java | 115 +- .../main/java/com/jcraft/jsch/KnownHosts.java | 399 ++-- .../jcraft/jsch/LocalIdentityRepository.java | 28 +- .../src/main/java/com/jcraft/jsch/Logger.java | 17 + .../src/main/java/com/jcraft/jsch/MAC.java | 1 + .../java/com/jcraft/jsch/OpenSSHConfig.java | 116 +- .../src/main/java/com/jcraft/jsch/Packet.java | 24 +- .../java/com/jcraft/jsch/PortWatcher.java | 159 +- .../main/java/com/jcraft/jsch/ProxyHTTP.java | 25 +- .../java/com/jcraft/jsch/ProxySOCKS4.java | 15 +- .../java/com/jcraft/jsch/ProxySOCKS5.java | 33 +- .../main/java/com/jcraft/jsch/Request.java | 8 +- .../jcraft/jsch/RequestAgentForwarding.java | 1 + .../main/java/com/jcraft/jsch/RequestEnv.java | 4 +- .../java/com/jcraft/jsch/RequestExec.java | 1 + .../java/com/jcraft/jsch/RequestPtyReq.java | 1 + .../java/com/jcraft/jsch/RequestSftp.java | 3 +- .../java/com/jcraft/jsch/RequestShell.java | 1 + .../java/com/jcraft/jsch/RequestSignal.java | 1 + .../com/jcraft/jsch/RequestSubsystem.java | 3 +- .../com/jcraft/jsch/RequestWindowChange.java | 1 + .../main/java/com/jcraft/jsch/RequestX11.java | 1 + .../main/java/com/jcraft/jsch/Session.java | 1696 ++++++++++------ .../main/java/com/jcraft/jsch/SftpATTRS.java | 31 +- .../java/com/jcraft/jsch/SftpException.java | 10 +- .../java/com/jcraft/jsch/SignatureEdDSA.java | 35 + .../java/com/jcraft/jsch/SocketFactory.java | 2 +- .../jcraft/jsch/UIKeyboardInteractive.java | 8 +- .../java/com/jcraft/jsch/USocketFactory.java | 40 + .../jcraft/jsch/UnixDomainSocketFactory.java | 55 + .../jcraft/jsch/UserAuthGSSAPIWithMIC.java | 9 +- .../jsch/UserAuthKeyboardInteractive.java | 155 +- .../java/com/jcraft/jsch/UserAuthNone.java | 43 +- .../com/jcraft/jsch/UserAuthPassword.java | 95 +- .../com/jcraft/jsch/UserAuthPublicKey.java | 313 ++- .../src/main/java/com/jcraft/jsch/Util.java | 171 +- .../main/java/com/jcraft/jsch/Version.java | 10 + .../src/main/java/com/jcraft/jsch/XDH.java | 37 + .../java/com/jcraft/jsch/jbcrypt/BCrypt.java | 859 ++++++++ .../java/com/jcraft/jsch/jce/AES128CBC.java | 16 +- .../java/com/jcraft/jsch/jce/AES128CTR.java | 16 +- .../java/com/jcraft/jsch/jce/AES128GCM.java | 37 + .../java/com/jcraft/jsch/jce/AES192CBC.java | 15 +- .../java/com/jcraft/jsch/jce/AES192CTR.java | 15 +- .../java/com/jcraft/jsch/jce/AES256CBC.java | 15 +- .../java/com/jcraft/jsch/jce/AES256CTR.java | 15 +- .../java/com/jcraft/jsch/jce/AES256GCM.java | 37 + .../main/java/com/jcraft/jsch/jce/AESGCM.java | 103 + .../java/com/jcraft/jsch/jce/ARCFOUR.java | 15 +- .../java/com/jcraft/jsch/jce/ARCFOUR128.java | 15 +- .../java/com/jcraft/jsch/jce/ARCFOUR256.java | 15 +- .../java/com/jcraft/jsch/jce/BlowfishCBC.java | 15 +- .../java/com/jcraft/jsch/jce/BlowfishCTR.java | 76 + .../src/main/java/com/jcraft/jsch/jce/DH.java | 10 +- .../java/com/jcraft/jsch/jce/ECDH256.java | 2 +- .../java/com/jcraft/jsch/jce/ECDH384.java | 2 +- .../java/com/jcraft/jsch/jce/ECDH521.java | 2 +- .../main/java/com/jcraft/jsch/jce/ECDHN.java | 4 + .../main/java/com/jcraft/jsch/jce/HMAC.java | 14 +- .../java/com/jcraft/jsch/jce/HMACMD596.java | 2 + .../com/jcraft/jsch/jce/HMACMD596ETM.java | 37 + .../HMACMD5.java => jce/HMACMD5ETM.java} | 26 +- .../java/com/jcraft/jsch/jce/HMACSHA196.java | 2 + .../com/jcraft/jsch/jce/HMACSHA196ETM.java | 38 + .../java/com/jcraft/jsch/jce/HMACSHA1ETM.java | 37 + .../com/jcraft/jsch/jce/HMACSHA224SSHCOM.java | 38 + .../jcraft/jsch/jce/HMACSHA2562SSHCOM.java | 38 + .../com/jcraft/jsch/jce/HMACSHA256ETM.java | 37 + .../HMACSHA256SSHCOM.java} | 31 +- .../com/jcraft/jsch/jce/HMACSHA384SSHCOM.java | 38 + .../com/jcraft/jsch/jce/HMACSHA512ETM.java | 37 + .../com/jcraft/jsch/jce/HMACSHA512SSHCOM.java | 38 + .../com/jcraft/jsch/jce/KeyPairGenDSA.java | 6 + .../com/jcraft/jsch/jce/KeyPairGenECDSA.java | 6 +- .../com/jcraft/jsch/jce/KeyPairGenRSA.java | 9 + .../main/java/com/jcraft/jsch/jce/MD5.java | 6 + .../main/java/com/jcraft/jsch/jce/PBKDF.java | 1 + .../main/java/com/jcraft/jsch/jce/Random.java | 5 +- .../main/java/com/jcraft/jsch/jce/SHA1.java | 6 + .../HMACSHA196.java => jce/SHA224.java} | 39 +- .../main/java/com/jcraft/jsch/jce/SHA256.java | 6 + .../main/java/com/jcraft/jsch/jce/SHA384.java | 6 + .../main/java/com/jcraft/jsch/jce/SHA512.java | 6 + .../com/jcraft/jsch/jce/SignatureDSA.java | 35 +- .../jcraft/jsch/jce/SignatureECDSA256.java | 6 +- .../jcraft/jsch/jce/SignatureECDSA384.java | 6 +- .../jcraft/jsch/jce/SignatureECDSA521.java | 6 +- .../com/jcraft/jsch/jce/SignatureECDSAN.java | 44 +- .../com/jcraft/jsch/jce/SignatureRSA.java | 53 +- .../com/jcraft/jsch/jce/SignatureRSAN.java | 101 + .../jsch/jce/SignatureRSASHA224SSHCOM.java | 37 + .../jcraft/jsch/jce/SignatureRSASHA256.java | 37 + .../jsch/jce/SignatureRSASHA256SSHCOM.java | 37 + .../jsch/jce/SignatureRSASHA384SSHCOM.java | 37 + .../jcraft/jsch/jce/SignatureRSASHA512.java | 37 + .../jsch/jce/SignatureRSASHA512SSHCOM.java | 37 + .../com/jcraft/jsch/jce/TripleDESCBC.java | 21 +- .../com/jcraft/jsch/jce/TripleDESCTR.java | 21 +- .../java/com/jcraft/jsch/jcraft/HMAC.java | 108 - .../java/com/jcraft/jsch/juz/Compression.java | 141 ++ .../java/com/jcraft/jsch/jzlib/Adler32.java | 144 ++ .../java/com/jcraft/jsch/jzlib/CRC32.java | 184 ++ .../java/com/jcraft/jsch/jzlib/Checksum.java | 43 + .../jsch/{jcraft => jzlib}/Compression.java | 136 +- .../java/com/jcraft/jsch/jzlib/Deflate.java | 1756 +++++++++++++++++ .../java/com/jcraft/jsch/jzlib/Deflater.java | 174 ++ .../jsch/jzlib/DeflaterOutputStream.java | 186 ++ .../com/jcraft/jsch/jzlib/GZIPException.java | 47 + .../com/jcraft/jsch/jzlib/GZIPHeader.java | 194 ++ .../java/com/jcraft/jsch/jzlib/InfBlocks.java | 615 ++++++ .../java/com/jcraft/jsch/jzlib/InfCodes.java | 611 ++++++ .../java/com/jcraft/jsch/jzlib/InfTree.java | 518 +++++ .../java/com/jcraft/jsch/jzlib/Inflate.java | 756 +++++++ .../java/com/jcraft/jsch/jzlib/Inflater.java | 189 ++ .../jsch/jzlib/InflaterInputStream.java | 255 +++ .../java/com/jcraft/jsch/jzlib/JZlib.java | 92 + .../com/jcraft/jsch/jzlib/StaticTree.java | 148 ++ .../main/java/com/jcraft/jsch/jzlib/Tree.java | 367 ++++ .../java/com/jcraft/jsch/jzlib/ZStream.java | 369 ++++ 193 files changed, 15652 insertions(+), 3200 deletions(-) create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentConnector.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentity.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxy.java rename src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/{jcraft/HMACSHA1.java => AgentProxyException.java} (75%) create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/ChannelDirectStreamLocal.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH25519.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH448.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14224.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14256.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14N.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15256.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15384.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15N.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16384.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16N.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG17.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG18.java rename src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/{jgss/GSSContextKrb5.java => DHGEX1.java} (89%) create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX224.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX384.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX512.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGN.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHXEC.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JavaVersion.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JulLogger.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDeferred.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd25519.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd448.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenXEC.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/SignatureEdDSA.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/USocketFactory.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/UnixDomainSocketFactory.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Version.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/XDH.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jbcrypt/BCrypt.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128GCM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256GCM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AESGCM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/BlowfishCTR.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java rename src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/{jcraft/HMACMD5.java => jce/HMACMD5ETM.java} (76%) create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java rename src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/{jcraft/HMACMD596.java => jce/HMACSHA256SSHCOM.java} (73%) create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java rename src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/{jcraft/HMACSHA196.java => jce/SHA224.java} (68%) create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSAN.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA224SSHCOM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA256.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA256SSHCOM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA384SSHCOM.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA512.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureRSASHA512SSHCOM.java delete mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMAC.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/juz/Compression.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Adler32.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/CRC32.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Checksum.java rename src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/{jcraft => jzlib}/Compression.java (54%) create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflate.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflater.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfTree.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflate.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflater.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/JZlib.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Tree.java create mode 100644 src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/ZStream.java diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentConnector.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentConnector.java new file mode 100644 index 00000000..41c8ca80 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentConnector.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 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 AgentConnector { + String getName(); + boolean isAvailable(); + void query(Buffer buffer) throws AgentProxyException; +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentity.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentity.java new file mode 100644 index 00000000..0433ce24 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentity.java @@ -0,0 +1,80 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 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; + +class AgentIdentity implements Identity { + + private AgentProxy agent; + private byte[] blob; + private String comment; + private String algname; + AgentIdentity(AgentProxy agent, byte[] blob, String comment) { + this.agent = agent; + this.blob = blob; + this.comment = comment; + algname = Util.byte2str((new Buffer(blob)).getString()); + } + + @Override + public boolean setPassphrase(byte[] passphrase) throws JSchException{ + return true; + } + + @Override + public byte[] getPublicKeyBlob() { return blob; } + + @Override + public byte[] getSignature(byte[] data){ + return agent.sign(blob, data, null); + } + + @Override + public byte[] getSignature(byte[] data, String alg){ + return agent.sign(blob, data, alg); + } + + @Override + @Deprecated + public boolean decrypt() { + throw new RuntimeException("not implemented"); + } + + @Override + public String getAlgName() { return algname; } + + @Override + public String getName() { return comment; } + + @Override + public boolean isEncrypted() { return false; } + + @Override + public void clear() { } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java new file mode 100644 index 00000000..acda110b --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentIdentityRepository.java @@ -0,0 +1,75 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 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; + +public class AgentIdentityRepository implements IdentityRepository { + + private AgentProxy agent; + public AgentIdentityRepository(AgentConnector connector) { + this.agent = new AgentProxy(connector); + } + + @Override + public Vector getIdentities() { + return agent.getIdentities(); + } + + @Override + public boolean add(byte[] identity) { + return agent.addIdentity(identity); + } + + @Override + public boolean remove(byte[] blob) { + return agent.removeIdentity(blob); + } + + @Override + public void removeAll() { + agent.removeAllIdentities(); + } + + @Override + public String getName() { + return agent.getConnector().getName(); + } + + @Override + public int getStatus() { + if(agent.getConnector().isAvailable()){ + return RUNNING; + } + else { + return NOTRUNNING; + } + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxy.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxy.java new file mode 100644 index 00000000..9d83b2a4 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/AgentProxy.java @@ -0,0 +1,256 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2012 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; + +class AgentProxy { + + private static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1; + private static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2; + private static final byte SSH_AGENTC_RSA_CHALLENGE = 3; + private static final byte SSH_AGENT_RSA_RESPONSE = 4; + private static final byte SSH_AGENT_FAILURE = 5; + private static final byte SSH_AGENT_SUCCESS = 6; + private static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7; + private static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8; + private static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9; + + private static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11; + private static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12; + private static final byte SSH2_AGENTC_SIGN_REQUEST = 13; + private static final byte SSH2_AGENT_SIGN_RESPONSE = 14; + private static final byte SSH2_AGENTC_ADD_IDENTITY = 17; + private static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18; + private static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19; + + private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY = 20; + private static final byte SSH_AGENTC_REMOVE_SMARTCARD_KEY = 21; + + private static final byte SSH_AGENTC_LOCK = 22; + private static final byte SSH_AGENTC_UNLOCK = 23; + + private static final byte SSH_AGENTC_ADD_RSA_ID_CONSTRAINED = 24; + private static final byte SSH2_AGENTC_ADD_ID_CONSTRAINED = 25; + private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED = 26; + + private static final byte SSH_AGENT_CONSTRAIN_LIFETIME = 1; + private static final byte SSH_AGENT_CONSTRAIN_CONFIRM = 2; + + private static final byte SSH2_AGENT_FAILURE = 30; + + private static final byte SSH_COM_AGENT2_FAILURE = 102; + + //private static final byte SSH_AGENT_OLD_SIGNATURE = 0x1; + private static final int SSH_AGENT_RSA_SHA2_256 = 0x2; + private static final int SSH_AGENT_RSA_SHA2_512 = 0x4; + + private static final int MAX_AGENT_IDENTITIES = 2048; + + private final byte[] buf = new byte[1024]; + private final Buffer buffer = new Buffer(buf); + + private AgentConnector connector; + + AgentProxy(AgentConnector connector){ + this.connector = connector; + } + + synchronized Vector getIdentities() { + Vector identities = new Vector<>(); + + int required_size = 1 + 4; + buffer.reset(); + buffer.checkFreeSize(required_size); + buffer.putInt(required_size - 4); + buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES); + + try { + connector.query(buffer); + } + catch(AgentProxyException e){ + buffer.rewind(); + buffer.putByte(SSH_AGENT_FAILURE); + return identities; + } + + int rcode = buffer.getByte(); + + //System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER); + + if(rcode != SSH2_AGENT_IDENTITIES_ANSWER) { + return identities; + } + + int count = buffer.getInt(); + //System.out.println(count); + if(count <= 0 || count > MAX_AGENT_IDENTITIES) { + return identities; + } + + for(int i=0; i>>4)&0xf]); - System.err.print(chars[foo&0xf]); + System.err.print(chars[(foo>>>4)&0xf]); + System.err.print(chars[foo&0xf]); if(i%16==15){ System.err.println(""); - continue; - } + continue; + } if(i>0 && i%2==1){ System.err.print(" "); - } + } } System.err.println(""); } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Channel.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Channel.java index 2d94e5cb..d7e143ac 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Channel.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/Channel.java @@ -29,14 +29,10 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; +import java.io.*; +import java.util.Vector; - -public abstract class Channel implements Runnable{ +public abstract class Channel{ static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION= 91; static final int SSH_MSG_CHANNEL_OPEN_FAILURE= 92; @@ -48,41 +44,49 @@ public abstract class Channel implements Runnable{ static final int SSH_OPEN_RESOURCE_SHORTAGE= 4; static int index=0; - private static java.util.Vector pool=new java.util.Vector(); - static Channel getChannel(String type){ + private static Vector pool=new Vector<>(); + static Channel getChannel(String type, Session session){ + Channel ret = null; if(type.equals("session")){ - return new ChannelSession(); + ret = new ChannelSession(); } if(type.equals("shell")){ - return new ChannelShell(); + ret = new ChannelShell(); } if(type.equals("exec")){ - return new ChannelExec(); + ret = new ChannelExec(); } if(type.equals("x11")){ - return new ChannelX11(); + ret = new ChannelX11(); } if(type.equals("auth-agent@openssh.com")){ - return new ChannelAgentForwarding(); + ret = new ChannelAgentForwarding(); } if(type.equals("direct-tcpip")){ - return new ChannelDirectTCPIP(); + ret = new ChannelDirectTCPIP(); } if(type.equals("forwarded-tcpip")){ - return new ChannelForwardedTCPIP(); + ret = new ChannelForwardedTCPIP(); } if(type.equals("sftp")){ - return new ChannelSftp(); + ret = new ChannelSftp(); } if(type.equals("subsystem")){ - return new ChannelSubsystem(); + ret = new ChannelSubsystem(); } - return null; + if(type.equals("direct-streamlocal@openssh.com")){ + ret = new ChannelDirectStreamLocal(); + } + if (ret == null) { + return null; + } + ret.setSession(session); + return ret; } static Channel getChannel(int id, Session session){ synchronized(pool){ for(int i=0; i identities = irepo.getIdentities(); synchronized(identities){ int count=0; for(int i=0; i identities = irepo.getIdentities(); Identity identity = null; synchronized(identities){ for(int i=0; i + * https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL + */ +public class ChannelDirectStreamLocal extends ChannelDirectTCPIP { + + static private final int LOCAL_WINDOW_SIZE_MAX = 0x20000; + static private final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000; + static private final byte[] _type = Util.str2byte("direct-streamlocal@openssh.com"); + + private String socketPath; + + ChannelDirectStreamLocal() { + super(); + type = _type; + setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX); + setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX); + setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); + } + + @Override + protected Packet genChannelOpenPacket() { + + if (socketPath == null) { + session.getLogger().log(Logger.FATAL, "socketPath must be set"); + throw new RuntimeException("socketPath must be set"); + } + + /* + Similar to direct-tcpip, direct-streamlocal is sent by the client + to request that the server make a connection to a Unix domain socket. + + byte SSH_MSG_CHANNEL_OPEN + string "direct-streamlocal@openssh.com" + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + string socket path + string reserved + uint32 reserved + */ + + Buffer buf = new Buffer(50 + + socketPath.length() + + Session.buffer_margin); + Packet packet = new Packet(buf); + packet.reset(); + buf.putByte((byte) SSH_MSG_CHANNEL_OPEN); + buf.putString(this.type); + buf.putInt(id); + buf.putInt(lwsize); + buf.putInt(lmpsize); + buf.putString(Util.str2byte(socketPath)); + buf.putString(Util.str2byte(originator_IP_address)); + buf.putInt(originator_port); + return packet; + } + + public String getSocketPath() { + return socketPath; + } + + public void setSocketPath(String socketPath) { + this.socketPath = socketPath; + } +} 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 70ddf429..f4c127be 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 @@ -50,10 +50,12 @@ public class ChannelDirectTCPIP extends Channel{ setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); } + @Override void init (){ io=new IO(); } + @Override public void connect(int connectTimeout) throws JSchException{ this.connectTimeout=connectTimeout; try{ @@ -63,7 +65,7 @@ public class ChannelDirectTCPIP extends Channel{ } if(io.in!=null){ - thread=new Thread(this); + thread=new Thread(this::run); thread.setName("DirectTCPIP thread "+_session.getHost()); if(_session.daemon_thread){ thread.setDaemon(_session.daemon_thread); @@ -84,7 +86,8 @@ public class ChannelDirectTCPIP extends Channel{ } } - public void run(){ + @Override + void run(){ try{ sendChannelOpen(); @@ -133,9 +136,11 @@ public class ChannelDirectTCPIP extends Channel{ disconnect(); } + @Override public void setInputStream(InputStream in){ io.setInputStream(in); } + @Override public void setOutputStream(OutputStream out){ io.setOutputStream(out); } @@ -145,6 +150,7 @@ public class ChannelDirectTCPIP extends Channel{ public void setOrgIPAddress(String foo){this.originator_IP_address=foo;} public void setOrgPort(int foo){this.originator_port=foo;} + @Override protected Packet genChannelOpenPacket(){ Buffer buf = new Buffer(50 + // 6 + 4*8 + 12 host.length() + originator_IP_address.length() + 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 f8f3aee9..3980ffd6 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 @@ -29,12 +29,14 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; +import java.io.*; import java.util.*; public class ChannelExec extends ChannelSession{ byte[] command=new byte[0]; + @Override public void start() throws JSchException{ Session _session=getSession(); try{ @@ -44,13 +46,11 @@ public class ChannelExec extends ChannelSession{ } catch(Exception e){ if(e instanceof JSchException) throw (JSchException)e; - if(e instanceof Throwable) - throw new JSchException("ChannelExec", (Throwable)e); - throw new JSchException("ChannelExec"); + throw new JSchException("ChannelExec", e); } if(io.in!=null){ - thread=new Thread(this); + thread=new Thread(this::run); thread.setName("Exec thread "+_session.getHost()); if(_session.daemon_thread){ thread.setDaemon(_session.daemon_thread); @@ -66,18 +66,19 @@ public class ChannelExec extends ChannelSession{ this.command=command; } + @Override void init() throws JSchException { io.setInputStream(getSession().in); io.setOutputStream(getSession().out); } - public void setErrStream(java.io.OutputStream out){ + public void setErrStream(OutputStream out){ setExtOutputStream(out); } - public void setErrStream(java.io.OutputStream out, boolean dontclose){ + public void setErrStream(OutputStream out, boolean dontclose){ setExtOutputStream(out, dontclose); } - public java.io.InputStream getErrStream() throws java.io.IOException { + public InputStream getErrStream() throws IOException { return getExtInputStream(); } } 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 0a59b254..0210e059 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 @@ -35,7 +35,7 @@ import java.util.Vector; public class ChannelForwardedTCPIP extends Channel{ - private static Vector pool = new Vector(); + private static Vector pool = new Vector<>(); static private final int LOCAL_WINDOW_SIZE_MAX=0x20000; //static private final int LOCAL_WINDOW_SIZE_MAX=0x100000; @@ -56,12 +56,13 @@ public class ChannelForwardedTCPIP extends Channel{ connected=true; } + @Override public void run(){ try{ if(config instanceof ConfigDaemon){ ConfigDaemon _config = (ConfigDaemon)config; - Class c=Class.forName(_config.target); - daemon=(ForwardedTCPIPDaemon)c.newInstance(); + Class c=Class.forName(_config.target).asSubclass(ForwardedTCPIPDaemon.class); + daemon=c.getDeclaredConstructor().newInstance(); PipedOutputStream out=new PipedOutputStream(); io.setInputStream(new PassiveInputStream(out @@ -128,6 +129,7 @@ public class ChannelForwardedTCPIP extends Channel{ disconnect(); } + @Override void getData(Buffer buf){ setRecipient(buf.getInt()); setRemoteWindowSize(buf.getUInt()); @@ -157,8 +159,8 @@ public class ChannelForwardedTCPIP extends Channel{ this.config = getPort(_session, null, port); if(this.config == null){ - if(JSch.getLogger().isEnabled(Logger.ERROR)){ - JSch.getLogger().log(Logger.ERROR, + if(_session.getLogger().isEnabled(Logger.ERROR)){ + _session.getLogger().log(Logger.ERROR, "ChannelForwardedTCPIP: "+Util.byte2str(addr)+":"+port+" is not registered."); } } @@ -167,7 +169,7 @@ public class ChannelForwardedTCPIP extends Channel{ private static Config getPort(Session session, String address_to_bind, int rport){ synchronized(pool){ for(int i=0; i foo = new Vector<>(); synchronized(pool){ for(int i=0; i env=null; protected boolean pty=false; @@ -68,16 +68,18 @@ class ChannelSession extends Channel{ * * @param enable */ + @Override public void setXForwarding(boolean enable){ xforwading=enable; } /** - * @deprecated Use {@link #setEnv(String, String)} or {@link #setEnv(byte[], byte[])} instead. + * @deprecated Use #setEnv(String, String) or #setEnv(byte[], byte[]) instead. * @see #setEnv(String, String) * @see #setEnv(byte[], byte[]) */ - public void setEnv(Hashtable env){ + @Deprecated + public void setEnv(Hashtable env){ synchronized(this){ this.env=env; } @@ -111,9 +113,9 @@ class ChannelSession extends Channel{ } } - private Hashtable getEnv(){ + private Hashtable getEnv(){ if(env==null) - env=new Hashtable(); + env=new Hashtable<>(); return env; } @@ -213,9 +215,9 @@ class ChannelSession extends Channel{ } if(env!=null){ - for(Enumeration _env=env.keys(); _env.hasMoreElements();){ - Object name=_env.nextElement(); - Object value=env.get(name); + for(Enumeration _env=env.keys(); _env.hasMoreElements();){ + byte[] name=_env.nextElement(); + byte[] value=env.get(name); request=new RequestEnv(); ((RequestEnv)request).setEnv(toByteArray(name), toByteArray(value)); @@ -231,7 +233,8 @@ class ChannelSession extends Channel{ return (byte[])o; } - public void run(){ + @Override + void run(){ //System.err.println(this+":run >"); Buffer buf=new Buffer(rmpsize); @@ -239,27 +242,27 @@ class ChannelSession extends Channel{ int i=-1; try{ while(isConnected() && - thread!=null && + thread!=null && io!=null && io.in!=null){ i=io.in.read(buf.buffer, 14, buf.buffer.length-14 -Session.buffer_margin - ); - if(i==0)continue; - if(i==-1){ - eof(); - break; - } - if(close)break; + ); + if(i==0)continue; + if(i==-1){ + eof(); + break; + } + if(close)break; //System.out.println("write: "+i); packet.reset(); buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA); buf.putInt(recipient); buf.putInt(i); buf.skip(i); - getSession().write(packet, this, i); + getSession().write(packet, this, i); } } catch(Exception e){ 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 f76d1d5d..0157752a 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 @@ -30,7 +30,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; import java.io.*; - +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Hashtable; import java.util.Vector; public class ChannelSftp extends ChannelSession{ @@ -146,7 +148,7 @@ public class ChannelSftp extends ChannelSession{ private int server_version=3; private String version=String.valueOf(client_version); - private java.util.Hashtable extensions=null; + private Hashtable extensions=null; private InputStream io_in=null; private boolean extension_posix_rename = false; @@ -170,16 +172,15 @@ public class ChannelSftp extends ChannelSession{ o Implementation changes, no actual protocol changes. */ - private static final String file_separator=java.io.File.separator; - private static final char file_separatorc=java.io.File.separatorChar; - private static boolean fs_is_bs=(byte)java.io.File.separatorChar == '\\'; + private static final String file_separator=File.separator; + private static final char file_separatorc=File.separatorChar; + private static boolean fs_is_bs=(byte)File.separatorChar == '\\'; private String cwd; private String home; private String lcwd; - private static final String UTF8="UTF-8"; - private String fEncoding=UTF8; + private Charset fEncoding=StandardCharsets.UTF_8; private boolean fEncoding_is_utf8=true; private RequestQueue rq = new RequestQueue(16); @@ -216,15 +217,17 @@ public class ChannelSftp extends ChannelSession{ setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE); } + @Override void init(){ } + @Override public void start() throws JSchException{ try{ PipedOutputStream pos=new PipedOutputStream(); io.setOutputStream(pos); - PipedInputStream pis=new MyPipedInputStream(pos, rmpsize); + PipedInputStream pis=new MyPipedInputStream(pos, rq.size()*rmpsize); io.setInputStream(pis); io_in=io.in; @@ -268,7 +271,7 @@ public class ChannelSftp extends ChannelSession{ type=header.type; // 2 -> SSH_FXP_VERSION server_version=header.rid; //System.err.println("SFTP protocol server-version="+server_version); - extensions=new java.util.Hashtable(); + extensions=new Hashtable<>(); if(length>0){ // extension data fill(buf, length); @@ -311,9 +314,7 @@ public class ChannelSftp extends ChannelSession{ catch(Exception e){ //System.err.println(e); if(e instanceof JSchException) throw (JSchException)e; - if(e instanceof Throwable) - throw new JSchException(e.toString(), (Throwable)e); - throw new JSchException(e.toString()); + throw new JSchException(e.toString(), e); } } @@ -323,7 +324,7 @@ public class ChannelSftp extends ChannelSession{ path=localAbsolutePath(path); if((new File(path)).isDirectory()){ try{ - path=(new File(path)).getCanonicalPath(); + path=(new File(path)).getCanonicalPath(); } catch(Exception e){} lcwd=path; @@ -355,9 +356,7 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } @@ -368,7 +367,7 @@ public class ChannelSftp extends ChannelSession{ put(src, dst, null, mode); } public void put(String src, String dst, - SftpProgressMonitor monitor) throws SftpException{ + SftpProgressMonitor monitor) throws SftpException{ put(src, dst, monitor, OVERWRITE); } @@ -383,7 +382,7 @@ public class ChannelSftp extends ChannelSession{ * @param mode how data should be added to dst */ public void put(String src, String dst, - SftpProgressMonitor monitor, int mode) throws SftpException{ + SftpProgressMonitor monitor, int mode) throws SftpException{ try{ ((MyPipedInputStream)io_in).updateReadSide(); @@ -391,7 +390,7 @@ public class ChannelSftp extends ChannelSession{ src=localAbsolutePath(src); dst=remoteAbsolutePath(dst); - Vector v=glob_remote(dst); + Vector v=glob_remote(dst); int vsize=v.size(); if(vsize!=1){ if(vsize==0){ @@ -403,7 +402,7 @@ public class ChannelSftp extends ChannelSession{ throw new SftpException(SSH_FX_FAILURE, v.toString()); } else{ - dst=(String)(v.elementAt(0)); + dst=v.elementAt(0); } boolean isRemoteDir=isRemoteDir(dst); @@ -411,12 +410,12 @@ public class ChannelSftp extends ChannelSession{ v=glob_local(src); vsize=v.size(); - StringBuffer dstsb=null; + StringBuilder dstsb=null; if(isRemoteDir){ if(!dst.endsWith("/")){ - dst+="/"; + dst+="/"; } - dstsb=new StringBuffer(dst); + dstsb=new StringBuilder(dst); } else if(vsize>1){ throw new SftpException(SSH_FX_FAILURE, @@ -424,68 +423,66 @@ public class ChannelSftp extends ChannelSession{ } for(int j=0; ji) i=ii; } - if(i==-1) dstsb.append(_src); - else dstsb.append(_src.substring(i + 1)); + if(i==-1) dstsb.append(_src); + else dstsb.append(_src.substring(i + 1)); _dst=dstsb.toString(); dstsb.delete(dst.length(), _dst.length()); - } + } else{ _dst=dst; } //System.err.println("_dst "+_dst); - long size_of_dst=0; - if(mode==RESUME){ - try{ - SftpATTRS attr=_stat(_dst); - size_of_dst=attr.getSize(); - } - catch(Exception eee){ - //System.err.println(eee); - } - long size_of_src=new File(_src).length(); - if(size_of_src v=glob_remote(dst); int vsize=v.size(); if(vsize!=1){ if(vsize==0){ @@ -528,7 +525,7 @@ public class ChannelSftp extends ChannelSession{ throw new SftpException(SSH_FX_FAILURE, v.toString()); } else{ - dst=(String)(v.elementAt(0)); + dst=v.elementAt(0); } if(monitor!=null){ @@ -547,9 +544,7 @@ public class ChannelSftp extends ChannelSession{ } throw (SftpException)e; } - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, e.toString(), (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, e.toString()); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } @@ -561,19 +556,19 @@ public class ChannelSftp extends ChannelSession{ byte[] dstb=Util.str2byte(dst, fEncoding); long skip=0; if(mode==RESUME || mode==APPEND){ - try{ - SftpATTRS attr=_stat(dstb); - skip=attr.getSize(); - } - catch(Exception eee){ - //System.err.println(eee); - } + try{ + SftpATTRS attr=_stat(dstb); + skip=attr.getSize(); + } + catch(Exception eee){ + //System.err.println(eee); + } } if(mode==RESUME && skip>0){ - long skipped=src.skip(skip); - if(skipped v=glob_remote(src); int vsize=v.size(); if(vsize==0){ throw new SftpException(SSH_FX_NO_SUCH_FILE, "No such file"); @@ -911,12 +907,12 @@ public class ChannelSftp extends ChannelSession{ File dstFile=new File(dst); boolean isDstDir=dstFile.isDirectory(); - StringBuffer dstsb=null; + StringBuilder dstsb=null; if(isDstDir){ if(!dst.endsWith(file_separator)){ dst+=file_separator; } - dstsb=new StringBuffer(dst); + dstsb=new StringBuilder(dst); } else if(vsize>1){ throw new SftpException(SSH_FX_FAILURE, @@ -924,22 +920,22 @@ public class ChannelSftp extends ChannelSession{ } for(int j=0; jdstc.length() && _dstc.substring(0, dstc.length()+1).equals(dstc+file_separator))){ throw new SftpException(SSH_FX_FAILURE, @@ -947,30 +943,30 @@ public class ChannelSftp extends ChannelSession{ } } dstsb.delete(dst.length(), _dst.length()); - } + } else{ _dst=dst; } File _dstFile=new File(_dst); - if(mode==RESUME){ - long size_of_src=attr.getSize(); - long size_of_dst=_dstFile.length(); - if(size_of_dst>size_of_src){ - throw new SftpException(SSH_FX_FAILURE, + if(mode==RESUME){ + long size_of_src=attr.getSize(); + long size_of_dst=_dstFile.length(); + if(size_of_dst>size_of_src){ + throw new SftpException(SSH_FX_FAILURE, "failed to resume for "+_dst); - } - if(size_of_dst==size_of_src){ - return; - } - } + } + if(size_of_dst==size_of_src){ + return; + } + } - if(monitor!=null){ - monitor.init(SftpProgressMonitor.GET, _src, _dst, attr.getSize()); - if(mode==RESUME){ - monitor.count(_dstFile.length()); - } - } + if(monitor!=null){ + monitor.init(SftpProgressMonitor.GET, _src, _dst, attr.getSize()); + if(mode==RESUME){ + monitor.count(_dstFile.length()); + } + } FileOutputStream fos=null; _dstExist = _dstFile.exists(); @@ -999,20 +995,18 @@ public class ChannelSftp extends ChannelSession{ } } if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void get(String src, OutputStream dst) throws SftpException{ get(src, dst, null, OVERWRITE, 0); } public void get(String src, OutputStream dst, - SftpProgressMonitor monitor) throws SftpException{ + SftpProgressMonitor monitor) throws SftpException{ get(src, dst, monitor, OVERWRITE, 0); } public void get(String src, OutputStream dst, - SftpProgressMonitor monitor, int mode, long skip) throws SftpException{ + SftpProgressMonitor monitor, int mode, long skip) throws SftpException{ //System.err.println("get: "+src+", "+dst); try{ ((MyPipedInputStream)io_in).updateReadSide(); @@ -1021,7 +1015,7 @@ public class ChannelSftp extends ChannelSession{ src=isUnique(src); if(monitor!=null){ - SftpATTRS attr=_stat(src); + SftpATTRS attr=_stat(src); monitor.init(SftpProgressMonitor.GET, src, "??", attr.getSize()); if(mode==RESUME){ monitor.count(skip); @@ -1031,9 +1025,7 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } @@ -1053,7 +1045,7 @@ public class ChannelSftp extends ChannelSession{ fill(buf, length); if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){ - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, ""); } if(type==SSH_FXP_STATUS){ @@ -1065,7 +1057,7 @@ public class ChannelSftp extends ChannelSession{ long offset=0; if(mode==RESUME){ - offset+=skip; + offset+=skip; } int request_max=1; @@ -1108,7 +1100,7 @@ public class ChannelSftp extends ChannelSession{ } if(type!=SSH_FXP_DATA){ - break loop; + break loop; } buf.rewind(); @@ -1136,7 +1128,7 @@ public class ChannelSftp extends ChannelSession{ int data_len = io_in.read(buf.buffer, 0, bar); if(data_len<0){ break loop; - } + } dst.write(buf.buffer, 0, data_len); @@ -1154,7 +1146,7 @@ public class ChannelSftp extends ChannelSession{ } } - //System.err.println("length: "+length); // length should be 0 + //System.err.println("length: "+length); // length should be 0 if(optional_data>0){ skip(optional_data); @@ -1180,15 +1172,14 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } private class RequestQueue { class OutOfOrderException extends Exception { + private static final long serialVersionUID=-1L; long offset; OutOfOrderException(long offset){ this.offset=offset; @@ -1296,12 +1287,14 @@ public class ChannelSftp extends ChannelSession{ /** * @deprecated This method will be deleted in the future. */ + @Deprecated public InputStream get(String src, int mode) throws SftpException{ return get(src, null, 0L); } /** * @deprecated This method will be deleted in the future. */ + @Deprecated public InputStream get(String src, final SftpProgressMonitor monitor, final int mode) throws SftpException{ return get(src, monitor, 0L); } @@ -1330,7 +1323,7 @@ public class ChannelSftp extends ChannelSession{ fill(buf, length); if(type!=SSH_FXP_STATUS && type!=SSH_FXP_HANDLE){ - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, ""); } if(type==SSH_FXP_STATUS){ int i=buf.getInt(); @@ -1341,7 +1334,7 @@ public class ChannelSftp extends ChannelSession{ rq.init(); - java.io.InputStream in=new java.io.InputStream(){ + InputStream in=new InputStream(){ long offset=skip; boolean closed=false; int rest_length=0; @@ -1351,7 +1344,8 @@ public class ChannelSftp extends ChannelSession{ int request_max=1; long request_offset=offset; - public int read() throws java.io.IOException{ + @Override + public int read() throws IOException{ if(closed)return -1; int i=read(_data, 0, 1); if (i==-1) { return -1; } @@ -1359,11 +1353,13 @@ public class ChannelSftp extends ChannelSession{ return _data[0]&0xff; } } - public int read(byte[] d) throws java.io.IOException{ + @Override + public int read(byte[] d) throws IOException{ if(closed)return -1; return read(d, 0, d.length); } - public int read(byte[] d, int s, int len) throws java.io.IOException{ + @Override + public int read(byte[] d, int s, int len) throws IOException{ if(closed)return -1; if(d==null){throw new NullPointerException();} if(s<0 || len <0 || s+len>d.length){ @@ -1430,7 +1426,7 @@ public class ChannelSftp extends ChannelSession{ return 0; } catch(SftpException e){ - throw new IOException("error: "+e.toString()); + throw new IOException("error: "+e.toString(), e); } if(type!=SSH_FXP_STATUS && type!=SSH_FXP_DATA){ @@ -1523,6 +1519,7 @@ public class ChannelSftp extends ChannelSession{ } return 0; // ?? } + @Override public void close() throws IOException{ if(closed)return; closed=true; @@ -1536,15 +1533,14 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } - public java.util.Vector ls(String path) throws SftpException{ - final java.util.Vector v = new Vector(); + public Vector ls(String path) throws SftpException{ + final Vector v = new Vector<>(); LsEntrySelector selector = new LsEntrySelector(){ + @Override public int select(LsEntry entry){ v.addElement(entry); return CONTINUE; @@ -1571,7 +1567,7 @@ public class ChannelSftp extends ChannelSession{ path=remoteAbsolutePath(path); byte[] pattern=null; - java.util.Vector v=new java.util.Vector(); + Vector v=new Vector<>(); int foo=path.lastIndexOf('/'); String dir=path.substring(0, ((foo==0)?1:foo)); @@ -1696,7 +1692,7 @@ public class ChannelSftp extends ChannelSession{ byte[] _filename=filename; if(!fEncoding_is_utf8){ f=Util.byte2str(_filename, fEncoding); - _filename=Util.str2byte(f, UTF8); + _filename=Util.str2byte(f, StandardCharsets.UTF_8); } find=Util.glob(pattern, _filename); } @@ -1743,9 +1739,7 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } @@ -1792,9 +1786,7 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } return null; } @@ -1845,9 +1837,7 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } @@ -1897,9 +1887,7 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } @@ -1917,13 +1905,13 @@ public class ChannelSftp extends ChannelSession{ oldpath=isUnique(oldpath); - Vector v=glob_remote(newpath); + Vector v=glob_remote(newpath); int vsize=v.size(); if(vsize>=2){ throw new SftpException(SSH_FX_FAILURE, v.toString()); } if(vsize==1){ - newpath=(String)(v.elementAt(0)); + newpath=v.elementAt(0); } else{ // vsize==0 if(isPattern(newpath)) @@ -1951,9 +1939,7 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } public void rm(String path) throws SftpException{ @@ -1962,13 +1948,13 @@ public class ChannelSftp extends ChannelSession{ path=remoteAbsolutePath(path); - Vector v=glob_remote(path); + Vector v=glob_remote(path); int vsize=v.size(); Header header=new Header(); for(int j=0; j v=glob_remote(path); int vsize=v.size(); for(int j=0; j v=glob_remote(path); int vsize=v.size(); for(int j=0; j v=glob_remote(path); int vsize=v.size(); for(int j=0; j v=glob_remote(path); int vsize=v.size(); for(int j=0; j v=glob_remote(path); int vsize=v.size(); Header header=new Header(); for(int j=0; j v=glob_remote(path); int vsize=v.size(); for(int j=0; j glob_remote(String _path) throws Exception{ + Vector v=new Vector<>(); int i=0; int foo=_path.lastIndexOf('/'); @@ -2730,11 +2684,11 @@ public class ChannelSftp extends ChannelSession{ type=header.type; if(type!=SSH_FXP_STATUS && type!=SSH_FXP_NAME){ - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, ""); } if(type==SSH_FXP_STATUS){ fill(buf, length); - break; + break; } buf.rewind(); @@ -2746,21 +2700,21 @@ public class ChannelSftp extends ChannelSession{ buf.reset(); while(count>0){ - if(length>0){ - buf.shift(); + if(length>0){ + buf.shift(); int j=(buf.buffer.length>(buf.index+length)) ? length : (buf.buffer.length-buf.index); - i=io_in.read(buf.buffer, buf.index, j); - if(i<=0)break; - buf.index+=i; - length-=i; - } + i=io_in.read(buf.buffer, buf.index, j); + if(i<=0)break; + buf.index+=i; + length-=i; + } - byte[] filename=buf.getString(); - //System.err.println("filename: "+new String(filename)); + byte[] filename=buf.getString(); + //System.err.println("filename: "+new String(filename)); if(server_version<=3){ str=buf.getString(); // longname } - SftpATTRS attrs=SftpATTRS.getATTR(buf); + SftpATTRS attrs=SftpATTRS.getATTR(buf); byte[] _filename=filename; String f=null; @@ -2768,11 +2722,11 @@ public class ChannelSftp extends ChannelSession{ if(!fEncoding_is_utf8){ f=Util.byte2str(filename, fEncoding); - _filename=Util.str2byte(f, UTF8); + _filename=Util.str2byte(f, StandardCharsets.UTF_8); } found=Util.glob(pattern, _filename); - if(found){ + if(found){ if(f==null){ f=Util.byte2str(filename, fEncoding); } @@ -2782,9 +2736,9 @@ public class ChannelSftp extends ChannelSession{ pdir+="/"; } } - v.addElement(pdir+f); - } - count--; + v.addElement(pdir+f); + } + count--; } } if(_sendCLOSE(handle, header)) @@ -2805,10 +2759,10 @@ public class ChannelSftp extends ChannelSession{ return false; } - private Vector glob_local(String _path) throws Exception{ + private Vector glob_local(String _path) throws Exception{ //System.err.println("glob_local: "+_path); - Vector v=new Vector(); - byte[] path=Util.str2byte(_path, UTF8); + Vector v=new Vector<>(); + byte[] path=Util.str2byte(_path, StandardCharsets.UTF_8); int i=path.length-1; while(i>=0){ if(path[i]!='*' && path[i]!='?'){ @@ -2851,13 +2805,13 @@ public class ChannelSftp extends ChannelSession{ //System.err.println("dir: "+new String(dir)+" pattern: "+new String(pattern)); try{ - String[] children=(new File(Util.byte2str(dir, UTF8))).list(); + String[] children=(new File(Util.byte2str(dir, StandardCharsets.UTF_8))).list(); String pdir=Util.byte2str(dir)+file_separator; for(int j=0; j=4){ // SSH_FXP_STATUS packet. byte[] str=buf.getString(); //byte[] tag=buf.getString(); - throw new SftpException(i, Util.byte2str(str, UTF8)); + throw new SftpException(i, Util.byte2str(str, StandardCharsets.UTF_8)); } else{ throw new SftpException(i, "Failure"); @@ -2881,12 +2835,13 @@ public class ChannelSftp extends ChannelSession{ return (new File(path)).isAbsolute(); } + @Override public void disconnect(){ super.disconnect(); } private boolean isPattern(String path, byte[][] utf8){ - byte[] _path=Util.str2byte(path, UTF8); + byte[] _path=Util.str2byte(path, StandardCharsets.UTF_8); if(utf8!=null) utf8[0]=_path; return isPattern(_path); @@ -2925,7 +2880,7 @@ public class ChannelSftp extends ChannelSession{ } } - class Header{ + static class Header{ int length; int type; int rid; @@ -2960,11 +2915,11 @@ public class ChannelSftp extends ChannelSession{ * @return the returned string is unquoted. */ private String isUnique(String path) throws SftpException, Exception{ - Vector v=glob_remote(path); + Vector v=glob_remote(path); if(v.size()!=1){ throw new SftpException(SSH_FX_FAILURE, path+" is not unique: "+v.toString()); } - return (String)(v.elementAt(0)); + return v.elementAt(0); } public int getServerVersion() throws SftpException{ @@ -2974,24 +2929,26 @@ public class ChannelSftp extends ChannelSession{ return server_version; } + @Deprecated public void setFilenameEncoding(String encoding) throws SftpException{ - int sversion=getServerVersion(); - if(3 <= sversion && sversion <= 5 && - !encoding.equals(UTF8)){ - throw new SftpException(SSH_FX_FAILURE, - "The encoding can not be changed for this sftp server."); + try{ + setFilenameEncoding(Charset.forName(encoding)); } - if(encoding.equals(UTF8)){ - encoding=UTF8; + catch(Exception e){ + if(e instanceof SftpException) throw (SftpException)e; + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } + } + + public void setFilenameEncoding(Charset encoding){ fEncoding=encoding; - fEncoding_is_utf8=fEncoding.equals(UTF8); + fEncoding_is_utf8=fEncoding.equals(StandardCharsets.UTF_8); } public String getExtension(String key){ if(extensions==null) return null; - return (String)extensions.get(key); + return extensions.get(key); } public String realpath(String path) throws SftpException{ @@ -3001,13 +2958,11 @@ public class ChannelSftp extends ChannelSession{ } catch(Exception e){ if(e instanceof SftpException) throw (SftpException)e; - if(e instanceof Throwable) - throw new SftpException(SSH_FX_FAILURE, "", (Throwable)e); - throw new SftpException(SSH_FX_FAILURE, ""); + throw new SftpException(SSH_FX_FAILURE, e.toString(), e); } } - public class LsEntry implements Comparable{ + public static class LsEntry implements Comparable{ private String filename; private String longname; private SftpATTRS attrs; @@ -3022,12 +2977,11 @@ public class ChannelSftp extends ChannelSession{ void setLongname(String longname){this.longname = longname;}; public SftpATTRS getAttrs(){return attrs;}; void setAttrs(SftpATTRS attrs) {this.attrs = attrs;}; + @Override public String toString(){ return longname; } - public int compareTo(Object o) throws ClassCastException{ - if(o instanceof LsEntry){ - return filename.compareTo(((LsEntry)o).getFilename()); - } - throw new ClassCastException("a decendent of LsEntry must be given."); + @Override + public int compareTo(LsEntry o){ + return filename.compareTo(o.getFilename()); } } 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 5113c503..2e8250d3 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 @@ -38,6 +38,7 @@ public class ChannelShell extends ChannelSession{ pty=true; } + @Override public void start() throws JSchException{ Session _session=getSession(); try{ @@ -48,13 +49,11 @@ public class ChannelShell extends ChannelSession{ } catch(Exception e){ if(e instanceof JSchException) throw (JSchException)e; - if(e instanceof Throwable) - throw new JSchException("ChannelShell", (Throwable)e); - throw new JSchException("ChannelShell"); + throw new JSchException("ChannelShell", e); } if(io.in!=null){ - thread=new Thread(this); + thread=new Thread(this::run); thread.setName("Shell for "+_session.host); if(_session.daemon_thread){ thread.setDaemon(_session.daemon_thread); @@ -63,6 +62,7 @@ public class ChannelShell extends ChannelSession{ } } + @Override void init() throws JSchException { io.setInputStream(getSession().in); io.setOutputStream(getSession().out); 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 568b4910..04a4fc89 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 @@ -29,15 +29,14 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; +import java.io.*; + public class ChannelSubsystem extends ChannelSession{ - boolean xforwading=false; - boolean pty=false; boolean want_reply=true; String subsystem=""; - public void setXForwarding(boolean foo){ xforwading=foo; } - public void setPty(boolean foo){ pty=foo; } public void setWantReply(boolean foo){ want_reply=foo; } public void setSubsystem(String foo){ subsystem=foo; } + @Override public void start() throws JSchException{ Session _session=getSession(); try{ @@ -47,20 +46,18 @@ public class ChannelSubsystem extends ChannelSession{ request.request(_session, this); } if(pty){ - request=new RequestPtyReq(); - request.request(_session, this); + request=new RequestPtyReq(); + request.request(_session, this); } request=new RequestSubsystem(); ((RequestSubsystem)request).request(_session, this, subsystem, want_reply); } catch(Exception e){ if(e instanceof JSchException){ throw (JSchException)e; } - if(e instanceof Throwable) - throw new JSchException("ChannelSubsystem", (Throwable)e); - throw new JSchException("ChannelSubsystem"); + throw new JSchException("ChannelSubsystem", e); } if(io.in!=null){ - thread=new Thread(this); + thread=new Thread(this::run); thread.setName("Subsystem for "+_session.host); if(_session.daemon_thread){ thread.setDaemon(_session.daemon_thread); @@ -69,15 +66,16 @@ public class ChannelSubsystem extends ChannelSession{ } } + @Override void init() throws JSchException { io.setInputStream(getSession().in); io.setOutputStream(getSession().out); } - public void setErrStream(java.io.OutputStream out){ + public void setErrStream(OutputStream out){ setExtOutputStream(out); } - public java.io.InputStream getErrStream() throws java.io.IOException { + public InputStream getErrStream() throws IOException { return getExtInputStream(); } } 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 5be9049f..2f211fb2 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 @@ -29,7 +29,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; +import java.io.IOException; import java.net.*; +import java.util.Hashtable; class ChannelX11 extends Channel{ @@ -46,8 +48,8 @@ class ChannelX11 extends Channel{ static byte[] cookie=null; private static byte[] cookie_hex=null; - private static java.util.Hashtable faked_cookie_pool=new java.util.Hashtable(); - private static java.util.Hashtable faked_cookie_hex_pool=new java.util.Hashtable(); + private static Hashtable faked_cookie_pool=new Hashtable<>(); + private static Hashtable faked_cookie_hex_pool=new Hashtable<>(); private static byte[] table={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39, 0x61,0x62,0x63,0x64,0x65,0x66}; @@ -64,21 +66,21 @@ class ChannelX11 extends Channel{ cookie_hex=Util.str2byte(foo); cookie=new byte[16]; for(int i=0; i<16; i++){ - cookie[i]=(byte)(((revtable(cookie_hex[i*2])<<4)&0xf0) | - ((revtable(cookie_hex[i*2+1]))&0xf)); + cookie[i]=(byte)(((revtable(cookie_hex[i*2])<<4)&0xf0) | + ((revtable(cookie_hex[i*2+1]))&0xf)); } } static void setHost(String foo){ host=foo; } static void setPort(int foo){ port=foo; } static byte[] getFakedCookie(Session session){ synchronized(faked_cookie_hex_pool){ - byte[] foo=(byte[])faked_cookie_hex_pool.get(session); + byte[] foo=faked_cookie_hex_pool.get(session); if(foo==null){ - Random random=Session.random; - foo=new byte[16]; - synchronized(random){ - random.fill(foo, 0, 16); - } + Random random=Session.random; + foo=new byte[16]; + synchronized(random){ + random.fill(foo, 0, 16); + } /* System.err.print("faked_cookie: "); for(int i=0; i>>4)&0xf]; - bar[2*i+1]=table[(foo[i])&0xf]; - } - faked_cookie_hex_pool.put(session, bar); - foo=bar; + faked_cookie_pool.put(session, foo); + byte[] bar=new byte[32]; + for(int i=0; i<16; i++){ + bar[2*i]=table[(foo[i]>>>4)&0xf]; + bar[2*i+1]=table[(foo[i])&0xf]; + } + faked_cookie_hex_pool.put(session, bar); + foo=bar; } return foo; } @@ -130,7 +132,8 @@ System.err.println(""); */ } - public void run(){ + @Override + void run(){ try{ socket=Util.createSocket(host, port, TIMEOUT); @@ -156,19 +159,19 @@ System.err.println(""); io!=null && io.in!=null){ i=io.in.read(buf.buffer, - 14, - buf.buffer.length-14-Session.buffer_margin); - if(i<=0){ - eof(); + 14, + buf.buffer.length-14-Session.buffer_margin); + if(i<=0){ + eof(); break; - } - if(close)break; + } + if(close)break; packet.reset(); buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA); buf.putInt(recipient); buf.putInt(i); buf.skip(i); - getSession().write(packet, this, i); + getSession().write(packet, this, i); } } catch(Exception e){ @@ -187,7 +190,8 @@ System.err.println(""); return cache; } - void write(byte[] foo, int s, int l) throws java.io.IOException { + @Override + void write(byte[] foo, int s, int l) throws IOException { //if(eof_local)return; if(init){ @@ -197,7 +201,7 @@ System.err.println(""); _session=getSession(); } catch(JSchException e){ - throw new java.io.IOException(e.toString()); + throw new IOException(e.toString(), e); } foo=addCache(foo, s, l); @@ -217,7 +221,7 @@ System.err.println(""); dlen=((dlen>>>8)&0xff)|((dlen<<8)&0xff00); } else{ - // ?? + // ?? } if(l<12+plen+((-plen)&3)+dlen) @@ -228,7 +232,7 @@ System.err.println(""); byte[] faked_cookie=null; synchronized(faked_cookie_pool){ - faked_cookie=(byte[])faked_cookie_pool.get(_session); + faked_cookie=faked_cookie_pool.get(_session); } /* @@ -249,7 +253,7 @@ System.err.println(""); System.arraycopy(cookie, 0, foo, s+12+plen+((-plen)&3), dlen); } else{ - //System.err.println("wrong cookie"); + //System.err.println("wrong cookie"); thread=null; eof(); io.close(); 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 966ceb5b..c417a8f2 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 @@ -34,7 +34,13 @@ public interface Cipher{ static int DECRYPT_MODE=1; int getIVSize(); int getBlockSize(); + default int getTagSize() {return 0;} void init(int mode, byte[] key, byte[] iv) throws Exception; + default void update(int foo) throws Exception {} void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception; + default void updateAAD(byte[] foo, int s1, int len) throws Exception {} + default void doFinal(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception {} boolean isCBC(); + default boolean isAEAD() {return false;} + default boolean isChaCha20() {return false;} } 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 917dd9fd..45466939 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 @@ -29,14 +29,19 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class CipherNone implements Cipher{ +class CipherNone implements Cipher{ private static final int ivsize=8; private static final int bsize=16; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ } + @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ } + @Override public boolean isCBC(){return false; } } 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 3db3176b..c1d5ca72 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 @@ -32,6 +32,13 @@ package com.jcraft.jsch; public interface Compression{ static public final int INFLATER=0; static public final int DEFLATER=1; + + default void init(int type, int level, Session session) { + init(type, level); + } + + default void end() {} + void init(int type, int level); byte[] compress(byte[] buf, int start, int[] len); byte[] uncompress(byte[] buf, int start, int[] len); 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 71338899..afbe8e0f 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 @@ -42,14 +42,20 @@ public interface ConfigRepository { } static final Config defaultConfig = new Config() { + @Override public String getHostname() {return null;} + @Override public String getUser() {return null;} + @Override public int getPort() {return -1;} + @Override public String getValue(String key) {return null;} + @Override public String[] getValues(String key) {return null;} }; static final ConfigRepository nullConfig = new ConfigRepository(){ + @Override public Config getConfig(String host) { return defaultConfig; } }; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH25519.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH25519.java new file mode 100644 index 00000000..706e3453 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH25519.java @@ -0,0 +1,38 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2015-2018 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; + +class DH25519 extends DHXEC { + public DH25519(){ + sha_name="sha-256"; + curve_name="X25519"; + key_len=32; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH448.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH448.java new file mode 100644 index 00000000..a0bb9206 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DH448.java @@ -0,0 +1,38 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2015-2018 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; + +class DH448 extends DHXEC { + public DH448(){ + sha_name="sha-512"; + curve_name="X448"; + key_len=56; + } +} 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 index 50454bb1..def8ded6 100644 --- 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 @@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class DHEC256 extends DHECN { +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 index 6438e71d..26a287fa 100644 --- 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 @@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class DHEC384 extends DHECN { +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 index 7a9ac78a..d68701e2 100644 --- 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 @@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class DHEC521 extends DHECN { +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 index d8d2378a..ebb1a7bf 100644 --- 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 @@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public abstract class DHECN extends KeyExchange{ +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; @@ -52,17 +52,17 @@ public abstract class DHECN extends KeyExchange{ protected String sha_name; protected int key_size; + @Override public void init(Session session, - byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ - this.session=session; + byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ 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()); + Class c=Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class); + sha=c.getDeclaredConstructor().newInstance(); sha.init(); } catch(Exception e){ @@ -76,17 +76,15 @@ public abstract class DHECN extends KeyExchange{ buf.putByte((byte)SSH_MSG_KEX_ECDH_INIT); try{ - Class c=Class.forName(session.getConfig("ecdh-sha2-nistp")); - ecdh=(ECDH)(c.newInstance()); + Class c=Class.forName(session.getConfig("ecdh-sha2-nistp")).asSubclass(ECDH.class); + ecdh=c.getDeclaredConstructor().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()); + throw new JSchException(e.toString(), e); } if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-( @@ -95,16 +93,17 @@ public abstract class DHECN extends KeyExchange{ session.write(packet); - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_ECDH_INIT sent"); - JSch.getLogger().log(Logger.INFO, + session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_ECDH_REPLY"); } state=SSH_MSG_KEX_ECDH_REPLY; } + @Override public boolean next(Buffer _buf) throws Exception{ int i,j; switch(state){ @@ -117,9 +116,9 @@ public abstract class DHECN extends KeyExchange{ j=_buf.getInt(); j=_buf.getByte(); j=_buf.getByte(); - if(j!=31){ - System.err.println("type: must be 31 "+j); - return false; + if(j!=SSH_MSG_KEX_ECDH_REPLY){ + System.err.println("type: must be SSH_MSG_KEX_ECDH_REPLY "+j); + return false; } K_S=_buf.getString(); @@ -135,7 +134,7 @@ public abstract class DHECN extends KeyExchange{ // 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; + return false; } K = ecdh.getSecret(r_s[0], r_s[1]); @@ -171,7 +170,7 @@ public abstract class DHECN extends KeyExchange{ i=0; j=0; j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); + ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); String alg=Util.byte2str(K_S, i, j); i+=j; @@ -183,5 +182,6 @@ public abstract class DHECN extends KeyExchange{ return false; } + @Override 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 c8596376..6d71c721 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 @@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class DHG1 extends KeyExchange{ +class DHG1 extends DHGN{ static final byte[] g={ 2 }; static final byte[] p={ @@ -52,145 +52,10 @@ public class DHG1 extends KeyExchange{ (byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF }; - private static final int SSH_MSG_KEXDH_INIT= 30; - private static final int SSH_MSG_KEXDH_REPLY= 31; - - private int state; - - DH dh; - - byte[] V_S; - byte[] V_C; - byte[] I_S; - byte[] I_C; - - byte[] e; - - private Buffer buf; - private Packet packet; - - 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-1")); - sha=(HASH)(c.newInstance()); - sha.init(); - } - catch(Exception e){ - System.err.println(e); - } - - buf=new Buffer(); - packet=new Packet(buf); - - try{ - Class c=Class.forName(session.getConfig("dh")); - dh=(DH)(c.newInstance()); - dh.init(); - } - catch(Exception e){ - //System.err.println(e); - throw e; - } - - dh.setP(p); - dh.setG(g); - - // The client responds with: - // byte SSH_MSG_KEXDH_INIT(30) - // mpint e <- g^x mod p - // x is a random number (1 < x < (p-1)/2) - - e=dh.getE(); - - packet.reset(); - buf.putByte((byte)SSH_MSG_KEXDH_INIT); - buf.putMPInt(e); - session.write(packet); - - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, - "SSH_MSG_KEXDH_INIT sent"); - JSch.getLogger().log(Logger.INFO, - "expecting SSH_MSG_KEXDH_REPLY"); - } - - state=SSH_MSG_KEXDH_REPLY; - } - - public boolean next(Buffer _buf) throws Exception{ - int i,j; - - switch(state){ - case SSH_MSG_KEXDH_REPLY: - // The server responds with: - // byte SSH_MSG_KEXDH_REPLY(31) - // string server public host key and certificates (K_S) - // mpint f - // string signature of H - j=_buf.getInt(); - j=_buf.getByte(); - j=_buf.getByte(); - if(j!=31){ - System.err.println("type: must be 31 "+j); - return false; - } - - K_S=_buf.getString(); - - byte[] f=_buf.getMPInt(); - byte[] sig_of_H=_buf.getString(); - - dh.setF(f); - - dh.checkRange(); - - K=normalize(dh.getK()); - - //The hash H is computed as the HASH hash of the concatenation of the - //following: - // string V_C, the client's version string (CR and NL excluded) - // string V_S, the server's version string (CR and NL excluded) - // string I_C, the payload of the client's SSH_MSG_KEXINIT - // string I_S, the payload of the server's SSH_MSG_KEXINIT - // string K_S, the host key - // mpint e, exchange value sent by the client - // mpint f, exchange value sent by the server - // mpint K, the shared secret - // This value is called the exchange hash, and it is used to authenti- - // cate the key exchange. - buf.reset(); - buf.putString(V_C); buf.putString(V_S); - buf.putString(I_C); buf.putString(I_S); - buf.putString(K_S); - buf.putMPInt(e); buf.putMPInt(f); - buf.putMPInt(K); - byte[] foo=new byte[buf.getLength()]; - buf.getByte(foo); - sha.update(foo, 0, foo.length); - H=sha.digest(); - //System.err.print("H -> "); //dump(H, 0, H.length); - - i=0; - j=0; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - String alg=Util.byte2str(K_S, i, j); - i+=j; - - boolean result = verify(alg, K_S, i, sig_of_H); - - state=STATE_END; - return result; - } - return false; - } - - public int getState(){return state; } + @Override + byte[] G(){ return g; } + @Override + byte[] P(){ return p; } + @Override + String sha_name(){ return "sha-1"; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14.java index 47cb5e85..0ddb65e8 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14.java @@ -29,187 +29,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class DHG14 extends KeyExchange{ +class DHG14 extends DHG14N{ - static final byte[] g={ 2 }; - static final byte[] p={ -(byte)0x00, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, -(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, -(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, -(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, -(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, -(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, -(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, -(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, -(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, -(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, -(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, -(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, -(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, -(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, -(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, -(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, -(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, -(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, -(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, -(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, -(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, -(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, -(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, -(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, -(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, -(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, -(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, -(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, -(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, -(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, -(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68, -(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF -}; - - private static final int SSH_MSG_KEXDH_INIT= 30; - private static final int SSH_MSG_KEXDH_REPLY= 31; - - private int state; - - DH dh; - - byte[] V_S; - byte[] V_C; - byte[] I_S; - byte[] I_C; - - byte[] e; - - private Buffer buf; - private Packet packet; - - 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-1")); - sha=(HASH)(c.newInstance()); - sha.init(); - } - catch(Exception e){ - System.err.println(e); - } - - buf=new Buffer(); - packet=new Packet(buf); - - try{ - Class c=Class.forName(session.getConfig("dh")); - dh=(DH)(c.newInstance()); - dh.init(); - } - catch(Exception e){ - //System.err.println(e); - throw e; - } - - dh.setP(p); - dh.setG(g); - // The client responds with: - // byte SSH_MSG_KEXDH_INIT(30) - // mpint e <- g^x mod p - // x is a random number (1 < x < (p-1)/2) - - e=dh.getE(); - packet.reset(); - buf.putByte((byte)SSH_MSG_KEXDH_INIT); - buf.putMPInt(e); - - 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_KEXDH_INIT sent"); - JSch.getLogger().log(Logger.INFO, - "expecting SSH_MSG_KEXDH_REPLY"); - } - - state=SSH_MSG_KEXDH_REPLY; - } - - public boolean next(Buffer _buf) throws Exception{ - int i,j; - - switch(state){ - case SSH_MSG_KEXDH_REPLY: - // The server responds with: - // byte SSH_MSG_KEXDH_REPLY(31) - // string server public host key and certificates (K_S) - // mpint f - // string signature of H - j=_buf.getInt(); - j=_buf.getByte(); - j=_buf.getByte(); - if(j!=31){ - System.err.println("type: must be 31 "+j); - return false; - } - - K_S=_buf.getString(); - - byte[] f=_buf.getMPInt(); - byte[] sig_of_H=_buf.getString(); - - dh.setF(f); - - dh.checkRange(); - - K=normalize(dh.getK()); - - //The hash H is computed as the HASH hash of the concatenation of the - //following: - // string V_C, the client's version string (CR and NL excluded) - // string V_S, the server's version string (CR and NL excluded) - // string I_C, the payload of the client's SSH_MSG_KEXINIT - // string I_S, the payload of the server's SSH_MSG_KEXINIT - // string K_S, the host key - // mpint e, exchange value sent by the client - // mpint f, exchange value sent by the server - // mpint K, the shared secret - // This value is called the exchange hash, and it is used to authenti- - // cate the key exchange. - buf.reset(); - buf.putString(V_C); buf.putString(V_S); - buf.putString(I_C); buf.putString(I_S); - buf.putString(K_S); - buf.putMPInt(e); buf.putMPInt(f); - buf.putMPInt(K); - byte[] foo=new byte[buf.getLength()]; - buf.getByte(foo); - sha.update(foo, 0, foo.length); - H=sha.digest(); - //System.err.print("H -> "); //dump(H, 0, H.length); - - i=0; - j=0; - j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); - String alg=Util.byte2str(K_S, i, j); - i+=j; - - boolean result = verify(alg, K_S, i, sig_of_H); - - state=STATE_END; - return result; - } - return false; - } - - public int getState(){return state; } + @Override + String sha_name(){ return "sha-1"; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14224.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14224.java new file mode 100644 index 00000000..69c0d4bf --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14224.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG14224 extends DHG14N{ + + @Override + String sha_name(){ return "sha-224"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14256.java new file mode 100644 index 00000000..9403843b --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14256.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG14256 extends DHG14N{ + + @Override + String sha_name(){ return "sha-256"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14N.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14N.java new file mode 100644 index 00000000..5c95b6d8 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG14N.java @@ -0,0 +1,75 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +abstract class DHG14N extends DHGN{ + + static final byte[] g={ 2 }; + static final byte[] p={ +(byte)0x00, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, +(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, +(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, +(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, +(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, +(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, +(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, +(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, +(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, +(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, +(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, +(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, +(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, +(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, +(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, +(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, +(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, +(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, +(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, +(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, +(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, +(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, +(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, +(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, +(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, +(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, +(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, +(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, +(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, +(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, +(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF +}; + + @Override + byte[] G(){ return g; } + @Override + byte[] P(){ return p; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15.java new file mode 100644 index 00000000..0e31d859 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG15 extends DHG15N{ + + @Override + String sha_name(){ return "sha-512"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15256.java new file mode 100644 index 00000000..359450a3 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15256.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG15256 extends DHG15N{ + + @Override + String sha_name(){ return "sha-256"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15384.java new file mode 100644 index 00000000..7c9f2fb7 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15384.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG15384 extends DHG15N{ + + @Override + String sha_name(){ return "sha-384"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15N.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15N.java new file mode 100644 index 00000000..8d72935f --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG15N.java @@ -0,0 +1,91 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +abstract class DHG15N extends DHGN{ + + static final byte[] g={ 2 }; + static final byte[] p={ +(byte)0x00, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, +(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, +(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, +(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, +(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, +(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, +(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, +(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, +(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, +(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, +(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, +(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, +(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, +(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, +(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, +(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, +(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, +(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, +(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, +(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, +(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, +(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, +(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, +(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, +(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, +(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, +(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, +(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, +(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, +(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, +(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D, +(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33, +(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64, +(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A, +(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D, +(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7, +(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7, +(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D, +(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B, +(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64, +(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64, +(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C, +(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C, +(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2, +(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31, +(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E, +(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x3A,(byte)0xD2,(byte)0xCA, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF +}; + + @Override + byte[] G(){ return g; } + @Override + byte[] P(){ return p; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16.java new file mode 100644 index 00000000..f8c62a20 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG16 extends DHG16N{ + + @Override + String sha_name(){ return "sha-512"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16384.java new file mode 100644 index 00000000..533b2046 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16384.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG16384 extends DHG16N{ + + @Override + String sha_name(){ return "sha-384"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16N.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16N.java new file mode 100644 index 00000000..acfcbab2 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG16N.java @@ -0,0 +1,107 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +abstract class DHG16N extends DHGN{ + + static final byte[] g={ 2 }; + static final byte[] p={ +(byte)0x00, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, +(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, +(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, +(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, +(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, +(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, +(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, +(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, +(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, +(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, +(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, +(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, +(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, +(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, +(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, +(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, +(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, +(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, +(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, +(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, +(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, +(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, +(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, +(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, +(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, +(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, +(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, +(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, +(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, +(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, +(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D, +(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33, +(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64, +(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A, +(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D, +(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7, +(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7, +(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D, +(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B, +(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64, +(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64, +(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C, +(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C, +(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2, +(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31, +(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E, +(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01, +(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7, +(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26, +(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C, +(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA, +(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8, +(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9, +(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6, +(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D, +(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2, +(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED, +(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF, +(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C, +(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9, +(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1, +(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F, +(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x06,(byte)0x31,(byte)0x99, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF +}; + + @Override + byte[] G(){ return g; } + @Override + byte[] P(){ return p; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG17.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG17.java new file mode 100644 index 00000000..9d415cf0 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG17.java @@ -0,0 +1,141 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG17 extends DHGN{ + + static final byte[] g={ 2 }; + static final byte[] p={ +(byte)0x00, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, +(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, +(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, +(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, +(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, +(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, +(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, +(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, +(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, +(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, +(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, +(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, +(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, +(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, +(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, +(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, +(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, +(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, +(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, +(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, +(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, +(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, +(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, +(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, +(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, +(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, +(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, +(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, +(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, +(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, +(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D, +(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33, +(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64, +(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A, +(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D, +(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7, +(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7, +(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D, +(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B, +(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64, +(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64, +(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C, +(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C, +(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2, +(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31, +(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E, +(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01, +(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7, +(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26, +(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C, +(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA, +(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8, +(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9, +(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6, +(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D, +(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2, +(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED, +(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF, +(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C, +(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9, +(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1, +(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F, +(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x02,(byte)0x84,(byte)0x92, +(byte)0x36,(byte)0xC3,(byte)0xFA,(byte)0xB4,(byte)0xD2,(byte)0x7C,(byte)0x70,(byte)0x26, +(byte)0xC1,(byte)0xD4,(byte)0xDC,(byte)0xB2,(byte)0x60,(byte)0x26,(byte)0x46,(byte)0xDE, +(byte)0xC9,(byte)0x75,(byte)0x1E,(byte)0x76,(byte)0x3D,(byte)0xBA,(byte)0x37,(byte)0xBD, +(byte)0xF8,(byte)0xFF,(byte)0x94,(byte)0x06,(byte)0xAD,(byte)0x9E,(byte)0x53,(byte)0x0E, +(byte)0xE5,(byte)0xDB,(byte)0x38,(byte)0x2F,(byte)0x41,(byte)0x30,(byte)0x01,(byte)0xAE, +(byte)0xB0,(byte)0x6A,(byte)0x53,(byte)0xED,(byte)0x90,(byte)0x27,(byte)0xD8,(byte)0x31, +(byte)0x17,(byte)0x97,(byte)0x27,(byte)0xB0,(byte)0x86,(byte)0x5A,(byte)0x89,(byte)0x18, +(byte)0xDA,(byte)0x3E,(byte)0xDB,(byte)0xEB,(byte)0xCF,(byte)0x9B,(byte)0x14,(byte)0xED, +(byte)0x44,(byte)0xCE,(byte)0x6C,(byte)0xBA,(byte)0xCE,(byte)0xD4,(byte)0xBB,(byte)0x1B, +(byte)0xDB,(byte)0x7F,(byte)0x14,(byte)0x47,(byte)0xE6,(byte)0xCC,(byte)0x25,(byte)0x4B, +(byte)0x33,(byte)0x20,(byte)0x51,(byte)0x51,(byte)0x2B,(byte)0xD7,(byte)0xAF,(byte)0x42, +(byte)0x6F,(byte)0xB8,(byte)0xF4,(byte)0x01,(byte)0x37,(byte)0x8C,(byte)0xD2,(byte)0xBF, +(byte)0x59,(byte)0x83,(byte)0xCA,(byte)0x01,(byte)0xC6,(byte)0x4B,(byte)0x92,(byte)0xEC, +(byte)0xF0,(byte)0x32,(byte)0xEA,(byte)0x15,(byte)0xD1,(byte)0x72,(byte)0x1D,(byte)0x03, +(byte)0xF4,(byte)0x82,(byte)0xD7,(byte)0xCE,(byte)0x6E,(byte)0x74,(byte)0xFE,(byte)0xF6, +(byte)0xD5,(byte)0x5E,(byte)0x70,(byte)0x2F,(byte)0x46,(byte)0x98,(byte)0x0C,(byte)0x82, +(byte)0xB5,(byte)0xA8,(byte)0x40,(byte)0x31,(byte)0x90,(byte)0x0B,(byte)0x1C,(byte)0x9E, +(byte)0x59,(byte)0xE7,(byte)0xC9,(byte)0x7F,(byte)0xBE,(byte)0xC7,(byte)0xE8,(byte)0xF3, +(byte)0x23,(byte)0xA9,(byte)0x7A,(byte)0x7E,(byte)0x36,(byte)0xCC,(byte)0x88,(byte)0xBE, +(byte)0x0F,(byte)0x1D,(byte)0x45,(byte)0xB7,(byte)0xFF,(byte)0x58,(byte)0x5A,(byte)0xC5, +(byte)0x4B,(byte)0xD4,(byte)0x07,(byte)0xB2,(byte)0x2B,(byte)0x41,(byte)0x54,(byte)0xAA, +(byte)0xCC,(byte)0x8F,(byte)0x6D,(byte)0x7E,(byte)0xBF,(byte)0x48,(byte)0xE1,(byte)0xD8, +(byte)0x14,(byte)0xCC,(byte)0x5E,(byte)0xD2,(byte)0x0F,(byte)0x80,(byte)0x37,(byte)0xE0, +(byte)0xA7,(byte)0x97,(byte)0x15,(byte)0xEE,(byte)0xF2,(byte)0x9B,(byte)0xE3,(byte)0x28, +(byte)0x06,(byte)0xA1,(byte)0xD5,(byte)0x8B,(byte)0xB7,(byte)0xC5,(byte)0xDA,(byte)0x76, +(byte)0xF5,(byte)0x50,(byte)0xAA,(byte)0x3D,(byte)0x8A,(byte)0x1F,(byte)0xBF,(byte)0xF0, +(byte)0xEB,(byte)0x19,(byte)0xCC,(byte)0xB1,(byte)0xA3,(byte)0x13,(byte)0xD5,(byte)0x5C, +(byte)0xDA,(byte)0x56,(byte)0xC9,(byte)0xEC,(byte)0x2E,(byte)0xF2,(byte)0x96,(byte)0x32, +(byte)0x38,(byte)0x7F,(byte)0xE8,(byte)0xD7,(byte)0x6E,(byte)0x3C,(byte)0x04,(byte)0x68, +(byte)0x04,(byte)0x3E,(byte)0x8F,(byte)0x66,(byte)0x3F,(byte)0x48,(byte)0x60,(byte)0xEE, +(byte)0x12,(byte)0xBF,(byte)0x2D,(byte)0x5B,(byte)0x0B,(byte)0x74,(byte)0x74,(byte)0xD6, +(byte)0xE6,(byte)0x94,(byte)0xF9,(byte)0x1E,(byte)0x6D,(byte)0xCC,(byte)0x40,(byte)0x24, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, +}; + + @Override + byte[] G(){ return g; } + @Override + byte[] P(){ return p; } + @Override + String sha_name(){ return "sha-512"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG18.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG18.java new file mode 100644 index 00000000..8f101ca0 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHG18.java @@ -0,0 +1,173 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHG18 extends DHGN{ + + static final byte[] g={ 2 }; + static final byte[] p={ +(byte)0x00, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF, +(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34, +(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1, +(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74, +(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22, +(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD, +(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B, +(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37, +(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45, +(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6, +(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B, +(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED, +(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5, +(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6, +(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D, +(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05, +(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A, +(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F, +(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96, +(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB, +(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D, +(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04, +(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C, +(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B, +(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03, +(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F, +(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9, +(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18, +(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5, +(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10, +(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D, +(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33, +(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64, +(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A, +(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D, +(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7, +(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7, +(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D, +(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B, +(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64, +(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64, +(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C, +(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C, +(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2, +(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31, +(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E, +(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01, +(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7, +(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26, +(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C, +(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA, +(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8, +(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9, +(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6, +(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D, +(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2, +(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED, +(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF, +(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C, +(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9, +(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1, +(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F, +(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x02,(byte)0x84,(byte)0x92, +(byte)0x36,(byte)0xC3,(byte)0xFA,(byte)0xB4,(byte)0xD2,(byte)0x7C,(byte)0x70,(byte)0x26, +(byte)0xC1,(byte)0xD4,(byte)0xDC,(byte)0xB2,(byte)0x60,(byte)0x26,(byte)0x46,(byte)0xDE, +(byte)0xC9,(byte)0x75,(byte)0x1E,(byte)0x76,(byte)0x3D,(byte)0xBA,(byte)0x37,(byte)0xBD, +(byte)0xF8,(byte)0xFF,(byte)0x94,(byte)0x06,(byte)0xAD,(byte)0x9E,(byte)0x53,(byte)0x0E, +(byte)0xE5,(byte)0xDB,(byte)0x38,(byte)0x2F,(byte)0x41,(byte)0x30,(byte)0x01,(byte)0xAE, +(byte)0xB0,(byte)0x6A,(byte)0x53,(byte)0xED,(byte)0x90,(byte)0x27,(byte)0xD8,(byte)0x31, +(byte)0x17,(byte)0x97,(byte)0x27,(byte)0xB0,(byte)0x86,(byte)0x5A,(byte)0x89,(byte)0x18, +(byte)0xDA,(byte)0x3E,(byte)0xDB,(byte)0xEB,(byte)0xCF,(byte)0x9B,(byte)0x14,(byte)0xED, +(byte)0x44,(byte)0xCE,(byte)0x6C,(byte)0xBA,(byte)0xCE,(byte)0xD4,(byte)0xBB,(byte)0x1B, +(byte)0xDB,(byte)0x7F,(byte)0x14,(byte)0x47,(byte)0xE6,(byte)0xCC,(byte)0x25,(byte)0x4B, +(byte)0x33,(byte)0x20,(byte)0x51,(byte)0x51,(byte)0x2B,(byte)0xD7,(byte)0xAF,(byte)0x42, +(byte)0x6F,(byte)0xB8,(byte)0xF4,(byte)0x01,(byte)0x37,(byte)0x8C,(byte)0xD2,(byte)0xBF, +(byte)0x59,(byte)0x83,(byte)0xCA,(byte)0x01,(byte)0xC6,(byte)0x4B,(byte)0x92,(byte)0xEC, +(byte)0xF0,(byte)0x32,(byte)0xEA,(byte)0x15,(byte)0xD1,(byte)0x72,(byte)0x1D,(byte)0x03, +(byte)0xF4,(byte)0x82,(byte)0xD7,(byte)0xCE,(byte)0x6E,(byte)0x74,(byte)0xFE,(byte)0xF6, +(byte)0xD5,(byte)0x5E,(byte)0x70,(byte)0x2F,(byte)0x46,(byte)0x98,(byte)0x0C,(byte)0x82, +(byte)0xB5,(byte)0xA8,(byte)0x40,(byte)0x31,(byte)0x90,(byte)0x0B,(byte)0x1C,(byte)0x9E, +(byte)0x59,(byte)0xE7,(byte)0xC9,(byte)0x7F,(byte)0xBE,(byte)0xC7,(byte)0xE8,(byte)0xF3, +(byte)0x23,(byte)0xA9,(byte)0x7A,(byte)0x7E,(byte)0x36,(byte)0xCC,(byte)0x88,(byte)0xBE, +(byte)0x0F,(byte)0x1D,(byte)0x45,(byte)0xB7,(byte)0xFF,(byte)0x58,(byte)0x5A,(byte)0xC5, +(byte)0x4B,(byte)0xD4,(byte)0x07,(byte)0xB2,(byte)0x2B,(byte)0x41,(byte)0x54,(byte)0xAA, +(byte)0xCC,(byte)0x8F,(byte)0x6D,(byte)0x7E,(byte)0xBF,(byte)0x48,(byte)0xE1,(byte)0xD8, +(byte)0x14,(byte)0xCC,(byte)0x5E,(byte)0xD2,(byte)0x0F,(byte)0x80,(byte)0x37,(byte)0xE0, +(byte)0xA7,(byte)0x97,(byte)0x15,(byte)0xEE,(byte)0xF2,(byte)0x9B,(byte)0xE3,(byte)0x28, +(byte)0x06,(byte)0xA1,(byte)0xD5,(byte)0x8B,(byte)0xB7,(byte)0xC5,(byte)0xDA,(byte)0x76, +(byte)0xF5,(byte)0x50,(byte)0xAA,(byte)0x3D,(byte)0x8A,(byte)0x1F,(byte)0xBF,(byte)0xF0, +(byte)0xEB,(byte)0x19,(byte)0xCC,(byte)0xB1,(byte)0xA3,(byte)0x13,(byte)0xD5,(byte)0x5C, +(byte)0xDA,(byte)0x56,(byte)0xC9,(byte)0xEC,(byte)0x2E,(byte)0xF2,(byte)0x96,(byte)0x32, +(byte)0x38,(byte)0x7F,(byte)0xE8,(byte)0xD7,(byte)0x6E,(byte)0x3C,(byte)0x04,(byte)0x68, +(byte)0x04,(byte)0x3E,(byte)0x8F,(byte)0x66,(byte)0x3F,(byte)0x48,(byte)0x60,(byte)0xEE, +(byte)0x12,(byte)0xBF,(byte)0x2D,(byte)0x5B,(byte)0x0B,(byte)0x74,(byte)0x74,(byte)0xD6, +(byte)0xE6,(byte)0x94,(byte)0xF9,(byte)0x1E,(byte)0x6D,(byte)0xBE,(byte)0x11,(byte)0x59, +(byte)0x74,(byte)0xA3,(byte)0x92,(byte)0x6F,(byte)0x12,(byte)0xFE,(byte)0xE5,(byte)0xE4, +(byte)0x38,(byte)0x77,(byte)0x7C,(byte)0xB6,(byte)0xA9,(byte)0x32,(byte)0xDF,(byte)0x8C, +(byte)0xD8,(byte)0xBE,(byte)0xC4,(byte)0xD0,(byte)0x73,(byte)0xB9,(byte)0x31,(byte)0xBA, +(byte)0x3B,(byte)0xC8,(byte)0x32,(byte)0xB6,(byte)0x8D,(byte)0x9D,(byte)0xD3,(byte)0x00, +(byte)0x74,(byte)0x1F,(byte)0xA7,(byte)0xBF,(byte)0x8A,(byte)0xFC,(byte)0x47,(byte)0xED, +(byte)0x25,(byte)0x76,(byte)0xF6,(byte)0x93,(byte)0x6B,(byte)0xA4,(byte)0x24,(byte)0x66, +(byte)0x3A,(byte)0xAB,(byte)0x63,(byte)0x9C,(byte)0x5A,(byte)0xE4,(byte)0xF5,(byte)0x68, +(byte)0x34,(byte)0x23,(byte)0xB4,(byte)0x74,(byte)0x2B,(byte)0xF1,(byte)0xC9,(byte)0x78, +(byte)0x23,(byte)0x8F,(byte)0x16,(byte)0xCB,(byte)0xE3,(byte)0x9D,(byte)0x65,(byte)0x2D, +(byte)0xE3,(byte)0xFD,(byte)0xB8,(byte)0xBE,(byte)0xFC,(byte)0x84,(byte)0x8A,(byte)0xD9, +(byte)0x22,(byte)0x22,(byte)0x2E,(byte)0x04,(byte)0xA4,(byte)0x03,(byte)0x7C,(byte)0x07, +(byte)0x13,(byte)0xEB,(byte)0x57,(byte)0xA8,(byte)0x1A,(byte)0x23,(byte)0xF0,(byte)0xC7, +(byte)0x34,(byte)0x73,(byte)0xFC,(byte)0x64,(byte)0x6C,(byte)0xEA,(byte)0x30,(byte)0x6B, +(byte)0x4B,(byte)0xCB,(byte)0xC8,(byte)0x86,(byte)0x2F,(byte)0x83,(byte)0x85,(byte)0xDD, +(byte)0xFA,(byte)0x9D,(byte)0x4B,(byte)0x7F,(byte)0xA2,(byte)0xC0,(byte)0x87,(byte)0xE8, +(byte)0x79,(byte)0x68,(byte)0x33,(byte)0x03,(byte)0xED,(byte)0x5B,(byte)0xDD,(byte)0x3A, +(byte)0x06,(byte)0x2B,(byte)0x3C,(byte)0xF5,(byte)0xB3,(byte)0xA2,(byte)0x78,(byte)0xA6, +(byte)0x6D,(byte)0x2A,(byte)0x13,(byte)0xF8,(byte)0x3F,(byte)0x44,(byte)0xF8,(byte)0x2D, +(byte)0xDF,(byte)0x31,(byte)0x0E,(byte)0xE0,(byte)0x74,(byte)0xAB,(byte)0x6A,(byte)0x36, +(byte)0x45,(byte)0x97,(byte)0xE8,(byte)0x99,(byte)0xA0,(byte)0x25,(byte)0x5D,(byte)0xC1, +(byte)0x64,(byte)0xF3,(byte)0x1C,(byte)0xC5,(byte)0x08,(byte)0x46,(byte)0x85,(byte)0x1D, +(byte)0xF9,(byte)0xAB,(byte)0x48,(byte)0x19,(byte)0x5D,(byte)0xED,(byte)0x7E,(byte)0xA1, +(byte)0xB1,(byte)0xD5,(byte)0x10,(byte)0xBD,(byte)0x7E,(byte)0xE7,(byte)0x4D,(byte)0x73, +(byte)0xFA,(byte)0xF3,(byte)0x6B,(byte)0xC3,(byte)0x1E,(byte)0xCF,(byte)0xA2,(byte)0x68, +(byte)0x35,(byte)0x90,(byte)0x46,(byte)0xF4,(byte)0xEB,(byte)0x87,(byte)0x9F,(byte)0x92, +(byte)0x40,(byte)0x09,(byte)0x43,(byte)0x8B,(byte)0x48,(byte)0x1C,(byte)0x6C,(byte)0xD7, +(byte)0x88,(byte)0x9A,(byte)0x00,(byte)0x2E,(byte)0xD5,(byte)0xEE,(byte)0x38,(byte)0x2B, +(byte)0xC9,(byte)0x19,(byte)0x0D,(byte)0xA6,(byte)0xFC,(byte)0x02,(byte)0x6E,(byte)0x47, +(byte)0x95,(byte)0x58,(byte)0xE4,(byte)0x47,(byte)0x56,(byte)0x77,(byte)0xE9,(byte)0xAA, +(byte)0x9E,(byte)0x30,(byte)0x50,(byte)0xE2,(byte)0x76,(byte)0x56,(byte)0x94,(byte)0xDF, +(byte)0xC8,(byte)0x1F,(byte)0x56,(byte)0xE8,(byte)0x80,(byte)0xB9,(byte)0x6E,(byte)0x71, +(byte)0x60,(byte)0xC9,(byte)0x80,(byte)0xDD,(byte)0x98,(byte)0xED,(byte)0xD3,(byte)0xDF, +(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF +}; + + @Override + byte[] G(){ return g; } + @Override + byte[] P(){ return p; } + @Override + String sha_name(){ return "sha-512"; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX.java index f975e5f1..774ca6ca 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX.java @@ -29,16 +29,16 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class DHGEX extends KeyExchange{ +abstract class DHGEX extends KeyExchange{ private static final int SSH_MSG_KEX_DH_GEX_GROUP= 31; private static final int SSH_MSG_KEX_DH_GEX_INIT= 32; private static final int SSH_MSG_KEX_DH_GEX_REPLY= 33; private static final int SSH_MSG_KEX_DH_GEX_REQUEST= 34; - static int min=1024; - static int preferred=1024; - int max=1024; + int min; + int preferred; + int max; private int state; @@ -56,19 +56,19 @@ public class DHGEX extends KeyExchange{ private byte[] g; private byte[] e; - protected String hash="sha-1"; + protected String hash; + @Override public void init(Session session, - byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ - this.session=session; + byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ 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(hash)); - sha=(HASH)(c.newInstance()); + Class c=Class.forName(session.getConfig(hash)).asSubclass(HASH.class); + sha=c.getDeclaredConstructor().newInstance(); sha.init(); } catch(Exception e){ @@ -79,11 +79,14 @@ public class DHGEX extends KeyExchange{ packet=new Packet(buf); try{ - Class c=Class.forName(session.getConfig("dh")); - // Since JDK8, SunJCE has lifted the keysize restrictions - // from 1024 to 2048 for DH. - preferred = max = check2048(c, max); - dh=(com.jcraft.jsch.DH)(c.newInstance()); + Class c=Class.forName(session.getConfig("dh")).asSubclass(DH.class); + min=Integer.parseInt(session.getConfig("dhgex_min")); + max=Integer.parseInt(session.getConfig("dhgex_max")); + preferred=Integer.parseInt(session.getConfig("dhgex_preferred")); + if(checkInvalidSize(min) || checkInvalidSize(max) || checkInvalidSize(preferred) || preferred < min || max < preferred){ + throw new JSchException("Invalid DHGEX sizes: min=" + min + " max=" + max + " preferred=" + preferred); + } + dh=c.getDeclaredConstructor().newInstance(); dh.init(); } catch(Exception e){ @@ -97,16 +100,17 @@ public class DHGEX extends KeyExchange{ buf.putInt(max); session.write(packet); - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent"); - JSch.getLogger().log(Logger.INFO, + session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_DH_GEX_GROUP"); } state=SSH_MSG_KEX_DH_GEX_GROUP; } + @Override public boolean next(Buffer _buf) throws Exception{ int i,j; switch(state){ @@ -118,8 +122,8 @@ public class DHGEX extends KeyExchange{ _buf.getByte(); j=_buf.getByte(); if(j!=SSH_MSG_KEX_DH_GEX_GROUP){ - System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j); - return false; + System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j); + return false; } p=_buf.getMPInt(); @@ -139,10 +143,10 @@ public class DHGEX extends KeyExchange{ buf.putMPInt(e); session.write(packet); - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, "SSH_MSG_KEX_DH_GEX_INIT sent"); - JSch.getLogger().log(Logger.INFO, + session.getLogger().log(Logger.INFO, "expecting SSH_MSG_KEX_DH_GEX_REPLY"); } @@ -160,8 +164,8 @@ public class DHGEX extends KeyExchange{ j=_buf.getByte(); j=_buf.getByte(); if(j!=SSH_MSG_KEX_DH_GEX_REPLY){ - System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j); - return false; + System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j); + return false; } K_S=_buf.getString(); @@ -212,7 +216,7 @@ public class DHGEX extends KeyExchange{ i=0; j=0; j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); + ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); String alg=Util.byte2str(K_S, i, j); i+=j; @@ -224,22 +228,10 @@ public class DHGEX extends KeyExchange{ return false; } + @Override public int getState(){return state; } - protected int check2048(Class c, int _max) throws Exception { - DH dh=(com.jcraft.jsch.DH)(c.newInstance()); - dh.init(); - byte[] foo = new byte[257]; - foo[1]=(byte)0xdd; - foo[256]=0x73; - dh.setP(foo); - byte[] bar = {(byte)0x02}; - dh.setG(bar); - try { - dh.getE(); - _max=2048; - } - catch(Exception e){ } - return _max; + static boolean checkInvalidSize(int size) { + return (size < 1024 || size > 8192 || size % 1024 != 0); } } 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/DHGEX1.java similarity index 89% rename from src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jgss/GSSContextKrb5.java rename to src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX1.java index c3b250d4..cb05879b 100644 --- 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/DHGEX1.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -Copyright (c) 2006-2016 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2002-2018 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: @@ -27,11 +27,10 @@ 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; - - -public class GSSContextKrb5 { +package com.jcraft.jsch; +class DHGEX1 extends DHGEX { + DHGEX1(){ + hash="sha-1"; + } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX224.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX224.java new file mode 100644 index 00000000..f2dc989c --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX224.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHGEX224 extends DHGEX { + DHGEX224(){ + hash="sha-224"; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX256.java index 6627aaa1..4c6be171 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX256.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX256.java @@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class DHGEX256 extends DHGEX { +class DHGEX256 extends DHGEX { DHGEX256(){ hash="sha-256"; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX384.java new file mode 100644 index 00000000..67c5b585 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX384.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHGEX384 extends DHGEX { + DHGEX384(){ + hash="sha-384"; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX512.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX512.java new file mode 100644 index 00000000..830a0bce --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGEX512.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +class DHGEX512 extends DHGEX { + DHGEX512(){ + hash="sha-512"; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGN.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGN.java new file mode 100644 index 00000000..fcaed930 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHGN.java @@ -0,0 +1,184 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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; + +abstract class DHGN extends KeyExchange{ + + private static final int SSH_MSG_KEXDH_INIT= 30; + private static final int SSH_MSG_KEXDH_REPLY= 31; + + private int state; + + DH dh; + + byte[] V_S; + byte[] V_C; + byte[] I_S; + byte[] I_C; + + byte[] e; + + private Buffer buf; + private Packet packet; + + abstract byte[] G(); + abstract byte[] P(); + abstract String sha_name(); + + @Override + public void init(Session session, + byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ + 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())).asSubclass(HASH.class); + sha=c.getDeclaredConstructor().newInstance(); + sha.init(); + } + catch(Exception e){ + System.err.println(e); + } + + buf=new Buffer(); + packet=new Packet(buf); + + try{ + Class c=Class.forName(session.getConfig("dh")).asSubclass(DH.class); + dh=c.getDeclaredConstructor().newInstance(); + dh.init(); + } + catch(Exception e){ + //System.err.println(e); + throw e; + } + + dh.setP(P()); + dh.setG(G()); + // The client responds with: + // byte SSH_MSG_KEXDH_INIT(30) + // mpint e <- g^x mod p + // x is a random number (1 < x < (p-1)/2) + + e=dh.getE(); + packet.reset(); + buf.putByte((byte)SSH_MSG_KEXDH_INIT); + buf.putMPInt(e); + + if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-( + return; + } + + session.write(packet); + + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, + "SSH_MSG_KEXDH_INIT sent"); + session.getLogger().log(Logger.INFO, + "expecting SSH_MSG_KEXDH_REPLY"); + } + + state=SSH_MSG_KEXDH_REPLY; + } + + @Override + public boolean next(Buffer _buf) throws Exception{ + int i,j; + + switch(state){ + case SSH_MSG_KEXDH_REPLY: + // The server responds with: + // byte SSH_MSG_KEXDH_REPLY(31) + // string server public host key and certificates (K_S) + // mpint f + // string signature of H + j=_buf.getInt(); + j=_buf.getByte(); + j=_buf.getByte(); + if(j!=31){ + System.err.println("type: must be 31 "+j); + return false; + } + + K_S=_buf.getString(); + + byte[] f=_buf.getMPInt(); + byte[] sig_of_H=_buf.getString(); + + dh.setF(f); + + dh.checkRange(); + + K=normalize(dh.getK()); + + //The hash H is computed as the HASH hash of the concatenation of the + //following: + // string V_C, the client's version string (CR and NL excluded) + // string V_S, the server's version string (CR and NL excluded) + // string I_C, the payload of the client's SSH_MSG_KEXINIT + // string I_S, the payload of the server's SSH_MSG_KEXINIT + // string K_S, the host key + // mpint e, exchange value sent by the client + // mpint f, exchange value sent by the server + // mpint K, the shared secret + // This value is called the exchange hash, and it is used to authenti- + // cate the key exchange. + buf.reset(); + buf.putString(V_C); buf.putString(V_S); + buf.putString(I_C); buf.putString(I_S); + buf.putString(K_S); + buf.putMPInt(e); buf.putMPInt(f); + buf.putMPInt(K); + byte[] foo=new byte[buf.getLength()]; + buf.getByte(foo); + sha.update(foo, 0, foo.length); + H=sha.digest(); + //System.err.print("H -> "); //dump(H, 0, H.length); + + i=0; + j=0; + j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| + ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); + String alg=Util.byte2str(K_S, i, j); + i+=j; + + boolean result = verify(alg, K_S, i, sig_of_H); + + state=STATE_END; + return result; + } + return false; + } + + @Override + public int getState(){return state; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHXEC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHXEC.java new file mode 100644 index 00000000..eb6bd58a --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/DHXEC.java @@ -0,0 +1,200 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2015-2018 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; + +abstract class DHXEC 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 XDH xdh; + + protected String sha_name; + protected String curve_name; + protected int key_len; + + @Override + public void init(Session session, + byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{ + 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)).asSubclass(HASH.class); + sha=c.getDeclaredConstructor().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("xdh")).asSubclass(XDH.class); + xdh=c.getDeclaredConstructor().newInstance(); + xdh.init(curve_name, key_len); + + Q_C = xdh.getQ(); + buf.putString(Q_C); + } + catch(Exception | NoClassDefFoundError e){ + throw new JSchException(e.toString(), e); + } + + if(V_S==null){ // This is a really ugly hack for Session.checkKexes ;-( + return; + } + + session.write(packet); + + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, + "SSH_MSG_KEX_ECDH_INIT sent"); + session.getLogger().log(Logger.INFO, + "expecting SSH_MSG_KEX_ECDH_REPLY"); + } + + state=SSH_MSG_KEX_ECDH_REPLY; + } + + @Override + 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!=SSH_MSG_KEX_ECDH_REPLY){ + System.err.println("type: must be SSH_MSG_KEX_ECDH_REPLY "+j); + return false; + } + + K_S=_buf.getString(); + + byte[] Q_S=_buf.getString(); + + // 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(!xdh.validate(Q_S)){ + return false; + } + + K = xdh.getSecret(Q_S); + 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. + // RFC 8731, + // 3.1. Shared Secret Encoding + // The shared secret, K, is defined in [RFC4253] and [RFC5656] as an + // integer encoded as a multiple precision integer (mpint). + // Curve25519/448 outputs a binary string X, which is the 32- or 56-byte + // point obtained by scalar multiplication of the other side's public + // key and the local private key scalar. The 32 or 56 bytes of X are + // converted into K by interpreting the octets as an unsigned fixed- + // length integer encoded in network byte order. + // + // The mpint K is then encoded using the process described in Section 5 + // of [RFC4251], and the resulting bytes are fed as described in + // [RFC4253] to the key exchange method's hash function to generate + // encryption keys. + 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; + } + + @Override + public int getState(){return state; } +} 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 bea8aa48..4a5ae817 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 @@ -34,4 +34,5 @@ public interface HASH{ int getBlockSize(); void update(byte[] foo, int start, int len) throws Exception; byte[] digest() throws Exception; + default String name() {return "";} } 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 c90a6fd8..c3d5ccd2 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 @@ -36,16 +36,20 @@ public class HostKey{ Util.str2byte("ssh-rsa"), Util.str2byte("ecdsa-sha2-nistp256"), Util.str2byte("ecdsa-sha2-nistp384"), - Util.str2byte("ecdsa-sha2-nistp521") + Util.str2byte("ecdsa-sha2-nistp521"), + Util.str2byte("ssh-ed25519"), + Util.str2byte("ssh-ed448") }; - protected static final int GUESS=0; + public static final int UNKNOWN=-1; + public static final int GUESS=0; public static final int SSHDSS=1; public static final int SSHRSA=2; public static final int ECDSA256=3; public static final int ECDSA384=4; public static final int ECDSA521=5; - static final int UNKNOWN=6; + public static final int ED25519=6; + public static final int ED448=7; protected String marker; protected String host; @@ -69,6 +73,8 @@ 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]=='e' && key[10]=='2'){ this.type=ED25519; } + else if(key[8]=='e' && key[10]=='4'){ this.type=ED448; } 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; } @@ -85,6 +91,8 @@ public class HostKey{ public String getType(){ if(type==SSHDSS || type==SSHRSA || + type==ED25519 || + type==ED448 || type==ECDSA256 || type==ECDSA384 || type==ECDSA521){ @@ -101,16 +109,17 @@ public class HostKey{ return UNKNOWN; } public String getKey(){ - return Util.byte2str(Util.toBase64(key, 0, key.length)); + return Util.byte2str(Util.toBase64(key, 0, key.length, true)); } public String getFingerPrint(JSch jsch){ HASH hash=null; try{ - Class c=Class.forName(jsch.getConfig("md5")); - hash=(HASH)(c.newInstance()); + String _c=JSch.getConfig("FingerprintHash").toLowerCase(); + Class c=Class.forName(JSch.getConfig(_c)).asSubclass(HASH.class); + hash=c.getDeclaredConstructor().newInstance(); } catch(Exception e){ System.err.println("getFingerPrint: "+e); } - return Util.getFingerPrint(hash, key); + return Util.getFingerPrint(hash, key, false, true); } public String getComment(){ return comment; } public String getMarker(){ return marker; } @@ -132,7 +141,7 @@ public class HostKey{ return hosts.regionMatches(true, i, _host, 0, hostlen); } if(hostlen==(j-i)){ - if(hosts.regionMatches(true, i, _host, 0, hostlen)) return true; + if(hosts.regionMatches(true, i, _host, 0, hostlen)) return true; } i=j+1; } 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 0be3bf0f..8e63b46f 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 @@ -30,8 +30,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; import java.io.*; +import java.net.SocketException; -public class IO{ +class IO{ InputStream in; OutputStream out; OutputStream out_ext; @@ -56,7 +57,7 @@ public class IO{ setInputStream(in); } - public void put(Packet p) throws IOException, java.net.SocketException { + void put(Packet p) throws IOException, SocketException { out.write(p.buffer.buffer, 0, p.buffer.index); out.flush(); } @@ -81,7 +82,7 @@ public class IO{ do{ int completed = in.read(array, begin, length); if(completed<0){ - throw new IOException("End of IO Stream Read"); + throw new IOException("End of IO Stream Read"); } begin+=completed; length-=completed; @@ -97,7 +98,7 @@ public class IO{ catch(Exception ee){} } - public void close(){ + void close(){ try{ if(in!=null && !in_dontclose) in.close(); in=null; @@ -114,7 +115,7 @@ public class IO{ } /* - public void finalize() throws Throwable{ + void finalize() throws Throwable{ try{ if(in!=null) in.close(); } 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 4b2c1aa5..f42ad2ee 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 @@ -34,7 +34,7 @@ public interface Identity{ /** * Decrypts this identity with the specified pass-phrase. * @param passphrase the pass-phrase for this identity. - * @return true if the decryption is succeeded + * @return true if the decryption is succeeded * or this identity is not cyphered. */ public boolean setPassphrase(byte[] passphrase) throws JSchException; @@ -47,15 +47,49 @@ public interface Identity{ /** * Signs on data with this identity, and returns the result. + *

+ * IMPORTANT NOTE: + *
+ * The {@link #getSignature(byte[], String)} method should be overridden + * to ensure {@code ssh-rsa} type public keys function with the + * {@code rsa-sha2-256} or {@code rsa-sha2-512} signature algorithms. + *

* @param data data to be signed * @return the signature + * @see #getSignature(byte[], String) */ public byte[] getSignature(byte[] data); /** - * @deprecated The decryption should be done automatically in #setPassphase(byte[] passphrase) - * @see #setPassphrase(byte[] passphrase) + * Signs on data with this identity, and returns the result. + *

+ * IMPORTANT NOTE: + *
+ * The default implementation of this method simply calls + * {@link #getSignature(byte[])}, which will fail with {@code ssh-rsa} + * type public keys when utilized with the {@code rsa-sha2-256} or + * {@code rsa-sha2-512} signature algorithms: + *
+ * it exists only to maintain backwards compatibility of this interface. + *

+ *

+ * This default method should be overridden by implementations to + * ensure the {@code rsa-sha2-256} and {@code rsa-sha2-512} signature + * algorithms function correctly. + *

+ * @param data data to be signed + * @param alg signature algorithm to use + * @return the signature + * @since 0.1.57 + * @see #getSignature(byte[]) */ + public default byte[] getSignature(byte[] data, String alg) {return getSignature(data);} + + /** + * @deprecated The decryption should be done automatically in {@link #setPassphrase(byte[])} + * @see #setPassphrase(byte[]) + */ + @Deprecated public boolean decrypt(); /** @@ -71,8 +105,8 @@ public interface Identity{ public String getName(); /** - * Returns true if this identity is cyphered. - * @return true if this identity is cyphered. + * Returns true if this identity is cyphered. + * @return true if this identity is cyphered. */ public boolean isEncrypted(); 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 fa41225e..b46933b5 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 @@ -56,9 +56,10 @@ class IdentityFile implements Identity{ /** * Decrypts this identity with the specified pass-phrase. * @param passphrase the pass-phrase for this identity. - * @return true if the decryption is succeeded + * @return true if the decryption is succeeded * or this identity is not cyphered. */ + @Override public boolean setPassphrase(byte[] passphrase) throws JSchException{ return kpair.decrypt(passphrase); } @@ -67,6 +68,7 @@ class IdentityFile implements Identity{ * Returns the public-key blob. * @return the public-key blob */ + @Override public byte[] getPublicKeyBlob(){ return kpair.getPublicKeyBlob(); } @@ -76,14 +78,28 @@ class IdentityFile implements Identity{ * @param data data to be signed * @return the signature */ + @Override public byte[] getSignature(byte[] data){ return kpair.getSignature(data); } + /** + * Signs on data with this identity, and returns the result. + * @param data data to be signed + * @param alg signature algorithm to use + * @return the signature + */ + @Override + public byte[] getSignature(byte[] data, String alg){ + return kpair.getSignature(data, alg); + } + /** * @deprecated This method should not be invoked. * @see #setPassphrase(byte[] passphrase) */ + @Override + @Deprecated public boolean decrypt(){ throw new RuntimeException("not implemented"); } @@ -92,28 +108,26 @@ class IdentityFile implements Identity{ * Returns the name of the key algorithm. * @return "ssh-rsa" or "ssh-dss" */ + @Override public String getAlgName(){ byte[] name = kpair.getKeyTypeName(); - try { - return new String(name, "UTF-8"); - } - catch (UnsupportedEncodingException e){ - return new String(name); - } + return Util.byte2str(name); } /** * Returns the name of this identity. * It will be useful to identify this object in the {@link IdentityRepository}. */ + @Override public String getName(){ return identity; } /** - * Returns true if this identity is cyphered. - * @return true if this identity is cyphered. + * Returns true if this identity is cyphered. + * @return true if this identity is cyphered. */ + @Override public boolean isEncrypted(){ return kpair.isEncrypted(); } @@ -121,6 +135,7 @@ class IdentityFile implements Identity{ /** * Disposes internally allocated data, like byte array for the private key. */ + @Override public void clear(){ kpair.dispose(); kpair = null; 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 d4f3f228..895b0226 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 @@ -37,79 +37,8 @@ public interface IdentityRepository { public static final int RUNNING=2; public String getName(); public int getStatus(); - public Vector getIdentities(); + public Vector getIdentities(); public boolean add(byte[] identity); public boolean remove(byte[] blob); public void removeAll(); - - /** - * JSch will accept ciphered keys, but some implementations of - * IdentityRepository can not. For example, IdentityRepository for - * ssh-agent and pageant only accept plain keys. The following class has - * been introduced to cache ciphered keys for them, and pass them - * whenever they are de-ciphered. - */ - static class Wrapper implements IdentityRepository { - private IdentityRepository ir; - private Vector cache = new Vector(); - private boolean keep_in_cache = false; - Wrapper(IdentityRepository ir){ - this(ir, false); - } - Wrapper(IdentityRepository ir, boolean keep_in_cache){ - this.ir = ir; - this.keep_in_cache = keep_in_cache; - } - public String getName() { - return ir.getName(); - } - public int getStatus() { - return ir.getStatus(); - } - public boolean add(byte[] identity) { - return ir.add(identity); - } - public boolean remove(byte[] blob) { - return ir.remove(blob); - } - public void removeAll() { - cache.removeAllElements(); - ir.removeAll(); - } - public Vector getIdentities() { - Vector result = new Vector(); - for(int i = 0; i< cache.size(); i++){ - Identity identity = (Identity)(cache.elementAt(i)); - result.add(identity); - } - Vector tmp = ir.getIdentities(); - for(int i = 0; i< tmp.size(); i++){ - result.add(tmp.elementAt(i)); - } - return result; - } - void add(Identity identity) { - if(!keep_in_cache && - !identity.isEncrypted() && (identity instanceof IdentityFile)) { - try { - ir.add(((IdentityFile)identity).getKeyPair().forSSHAgent()); - } - catch(JSchException e){ - // an exception will not be thrown. - } - } - else - cache.addElement(identity); - } - void check() { - if(cache.size() > 0){ - Object[] identities = cache.toArray(); - for(int i = 0; i < identities.length; i++){ - Identity identity = (Identity)(identities[i]); - cache.removeElement(identity); - add(identity); - } - } - } - } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java new file mode 100644 index 00000000..8ce08b4b --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/IdentityRepositoryWrapper.java @@ -0,0 +1,109 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2012-2018 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; + +/** + * JSch will accept ciphered keys, but some implementations of + * IdentityRepository can not. For example, IdentityRepository for + * ssh-agent and pageant only accept plain keys. The following class has + * been introduced to cache ciphered keys for them, and pass them + * whenever they are de-ciphered. + */ +class IdentityRepositoryWrapper implements IdentityRepository { + private IdentityRepository ir; + private Vector cache = new Vector<>(); + private boolean keep_in_cache = false; + IdentityRepositoryWrapper(IdentityRepository ir){ + this(ir, false); + } + IdentityRepositoryWrapper(IdentityRepository ir, boolean keep_in_cache){ + this.ir = ir; + this.keep_in_cache = keep_in_cache; + } + @Override + public String getName() { + return ir.getName(); + } + @Override + public int getStatus() { + return ir.getStatus(); + } + @Override + public boolean add(byte[] identity) { + return ir.add(identity); + } + @Override + public boolean remove(byte[] blob) { + return ir.remove(blob); + } + @Override + public void removeAll() { + cache.removeAllElements(); + ir.removeAll(); + } + @Override + public Vector getIdentities() { + Vector result = new Vector<>(); + for(int i = 0; i< cache.size(); i++){ + Identity identity = cache.elementAt(i); + result.add(identity); + } + Vector tmp = ir.getIdentities(); + for(int i = 0; i< tmp.size(); i++){ + result.add(tmp.elementAt(i)); + } + return result; + } + void add(Identity identity) { + if(!keep_in_cache && + !identity.isEncrypted() && (identity instanceof IdentityFile)) { + try { + ir.add(((IdentityFile)identity).getKeyPair().forSSHAgent()); + } + catch(JSchException e){ + // an exception will not be thrown. + } + } + else + cache.addElement(identity); + } + void check() { + if(cache.size() > 0){ + Object[] identities = cache.toArray(); + for(int i = 0; i < identities.length; i++){ + Identity identity = (Identity)(identities[i]); + cache.removeElement(identity); + add(identity); + } + } + } +} 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 b93c2885..f053e233 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 @@ -30,42 +30,76 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; import java.io.InputStream; +import java.util.Enumeration; +import java.util.Hashtable; import java.util.Vector; public class JSch{ /** * The version number. */ - public static final String VERSION = "0.1.54"; + public static final String VERSION = Version.getVersion(); - static java.util.Hashtable config=new java.util.Hashtable(); + static Hashtable config=new Hashtable<>(); static{ - 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-ctr,aes192-cbc,aes256-ctr,aes256-cbc"); - config.put("cipher.c2s", - "aes128-ctr,aes128-cbc,3des-ctr,3des-cbc,blowfish-cbc,aes192-ctr,aes192-cbc,aes256-ctr,aes256-cbc"); + config.put("kex", Util.getSystemProperty("jsch.kex", "curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256")); + config.put("server_host_key", Util.getSystemProperty("jsch.server_host_key", "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256")); + config.put("prefer_known_host_key_types", Util.getSystemProperty("jsch.prefer_known_host_key_types", "yes")); + config.put("enable_server_sig_algs", Util.getSystemProperty("jsch.enable_server_sig_algs", "yes")); + config.put("cipher.s2c", Util.getSystemProperty("jsch.cipher", "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com")); + config.put("cipher.c2s", Util.getSystemProperty("jsch.cipher", "aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com")); + config.put("mac.s2c", Util.getSystemProperty("jsch.mac", "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1")); + config.put("mac.c2s", Util.getSystemProperty("jsch.mac", "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1")); + config.put("compression.s2c", Util.getSystemProperty("jsch.compression", "none")); + config.put("compression.c2s", Util.getSystemProperty("jsch.compression", "none")); - config.put("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96"); - config.put("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96"); - config.put("compression.s2c", "none"); - config.put("compression.c2s", "none"); + config.put("lang.s2c", Util.getSystemProperty("jsch.lang", "")); + config.put("lang.c2s", Util.getSystemProperty("jsch.lang", "")); - config.put("lang.s2c", ""); - config.put("lang.c2s", ""); + config.put("dhgex_min", Util.getSystemProperty("jsch.dhgex_min", "2048")); + config.put("dhgex_max", Util.getSystemProperty("jsch.dhgex_max", "8192")); + config.put("dhgex_preferred", Util.getSystemProperty("jsch.dhgex_preferred", "3072")); - config.put("compression_level", "6"); + config.put("compression_level", Util.getSystemProperty("jsch.compression_level", "6")); config.put("diffie-hellman-group-exchange-sha1", - "com.jcraft.jsch.DHGEX"); + "com.jcraft.jsch.DHGEX1"); config.put("diffie-hellman-group1-sha1", - "com.jcraft.jsch.DHG1"); + "com.jcraft.jsch.DHG1"); config.put("diffie-hellman-group14-sha1", - "com.jcraft.jsch.DHG14"); // available since JDK8. + "com.jcraft.jsch.DHG14"); config.put("diffie-hellman-group-exchange-sha256", - "com.jcraft.jsch.DHGEX256"); // available since JDK1.4.2. - // On JDK8, 2048bits will be used. + "com.jcraft.jsch.DHGEX256"); + config.put("diffie-hellman-group-exchange-sha224@ssh.com", + "com.jcraft.jsch.DHGEX224"); + config.put("diffie-hellman-group-exchange-sha384@ssh.com", + "com.jcraft.jsch.DHGEX384"); + config.put("diffie-hellman-group-exchange-sha512@ssh.com", + "com.jcraft.jsch.DHGEX512"); + config.put("diffie-hellman-group14-sha256", + "com.jcraft.jsch.DHG14256"); + config.put("diffie-hellman-group15-sha512", + "com.jcraft.jsch.DHG15"); + config.put("diffie-hellman-group16-sha512", + "com.jcraft.jsch.DHG16"); + config.put("diffie-hellman-group17-sha512", + "com.jcraft.jsch.DHG17"); + config.put("diffie-hellman-group18-sha512", + "com.jcraft.jsch.DHG18"); + config.put("diffie-hellman-group14-sha256@ssh.com", + "com.jcraft.jsch.DHG14256"); + config.put("diffie-hellman-group14-sha224@ssh.com", + "com.jcraft.jsch.DHG14224"); + config.put("diffie-hellman-group15-sha256@ssh.com", + "com.jcraft.jsch.DHG15256"); + config.put("diffie-hellman-group15-sha384@ssh.com", + "com.jcraft.jsch.DHG15384"); + config.put("diffie-hellman-group16-sha512@ssh.com", + "com.jcraft.jsch.DHG16"); + config.put("diffie-hellman-group16-sha384@ssh.com", + "com.jcraft.jsch.DHG16384"); + config.put("diffie-hellman-group18-sha512@ssh.com", + "com.jcraft.jsch.DHG18"); config.put("ecdsa-sha2-nistp256", "com.jcraft.jsch.jce.SignatureECDSA256"); config.put("ecdsa-sha2-nistp384", "com.jcraft.jsch.jce.SignatureECDSA384"); config.put("ecdsa-sha2-nistp521", "com.jcraft.jsch.jce.SignatureECDSA521"); @@ -76,39 +110,85 @@ public class JSch{ config.put("ecdh-sha2-nistp", "com.jcraft.jsch.jce.ECDHN"); + config.put("curve25519-sha256", "com.jcraft.jsch.DH25519"); + config.put("curve25519-sha256@libssh.org", "com.jcraft.jsch.DH25519"); + config.put("curve448-sha512", "com.jcraft.jsch.DH448"); + config.put("dh", "com.jcraft.jsch.jce.DH"); config.put("3des-cbc", "com.jcraft.jsch.jce.TripleDESCBC"); config.put("blowfish-cbc", "com.jcraft.jsch.jce.BlowfishCBC"); config.put("hmac-sha1", "com.jcraft.jsch.jce.HMACSHA1"); config.put("hmac-sha1-96", "com.jcraft.jsch.jce.HMACSHA196"); config.put("hmac-sha2-256", "com.jcraft.jsch.jce.HMACSHA256"); - // The "hmac-sha2-512" will require the key-length 2048 for DH, - // but Sun's JCE has not allowed to use such a long key. - //config.put("hmac-sha2-512", "com.jcraft.jsch.jce.HMACSHA512"); + config.put("hmac-sha2-512", "com.jcraft.jsch.jce.HMACSHA512"); config.put("hmac-md5", "com.jcraft.jsch.jce.HMACMD5"); config.put("hmac-md5-96", "com.jcraft.jsch.jce.HMACMD596"); + config.put("hmac-sha1-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA1ETM"); + config.put("hmac-sha1-96-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA196ETM"); + config.put("hmac-sha2-256-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA256ETM"); + config.put("hmac-sha2-512-etm@openssh.com", "com.jcraft.jsch.jce.HMACSHA512ETM"); + config.put("hmac-md5-etm@openssh.com", "com.jcraft.jsch.jce.HMACMD5ETM"); + config.put("hmac-md5-96-etm@openssh.com", "com.jcraft.jsch.jce.HMACMD596ETM"); + config.put("hmac-sha256-2@ssh.com", "com.jcraft.jsch.jce.HMACSHA2562SSHCOM"); + config.put("hmac-sha224@ssh.com", "com.jcraft.jsch.jce.HMACSHA224SSHCOM"); + config.put("hmac-sha256@ssh.com", "com.jcraft.jsch.jce.HMACSHA256SSHCOM"); + config.put("hmac-sha384@ssh.com", "com.jcraft.jsch.jce.HMACSHA384SSHCOM"); + config.put("hmac-sha512@ssh.com", "com.jcraft.jsch.jce.HMACSHA512SSHCOM"); 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("sha-224", "com.jcraft.jsch.jce.SHA224"); + 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("sha1", "com.jcraft.jsch.jce.SHA1"); + config.put("sha224", "com.jcraft.jsch.jce.SHA224"); + config.put("sha256", "com.jcraft.jsch.jce.SHA256"); + config.put("sha384", "com.jcraft.jsch.jce.SHA384"); + config.put("sha512", "com.jcraft.jsch.jce.SHA512"); config.put("signature.dss", "com.jcraft.jsch.jce.SignatureDSA"); - config.put("signature.rsa", "com.jcraft.jsch.jce.SignatureRSA"); + config.put("ssh-rsa", "com.jcraft.jsch.jce.SignatureRSA"); + config.put("rsa-sha2-256", "com.jcraft.jsch.jce.SignatureRSASHA256"); + config.put("rsa-sha2-512", "com.jcraft.jsch.jce.SignatureRSASHA512"); + config.put("ssh-rsa-sha224@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA224SSHCOM"); + config.put("ssh-rsa-sha256@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA256SSHCOM"); + config.put("ssh-rsa-sha384@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA384SSHCOM"); + config.put("ssh-rsa-sha512@ssh.com", "com.jcraft.jsch.jce.SignatureRSASHA512SSHCOM"); 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("hmac-ripemd160", "com.jcraft.jsch.bc.HMACRIPEMD160"); + config.put("hmac-ripemd160@openssh.com", "com.jcraft.jsch.bc.HMACRIPEMD160OpenSSH"); + config.put("hmac-ripemd160-etm@openssh.com", "com.jcraft.jsch.bc.HMACRIPEMD160ETM"); + config.put("none", "com.jcraft.jsch.CipherNone"); + config.put("aes128-gcm@openssh.com", "com.jcraft.jsch.jce.AES128GCM"); + config.put("aes256-gcm@openssh.com", "com.jcraft.jsch.jce.AES256GCM"); + config.put("aes128-cbc", "com.jcraft.jsch.jce.AES128CBC"); config.put("aes192-cbc", "com.jcraft.jsch.jce.AES192CBC"); config.put("aes256-cbc", "com.jcraft.jsch.jce.AES256CBC"); + config.put("rijndael-cbc@lysator.liu.se", "com.jcraft.jsch.jce.AES256CBC"); + + config.put("chacha20-poly1305@openssh.com", "com.jcraft.jsch.bc.ChaCha20Poly1305"); + config.put("cast128-cbc", "com.jcraft.jsch.bc.CAST128CBC"); + config.put("cast128-ctr", "com.jcraft.jsch.bc.CAST128CTR"); + config.put("twofish128-cbc", "com.jcraft.jsch.bc.Twofish128CBC"); + config.put("twofish192-cbc", "com.jcraft.jsch.bc.Twofish192CBC"); + config.put("twofish256-cbc", "com.jcraft.jsch.bc.Twofish256CBC"); + config.put("twofish-cbc", "com.jcraft.jsch.bc.Twofish256CBC"); + config.put("twofish128-ctr", "com.jcraft.jsch.bc.Twofish128CTR"); + config.put("twofish192-ctr", "com.jcraft.jsch.bc.Twofish192CTR"); + config.put("twofish256-ctr", "com.jcraft.jsch.bc.Twofish256CTR"); + config.put("seed-cbc@ssh.com", "com.jcraft.jsch.bc.SEEDCBC"); config.put("aes128-ctr", "com.jcraft.jsch.jce.AES128CTR"); config.put("aes192-ctr", "com.jcraft.jsch.jce.AES192CTR"); config.put("aes256-ctr", "com.jcraft.jsch.jce.AES256CTR"); config.put("3des-ctr", "com.jcraft.jsch.jce.TripleDESCTR"); + config.put("blowfish-ctr", "com.jcraft.jsch.jce.BlowfishCTR"); config.put("arcfour", "com.jcraft.jsch.jce.ARCFOUR"); config.put("arcfour128", "com.jcraft.jsch.jce.ARCFOUR128"); config.put("arcfour256", "com.jcraft.jsch.jce.ARCFOUR256"); @@ -120,25 +200,46 @@ public class JSch{ config.put("userauth.gssapi-with-mic", "com.jcraft.jsch.UserAuthGSSAPIWithMIC"); config.put("gssapi-with-mic.krb5", "com.jcraft.jsch.jgss.GSSContextKrb5"); - config.put("zlib", "com.jcraft.jsch.jcraft.Compression"); - config.put("zlib@openssh.com", "com.jcraft.jsch.jcraft.Compression"); + config.put("zlib", "com.jcraft.jsch.jzlib.Compression"); + config.put("zlib@openssh.com", "com.jcraft.jsch.jzlib.Compression"); config.put("pbkdf", "com.jcraft.jsch.jce.PBKDF"); + if(JavaVersion.getVersion()>=11){ + config.put("xdh", "com.jcraft.jsch.jce.XDH"); + } + else{ + config.put("xdh", "com.jcraft.jsch.bc.XDH"); + } + + if(JavaVersion.getVersion()>=15){ + config.put("keypairgen.eddsa", "com.jcraft.jsch.jce.KeyPairGenEdDSA"); + config.put("ssh-ed25519", "com.jcraft.jsch.jce.SignatureEd25519"); + config.put("ssh-ed448", "com.jcraft.jsch.jce.SignatureEd448"); + } + else{ + config.put("keypairgen.eddsa", "com.jcraft.jsch.bc.KeyPairGenEdDSA"); + config.put("ssh-ed25519", "com.jcraft.jsch.bc.SignatureEd25519"); + config.put("ssh-ed448", "com.jcraft.jsch.bc.SignatureEd448"); + } + config.put("StrictHostKeyChecking", "ask"); config.put("HashKnownHosts", "no"); - config.put("PreferredAuthentications", "gssapi-with-mic,publickey,keyboard-interactive,password"); + config.put("PreferredAuthentications", Util.getSystemProperty("jsch.preferred_authentications", "gssapi-with-mic,publickey,keyboard-interactive,password")); + config.put("PubkeyAcceptedAlgorithms", Util.getSystemProperty("jsch.client_pubkey", "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,rsa-sha2-512,rsa-sha2-256")); - 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,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521"); - config.put("CheckSignatures", "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521"); + config.put("CheckCiphers", Util.getSystemProperty("jsch.check_ciphers", "chacha20-poly1305@openssh.com")); + config.put("CheckMacs", Util.getSystemProperty("jsch.check_macs", "")); + config.put("CheckKexes", Util.getSystemProperty("jsch.check_kexes", "curve25519-sha256,curve25519-sha256@libssh.org,curve448-sha512")); + config.put("CheckSignatures", Util.getSystemProperty("jsch.check_signatures", "ssh-ed25519,ssh-ed448")); + config.put("FingerprintHash", Util.getSystemProperty("jsch.fingerprint_hash", "sha256")); - config.put("MaxAuthTries", "6"); + config.put("MaxAuthTries", Util.getSystemProperty("jsch.max_auth_tries", "6")); config.put("ClearAllForwardings", "no"); } - private java.util.Vector sessionPool = new java.util.Vector(); + private Vector sessionPool = new Vector<>(); private IdentityRepository defaultIdentityRepository = new LocalIdentityRepository(this); @@ -179,28 +280,16 @@ public class JSch{ private HostKeyRepository known_hosts=null; - private static final Logger DEVNULL=new Logger(){ + static final Logger DEVNULL=new Logger(){ + @Override public boolean isEnabled(int level){return false;} + @Override public void log(int level, String message){} }; static Logger logger=DEVNULL; + private Logger instLogger; 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")){ - config.put("hmac-sha1", "com.jcraft.jsch.jcraft.HMACSHA1"); - config.put("hmac-md5", "com.jcraft.jsch.jcraft.HMACMD5"); - config.put("hmac-md5-96", "com.jcraft.jsch.jcraft.HMACMD596"); - config.put("hmac-sha1-96", "com.jcraft.jsch.jcraft.HMACSHA196"); - } - } - catch(Exception e){ - } - */ } /** @@ -313,7 +402,7 @@ public class JSch{ if(known_hosts==null) known_hosts=new KnownHosts(this); if(known_hosts instanceof KnownHosts){ synchronized(known_hosts){ - ((KnownHosts)known_hosts).setKnownHosts(filename); + ((KnownHosts)known_hosts).setKnownHosts(filename); } } } @@ -333,7 +422,7 @@ public class JSch{ if(known_hosts==null) known_hosts=new KnownHosts(this); if(known_hosts instanceof KnownHosts){ synchronized(known_hosts){ - ((KnownHosts)known_hosts).setKnownHosts(stream); + ((KnownHosts)known_hosts).setKnownHosts(stream); } } } @@ -474,21 +563,22 @@ public class JSch{ } else { synchronized(this){ - if(!(identityRepository instanceof IdentityRepository.Wrapper)){ - setIdentityRepository(new IdentityRepository.Wrapper(identityRepository)); + if(!(identityRepository instanceof IdentityRepositoryWrapper)){ + setIdentityRepository(new IdentityRepositoryWrapper(identityRepository)); } } - ((IdentityRepository.Wrapper)identityRepository).add(identity); + ((IdentityRepositoryWrapper)identityRepository).add(identity); } } /** * @deprecated use #removeIdentity(Identity identity) */ + @Deprecated public void removeIdentity(String name) throws JSchException{ - Vector identities = identityRepository.getIdentities(); + Vector identities = identityRepository.getIdentities(); for(int i=0; i getIdentityNames() throws JSchException{ + Vector foo=new Vector<>(); + Vector identities = identityRepository.getIdentities(); for(int i=0; i newconf){ synchronized(config){ - for(java.util.Enumeration e=newconf.keys() ; e.hasMoreElements() ;) { - String key=(String)(e.nextElement()); - config.put(key, (String)(newconf.get(key))); + for(Enumeration e=newconf.keys() ; e.hasMoreElements() ;) { + String newkey=e.nextElement(); + String key=(newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey); + config.put(key, newconf.get(newkey)); } } } @@ -569,13 +663,19 @@ public class JSch{ * @param value value for the configuration */ public static void setConfig(String key, String value){ - config.put(key, value); + if(key.equals("PubkeyAcceptedKeyTypes")){ + config.put("PubkeyAcceptedAlgorithms", value); + } + else{ + config.put(key, value); + } } /** * Sets the logger * - * @param logger logger + * @param logger logger or null if no logging + * should take place * * @see com.jcraft.jsch.Logger */ @@ -583,8 +683,34 @@ public class JSch{ if(logger==null) logger=DEVNULL; JSch.logger=logger; } - - static Logger getLogger(){ + + /** + * Returns a logger to be used for this particular instance of JSch + * @return The logger that is used by this instance. If no particular + * logger has been set, the statically set logger is returned. + */ + public Logger getInstanceLogger() { + if (this.instLogger == null) { + return logger; + } + return instLogger; + } + + /** + * Sets a logger to be used for this particular instance of JSch + * @param logger The logger to be used or null if + * the statically set logger should be used + */ + public void setInstanceLogger(Logger logger) { + this.instLogger = logger; + } + + /** + * Returns the statically set logger, i.e. the logger being + * used by all JSch instances without explicitly set logger. + * @return The logger + */ + public static Logger getLogger(){ return logger; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java new file mode 100644 index 00000000..fbdbf446 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JSchAlgoNegoFailException.java @@ -0,0 +1,69 @@ +package com.jcraft.jsch; + +/** + * Extension of {@link JSchException} to indicate when a connection fails during algorithm + * negotiation. + */ +public class JSchAlgoNegoFailException extends JSchException { + + private static final long serialVersionUID = -1L; + + private final String algorithmName; + private final String jschProposal; + private final String serverProposal; + + JSchAlgoNegoFailException(int algorithmIndex, String jschProposal, String serverProposal) { + super(failString(algorithmIndex, jschProposal, serverProposal)); + algorithmName = algorithmNameFromIndex(algorithmIndex); + this.jschProposal = jschProposal; + this.serverProposal = serverProposal; + } + + /** Get the algorithm name. */ + public String getAlgorithmName() { + return algorithmName; + } + + /** Get the JSch algorithm proposal. */ + public String getJSchProposal() { + return jschProposal; + } + + /** Get the server algorithm proposal. */ + public String getServerProposal() { + return serverProposal; + } + + private static String failString(int algorithmIndex, String jschProposal, String serverProposal) { + return String.format( + "Algorithm negotiation fail: algorithmName=\"%s\" jschProposal=\"%s\" serverProposal=\"%s\"", + algorithmNameFromIndex(algorithmIndex), jschProposal, serverProposal); + } + + private static String algorithmNameFromIndex(int algorithmIndex) { + switch (algorithmIndex) { + case KeyExchange.PROPOSAL_KEX_ALGS: + return "kex"; + case KeyExchange.PROPOSAL_SERVER_HOST_KEY_ALGS: + return "server_host_key"; + case KeyExchange.PROPOSAL_ENC_ALGS_CTOS: + return "cipher.c2s"; + case KeyExchange.PROPOSAL_ENC_ALGS_STOC: + return "cipher.s2c"; + case KeyExchange.PROPOSAL_MAC_ALGS_CTOS: + return "mac.c2s"; + case KeyExchange.PROPOSAL_MAC_ALGS_STOC: + return "mac.s2c"; + case KeyExchange.PROPOSAL_COMP_ALGS_CTOS: + return "compression.c2s"; + case KeyExchange.PROPOSAL_COMP_ALGS_STOC: + return "compression.s2c"; + case KeyExchange.PROPOSAL_LANG_CTOS: + return "lang.c2s"; + case KeyExchange.PROPOSAL_LANG_STOC: + return "lang.s2c"; + default: + return ""; + } + } +} 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 39450991..288f4b51 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 @@ -30,7 +30,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; class JSchAuthCancelException extends JSchException{ - //private static final long serialVersionUID=3204965907117900987L; + private static final long serialVersionUID=-1L; String method; JSchAuthCancelException () { super(); 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 a8942277..c55b4f16 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 @@ -30,8 +30,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; public class JSchException extends Exception{ - //private static final long serialVersionUID=-1319309923966731989L; - private Throwable cause=null; + private static final long serialVersionUID=-1L; public JSchException () { super(); } @@ -39,10 +38,6 @@ public class JSchException extends Exception{ super(s); } public JSchException (String s, Throwable e) { - super(s); - this.cause=e; - } - public Throwable getCause(){ - return this.cause; + super(s, e); } } 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 e6fb2770..ce5c29a6 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 @@ -30,7 +30,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; class JSchPartialAuthException extends JSchException{ - //private static final long serialVersionUID=-378849862323360367L; + private static final long serialVersionUID=-1L; String methods; public JSchPartialAuthException () { super(); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JavaVersion.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JavaVersion.java new file mode 100644 index 00000000..b6184b14 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JavaVersion.java @@ -0,0 +1,8 @@ +package com.jcraft.jsch; + +final class JavaVersion { + + static int getVersion() { + return 8; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JulLogger.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JulLogger.java new file mode 100644 index 00000000..9316d2fa --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/JulLogger.java @@ -0,0 +1,53 @@ +package com.jcraft.jsch; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class JulLogger implements com.jcraft.jsch.Logger { + + private static final Logger stlogger = Logger.getLogger(JSch.class.getName()); + private final Logger logger; + + public JulLogger() { + this(stlogger); + } + + JulLogger(Logger logger) { + this.logger = logger; + } + + @Override + public boolean isEnabled(int level) { + return logger.isLoggable(getLevel(level)); + } + + @Override + public void log(int level, String message) { + log(level, message, null); + } + + @Override + public void log(int level, String message, Throwable cause) { + if (cause == null) { + logger.log(getLevel(level), message); + return; + } + logger.log(getLevel(level), message, cause); + } + + static Level getLevel(int level) { + switch (level) { + case com.jcraft.jsch.Logger.DEBUG: + return Level.FINE; + case com.jcraft.jsch.Logger.INFO: + return Level.INFO; + case com.jcraft.jsch.Logger.WARN: + return Level.WARNING; + case com.jcraft.jsch.Logger.ERROR: + case com.jcraft.jsch.Logger.FATAL: + return Level.SEVERE; + default: + return Level.FINER; + } + } +} 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 2b5e544e..251b312d 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 @@ -68,7 +68,12 @@ public abstract class KeyExchange{ protected byte[] K_S=null; public abstract void init(Session session, - byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception; + byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception; + void doInit(Session session, + byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception { + this.session = session; + init(session, V_S, V_C, I_S, I_C); + } public abstract boolean next(Buffer buf) throws Exception; public abstract int getState(); @@ -76,12 +81,14 @@ public abstract class KeyExchange{ protected final int RSA=0; protected final int DSS=1; protected final int ECDSA=2; + protected final int EDDSA=3; private int type=0; private String key_alg_name = ""; public String getKeyType() { if(type==DSS) return "DSA"; if(type==RSA) return "RSA"; + if(type==EDDSA) return "EDDSA"; return "ECDSA"; } @@ -89,18 +96,18 @@ public abstract class KeyExchange{ return key_alg_name; } - protected static String[] guess(byte[]I_S, byte[]I_C){ + protected static String[] guess(Session session, byte[]I_S, byte[]I_C) throws Exception{ String[] guess=new String[PROPOSAL_MAX]; Buffer sb=new Buffer(I_S); sb.setOffSet(17); Buffer cb=new Buffer(I_C); cb.setOffSet(17); - if(JSch.getLogger().isEnabled(Logger.INFO)){ + if(session.getLogger().isEnabled(Logger.INFO)){ for(int i=0; i _s2cclazz=Class.forName(session.getConfig(guess[PROPOSAL_ENC_ALGS_STOC])).asSubclass(Cipher.class); + Cipher _s2ccipher=_s2cclazz.getDeclaredConstructor().newInstance(); + _s2cAEAD=_s2ccipher.isAEAD(); + if(_s2cAEAD){ + guess[PROPOSAL_MAC_ALGS_STOC]=null; + } + + Class _c2sclazz=Class.forName(session.getConfig(guess[PROPOSAL_ENC_ALGS_CTOS])).asSubclass(Cipher.class); + Cipher _c2scipher=_c2sclazz.getDeclaredConstructor().newInstance(); + _c2sAEAD=_c2scipher.isAEAD(); + if(_c2sAEAD){ + guess[PROPOSAL_MAC_ALGS_CTOS]=null; + } + } + catch(Exception | NoClassDefFoundError e){ + throw new JSchException(e.toString(), e); + } + + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, + "kex: algorithm: "+guess[PROPOSAL_KEX_ALGS]); + session.getLogger().log(Logger.INFO, + "kex: host key algorithm: "+guess[PROPOSAL_SERVER_HOST_KEY_ALGS]); + session.getLogger().log(Logger.INFO, "kex: server->client"+ - " "+guess[PROPOSAL_ENC_ALGS_STOC]+ - " "+guess[PROPOSAL_MAC_ALGS_STOC]+ - " "+guess[PROPOSAL_COMP_ALGS_STOC]); - JSch.getLogger().log(Logger.INFO, + " cipher: "+guess[PROPOSAL_ENC_ALGS_STOC]+ + " MAC: "+(_s2cAEAD?(""):(guess[PROPOSAL_MAC_ALGS_STOC]))+ + " compression: "+guess[PROPOSAL_COMP_ALGS_STOC]); + session.getLogger().log(Logger.INFO, "kex: client->server"+ - " "+guess[PROPOSAL_ENC_ALGS_CTOS]+ - " "+guess[PROPOSAL_MAC_ALGS_CTOS]+ - " "+guess[PROPOSAL_COMP_ALGS_CTOS]); + " cipher: "+guess[PROPOSAL_ENC_ALGS_CTOS]+ + " MAC: "+(_c2sAEAD?(""):(guess[PROPOSAL_MAC_ALGS_CTOS]))+ + " compression: "+guess[PROPOSAL_COMP_ALGS_CTOS]); } return guess; @@ -160,11 +192,12 @@ public abstract class KeyExchange{ public String getFingerPrint(){ HASH hash=null; try{ - Class c=Class.forName(session.getConfig("md5")); - hash=(HASH)(c.newInstance()); + String _c=session.getConfig("FingerprintHash").toLowerCase(); + Class c=Class.forName(session.getConfig(_c)).asSubclass(HASH.class); + hash=c.getDeclaredConstructor().newInstance(); } catch(Exception e){ System.err.println("getFingerPrint: "+e); } - return Util.getFingerPrint(hash, getHostKey()); + return Util.getFingerPrint(hash, getHostKey(), true, false); } byte[] getK(){ return K; } byte[] getH(){ return H; } @@ -211,11 +244,13 @@ public abstract class KeyExchange{ ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; n=tmp; - + SignatureRSA sig=null; + Buffer buf=new Buffer(sig_of_H); + String foo=Util.byte2str(buf.getString()); try{ - Class c=Class.forName(session.getConfig("signature.rsa")); - sig=(SignatureRSA)(c.newInstance()); + Class c=Class.forName(session.getConfig(foo)).asSubclass(SignatureRSA.class); + sig=c.getDeclaredConstructor().newInstance(); sig.init(); } catch(Exception e){ @@ -225,9 +260,9 @@ public abstract class KeyExchange{ 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); + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, + "ssh_rsa_verify: "+foo+" signature "+result); } } else if(alg.equals("ssh-dss")){ @@ -241,7 +276,7 @@ public abstract class KeyExchange{ key_alg_name=alg; j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| - ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); + ((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)| @@ -249,7 +284,7 @@ public abstract class KeyExchange{ 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); + ((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)| @@ -259,8 +294,8 @@ public abstract class KeyExchange{ SignatureDSA sig=null; try{ - Class c=Class.forName(session.getConfig("signature.dss")); - sig=(SignatureDSA)(c.newInstance()); + Class c=Class.forName(session.getConfig("signature.dss")).asSubclass(SignatureDSA.class); + sig=c.getDeclaredConstructor().newInstance(); sig.init(); } catch(Exception e){ @@ -270,8 +305,8 @@ public abstract class KeyExchange{ sig.update(H); result=sig.verify(sig_of_H); - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, "ssh_dss_verify: signature "+result); } } @@ -301,8 +336,8 @@ public abstract class KeyExchange{ SignatureECDSA sig=null; try{ - Class c=Class.forName(session.getConfig(alg)); - sig=(SignatureECDSA)(c.newInstance()); + Class c=Class.forName(session.getConfig(alg)).asSubclass(SignatureECDSA.class); + sig=c.getDeclaredConstructor().newInstance(); sig.init(); } catch(Exception e){ @@ -314,10 +349,48 @@ public abstract class KeyExchange{ sig.update(H); result=sig.verify(sig_of_H); + + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, + "ssh_ecdsa_verify: "+alg+" signature "+result); + } + } + else if(alg.equals("ssh-ed25519") || + alg.equals("ssh-ed448")) { + byte[] tmp; + + // RFC 8709, + type=EDDSA; + key_alg_name=alg; + + j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)| + ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff); + tmp=new byte[j]; System.arraycopy(K_S, i, tmp, 0, j); i+=j; + + SignatureEdDSA sig=null; + try{ + Class c=Class.forName(session.getConfig(alg)).asSubclass(SignatureEdDSA.class); + sig=c.getDeclaredConstructor().newInstance(); + sig.init(); + } + catch(Exception | NoClassDefFoundError e){ + System.err.println(e); + } + + sig.setPubKey(tmp); + + sig.update(H); + + result=sig.verify(sig_of_H); + + if(session.getLogger().isEnabled(Logger.INFO)){ + session.getLogger().log(Logger.INFO, + "ssh_eddsa_verify: "+alg+" signature "+result); + } } else{ System.err.println("unknown alg"); - } + } return result; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPair.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPair.java index 76b396ee..39423875 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPair.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPair.java @@ -29,25 +29,31 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -import java.io.FileOutputStream; -import java.io.FileInputStream; -import java.io.File; -import java.io.IOException; +import java.io.*; +import java.util.Arrays; +import java.util.Hashtable; +import java.util.Vector; public abstract class KeyPair{ + + public static final int DEFERRED = -1; public static final int ERROR=0; public static final int DSA=1; public static final int RSA=2; public static final int ECDSA=3; public static final int UNKNOWN=4; - + public static final int ED25519=5; + public static final int ED448=6; + static final int VENDOR_OPENSSH=0; static final int VENDOR_FSECURE=1; static final int VENDOR_PUTTY=2; static final int VENDOR_PKCS8=3; + static final int VENDOR_OPENSSH_V1 = 4; int vendor=VENDOR_OPENSSH; + private static final byte[] AUTH_MAGIC = Util.str2byte("openssh-key-v1\0"); private static final byte[] cr=Util.str2byte("\n"); public static KeyPair genKeyPair(JSch jsch, int type) throws JSchException{ @@ -58,6 +64,8 @@ public abstract class KeyPair{ if(type==DSA){ kpair=new KeyPairDSA(jsch); } else if(type==RSA){ kpair=new KeyPairRSA(jsch); } else if(type==ECDSA){ kpair=new KeyPairECDSA(jsch); } + else if(type==ED25519){ kpair=new KeyPairEd25519(jsch); } + else if(type==ED448){ kpair=new KeyPairEd448(jsch); } if(kpair!=null){ kpair.generate(key_size); } @@ -68,10 +76,12 @@ public abstract class KeyPair{ abstract byte[] getBegin(); abstract byte[] getEnd(); - abstract int getKeySize(); + public abstract int getKeySize(); public abstract byte[] getSignature(byte[] data); + public abstract byte[] getSignature(byte[] data, String alg); public abstract Signature getVerifier(); + public abstract Signature getVerifier(String alg); public abstract byte[] forSSHAgent() throws JSchException; @@ -86,12 +96,15 @@ public abstract class KeyPair{ protected String publicKeyComment = "no comment"; JSch jsch=null; - private Cipher cipher; + protected Cipher cipher; private HASH hash; private Random random; private byte[] passphrase; + protected String kdfName; + protected byte[] kdfOptions; + public KeyPair(JSch jsch){ this.jsch=jsch; } @@ -104,9 +117,9 @@ public abstract class KeyPair{ /** * Writes the plain private key to the given output stream. * @param out output stream - * @see #writePrivateKey(java.io.OutputStream out, byte[] passphrase) + * @see #writePrivateKey(OutputStream out, byte[] passphrase) */ - public void writePrivateKey(java.io.OutputStream out){ + public void writePrivateKey(OutputStream out){ this.writePrivateKey(out, null); } @@ -115,7 +128,7 @@ public abstract class KeyPair{ * @param out output stream * @param passphrase a passphrase to encrypt the private key */ - public void writePrivateKey(java.io.OutputStream out, byte[] passphrase){ + public void writePrivateKey(OutputStream out, byte[] passphrase){ if(passphrase == null) passphrase = this.passphrase; @@ -125,31 +138,31 @@ public abstract class KeyPair{ if(encoded!=plain) Util.bzero(plain); byte[] iv=_iv[0]; - byte[] prv=Util.toBase64(encoded, 0, encoded.length); + byte[] prv=Util.toBase64(encoded, 0, encoded.length, true); try{ out.write(getBegin()); out.write(cr); if(passphrase!=null){ - out.write(header[0]); out.write(cr); - out.write(header[1]); - for(int i=0; i>>4)&0x0f))); - out.write(b2a((byte)(iv[i]&0x0f))); - } + out.write(header[0]); out.write(cr); + out.write(header[1]); + for(int i=0; i>>4)&0x0f))); + out.write(b2a((byte)(iv[i]&0x0f))); + } + out.write(cr); out.write(cr); - out.write(cr); } int i=0; while(i c=Class.forName(JSch.getConfig("random")).asSubclass(Random.class); + random=c.getDeclaredConstructor().newInstance(); } catch(Exception e){ System.err.println("connect: random "+e); } } @@ -396,8 +409,8 @@ public abstract class KeyPair{ private HASH genHash(){ try{ - Class c=Class.forName(jsch.getConfig("md5")); - hash=(HASH)(c.newInstance()); + Class c=Class.forName(JSch.getConfig("md5")).asSubclass(HASH.class); + hash=c.getDeclaredConstructor().newInstance(); hash.init(); } catch(Exception e){ @@ -406,9 +419,8 @@ public abstract class KeyPair{ } private Cipher genCipher(){ try{ - Class c; - c=Class.forName(jsch.getConfig("3des-cbc")); - cipher=(Cipher)(c.newInstance()); + Class c=Class.forName(JSch.getConfig("3des-cbc")).asSubclass(Cipher.class); + cipher=c.getDeclaredConstructor().newInstance(); } catch(Exception e){ } @@ -428,33 +440,33 @@ public abstract class KeyPair{ byte[] key=new byte[cipher.getBlockSize()]; int hsize=hash.getBlockSize(); byte[] hn=new byte[key.length/hsize*hsize+ - (key.length%hsize==0?0:hsize)]; + (key.length%hsize==0?0:hsize)]; try{ byte[] tmp=null; if(vendor==VENDOR_OPENSSH){ - for(int index=0; index+hsize<=hn.length;){ - if(tmp!=null){ hash.update(tmp, 0, tmp.length); } - hash.update(passphrase, 0, passphrase.length); + for(int index=0; index+hsize<=hn.length;){ + if(tmp!=null){ hash.update(tmp, 0, tmp.length); } + hash.update(passphrase, 0, passphrase.length); hash.update(iv, 0, iv.length > 8 ? 8: iv.length); - tmp=hash.digest(); - System.arraycopy(tmp, 0, hn, index, tmp.length); - index+=tmp.length; - } - System.arraycopy(hn, 0, key, 0, key.length); + tmp=hash.digest(); + System.arraycopy(tmp, 0, hn, index, tmp.length); + index+=tmp.length; + } + System.arraycopy(hn, 0, key, 0, key.length); } else if(vendor==VENDOR_FSECURE){ - for(int index=0; index+hsize<=hn.length;){ - if(tmp!=null){ hash.update(tmp, 0, tmp.length); } - hash.update(passphrase, 0, passphrase.length); - tmp=hash.digest(); - System.arraycopy(tmp, 0, hn, index, tmp.length); - index+=tmp.length; - } - System.arraycopy(hn, 0, key, 0, key.length); + for(int index=0; index+hsize<=hn.length;){ + if(tmp!=null){ hash.update(tmp, 0, tmp.length); } + hash.update(passphrase, 0, passphrase.length); + tmp=hash.digest(); + System.arraycopy(tmp, 0, hn, index, tmp.length); + index+=tmp.length; + } + System.arraycopy(hn, 0, key, 0, key.length); } else if(vendor==VENDOR_PUTTY){ - Class c=Class.forName((String)jsch.getConfig("sha-1")); - HASH sha1=(HASH)(c.newInstance()); + Class c=Class.forName(JSch.getConfig("sha-1")).asSubclass(HASH.class); + HASH sha1=c.getDeclaredConstructor().newInstance(); tmp = new byte[4]; key = new byte[20*2]; for(int i = 0; i < 2; i++){ @@ -473,8 +485,9 @@ public abstract class KeyPair{ } /** - * @deprecated use #writePrivateKey(java.io.OutputStream out, byte[] passphrase) + * @deprecated use #writePrivateKey(OutputStream out, byte[] passphrase) */ + @Deprecated public void setPassphrase(String passphrase){ if(passphrase==null || passphrase.length()==0){ setPassphrase((byte[])null); @@ -487,6 +500,7 @@ public abstract class KeyPair{ /** * @deprecated use #writePrivateKey(String name, byte[] passphrase) */ + @Deprecated public void setPassphrase(byte[] passphrase){ if(passphrase!=null && passphrase.length==0) passphrase=null; @@ -540,7 +554,7 @@ public abstract class KeyPair{ prvkey = Util.fromFile(prvfile); } catch(IOException e){ - throw new JSchException(e.toString(), (Throwable)e); + throw new JSchException(e.toString(), e); } String _pubfile=pubfile; @@ -553,7 +567,7 @@ public abstract class KeyPair{ } catch(IOException e){ if(pubfile!=null){ - throw new JSchException(e.toString(), (Throwable)e); + throw new JSchException(e.toString(), e); } } @@ -577,17 +591,20 @@ public abstract class KeyPair{ int vendor=VENDOR_OPENSSH; String publicKeyComment = ""; Cipher cipher=null; + String kdfName = null; + byte[] kdfOptions = null; // prvkey from "ssh-add" command on the remote. if(pubkey==null && prvkey!=null && (prvkey.length>11 && prvkey[0]==0 && prvkey[1]==0 && prvkey[2]==0 && - (prvkey[3]==7 || prvkey[3]==19))){ + // length of key type string + (prvkey[3]==7 || prvkey[3]==9 || prvkey[3]==11 || prvkey[3]==19))){ Buffer buf=new Buffer(prvkey); buf.skip(prvkey.length); // for using Buffer#available() - String _type = new String(buf.getString()); // ssh-rsa or ssh-dss + String _type = Util.byte2str(buf.getString()); // ssh-rsa or ssh-dss buf.rewind(); KeyPair kpair=null; @@ -602,8 +619,14 @@ public abstract class KeyPair{ _type.equals("ecdsa-sha2-nistp521")){ kpair=KeyPairECDSA.fromSSHAgent(jsch, buf); } + else if(_type.equals("ssh-ed25519")){ + kpair=KeyPairEd25519.fromSSHAgent(jsch, buf); + } + else if(_type.equals("ssh-ed448")){ + kpair=KeyPairEd448.fromSSHAgent(jsch, buf); + } else{ - throw new JSchException("privatekey: invalid key "+new String(prvkey, 4, 7)); + throw new JSchException("privatekey: invalid key "+Util.byte2str(prvkey, 4, 7)); } return kpair; } @@ -634,117 +657,120 @@ public abstract class KeyPair{ if(buf[i]=='B'&& i+3= len) - throw new JSchException("invalid privatekey: "+prvkey); + throw new JSchException("invalid privatekey"); 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 && + 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; + type=UNKNOWN; + vendor=VENDOR_PKCS8; encrypted=false; i+=3; - } - else if(i+8 < len && + } + 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; + type=UNKNOWN; + vendor=VENDOR_PKCS8; i+=5; - } - else{ - throw new JSchException("invalid privatekey: "+prvkey); - } + + } else if (isOpenSSHPrivateKey(buf, i, len)) { + type = UNKNOWN; + vendor = VENDOR_OPENSSH_V1; + } else { + throw new JSchException("invalid privatekey"); + } i+=3; - continue; - } + continue; + } if(buf[i]=='A'&& i+7 c=Class.forName(JSch.getConfig("aes256-cbc")).asSubclass(Cipher.class); + cipher=c.getDeclaredConstructor().newInstance(); // key=new byte[cipher.getBlockSize()]; iv=new byte[cipher.getIVSize()]; } else{ - throw new JSchException("privatekey: aes256-cbc is not available "+prvkey); + throw new JSchException("privatekey: aes256-cbc is not available"); } continue; } if(buf[i]=='A'&& i+7 c=Class.forName(JSch.getConfig("aes192-cbc")).asSubclass(Cipher.class); + cipher=c.getDeclaredConstructor().newInstance(); // key=new byte[cipher.getBlockSize()]; iv=new byte[cipher.getIVSize()]; } else{ - throw new JSchException("privatekey: aes192-cbc is not available "+prvkey); + throw new JSchException("privatekey: aes192-cbc is not available"); } continue; } if(buf[i]=='A'&& i+7 c=Class.forName(JSch.getConfig("aes128-cbc")).asSubclass(Cipher.class); + cipher=c.getDeclaredConstructor().newInstance(); // key=new byte[cipher.getBlockSize()]; iv=new byte[cipher.getIVSize()]; } else{ - throw new JSchException("privatekey: aes128-cbc is not available "+prvkey); + throw new JSchException("privatekey: aes128-cbc is not available"); } continue; } if(buf[i]=='C'&& i+34 && // FSecure - data[0]==(byte)0x3f && - data[1]==(byte)0x6f && - data[2]==(byte)0xf9 && - data[3]==(byte)0xeb){ + data[0]==(byte)0x3f && + data[1]==(byte)0x6f && + data[2]==(byte)0xf9 && + data[3]==(byte)0xeb){ - Buffer _buf=new Buffer(data); - _buf.getInt(); // 0x3f6ff9be - _buf.getInt(); - byte[]_type=_buf.getString(); - //System.err.println("type: "+new String(_type)); - String _cipher=Util.byte2str(_buf.getString()); - //System.err.println("cipher: "+_cipher); - if(_cipher.equals("3des-cbc")){ - _buf.getInt(); - byte[] foo=new byte[data.length-_buf.getOffSet()]; - _buf.getByte(foo); - data=foo; - encrypted=true; - throw new JSchException("unknown privatekey format: "+prvkey); - } - else if(_cipher.equals("none")){ - _buf.getInt(); - _buf.getInt(); + Buffer _buf=new Buffer(data); + _buf.getInt(); // 0x3f6ff9be + _buf.getInt(); + byte[]_type=_buf.getString(); + //System.err.println("type: "+Util.byte2str(_type)); + String _cipher=Util.byte2str(_buf.getString()); + //System.err.println("cipher: "+_cipher); + if(_cipher.equals("3des-cbc")){ + _buf.getInt(); + byte[] foo=new byte[data.length-_buf.getOffSet()]; + _buf.getByte(foo); + data=foo; + encrypted=true; + throw new JSchException("unknown privatekey format"); + } + else if(_cipher.equals("none")){ + _buf.getInt(); + _buf.getInt(); encrypted=false; - byte[] foo=new byte[data.length-_buf.getOffSet()]; - _buf.getByte(foo); - data=foo; - } + byte[] foo=new byte[data.length-_buf.getOffSet()]; + _buf.getByte(foo); + data=foo; + } + } + // OPENSSH V1 PRIVATE KEY + else if (data != null && + Util.array_equals(AUTH_MAGIC, Arrays.copyOfRange(data, 0, AUTH_MAGIC.length))) { + + vendor = VENDOR_OPENSSH_V1; + Buffer buffer = new Buffer(data); + byte[] magic = new byte[AUTH_MAGIC.length]; + buffer.getByte(magic); + + String cipherName = Util.byte2str(buffer.getString()); + kdfName = Util.byte2str(buffer.getString()); // string kdfname + kdfOptions = buffer.getString(); // string kdfoptions + + int nrKeys = buffer.getInt(); // int number of keys N; Should be 1 + if (nrKeys != 1) { + throw new IOException("We don't support having more than 1 key in the file (yet)."); } + pubkey = buffer.getString(); + + if ("none".equals(cipherName)) { + encrypted = false; + data = buffer.getString(); + type = readOpenSSHKeyv1(data); + } else if (Session.checkCipher(JSch.getConfig(cipherName))) { + encrypted = true; + Class c = Class.forName(JSch.getConfig(cipherName)).asSubclass(Cipher.class); + cipher = c.getDeclaredConstructor().newInstance(); + data = buffer.getString(); + // the type can only be determined after encryption, so we take this intermediate here: + type = DEFERRED; + } else { + throw new JSchException("cipher " + cipherName + " is not available"); + } + } + if(pubkey!=null){ - try{ - buf=pubkey; + try{ + buf=pubkey; len=buf.length; - if(buf.length>4 && // FSecure's public key - buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-'){ + if(buf.length>4 && // FSecure's public key + buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-'){ - boolean valid=true; - i=0; - do{i++;}while(buf.length>i && buf[i]!=0x0a); - if(buf.length<=i) {valid=false;} + boolean valid=true; + i=0; + do{i++;}while(buf.length>i && buf[i]!=0x0a); + if(buf.length<=i) {valid=false;} - while(valid){ - if(buf[i]==0x0a){ - boolean inheader=false; - for(int j=i+1; j7){ - if(buf[4]=='d'){ type=DSA; } - else if(buf[4]=='r'){ type=RSA; } + if(buf[4]=='d'){ type=DSA; } + else if(buf[4]=='r'){ type=RSA; } + else if(buf[4]=='e' && buf[6]=='2'){ type=ED25519; } + else if(buf[4]=='e' && buf[6]=='4'){ type=ED448; } + } + i=0; + while(i0 && buf[i-1]==0x0d) i--; if(start7){ type=ECDSA; @@ -904,53 +967,103 @@ public abstract class KeyPair{ while(i0 && buf[i-1]==0x0d) i--; if(start v = new Hashtable<>(); while(true){ if(!parseHeader(buffer, v)) break; } - String typ = (String)v.get("PuTTY-User-Key-File-2"); + String typ = v.get("PuTTY-User-Key-File-2"); if(typ == null){ return null; } - lines = Integer.parseInt((String)v.get("Public-Lines")); + lines = Integer.parseInt(v.get("Public-Lines")); pubkey = parseLines(buffer, lines); while(true){ @@ -1011,7 +1126,7 @@ public abstract class KeyPair{ break; } - lines = Integer.parseInt((String)v.get("Private-Lines")); + lines = Integer.parseInt(v.get("Private-Lines")); prvkey = parseLines(buffer, lines); while(true){ @@ -1065,12 +1180,12 @@ public abstract class KeyPair{ kpair.encrypted = !v.get("Encryption").equals("none"); kpair.vendor = VENDOR_PUTTY; - kpair.publicKeyComment = (String)v.get("Comment"); + kpair.publicKeyComment = v.get("Comment"); if(kpair.encrypted){ - if(Session.checkCipher((String)jsch.getConfig("aes256-cbc"))){ + if(Session.checkCipher(JSch.getConfig("aes256-cbc"))){ try { - Class c=Class.forName((String)jsch.getConfig("aes256-cbc")); - kpair.cipher=(Cipher)(c.newInstance()); + Class c=Class.forName(JSch.getConfig("aes256-cbc")).asSubclass(Cipher.class); + kpair.cipher=c.getDeclaredConstructor().newInstance(); kpair.iv=new byte[kpair.cipher.getIVSize()]; } catch(Exception e){ @@ -1123,7 +1238,7 @@ public abstract class KeyPair{ return data; } - private static boolean parseHeader(Buffer buffer, java.util.Hashtable v){ + private static boolean parseHeader(Buffer buffer, Hashtable v){ byte[] buf = buffer.buffer; int index = buffer.index; String key = null; @@ -1133,7 +1248,7 @@ public abstract class KeyPair{ break; } if(buf[i] == ':'){ - key = new String(buf, index, i - index); + key = Util.byte2str(buf, index, i - index); i++; if(i < buf.length && buf[i] == ' '){ i++; @@ -1148,7 +1263,7 @@ public abstract class KeyPair{ for(int i = index; i < buf.length; i++){ if(buf[i] == 0x0d){ - value = new String(buf, index, i - index); + value = Util.byte2str(buf, index, i - index); i++; if(i < buf.length && buf[i] == 0x0a){ i++; @@ -1173,7 +1288,8 @@ public abstract class KeyPair{ this.cipher=kpair.cipher; } - class ASN1Exception extends Exception { + static class ASN1Exception extends Exception { + private static final long serialVersionUID=-1L; } class ASN1 { @@ -1233,7 +1349,7 @@ public abstract class KeyPair{ return new ASN1[0]; } int index=indexp[0]; - java.util.Vector values = new java.util.Vector(); + Vector values = new Vector<>(); while(length>0) { index++; length--; int tmp=index; @@ -1247,7 +1363,7 @@ public abstract class KeyPair{ } ASN1[] result = new ASN1[values.size()]; for(int i = 0; i c=Class.forName(JSch.getConfig("keypairgen.dsa")).asSubclass(KeyPairGenDSA.class); + KeyPairGenDSA keypairgen=c.getDeclaredConstructor().newInstance(); keypairgen.init(key_size); P_array=keypairgen.getP(); Q_array=keypairgen.getQ(); @@ -74,19 +77,20 @@ public class KeyPairDSA extends KeyPair{ keypairgen=null; } catch(Exception e){ - //System.err.println("KeyPairDSA: "+e); - if(e instanceof Throwable) - throw new JSchException(e.toString(), (Throwable)e); - throw new JSchException(e.toString()); + //System.err.println("KeyPairDSA: "+e); + throw new JSchException(e.toString(), e); } } private static final byte[] begin=Util.str2byte("-----BEGIN DSA PRIVATE KEY-----"); private static final byte[] end=Util.str2byte("-----END DSA PRIVATE KEY-----"); + @Override byte[] getBegin(){ return begin; } + @Override byte[] getEnd(){ return end; } + @Override byte[] getPrivateKey(){ int content= 1+countLength(1) + 1 + // INTEGER @@ -111,23 +115,24 @@ public class KeyPairDSA extends KeyPair{ return plain; } + @Override boolean parse(byte[] plain){ try{ if(vendor==VENDOR_FSECURE){ - if(plain[0]!=0x30){ // FSecure - Buffer buf=new Buffer(plain); - buf.getInt(); - P_array=buf.getMPIntBits(); - G_array=buf.getMPIntBits(); - Q_array=buf.getMPIntBits(); - pub_array=buf.getMPIntBits(); - prv_array=buf.getMPIntBits(); + if(plain[0]!=0x30){ // FSecure + Buffer buf=new Buffer(plain); + buf.getInt(); + P_array=buf.getMPIntBits(); + G_array=buf.getMPIntBits(); + Q_array=buf.getMPIntBits(); + pub_array=buf.getMPIntBits(); + prv_array=buf.getMPIntBits(); if(P_array!=null) - key_size = (new java.math.BigInteger(P_array)).bitLength(); - return true; - } - return false; + key_size = (new BigInteger(P_array)).bitLength(); + return true; + } + return false; } else if(vendor==VENDOR_PUTTY){ Buffer buf=new Buffer(plain); @@ -144,6 +149,29 @@ public class KeyPairDSA extends KeyPair{ return true; } + // OPENSSH Key v1 Format + else if (vendor == VENDOR_OPENSSH_V1) { + + final Buffer prvKEyBuffer = new Buffer(plain); + int checkInt1 = prvKEyBuffer.getInt(); // uint32 checkint1 + int checkInt2 = prvKEyBuffer.getInt(); // uint32 checkint2 + if (checkInt1 != checkInt2) { + throw new JSchException("check failed"); + } + // The private key section contains both the public key and the private key + String keyType = Util.byte2str(prvKEyBuffer.getString()); // string keytype + + P_array=prvKEyBuffer.getMPInt(); + Q_array=prvKEyBuffer.getMPInt(); + G_array= prvKEyBuffer.getMPInt(); + pub_array=prvKEyBuffer.getMPInt(); + prv_array=prvKEyBuffer.getMPInt(); + publicKeyComment=Util.byte2str(prvKEyBuffer.getString()); + //if(P_array!=null) key_size = (new BigInteger(P_array)).bitLength(); + return true; + + } + int index=0; int length=0; @@ -215,7 +243,7 @@ public class KeyPairDSA extends KeyPair{ index+=length; if(P_array!=null) - key_size = (new java.math.BigInteger(P_array)).bitLength(); + key_size = (new BigInteger(P_array)).bitLength(); } catch(Exception e){ //System.err.println(e); @@ -225,6 +253,7 @@ public class KeyPairDSA extends KeyPair{ return true; } + @Override public byte[] getPublicKeyBlob(){ byte[] foo=super.getPublicKeyBlob(); if(foo!=null) return foo; @@ -240,17 +269,21 @@ public class KeyPairDSA extends KeyPair{ } private static final byte[] sshdss=Util.str2byte("ssh-dss"); + @Override byte[] getKeyTypeName(){return sshdss;} + @Override public int getKeyType(){return DSA;} + @Override public int getKeySize(){ return key_size; } + @Override public byte[] getSignature(byte[] data){ - try{ - Class c=Class.forName((String)jsch.getConfig("signature.dss")); - SignatureDSA dsa=(SignatureDSA)(c.newInstance()); + try{ + Class c=Class.forName(JSch.getConfig("signature.dss")).asSubclass(SignatureDSA.class); + SignatureDSA dsa=c.getDeclaredConstructor().newInstance(); dsa.init(); dsa.setPrvKey(prv_array, P_array, Q_array, G_array); @@ -267,10 +300,16 @@ public class KeyPairDSA extends KeyPair{ return null; } + @Override + public byte[] getSignature(byte[] data, String alg){ + return getSignature(data); + } + + @Override public Signature getVerifier(){ - try{ - Class c=Class.forName((String)jsch.getConfig("signature.dss")); - SignatureDSA dsa=(SignatureDSA)(c.newInstance()); + try{ + Class c=Class.forName(JSch.getConfig("signature.dss")).asSubclass(SignatureDSA.class); + SignatureDSA dsa=c.getDeclaredConstructor().newInstance(); dsa.init(); if(pub_array == null && P_array == null && getPublicKeyBlob()!=null){ @@ -280,7 +319,7 @@ public class KeyPairDSA extends KeyPair{ Q_array = buf.getString(); G_array = buf.getString(); pub_array = buf.getString(); - } + } dsa.setPubKey(pub_array, P_array, Q_array, G_array); return dsa; @@ -291,6 +330,11 @@ public class KeyPairDSA extends KeyPair{ return null; } + @Override + public Signature getVerifier(String alg){ + return getVerifier(); + } + static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { byte[][] tmp = buf.getBytes(7, "invalid key format"); @@ -303,11 +347,12 @@ public class KeyPairDSA extends KeyPair{ KeyPairDSA kpair = new KeyPairDSA(jsch, P_array, Q_array, G_array, pub_array, prv_array); - kpair.publicKeyComment = new String(tmp[6]); + kpair.publicKeyComment = Util.byte2str(tmp[6]); kpair.vendor=VENDOR_OPENSSH; return kpair; } + @Override public byte[] forSSHAgent() throws JSchException { if(isEncrypted()){ throw new JSchException("key is encrypted."); @@ -325,6 +370,7 @@ public class KeyPairDSA extends KeyPair{ return result; } + @Override public void dispose(){ super.dispose(); Util.bzero(prv_array); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDeferred.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDeferred.java new file mode 100644 index 00000000..d4f5aaba --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairDeferred.java @@ -0,0 +1,163 @@ +package com.jcraft.jsch; + +import com.jcraft.jsch.jbcrypt.BCrypt; + +import java.util.Arrays; + +/** + * A {@link KeyPair} which can only reveal its type and content after it was decrypted using {@link com.jcraft.jsch.KeyPairDeferred#decrypt(byte[])}. + * This is needed for openssh-v1-private-key format. + */ +class KeyPairDeferred extends KeyPair { + + private KeyPair delegate; + + KeyPairDeferred(JSch jsch) { + super(jsch); + } + + @Override + public boolean decrypt(String _passphrase) { + return decrypt(Util.str2byte(_passphrase)); + } + + @Override + public boolean decrypt(byte[] _passphrase) { + try { + if (!isEncrypted()) { + return true; + } + if (_passphrase == null) { + jsch.getInstanceLogger().log(Logger.ERROR, "no passphrase set."); + return false; + } + + initCipher(_passphrase); + + byte[] plain = new byte[data.length]; + cipher.update(data, 0, data.length, plain, 0); + + // now we have decrypted key and can determine type + int type = readOpenSSHKeyv1(plain); + + delegate = getKeyPair(jsch, null, null, null, false, plain, getPublicKeyBlob(), type, VENDOR_OPENSSH_V1, publicKeyComment, cipher, null, null); + + return delegate != null; + + + } catch (Exception e) { + throw new IllegalArgumentException("Could not sucessfully decrypt openssh v1 key", e); + } + + } + + private void initCipher(byte[] _passphrase) throws Exception { + + // the encrypted private key is here: + if ("bcrypt".equals(kdfName)) { + Buffer opts = new Buffer(kdfOptions); + + byte[] keyiv = new byte[48]; + + new BCrypt().pbkdf(_passphrase, opts.getString(), opts.getInt(), keyiv); + + Arrays.fill(_passphrase, (byte) 0); + byte[] key = Arrays.copyOfRange(keyiv, 0, 32); + byte[] iv = Arrays.copyOfRange(keyiv, 32, 48); + cipher.init(Cipher.DECRYPT_MODE, key, iv); + } else { + throw new IllegalStateException("No support for KDF '" + kdfName + "'."); + } + } + + @Override + void generate(int key_size) throws JSchException { + throw new UnsupportedOperationException(); + } + + @Override + byte[] getBegin() { + return requireDecrypted(delegate).getBegin(); + } + + @Override + byte[] getEnd() { + return requireDecrypted(delegate).getEnd(); + } + + @Override + public int getKeySize() { + return requireDecrypted(delegate).getKeySize(); + } + + @Override + public byte[] getSignature(byte[] data) { + return requireDecrypted(delegate).getSignature(data); + } + + @Override + public byte[] getSignature(byte[] data, String alg) { + return requireDecrypted(delegate).getSignature(data, alg); + } + + @Override + public Signature getVerifier() { + return requireDecrypted(delegate).getVerifier(); + } + + @Override + public Signature getVerifier(String alg) { + return requireDecrypted(delegate).getVerifier(alg); + } + + @Override + public byte[] forSSHAgent() throws JSchException { + return requireDecrypted(delegate).forSSHAgent(); + } + + @Override + byte[] getPrivateKey() { + return requireDecrypted(delegate).getPrivateKey(); + } + + @Override + byte[] getKeyTypeName() { + return requireDecrypted(delegate).getKeyTypeName(); + } + + @Override + public int getKeyType() { + return requireDecrypted(delegate).getKeyType(); + } + + @Override + boolean parse(byte[] data) { + return requireDecrypted(delegate).parse(data); + } + + @Override + public byte[] getPublicKeyBlob() { + return delegate != null ? delegate.getPublicKeyBlob() : null; + } + + @Override + public String getPublicKeyComment() { + return requireDecrypted(delegate).getPublicKeyComment(); + } + + @Override + public String getFingerPrint() { + return requireDecrypted(delegate).getFingerPrint(); + } + + @Override + public boolean isEncrypted() { + return delegate != null ? delegate.isEncrypted() : super.isEncrypted(); + } + + private T requireDecrypted(T obj) { + if (obj == null) + throw new IllegalStateException("encrypted key has not been decrypted yet."); + return obj; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairECDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairECDSA.java index e00c3ca0..283e520b 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairECDSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairECDSA.java @@ -29,7 +29,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class KeyPairECDSA extends KeyPair{ +import java.util.Arrays; + +class KeyPairECDSA extends KeyPair{ private static byte[][] oids = { {(byte)0x06, (byte)0x08, (byte)0x2a, (byte)0x86, (byte)0x48, // 256 @@ -51,11 +53,11 @@ public class KeyPairECDSA extends KeyPair{ private int key_size=256; - public KeyPairECDSA(JSch jsch){ + KeyPairECDSA(JSch jsch){ this(jsch, null, null, null, null); } - public KeyPairECDSA(JSch jsch , byte[] pubkey){ + KeyPairECDSA(JSch jsch , byte[] pubkey){ this(jsch, null, null, null, null); if(pubkey!=null){ @@ -72,7 +74,7 @@ public class KeyPairECDSA extends KeyPair{ } } - public KeyPairECDSA(JSch jsch, + KeyPairECDSA(JSch jsch, byte[] name, byte[] r_array, byte[] s_array, @@ -84,15 +86,16 @@ public class KeyPairECDSA extends KeyPair{ this.s_array = s_array; this.prv_array = prv_array; if(prv_array!=null) - key_size = prv_array.length>=64 ? 521 : + key_size = prv_array.length>=64 ? 521 : (prv_array.length>=48 ? 384 : 256); } + @Override 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()); + Class c=Class.forName(JSch.getConfig("keypairgen.ecdsa")).asSubclass(KeyPairGenECDSA.class); + KeyPairGenECDSA keypairgen=c.getDeclaredConstructor().newInstance(); keypairgen.init(key_size); prv_array=keypairgen.getD(); r_array=keypairgen.getR(); @@ -102,20 +105,21 @@ public class KeyPairECDSA extends KeyPair{ keypairgen=null; } catch(Exception e){ - if(e instanceof Throwable) - throw new JSchException(e.toString(), (Throwable)e); - throw new JSchException(e.toString()); + throw new JSchException(e.toString(), e); } } - private static final byte[] begin = + private static final byte[] begin = Util.str2byte("-----BEGIN EC PRIVATE KEY-----"); private static final byte[] end = Util.str2byte("-----END EC PRIVATE KEY-----"); + @Override byte[] getBegin(){ return begin; } + @Override byte[] getEnd(){ return end; } + @Override byte[] getPrivateKey(){ byte[] tmp = new byte[1]; tmp[0]=1; @@ -130,7 +134,7 @@ public class KeyPairECDSA extends KeyPair{ 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 + foo[0]=0x03; // BITSTRING if(bar==3){ foo[1]=(byte)(point.length+1); } @@ -160,17 +164,18 @@ public class KeyPairECDSA extends KeyPair{ return plain; } + @Override boolean parse(byte[] plain){ try{ if(vendor==VENDOR_FSECURE){ /* - if(plain[0]!=0x30){ // FSecure - return true; - } - return false; + if(plain[0]!=0x30){ // FSecure + return true; + } + return false; */ - return false; + return false; } else if(vendor==VENDOR_PUTTY){ /* @@ -187,7 +192,43 @@ public class KeyPairECDSA extends KeyPair{ return true; */ - return false; + return false; + } + + // OPENSSH Key v1 Format + if (vendor == VENDOR_OPENSSH_V1) { + + final Buffer prvKeyBuffer = new Buffer(plain); + int checkInt1 = prvKeyBuffer.getInt(); // uint32 checkint1 + int checkInt2 = prvKeyBuffer.getInt(); // uint32 checkint2 + if (checkInt1 != checkInt2) { + throw new JSchException("check failed"); + } + + String keyType = Util.byte2str(prvKeyBuffer.getString()); // string keytype + + name = prvKeyBuffer.getString(); + if(!Arrays.asList(names).contains(Util.byte2str(name))){ + throw new IllegalArgumentException("unknown curve name "+Util.byte2str(name)); + } + + final int keyLen = prvKeyBuffer.getInt(); + final int x04 = prvKeyBuffer.getByte(); // in case of x04 it is uncompressed https://tools.ietf.org/html/rfc5480#page-7 + final byte[] x = new byte[(keyLen - 1) / 2]; + final byte[] y = new byte[(keyLen - 1) / 2]; + prvKeyBuffer.getByte(x); + prvKeyBuffer.getByte(y); + + + prv_array=prvKeyBuffer.getString(); + publicKeyComment=Util.byte2str(prvKeyBuffer.getString()); + r_array = x; + s_array = y; + key_size = x.length>=64 ? 521 : + (x.length>=48 ? 384 : 256); + + return true; + } int index=0; @@ -260,7 +301,7 @@ public class KeyPairECDSA extends KeyPair{ s_array = tmp[1]; if(prv_array!=null) - key_size = prv_array.length>=64 ? 521 : + key_size = prv_array.length>=64 ? 521 : (prv_array.length>=48 ? 384 : 256); } catch(Exception e){ @@ -271,6 +312,7 @@ public class KeyPairECDSA extends KeyPair{ return true; } + @Override public byte[] getPublicKeyBlob(){ byte[] foo = super.getPublicKeyBlob(); @@ -279,7 +321,7 @@ public class KeyPairECDSA extends KeyPair{ if(r_array==null) return null; byte[][] tmp = new byte[3][]; - tmp[0] = Util.str2byte("ecdsa-sha2-"+new String(name)); + tmp[0] = Util.str2byte("ecdsa-sha2-"+Util.byte2str(name)); tmp[1] = name; tmp[2] = new byte[1+r_array.length+s_array.length]; tmp[2][0] = 4; // POINT_CONVERSION_UNCOMPRESSED @@ -289,20 +331,24 @@ public class KeyPairECDSA extends KeyPair{ return Buffer.fromBytes(tmp).buffer; } + @Override byte[] getKeyTypeName(){ - return Util.str2byte("ecdsa-sha2-"+new String(name)); + return Util.str2byte("ecdsa-sha2-"+Util.byte2str(name)); } + @Override public int getKeyType(){ return ECDSA; } + @Override public int getKeySize(){ return key_size; } + @Override public byte[] getSignature(byte[] data){ try{ - Class c=Class.forName((String)jsch.getConfig("ecdsa-sha2-"+new String(name))); - SignatureECDSA ecdsa=(SignatureECDSA)(c.newInstance()); + Class c=Class.forName(JSch.getConfig("ecdsa-sha2-"+Util.byte2str(name))).asSubclass(SignatureECDSA.class); + SignatureECDSA ecdsa=c.getDeclaredConstructor().newInstance(); ecdsa.init(); ecdsa.setPrvKey(prv_array); @@ -310,7 +356,7 @@ public class KeyPairECDSA extends KeyPair{ byte[] sig = ecdsa.sign(); byte[][] tmp = new byte[2][]; - tmp[0] = Util.str2byte("ecdsa-sha2-"+new String(name)); + tmp[0] = Util.str2byte("ecdsa-sha2-"+Util.byte2str(name)); tmp[1] = sig; return Buffer.fromBytes(tmp).buffer; } @@ -320,10 +366,16 @@ public class KeyPairECDSA extends KeyPair{ return null; } + @Override + public byte[] getSignature(byte[] data, String al){ + return getSignature(data); + } + + @Override public Signature getVerifier(){ try{ - Class c=Class.forName((String)jsch.getConfig("ecdsa-sha2-"+new String(name))); - final SignatureECDSA ecdsa=(SignatureECDSA)(c.newInstance()); + Class c=Class.forName(JSch.getConfig("ecdsa-sha2-"+Util.byte2str(name))).asSubclass(SignatureECDSA.class); + final SignatureECDSA ecdsa=c.getDeclaredConstructor().newInstance(); ecdsa.init(); if(r_array == null && s_array == null && getPublicKeyBlob()!=null){ @@ -333,7 +385,7 @@ public class KeyPairECDSA extends KeyPair{ byte[][] tmp = fromPoint(buf.getString()); r_array = tmp[0]; s_array = tmp[1]; - } + } ecdsa.setPubKey(r_array, s_array); return ecdsa; } @@ -343,6 +395,11 @@ public class KeyPairECDSA extends KeyPair{ return null; } + @Override + public Signature getVerifier(String alg){ + return getVerifier(); + } + static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { byte[][] tmp = buf.getBytes(5, "invalid key format"); @@ -357,17 +414,18 @@ public class KeyPairECDSA extends KeyPair{ name, r_array, s_array, prv_array); - kpair.publicKeyComment = new String(tmp[4]); + kpair.publicKeyComment = Util.byte2str(tmp[4]); kpair.vendor=VENDOR_OPENSSH; return kpair; } + @Override 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(Util.str2byte("ecdsa-sha2-"+Util.byte2str(name))); buf.putString(name); buf.putString(toPoint(r_array, s_array)); buf.putString(prv_array); @@ -401,6 +459,7 @@ public class KeyPairECDSA extends KeyPair{ return tmp; } + @Override public void dispose(){ super.dispose(); Util.bzero(prv_array); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd25519.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd25519.java new file mode 100644 index 00000000..fed75354 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd25519.java @@ -0,0 +1,68 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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.Arrays; + +class KeyPairEd25519 extends KeyPairEdDSA{ + + private static int keySize = 32; + + KeyPairEd25519(JSch jsch){ + this(jsch, null, null); + } + + KeyPairEd25519(JSch jsch, + byte[] pub_array, + byte[] prv_array){ + super(jsch, pub_array, prv_array); + } + + @Override + public int getKeyType(){ return ED25519; } + @Override + public int getKeySize(){ return keySize; } + @Override + String getSshName(){ return "ssh-ed25519"; } + @Override + String getJceName(){ return "Ed25519"; } + + static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { + + byte[][] tmp = buf.getBytes(4, "invalid key format"); + + byte[] pub_array = tmp[1]; + byte[] prv_array = Arrays.copyOf(tmp[2], keySize); + KeyPairEd25519 kpair = new KeyPairEd25519(jsch, pub_array, prv_array); + kpair.publicKeyComment = Util.byte2str(tmp[3]); + kpair.vendor=VENDOR_OPENSSH; + return kpair; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd448.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd448.java new file mode 100644 index 00000000..ad68fb07 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEd448.java @@ -0,0 +1,68 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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.Arrays; + +class KeyPairEd448 extends KeyPairEdDSA{ + + private static int keySize = 57; + + KeyPairEd448(JSch jsch){ + this(jsch, null, null); + } + + KeyPairEd448(JSch jsch, + byte[] pub_array, + byte[] prv_array){ + super(jsch, pub_array, prv_array); + } + + @Override + public int getKeyType(){ return ED448; } + @Override + public int getKeySize(){ return keySize; } + @Override + String getSshName(){ return "ssh-ed448"; } + @Override + String getJceName(){ return "Ed448"; } + + static KeyPair fromSSHAgent(JSch jsch, Buffer buf) throws JSchException { + + byte[][] tmp = buf.getBytes(4, "invalid key format"); + + byte[] pub_array = tmp[1]; + byte[] prv_array = Arrays.copyOf(tmp[2], keySize); + KeyPairEd448 kpair = new KeyPairEd448(jsch, pub_array, prv_array); + kpair.publicKeyComment = Util.byte2str(tmp[3]); + kpair.vendor=VENDOR_OPENSSH; + return kpair; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java new file mode 100644 index 00000000..48246d40 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairEdDSA.java @@ -0,0 +1,191 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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.Arrays; + +abstract class KeyPairEdDSA extends KeyPair{ + private byte[] pub_array; + private byte[] prv_array; + + KeyPairEdDSA(JSch jsch, + byte[] pub_array, + byte[] prv_array){ + super(jsch); + this.pub_array = pub_array; + this.prv_array = prv_array; + } + + abstract String getSshName(); + abstract String getJceName(); + + @Override + void generate(int key_size) throws JSchException{ + try{ + Class c=Class.forName(JSch.getConfig("keypairgen.eddsa")).asSubclass(KeyPairGenEdDSA.class); + KeyPairGenEdDSA keypairgen=c.getDeclaredConstructor().newInstance(); + keypairgen.init(getJceName(), getKeySize()); + pub_array=keypairgen.getPub(); + prv_array=keypairgen.getPrv(); + + keypairgen=null; + } + catch(Exception | NoClassDefFoundError e){ + //System.err.println("KeyPairEdDSA: "+e); + throw new JSchException(e.toString(), e); + } + } + + // These methods appear to be for writing keys to a file. + // And since writing VENDOR_OPENSSH_V1 isn't supported yet, have these methods fail. + @Override + byte[] getBegin(){ throw new UnsupportedOperationException(); } + @Override + byte[] getEnd(){ throw new UnsupportedOperationException(); } + @Override + byte[] getPrivateKey(){ throw new UnsupportedOperationException(); } + + @Override + boolean parse(byte [] plain){ + + // Only OPENSSH Key v1 Format supported for EdDSA keys + if(vendor != VENDOR_OPENSSH_V1) return false; + try{ + // OPENSSH Key v1 Format + final Buffer buf = new Buffer(plain); + int checkInt1 = buf.getInt(); // uint32 checkint1 + int checkInt2 = buf.getInt(); // uint32 checkint2 + if (checkInt1 != checkInt2) { + throw new JSchException("check failed"); + } + String keyType = Util.byte2str(buf.getString()); // string keytype + pub_array = buf.getString(); // public key + // OpenSSH stores private key in first half of string and duplicate copy of public key in second half of string + byte[] tmp = buf.getString(); // secret key (private key + public key) + prv_array = Arrays.copyOf(tmp, getKeySize()); + publicKeyComment = Util.byte2str(buf.getString()); + return true; + } + catch(Exception e){ + //System.err.println(e); + return false; + } + } + + @Override + public byte[] getPublicKeyBlob(){ + byte[] foo=super.getPublicKeyBlob(); + if(foo!=null) return foo; + + if(pub_array==null) return null; + byte[][] tmp = new byte[2][]; + tmp[0] = getKeyTypeName(); + tmp[1] = pub_array; + return Buffer.fromBytes(tmp).buffer; + } + + @Override + byte[] getKeyTypeName(){ return Util.str2byte(getSshName()); } + + @Override + public byte[] getSignature(byte[] data){ + return getSignature(data, getSshName()); + } + + @Override + public byte[] getSignature(byte[] data, String alg){ + try{ + Class c=Class.forName(JSch.getConfig(alg)).asSubclass(SignatureEdDSA.class); + SignatureEdDSA eddsa=c.getDeclaredConstructor().newInstance(); + eddsa.init(); + eddsa.setPrvKey(prv_array); + + eddsa.update(data); + byte[] sig = eddsa.sign(); + byte[][] tmp = new byte[2][]; + tmp[0] = Util.str2byte(alg); + tmp[1] = sig; + return Buffer.fromBytes(tmp).buffer; + } + catch(Exception | NoClassDefFoundError e){ + } + return null; + } + + @Override + public Signature getVerifier(){ + return getVerifier(getSshName()); + } + + @Override + public Signature getVerifier(String alg){ + try{ + Class c=Class.forName(JSch.getConfig(alg)).asSubclass(SignatureEdDSA.class); + SignatureEdDSA eddsa=c.getDeclaredConstructor().newInstance(); + eddsa.init(); + + if(pub_array == null && getPublicKeyBlob()!=null){ + Buffer buf = new Buffer(getPublicKeyBlob()); + buf.getString(); + pub_array = buf.getString(); + } + + eddsa.setPubKey(pub_array); + return eddsa; + } + catch(Exception | NoClassDefFoundError e){ + } + return null; + } + + @Override + public byte[] forSSHAgent() throws JSchException { + if(isEncrypted()){ + throw new JSchException("key is encrypted."); + } + Buffer buf = new Buffer(); + buf.putString(getKeyTypeName()); + buf.putString(pub_array); + byte[] tmp = new byte[prv_array.length + pub_array.length]; + System.arraycopy(prv_array, 0, tmp, 0, prv_array.length); + System.arraycopy(pub_array, 0, tmp, prv_array.length, pub_array.length); + buf.putString(tmp); + buf.putString(Util.str2byte(publicKeyComment)); + byte[] result = new byte[buf.getLength()]; + buf.getByte(result, 0, result.length); + return result; + } + + @Override + public void dispose(){ + super.dispose(); + Util.bzero(prv_array); + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java new file mode 100644 index 00000000..e6983524 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenEdDSA.java @@ -0,0 +1,36 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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 KeyPairGenEdDSA{ + void init(String Name, int keylen) throws Exception; + byte[] getPub(); + byte[] getPrv(); +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenXEC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenXEC.java new file mode 100644 index 00000000..2bb51f71 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/KeyPairGenXEC.java @@ -0,0 +1,34 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2015-2018 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 KeyPairGenXEC{ + void init(String name) throws Exception; +} 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 index 33f4b6f6..fa1f3f06 100644 --- 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 @@ -32,7 +32,7 @@ package com.jcraft.jsch; import java.util.Vector; import java.math.BigInteger; -public class KeyPairPKCS8 extends KeyPair { +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 @@ -75,23 +75,28 @@ public class KeyPairPKCS8 extends KeyPair { private KeyPair kpair = null; - public KeyPairPKCS8(JSch jsch){ + KeyPairPKCS8(JSch jsch){ super(jsch); } + @Override 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-----"); + @Override byte[] getBegin(){ return begin; } + @Override byte[] getEnd(){ return end; } + @Override byte[] getPrivateKey(){ return null; } + @Override boolean parse(byte[] plain){ /* from RFC5208 @@ -109,7 +114,7 @@ public class KeyPairPKCS8 extends KeyPair { */ try{ - Vector values = new Vector(); + Vector values = new Vector<>(); ASN1[] contents = null; ASN1 asn1 = new ASN1(plain); @@ -163,10 +168,10 @@ public class KeyPairPKCS8 extends KeyPair { 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); + byte[] P_array = values.elementAt(0); + byte[] Q_array = values.elementAt(1); + byte[] G_array = values.elementAt(2); + byte[] prv_array = values.elementAt(3); // Y = g^X mode p byte[] pub_array = (new BigInteger(G_array)). @@ -195,29 +200,47 @@ public class KeyPairPKCS8 extends KeyPair { return kpair != null; } + @Override public byte[] getPublicKeyBlob(){ return kpair.getPublicKeyBlob(); } + @Override byte[] getKeyTypeName(){ return kpair.getKeyTypeName();} + @Override public int getKeyType(){return kpair.getKeyType();} + @Override public int getKeySize(){ return kpair.getKeySize(); } + @Override public byte[] getSignature(byte[] data){ return kpair.getSignature(data); } + @Override + public byte[] getSignature(byte[] data, String alg){ + return kpair.getSignature(data, alg); + } + + @Override public Signature getVerifier(){ return kpair.getVerifier(); } + @Override + public Signature getVerifier(String alg){ + return kpair.getVerifier(alg); + } + + @Override public byte[] forSSHAgent() throws JSchException { return kpair.forSSHAgent(); } + @Override public boolean decrypt(byte[] _passphrase){ if(!isEncrypted()){ return true; @@ -300,8 +323,8 @@ or byte[] key=null; try{ - Class c=Class.forName((String)jsch.getConfig("pbkdf")); - PBKDF tmp=(PBKDF)(c.newInstance()); + Class c=Class.forName(JSch.getConfig("pbkdf")).asSubclass(PBKDF.class); + PBKDF tmp=c.getDeclaredConstructor().newInstance(); key = tmp.getKey(_passphrase, salt, iterations, cipher.getBlockSize()); } catch(Exception ee){ @@ -343,11 +366,11 @@ or else if(Util.array_equals(id, aes256cbc)){ name="aes256-cbc"; } - Class c=Class.forName((String)jsch.getConfig(name)); - cipher=(Cipher)(c.newInstance()); + Class c=Class.forName(JSch.getConfig(name)).asSubclass(Cipher.class); + cipher=c.getDeclaredConstructor().newInstance(); } catch(Exception e){ - if(JSch.getLogger().isEnabled(Logger.FATAL)){ + if(jsch.getInstanceLogger().isEnabled(Logger.FATAL)){ String message=""; if(name==null){ message="unknown oid: "+Util.toHex(id); @@ -355,7 +378,7 @@ or else { message="function "+name+" is not supported"; } - JSch.getLogger().log(Logger.FATAL, "PKCS8: "+message); + jsch.getInstanceLogger().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 eb0d35b6..eef7ffa3 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 @@ -31,9 +31,9 @@ package com.jcraft.jsch; import java.math.BigInteger; -public class KeyPairRSA extends KeyPair{ +class KeyPairRSA extends KeyPair{ private byte[] n_array; // modulus p multiply q - private byte[] pub_array; // e + private byte[] pub_array; // e private byte[] prv_array; // d e^-1 mod (p-1)(q-1) private byte[] p_array; // prime p @@ -44,11 +44,11 @@ public class KeyPairRSA extends KeyPair{ private int key_size=1024; - public KeyPairRSA(JSch jsch){ + KeyPairRSA(JSch jsch){ this(jsch, null, null, null); } - public KeyPairRSA(JSch jsch, + KeyPairRSA(JSch jsch, byte[] n_array, byte[] pub_array, byte[] prv_array){ @@ -57,15 +57,16 @@ public class KeyPairRSA extends KeyPair{ this.pub_array = pub_array; this.prv_array = prv_array; if(n_array!=null){ - key_size = (new java.math.BigInteger(n_array)).bitLength(); + key_size = (new BigInteger(n_array)).bitLength(); } } + @Override void generate(int key_size) throws JSchException{ this.key_size=key_size; try{ - Class c=Class.forName(jsch.getConfig("keypairgen.rsa")); - KeyPairGenRSA keypairgen=(KeyPairGenRSA)(c.newInstance()); + Class c=Class.forName(JSch.getConfig("keypairgen.rsa")).asSubclass(KeyPairGenRSA.class); + KeyPairGenRSA keypairgen=c.getDeclaredConstructor().newInstance(); keypairgen.init(key_size); pub_array=keypairgen.getE(); prv_array=keypairgen.getD(); @@ -80,19 +81,20 @@ public class KeyPairRSA extends KeyPair{ keypairgen=null; } catch(Exception e){ - //System.err.println("KeyPairRSA: "+e); - if(e instanceof Throwable) - throw new JSchException(e.toString(), (Throwable)e); - throw new JSchException(e.toString()); + //System.err.println("KeyPairRSA: "+e); + throw new JSchException(e.toString(), e); } } private static final byte[] begin=Util.str2byte("-----BEGIN RSA PRIVATE KEY-----"); private static final byte[] end=Util.str2byte("-----END RSA PRIVATE KEY-----"); + @Override byte[] getBegin(){ return begin; } + @Override byte[] getEnd(){ return end; } + @Override byte[] getPrivateKey(){ int content= 1+countLength(1) + 1 + // INTEGER @@ -123,6 +125,7 @@ public class KeyPairRSA extends KeyPair{ return plain; } + @Override boolean parse(byte [] plain){ try{ @@ -151,27 +154,49 @@ public class KeyPairRSA extends KeyPair{ } if(vendor==VENDOR_FSECURE){ - if(plain[index]!=0x30){ // FSecure - Buffer buf=new Buffer(plain); - pub_array=buf.getMPIntBits(); - prv_array=buf.getMPIntBits(); - n_array=buf.getMPIntBits(); - byte[] u_array=buf.getMPIntBits(); - p_array=buf.getMPIntBits(); - q_array=buf.getMPIntBits(); + if(plain[index]!=0x30){ // FSecure + Buffer buf=new Buffer(plain); + pub_array=buf.getMPIntBits(); + prv_array=buf.getMPIntBits(); + n_array=buf.getMPIntBits(); + byte[] u_array=buf.getMPIntBits(); + p_array=buf.getMPIntBits(); + q_array=buf.getMPIntBits(); if(n_array!=null){ - key_size = (new java.math.BigInteger(n_array)).bitLength(); + key_size = (new BigInteger(n_array)).bitLength(); } getEPArray(); getEQArray(); getCArray(); - return true; - } - return false; + return true; + } + return false; } + // OPENSSH Key v1 Format + if (vendor == VENDOR_OPENSSH_V1) { + final Buffer prvKEyBuffer = new Buffer(plain); + int checkInt1 = prvKEyBuffer.getInt(); // uint32 checkint1 + int checkInt2 = prvKEyBuffer.getInt(); // uint32 checkint2 + if (checkInt1 != checkInt2) { + throw new JSchException("check failed"); + } + String keyType = Util.byte2str(prvKEyBuffer.getString()); // string keytype + n_array = prvKEyBuffer.getMPInt(); // Modulus + pub_array=prvKEyBuffer.getMPInt(); // Public Exponent + prv_array = prvKEyBuffer.getMPInt(); // Private Exponent + c_array= prvKEyBuffer.getMPInt(); // iqmp (q^-1 mod p) + p_array=prvKEyBuffer.getMPInt(); // p (Prime 1) + q_array=prvKEyBuffer.getMPInt(); // q (Prime 2) + + getEPArray(); + getEQArray(); + + return true; + } + /* Key must be in the following ASN.1 DER encoding, RSAPrivateKey ::= SEQUENCE { @@ -285,7 +310,7 @@ public class KeyPairRSA extends KeyPair{ index+=length; if(n_array!=null){ - key_size = (new java.math.BigInteger(n_array)).bitLength(); + key_size = (new BigInteger(n_array)).bitLength(); } } @@ -296,6 +321,7 @@ public class KeyPairRSA extends KeyPair{ return true; } + @Override public byte[] getPublicKeyBlob(){ byte[] foo=super.getPublicKeyBlob(); if(foo!=null) return foo; @@ -309,24 +335,33 @@ public class KeyPairRSA extends KeyPair{ } private static final byte[] sshrsa=Util.str2byte("ssh-rsa"); + @Override byte[] getKeyTypeName(){return sshrsa;} + @Override public int getKeyType(){return RSA;} + @Override public int getKeySize(){ return key_size; } + @Override public byte[] getSignature(byte[] data){ - try{ - Class c=Class.forName((String)jsch.getConfig("signature.rsa")); - SignatureRSA rsa=(SignatureRSA)(c.newInstance()); + return getSignature(data, "ssh-rsa"); + } + + @Override + public byte[] getSignature(byte[] data, String alg){ + try{ + Class c=Class.forName(JSch.getConfig(alg)).asSubclass(SignatureRSA.class); + SignatureRSA rsa=c.getDeclaredConstructor().newInstance(); rsa.init(); rsa.setPrvKey(prv_array, n_array); rsa.update(data); byte[] sig = rsa.sign(); byte[][] tmp = new byte[2][]; - tmp[0] = sshrsa; + tmp[0] = Util.str2byte(alg); tmp[1] = sig; return Buffer.fromBytes(tmp).buffer; } @@ -335,10 +370,16 @@ public class KeyPairRSA extends KeyPair{ return null; } + @Override public Signature getVerifier(){ - try{ - Class c=Class.forName((String)jsch.getConfig("signature.rsa")); - SignatureRSA rsa=(SignatureRSA)(c.newInstance()); + return getVerifier("ssh-rsa"); + } + + @Override + public Signature getVerifier(String alg){ + try{ + Class c=Class.forName(JSch.getConfig(alg)).asSubclass(SignatureRSA.class); + SignatureRSA rsa=c.getDeclaredConstructor().newInstance(); rsa.init(); if(pub_array == null && n_array == null && getPublicKeyBlob()!=null){ @@ -346,7 +387,7 @@ public class KeyPairRSA extends KeyPair{ buf.getString(); pub_array = buf.getString(); n_array = buf.getString(); - } + } rsa.setPubKey(pub_array, n_array); return rsa; @@ -367,11 +408,12 @@ public class KeyPairRSA extends KeyPair{ kpair.c_array = tmp[4]; // iqmp kpair.p_array = tmp[5]; kpair.q_array = tmp[6]; - kpair.publicKeyComment = new String(tmp[7]); + kpair.publicKeyComment = Util.byte2str(tmp[7]); kpair.vendor=VENDOR_OPENSSH; return kpair; } + @Override public byte[] forSSHAgent() throws JSchException { if(isEncrypted()){ throw new JSchException("key is encrypted."); @@ -395,22 +437,23 @@ public class KeyPairRSA extends KeyPair{ ep_array=(new BigInteger(prv_array)).mod(new BigInteger(p_array).subtract(BigInteger.ONE)).toByteArray(); } return ep_array; - } + } private byte[] getEQArray(){ if(eq_array==null){ eq_array=(new BigInteger(prv_array)).mod(new BigInteger(q_array).subtract(BigInteger.ONE)).toByteArray(); } return eq_array; - } + } private byte[] getCArray(){ if(c_array==null){ c_array=(new BigInteger(q_array)).modInverse(new BigInteger(p_array)).toByteArray(); } return c_array; - } + } + @Override public void dispose(){ super.dispose(); Util.bzero(prv_array); 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 f6b7049b..ae8f5f16 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 @@ -29,23 +29,29 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; -public class KnownHosts implements HostKeyRepository{ - private static final String _known_hosts="known_hosts"; - private JSch jsch=null; private String known_hosts=null; - private java.util.Vector pool=null; + private Vector pool=null; - private MAC hmacsha1=null; + MAC hmacsha1; - KnownHosts(JSch jsch){ + KnownHosts(JSch jsch) { super(); this.jsch=jsch; - this.hmacsha1 = getHMACSHA1(); - pool=new java.util.Vector(); + getHMACSHA1(); + pool=new Vector<>(); } void setKnownHosts(String filename) throws JSchException{ @@ -60,7 +66,7 @@ class KnownHosts implements HostKeyRepository{ } void setKnownHosts(InputStream input) throws JSchException{ pool.removeAllElements(); - StringBuffer sb=new StringBuffer(); + StringBuilder sb=new StringBuilder(); byte i; int j; boolean error=false; @@ -73,15 +79,15 @@ class KnownHosts implements HostKeyRepository{ int bufl=0; loop: while(true){ - bufl=0; + bufl=0; while(true){ j=fis.read(); if(j==-1){ if(bufl==0){ break loop; } - else{ break; } + break; } - if(j==0x0d){ continue; } - if(j==0x0a){ break; } + if(j==0x0d){ continue; } + if(j==0x0a){ break; } if(buf.length<=bufl){ if(bufl>1024*10) break; // too long... byte[] newbuf=new byte[buf.length*2]; @@ -89,38 +95,38 @@ loop: buf=newbuf; } buf[bufl++]=(byte)j; - } + } - j=0; + j=0; while(j=bufl){ - addInvalidLine(Util.byte2str(buf, 0, bufl)); - continue loop; - } + if(i==' '||i=='\t'){ j++; continue; } + if(i=='#'){ + addInvalidLine(Util.byte2str(buf, 0, bufl)); + continue loop; + } + break; + } + if(j>=bufl){ + addInvalidLine(Util.byte2str(buf, 0, bufl)); + continue loop; + } sb.setLength(0); while(j=bufl || host.length()==0){ - addInvalidLine(Util.byte2str(buf, 0, bufl)); - continue loop; - } + } + host=sb.toString(); + if(j>=bufl || host.length()==0){ + addInvalidLine(Util.byte2str(buf, 0, bufl)); + continue loop; + } while(j=bufl){ - addInvalidLine(Util.byte2str(buf, 0, bufl)); - continue loop; - } + } + 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)); + continue loop; + } while(j v = new ArrayList<>(); for(int i=0; i1){ HostKey[] tmp = @@ -382,28 +398,31 @@ loop: return foo; } } + @Override public void remove(String host, String type){ remove(host, type, null); } + @Override public void remove(String host, String type, byte[] key){ boolean sync=false; synchronized(pool){ for(int i=0; i c=Class.forName(hmacClassname).asSubclass(MAC.class); + return c.getDeclaredConstructor().newInstance(); + } + catch(Exception e){ + jsch.getInstanceLogger().log(Logger.ERROR, "unable to instantiate HMAC-class " + hmacClassname, e); + throw new IllegalArgumentException("instantiation of " + hmacClassname + " lead to an error", e); + } + } HostKey createHashedHostKey(String host, byte[]key) throws JSchException { HashedHostKey hhk=new HashedHostKey(host, key); @@ -524,8 +554,8 @@ loop: String _hash=data.substring(data.indexOf(HASH_DELIM)+1); salt=Util.fromBase64(Util.str2byte(_salt), 0, _salt.length()); hash=Util.fromBase64(Util.str2byte(_hash), 0, _hash.length()); - if(salt.length!=20 || // block size of hmac-sha1 - hash.length!=20){ + int blockSize = hmacsha1.getBlockSize(); + if (salt.length!=blockSize || hash.length!=blockSize) { salt=null; hash=null; return; @@ -534,23 +564,23 @@ loop: } } + @Override boolean isMatched(String _host){ if(!hashed){ return super.isMatched(_host); } - MAC macsha1=getHMACSHA1(); try{ - synchronized(macsha1){ - macsha1.init(salt); + synchronized(hmacsha1){ + hmacsha1.init(salt); byte[] foo=Util.str2byte(_host); - macsha1.update(foo, 0, foo.length); - byte[] bar=new byte[macsha1.getBlockSize()]; - macsha1.doFinal(bar, 0); + hmacsha1.update(foo, 0, foo.length); + byte[] bar=new byte[hmacsha1.getBlockSize()]; + hmacsha1.doFinal(bar, 0); return Util.array_equals(hash, bar); } } catch(Exception e){ - System.out.println(e); + jsch.getInstanceLogger().log(Logger.ERROR, "an error occurred while trying to check hash for host " + _host, e); } return false; } @@ -562,27 +592,30 @@ loop: void hash(){ if(hashed) return; - MAC macsha1=getHMACSHA1(); if(salt==null){ Random random=Session.random; synchronized(random){ - salt=new byte[macsha1.getBlockSize()]; + salt=new byte[hmacsha1.getBlockSize()]; random.fill(salt, 0, salt.length); } } try{ - synchronized(macsha1){ - macsha1.init(salt); + synchronized(hmacsha1){ + hmacsha1.init(salt); byte[] foo=Util.str2byte(host); - macsha1.update(foo, 0, foo.length); - hash=new byte[macsha1.getBlockSize()]; - macsha1.doFinal(hash, 0); + hmacsha1.update(foo, 0, foo.length); + hash=new byte[hmacsha1.getBlockSize()]; + hmacsha1.doFinal(hash, 0); } } catch(Exception e){ + jsch.getInstanceLogger().log(Logger.ERROR, "an error occurred while trying to calculate the hash for host " + host, e); + salt = null; + hash = null; + return; } - host=HASH_MAGIC+Util.byte2str(Util.toBase64(salt, 0, salt.length))+ - HASH_DELIM+Util.byte2str(Util.toBase64(hash, 0, hash.length)); + host=HASH_MAGIC+Util.byte2str(Util.toBase64(salt, 0, salt.length, true))+ + HASH_DELIM+Util.byte2str(Util.toBase64(hash, 0, hash.length, true)); hashed=true; } } 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 227995c4..82b9cbdd 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 @@ -34,24 +34,27 @@ import java.util.Vector; class LocalIdentityRepository implements IdentityRepository { private static final String name = "Local Identity Repository"; - private Vector identities = new Vector(); + private Vector identities = new Vector<>(); private JSch jsch; LocalIdentityRepository(JSch jsch){ this.jsch = jsch; } + @Override public String getName(){ return name; } + @Override public int getStatus(){ return RUNNING; } - public synchronized Vector getIdentities() { + @Override + public synchronized Vector getIdentities() { removeDupulicates(); - Vector v = new Vector(); + Vector v = new Vector<>(); for(int i=0; i v = new Vector<>(); int len = identities.size(); if(len == 0) return; for(int i=0; iHostname *
  • Port
  • *
  • PreferredAuthentications
  • + *
  • PubkeyAcceptedAlgorithms
  • + *
  • FingerprintHash
  • *
  • IdentityFile
  • *
  • NumberOfPasswordPrompts
  • *
  • ConnectTimeout
  • @@ -60,7 +68,7 @@ import java.util.Vector; *
  • CompressionLevel
  • *
  • ForwardAgent
  • *
  • RequestTTY
  • - *
  • ServerAliveInterval
  • + *
  • ServerAliveInterval
  • *
  • LocalForward
  • *
  • RemoteForward
  • *
  • ClearAllForwardings
  • @@ -70,6 +78,10 @@ import java.util.Vector; */ public class OpenSSHConfig implements ConfigRepository { + private static final Set keysWithListAdoption = Stream + .of("KexAlgorithms", "Ciphers","HostKeyAlgorithms", "MACs", "PubkeyAcceptedAlgorithms", "PubkeyAcceptedKeyTypes") + .map(String::toUpperCase).collect(Collectors.toSet()); + /** * Parses the given string, and returns an instance of ConfigRepository. * @@ -77,12 +89,10 @@ public class OpenSSHConfig implements ConfigRepository { * @return an instanceof OpenSSHConfig */ public static OpenSSHConfig parse(String conf) throws IOException { - Reader r = new StringReader(conf); - try { - return new OpenSSHConfig(r); - } - finally { - r.close(); + try(Reader r = new StringReader(conf)) { + try(BufferedReader br = new BufferedReader(r)) { + return new OpenSSHConfig(br); + } } } @@ -93,27 +103,21 @@ public class OpenSSHConfig implements ConfigRepository { * @return an instanceof OpenSSHConfig */ public static OpenSSHConfig parseFile(String file) throws IOException { - Reader r = new FileReader(Util.checkTilde(file)); - try { - return new OpenSSHConfig(r); - } - finally { - r.close(); + try(BufferedReader br = Files.newBufferedReader(Paths.get(Util.checkTilde(file)), StandardCharsets.UTF_8)) { + return new OpenSSHConfig(br); } } - OpenSSHConfig(Reader r) throws IOException { - _parse(r); + OpenSSHConfig(BufferedReader br) throws IOException { + _parse(br); } - private final Hashtable config = new Hashtable(); - private final Vector hosts = new Vector(); - - private void _parse(Reader r) throws IOException { - BufferedReader br = new BufferedReader(r); + private final Hashtable> config = new Hashtable<>(); + private final Vector hosts = new Vector<>(); + private void _parse(BufferedReader br) throws IOException { String host = ""; - Vector/**/ kv = new Vector(); + Vector kv = new Vector<>(); String l = null; while((l = br.readLine()) != null){ @@ -128,11 +132,11 @@ public class OpenSSHConfig implements ConfigRepository { if(key_value.length <= 1) continue; - if(key_value[0].equals("Host")){ + if(key_value[0].equalsIgnoreCase("Host")){ config.put(host, kv); hosts.addElement(host); host = key_value[1]; - kv = new Vector(); + kv = new Vector<>(); } else { kv.addElement(key_value); @@ -142,11 +146,21 @@ public class OpenSSHConfig implements ConfigRepository { hosts.addElement(host); } + @Override public Config getConfig(String host) { return new MyConfig(host); } - private static final Hashtable keymap = new Hashtable(); + /** + * Returns mapping of jsch config property names to OpenSSH property names. + * + * @return map + */ + static Hashtable getKeymap() { + return keymap; + } + + private static final Hashtable keymap = new Hashtable<>(); static { keymap.put("kex", "KexAlgorithms"); keymap.put("server_host_key", "HostKeyAlgorithms"); @@ -163,7 +177,7 @@ public class OpenSSHConfig implements ConfigRepository { class MyConfig implements Config { private String host; - private Vector _configs = new Vector(); + private Vector> _configs = new Vector<>(); MyConfig(String host){ this.host = host; @@ -173,7 +187,7 @@ public class OpenSSHConfig implements ConfigRepository { byte[] _host = Util.str2byte(host); if(hosts.size() > 1){ for(int i = 1; i < hosts.size(); i++){ - String patterns[] = ((String)hosts.elementAt(i)).split("[ \t]"); + String patterns[] = hosts.elementAt(i).split("[ \t]"); for(int j = 0; j < patterns.length; j++){ boolean negate = false; String foo = patterns[j].trim(); @@ -183,11 +197,11 @@ public class OpenSSHConfig implements ConfigRepository { } if(Util.glob(Util.str2byte(foo), _host)){ if(!negate){ - _configs.addElement(config.get((String)hosts.elementAt(i))); + _configs.addElement(config.get(hosts.elementAt(i))); } } else if(negate){ - _configs.addElement(config.get((String)hosts.elementAt(i))); + _configs.addElement(config.get(hosts.elementAt(i))); } } } @@ -195,15 +209,16 @@ public class OpenSSHConfig implements ConfigRepository { } private String find(String key) { + String originalKey=key; if(keymap.get(key)!=null) { - key = (String)keymap.get(key); + key = keymap.get(key); } key = key.toUpperCase(); String value = null; for(int i = 0; i < _configs.size(); i++) { - Vector v = (Vector)_configs.elementAt(i); + Vector v = _configs.elementAt(i); for(int j = 0; j < v.size(); j++) { - String[] kv = (String[])v.elementAt(j); + String[] kv = v.elementAt(j); if(kv[0].toUpperCase().equals(key)) { value = kv[1]; break; @@ -226,16 +241,34 @@ public class OpenSSHConfig implements ConfigRepository { } } */ + + if (keysWithListAdoption.contains(key) && value != null && (value.startsWith("+") || value.startsWith("-") || value.startsWith("^"))) { + + String origConfig = JSch.getConfig(originalKey).trim(); + + if (value.startsWith("+")) { + value=origConfig + "," + value.substring(1).trim(); + } else if (value.startsWith("-")) { + List algList = Arrays.stream(Util.split(origConfig,",")).collect(Collectors.toList()); + for (String alg : Util.split(value.substring(1).trim(),",")) { + algList.remove(alg.trim()); + } + value = String.join(",", algList); + } else if (value.startsWith("^")) { + value = value.substring(1).trim() + "," + origConfig; + } + } + return value; } private String[] multiFind(String key) { key = key.toUpperCase(); - Vector value = new Vector(); + Vector value = new Vector<>(); for(int i = 0; i < _configs.size(); i++) { - Vector v = (Vector)_configs.elementAt(i); + Vector v = _configs.elementAt(i); for(int j = 0; j < v.size(); j++) { - String[] kv = (String[])v.elementAt(j); + String[] kv = v.elementAt(j); if(kv[0].toUpperCase().equals(key)) { String foo = kv[1]; if(foo != null) { @@ -245,13 +278,16 @@ public class OpenSSHConfig implements ConfigRepository { } } } - String[] result = new String[value.size()]; + String[] result = new String[value.size()]; value.toArray(result); return result; } + @Override public String getHostname(){ return find("Hostname"); } + @Override public String getUser(){ return find("User"); } + @Override public int getPort(){ String foo = find("Port"); int port = -1; @@ -263,6 +299,7 @@ public class OpenSSHConfig implements ConfigRepository { } return port; } + @Override public String getValue(String key){ if(key.equals("compression.s2c") || key.equals("compression.c2s")) { @@ -273,6 +310,7 @@ public class OpenSSHConfig implements ConfigRepository { } return find(key); } + @Override public String[] getValues(String key){ return multiFind(key); } } } 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 0a9a5c13..cd477fb3 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 @@ -29,26 +29,32 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class Packet{ +class Packet{ private static Random random=null; static void setRandom(Random foo){ random=foo;} Buffer buffer; byte[] ba4=new byte[4]; - public Packet(Buffer buffer){ + Packet(Buffer buffer){ this.buffer=buffer; } - public void reset(){ + void reset(){ buffer.index=5; } - void padding(int bsize){ + void padding(int bsize, boolean includePktLen){ int len=buffer.index; + if(!includePktLen){ + len-=4; + } int pad=(-len)&(bsize-1); if(pad>>24); ba4[1]=(byte)(len>>>16); ba4[2]=(byte)(len>>>8); @@ -91,8 +97,8 @@ System.err.println(""); // System.err.println("buffer.buffer.length="+buffer.buffer.length+" s="+(s)); System.arraycopy(buffer.buffer, - len+5+9, - buffer.buffer, s, buffer.index-5-9-len); + len+5+9, + buffer.buffer, s, buffer.index-5-9-len); buffer.index=10; buffer.putInt(len); @@ -101,8 +107,8 @@ System.err.println(""); } void unshift(byte command, int recipient, int s, int len){ System.arraycopy(buffer.buffer, - s, - buffer.buffer, 5+9, len); + s, + buffer.buffer, 5+9, len); buffer.buffer[5]=command; buffer.index=6; buffer.putInt(recipient); 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 d59cbc27..104d7abb 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 @@ -29,11 +29,16 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -import java.net.*; -import java.io.*; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.Vector; -class PortWatcher implements Runnable{ - private static java.util.Vector pool=new java.util.Vector(); +class PortWatcher{ + private static Vector pool=new Vector<>(); private static InetAddress anyLocalAddress=null; static{ // 0.0.0.0 @@ -47,6 +52,7 @@ class PortWatcher implements Runnable{ } } + Session session; int lport; int rport; @@ -55,20 +61,46 @@ class PortWatcher implements Runnable{ Runnable thread; ServerSocket ss; int connectTimeout=0; + private String socketPath; + + PortWatcher(Session session, String address, int lport, String socketPath, ServerSocketFactory ssf) throws JSchException { + this.session=session; + this.lport=lport; + this.socketPath = socketPath; + bindLocalPort(address, lport, ssf); + } + + private void bindLocalPort(String address, int lport, ServerSocketFactory ssf) throws JSchException { + try{ + boundaddress= InetAddress.getByName(address); + ss=(ssf==null) ? + new ServerSocket(lport, 0, boundaddress) : + ssf.createServerSocket(lport, 0, boundaddress); + } + catch(Exception e){ + String message="PortForwardingL: local port "+address+":"+lport+" cannot be bound."; + throw new JSchException(message, e); + } + if(lport==0){ + int assigned=ss.getLocalPort(); + if(assigned!=-1) + this.lport=assigned; + } + } static String[] getPortForwarding(Session session){ - java.util.Vector foo=new java.util.Vector(); + Vector foo=new Vector<>(); synchronized(pool){ for(int i=0; i0){ + ChannelDirectStreamLocal channel = new ChannelDirectStreamLocal(); + channel.setSession(session); + channel.init(); + channel.setInputStream(in); + channel.setOutputStream(out); + session.addChannel(channel); + channel.setSocketPath(socketPath); + channel.setOrgIPAddress(socket.getInetAddress().getHostAddress()); + channel.setOrgPort(socket.getPort()); + channel.connect(connectTimeout); + } else { + ChannelDirectTCPIP channel = new ChannelDirectTCPIP(); + channel.setSession(session); + channel.init(); + channel.setInputStream(in); + channel.setOutputStream(out); + session.addChannel(channel); + channel.setHost(host); + channel.setPort(rport); + channel.setOrgIPAddress(socket.getInetAddress().getHostAddress()); + channel.setOrgPort(socket.getPort()); + channel.connect(connectTimeout); + if (channel.exitstatus != -1) { + } + } } } catch(Exception e){ @@ -195,7 +234,7 @@ class PortWatcher implements Runnable{ void delete(){ thread=null; - try{ + try{ if(ss!=null)ss.close(); ss=null; } 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 85b2be35..f5b5994b 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 @@ -48,8 +48,8 @@ public class ProxyHTTP implements Proxy{ String host=proxy_host; if(proxy_host.indexOf(':')!=-1){ try{ - host=proxy_host.substring(0, proxy_host.indexOf(':')); - port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1)); + host=proxy_host.substring(0, proxy_host.indexOf(':')); + port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1)); } catch(Exception e){ } @@ -65,6 +65,7 @@ public class ProxyHTTP implements Proxy{ this.user=user; this.passwd=passwd; } + @Override public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{ try{ if(socket_factory==null){ @@ -85,11 +86,11 @@ public class ProxyHTTP implements Proxy{ out.write(Util.str2byte("CONNECT "+host+":"+port+" HTTP/1.0\r\n")); if(user!=null && passwd!=null){ - byte[] code=Util.str2byte(user+":"+passwd); - code=Util.toBase64(code, 0, code.length); - out.write(Util.str2byte("Proxy-Authorization: Basic ")); - out.write(code); - out.write(Util.str2byte("\r\n")); + byte[] code=Util.str2byte(user+":"+passwd); + code=Util.toBase64(code, 0, code.length, true); + out.write(Util.str2byte("Proxy-Authorization: Basic ")); + out.write(code); + out.write(Util.str2byte("\r\n")); } out.write(Util.str2byte("\r\n")); @@ -97,7 +98,7 @@ public class ProxyHTTP implements Proxy{ int foo=0; - StringBuffer sb=new StringBuffer(); + StringBuilder sb=new StringBuilder(); while(foo>=0){ foo=in.read(); if(foo!=13){sb.append((char)foo); continue;} foo=in.read(); if(foo!=10){continue;} @@ -154,14 +155,16 @@ public class ProxyHTTP implements Proxy{ catch(Exception eee){ } String message="ProxyHTTP: "+e.toString(); - if(e instanceof Throwable) - throw new JSchException(message, (Throwable)e); - throw new JSchException(message); + throw new JSchException(message, e); } } + @Override public InputStream getInputStream(){ return in; } + @Override public OutputStream getOutputStream(){ return out; } + @Override public Socket getSocket(){ return socket; } + @Override public void close(){ try{ if(in!=null)in.close(); 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 76dcb04f..1c0d6e36 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 @@ -53,8 +53,8 @@ public class ProxySOCKS4 implements Proxy{ String host=proxy_host; if(proxy_host.indexOf(':')!=-1){ try{ - host=proxy_host.substring(0, proxy_host.indexOf(':')); - port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1)); + host=proxy_host.substring(0, proxy_host.indexOf(':')); + port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1)); } catch(Exception e){ } @@ -70,6 +70,7 @@ public class ProxySOCKS4 implements Proxy{ this.user=user; this.passwd=passwd; } + @Override public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{ try{ if(socket_factory==null){ @@ -175,8 +176,8 @@ public class ProxySOCKS4 implements Proxy{ } if(buf[1]!=90){ try{ socket.close(); } - catch(Exception eee){ - } + catch(Exception eee){ + } String message="ProxySOCKS4: server returns CD "+buf[1]; throw new JSchException(message); } @@ -188,12 +189,16 @@ public class ProxySOCKS4 implements Proxy{ try{ if(socket!=null)socket.close(); } catch(Exception eee){ } - throw new JSchException("ProxySOCKS4: "+e.toString()); + throw new JSchException("ProxySOCKS4: "+e.toString(), e); } } + @Override public InputStream getInputStream(){ return in; } + @Override public OutputStream getOutputStream(){ return out; } + @Override public Socket getSocket(){ return socket; } + @Override public void close(){ try{ if(in!=null)in.close(); 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 7c3f8e9a..4f255e11 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 @@ -53,8 +53,8 @@ public class ProxySOCKS5 implements Proxy{ String host=proxy_host; if(proxy_host.indexOf(':')!=-1){ try{ - host=proxy_host.substring(0, proxy_host.indexOf(':')); - port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1)); + host=proxy_host.substring(0, proxy_host.indexOf(':')); + port=Integer.parseInt(proxy_host.substring(proxy_host.indexOf(':')+1)); } catch(Exception e){ } @@ -70,6 +70,7 @@ public class ProxySOCKS5 implements Proxy{ this.user=user; this.passwd=passwd; } + @Override public void connect(SocketFactory socket_factory, String host, int port, int timeout) throws JSchException{ try{ if(socket_factory==null){ @@ -163,11 +164,11 @@ public class ProxySOCKS5 implements Proxy{ index=0; buf[index++]=1; buf[index++]=(byte)(user.length()); - System.arraycopy(Util.str2byte(user), 0, buf, index, user.length()); - index+=user.length(); + System.arraycopy(Util.str2byte(user), 0, buf, index, user.length()); + index+=user.length(); buf[index++]=(byte)(passwd.length()); - System.arraycopy(Util.str2byte(passwd), 0, buf, index, passwd.length()); - index+=passwd.length(); + System.arraycopy(Util.str2byte(passwd), 0, buf, index, passwd.length()); + index+=passwd.length(); out.write(buf, 0, index); @@ -195,8 +196,8 @@ public class ProxySOCKS5 implements Proxy{ if(!check){ try{ socket.close(); } - catch(Exception eee){ - } + catch(Exception eee){ + } throw new JSchException("fail in SOCKS5 proxy"); } @@ -282,8 +283,8 @@ public class ProxySOCKS5 implements Proxy{ if(buf[1]!=0){ try{ socket.close(); } - catch(Exception eee){ - } + catch(Exception eee){ + } throw new JSchException("ProxySOCKS5: server returns "+buf[1]); } @@ -291,13 +292,13 @@ public class ProxySOCKS5 implements Proxy{ case 1: //in.read(buf, 0, 6); fill(in, buf, 6); - break; + break; case 3: //in.read(buf, 0, 1); fill(in, buf, 1); //in.read(buf, 0, buf[0]+2); fill(in, buf, (buf[0]&0xff)+2); - break; + break; case 4: //in.read(buf, 0, 18); fill(in, buf, 18); @@ -313,14 +314,16 @@ public class ProxySOCKS5 implements Proxy{ catch(Exception eee){ } String message="ProxySOCKS5: "+e.toString(); - if(e instanceof Throwable) - throw new JSchException(message, (Throwable)e); - throw new JSchException(message); + throw new JSchException(message, e); } } + @Override public InputStream getInputStream(){ return in; } + @Override public OutputStream getOutputStream(){ return out; } + @Override public Socket getSocket(){ return socket; } + @Override public void close(){ try{ if(in!=null)in.close(); 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 a3bca8f8..38cd98a9 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 @@ -51,9 +51,9 @@ abstract class Request{ long start=System.currentTimeMillis(); long timeout=channel.connectTimeout; while(channel.isConnected() && channel.reply==-1){ - try{Thread.sleep(10);} - catch(Exception ee){ - } + try{Thread.sleep(10);} + catch(Exception ee){ + } if(timeout>0L && (System.currentTimeMillis()-start)>timeout){ channel.reply=0; @@ -62,7 +62,7 @@ abstract class Request{ } if(channel.reply==0){ - throw new JSchException("failed to send channel request"); + throw new JSchException("failed to send channel request"); } } } 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 9528c19c..d8834c53 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 @@ -30,6 +30,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; class RequestAgentForwarding extends Request{ + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 afc4d702..ad4afca4 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 @@ -36,8 +36,10 @@ class RequestEnv extends Request{ this.name=name; this.value=value; } + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); + setReply(false); Buffer buf=new Buffer(); Packet packet=new Packet(buf); @@ -46,7 +48,7 @@ class RequestEnv extends Request{ buf.putByte((byte) Session.SSH_MSG_CHANNEL_REQUEST); buf.putInt(channel.getRecipient()); buf.putString(Util.str2byte("env")); - buf.putByte((byte)(waitForReply() ? 1 : 0)); + buf.putByte((byte) 0); buf.putString(name); buf.putString(value); write(packet); 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 44e41a7d..bd7eefe4 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 @@ -34,6 +34,7 @@ class RequestExec extends Request{ RequestExec(byte[] command){ this.command=command; } + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 63b3125b..b4975438 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 @@ -56,6 +56,7 @@ class RequestPtyReq extends Request{ this.thp=thp; } + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 3ad5166b..481cef48 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 @@ -29,10 +29,11 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class RequestSftp extends Request{ +class RequestSftp extends Request{ RequestSftp(){ setReply(true); } + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 12ef31bf..699636d0 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 @@ -30,6 +30,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; class RequestShell extends Request{ + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 a5146712..7814c442 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 @@ -32,6 +32,7 @@ package com.jcraft.jsch; class RequestSignal extends Request{ private String signal="KILL"; public void setSignal(String foo){ signal=foo; } + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 a3edeae4..c766a52d 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 @@ -29,13 +29,14 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -public class RequestSubsystem extends Request{ +class RequestSubsystem extends Request{ private String subsystem=null; public void request(Session session, Channel channel, String subsystem, boolean want_reply) throws Exception{ setReply(want_reply); this.subsystem=subsystem; this.request(session, channel); } + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 d465f40c..8e4a2084 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 @@ -40,6 +40,7 @@ class RequestWindowChange extends Request{ this.width_pixels=wp; this.height_pixels=hp; } + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 3c87179a..74e2ea8a 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 @@ -33,6 +33,7 @@ class RequestX11 extends Request{ public void setCookie(String cookie){ ChannelX11.cookie=Util.str2byte(cookie); } + @Override public void request(Session session, Channel channel) throws Exception{ super.request(session, channel); 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 9f56c735..ceac6a62 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 @@ -29,11 +29,23 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; -import java.io.*; -import java.net.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.InterruptedIOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; import java.util.Vector; -public class Session implements Runnable{ +import javax.crypto.AEADBadTagException; + +public class Session{ // http://ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-01.txt static final int SSH_MSG_DISCONNECT= 1; @@ -42,6 +54,7 @@ public class Session implements Runnable{ static final int SSH_MSG_DEBUG= 4; static final int SSH_MSG_SERVICE_REQUEST= 5; static final int SSH_MSG_SERVICE_ACCEPT= 6; + static final int SSH_MSG_EXT_INFO= 7; static final int SSH_MSG_KEXINIT= 20; static final int SSH_MSG_NEWKEYS= 21; static final int SSH_MSG_KEXDH_INIT= 30; @@ -68,7 +81,7 @@ public class Session implements Runnable{ private static final int PACKET_MAX_SIZE = 256 * 1024; private byte[] V_S; // server version - private byte[] V_C=Util.str2byte("SSH-2.0-JSCH-"+JSch.VERSION); // client version + private byte[] V_C=Util.str2byte("SSH-2.0-JSCH_"+JSch.VERSION); // client version private byte[] I_C; // the payload of the client's SSH_MSG_KEXINIT private byte[] I_S; // the payload of the server's SSH_MSG_KEXINIT @@ -104,7 +117,7 @@ public class Session implements Runnable{ private volatile boolean isConnected=false; - private boolean isAuthed=false; + private volatile boolean isAuthed=false; private Thread connectThread=null; private Object lock=new Object(); @@ -126,7 +139,7 @@ public class Session implements Runnable{ 64 + // maximum mac length 32; // margin for deflater; deflater may inflate data - private java.util.Hashtable config=null; + private Hashtable config=null; private Proxy proxy=null; private UserInfo userinfo; @@ -137,6 +150,8 @@ public class Session implements Runnable{ private IdentityRepository identityRepository = null; private HostKeyRepository hostkeyRepository = null; + private volatile String[] serverSigAlgs = null; + private volatile boolean sshBugSigType74 = false; protected boolean daemon_thread=false; @@ -153,6 +168,7 @@ public class Session implements Runnable{ byte[] password=null; JSch jsch; + Logger logger; Session(JSch jsch, String username, String host, int port) throws JSchException{ super(); @@ -166,12 +182,7 @@ public class Session implements Runnable{ applyConfig(); if(this.username==null) { - try { - this.username=(String)(System.getProperties().get("user.name")); - } - catch(SecurityException e){ - // ignore e - } + this.username=Util.getSystemProperty("user.name"); } if(this.username==null) { @@ -191,48 +202,48 @@ public class Session implements Runnable{ io=new IO(); if(random==null){ try{ - Class c=Class.forName(getConfig("random")); - random=(Random)(c.newInstance()); + Class c=Class.forName(getConfig("random")).asSubclass(Random.class); + random=c.getDeclaredConstructor().newInstance(); } - catch(Exception e){ + catch(Exception e){ throw new JSchException(e.toString(), e); } } Packet.setRandom(random); - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Connecting to "+host+" port "+port); } - try { + try { int i, j; if(proxy==null){ InputStream in; OutputStream out; - if(socket_factory==null){ + if(socket_factory==null){ socket=Util.createSocket(host, port, connectTimeout); - in=socket.getInputStream(); - out=socket.getOutputStream(); - } - else{ + in=socket.getInputStream(); + out=socket.getOutputStream(); + } + else{ socket=socket_factory.createSocket(host, port); - in=socket_factory.getInputStream(socket); - out=socket_factory.getOutputStream(socket); - } - //if(timeout>0){ socket.setSoTimeout(timeout); } + in=socket_factory.getInputStream(socket); + out=socket_factory.getOutputStream(socket); + } + //if(timeout>0){ socket.setSoTimeout(timeout); } socket.setTcpNoDelay(true); io.setInputStream(in); io.setOutputStream(out); } else{ - synchronized(proxy){ + synchronized(proxy){ proxy.connect(socket_factory, host, port, connectTimeout); - io.setInputStream(proxy.getInputStream()); - io.setOutputStream(proxy.getOutputStream()); + io.setInputStream(proxy.getInputStream()); + io.setOutputStream(proxy.getOutputStream()); socket=proxy.getSocket(); - } + } } if(connectTimeout>0 && socket!=null){ @@ -241,19 +252,20 @@ public class Session implements Runnable{ isConnected=true; - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Connection established"); } jsch.addSession(this); { - // Some Cisco devices will miss to read '\n' if it is sent separately. - byte[] foo=new byte[V_C.length+1]; - System.arraycopy(V_C, 0, foo, 0, V_C.length); - foo[foo.length-1]=(byte)'\n'; - io.put(foo, 0, foo.length); + // Some Cisco devices will miss to read '\n' if it is sent separately. + byte[] foo=new byte[V_C.length+2]; + System.arraycopy(V_C, 0, foo, 0, V_C.length); + foo[foo.length-2]=(byte)'\r'; + foo[foo.length-1]=(byte)'\n'; + io.put(foo, 0, foo.length); } while(true){ @@ -262,7 +274,7 @@ public class Session implements Runnable{ while(i c=Class.forName(getConfig("userauth.none")).asSubclass(UserAuth.class); + ua=c.getDeclaredConstructor().newInstance(); } - catch(Exception e){ + catch(Exception e){ throw new JSchException(e.toString(), e); } @@ -419,8 +433,8 @@ public class Session implements Runnable{ loop: while(true){ - while(!auth && - cmethoda!=null && methodi c=null; if(getConfig("userauth."+method)!=null){ - c=Class.forName(getConfig("userauth."+method)); - ua=(UserAuth)(c.newInstance()); + c=Class.forName(getConfig("userauth."+method)).asSubclass(UserAuth.class); + ua=c.getDeclaredConstructor().newInstance(); } } catch(Exception e){ - if(JSch.getLogger().isEnabled(Logger.WARN)){ - JSch.getLogger().log(Logger.WARN, + if(getLogger().isEnabled(Logger.WARN)){ + getLogger().log(Logger.WARN, "failed to load "+method+" method"); } } - if(ua!=null){ + if(ua!=null){ auth_cancel=false; - try{ - auth=ua.start(this); - if(auth && - JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + try{ + auth=ua.start(this); + if(auth && + getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Authentication succeeded ("+method+")."); } - } - catch(JSchAuthCancelException ee){ - auth_cancel=true; - } - catch(JSchPartialAuthException ee){ + } + catch(JSchAuthCancelException ee){ + auth_cancel=true; + } + catch(JSchPartialAuthException ee){ String tmp = smethods; smethods=ee.getMethods(); smethoda=Util.split(smethods, ","); if(!tmp.equals(smethods)){ methodi=0; } - //System.err.println("PartialAuth: "+methods); - auth_cancel=false; - continue loop; - } - catch(RuntimeException ee){ - throw ee; - } - catch(JSchException ee){ + //System.err.println("PartialAuth: "+methods); + auth_cancel=false; + continue loop; + } + catch(RuntimeException ee){ throw ee; - } - catch(Exception ee){ - //System.err.println("ee: "+ee); // SSH_MSG_DISCONNECT: 2 Too many authentication failures - if(JSch.getLogger().isEnabled(Logger.WARN)){ - JSch.getLogger().log(Logger.WARN, + } + catch(JSchException ee){ + throw ee; + } + catch(Exception ee){ + //System.err.println("ee: "+ee); // SSH_MSG_DISCONNECT: 2 Too many authentication failures + if(getLogger().isEnabled(Logger.WARN)){ + getLogger().log(Logger.WARN, "an exception during authentication\n"+ee.toString()); } break loop; - } - } - } + } + } + } break; } if(!auth){ if(auth_failures >= max_auth_tries){ - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Login trials exceeds "+max_auth_tries); } } - if(auth_cancel) - throw new JSchException("Auth cancel"); - throw new JSchException("Auth fail"); + throw new JSchException((auth_cancel ? "Auth cancel" + : "Auth fail") + + " for methods '" + smethods + "'"); } if(socket!=null && (connectTimeout>0 || timeout>0)){ @@ -527,7 +541,7 @@ public class Session implements Runnable{ synchronized(lock){ if(isConnected){ - connectThread=new Thread(this); + connectThread=new Thread(this::run); connectThread.setName("Connect thread "+host+" session"); if(daemon_thread){ connectThread.setDaemon(daemon_thread); @@ -562,7 +576,7 @@ public class Session implements Runnable{ //e.printStackTrace(); if(e instanceof RuntimeException) throw (RuntimeException)e; if(e instanceof JSchException) throw (JSchException)e; - throw new JSchException("Session.connect: "+e); + throw new JSchException("Session.connect: "+e, e); } finally{ Util.bzero(this.password); @@ -585,9 +599,11 @@ public class Session implements Runnable{ send_kexinit(); } - guess=KeyExchange.guess(I_S, I_C); - if(guess==null){ - throw new JSchException("Algorithm negotiation fail"); + guess=KeyExchange.guess(this, I_S, I_C); + + if(guess[KeyExchange.PROPOSAL_KEX_ALGS].equals("ext-info-c") || + guess[KeyExchange.PROPOSAL_KEX_ALGS].equals("ext-info-s")){ + throw new JSchException("Invalid Kex negotiated: " + guess[KeyExchange.PROPOSAL_KEX_ALGS]); } if(!isAuthed && @@ -598,19 +614,23 @@ public class Session implements Runnable{ KeyExchange kex=null; try{ - Class c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_KEX_ALGS])); - kex=(KeyExchange)(c.newInstance()); + Class c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_KEX_ALGS])).asSubclass(KeyExchange.class); + kex=c.getDeclaredConstructor().newInstance(); } - catch(Exception e){ + catch(Exception | NoClassDefFoundError e){ throw new JSchException(e.toString(), e); } - kex.init(this, V_S, V_C, I_S, I_C); + kex.doInit(this, V_S, V_C, I_S, I_C); return kex; } private volatile boolean in_kex=false; private volatile boolean in_prompt=false; + private volatile String[] not_available_shks=null; + public String[] getUnavailableSignatures() { + return not_available_shks; + } public void rekey() throws Exception { send_kexinit(); } @@ -620,33 +640,146 @@ public class Session implements Runnable{ String cipherc2s=getConfig("cipher.c2s"); String ciphers2c=getConfig("cipher.s2c"); - String[] not_available_ciphers=checkCiphers(getConfig("CheckCiphers")); if(not_available_ciphers!=null && not_available_ciphers.length>0){ + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "cipher.c2s proposal before removing unavailable algos is: " + cipherc2s); + getLogger().log(Logger.DEBUG, + "cipher.s2c proposal before removing unavailable algos is: " + ciphers2c); + } + cipherc2s=Util.diffString(cipherc2s, not_available_ciphers); ciphers2c=Util.diffString(ciphers2c, not_available_ciphers); if(cipherc2s==null || ciphers2c==null){ throw new JSchException("There are not any available ciphers."); } + + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "cipher.c2s proposal after removing unavailable algos is: " + cipherc2s); + getLogger().log(Logger.DEBUG, + "cipher.s2c proposal after removing unavailable algos is: " + ciphers2c); + } + } + + String macc2s=getConfig("mac.c2s"); + String macs2c=getConfig("mac.s2c"); + String[] not_available_macs=checkMacs(getConfig("CheckMacs")); + if(not_available_macs!=null && not_available_macs.length>0){ + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "mac.c2s proposal before removing unavailable algos is: " + macc2s); + getLogger().log(Logger.DEBUG, + "mac.s2c proposal before removing unavailable algos is: " + macs2c); + } + + macc2s=Util.diffString(macc2s, not_available_macs); + macs2c=Util.diffString(macs2c, not_available_macs); + if(macc2s==null || macs2c==null){ + throw new JSchException("There are not any available macs."); + } + + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "mac.c2s proposal after removing unavailable algos is: " + macc2s); + getLogger().log(Logger.DEBUG, + "mac.s2c proposal after removing unavailable algos is: " + macs2c); + } } String kex=getConfig("kex"); String[] not_available_kexes=checkKexes(getConfig("CheckKexes")); if(not_available_kexes!=null && not_available_kexes.length>0){ + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "kex proposal before removing unavailable algos is: " + kex); + } + kex=Util.diffString(kex, not_available_kexes); if(kex==null){ throw new JSchException("There are not any available kexes."); } + + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "kex proposal after removing unavailable algos is: " + kex); + } + } + + String enable_server_sig_algs=getConfig("enable_server_sig_algs"); + if(enable_server_sig_algs.equals("yes") && !isAuthed){ + kex+=",ext-info-c"; } String server_host_key = getConfig("server_host_key"); String[] not_available_shks = checkSignatures(getConfig("CheckSignatures")); + // Cache for UserAuthPublicKey + this.not_available_shks = not_available_shks; if(not_available_shks!=null && not_available_shks.length>0){ + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "server_host_key proposal before removing unavailable algos is: " + server_host_key); + } + 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."); } + + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "server_host_key proposal after removing unavailable algos is: " + server_host_key); + } + } + + String prefer_hkr=getConfig("prefer_known_host_key_types"); + if(prefer_hkr.equals("yes")){ + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "server_host_key proposal before known_host reordering is: " + server_host_key); + } + + HostKeyRepository hkr=getHostKeyRepository(); + String chost=host; + if(hostKeyAlias!=null){ + chost=hostKeyAlias; + } + if(hostKeyAlias==null && port!=22){ + chost=("["+chost+"]:"+port); + } + HostKey[] hks=hkr.getHostKey(chost, null); + if(hks!=null && hks.length>0){ + List pref_shks=new ArrayList<>(); + List shks=new ArrayList<>(Arrays.asList(Util.split(server_host_key, ","))); + Iterator it=shks.iterator(); + while(it.hasNext()){ + String algo=it.next(); + String type=algo; + if(type.equals("rsa-sha2-256") || type.equals("rsa-sha2-512") || + type.equals("ssh-rsa-sha224@ssh.com") || type.equals("ssh-rsa-sha256@ssh.com") || + type.equals("ssh-rsa-sha384@ssh.com") || type.equals("ssh-rsa-sha512@ssh.com")){ + type="ssh-rsa"; + } + for(HostKey hk : hks){ + if(hk.getType().equals(type)){ + pref_shks.add(algo); + it.remove(); + break; + } + } + } + if(pref_shks.size()>0){ + pref_shks.addAll(shks); + server_host_key=String.join(",", pref_shks); + } + } + + if(getLogger().isEnabled(Logger.DEBUG)){ + getLogger().log(Logger.DEBUG, + "server_host_key proposal after known_host reordering is: " + server_host_key); + } } in_kex=true; @@ -690,8 +823,8 @@ public class Session implements Runnable{ write(packet); - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "SSH_MSG_KEXINIT sent"); } } @@ -702,8 +835,8 @@ public class Session implements Runnable{ buf.putByte((byte)SSH_MSG_NEWKEYS); write(packet); - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "SSH_MSG_NEWKEYS sent"); } } @@ -745,7 +878,7 @@ public class Session implements Runnable{ i==HostKeyRepository.CHANGED){ String file=null; synchronized(hkr){ - file=hkr.getKnownHostsRepositoryID(); + file=hkr.getKnownHostsRepositoryID(); } if(file==null){file="known_hosts";} @@ -776,7 +909,7 @@ key_fprint+".\n"+ } synchronized(hkr){ - hkr.remove(chost, + hkr.remove(chost, kex.getKeyAlgorithName(), null); insert=true; @@ -786,29 +919,29 @@ key_fprint+".\n"+ if((shkc.equals("ask") || shkc.equals("yes")) && (i!=HostKeyRepository.OK) && !insert){ if(shkc.equals("yes")){ - throw new JSchException("reject HostKey: "+host); + throw new JSchException("reject HostKey: "+host); } //System.err.println("finger-print: "+key_fprint); if(userinfo!=null){ - boolean foo=userinfo.promptYesNo( + boolean foo=userinfo.promptYesNo( "The authenticity of host '"+host+"' can't be established.\n"+ key_type+" key fingerprint is "+key_fprint+".\n"+ "Are you sure you want to continue connecting?" - ); - if(!foo){ - throw new JSchException("reject HostKey: "+host); - } - insert=true; + ); + if(!foo){ + throw new JSchException("reject HostKey: "+host); + } + insert=true; } else{ - if(i==HostKeyRepository.NOT_INCLUDED) - throw new JSchException("UnknownHostKey: "+host+". "+key_type+" key fingerprint is "+key_fprint); - else + if(i==HostKeyRepository.NOT_INCLUDED) + throw new JSchException("UnknownHostKey: "+host+". "+key_type+" key fingerprint is "+key_fprint); + else throw new JSchException("HostKey has been changed: "+host); } } - if(shkc.equals("no") && + if(shkc.equals("no") && HostKeyRepository.NOT_INCLUDED==i){ insert=true; } @@ -816,9 +949,9 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ if(i==HostKeyRepository.OK){ HostKey[] keys = hkr.getHostKey(chost, kex.getKeyAlgorithName()); - String _key= Util.byte2str(Util.toBase64(K_S, 0, K_S.length)); + String _key= Util.byte2str(Util.toBase64(K_S, 0, K_S.length, true)); for(int j=0; j< keys.length; j++){ - if(keys[i].getKey().equals(_key) && + if(keys[j].getKey().equals(_key) && keys[j].getMarker().equals("@revoked")){ if(userinfo!=null){ userinfo.showMessage( @@ -826,8 +959,8 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ "This could mean that a stolen key is being used to "+ "impersonate this host."); } - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Host '"+host+"' has provided revoked key."); } throw new JSchException("revoked HostKey: "+host); @@ -836,20 +969,20 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ } if(i==HostKeyRepository.OK && - JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Host '"+host+"' is known and matches the "+key_type+" host key"); } if(insert && - JSch.getLogger().isEnabled(Logger.WARN)){ - JSch.getLogger().log(Logger.WARN, + getLogger().isEnabled(Logger.WARN)){ + getLogger().log(Logger.WARN, "Permanently added '"+host+"' ("+key_type+") to the list of known hosts."); } if(insert){ synchronized(hkr){ - hkr.add(hostkey, userinfo); + hkr.add(hostkey, userinfo); } } } @@ -861,7 +994,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ throw new JSchException("session is down"); } try{ - Channel channel=Channel.getChannel(type); + Channel channel=Channel.getChannel(type, this); addChannel(channel); channel.init(); if(channel instanceof ChannelSession){ @@ -876,7 +1009,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ } // encode will bin invoked in write with synchronization. - public void encode(Packet packet) throws Exception{ + void encode(Packet packet) throws Exception{ //System.err.println("encode: "+packet.buffer.getCommand()); //System.err.println(" "+packet.buffer.index); //if(packet.buffer.getCommand()==96){ @@ -884,34 +1017,55 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ //} if(deflater!=null){ compress_len[0]=packet.buffer.index; - packet.buffer.buffer=deflater.compress(packet.buffer.buffer, + packet.buffer.buffer=deflater.compress(packet.buffer.buffer, 5, compress_len); packet.buffer.index=compress_len[0]; } + int bsize=8; if(c2scipher!=null){ - //packet.padding(c2scipher.getIVSize()); - packet.padding(c2scipher_size); - int pad=packet.buffer.buffer[4]; - synchronized(random){ - random.fill(packet.buffer.buffer, packet.buffer.index-pad, pad); - } - } - else{ - packet.padding(8); + //bsize=c2scipher.getIVSize(); + bsize=c2scipher_size; } + boolean isChaCha20=(c2scipher!=null && c2scipher.isChaCha20()); + boolean isAEAD=(c2scipher!=null && c2scipher.isAEAD()); + boolean isEtM=(!isChaCha20 && !isAEAD && c2scipher!=null && c2smac!=null && c2smac.isEtM()); + packet.padding(bsize, !(isChaCha20 || isAEAD || isEtM)); - if(c2smac!=null){ + byte[] buf=packet.buffer.buffer; + if(isChaCha20){ + // init cipher with seq number + c2scipher.update(seqo); + //encrypt packet length field + c2scipher.update(buf, 0, 4, buf, 0); + //encrypt rest of packet & add tag + c2scipher.doFinal(buf, 0, packet.buffer.index, buf, 0); + packet.buffer.skip(c2scipher.getTagSize()); + } + else if(isAEAD){ + c2scipher.updateAAD(buf, 0, 4); + c2scipher.doFinal(buf, 4, packet.buffer.index-4, buf, 4); + packet.buffer.skip(c2scipher.getTagSize()); + } + else if(isEtM){ + c2scipher.update(buf, 4, packet.buffer.index-4, buf, 4); c2smac.update(seqo); c2smac.update(packet.buffer.buffer, 0, packet.buffer.index); c2smac.doFinal(packet.buffer.buffer, packet.buffer.index); - } - if(c2scipher!=null){ - byte[] buf=packet.buffer.buffer; - c2scipher.update(buf, 0, packet.buffer.index, buf, 0); - } - if(c2smac!=null){ packet.buffer.skip(c2smac.getBlockSize()); } + else{ + if(c2smac!=null){ + c2smac.update(seqo); + c2smac.update(packet.buffer.buffer, 0, packet.buffer.index); + c2smac.doFinal(packet.buffer.buffer, packet.buffer.index); + } + if(c2scipher!=null){ + c2scipher.update(buf, 0, packet.buffer.index, buf, 0); + } + if(c2smac!=null){ + packet.buffer.skip(c2smac.getBlockSize()); + } + } } int[] uncompress_len=new int[1]; @@ -919,78 +1073,180 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ private int s2ccipher_size=8; private int c2scipher_size=8; - public Buffer read(Buffer buf) throws Exception{ + Buffer read(Buffer buf) throws Exception{ int j=0; + boolean isChaCha20=(s2ccipher!=null && s2ccipher.isChaCha20()); + boolean isAEAD=(s2ccipher!=null && s2ccipher.isAEAD()); + boolean isEtM=(!isChaCha20 && !isAEAD && s2ccipher!=null && s2cmac!=null && s2cmac.isEtM()); while(true){ buf.reset(); - io.getByte(buf.buffer, buf.index, s2ccipher_size); - buf.index+=s2ccipher_size; - if(s2ccipher!=null){ - s2ccipher.update(buf.buffer, 0, s2ccipher_size, buf.buffer, 0); - } - j=((buf.buffer[0]<<24)&0xff000000)| - ((buf.buffer[1]<<16)&0x00ff0000)| - ((buf.buffer[2]<< 8)&0x0000ff00)| - ((buf.buffer[3] )&0x000000ff); - // RFC 4253 6.1. Maximum Packet Length - if(j<5 || j>PACKET_MAX_SIZE){ - start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE); - } - int need = j+4-s2ccipher_size; - //if(need<0){ - // throw new IOException("invalid data"); - //} - if((buf.index+need)>buf.buffer.length){ - byte[] foo=new byte[buf.index+need]; - System.arraycopy(buf.buffer, 0, foo, 0, buf.index); - buf.buffer=foo; - } - - if((need%s2ccipher_size)!=0){ - String message="Bad packet length "+need; - if(JSch.getLogger().isEnabled(Logger.FATAL)){ - JSch.getLogger().log(Logger.FATAL, message); + if(isChaCha20){ + //read encrypted packet length field + io.getByte(buf.buffer, buf.index, 4); + buf.index+=4; + // init cipher with seq number + s2ccipher.update(seqi); + //decrypt packet length field + byte[] tmp=new byte[4]; + s2ccipher.update(buf.buffer, 0, 4, tmp, 0); + j=((tmp[0]<<24)&0xff000000)| + ((tmp[1]<<16)&0x00ff0000)| + ((tmp[2]<< 8)&0x0000ff00)| + ((tmp[3] )&0x000000ff); + // RFC 4253 6.1. Maximum Packet Length + if(j<5 || j>PACKET_MAX_SIZE){ + start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); + } + j+=s2ccipher.getTagSize(); + if((buf.index+j)>buf.buffer.length){ + byte[] foo=new byte[buf.index+j]; + System.arraycopy(buf.buffer, 0, foo, 0, buf.index); + buf.buffer=foo; } - start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE-s2ccipher_size); - } - if(need>0){ - io.getByte(buf.buffer, buf.index, need); buf.index+=(need); - if(s2ccipher!=null){ - s2ccipher.update(buf.buffer, s2ccipher_size, need, buf.buffer, s2ccipher_size); - } - } - - if(s2cmac!=null){ - s2cmac.update(seqi); - s2cmac.update(buf.buffer, 0, buf.index); - - s2cmac.doFinal(s2cmac_result1, 0); - io.getByte(s2cmac_result2, 0, s2cmac_result2.length); - if(!java.util.Arrays.equals(s2cmac_result1, s2cmac_result2)){ - if(need > PACKET_MAX_SIZE){ - throw new IOException("MAC Error"); + if((j%s2ccipher_size)!=0){ + String message="Bad packet length "+j; + if(getLogger().isEnabled(Logger.FATAL)){ + getLogger().log(Logger.FATAL, message); } - start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE-need); - continue; - } + start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE-s2ccipher_size); + } + + io.getByte(buf.buffer, buf.index, j); + // subtract tag size now that whole packet has been fetched + j -= s2ccipher.getTagSize(); buf.index+=(j); + try { + s2ccipher.doFinal(buf.buffer, 0, j+4, buf.buffer, 0); + } + catch(AEADBadTagException e){ + throw new JSchException("Packet corrupt", e); + } + // overwrite encrypted packet length field with decrypted version + System.arraycopy(tmp, 0, buf.buffer, 0, 4); + } + else if(isAEAD || isEtM){ + io.getByte(buf.buffer, buf.index, 4); + buf.index+=4; + j=((buf.buffer[0]<<24)&0xff000000)| + ((buf.buffer[1]<<16)&0x00ff0000)| + ((buf.buffer[2]<< 8)&0x0000ff00)| + ((buf.buffer[3] )&0x000000ff); + // RFC 4253 6.1. Maximum Packet Length + if(j<5 || j>PACKET_MAX_SIZE){ + start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); + } + if(isAEAD){ + j+=s2ccipher.getTagSize(); + } + if((buf.index+j)>buf.buffer.length){ + byte[] foo=new byte[buf.index+j]; + System.arraycopy(buf.buffer, 0, foo, 0, buf.index); + buf.buffer=foo; + } + + if((j%s2ccipher_size)!=0){ + String message="Bad packet length "+j; + if(getLogger().isEnabled(Logger.FATAL)){ + getLogger().log(Logger.FATAL, message); + } + start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE-s2ccipher_size); + } + + io.getByte(buf.buffer, buf.index, j); buf.index+=(j); + + if(isAEAD){ + try { + s2ccipher.updateAAD(buf.buffer, 0, 4); + s2ccipher.doFinal(buf.buffer, 4, j, buf.buffer, 4); + } + catch(AEADBadTagException e){ + throw new JSchException("Packet corrupt", e); + } + // don't include AEAD tag size in buf so that decompression works below + buf.index -= s2ccipher.getTagSize(); + } + else{ + s2cmac.update(seqi); + s2cmac.update(buf.buffer, 0, buf.index); + s2cmac.doFinal(s2cmac_result1, 0); + + io.getByte(s2cmac_result2, 0, s2cmac_result2.length); + if(!Util.arraysequals(s2cmac_result1, s2cmac_result2)){ + throw new JSchException("Packet corrupt"); + } + s2ccipher.update(buf.buffer, 4, j, buf.buffer, 4); + } + } + else{ + io.getByte(buf.buffer, buf.index, s2ccipher_size); + buf.index+=s2ccipher_size; + if(s2ccipher!=null){ + s2ccipher.update(buf.buffer, 0, s2ccipher_size, buf.buffer, 0); + } + j=((buf.buffer[0]<<24)&0xff000000)| + ((buf.buffer[1]<<16)&0x00ff0000)| + ((buf.buffer[2]<< 8)&0x0000ff00)| + ((buf.buffer[3] )&0x000000ff); + // RFC 4253 6.1. Maximum Packet Length + if(j<5 || j>PACKET_MAX_SIZE){ + start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE); + } + int need = j+4-s2ccipher_size; + //if(need<0){ + // throw new IOException("invalid data"); + //} + if((buf.index+need)>buf.buffer.length){ + byte[] foo=new byte[buf.index+need]; + System.arraycopy(buf.buffer, 0, foo, 0, buf.index); + buf.buffer=foo; + } + + if((need%s2ccipher_size)!=0){ + String message="Bad packet length "+need; + if(getLogger().isEnabled(Logger.FATAL)){ + getLogger().log(Logger.FATAL, message); + } + start_discard(buf, s2ccipher, s2cmac, 0, PACKET_MAX_SIZE-s2ccipher_size); + } + + if(need>0){ + io.getByte(buf.buffer, buf.index, need); buf.index+=(need); + if(s2ccipher!=null){ + s2ccipher.update(buf.buffer, s2ccipher_size, need, buf.buffer, s2ccipher_size); + } + } + + if(s2cmac!=null){ + s2cmac.update(seqi); + s2cmac.update(buf.buffer, 0, buf.index); + s2cmac.doFinal(s2cmac_result1, 0); + + io.getByte(s2cmac_result2, 0, s2cmac_result2.length); + if(!Util.arraysequals(s2cmac_result1, s2cmac_result2)){ + if(need+s2ccipher_size > PACKET_MAX_SIZE){ + throw new IOException("MAC Error"); + } + start_discard(buf, s2ccipher, s2cmac, buf.index, PACKET_MAX_SIZE-need-s2ccipher_size); + continue; + } + } } seqi++; if(inflater!=null){ //inflater.uncompress(buf); - int pad=buf.buffer[4]; - uncompress_len[0]=buf.index-5-pad; - byte[] foo=inflater.uncompress(buf.buffer, 5, uncompress_len); - if(foo!=null){ - buf.buffer=foo; - buf.index=5+uncompress_len[0]; - } - else{ - System.err.println("fail in inflater"); - break; - } + int pad=buf.buffer[4]; + uncompress_len[0]=buf.index-5-pad; + byte[] foo=inflater.uncompress(buf.buffer, 5, uncompress_len); + if(foo!=null){ + buf.buffer=foo; + buf.index=5+uncompress_len[0]; + } + else{ + System.err.println("fail in inflater"); + break; + } } int type=buf.getCommand()&0xff; @@ -998,23 +1254,23 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ if(type==SSH_MSG_DISCONNECT){ buf.rewind(); buf.getInt();buf.getShort(); - int reason_code=buf.getInt(); - byte[] description=buf.getString(); - byte[] language_tag=buf.getString(); - throw new JSchException("SSH_MSG_DISCONNECT: "+ - reason_code+ - " "+Util.byte2str(description)+ - " "+Util.byte2str(language_tag)); - //break; + int reason_code=buf.getInt(); + byte[] description=buf.getString(); + byte[] language_tag=buf.getString(); + throw new JSchException("SSH_MSG_DISCONNECT: "+ + reason_code+ + " "+Util.byte2str(description)+ + " "+Util.byte2str(language_tag)); + //break; } else if(type==SSH_MSG_IGNORE){ } else if(type==SSH_MSG_UNIMPLEMENTED){ buf.rewind(); buf.getInt();buf.getShort(); - int reason_id=buf.getInt(); - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + int reason_id=buf.getInt(); + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Received SSH_MSG_UNIMPLEMENTED for "+reason_id); } } @@ -1022,23 +1278,75 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ buf.rewind(); buf.getInt();buf.getShort(); /* - byte always_display=(byte)buf.getByte(); - byte[] message=buf.getString(); - byte[] language_tag=buf.getString(); - System.err.println("SSH_MSG_DEBUG:"+ - " "+Util.byte2str(message)+ - " "+Util.byte2str(language_tag)); + byte always_display=(byte)buf.getByte(); + byte[] message=buf.getString(); + byte[] language_tag=buf.getString(); + System.err.println("SSH_MSG_DEBUG:"+ + " "+Util.byte2str(message)+ + " "+Util.byte2str(language_tag)); */ } else if(type==SSH_MSG_CHANNEL_WINDOW_ADJUST){ buf.rewind(); buf.getInt();buf.getShort(); - Channel c=Channel.getChannel(buf.getInt(), this); - if(c==null){ - } - else{ - c.addRemoteWindowSize(buf.getUInt()); - } + Channel c=Channel.getChannel(buf.getInt(), this); + if(c==null){ + } + else{ + c.addRemoteWindowSize(buf.getUInt()); + } + } + else if(type==SSH_MSG_EXT_INFO){ + buf.rewind(); + buf.getInt();buf.getShort(); + boolean ignore=false; + String enable_server_sig_algs=getConfig("enable_server_sig_algs"); + if(!enable_server_sig_algs.equals("yes")){ + ignore=true; + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO while enable_server_sig_algs != yes"); + } + } + else if(isAuthed){ + ignore=true; + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO received after SSH_MSG_USERAUTH_SUCCESS"); + } + } + else if(in_kex){ + ignore=true; + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "Ignoring SSH_MSG_EXT_INFO received before SSH_MSG_NEWKEYS"); + } + } + else{ + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "SSH_MSG_EXT_INFO received"); + } + } + long num_extensions=buf.getUInt(); + for(long i=0; i"); + } + if(sshBugSigType74){ + if(!foo.isEmpty()){ + foo+=",rsa-sha2-256,rsa-sha2-512"; + } + else{ + foo="rsa-sha2-256,rsa-sha2-512"; + } + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "OpenSSH 7.4 detected: adding rsa-sha2-256 & rsa-sha2-512 to server-sig-algs"); + } + } + serverSigAlgs=Util.split(foo, ","); + } + } } else if(type==UserAuth.SSH_MSG_USERAUTH_SUCCESS){ isAuthed=true; @@ -1059,35 +1367,46 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ return buf; } - private void start_discard(Buffer buf, Cipher cipher, MAC mac, - int packet_length, int discard) throws JSchException, IOException{ - MAC discard_mac = null; - - if(!cipher.isCBC()){ + private void start_discard(Buffer buf, Cipher cipher, MAC mac, + int mac_already, int discard) throws JSchException{ + if(!cipher.isCBC() || (mac != null && mac.isEtM())){ throw new JSchException("Packet corrupt"); } - if(packet_length!=PACKET_MAX_SIZE && mac != null){ - discard_mac = mac; + if(mac != null){ + mac.update(seqi); + mac.update(buf.buffer, 0, mac_already); } - discard -= buf.index; - - while(discard>0){ - buf.reset(); - int len = discard>buf.buffer.length ? buf.buffer.length : discard; - io.getByte(buf.buffer, 0, len); - if(discard_mac!=null){ - discard_mac.update(buf.buffer, 0, len); + IOException ioe=null; + try{ + while(discard>0){ + buf.reset(); + int len = discard>buf.buffer.length ? buf.buffer.length : discard; + io.getByte(buf.buffer, 0, len); + if(mac!=null){ + mac.update(buf.buffer, 0, len); + } + discard -= len; + } + } + catch(IOException e){ + ioe = e; + if(getLogger().isEnabled(Logger.ERROR)){ + getLogger().log(Logger.ERROR, + "start_discard finished early due to " + e.getMessage()); } - discard -= len; } - if(discard_mac!=null){ - discard_mac.doFinal(buf.buffer, 0); + if(mac!=null){ + mac.doFinal(buf.buffer, 0); } - throw new JSchException("Packet corrupt"); + JSchException e = new JSchException("Packet corrupt"); + if(ioe!=null){ + e.addSuppressed(ioe); + } + throw e; } byte[] getSessionId(){ @@ -1148,12 +1467,13 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ MACs2c=hash.digest(); try{ - Class c; + Class cc; + Class cm; String method; - + method=guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC]; - c=Class.forName(getConfig(method)); - s2ccipher=(Cipher)(c.newInstance()); + cc=Class.forName(getConfig(method)).asSubclass(Cipher.class); + s2ccipher=cc.getDeclaredConstructor().newInstance(); while(s2ccipher.getBlockSize()>Es2c.length){ buf.reset(); buf.putMPInt(K); @@ -1162,25 +1482,27 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ hash.update(buf.buffer, 0, buf.index); byte[] foo=hash.digest(); byte[] bar=new byte[Es2c.length+foo.length]; - System.arraycopy(Es2c, 0, bar, 0, Es2c.length); - System.arraycopy(foo, 0, bar, Es2c.length, foo.length); - Es2c=bar; + System.arraycopy(Es2c, 0, bar, 0, Es2c.length); + System.arraycopy(foo, 0, bar, Es2c.length, foo.length); + Es2c=bar; } s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c); s2ccipher_size=s2ccipher.getIVSize(); - method=guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC]; - c=Class.forName(getConfig(method)); - s2cmac=(MAC)(c.newInstance()); - MACs2c = expandKey(buf, K, H, MACs2c, hash, s2cmac.getBlockSize()); - s2cmac.init(MACs2c); - //mac_buf=new byte[s2cmac.getBlockSize()]; - s2cmac_result1=new byte[s2cmac.getBlockSize()]; - s2cmac_result2=new byte[s2cmac.getBlockSize()]; + if(!s2ccipher.isAEAD()){ + method=guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC]; + cm=Class.forName(getConfig(method)).asSubclass(MAC.class); + s2cmac=cm.getDeclaredConstructor().newInstance(); + MACs2c = expandKey(buf, K, H, MACs2c, hash, s2cmac.getBlockSize()); + s2cmac.init(MACs2c); + //mac_buf=new byte[s2cmac.getBlockSize()]; + s2cmac_result1=new byte[s2cmac.getBlockSize()]; + s2cmac_result2=new byte[s2cmac.getBlockSize()]; + } method=guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS]; - c=Class.forName(getConfig(method)); - c2scipher=(Cipher)(c.newInstance()); + cc=Class.forName(getConfig(method)).asSubclass(Cipher.class); + c2scipher=cc.getDeclaredConstructor().newInstance(); while(c2scipher.getBlockSize()>Ec2s.length){ buf.reset(); buf.putMPInt(K); @@ -1189,18 +1511,20 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ hash.update(buf.buffer, 0, buf.index); byte[] foo=hash.digest(); byte[] bar=new byte[Ec2s.length+foo.length]; - System.arraycopy(Ec2s, 0, bar, 0, Ec2s.length); - System.arraycopy(foo, 0, bar, Ec2s.length, foo.length); - Ec2s=bar; + System.arraycopy(Ec2s, 0, bar, 0, Ec2s.length); + System.arraycopy(foo, 0, bar, Ec2s.length, foo.length); + Ec2s=bar; } c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s); c2scipher_size=c2scipher.getIVSize(); - method=guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS]; - c=Class.forName(getConfig(method)); - c2smac=(MAC)(c.newInstance()); - MACc2s = expandKey(buf, K, H, MACc2s, hash, c2smac.getBlockSize()); - c2smac.init(MACc2s); + if(!c2scipher.isAEAD()){ + method=guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS]; + cm=Class.forName(getConfig(method)).asSubclass(MAC.class); + c2smac=cm.getDeclaredConstructor().newInstance(); + MACc2s = expandKey(buf, K, H, MACc2s, hash, c2smac.getBlockSize()); + c2smac.init(MACc2s); + } method=guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]; initDeflater(method); @@ -1208,11 +1532,11 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ method=guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]; initInflater(method); } - catch(Exception e){ + catch(Exception | NoClassDefFoundError e){ if(e instanceof JSchException) throw e; throw new JSchException(e.toString(), e); - //System.err.println("updatekeys: "+e); + //System.err.println("updatekeys: "+e); } } @@ -1250,7 +1574,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ return result; } - /*public*/ /*synchronized*/ void write(Packet packet, Channel c, int length) throws Exception{ + /*synchronized*/ void write(Packet packet, Channel c, int length) throws Exception{ long t = getTimeout(); while(true){ if(in_kex){ @@ -1258,17 +1582,17 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ throw new JSchException("timeout in waiting for rekeying process."); } try{Thread.sleep(10);} - catch(java.lang.InterruptedException e){}; + catch(InterruptedException e){}; continue; } synchronized(c){ if(c.rwsize0){ - long len=c.rwsize; + if(c.rwsize>0){ + long len=c.rwsize; if(len>length){ len=length; } if(len!=length){ - s=packet.shift((int)len, + s=packet.shift((int)len, (c2scipher!=null ? c2scipher_size : 8), (c2smac!=null ? c2smac.getBlockSize() : 0)); } - command=packet.buffer.getCommand(); - recipient=c.getRecipient(); - length-=len; - c.rwsize-=len; - sendit=true; - } + command=packet.buffer.getCommand(); + recipient=c.getRecipient(); + length-=len; + c.rwsize-=len; + sendit=true; + } } if(sendit){ - _write(packet); + _write(packet); if(length==0){ return; } - packet.unshift(command, recipient, s, length); + packet.unshift(command, recipient, s, length); } synchronized(c){ @@ -1328,12 +1652,12 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ break; } - //try{ + //try{ //System.out.println("1wait: "+c.rwsize); // c.notifyme++; - // c.wait(100); + // c.wait(100); //} - //catch(java.lang.InterruptedException e){ + //catch(InterruptedException e){ //} //finally{ // c.notifyme--; @@ -1343,7 +1667,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ _write(packet); } - public void write(Packet packet) throws Exception{ + void write(Packet packet) throws Exception{ // System.err.println("in_kex="+in_kex+" "+(packet.buffer.getCommand())); long t = getTimeout(); while(in_kex){ @@ -1367,7 +1691,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ break; } try{Thread.sleep(10);} - catch(java.lang.InterruptedException e){}; + catch(InterruptedException e){}; } _write(packet); } @@ -1383,8 +1707,8 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ } Runnable thread; - public void run(){ - thread=this; + void run(){ + thread=this::run; byte[] foo; Buffer buf=new Buffer(); @@ -1398,7 +1722,7 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ int stimeout=0; try{ while(isConnected && - thread!=null){ + thread!=null){ try{ buf=read(buf); stimeout=0; @@ -1416,149 +1740,149 @@ key_type+" key fingerprint is "+key_fprint+".\n"+ throw ee; } - int msgType=buf.getCommand()&0xff; + int msgType=buf.getCommand()&0xff; - if(kex!=null && kex.getState()==msgType){ + if(kex!=null && kex.getState()==msgType){ kex_start_time=System.currentTimeMillis(); - boolean result=kex.next(buf); - if(!result){ - throw new JSchException("verify: "+result); - } - continue; - } + boolean result=kex.next(buf); + if(!result){ + throw new JSchException("verify: "+result); + } + continue; + } switch(msgType){ - case SSH_MSG_KEXINIT: + case SSH_MSG_KEXINIT: //System.err.println("KEXINIT"); - kex=receive_kexinit(buf); - break; + kex=receive_kexinit(buf); + break; - case SSH_MSG_NEWKEYS: + case SSH_MSG_NEWKEYS: //System.err.println("NEWKEYS"); send_newkeys(); - receive_newkeys(buf, kex); - kex=null; - break; + receive_newkeys(buf, kex); + kex=null; + break; - case SSH_MSG_CHANNEL_DATA: - buf.getInt(); - buf.getByte(); - buf.getByte(); - i=buf.getInt(); - channel=Channel.getChannel(i, this); - foo=buf.getString(start, length); - if(channel==null){ - break; - } + case SSH_MSG_CHANNEL_DATA: + buf.getInt(); + buf.getByte(); + buf.getByte(); + i=buf.getInt(); + channel=Channel.getChannel(i, this); + foo=buf.getString(start, length); + if(channel==null){ + break; + } if(length[0]==0){ - break; + break; } try{ - channel.write(foo, start[0], length[0]); + channel.write(foo, start[0], length[0]); } catch(Exception e){ //System.err.println(e); try{channel.disconnect();}catch(Exception ee){} break; } - int len=length[0]; - channel.setLocalWindowSize(channel.lwsize-len); - if(channel.lwsizelport is 0, the tcp port will be allocated. - * @param lport local port for local port forwarding + * @param lport local port for local port forwarding * @param host host address for local port forwarding * @param rport remote port number for local port forwarding * @return an allocated local TCP port number @@ -1799,7 +2123,7 @@ break; * null, the listening port will be bound for local use only. * If lport is 0, the tcp port will be allocated. * @param bind_address bind address for local port forwarding - * @param lport local port for local port forwarding + * @param lport local port for local port forwarding * @param host host address for local port forwarding * @param rport remote port number for local port forwarding * @return an allocated local TCP port number @@ -1817,7 +2141,7 @@ break; * null, the listening port will be bound for local use only. * If lport is 0, the tcp port will be allocated. * @param bind_address bind address for local port forwarding - * @param lport local port for local port forwarding + * @param lport local port for local port forwarding * @param host host address for local port forwarding * @param rport remote port number for local port forwarding * @param ssf socket factory @@ -1836,17 +2160,29 @@ break; * null, the listening port will be bound for local use only. * If lport is 0, the tcp port will be allocated. * @param bind_address bind address for local port forwarding - * @param lport local port for local port forwarding + * @param lport local port for local port forwarding * @param host host address for local port forwarding * @param rport remote port number for local port forwarding * @param ssf socket factory * @param connectTimeout timeout for establishing port connection - * @return an allocated local TCP port number + * @return an allocated local TCP port number */ public int setPortForwardingL(String bind_address, int lport, String host, int rport, ServerSocketFactory ssf, int connectTimeout) throws JSchException{ PortWatcher pw=PortWatcher.addPort(this, bind_address, lport, host, rport, ssf); pw.setConnectTimeout(connectTimeout); - Thread tmp=new Thread(pw); + Thread tmp=new Thread(pw::run); + tmp.setName("PortWatcher Thread for "+host); + if(daemon_thread){ + tmp.setDaemon(daemon_thread); + } + tmp.start(); + return pw.lport; + } + + public int setSocketForwardingL(String bindAddress, int lport, String socketPath, ServerSocketFactory ssf, int connectTimeout) throws JSchException { + PortWatcher pw=PortWatcher.addSocket(this, bindAddress, lport, socketPath, ssf); + pw.setConnectTimeout(connectTimeout); + Thread tmp=new Thread(pw::run); tmp.setName("PortWatcher Thread for "+host); if(daemon_thread){ tmp.setDaemon(daemon_thread); @@ -1997,7 +2333,7 @@ break; * remote, "localhost" is always used as a bind_address. * The TCP connection to rport on the remote will be * forwarded to an instance of the class daemon with the - * argument arg. + * argument arg. * The class specified by daemon must implement ForwardedTCPIPDaemon. * * @param bind_address bind address @@ -2021,33 +2357,34 @@ break; return ChannelForwardedTCPIP.getPortForwarding(this); } - private class Forwarding { + static class Forwarding { String bind_address = null; int port = -1; String host = null; int hostport = -1; + String socketPath = null; } /** * The given argument may be "[bind_address:]port:host:hostport" or * "[bind_address:]port host:hostport", which is from LocalForward command of - * ~/.ssh/config . + * ~/.ssh/config . Also allows "[bind_address:]port:socketPath" or "[bind_address:]port socketPath" for socket forwarding. */ - private Forwarding parseForwarding(String conf) throws JSchException { + Forwarding parseForwarding(String conf) throws JSchException { String[] tmp = conf.split(" "); if(tmp.length>1){ // "[bind_address:]port host:hostport" - Vector foo = new Vector(); + Vector foo = new Vector<>(); for(int i=0; i"*" or an empty string, * then the forwarding is requested to listen on all interfaces. @@ -2133,9 +2475,9 @@ break; channel.setHost(host); channel.setPort(port); return channel; - } + } - private class GlobalRequestReply{ + private static class GlobalRequestReply{ private Thread thread=null; private int reply=-1; private int port=0; @@ -2152,7 +2494,7 @@ break; private GlobalRequestReply grr=new GlobalRequestReply(); private int _setPortForwardingR(String bind_address, int rport) throws JSchException{ synchronized(grr){ - Buffer buf=new Buffer(100); // ?? + Buffer buf=new Buffer(200); // ?? Packet packet=new Packet(buf); String address_to_bind=ChannelForwardedTCPIP.normalize(bind_address); @@ -2176,9 +2518,7 @@ break; } catch(Exception e){ grr.setThread(null); - if(e instanceof Throwable) - throw new JSchException(e.toString(), (Throwable)e); - throw new JSchException(e.toString()); + throw new JSchException(e.toString(), e); } int count = 0; @@ -2187,7 +2527,7 @@ break; try{ Thread.sleep(1000); } catch(Exception e){ } - count++; + count++; reply = grr.getReply(); } grr.setThread(null); @@ -2221,8 +2561,12 @@ break; } private void initDeflater(String method) throws JSchException{ + Compression odeflater=deflater; if(method.equals("none")){ deflater=null; + if(odeflater!=null){ + odeflater.end(); + } return; } String foo=getConfig(method); @@ -2230,26 +2574,32 @@ break; if(method.equals("zlib") || (isAuthed && method.equals("zlib@openssh.com"))){ try{ - Class c=Class.forName(foo); - deflater=(Compression)(c.newInstance()); + Class c=Class.forName(foo).asSubclass(Compression.class); + deflater=c.getDeclaredConstructor().newInstance(); int level=6; try{ level=Integer.parseInt(getConfig("compression_level"));} catch(Exception ee){ } - deflater.init(Compression.DEFLATER, level); - } - catch(NoClassDefFoundError ee){ - throw new JSchException(ee.toString(), ee); + deflater.init(Compression.DEFLATER, level, this); } catch(Exception ee){ throw new JSchException(ee.toString(), ee); //System.err.println(foo+" isn't accessible."); } + finally{ + if(odeflater!=null){ + odeflater.end(); + } + } } } } private void initInflater(String method) throws JSchException{ + Compression oinflater=inflater; if(method.equals("none")){ inflater=null; + if(oinflater!=null){ + oinflater.end(); + } return; } String foo=getConfig(method); @@ -2257,13 +2607,18 @@ break; if(method.equals("zlib") || (isAuthed && method.equals("zlib@openssh.com"))){ try{ - Class c=Class.forName(foo); - inflater=(Compression)(c.newInstance()); - inflater.init(Compression.INFLATER, 0); + Class c=Class.forName(foo).asSubclass(Compression.class); + inflater=c.getDeclaredConstructor().newInstance(); + inflater.init(Compression.INFLATER, 0, this); } catch(Exception ee){ throw new JSchException(ee.toString(), ee); - //System.err.println(foo+" isn't accessible."); + //System.err.println(foo+" isn't accessible."); + } + finally{ + if(oinflater!=null){ + oinflater.end(); + } } } } @@ -2273,6 +2628,7 @@ break; channel.setSession(this); } + String[] getServerSigAlgs(){ return serverSigAlgs; } public void setProxy(Proxy proxy){ this.proxy=proxy; } public void setHost(String host){ this.host=host; } public void setPort(int port){ this.port=port; } @@ -2288,49 +2644,69 @@ break; if(password!=null) this.password=Util.str2byte(password); } - public void setPassword(byte[] password){ + public void setPassword(byte[] password){ if(password!=null){ this.password=new byte[password.length]; System.arraycopy(password, 0, this.password, 0, password.length); } } - public void setConfig(java.util.Properties newconf){ - setConfig((java.util.Hashtable)newconf); + public void setConfig(Properties newconf){ + Hashtable foo=new Hashtable<>(); + for(String key : newconf.stringPropertyNames()){ + foo.put(key, newconf.getProperty(key)); + } + setConfig(foo); } - - public void setConfig(java.util.Hashtable newconf){ + + public void setConfig(Hashtable newconf){ synchronized(lock){ - if(config==null) - config=new java.util.Hashtable(); - for(java.util.Enumeration e=newconf.keys() ; e.hasMoreElements() ;) { - String key=(String)(e.nextElement()); - config.put(key, (String)(newconf.get(key))); + if(config==null) + config=new Hashtable<>(); + for(Enumeration e=newconf.keys() ; e.hasMoreElements() ;) { + String newkey=e.nextElement(); + String key=(newkey.equals("PubkeyAcceptedKeyTypes") ? "PubkeyAcceptedAlgorithms" : newkey); + String value=newconf.get(newkey); + if(key.equals("enable_server_sig_algs") && !value.equals("yes")){ + serverSigAlgs=null; + } + config.put(key, value); } } } public void setConfig(String key, String value){ - synchronized(lock){ + synchronized(lock){ if(config==null){ - config=new java.util.Hashtable(); + config=new Hashtable<>(); + } + if(key.equals("PubkeyAcceptedKeyTypes")){ + config.put("PubkeyAcceptedAlgorithms", value); + } + else{ + if(key.equals("enable_server_sig_algs") && !value.equals("yes")){ + serverSigAlgs=null; + } + config.put(key, value); } - config.put(key, value); } } public String getConfig(String key){ + if(key.equals("PubkeyAcceptedKeyTypes")){ + key="PubkeyAcceptedAlgorithms"; + } Object foo=null; if(config!=null){ foo=config.get(key); if(foo instanceof String) return (String)foo; } - foo=jsch.getConfig(key); + foo=JSch.getConfig(key); if(foo instanceof String) return (String)foo; return null; } - public void setSocketFactory(SocketFactory sfactory){ + public void setSocketFactory(SocketFactory sfactory){ socket_factory=sfactory; } public boolean isConnected(){ return isConnected; } @@ -2348,9 +2724,7 @@ break; this.timeout=timeout; } catch(Exception e){ - if(e instanceof Throwable) - throw new JSchException(e.toString(), (Throwable)e); - throw new JSchException(e.toString()); + throw new JSchException(e.toString(), e); } } public String getServerVersion(){ @@ -2392,7 +2766,7 @@ break; buf.putByte((byte)0); write(packet); } - + private HostKey hostkey=null; public HostKey getHostKey(){ return hostkey; } public String getHost(){return host;} @@ -2457,15 +2831,15 @@ break; if(ciphers==null || ciphers.length()==0) return null; - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "CheckCiphers: "+ciphers); } String cipherc2s=getConfig("cipher.c2s"); String ciphers2c=getConfig("cipher.s2c"); - Vector result=new Vector(); + Vector result=new Vector<>(); String[] _ciphers=Util.split(ciphers, ","); for(int i=0; i<_ciphers.length; i++){ String cipher=_ciphers[i]; @@ -2480,9 +2854,9 @@ break; String[] foo=new String[result.size()]; System.arraycopy(result.toArray(), 0, foo, 0, result.size()); - if(JSch.getLogger().isEnabled(Logger.INFO)){ + if(getLogger().isEnabled(Logger.INFO)){ for(int i=0; i c=Class.forName(cipher).asSubclass(Cipher.class); + Cipher _c=c.getDeclaredConstructor().newInstance(); _c.init(Cipher.ENCRYPT_MODE, new byte[_c.getBlockSize()], new byte[_c.getIVSize()]); return true; } - catch(Exception e){ + catch(Exception | NoClassDefFoundError e){ + return false; + } + } + + private String[] checkMacs(String macs){ + if(macs==null || macs.length()==0) + return null; + + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, + "CheckMacs: "+macs); + } + + String macc2s=getConfig("mac.c2s"); + String macs2c=getConfig("mac.s2c"); + + Vector result=new Vector<>(); + String[] _macs=Util.split(macs, ","); + for(int i=0; i<_macs.length; i++){ + String mac=_macs[i]; + if(macs2c.indexOf(mac) == -1 && macc2s.indexOf(mac) == -1) + continue; + if(!checkMac(getConfig(mac))){ + result.addElement(mac); + } + } + if(result.size()==0) + return null; + String[] foo=new String[result.size()]; + System.arraycopy(result.toArray(), 0, foo, 0, result.size()); + + if(getLogger().isEnabled(Logger.INFO)){ + for(int i=0; i c=Class.forName(mac).asSubclass(MAC.class); + MAC _c=c.getDeclaredConstructor().newInstance(); + _c.init(new byte[_c.getBlockSize()]); + return true; + } + catch(Exception | NoClassDefFoundError e){ return false; } } @@ -2508,12 +2931,12 @@ break; if(kexes==null || kexes.length()==0) return null; - if(JSch.getLogger().isEnabled(Logger.INFO)){ - JSch.getLogger().log(Logger.INFO, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "CheckKexes: "+kexes); } - java.util.Vector result=new java.util.Vector(); + Vector result=new Vector<>(); String[] _kexes=Util.split(kexes, ","); for(int i=0; i<_kexes.length; i++){ if(!checkKex(this, getConfig(_kexes[i]))){ @@ -2525,9 +2948,9 @@ break; String[] foo=new String[result.size()]; System.arraycopy(result.toArray(), 0, foo, 0, result.size()); - if(JSch.getLogger().isEnabled(Logger.INFO)){ + if(getLogger().isEnabled(Logger.INFO)){ for(int i=0; i c=Class.forName(kex).asSubclass(KeyExchange.class); + KeyExchange _c=c.getDeclaredConstructor().newInstance(); + _c.doInit(s ,null, null, null, null); return true; } - catch(Exception e){ return false; } + catch(Exception | NoClassDefFoundError 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, + if(getLogger().isEnabled(Logger.INFO)){ + getLogger().log(Logger.INFO, "CheckSignatures: "+sigs); } - java.util.Vector result=new java.util.Vector(); + Vector result=new 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()); + try{ + Class c=Class.forName(JSch.getConfig(_sigs[i])).asSubclass(Signature.class); + final Signature sig=c.getDeclaredConstructor().newInstance(); sig.init(); } - catch(Exception e){ + catch(Exception | NoClassDefFoundError e){ result.addElement(_sigs[i]); } } @@ -2570,9 +2993,9 @@ break; return null; String[] foo=new String[result.size()]; System.arraycopy(result.toArray(), 0, foo, 0, result.size()); - if(JSch.getLogger().isEnabled(Logger.INFO)){ + if(getLogger().isEnabled(Logger.INFO)){ for(int i=0; inull. * - * @param identityRepository + * @param identityRepository * @see #getIdentityRepository() */ public void setIdentityRepository(IdentityRepository identityRepository){ @@ -2604,9 +3027,9 @@ break; } /** - * Sets the hostkeyRepository, which will be referred in checking host keys. + * Sets the hostkeyRepository, which will be referred in checking host keys. * - * @param hostkeyRepository + * @param hostkeyRepository * @see #getHostKeyRepository() */ public void setHostKeyRepository(HostKeyRepository hostkeyRepository){ @@ -2627,7 +3050,7 @@ break; } /* - // setProxyCommand("ssh -l user2 host2 -o 'ProxyCommand ssh user1@host1 nc host2 22' nc %h %p") + // setProxyCommand("ssh -l user2 host2 -o 'ProxyCommand ssh user1@host1 nc host2 22' nc %h %p") public void setProxyCommand(String command){ setProxy(new ProxyCommand(command)); } @@ -2693,6 +3116,7 @@ break; checkConfig(config, "kex"); checkConfig(config, "server_host_key"); + checkConfig(config, "prefer_known_host_key_types"); checkConfig(config, "cipher.c2s"); checkConfig(config, "cipher.s2c"); @@ -2705,6 +3129,8 @@ break; checkConfig(config, "StrictHostKeyChecking"); checkConfig(config, "HashKnownHosts"); checkConfig(config, "PreferredAuthentications"); + checkConfig(config, "PubkeyAcceptedAlgorithms"); + checkConfig(config, "FingerprintHash"); checkConfig(config, "MaxAuthTries"); checkConfig(config, "ClearAllForwardings"); @@ -2732,8 +3158,8 @@ break; global = new String[0]; } if(values.length - global.length > 0){ - IdentityRepository.Wrapper ir = - new IdentityRepository.Wrapper(jsch.getIdentityRepository(), true); + IdentityRepositoryWrapper ir = + new IdentityRepositoryWrapper(jsch.getIdentityRepository(), true); for(int i = 0; i < values.length; i++){ String ifile = values[i]; for(int j = 0; j < global.length; j++){ @@ -2834,7 +3260,31 @@ break; private void checkConfig(ConfigRepository.Config config, String key){ String value = config.getValue(key); + if(value == null && key.equals("PubkeyAcceptedAlgorithms")) + value = config.getValue("PubkeyAcceptedKeyTypes"); if(value != null) this.setConfig(key, value); } + + /** + * Returns the logger being used by this instance of Session. If no + * particular logger has been set, the instance logger of the + * jsch instance is returned this session belongs to. + * @return The logger + */ + public Logger getLogger() { + if (logger != null) { + return logger; + } + return jsch.getInstanceLogger(); + } + + /** + * Sets the logger being used by this instance of Session + * @param logger The logger or null if the instance logger + * of this instance's jsch instance should be used + */ + public void setLogger(Logger logger) { + this.logger = logger; + } } 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 a871427e..c98877b2 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 @@ -70,7 +70,7 @@ public class SftpATTRS { private static final int pmask = 0xFFF; public String getPermissionsString() { - StringBuffer buf = new StringBuffer(10); + StringBuilder buf = new StringBuilder(10); if(isDir()) buf.append('d'); else if(isLink()) buf.append('l'); @@ -145,7 +145,7 @@ public class SftpATTRS { } static SftpATTRS getATTR(Buffer buf){ - SftpATTRS attr=new SftpATTRS(); + SftpATTRS attr=new SftpATTRS(); attr.flags=buf.getInt(); if((attr.flags&SSH_FILEXFER_ATTR_SIZE)!=0){ attr.size=buf.getLong(); } if((attr.flags&SSH_FILEXFER_ATTR_UIDGID)!=0){ @@ -163,11 +163,11 @@ public class SftpATTRS { if((attr.flags&SSH_FILEXFER_ATTR_EXTENDED)!=0){ int count=buf.getInt(); if(count>0){ - attr.extended=new String[count*2]; - for(int i=0; i0){ - for(int i=0; i0){ - for(int i=0; i c=Class.forName(session.getConfig(method)).asSubclass(GSSContext.class); + context=c.getDeclaredConstructor().newInstance(); } catch(Exception e){ return false; @@ -215,7 +216,7 @@ public class UserAuthGSSAPIWithMIC extends UserAuth { byte[] foo=buf.getString(); int partial_success=buf.getByte(); //System.err.println(new String(foo)+ - // " partial_success:"+(partial_success!=0)); + // " partial_success:"+(partial_success!=0)); if(partial_success!=0){ throw new JSchPartialAuthException(Util.byte2str(foo)); } 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 2a3abb4d..1efe03a9 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 @@ -30,6 +30,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch; class UserAuthKeyboardInteractive extends UserAuth{ + @Override public boolean start(Session session) throws Exception{ super.start(session); @@ -51,7 +52,7 @@ class UserAuthKeyboardInteractive extends UserAuth{ while(true){ if(session.auth_failures >= session.max_auth_tries){ - return false; + return false; } // send @@ -77,53 +78,53 @@ class UserAuthKeyboardInteractive extends UserAuth{ buf=session.read(buf); int command=buf.getCommand()&0xff; - if(command==SSH_MSG_USERAUTH_SUCCESS){ - return true; - } - if(command==SSH_MSG_USERAUTH_BANNER){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] _message=buf.getString(); - byte[] lang=buf.getString(); - String message=Util.byte2str(_message); - if(userinfo!=null){ - userinfo.showMessage(message); - } - continue loop; - } - if(command==SSH_MSG_USERAUTH_FAILURE){ - buf.getInt(); buf.getByte(); buf.getByte(); - byte[] foo=buf.getString(); - int partial_success=buf.getByte(); -// System.err.println(new String(foo)+ -// " partial_success:"+(partial_success!=0)); + if(command==SSH_MSG_USERAUTH_SUCCESS){ + return true; + } + if(command==SSH_MSG_USERAUTH_BANNER){ + buf.getInt(); buf.getByte(); buf.getByte(); + byte[] _message=buf.getString(); + byte[] lang=buf.getString(); + String message=Util.byte2str(_message); + if(userinfo!=null){ + userinfo.showMessage(message); + } + continue loop; + } + if(command==SSH_MSG_USERAUTH_FAILURE){ + buf.getInt(); buf.getByte(); buf.getByte(); + byte[] foo=buf.getString(); + int partial_success=buf.getByte(); +// System.err.println(new String(foo)+ +// " partial_success:"+(partial_success!=0)); - if(partial_success!=0){ - throw new JSchPartialAuthException(Util.byte2str(foo)); - } + if(partial_success!=0){ + throw new JSchPartialAuthException(Util.byte2str(foo)); + } - if(firsttime){ - return false; - //throw new JSchException("USERAUTH KI is not supported"); - //cancel=true; // ?? - } + if(firsttime){ + return false; + //throw new JSchException("USERAUTH KI is not supported"); + //cancel=true; // ?? + } session.auth_failures++; - break; - } - if(command==SSH_MSG_USERAUTH_INFO_REQUEST){ - firsttime=false; - buf.getInt(); buf.getByte(); buf.getByte(); - String name=Util.byte2str(buf.getString()); - String instruction=Util.byte2str(buf.getString()); - String languate_tag=Util.byte2str(buf.getString()); - int num=buf.getInt(); - String[] prompt=new String[num]; - boolean[] echo=new boolean[num]; - for(int i=0; i0 - ||(name.length()>0 || instruction.length()>0) - ){ - if(userinfo!=null){ + ||(name.length()>0 || instruction.length()>0) + ){ + if(userinfo!=null){ UIKeyboardInteractive kbi=(UIKeyboardInteractive)userinfo; String[] _response=kbi.promptKeyboardInteractive(dest, name, @@ -149,19 +150,19 @@ class UserAuthKeyboardInteractive extends UserAuth{ response[i]=Util.str2byte(_response[i]); } } - } - } + } + } - // byte SSH_MSG_USERAUTH_INFO_RESPONSE(61) - // int num-responses - // string response[1] (ISO-10646 UTF-8) - // ... - // string response[num-responses] (ISO-10646 UTF-8) - packet.reset(); - buf.putByte((byte)SSH_MSG_USERAUTH_INFO_RESPONSE); - if(num>0 && - (response==null || // cancel - num!=response.length)){ + // byte SSH_MSG_USERAUTH_INFO_RESPONSE(61) + // int num-responses + // string response[1] (ISO-10646 UTF-8) + // ... + // string response[num-responses] (ISO-10646 UTF-8) + packet.reset(); + buf.putByte((byte)SSH_MSG_USERAUTH_INFO_RESPONSE); + if(num>0 && + (response==null || // cancel + num!=response.length)){ if(response==null){ // working around the bug in OpenSSH ;-< @@ -174,28 +175,28 @@ class UserAuthKeyboardInteractive extends UserAuth{ buf.putInt(0); } - if(response==null) - cancel=true; - } - else{ - buf.putInt(num); - for(int i=0; i identities=session.getIdentityRepository().getIdentities(); synchronized(identities){ if(identities.size()<=0){ return false; } - _username=Util.str2byte(username); + String pkmethodstr=session.getConfig("PubkeyAcceptedAlgorithms"); + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + "PubkeyAcceptedAlgorithms = " + pkmethodstr); + } - for(int i=0; i not_available_pks=(not_available_pka!=null && not_available_pka.length>0 ? + Arrays.asList(not_available_pka) : + Collections.emptyList()); + if(!not_available_pks.isEmpty()){ + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + "Signature algorithms unavailable for non-agent identities = " + not_available_pks); + } + } - if(session.auth_failures >= session.max_auth_tries){ - return false; + List pkmethods=Arrays.asList(Util.split(pkmethodstr, ",")); + if(pkmethods.isEmpty()){ + return false; + } + + String[] server_sig_algs=session.getServerSigAlgs(); + if(server_sig_algs!=null && server_sig_algs.length>0){ + List _known=new ArrayList<>(); + List _unknown=new ArrayList<>(); + for(String pkmethod : pkmethods){ + boolean add=false; + for(String server_sig_alg : server_sig_algs){ + if(pkmethod.equals(server_sig_alg)){ + add=true; + break; + } + } + + if(add){ + _known.add(pkmethod); + } + else{ + _unknown.add(pkmethod); + } } - Identity identity=(Identity)(identities.elementAt(i)); - byte[] pubkeyblob=identity.getPublicKeyBlob(); + if(!_known.isEmpty()){ + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + "PubkeyAcceptedAlgorithms in server-sig-algs = " + _known); + } + } + + if(!_unknown.isEmpty()){ + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + "PubkeyAcceptedAlgorithms not in server-sig-algs = " + _unknown); + } + } + + if(!_known.isEmpty() && !_unknown.isEmpty()){ + boolean success=_start(session, identities, _known, not_available_pks); + if(success){ + return true; + } + + return _start(session, identities, _unknown, not_available_pks); + } + } + else{ + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, "No server-sig-algs found, using PubkeyAcceptedAlgorithms = " + pkmethods); + } + } + + return _start(session, identities, pkmethods, not_available_pks); + } + } + + private boolean _start(Session session, List identities, List pkmethods, List not_available_pks) throws Exception{ + if(session.auth_failures >= session.max_auth_tries){ + return false; + } + + List rsamethods=new ArrayList<>(); + List nonrsamethods=new ArrayList<>(); + for(String pkmethod : pkmethods){ + if(pkmethod.equals("ssh-rsa") || pkmethod.equals("rsa-sha2-256") || pkmethod.equals("rsa-sha2-512") || + pkmethod.equals("ssh-rsa-sha224@ssh.com") || pkmethod.equals("ssh-rsa-sha256@ssh.com") || + pkmethod.equals("ssh-rsa-sha384@ssh.com") || pkmethod.equals("ssh-rsa-sha512@ssh.com")){ + rsamethods.add(pkmethod); + } + else{ + nonrsamethods.add(pkmethod); + } + } + + byte[] _username=Util.str2byte(username); + + int command; + + iloop: + for(Identity identity : identities){ + + if(session.auth_failures >= session.max_auth_tries){ + return false; + } + + //System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted()); + decryptKey(session, identity); + //System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted()); + + String _ipkmethod=identity.getAlgName(); + List ipkmethods=null; + if(_ipkmethod.equals("ssh-rsa")){ + ipkmethods=rsamethods; + } + else if(nonrsamethods.contains(_ipkmethod)){ + ipkmethods=Collections.singletonList(_ipkmethod); + } + if(ipkmethods==null) { + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + _ipkmethod+" cannot be used as public key type for identity "+identity.getName()); + } + continue; + } + + byte[] pubkeyblob=identity.getPublicKeyBlob(); + List pkmethodsuccesses=null; + + if(pubkeyblob!=null){ + command=SSH_MSG_USERAUTH_FAILURE; + loop3: + for(String ipkmethod : ipkmethods){ + if(not_available_pks.contains(ipkmethod) && !(identity instanceof AgentIdentity)){ + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + ipkmethod+" not available for identity "+identity.getName()); + } + continue loop3; + } - if(pubkeyblob!=null){ // send // byte SSH_MSG_USERAUTH_REQUEST(50) // string user name @@ -74,7 +198,7 @@ class UserAuthPublicKey extends UserAuth{ buf.putString(Util.str2byte("ssh-connection")); buf.putString(Util.str2byte("publickey")); buf.putByte((byte)0); - buf.putString(Util.str2byte(identity.getAlgName())); + buf.putString(Util.str2byte(ipkmethod)); buf.putString(pubkeyblob); session.write(packet); @@ -84,10 +208,19 @@ class UserAuthPublicKey extends UserAuth{ command=buf.getCommand()&0xff; if(command==SSH_MSG_USERAUTH_PK_OK){ - break; + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + ipkmethod + " preauth success"); + } + pkmethodsuccesses=Collections.singletonList(ipkmethod); + break loop3; } else if(command==SSH_MSG_USERAUTH_FAILURE){ - break; + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + ipkmethod + " preauth failure"); + } + continue loop3; } else if(command==SSH_MSG_USERAUTH_BANNER){ buf.getInt(); buf.getByte(); buf.getByte(); @@ -100,60 +233,41 @@ class UserAuthPublicKey extends UserAuth{ continue loop1; } else{ - //System.err.println("USERAUTH fail ("+command+")"); - //throw new JSchException("USERAUTH fail ("+command+")"); - break; - } - } - - if(command!=SSH_MSG_USERAUTH_PK_OK){ - continue; - } - } - -//System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted()); - - int count=5; - while(true){ - if((identity.isEncrypted() && passphrase==null)){ - if(userinfo==null) throw new JSchException("USERAUTH fail"); - if(identity.isEncrypted() && - !userinfo.promptPassphrase("Passphrase for "+identity.getName())){ - throw new JSchAuthCancelException("publickey"); - //throw new JSchException("USERAUTH cancel"); - //break; - } - String _passphrase=userinfo.getPassphrase(); - if(_passphrase!=null){ - passphrase=Util.str2byte(_passphrase); - } - } - - if(!identity.isEncrypted() || passphrase!=null){ - if(identity.setPassphrase(passphrase)){ - if(passphrase!=null && - (session.getIdentityRepository() instanceof IdentityRepository.Wrapper)){ - ((IdentityRepository.Wrapper)session.getIdentityRepository()).check(); + //System.err.println("USERAUTH fail ("+command+")"); + //throw new JSchException("USERAUTH fail ("+command+")"); + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + ipkmethod + " preauth failure command (" + command + ")"); } - break; + continue loop3; } } - Util.bzero(passphrase); - passphrase=null; - count--; - if(count==0)break; } - Util.bzero(passphrase); - passphrase=null; -//System.err.println("UserAuthPublicKey: identity.isEncrypted()="+identity.isEncrypted()); + if(command!=SSH_MSG_USERAUTH_PK_OK){ + continue iloop; + } + } - if(identity.isEncrypted()) continue; - if(pubkeyblob==null) pubkeyblob=identity.getPublicKeyBlob(); + + + if(identity.isEncrypted()) continue; + if(pubkeyblob==null) pubkeyblob=identity.getPublicKeyBlob(); //System.err.println("UserAuthPublicKey: pubkeyblob="+pubkeyblob); - if(pubkeyblob==null) continue; + if(pubkeyblob==null) continue; + if(pkmethodsuccesses==null) pkmethodsuccesses=ipkmethods; + + loop4: + for(String pkmethodsuccess : pkmethodsuccesses){ + if(not_available_pks.contains(pkmethodsuccess) && !(identity instanceof AgentIdentity)){ + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + pkmethodsuccess+" not available for identity "+identity.getName()); + } + continue loop4; + } // send // byte SSH_MSG_USERAUTH_REQUEST(50) @@ -170,12 +284,12 @@ class UserAuthPublicKey extends UserAuth{ buf.putString(Util.str2byte("ssh-connection")); buf.putString(Util.str2byte("publickey")); buf.putByte((byte)1); - buf.putString(Util.str2byte(identity.getAlgName())); + buf.putString(Util.str2byte(pkmethodsuccess)); buf.putString(pubkeyblob); -// byte[] tmp=new byte[buf.index-5]; -// System.arraycopy(buf.buffer, 5, tmp, 0, tmp.length); -// buf.putString(signature); +// byte[] tmp=new byte[buf.index-5]; +// System.arraycopy(buf.buffer, 5, tmp, 0, tmp.length); +// buf.putString(signature); byte[] sid=session.getSessionId(); int sidlen=sid.length; @@ -186,9 +300,13 @@ class UserAuthPublicKey extends UserAuth{ tmp[3]=(byte)(sidlen); System.arraycopy(sid, 0, tmp, 4, sidlen); System.arraycopy(buf.buffer, 5, tmp, 4+sidlen, buf.index-5); - byte[] signature=identity.getSignature(tmp); + byte[] signature=identity.getSignature(tmp, pkmethodsuccess); if(signature==null){ // for example, too long key length. - break; + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + pkmethodsuccess + " signature failure"); + } + continue loop4; } buf.putString(signature); session.write(packet); @@ -199,6 +317,10 @@ class UserAuthPublicKey extends UserAuth{ command=buf.getCommand()&0xff; if(command==SSH_MSG_USERAUTH_SUCCESS){ + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + pkmethodsuccess + " auth success"); + } return true; } else if(command==SSH_MSG_USERAUTH_BANNER){ @@ -212,23 +334,68 @@ class UserAuthPublicKey extends UserAuth{ continue loop2; } else if(command==SSH_MSG_USERAUTH_FAILURE){ - buf.getInt(); buf.getByte(); buf.getByte(); + buf.getInt(); buf.getByte(); buf.getByte(); byte[] foo=buf.getString(); int partial_success=buf.getByte(); - //System.err.println(new String(foo)+ - // " partial_success:"+(partial_success!=0)); + //System.err.println(new String(foo)+ + // " partial_success:"+(partial_success!=0)); if(partial_success!=0){ throw new JSchPartialAuthException(Util.byte2str(foo)); } session.auth_failures++; - break; + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + pkmethodsuccess + " auth failure"); + } + break loop2; } //System.err.println("USERAUTH fail ("+command+")"); //throw new JSchException("USERAUTH fail ("+command+")"); - break; + if(session.getLogger().isEnabled(Logger.DEBUG)){ + session.getLogger().log(Logger.DEBUG, + pkmethodsuccess + " auth failure command (" + command +")"); + } + break loop2; } } } return false; } + + private void decryptKey(Session session, Identity identity) throws JSchException { + byte[] passphrase=null; + int count=5; + while(true){ + if((identity.isEncrypted() && passphrase==null)){ + if(userinfo==null) throw new JSchException("USERAUTH fail"); + if(identity.isEncrypted() && + !userinfo.promptPassphrase("Passphrase for "+identity.getName())){ + throw new JSchAuthCancelException("publickey"); + //throw new JSchException("USERAUTH cancel"); + //break; + } + String _passphrase=userinfo.getPassphrase(); + if(_passphrase!=null){ + passphrase= Util.str2byte(_passphrase); + } + } + + if(!identity.isEncrypted() || passphrase!=null){ + if(identity.setPassphrase(passphrase)){ + if(passphrase!=null && + (session.getIdentityRepository() instanceof IdentityRepositoryWrapper)){ + ((IdentityRepositoryWrapper)session.getIdentityRepository()).check(); + } + break; + } + } + Util.bzero(passphrase); + passphrase=null; + count--; + if(count==0)break; + } + + Util.bzero(passphrase); + passphrase=null; + } } 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 ef0700c2..dcfd4b67 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 @@ -32,6 +32,9 @@ import java.net.Socket; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Vector; class Util{ @@ -63,7 +66,7 @@ class Util{ throw new JSchException("fromBase64: invalid base64 data", e); } } - static byte[] toBase64(byte[] buf, int start, int length){ + static byte[] toBase64(byte[] buf, int start, int length, boolean include_pad){ byte[] tmp=new byte[length*2]; int i,j,k; @@ -87,8 +90,10 @@ class Util{ tmp[i++]=b64[k]; k=((buf[j]&0x03)<<4)&0x3f; tmp[i++]=b64[k]; - tmp[i++]=(byte)'='; - tmp[i++]=(byte)'='; + if(include_pad){ + tmp[i++]=(byte)'='; + tmp[i++]=(byte)'='; + } } else if(foo==2){ k=(buf[j]>>>2)&0x3f; @@ -97,7 +102,9 @@ class Util{ tmp[i++]=b64[k]; k=((buf[j+1]&0x0f)<<2)&0x3f; tmp[i++]=b64[k]; - tmp[i++]=(byte)'='; + if(include_pad){ + tmp[i++]=(byte)'='; + } } byte[] bar=new byte[i]; System.arraycopy(tmp, 0, bar, 0, i); @@ -110,22 +117,22 @@ class Util{ if(foo==null) return null; byte[] buf=Util.str2byte(foo); - java.util.Vector bar=new java.util.Vector(); + Vector bar=new Vector<>(); int start=0; int index; while(true){ index=foo.indexOf(split, start); if(index>=0){ - bar.addElement(Util.byte2str(buf, start, index-start)); - start=index+1; - continue; + bar.addElement(Util.byte2str(buf, start, index-start)); + start=index+1; + continue; } bar.addElement(Util.byte2str(buf, start, buf.length-start)); break; } String[] result=new String[bar.size()]; for(int i=0; i0 && name[0]=='.'){ if(pattern.length>0 && pattern[0]=='.'){ if(pattern.length==2 && pattern[1]=='*') return true; @@ -144,7 +151,7 @@ class Util{ return glob(pattern, pattern_index, name, name_index); } static private boolean glob(byte[] pattern, int pattern_index, - byte[] name, int name_index){ + byte[] name, int name_index){ //System.err.println("glob: "+new String(pattern)+", "+pattern_index+" "+new String(name)+", "+name_index); int patternlen=pattern.length; @@ -157,14 +164,14 @@ class Util{ while(i>>4)&0xf]); - sb.append(chars[(bar)&0xf]); - if(i+1>>4)&0xf]); + sb.append(chars[(bar)&0xf]); + if(i+1 { sockp[0]=null; try{ sockp[0]=new Socket(_host, _port); @@ -371,7 +385,6 @@ class Util{ } sockp[0]=null; } - } }); tmp.setName("Opening Socket "+host); tmp.start(); @@ -379,7 +392,7 @@ class Util{ tmp.join(timeout); message="timeout: "; } - catch(java.lang.InterruptedException eee){ + catch(InterruptedException eee){ } if(sockp[0]!=null && sockp[0].isConnected()){ socket=sockp[0]; @@ -396,40 +409,34 @@ class Util{ return socket; } - static byte[] str2byte(String str, String encoding){ + static byte[] str2byte(String str, Charset encoding){ if(str==null) return null; - try{ return str.getBytes(encoding); } - catch(java.io.UnsupportedEncodingException e){ - return str.getBytes(); - } + return str.getBytes(encoding); } static byte[] str2byte(String str){ - return str2byte(str, "UTF-8"); + return str2byte(str, StandardCharsets.UTF_8); } - static String byte2str(byte[] str, String encoding){ + static String byte2str(byte[] str, Charset encoding){ return byte2str(str, 0, str.length, encoding); } - static String byte2str(byte[] str, int s, int l, String encoding){ - try{ return new String(str, s, l, encoding); } - catch(java.io.UnsupportedEncodingException e){ - return new String(str, s, l); - } + static String byte2str(byte[] str, int s, int l, Charset encoding){ + return new String(str, s, l, encoding); } static String byte2str(byte[] str){ - return byte2str(str, 0, str.length, "UTF-8"); + return byte2str(str, 0, str.length, StandardCharsets.UTF_8); } static String byte2str(byte[] str, int s, int l){ - return byte2str(str, s, l, "UTF-8"); + return byte2str(str, s, l, StandardCharsets.UTF_8); } static String toHex(byte[] str){ - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); for(int i = 0; i +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +package com.jcraft.jsch.jbcrypt; + +import java.nio.charset.StandardCharsets; +import java.security.DigestException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +/** + * BCrypt implements OpenBSD-style Blowfish password hashing using + * the scheme described in "A Future-Adaptable Password Scheme" by + * Niels Provos and David Mazieres. + *

    + * This password hashing system tries to thwart off-line password + * cracking using a computationally-intensive hashing algorithm, + * based on Bruce Schneier's Blowfish cipher. The work factor of + * the algorithm is parameterised, so it can be increased as + * computers get faster. + *

    + * Usage is really simple. To hash a password for the first time, + * call the hashpw method with a random salt, like this: + *

    + * + * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
    + *
    + *

    + * To check whether a plaintext password matches one that has been + * hashed previously, use the checkpw method: + *

    + * + * if (BCrypt.checkpw(candidate_password, stored_hash))
    + *     System.out.println("It matches");
    + * else
    + *     System.out.println("It does not match");
    + *
    + *

    + * The gensalt() method takes an optional parameter (log_rounds) + * that determines the computational complexity of the hashing: + *

    + * + * String strong_salt = BCrypt.gensalt(10)
    + * String stronger_salt = BCrypt.gensalt(12)
    + *
    + *

    + * The amount of work increases exponentially (2**log_rounds), so + * each increment is twice as much work. The default log_rounds is + * 10, and the valid range is 4 to 30. + * + * @author Damien Miller + * @version 0.2 + */ +public class BCrypt { + // BCrypt parameters + private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10; + private static final int BCRYPT_SALT_LEN = 16; + + // Blowfish parameters + private static final int BLOWFISH_NUM_ROUNDS = 16; + + // Initial contents of key schedule + private static final int P_orig[] = { + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b + }; + private static final int S_orig[] = { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + }; + + // OpenBSD IV: "OxychromaticBlowfishSwatDynamite" in big endian + private static final int[] openbsd_iv = new int[] { + 0x4f787963, 0x68726f6d, 0x61746963, 0x426c6f77, + 0x66697368, 0x53776174, 0x44796e61, 0x6d697465, + }; + + // bcrypt IV: "OrpheanBeholderScryDoubt". The C implementation calls + // this "ciphertext", but it is really plaintext or an IV. We keep + // the name to make code comparison easier. + static private final int bf_crypt_ciphertext[] = { + 0x4f727068, 0x65616e42, 0x65686f6c, + 0x64657253, 0x63727944, 0x6f756274 + }; + + // Table for Base64 encoding + static private final char base64_code[] = { + '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9' + }; + + // Table for Base64 decoding + static private final byte index_64[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0, 1, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, + -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + -1, -1, -1, -1, -1, -1, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, -1, -1, -1, -1, -1 + }; + + // Expanded Blowfish key + private int P[]; + private int S[]; + + /** + * Encode a byte array using bcrypt's slightly-modified base64 + * encoding scheme. Note that this is *not* compatible with + * the standard MIME-base64 encoding. + * + * @param d the byte array to encode + * @param len the number of bytes to encode + * @return base64-encoded string + * @exception IllegalArgumentException if the length is invalid + */ + private static String encode_base64(byte d[], int len) + throws IllegalArgumentException { + int off = 0; + StringBuilder rs = new StringBuilder(); + int c1, c2; + + if (len <= 0 || len > d.length) + throw new IllegalArgumentException ("Invalid len"); + + while (off < len) { + c1 = d[off++] & 0xff; + rs.append(base64_code[(c1 >> 2) & 0x3f]); + c1 = (c1 & 0x03) << 4; + if (off >= len) { + rs.append(base64_code[c1 & 0x3f]); + break; + } + c2 = d[off++] & 0xff; + c1 |= (c2 >> 4) & 0x0f; + rs.append(base64_code[c1 & 0x3f]); + c1 = (c2 & 0x0f) << 2; + if (off >= len) { + rs.append(base64_code[c1 & 0x3f]); + break; + } + c2 = d[off++] & 0xff; + c1 |= (c2 >> 6) & 0x03; + rs.append(base64_code[c1 & 0x3f]); + rs.append(base64_code[c2 & 0x3f]); + } + return rs.toString(); + } + + /** + * Look up the 3 bits base64-encoded by the specified character, + * range-checking againt conversion table + * @param x the base64-encoded value + * @return the decoded value of x + */ + private static byte char64(char x) { + if ((int)x < 0 || (int)x > index_64.length) + return -1; + return index_64[(int)x]; + } + + /** + * Decode a string encoded using bcrypt's base64 scheme to a + * byte array. Note that this is *not* compatible with + * the standard MIME-base64 encoding. + * @param s the string to decode + * @param maxolen the maximum number of bytes to decode + * @return an array containing the decoded bytes + * @throws IllegalArgumentException if maxolen is invalid + */ + private static byte[] decode_base64(String s, int maxolen) + throws IllegalArgumentException { + StringBuilder rs = new StringBuilder(); + int off = 0, slen = s.length(), olen = 0; + byte ret[]; + byte c1, c2, c3, c4, o; + + if (maxolen <= 0) + throw new IllegalArgumentException ("Invalid maxolen"); + + while (off < slen - 1 && olen < maxolen) { + c1 = char64(s.charAt(off++)); + c2 = char64(s.charAt(off++)); + if (c1 == -1 || c2 == -1) + break; + o = (byte)(c1 << 2); + o |= (c2 & 0x30) >> 4; + rs.append((char)o); + if (++olen >= maxolen || off >= slen) + break; + c3 = char64(s.charAt(off++)); + if (c3 == -1) + break; + o = (byte)((c2 & 0x0f) << 4); + o |= (c3 & 0x3c) >> 2; + rs.append((char)o); + if (++olen >= maxolen || off >= slen) + break; + c4 = char64(s.charAt(off++)); + o = (byte)((c3 & 0x03) << 6); + o |= c4; + rs.append((char)o); + ++olen; + } + + ret = new byte[olen]; + for (off = 0; off < olen; off++) + ret[off] = (byte)rs.charAt(off); + return ret; + } + + /** + * Blowfish encipher a single 64-bit block encoded as + * two 32-bit halves + * @param lr an array containing the two 32-bit half blocks + * @param off the position in the array of the blocks + */ + private final void encipher(int lr[], int off) { + int i, n, l = lr[off], r = lr[off + 1]; + + l ^= P[0]; + for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) { + // Feistel substitution on left word + n = S[(l >> 24) & 0xff]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[++i]; + + // Feistel substitution on right word + n = S[(r >> 24) & 0xff]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[++i]; + } + lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; + lr[off + 1] = l; + } + + /** + * Cycically extract a word of key material + * @param data the string to extract the data from + * @param offp a "pointer" (as a one-entry array) to the + * current offset into data + * @return the next word of material from data + */ + private static int streamtoword(byte data[], int offp[]) { + int i; + int word = 0; + int off = offp[0]; + + for (i = 0; i < 4; i++) { + word = (word << 8) | (data[off] & 0xff); + off = (off + 1) % data.length; + } + + offp[0] = off; + return word; + } + + /** + * Initialise the Blowfish key schedule + */ + private void init_key() { + P = P_orig.clone(); + S = S_orig.clone(); + } + + /** + * Key the Blowfish cipher + * @param key an array containing the key + */ + private void key(byte key[]) { + int i; + int koffp[] = { 0 }; + int lr[] = { 0, 0 }; + int plen = P.length, slen = S.length; + + for (i = 0; i < plen; i++) + P[i] = P[i] ^ streamtoword(key, koffp); + + for (i = 0; i < plen; i += 2) { + encipher(lr, 0); + P[i] = lr[0]; + P[i + 1] = lr[1]; + } + + for (i = 0; i < slen; i += 2) { + encipher(lr, 0); + S[i] = lr[0]; + S[i + 1] = lr[1]; + } + } + + /** + * Perform the "enhanced key schedule" step described by + * Provos and Mazieres in "A Future-Adaptable Password Scheme" + * http://www.openbsd.org/papers/bcrypt-paper.ps + * @param data salt information + * @param key password information + */ + private void ekskey(byte data[], byte key[]) { + int i; + int koffp[] = { 0 }, doffp[] = { 0 }; + int lr[] = { 0, 0 }; + int plen = P.length, slen = S.length; + + for (i = 0; i < plen; i++) + P[i] = P[i] ^ streamtoword(key, koffp); + + for (i = 0; i < plen; i += 2) { + lr[0] ^= streamtoword(data, doffp); + lr[1] ^= streamtoword(data, doffp); + encipher(lr, 0); + P[i] = lr[0]; + P[i + 1] = lr[1]; + } + + for (i = 0; i < slen; i += 2) { + lr[0] ^= streamtoword(data, doffp); + lr[1] ^= streamtoword(data, doffp); + encipher(lr, 0); + S[i] = lr[0]; + S[i + 1] = lr[1]; + } + } + + /** + * Compatibility with new OpenBSD function. + */ + public void hash(byte[] hpass, byte[] hsalt, byte[] output) { + init_key(); + ekskey(hsalt, hpass); + for (int i = 0; i < 64; i++) { + key(hsalt); + key(hpass); + } + + int[] buf = new int[openbsd_iv.length]; + System.arraycopy(openbsd_iv, 0, buf, 0, openbsd_iv.length); + for (int i = 0; i < 8; i += 2) { + for (int j = 0; j < 64; j++) { + encipher(buf, i); + } + } + + for (int i = 0, j = 0; i < buf.length; i++) { + // Output of this is little endian + output[j++] = (byte)(buf[i] & 0xff); + output[j++] = (byte)((buf[i] >> 8) & 0xff); + output[j++] = (byte)((buf[i] >> 16) & 0xff); + output[j++] = (byte)((buf[i] >> 24) & 0xff); + } + } + + /** + * Compatibility with new OpenBSD function. + */ + public void pbkdf(byte[] password, byte[] salt, int rounds, byte[] output) { + try { + MessageDigest sha512 = MessageDigest.getInstance("SHA-512"); + + int nblocks = (output.length + 31) / 32; + byte[] hpass = sha512.digest(password); + + byte[] hsalt = new byte[64]; + byte[] block_b = new byte[4]; + byte[] out = new byte[32]; + byte[] tmp = new byte[32]; + for (int block = 1; block <= nblocks; block++) { + // Block count is in big endian + block_b[0] = (byte) ((block >> 24) & 0xFF); + block_b[1] = (byte) ((block >> 16) & 0xFF); + block_b[2] = (byte) ((block >> 8) & 0xFF); + block_b[3] = (byte) (block & 0xFF); + + sha512.reset(); + sha512.update(salt); + sha512.update(block_b); + sha512.digest(hsalt, 0, hsalt.length); + + hash(hpass, hsalt, out); + System.arraycopy(out, 0, tmp, 0, out.length); + + for (int round = 1; round < rounds; round++) { + sha512.reset(); + sha512.update(tmp); + sha512.digest(hsalt, 0, hsalt.length); + + hash(hpass, hsalt, tmp); + + for (int i = 0; i < tmp.length; i++) { + out[i] ^= tmp[i]; + } + } + + for (int i = 0; i < out.length; i++) { + int idx = i * nblocks + (block - 1); + if (idx < output.length) { + output[idx] = out[i]; + } + } + } + } catch (DigestException e) { + throw new RuntimeException(e); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + /** + * Perform the central password hashing step in the + * bcrypt scheme + * @param password the password to hash + * @param salt the binary salt to hash with the password + * @param log_rounds the binary logarithm of the number + * of rounds of hashing to apply + * @param cdata the plaintext to encrypt + * @return an array containing the binary hashed password + */ + public byte[] crypt_raw(byte password[], byte salt[], int log_rounds, + int cdata[]) { + int rounds, i, j; + int clen = cdata.length; + byte ret[]; + + if (log_rounds < 4 || log_rounds > 30) + throw new IllegalArgumentException ("Bad number of rounds"); + rounds = 1 << log_rounds; + if (salt.length != BCRYPT_SALT_LEN) + throw new IllegalArgumentException ("Bad salt length"); + + init_key(); + ekskey(salt, password); + for (i = 0; i != rounds; i++) { + key(password); + key(salt); + } + + for (i = 0; i < 64; i++) { + for (j = 0; j < (clen >> 1); j++) + encipher(cdata, j << 1); + } + + ret = new byte[clen * 4]; + for (i = 0, j = 0; i < clen; i++) { + ret[j++] = (byte)((cdata[i] >> 24) & 0xff); + ret[j++] = (byte)((cdata[i] >> 16) & 0xff); + ret[j++] = (byte)((cdata[i] >> 8) & 0xff); + ret[j++] = (byte)(cdata[i] & 0xff); + } + return ret; + } + + /** + * Hash a password using the OpenBSD bcrypt scheme + * @param password the password to hash + * @param salt the salt to hash with (perhaps generated + * using BCrypt.gensalt) + * @return the hashed password + */ + public static String hashpw(String password, String salt) { + BCrypt B; + String real_salt; + byte passwordb[], saltb[], hashed[]; + char minor = (char)0; + int rounds, off = 0; + StringBuilder rs = new StringBuilder(); + + if (salt.charAt(0) != '$' || salt.charAt(1) != '2') + throw new IllegalArgumentException ("Invalid salt version"); + if (salt.charAt(2) == '$') + off = 3; + else { + minor = salt.charAt(2); + if (minor != 'a' || salt.charAt(3) != '$') + throw new IllegalArgumentException ("Invalid salt revision"); + off = 4; + } + + // Extract number of rounds + if (salt.charAt(off + 2) > '$') + throw new IllegalArgumentException ("Missing salt rounds"); + rounds = Integer.parseInt(salt.substring(off, off + 2)); + + real_salt = salt.substring(off + 3, off + 25); + passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes(StandardCharsets.UTF_8); + + saltb = decode_base64(real_salt, BCRYPT_SALT_LEN); + + B = new BCrypt(); + hashed = B.crypt_raw(passwordb, saltb, rounds, + bf_crypt_ciphertext.clone()); + + rs.append("$2"); + if (minor >= 'a') + rs.append(minor); + rs.append("$"); + if (rounds < 10) + rs.append("0"); + if (rounds > 30) { + throw new IllegalArgumentException( + "rounds exceeds maximum (30)"); + } + rs.append(Integer.toString(rounds)); + rs.append("$"); + rs.append(encode_base64(saltb, saltb.length)); + rs.append(encode_base64(hashed, + bf_crypt_ciphertext.length * 4 - 1)); + return rs.toString(); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method + * @param log_rounds the log2 of the number of rounds of + * hashing to apply - the work factor therefore increases as + * 2**log_rounds. + * @param random an instance of SecureRandom to use + * @return an encoded salt value + */ + public static String gensalt(int log_rounds, SecureRandom random) { + StringBuilder rs = new StringBuilder(); + byte rnd[] = new byte[BCRYPT_SALT_LEN]; + + random.nextBytes(rnd); + + rs.append("$2a$"); + if (log_rounds < 10) + rs.append("0"); + if (log_rounds > 30) { + throw new IllegalArgumentException( + "log_rounds exceeds maximum (30)"); + } + rs.append(Integer.toString(log_rounds)); + rs.append("$"); + rs.append(encode_base64(rnd, rnd.length)); + return rs.toString(); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method + * @param log_rounds the log2 of the number of rounds of + * hashing to apply - the work factor therefore increases as + * 2**log_rounds. + * @return an encoded salt value + */ + public static String gensalt(int log_rounds) { + return gensalt(log_rounds, new SecureRandom()); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method, + * selecting a reasonable default for the number of hashing + * rounds to apply + * @return an encoded salt value + */ + public static String gensalt() { + return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS); + } + + /** + * Check that a plaintext password matches a previously hashed + * one + * @param plaintext the plaintext password to verify + * @param hashed the previously-hashed password + * @return true if the passwords match, false otherwise + */ + public static boolean checkpw(String plaintext, String hashed) { + String try_pw = hashpw(plaintext, hashed); + byte hashed_bytes[] = hashed.getBytes(StandardCharsets.UTF_8); + byte try_bytes[] = try_pw.getBytes(StandardCharsets.UTF_8); + if (hashed_bytes.length != try_bytes.length) + return false; + byte ret = 0; + for (int i = 0; i < try_bytes.length; i++) + ret |= hashed_bytes[i] ^ try_bytes[i]; + return ret == 0; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CBC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CBC.java index 0fb4dfc0..b8ea67bc 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CBC.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CBC.java @@ -36,8 +36,11 @@ public class AES128CBC implements Cipher{ private static final int ivsize=16; private static final int bsize=16; private javax.crypto.Cipher cipher; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ String pad="NoPadding"; byte[] tmp; @@ -55,21 +58,20 @@ public class AES128CBC implements Cipher{ try{ SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + keyspec, new IvParameterSpec(iv)); } catch(Exception e){ cipher=null; throw e; } } + @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ cipher.update(foo, s1, len, bar, s2); } - + @Override public boolean isCBC(){return true; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CTR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CTR.java index a88b2d5c..950b08d9 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CTR.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128CTR.java @@ -36,8 +36,11 @@ public class AES128CTR implements Cipher{ private static final int ivsize=16; private static final int bsize=16; private javax.crypto.Cipher cipher; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ String pad="NoPadding"; byte[] tmp; @@ -55,21 +58,20 @@ public class AES128CTR implements Cipher{ try{ SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + keyspec, new IvParameterSpec(iv)); } catch(Exception e){ cipher=null; throw e; } } + @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ cipher.update(foo, s1, len, bar, s2); } - + @Override public boolean isCBC(){return false; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128GCM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128GCM.java new file mode 100644 index 00000000..d10df726 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES128GCM.java @@ -0,0 +1,37 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2008-2018 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.jce; + +public class AES128GCM extends AESGCM{ + //Actually the key size, not block size + private static final int bsize=16; + @Override + public int getBlockSize(){return bsize;} +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CBC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CBC.java index e67535bf..24d2abd5 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CBC.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CBC.java @@ -36,8 +36,11 @@ public class AES192CBC implements Cipher{ private static final int ivsize=16; private static final int bsize=24; private javax.crypto.Cipher cipher; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ String pad="NoPadding"; byte[] tmp; @@ -54,20 +57,20 @@ public class AES192CBC implements Cipher{ try{ SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + keyspec, new IvParameterSpec(iv)); } catch(Exception e){ cipher=null; throw e; } } + @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ cipher.update(foo, s1, len, bar, s2); } + @Override public boolean isCBC(){return true; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CTR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CTR.java index e99735e3..339f5832 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CTR.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES192CTR.java @@ -36,8 +36,11 @@ public class AES192CTR implements Cipher{ private static final int ivsize=16; private static final int bsize=24; private javax.crypto.Cipher cipher; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ String pad="NoPadding"; byte[] tmp; @@ -54,20 +57,20 @@ public class AES192CTR implements Cipher{ try{ SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + keyspec, new IvParameterSpec(iv)); } catch(Exception e){ cipher=null; throw e; } } + @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ cipher.update(foo, s1, len, bar, s2); } + @Override public boolean isCBC(){return false; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CBC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CBC.java index cb6ac972..dd706046 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CBC.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CBC.java @@ -36,8 +36,11 @@ public class AES256CBC implements Cipher{ private static final int ivsize=16; private static final int bsize=32; private javax.crypto.Cipher cipher; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ String pad="NoPadding"; byte[] tmp; @@ -54,20 +57,20 @@ public class AES256CBC implements Cipher{ try{ SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + keyspec, new IvParameterSpec(iv)); } catch(Exception e){ cipher=null; throw e; } } + @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ cipher.update(foo, s1, len, bar, s2); } + @Override public boolean isCBC(){return true; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CTR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CTR.java index 2437703f..cff20fcf 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CTR.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256CTR.java @@ -36,8 +36,11 @@ public class AES256CTR implements Cipher{ private static final int ivsize=16; private static final int bsize=32; private javax.crypto.Cipher cipher; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ String pad="NoPadding"; byte[] tmp; @@ -54,20 +57,20 @@ public class AES256CTR implements Cipher{ try{ SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); cipher=javax.crypto.Cipher.getInstance("AES/CTR/"+pad); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - keyspec, new IvParameterSpec(iv)); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + keyspec, new IvParameterSpec(iv)); } catch(Exception e){ cipher=null; throw e; } } + @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ cipher.update(foo, s1, len, bar, s2); } + @Override public boolean isCBC(){return false; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256GCM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256GCM.java new file mode 100644 index 00000000..d61a6142 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AES256GCM.java @@ -0,0 +1,37 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2008-2018 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.jce; + +public class AES256GCM extends AESGCM{ + //Actually the key size, not block size + private static final int bsize=32; + @Override + public int getBlockSize(){return bsize;} +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AESGCM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AESGCM.java new file mode 100644 index 00000000..de33b7c4 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/AESGCM.java @@ -0,0 +1,103 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2008-2018 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.jce; + +import com.jcraft.jsch.Cipher; +import java.nio.ByteBuffer; +import javax.crypto.spec.*; + +abstract class AESGCM implements Cipher{ + //Actually the block size, not IV size + private static final int ivsize=16; + private static final int tagsize=16; + private javax.crypto.Cipher cipher; + private SecretKeySpec keyspec; + private int mode; + private ByteBuffer iv; + private long initcounter; + @Override + public int getIVSize(){return ivsize;} + @Override + public int getTagSize(){return tagsize;} + @Override + public void init(int mode, byte[] key, byte[] iv) throws Exception{ + String pad="NoPadding"; + byte[] tmp; + if(iv.length>12){ + tmp=new byte[12]; + System.arraycopy(iv, 0, tmp, 0, tmp.length); + iv=tmp; + } + int bsize=getBlockSize(); + if(key.length>bsize){ + tmp=new byte[bsize]; + System.arraycopy(key, 0, tmp, 0, tmp.length); + key=tmp; + } + this.mode=((mode==ENCRYPT_MODE)? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE); + this.iv=ByteBuffer.wrap(iv); + this.initcounter=this.iv.getLong(4); + try{ + keyspec=new SecretKeySpec(key, "AES"); + cipher=javax.crypto.Cipher.getInstance("AES/GCM/"+pad); + cipher.init(this.mode, keyspec, new GCMParameterSpec(tagsize*8,iv)); + } + catch(Exception e){ + cipher=null; + keyspec=null; + this.iv=null; + throw e; + } + } + @Override + public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ + cipher.update(foo, s1, len, bar, s2); + } + @Override + public void updateAAD(byte[] foo, int s1, int len) throws Exception{ + cipher.updateAAD(foo, s1, len); + } + @Override + public void doFinal(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ + cipher.doFinal(foo, s1, len, bar, s2); + long newcounter=iv.getLong(4)+1; + if (newcounter == initcounter) { + throw new IllegalStateException("GCM IV would be reused"); + } + iv.putLong(4, newcounter); + cipher.init(mode, keyspec, new GCMParameterSpec(tagsize*8,iv.array())); + } + @Override + public boolean isCBC(){return false; } + @Override + public boolean isAEAD(){return true; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java index dbe6bf9a..1ca00556 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR.java @@ -37,8 +37,11 @@ public class ARCFOUR implements Cipher{ private static final int ivsize=8; private static final int bsize=16; private javax.crypto.Cipher cipher; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ String pad="NoPadding"; byte[] tmp; @@ -51,20 +54,20 @@ public class ARCFOUR implements Cipher{ try{ cipher=javax.crypto.Cipher.getInstance("RC4"); SecretKeySpec _key = new SecretKeySpec(key, "RC4"); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - _key); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + _key); } catch(Exception e){ cipher=null; throw e; } } + @Override public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ cipher.update(foo, s1, len, bar, s2); } + @Override public boolean isCBC(){return false; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java index b77b0c1f..ebb8d017 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ARCFOUR128.java @@ -38,8 +38,11 @@ public class ARCFOUR128 implements Cipher{ private static final int bsize=16; private static final int skip=1536; private javax.crypto.Cipher cipher; + @Override public int getIVSize(){return ivsize;} + @Override public int getBlockSize(){return bsize;} + @Override public void init(int mode, byte[] key, byte[] iv) throws Exception{ byte[] tmp; if(key.length>bsize){ @@ -50,12 +53,10 @@ public class ARCFOUR128 implements Cipher{ try{ cipher=javax.crypto.Cipher.getInstance("RC4"); SecretKeySpec _key = new SecretKeySpec(key, "RC4"); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - _key); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + _key); byte[] foo=new byte[1]; for(int i=0; ibsize){ @@ -50,12 +53,10 @@ public class ARCFOUR256 implements Cipher{ try{ cipher=javax.crypto.Cipher.getInstance("RC4"); SecretKeySpec _key = new SecretKeySpec(key, "RC4"); - synchronized(javax.crypto.Cipher.class){ - cipher.init((mode==ENCRYPT_MODE? - javax.crypto.Cipher.ENCRYPT_MODE: - javax.crypto.Cipher.DECRYPT_MODE), - _key); - } + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + _key); byte[] foo=new byte[1]; for(int i=0; iivsize){ + tmp=new byte[ivsize]; + System.arraycopy(iv, 0, tmp, 0, tmp.length); + iv=tmp; + } + if(key.length>bsize){ + tmp=new byte[bsize]; + System.arraycopy(key, 0, tmp, 0, tmp.length); + key=tmp; + } + try{ + SecretKeySpec skeySpec = new SecretKeySpec(key, "Blowfish"); + cipher=javax.crypto.Cipher.getInstance("Blowfish/CTR/"+pad); + cipher.init((mode==ENCRYPT_MODE? + javax.crypto.Cipher.ENCRYPT_MODE: + javax.crypto.Cipher.DECRYPT_MODE), + skeySpec, new IvParameterSpec(iv)); + } + catch(Exception e){ + throw e; + } + } + @Override + public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{ + cipher.update(foo, s1, len, bar, s2); + } + @Override + public boolean isCBC(){return false; } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/DH.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/DH.java index b8a4506f..b4690b1f 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/DH.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/DH.java @@ -32,6 +32,7 @@ package com.jcraft.jsch.jce; import java.math.BigInteger; import java.security.*; import javax.crypto.*; +import javax.crypto.interfaces.*; import javax.crypto.spec.*; import com.jcraft.jsch.JSchException; @@ -46,21 +47,24 @@ public class DH implements com.jcraft.jsch.DH{ private KeyPairGenerator myKpairGen; private KeyAgreement myKeyAgree; + @Override public void init() throws Exception{ myKpairGen=KeyPairGenerator.getInstance("DH"); myKeyAgree=KeyAgreement.getInstance("DH"); } + @Override public byte[] getE() throws Exception{ if(e==null){ DHParameterSpec dhSkipParamSpec=new DHParameterSpec(p, g); myKpairGen.initialize(dhSkipParamSpec); KeyPair myKpair=myKpairGen.generateKeyPair(); myKeyAgree.init(myKpair.getPrivate()); - e=((javax.crypto.interfaces.DHPublicKey)(myKpair.getPublic())).getY(); + e=((DHPublicKey)(myKpair.getPublic())).getY(); e_array=e.toByteArray(); } return e_array; } + @Override public byte[] getK() throws Exception{ if(K==null){ KeyFactory myKeyFac=KeyFactory.getInstance("DH"); @@ -74,14 +78,18 @@ public class DH implements com.jcraft.jsch.DH{ } return K_array; } + @Override public void setP(byte[] p){ setP(new BigInteger(1, p)); } + @Override public void setG(byte[] g){ setG(new BigInteger(1, g)); } + @Override public void setF(byte[] f){ setF(new BigInteger(1, f)); } void setP(BigInteger p){this.p=p;} void setG(BigInteger g){this.g=g;} void setF(BigInteger f){this.f=f;} // e, f must be in [1, p-1]. + @Override public void checkRange() throws Exception { /* checkRange(e); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH256.java index 29c37db6..5a1f2217 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH256.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH256.java @@ -28,7 +28,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; - + public class ECDH256 extends ECDHN implements com.jcraft.jsch.ECDH { public void init() throws Exception { super.init(256); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH384.java index 2ced69b2..280efbcf 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH384.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH384.java @@ -28,7 +28,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; - + public class ECDH384 extends ECDHN implements com.jcraft.jsch.ECDH { public void init() throws Exception { super.init(384); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH521.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH521.java index cd1c9fd0..0b7dc9e5 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH521.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDH521.java @@ -28,7 +28,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.jcraft.jsch.jce; - + public class ECDH521 extends ECDHN implements com.jcraft.jsch.ECDH { public void init() throws Exception { super.init(521); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDHN.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDHN.java index 07abe309..37a6d277 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDHN.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/ECDHN.java @@ -40,6 +40,7 @@ public class ECDHN implements com.jcraft.jsch.ECDH { ECPublicKey publicKey; private KeyAgreement myKeyAgree; + @Override public void init(int size) throws Exception{ myKeyAgree = KeyAgreement.getInstance("ECDH"); KeyPairGenECDSA kpair = new KeyPairGenECDSA(); @@ -51,10 +52,12 @@ public class ECDHN implements com.jcraft.jsch.ECDH { myKeyAgree.init(kpair.getPrivateKey()); } + @Override public byte[] getQ() throws Exception{ return Q_array; } + @Override public byte[] getSecret(byte[] r, byte[] s) throws Exception{ KeyFactory kf = KeyFactory.getInstance("EC"); @@ -71,6 +74,7 @@ public class ECDHN implements com.jcraft.jsch.ECDH { // SEC 1: Elliptic Curve Cryptography, Version 2.0 // http://www.secg.org/sec1-v2.pdf // 3.2.2.1 Elliptic Curve Public Key Validation Primitive + @Override public boolean validate(byte[] r, byte[] s) throws Exception{ BigInteger x = new BigInteger(1, r); BigInteger y = new BigInteger(1, s); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMAC.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMAC.java index e13d825b..7112bfbf 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMAC.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMAC.java @@ -37,16 +37,19 @@ abstract class HMAC implements MAC { protected String name; protected int bsize; protected String algorithm; + protected boolean etm; private Mac mac; + @Override public int getBlockSize() { return bsize; }; + @Override public void init(byte[] key) throws Exception { if(key.length>bsize){ byte[] tmp = new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, bsize); + System.arraycopy(key, 0, tmp, 0, bsize); key = tmp; } SecretKeySpec skey = new SecretKeySpec(key, algorithm); @@ -55,6 +58,7 @@ abstract class HMAC implements MAC { } private final byte[] tmp = new byte[4]; + @Override public void update(int i){ tmp[0] = (byte)(i>>>24); tmp[1] = (byte)(i>>>16); @@ -63,10 +67,12 @@ abstract class HMAC implements MAC { update(tmp, 0, 4); } + @Override public void update(byte foo[], int s, int l){ mac.update(foo, s, l); } + @Override public void doFinal(byte[] buf, int offset){ try{ mac.doFinal(buf, offset); @@ -76,7 +82,13 @@ abstract class HMAC implements MAC { } } + @Override public String getName(){ return name; } + + @Override + public boolean isEtM(){ + return etm; + } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596.java index 039c3712..3c1bb7bc 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596.java @@ -34,11 +34,13 @@ public class HMACMD596 extends HMACMD5 { name="hmac-md5-96"; } + @Override public int getBlockSize(){ return 12; }; private final byte[] _buf16 = new byte[16]; + @Override public void doFinal(byte[] buf, int offset){ super.doFinal(_buf16, 0); System.arraycopy(_buf16, 0, buf, offset, 12); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java new file mode 100644 index 00000000..d6310644 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD596ETM.java @@ -0,0 +1,37 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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.jce; + +public class HMACMD596ETM extends HMACMD596 { + public HMACMD596ETM(){ + name="hmac-md5-96-etm@openssh.com"; + etm=true; + } +} 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/jce/HMACMD5ETM.java similarity index 76% rename from src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD5.java rename to src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACMD5ETM.java index 174a126e..ea21e74b 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/jce/HMACMD5ETM.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2002-2018 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: @@ -27,25 +27,15 @@ 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.jcraft; +package com.jcraft.jsch.jce; import com.jcraft.jsch.MAC; -import java.security.*; +import javax.crypto.*; +import javax.crypto.spec.*; -public class HMACMD5 extends HMAC implements MAC{ - private static final String name="hmac-md5"; - - public HMACMD5(){ - super(); - MessageDigest md=null; - try{ md=MessageDigest.getInstance("MD5"); } - catch(Exception e){ - System.err.println(e); - } - setH(md); - } - - public String getName(){ - return name; +public class HMACMD5ETM extends HMACMD5 { + public HMACMD5ETM(){ + name = "hmac-md5-etm@openssh.com"; + etm = true; } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java index 247ecb2d..a2348331 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196.java @@ -35,11 +35,13 @@ public class HMACSHA196 extends HMACSHA1 { name = "hmac-sha1-96"; } + @Override public int getBlockSize(){ return 12; }; private final byte[] _buf20 = new byte[20]; + @Override public void doFinal(byte[] buf, int offset){ super.doFinal(_buf20, 0); System.arraycopy(_buf20, 0, buf, offset, 12); diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java new file mode 100644 index 00000000..c1a0e23f --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA196ETM.java @@ -0,0 +1,38 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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.jce; + +public class HMACSHA196ETM extends HMACSHA196 { + + public HMACSHA196ETM(){ + name = "hmac-sha1-96-etm@openssh.com"; + etm = true; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java new file mode 100644 index 00000000..05db55c1 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA1ETM.java @@ -0,0 +1,37 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2002-2018 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.jce; + +public class HMACSHA1ETM extends HMACSHA1 { + public HMACSHA1ETM(){ + name = "hmac-sha1-etm@openssh.com"; + etm = true; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java new file mode 100644 index 00000000..dae8689a --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA224SSHCOM.java @@ -0,0 +1,38 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2012-2018 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.jce; + +public class HMACSHA224SSHCOM extends HMAC { + public HMACSHA224SSHCOM(){ + name = "hmac-sha224@ssh.com"; + bsize = 28; + algorithm = "HmacSHA224"; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java new file mode 100644 index 00000000..51668f21 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA2562SSHCOM.java @@ -0,0 +1,38 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2012-2018 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.jce; + +public class HMACSHA2562SSHCOM extends HMAC { + public HMACSHA2562SSHCOM(){ + name = "hmac-sha256-2@ssh.com"; + bsize = 32; + algorithm = "HmacSHA256"; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java new file mode 100644 index 00000000..8f852d06 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256ETM.java @@ -0,0 +1,37 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2012-2018 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.jce; + +public class HMACSHA256ETM extends HMACSHA256 { + public HMACSHA256ETM(){ + name = "hmac-sha2-256-etm@openssh.com"; + etm = true; + } +} 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/jce/HMACSHA256SSHCOM.java similarity index 73% rename from src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACMD596.java rename to src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA256SSHCOM.java index 5fcc225e..8d6571f2 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/jce/HMACSHA256SSHCOM.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2012-2018 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: @@ -27,24 +27,19 @@ 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.jcraft; +package com.jcraft.jsch.jce; -import com.jcraft.jsch.MAC; - -public class HMACMD596 extends HMACMD5{ - - private static final String name="hmac-md5-96"; - private static final int BSIZE=12; - - public int getBlockSize(){return BSIZE;}; - - private final byte[] _buf16=new byte[16]; - public void doFinal(byte[] buf, int offset){ - super.doFinal(_buf16, 0); - System.arraycopy(_buf16, 0, buf, offset, BSIZE); +//This MAC appears to use a shortened keysize of 16 bytes instead of 32 bytes. +//See discussion at https://github.com/ronf/asyncssh/issues/399. +public class HMACSHA256SSHCOM extends HMAC { + public HMACSHA256SSHCOM(){ + name = "hmac-sha256@ssh.com"; + bsize = 16; + algorithm = "HmacSHA256"; } - public String getName(){ - return name; - } + @Override + public int getBlockSize(){ + return 32; + }; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java new file mode 100644 index 00000000..64fe7608 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA384SSHCOM.java @@ -0,0 +1,38 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2012-2018 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.jce; + +public class HMACSHA384SSHCOM extends HMAC { + public HMACSHA384SSHCOM(){ + name = "hmac-sha384@ssh.com"; + bsize = 48; + algorithm = "HmacSHA384"; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java new file mode 100644 index 00000000..d4656e02 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512ETM.java @@ -0,0 +1,37 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2012-2018 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.jce; + +public class HMACSHA512ETM extends HMACSHA512 { + public HMACSHA512ETM(){ + name = "hmac-sha2-512-etm@openssh.com"; + etm = true; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java new file mode 100644 index 00000000..722fe92c --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/HMACSHA512SSHCOM.java @@ -0,0 +1,38 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2012-2018 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.jce; + +public class HMACSHA512SSHCOM extends HMAC { + public HMACSHA512SSHCOM(){ + name = "hmac-sha512@ssh.com"; + bsize = 64; + algorithm = "HmacSHA512"; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java index d36848d7..9f30710b 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenDSA.java @@ -39,6 +39,7 @@ public class KeyPairGenDSA implements com.jcraft.jsch.KeyPairGenDSA{ byte[] q; byte[] g; + @Override public void init(int key_size) throws Exception{ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); keyGen.initialize(key_size, new SecureRandom()); @@ -54,9 +55,14 @@ public class KeyPairGenDSA implements com.jcraft.jsch.KeyPairGenDSA{ q=params.getQ().toByteArray(); g=params.getG().toByteArray(); } + @Override public byte[] getX(){return x;} + @Override public byte[] getY(){return y;} + @Override public byte[] getP(){return p;} + @Override public byte[] getQ(){return q;} + @Override public byte[] getG(){return g;} } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java index 82d62a14..dc55ad44 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenECDSA.java @@ -41,6 +41,7 @@ public class KeyPairGenECDSA implements com.jcraft.jsch.KeyPairGenECDSA { ECPublicKey pubKey; ECPrivateKey prvKey; ECParameterSpec params; + @Override public void init(int key_size) throws Exception { String name=null; if(key_size==256) name="secp256r1"; @@ -56,7 +57,7 @@ public class KeyPairGenECDSA implements com.jcraft.jsch.KeyPairGenECDSA { prvKey = (ECPrivateKey)kp.getPrivate(); pubKey = (ECPublicKey)kp.getPublic(); params=pubKey.getParams(); - d=((ECPrivateKey)prvKey).getS().toByteArray(); + d=prvKey.getS().toByteArray(); ECPoint w = pubKey.getW(); r = w.getAffineX().toByteArray(); s = w.getAffineY().toByteArray(); @@ -70,8 +71,11 @@ public class KeyPairGenECDSA implements com.jcraft.jsch.KeyPairGenECDSA { d=insert0(d); } } + @Override public byte[] getD(){return d;} + @Override public byte[] getR(){return r;} + @Override public byte[] getS(){return s;} ECPublicKey getPublicKey(){ return pubKey; } ECPrivateKey getPrivateKey(){ return prvKey; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenRSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenRSA.java index a15d1678..34634430 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenRSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/KeyPairGenRSA.java @@ -43,6 +43,7 @@ public class KeyPairGenRSA implements com.jcraft.jsch.KeyPairGenRSA{ byte[] p; // prime p byte[] q; // prime q + @Override public void init(int key_size) throws Exception{ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(key_size, new SecureRandom()); @@ -61,12 +62,20 @@ public class KeyPairGenRSA implements com.jcraft.jsch.KeyPairGenRSA{ p=((RSAPrivateCrtKey)prvKey).getPrimeP().toByteArray(); q=((RSAPrivateCrtKey)prvKey).getPrimeQ().toByteArray(); } + @Override public byte[] getD(){return d;} + @Override public byte[] getE(){return e;} + @Override public byte[] getN(){return n;} + @Override public byte[] getC(){return c;} + @Override public byte[] getEP(){return ep;} + @Override public byte[] getEQ(){return eq;} + @Override public byte[] getP(){return p;} + @Override public byte[] getQ(){return q;} } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/MD5.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/MD5.java index 78e025f6..4c461d66 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/MD5.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/MD5.java @@ -35,17 +35,23 @@ import java.security.*; public class MD5 implements HASH{ MessageDigest md; + @Override public int getBlockSize(){return 16;} + @Override public void init() throws Exception{ try{ md=MessageDigest.getInstance("MD5"); } catch(Exception e){ System.err.println(e); } } + @Override public void update(byte[] foo, int start, int len) throws Exception{ md.update(foo, start, len); } + @Override public byte[] digest() throws Exception{ return md.digest(); } + @Override + public String name(){return "MD5";} } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/PBKDF.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/PBKDF.java index 57433afb..370eaa4a 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/PBKDF.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/PBKDF.java @@ -37,6 +37,7 @@ import java.security.spec.InvalidKeySpecException; import java.security.NoSuchAlgorithmException; public class PBKDF implements com.jcraft.jsch.PBKDF{ + @Override public byte[] getKey(byte[] _pass, byte[] salt, int iterations, int size){ char[] pass=new char[_pass.length]; for(int i = 0; i < _pass.length; i++){ diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/Random.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/Random.java index b77f22b3..ba535af5 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/Random.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/Random.java @@ -52,7 +52,7 @@ public class Random implements com.jcraft.jsch.Random{ random=SecureRandom.getInstance("SHA1PRNG"); return; } - catch(java.security.NoSuchAlgorithmException e){ + catch(NoSuchAlgorithmException e){ // System.err.println(e); } @@ -61,11 +61,12 @@ public class Random implements com.jcraft.jsch.Random{ random=SecureRandom.getInstance("IBMSecureRandom"); return; } - catch(java.security.NoSuchAlgorithmException ee){ + catch(NoSuchAlgorithmException ee){ //System.err.println(ee); } */ } + @Override public void fill(byte[] foo, int start, int len){ /* // This case will not become true in our usage. diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA1.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA1.java index 0d3997c2..00bbb845 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA1.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA1.java @@ -35,17 +35,23 @@ import java.security.*; public class SHA1 implements HASH{ MessageDigest md; + @Override public int getBlockSize(){return 20;} + @Override public void init() throws Exception{ try{ md=MessageDigest.getInstance("SHA-1"); } catch(Exception e){ System.err.println(e); } } + @Override public void update(byte[] foo, int start, int len) throws Exception{ md.update(foo, start, len); } + @Override public byte[] digest() throws Exception{ return md.digest(); } + @Override + public String name(){return "SHA1";} } 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/jce/SHA224.java similarity index 68% rename from src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/HMACSHA196.java rename to src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA224.java index 20d961b1..e7fcf883 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/jce/SHA224.java @@ -1,6 +1,6 @@ /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ /* -Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved. +Copyright (c) 2002-2018 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: @@ -27,24 +27,31 @@ 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.jcraft; +package com.jcraft.jsch.jce; -import com.jcraft.jsch.MAC; +import com.jcraft.jsch.HASH; -public class HMACSHA196 extends HMACSHA1{ +import java.security.*; - private static final String name="hmac-sha1-96"; - private static final int BSIZE=12; - - public int getBlockSize(){return BSIZE;}; - - private final byte[] _buf16=new byte[20]; - public void doFinal(byte[] buf, int offset){ - super.doFinal(_buf16, 0); - System.arraycopy(_buf16, 0, buf, offset, BSIZE); +public class SHA224 implements HASH { + MessageDigest md; + @Override + public int getBlockSize(){return 28;} + @Override + public void init() throws Exception { + try{ md=MessageDigest.getInstance("SHA-224"); } + catch(Exception e){ + System.err.println(e); + } } - - public String getName(){ - return name; + @Override + public void update(byte[] foo, int start, int len) throws Exception { + md.update(foo, start, len); } + @Override + public byte[] digest() throws Exception { + return md.digest(); + } + @Override + public String name(){return "SHA224";} } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA256.java index f2f90948..bd5da24f 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA256.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA256.java @@ -35,17 +35,23 @@ import java.security.*; public class SHA256 implements HASH { MessageDigest md; + @Override public int getBlockSize(){return 32;} + @Override public void init() throws Exception { try{ md=MessageDigest.getInstance("SHA-256"); } catch(Exception e){ System.err.println(e); } } + @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } + @Override public byte[] digest() throws Exception { return md.digest(); } + @Override + public String name(){return "SHA256";} } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA384.java index 976f9cc3..6221a7d2 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA384.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA384.java @@ -33,17 +33,23 @@ import java.security.*; public class SHA384 implements com.jcraft.jsch.HASH { MessageDigest md; + @Override public int getBlockSize(){return 48;} + @Override public void init() throws Exception { try{ md=MessageDigest.getInstance("SHA-384"); } catch(Exception e){ System.err.println(e); } } + @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } + @Override public byte[] digest() throws Exception { return md.digest(); } + @Override + public String name(){return "SHA384";} } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA512.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA512.java index 4c6b1949..a201f536 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA512.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SHA512.java @@ -33,17 +33,23 @@ import java.security.*; public class SHA512 implements com.jcraft.jsch.HASH { MessageDigest md; + @Override public int getBlockSize(){return 64;} + @Override public void init() throws Exception { try{ md=MessageDigest.getInstance("SHA-512"); } catch(Exception e){ System.err.println(e); } } + @Override public void update(byte[] foo, int start, int len) throws Exception { md.update(foo, start, len); } + @Override public byte[] digest() throws Exception { return md.digest(); } + @Override + public String name(){return "SHA512";} } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java index 94ba7dea..26df5621 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureDSA.java @@ -30,6 +30,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch.jce; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.*; import com.jcraft.jsch.Buffer; @@ -39,28 +40,32 @@ public class SignatureDSA implements com.jcraft.jsch.SignatureDSA{ java.security.Signature signature; KeyFactory keyFactory; + @Override public void init() throws Exception{ signature=java.security.Signature.getInstance("SHA1withDSA"); keyFactory=KeyFactory.getInstance("DSA"); } + @Override public void setPubKey(byte[] y, byte[] p, byte[] q, byte[] g) throws Exception{ DSAPublicKeySpec dsaPubKeySpec = - new DSAPublicKeySpec(new BigInteger(y), - new BigInteger(p), - new BigInteger(q), - new BigInteger(g)); + new DSAPublicKeySpec(new BigInteger(y), + new BigInteger(p), + new BigInteger(q), + new BigInteger(g)); PublicKey pubKey=keyFactory.generatePublic(dsaPubKeySpec); signature.initVerify(pubKey); } + @Override public void setPrvKey(byte[] x, byte[] p, byte[] q, byte[] g) throws Exception{ DSAPrivateKeySpec dsaPrivKeySpec = - new DSAPrivateKeySpec(new BigInteger(x), - new BigInteger(p), - new BigInteger(q), - new BigInteger(g)); + new DSAPrivateKeySpec(new BigInteger(x), + new BigInteger(p), + new BigInteger(q), + new BigInteger(g)); PrivateKey prvKey = keyFactory.generatePrivate(dsaPrivKeySpec); signature.initSign(prvKey); } + @Override public byte[] sign() throws Exception{ byte[] sig=signature.sign(); /* @@ -72,7 +77,7 @@ System.err.println(""); */ // sig is in ASN.1 // SEQUENCE::={ r INTEGER, s INTEGER } - int len=0; + int len=0; int index=3; len=sig[index++]&0xff; //System.err.println("! len="+len); @@ -89,27 +94,29 @@ System.err.println(""); // result must be 40 bytes, but length of r and s may not be 20 bytes System.arraycopy(r, (r.length>20)?1:0, - result, (r.length>20)?0:20-r.length, - (r.length>20)?20:r.length); + result, (r.length>20)?0:20-r.length, + (r.length>20)?20:r.length); System.arraycopy(s, (s.length>20)?1:0, - result, (s.length>20)?20:40-s.length, - (s.length>20)?20:s.length); + result, (s.length>20)?20:40-s.length, + (s.length>20)?20:s.length); // System.arraycopy(sig, (sig[3]==20?4:5), result, 0, 20); // System.arraycopy(sig, sig.length-20, result, 20, 20); return result; } + @Override public void update(byte[] foo) throws Exception{ signature.update(foo); } + @Override public boolean verify(byte[] sig) throws Exception{ int i=0; int j=0; byte[] tmp; Buffer buf=new Buffer(sig); - if(new String(buf.getString()).equals("ssh-dss")){ + if(new String(buf.getString(), StandardCharsets.UTF_8).equals("ssh-dss")){ j=buf.getInt(); i=buf.getOffSet(); tmp=new byte[j]; diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java index 3d36c841..6989de24 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA256.java @@ -29,12 +29,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch.jce; -import java.math.BigInteger; -import java.security.*; -import java.security.spec.*; -import com.jcraft.jsch.Buffer; - public class SignatureECDSA256 extends SignatureECDSAN { + @Override String getName() { return "ecdsa-sha2-nistp256"; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java index 8055d447..3ff01166 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA384.java @@ -29,12 +29,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch.jce; -import java.math.BigInteger; -import java.security.*; -import java.security.spec.*; -import com.jcraft.jsch.Buffer; - public class SignatureECDSA384 extends SignatureECDSAN { + @Override String getName() { return "ecdsa-sha2-nistp384"; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java index 7cb03c02..f6527ff4 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSA521.java @@ -29,12 +29,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.jcraft.jsch.jce; -import java.math.BigInteger; -import java.security.*; -import java.security.spec.*; -import com.jcraft.jsch.Buffer; - public class SignatureECDSA521 extends SignatureECDSAN { + @Override String getName() { return "ecdsa-sha2-nistp521"; } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java index 8037eb20..0a5dca9a 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jce/SignatureECDSAN.java @@ -34,13 +34,14 @@ import java.security.*; import java.security.spec.*; import com.jcraft.jsch.Buffer; -public abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA { +abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA { Signature signature; KeyFactory keyFactory; abstract String getName(); + @Override public void init() throws Exception{ String name = getName(); String foo="SHA256withECDSA"; @@ -49,7 +50,8 @@ public abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA signature=java.security.Signature.getInstance(foo); keyFactory=KeyFactory.getInstance("EC"); } - + + @Override public void setPubKey(byte[] r, byte[] s) throws Exception{ // r and s must be unsigned values. @@ -62,14 +64,14 @@ public abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA AlgorithmParameters param = AlgorithmParameters.getInstance("EC"); param.init(new ECGenParameterSpec(name)); - ECParameterSpec ecparam = - (ECParameterSpec)param.getParameterSpec(ECParameterSpec.class); + ECParameterSpec ecparam = 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); } + @Override public void setPrvKey(byte[] d) throws Exception{ // d must be unsigned value. @@ -81,13 +83,13 @@ public abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA AlgorithmParameters param = AlgorithmParameters.getInstance("EC"); param.init(new ECGenParameterSpec(name)); - ECParameterSpec ecparam = - (ECParameterSpec)param.getParameterSpec(ECParameterSpec.class); + ECParameterSpec ecparam = param.getParameterSpec(ECParameterSpec.class); BigInteger _d = new BigInteger(1, d); PrivateKey prvKey = keyFactory.generatePrivate(new ECPrivateKeySpec(_d, ecparam)); signature.initSign(prvKey); } + @Override public byte[] sign() throws Exception{ byte[] sig=signature.sign(); @@ -120,9 +122,11 @@ public abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA return sig; } + @Override public void update(byte[] foo) throws Exception{ signature.update(foo); } + @Override public boolean verify(byte[] sig) throws Exception{ // It seems that SunEC expects ASN.1 data, @@ -138,8 +142,8 @@ public abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA byte[] r = b.getMPInt(); byte[] s = b.getMPInt(); - r=insert0(r); - s=insert0(s); + r=trimLeadingZeros(insert0(r)); + s=trimLeadingZeros(insert0(s)); byte[] asn1 = null; if(r.length<64){ @@ -171,14 +175,15 @@ public abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA return signature.verify(sig); } - private byte[] insert0(byte[] buf){ + private static 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){ + + private static 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); @@ -186,7 +191,24 @@ public abstract class SignatureECDSAN implements com.jcraft.jsch.SignatureECDSA return tmp; } - private void bzero(byte[] buf){ + private static void bzero(byte[] buf){ for(int i = 0; ibsize){ - byte[] tmp=new byte[bsize]; - System.arraycopy(key, 0, tmp, 0, bsize); - key=tmp; - } - - /* if key is longer than B bytes reset it to key=MD5(key) */ - if(key.length>B){ - md.update(key, 0, key.length); - key=md.digest(); - } - - k_ipad=new byte[B]; - System.arraycopy(key, 0, k_ipad, 0, key.length); - k_opad=new byte[B]; - System.arraycopy(key, 0, k_opad, 0, key.length); - - /* XOR key with ipad and opad values */ - for(int i=0; i>>24); - tmp[1]=(byte)(i>>>16); - tmp[2]=(byte)(i>>>8); - tmp[3]=(byte)i; - update(tmp, 0, 4); - } - - public void update(byte foo[], int s, int l){ - md.update(foo, s, l); - } - - public void doFinal(byte[] buf, int offset){ - byte[] result=md.digest(); - md.update(k_opad, 0, B); - md.update(result, 0, bsize); - try{md.digest(buf, offset, bsize);}catch(Exception e){} - md.update(k_ipad, 0, B); - } -} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/juz/Compression.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/juz/Compression.java new file mode 100644 index 00000000..9bfe26e4 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/juz/Compression.java @@ -0,0 +1,141 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +package com.jcraft.jsch.juz; + +import com.jcraft.jsch.*; +import java.util.function.Supplier; +import java.util.zip.Deflater; +import java.util.zip.Inflater; + +/** + * This example demonstrates the packet compression without using jzlib[1]. + * + * The ssh protocol adopts zlib[2] for the packet compression. Fortunately, + * JDK has provided wrapper classes for zlib(j.u.z.{Deflater, Inflater}), + * but it does not expose enough functionality of zlib, unfortunately; + * it must not allow to compress data with SYNC_FLUSH. So, JSch has been + * using jzlib by the default. After 12 years of bug parade entry[3] filing, + * Java7 has revised j.u.z.Deflater, and SYNC_FLUSH has been supported at last. + * This example shows how to enable the packet compression by using JDK's + * java.util.zip package. + * + * + * [1] http://www.jcraft.com/jzlib/ + * [2] http://www.zlib.net/ + * [3] https://bugs.openjdk.java.net/browse/JDK-4206909 + */ +public class Compression implements com.jcraft.jsch.Compression { + static private final int BUF_SIZE=4096; + private final int buffer_margin=32+20; // AES256 + HMACSHA1 + private Deflater deflater; + private Inflater inflater; + private byte[] tmpbuf=new byte[BUF_SIZE]; + private byte[] inflated_buf; + private Session session; + + public Compression(){ + } + + private void logMessage(int level, Supplier message) { + Logger logger = session == null ? JSch.getLogger() : session.getLogger(); + if (!logger.isEnabled(level)) { + return; + } + logger.log(level, message.get()); + } + + @Override + public void end() { + inflated_buf=null; + if(inflater!=null){ + inflater.end(); + inflater=null; + } + if(deflater!=null){ + deflater.end(); + deflater=null; + } + session=null; + } + + @Override + public void init(int type, int level, Session session){ + this.session = session; + init(type, level); + } + + @Override + public void init(int type, int level){ + if(type==DEFLATER){ + deflater=new Deflater(level); + } + else if(type==INFLATER){ + inflater=new Inflater(); + inflated_buf=new byte[BUF_SIZE]; + } + logMessage(Logger.DEBUG, () -> "zlib using "+this.getClass().getCanonicalName()); + } + + @Override + public byte[] compress(byte[] buf, int start, int[] end){ + + // There may be a bug in j.u.z.Deflater. + // It seems to me that if the size of buffer for Deflater#deflate() is + // not enough, that method will return weird value ;-( + if(tmpbuf.length0); + } + catch(java.util.zip.DataFormatException e){ + logMessage(Logger.WARN, () -> "an exception during uncompress\n"+e.toString()); + } + + if(buf.length>16)&0xffff; + } + + @Override + public void reset(){ + s1=1L; + s2=0L; + } + + @Override + public long getValue(){ + return ((s2<<16)|s1); + } + + @Override + public void update(byte[] buf, int index, int len){ + + if(len==1){ + s1+=buf[index++]&0xff; s2+=s1; + s1%=BASE; + s2%=BASE; + return; + } + + int len1 = len/NMAX; + int len2 = len%NMAX; + while(len1-->0) { + int k=NMAX; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + int k=len2; + len-=k; + while(k-->0){ + s1+=buf[index++]&0xff; s2+=s1; + } + s1%=BASE; + s2%=BASE; + } + + @Override + public Adler32 copy(){ + Adler32 foo = new Adler32(); + foo.s1 = this.s1; + foo.s2 = this.s2; + return foo; + } + + // The following logic has come from zlib.1.2. + static long combine(long adler1, long adler2, long len2){ + long BASEL = (long)BASE; + long sum1; + long sum2; + long rem; // unsigned int + + rem = len2 % BASEL; + sum1 = adler1 & 0xffffL; + sum2 = rem * sum1; + sum2 %= BASEL; // MOD(sum2); + sum1 += (adler2 & 0xffffL) + BASEL - 1; + sum2 += ((adler1 >> 16) & 0xffffL) + ((adler2 >> 16) & 0xffffL) + BASEL - rem; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum1 >= BASEL) sum1 -= BASEL; + if (sum2 >= (BASEL << 1)) sum2 -= (BASEL << 1); + if (sum2 >= BASEL) sum2 -= BASEL; + return sum1 | (sum2 << 16); + } + +/* + private java.util.zip.Adler32 adler=new java.util.zip.Adler32(); + void update(byte[] buf, int index, int len){ + if(buf==null) {adler.reset();} + else{adler.update(buf, index, len);} + } + void reset(){ + adler.reset(); + } + void reset(long init){ + if(init==1L){ + adler.reset(); + } + else{ + System.err.println("unsupported operation"); + } + } + long getValue(){ + return adler.getValue(); + } +*/ +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/CRC32.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/CRC32.java new file mode 100644 index 00000000..969030bc --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/CRC32.java @@ -0,0 +1,184 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class CRC32 implements Checksum { + + /* + * The following logic has come from RFC1952. + */ + private int v = 0; + private static int[] crc_table = null; + static { + crc_table = new int[256]; + for (int n = 0; n < 256; n++) { + int c = n; + for (int k = 8; --k >= 0; ) { + if ((c & 1) != 0) + c = 0xedb88320 ^ (c >>> 1); + else + c = c >>> 1; + } + crc_table[n] = c; + } + } + + @Override + public void update (byte[] buf, int index, int len) { + int c = ~v; + while (--len >= 0) + c = crc_table[(c^buf[index++])&0xff]^(c >>> 8); + v = ~c; + } + + @Override + public void reset(){ + v = 0; + } + + @Override + public void reset(long vv){ + v = (int)(vv&0xffffffffL); + } + + @Override + public long getValue(){ + return v&0xffffffffL; + } + + // The following logic has come from zlib.1.2. + private static final int GF2_DIM = 32; + static long combine(long crc1, long crc2, long len2){ + long row; + long[] even = new long[GF2_DIM]; + long[] odd = new long[GF2_DIM]; + + // degenerate case (also disallow negative lengths) + if (len2 <= 0) + return crc1; + + // put operator for one zero bit in odd + odd[0] = 0xedb88320L; // CRC-32 polynomial + row = 1; + for (int n = 1; n < GF2_DIM; n++) { + odd[n] = row; + row <<= 1; + } + + // put operator for two zero bits in even + gf2_matrix_square(even, odd); + + // put operator for four zero bits in odd + gf2_matrix_square(odd, even); + + // apply len2 zeros to crc1 (first square will put the operator for one + // zero byte, eight zero bits, in even) + do { + // apply zeros operator for this bit of len2 + gf2_matrix_square(even, odd); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; + + // if no more bits set, then done + if (len2 == 0) + break; + + // another iteration of the loop with odd and even swapped + gf2_matrix_square(odd, even); + if ((len2 & 1)!=0) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; + + // if no more bits set, then done + } while (len2 != 0); + + /* return combined crc */ + crc1 ^= crc2; + return crc1; + } + + private static long gf2_matrix_times(long[] mat, long vec){ + long sum = 0; + int index = 0; + while (vec!=0) { + if ((vec & 1)!=0) + sum ^= mat[index]; + vec >>= 1; + index++; + } + return sum; + } + + static final void gf2_matrix_square(long[] square, long[] mat) { + for (int n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); + } + + /* + private java.util.zip.CRC32 crc32 = new java.util.zip.CRC32(); + + void update(byte[] buf, int index, int len){ + if(buf==null) {crc32.reset();} + else{crc32.update(buf, index, len);} + } + void reset(){ + crc32.reset(); + } + void reset(long init){ + if(init==0L){ + crc32.reset(); + } + else{ + System.err.println("unsupported operation"); + } + } + long getValue(){ + return crc32.getValue(); + } +*/ + @Override + public CRC32 copy(){ + CRC32 foo = new CRC32(); + foo.v = this.v; + return foo; + } + + static int[] getCRC32Table(){ + int[] tmp = new int[crc_table.length]; + System.arraycopy(crc_table, 0, tmp, 0, tmp.length); + return tmp; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Checksum.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Checksum.java new file mode 100644 index 00000000..013c1b2f --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Checksum.java @@ -0,0 +1,43 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +interface Checksum { + void update(byte[] buf, int index, int len); + void reset(); + void reset(long init); + long getValue(); + Checksum copy(); +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/Compression.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Compression.java similarity index 54% rename from src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/Compression.java rename to src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Compression.java index a973fb9a..206fe172 100644 --- a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jcraft/Compression.java +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Compression.java @@ -27,52 +27,87 @@ 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.jcraft; -import com.jcraft.jzlib.*; -import com.jcraft.jsch.*; +package com.jcraft.jsch.jzlib; + +import java.util.function.Supplier; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.Logger; +import com.jcraft.jsch.Session; +import java.io.UncheckedIOException; public class Compression implements com.jcraft.jsch.Compression { static private final int BUF_SIZE=4096; private final int buffer_margin=32+20; // AES256 + HMACSHA1 - private int type; - private ZStream stream; + private Deflater deflater; + private Inflater inflater; private byte[] tmpbuf=new byte[BUF_SIZE]; + private byte[] inflated_buf; + private Session session; public Compression(){ - stream=new ZStream(); } - public void init(int type, int level){ + private void logMessage(int level, Supplier message) { + Logger logger = session == null ? JSch.getLogger() : session.getLogger(); + if (!logger.isEnabled(level)) { + return; + } + logger.log(level, message.get()); + } + + @Override + public void end() { + inflated_buf=null; + if(inflater!=null){ + inflater.end(); + inflater=null; + } + if(deflater!=null){ + deflater.end(); + deflater=null; + } + session=null; + } + + @Override + public void init(int type, int level, Session session) { + this.session = session; + init(type, level); + } + + public void init(int type, int level) throws UncheckedIOException { if(type==DEFLATER){ - stream.deflateInit(level); - this.type=DEFLATER; + try{ + deflater=new Deflater(level); + } + catch(GZIPException e){ + throw new UncheckedIOException(e); + } } else if(type==INFLATER){ - stream.inflateInit(); + inflater=new Inflater(); inflated_buf=new byte[BUF_SIZE]; - this.type=INFLATER; } + logMessage(Logger.DEBUG, () -> "zlib using "+this.getClass().getCanonicalName()); } - private byte[] inflated_buf; - + @Override public byte[] compress(byte[] buf, int start, int[] len){ - stream.next_in=buf; - stream.next_in_index=start; - stream.avail_in=len[0]-start; - int status; + deflater.next_in=buf; + deflater.next_in_index=start; + deflater.avail_in=len[0]-start; int outputlen=start; byte[] outputbuf=buf; int tmp=0; do{ - stream.next_out=tmpbuf; - stream.next_out_index=0; - stream.avail_out=BUF_SIZE; - status=stream.deflate(JZlib.Z_PARTIAL_FLUSH); + deflater.next_out=tmpbuf; + deflater.next_out_index=0; + deflater.avail_out=BUF_SIZE; + int status=deflater.deflate(JZlib.Z_PARTIAL_FLUSH); switch(status){ case JZlib.Z_OK: - tmp=BUF_SIZE-stream.avail_out; + tmp=BUF_SIZE-deflater.avail_out; if(outputbuf.length "compress: deflate returnd "+status); } } - while(stream.avail_out==0); + while(deflater.avail_out==0); len[0]=outputlen; return outputbuf; } + @Override public byte[] uncompress(byte[] buffer, int start, int[] length){ int inflated_end=0; - stream.next_in=buffer; - stream.next_in_index=start; - stream.avail_in=length[0]; + inflater.next_in=buffer; + inflater.next_in_index=start; + inflater.avail_in=length[0]; while(true){ - stream.next_out=tmpbuf; - stream.next_out_index=0; - stream.avail_out=BUF_SIZE; - int status=stream.inflate(JZlib.Z_PARTIAL_FLUSH); + inflater.next_out=tmpbuf; + inflater.next_out_index=0; + inflater.avail_out=BUF_SIZE; + int status=inflater.inflate(JZlib.Z_PARTIAL_FLUSH); switch(status){ case JZlib.Z_OK: - if(inflated_buf.lengthbuffer.length-start){ byte[] foo=new byte[inflated_end+start]; System.arraycopy(buffer, 0, foo, 0, start); System.arraycopy(inflated_buf, 0, foo, start, inflated_end); - buffer=foo; - } - else{ + buffer=foo; + } + else{ System.arraycopy(inflated_buf, 0, buffer, start, inflated_end); - } + } length[0]=inflated_end; - return buffer; - default: - System.err.println("uncompress: inflate returnd "+status); - return null; + return buffer; + default: + logMessage(Logger.WARN, () -> "compress: deflate returnd "+status); + return null; } } } diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflate.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflate.java new file mode 100644 index 00000000..f30f274e --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflate.java @@ -0,0 +1,1756 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000-2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class Deflate implements Cloneable { + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_DEFAULT_COMPRESSION=-1; + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_MEM_LEVEL=8; + + static class Config{ + int good_length; // reduce lazy search above this match length + int max_lazy; // do not perform lazy search above this match length + int nice_length; // quit search above this match length + int max_chain; + int func; + Config(int good_length, int max_lazy, + int nice_length, int max_chain, int func){ + this.good_length=good_length; + this.max_lazy=max_lazy; + this.nice_length=nice_length; + this.max_chain=max_chain; + this.func=func; + } + } + + static final private int STORED=0; + static final private int FAST=1; + static final private int SLOW=2; + static final private Config[] config_table; + static{ + config_table=new Config[10]; + // good lazy nice chain + config_table[0]=new Config(0, 0, 0, 0, STORED); + config_table[1]=new Config(4, 4, 8, 4, FAST); + config_table[2]=new Config(4, 5, 16, 8, FAST); + config_table[3]=new Config(4, 6, 32, 32, FAST); + + config_table[4]=new Config(4, 4, 16, 16, SLOW); + config_table[5]=new Config(8, 16, 32, 32, SLOW); + config_table[6]=new Config(8, 16, 128, 128, SLOW); + config_table[7]=new Config(8, 32, 128, 256, SLOW); + config_table[8]=new Config(32, 128, 258, 1024, SLOW); + config_table[9]=new Config(32, 258, 258, 4096, SLOW); + } + + static final private String[] z_errmsg = { + "need dictionary", // Z_NEED_DICT 2 + "stream end", // Z_STREAM_END 1 + "", // Z_OK 0 + "file error", // Z_ERRNO (-1) + "stream error", // Z_STREAM_ERROR (-2) + "data error", // Z_DATA_ERROR (-3) + "insufficient memory", // Z_MEM_ERROR (-4) + "buffer error", // Z_BUF_ERROR (-5) + "incompatible version",// Z_VERSION_ERROR (-6) + "" + }; + + // block not completed, need more input or more output + static final private int NeedMore=0; + + // block flush performed + static final private int BlockDone=1; + + // finish started, need only more output at next deflate + static final private int FinishStarted=2; + + // finish done, accept no more input or output + static final private int FinishDone=3; + + // preset dictionary flag in zlib header + static final private int PRESET_DICT=0x20; + + static final private int Z_FILTERED=1; + static final private int Z_HUFFMAN_ONLY=2; + static final private int Z_DEFAULT_STRATEGY=0; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final private int INIT_STATE=42; + static final private int BUSY_STATE=113; + static final private int FINISH_STATE=666; + + // The deflate compression method + static final private int Z_DEFLATED=8; + + static final private int STORED_BLOCK=0; + static final private int STATIC_TREES=1; + static final private int DYN_TREES=2; + + // The three kinds of block type + static final private int Z_BINARY=0; + static final private int Z_ASCII=1; + static final private int Z_UNKNOWN=2; + + static final private int Buf_size=8*2; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + static final private int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + static final private int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + static final private int REPZ_11_138=18; + + static final private int MIN_MATCH=3; + static final private int MAX_MATCH=258; + static final private int MIN_LOOKAHEAD=(MAX_MATCH+MIN_MATCH+1); + + static final private int MAX_BITS=15; + static final private int D_CODES=30; + static final private int BL_CODES=19; + static final private int LENGTH_CODES=29; + static final private int LITERALS=256; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + static final private int HEAP_SIZE=(2*L_CODES+1); + + static final private int END_BLOCK=256; + + ZStream strm; // pointer back to this zlib stream + int status; // as the name implies + byte[] pending_buf; // output still pending + int pending_buf_size; // size of pending_buf + int pending_out; // next pending byte to output to the stream + int pending; // nb of bytes in the pending buffer + int wrap = 1; + byte data_type; // UNKNOWN, BINARY or ASCII + byte method; // STORED (for zip only) or DEFLATED + int last_flush; // value of flush param for previous deflate call + + int w_size; // LZ77 window size (32K by default) + int w_bits; // log2(w_size) (8..16) + int w_mask; // w_size - 1 + + byte[] window; + // Sliding window. Input bytes are read into the second half of the window, + // and move to the first half later to keep a dictionary of at least wSize + // bytes. With this organization, matches are limited to a distance of + // wSize-MAX_MATCH bytes, but this ensures that IO is always + // performed with a length multiple of the block size. Also, it limits + // the window size to 64K, which is quite useful on MSDOS. + // To do: use the user input buffer as sliding window. + + int window_size; + // Actual size of window: 2*wSize, except when the user input buffer + // is directly used as sliding window. + + short[] prev; + // Link to older string with same hash index. To limit the size of this + // array to 64K, this link is maintained only for the last 32K strings. + // An index in this array is thus a window index modulo 32K. + + short[] head; // Heads of the hash chains or NIL. + + int ins_h; // hash index of string to be inserted + int hash_size; // number of elements in hash table + int hash_bits; // log2(hash_size) + int hash_mask; // hash_size-1 + + // Number of bits by which ins_h must be shifted at each input + // step. It must be such that after MIN_MATCH steps, the oldest + // byte no longer takes part in the hash key, that is: + // hash_shift * MIN_MATCH >= hash_bits + int hash_shift; + + // Window position at the beginning of the current output block. Gets + // negative when the window is moved backwards. + + int block_start; + + int match_length; // length of best match + int prev_match; // previous match + int match_available; // set if previous match exists + int strstart; // start of string to insert + int match_start; // start of matching string + int lookahead; // number of valid bytes ahead in window + + // Length of the best match at previous step. Matches not greater than this + // are discarded. This is used in the lazy match evaluation. + int prev_length; + + // To speed up deflation, hash chains are never searched beyond this + // length. A higher limit improves compression ratio but degrades the speed. + int max_chain_length; + + // Attempt to find a better match only when the current match is strictly + // smaller than this value. This mechanism is used only for compression + // levels >= 4. + int max_lazy_match; + + // Insert new strings in the hash table only if the match length is not + // greater than this length. This saves time but degrades compression. + // max_insert_length is used only for compression levels <= 3. + + int level; // compression level (1..9) + int strategy; // favor or force Huffman coding + + // Use a faster search when the previous match is longer than this + int good_match; + + // Stop searching when current match exceeds this + int nice_match; + + short[] dyn_ltree; // literal and length tree + short[] dyn_dtree; // distance tree + short[] bl_tree; // Huffman tree for bit lengths + + Tree l_desc=new Tree(); // desc for literal tree + Tree d_desc=new Tree(); // desc for distance tree + Tree bl_desc=new Tree(); // desc for bit length tree + + // number of codes at each bit length for an optimal tree + short[] bl_count=new short[MAX_BITS+1]; + // working area to be used in Tree#gen_codes() + short[] next_code=new short[MAX_BITS+1]; + + // heap used to build the Huffman trees + int[] heap=new int[2*L_CODES+1]; + + int heap_len; // number of elements in the heap + int heap_max; // element of largest frequency + // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + // The same heap array is used to build all trees. + + // Depth of each subtree used as tie breaker for trees of equal frequency + byte[] depth=new byte[2*L_CODES+1]; + + byte[] l_buf; // index for literals or lengths */ + + // Size of match buffer for literals/lengths. There are 4 reasons for + // limiting lit_bufsize to 64K: + // - frequencies can be kept in 16 bit counters + // - if compression is not successful for the first block, all input + // data is still in the window so we can still emit a stored block even + // when input comes from standard input. (This can also be done for + // all blocks if lit_bufsize is not greater than 32K.) + // - if compression is not successful for a file smaller than 64K, we can + // even emit a stored file instead of a stored block (saving 5 bytes). + // This is applicable only for zip (not gzip or zlib). + // - creating new Huffman trees less frequently may not provide fast + // adaptation to changes in the input data statistics. (Take for + // example a binary file with poorly compressible code followed by + // a highly compressible string table.) Smaller buffer sizes give + // fast adaptation but have of course the overhead of transmitting + // trees more frequently. + // - I can't count above 4 + int lit_bufsize; + + int last_lit; // running index in l_buf + + // Buffer for distances. To simplify the code, d_buf and l_buf have + // the same number of elements. To use different lengths, an extra flag + // array would be necessary. + + int d_buf; // index of pendig_buf + + int opt_len; // bit length of current block with optimal trees + int static_len; // bit length of current block with static trees + int matches; // number of string matches in current block + int last_eob_len; // bit length of EOB code for last block + + // Output buffer. bits are inserted starting at the bottom (least + // significant bits). + short bi_buf; + + // Number of valid bits in bi_buf. All bits above the last valid bit + // are always zero. + int bi_valid; + + GZIPHeader gheader = null; + + Deflate(ZStream strm){ + this.strm=strm; + dyn_ltree=new short[HEAP_SIZE*2]; + dyn_dtree=new short[(2*D_CODES+1)*2]; // distance tree + bl_tree=new short[(2*BL_CODES+1)*2]; // Huffman tree for bit lengths + } + + void lm_init() { + window_size=2*w_size; + + head[hash_size-1]=0; + for(int i=0; i= 3; max_blindex--) { + if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; + } + // Update opt_len to include the bit length tree and counts + opt_len += 3*(max_blindex+1) + 5+5+4; + + return max_blindex; + } + + + // Send the header for a block using dynamic Huffman trees: the counts, the + // lengths of the bit length codes, the literal tree and the distance tree. + // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + void send_all_trees(int lcodes, int dcodes, int blcodes){ + int rank; // index in bl_order + + send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt + send_bits(dcodes-1, 5); + send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt + for (rank = 0; rank < blcodes; rank++) { + send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); + } + send_tree(dyn_ltree, lcodes-1); // literal tree + send_tree(dyn_dtree, dcodes-1); // distance tree + } + + // Send a literal or distance tree in compressed form, using the codes in + // bl_tree. + void send_tree (short[] tree,// the tree to be sent + int max_code // and its largest code of non zero frequency + ){ + int n; // iterates over all tree elements + int prevlen = -1; // last emitted length + int curlen; // length of current code + int nextlen = tree[0*2+1]; // length of next code + int count = 0; // repeat count of the current code + int max_count = 7; // max repeat count + int min_count = 4; // min repeat count + + if (nextlen == 0){ max_count = 138; min_count = 3; } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[(n+1)*2+1]; + if(++count < max_count && curlen == nextlen) { + continue; + } + else if(count < min_count) { + do { send_code(curlen, bl_tree); } while (--count != 0); + } + else if(curlen != 0){ + if(curlen != prevlen){ + send_code(curlen, bl_tree); count--; + } + send_code(REP_3_6, bl_tree); + send_bits(count-3, 2); + } + else if(count <= 10){ + send_code(REPZ_3_10, bl_tree); + send_bits(count-3, 3); + } + else{ + send_code(REPZ_11_138, bl_tree); + send_bits(count-11, 7); + } + count = 0; prevlen = curlen; + if(nextlen == 0){ + max_count = 138; min_count = 3; + } + else if(curlen == nextlen){ + max_count = 6; min_count = 3; + } + else{ + max_count = 7; min_count = 4; + } + } + } + + // Output a byte on the stream. + // IN assertion: there is enough room in pending_buf. + final void put_byte(byte[] p, int start, int len){ + System.arraycopy(p, start, pending_buf, pending, len); + pending+=len; + } + + final void put_byte(byte c){ + pending_buf[pending++]=c; + } + final void put_short(int w) { + put_byte((byte)(w/*&0xff*/)); + put_byte((byte)(w>>>8)); + } + final void putShortMSB(int b){ + put_byte((byte)(b>>8)); + put_byte((byte)(b/*&0xff*/)); + } + + final void send_code(int c, short[] tree){ + int c2=c*2; + send_bits((tree[c2]&0xffff), (tree[c2+1]&0xffff)); + } + + void send_bits(int value, int length){ + int len = length; + if (bi_valid > Buf_size - len) { + int val = value; +// bi_buf |= (val << bi_valid); + bi_buf |= ((val << bi_valid)&0xffff); + put_short(bi_buf); + bi_buf = (short)(val >>> (Buf_size - bi_valid)); + bi_valid += len - Buf_size; + } else { +// bi_buf |= (value) << bi_valid; + bi_buf |= (((value) << bi_valid)&0xffff); + bi_valid += len; + } + } + + // Send one empty static block to give enough lookahead for inflate. + // This takes 10 bits, of which 7 may remain in the bit buffer. + // The current inflate code requires 9 bits of lookahead. If the + // last two codes for the previous block (real code plus EOB) were coded + // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + // the last real code. In this case we send two empty static blocks instead + // of one. (There are no problems if the previous block is stored or fixed.) + // To simplify the code, we assume the worst case of last real code encoded + // on one bit only. + void _tr_align(){ + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + + bi_flush(); + + // Of the 10 bits for the empty block, we have already sent + // (10 - bi_valid) bits. The lookahead for the last real code (before + // the EOB of the previous block) was thus at least one plus the length + // of the EOB plus what we have just sent of the empty static block. + if (1 + last_eob_len + 10 - bi_valid < 9) { + send_bits(STATIC_TREES<<1, 3); + send_code(END_BLOCK, StaticTree.static_ltree); + bi_flush(); + } + last_eob_len = 7; + } + + + // Save the match info and tally the frequency counts. Return true if + // the current block must be flushed. + boolean _tr_tally (int dist, // distance of matched string + int lc // match length-MIN_MATCH or unmatched char (if dist==0) + ){ + + pending_buf[d_buf+last_lit*2] = (byte)(dist>>>8); + pending_buf[d_buf+last_lit*2+1] = (byte)dist; + + l_buf[last_lit] = (byte)lc; last_lit++; + + if (dist == 0) { + // lc is the unmatched char + dyn_ltree[lc*2]++; + } + else { + matches++; + // Here, lc is the match length - MIN_MATCH + dist--; // dist = match distance - 1 + dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; + dyn_dtree[Tree.d_code(dist)*2]++; + } + + if ((last_lit & 0x1fff) == 0 && level > 2) { + // Compute an upper bound for the compressed length + int out_length = last_lit*8; + int in_length = strstart - block_start; + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (int)dyn_dtree[dcode*2] * + (5L+Tree.extra_dbits[dcode]); + } + out_length >>>= 3; + if ((matches < (last_lit/2)) && out_length < in_length/2) return true; + } + + return (last_lit == lit_bufsize-1); + // We avoid equality with lit_bufsize because of wraparound at 64K + // on 16 bit machines and because stored blocks are restricted to + // 64K-1 bytes. + } + + // Send the block data compressed using the given Huffman trees + void compress_block(short[] ltree, short[] dtree){ + int dist; // distance of matched string + int lc; // match length or unmatched char (if dist == 0) + int lx = 0; // running index in l_buf + int code; // the code to send + int extra; // number of extra bits to send + + if (last_lit != 0){ + do{ + dist=((pending_buf[d_buf+lx*2]<<8)&0xff00)| + (pending_buf[d_buf+lx*2+1]&0xff); + lc=(l_buf[lx])&0xff; lx++; + + if(dist == 0){ + send_code(lc, ltree); // send a literal byte + } + else{ + // Here, lc is the match length - MIN_MATCH + code = Tree._length_code[lc]; + + send_code(code+LITERALS+1, ltree); // send the length code + extra = Tree.extra_lbits[code]; + if(extra != 0){ + lc -= Tree.base_length[code]; + send_bits(lc, extra); // send the extra length bits + } + dist--; // dist is now the match distance - 1 + code = Tree.d_code(dist); + + send_code(code, dtree); // send the distance code + extra = Tree.extra_dbits[code]; + if (extra != 0) { + dist -= Tree.base_dist[code]; + send_bits(dist, extra); // send the extra distance bits + } + } // literal or match pair ? + + // Check that the overlay between pending_buf and d_buf+l_buf is ok: + } + while (lx < last_lit); + } + + send_code(END_BLOCK, ltree); + last_eob_len = ltree[END_BLOCK*2+1]; + } + + // Set the data type to ASCII or BINARY, using a crude approximation: + // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + // IN assertion: the fields freq of dyn_ltree are set and the total of all + // frequencies does not exceed 64K (to fit in an int on 16 bit machines). + void set_data_type(){ + int n = 0; + int ascii_freq = 0; + int bin_freq = 0; + while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} + while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} + while(n (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); + } + + // Flush the bit buffer, keeping at most 7 bits in it. + void bi_flush(){ + if (bi_valid == 16) { + put_short(bi_buf); + bi_buf=0; + bi_valid=0; + } + else if (bi_valid >= 8) { + put_byte((byte)bi_buf); + bi_buf>>>=8; + bi_valid-=8; + } + } + + // Flush the bit buffer and align the output on a byte boundary + void bi_windup(){ + if (bi_valid > 8) { + put_short(bi_buf); + } else if (bi_valid > 0) { + put_byte((byte)bi_buf); + } + bi_buf = 0; + bi_valid = 0; + } + + // Copy a stored block, storing first the length and its + // one's complement if requested. + void copy_block(int buf, // the input data + int len, // its length + boolean header // true if block header must be written + ){ + int index=0; + bi_windup(); // align on byte boundary + last_eob_len = 8; // enough lookahead for inflate + + if (header) { + put_short((short)len); + put_short((short)~len); + } + + // while(len--!=0) { + // put_byte(window[buf+index]); + // index++; + // } + put_byte(window, buf, len); + } + + void flush_block_only(boolean eof){ + _tr_flush_block(block_start>=0 ? block_start : -1, + strstart-block_start, + eof); + block_start=strstart; + strm.flush_pending(); + } + + // Copy without compression as much as possible from the input stream, return + // the current block state. + // This function does not insert new strings in the dictionary since + // uncompressible data is probably not useful. This function is used + // only for the level=0 compression option. + // NOTE: this function should be optimized to avoid extra copying from + // window to pending_buf. + int deflate_stored(int flush){ + // Stored blocks are limited to 0xffff bytes, pending_buf is limited + // to pending_buf_size, and each stored block has a 5 byte header: + + int max_block_size = 0xffff; + int max_start; + + if(max_block_size > pending_buf_size - 5) { + max_block_size = pending_buf_size - 5; + } + + // Copy as much as possible from input to output: + while(true){ + // Fill the window as much as possible: + if(lookahead<=1){ + fill_window(); + if(lookahead==0 && flush==Z_NO_FLUSH) return NeedMore; + if(lookahead==0) break; // flush the current block + } + + strstart+=lookahead; + lookahead=0; + + // Emit a stored block if pending_buf will be full: + max_start=block_start+max_block_size; + if(strstart==0|| strstart>=max_start) { + // strstart == 0 is possible when wraparound on 16-bit machine + lookahead = strstart-max_start; + strstart = max_start; + + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + + } + + // Flush if we may have to slide, otherwise block_start may become + // negative and the data will be gone: + if(strstart-block_start >= w_size-MIN_LOOKAHEAD) { + flush_block_only(false); + if(strm.avail_out==0) return NeedMore; + } + } + + flush_block_only(flush == Z_FINISH); + if(strm.avail_out==0) + return (flush == Z_FINISH) ? FinishStarted : NeedMore; + + return flush == Z_FINISH ? FinishDone : BlockDone; + } + + // Send a stored block + void _tr_stored_block(int buf, // input block + int stored_len, // length of input block + boolean eof // true if this is the last block for a file + ){ + send_bits((STORED_BLOCK<<1)+(eof?1:0), 3); // send block type + copy_block(buf, stored_len, true); // with header + } + + // Determine the best encoding for the current block: dynamic trees, static + // trees or store, and output the encoded block to the zip file. + void _tr_flush_block(int buf, // input block, or NULL if too old + int stored_len, // length of input block + boolean eof // true if this is the last block for a file + ) { + int opt_lenb, static_lenb;// opt_len and static_len in bytes + int max_blindex = 0; // index of last bit length code of non zero freq + + // Build the Huffman trees unless a stored block is forced + if(level > 0) { + // Check if the file is ascii or binary + if(data_type == Z_UNKNOWN) set_data_type(); + + // Construct the literal and distance trees + l_desc.build_tree(this); + + d_desc.build_tree(this); + + // At this point, opt_len and static_len are the total bit lengths of + // the compressed block data, excluding the tree representations. + + // Build the bit length tree for the above two trees, and get the index + // in bl_order of the last bit length code to send. + max_blindex=build_bl_tree(); + + // Determine the best encoding. Compute first the block length in bytes + opt_lenb=(opt_len+3+7)>>>3; + static_lenb=(static_len+3+7)>>>3; + + if(static_lenb<=opt_lenb) opt_lenb=static_lenb; + } + else { + opt_lenb=static_lenb=stored_len+5; // force a stored block + } + + if(stored_len+4<=opt_lenb && buf != -1){ + // 4: two words for the lengths + // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + // Otherwise we can't have processed more than WSIZE input bytes since + // the last block flush, because compression would have been + // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + // transform a block into a stored block. + _tr_stored_block(buf, stored_len, eof); + } + else if(static_lenb == opt_lenb){ + send_bits((STATIC_TREES<<1)+(eof?1:0), 3); + compress_block(StaticTree.static_ltree, StaticTree.static_dtree); + } + else{ + send_bits((DYN_TREES<<1)+(eof?1:0), 3); + send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1); + compress_block(dyn_ltree, dyn_dtree); + } + + // The above check is made mod 2^32, for files larger than 512 MB + // and uLong implemented on 32 bits. + + init_block(); + + if(eof){ + bi_windup(); + } + } + + // Fill the window when the lookahead becomes insufficient. + // Updates strstart and lookahead. + // + // IN assertion: lookahead < MIN_LOOKAHEAD + // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + // At least one byte has been read, or avail_in == 0; reads are + // performed for at least two bytes (required for the zip translate_eol + // option -- not supported here). + void fill_window(){ + int n, m; + int p; + int more; // Amount of free space at the end of the window. + + do{ + more = (window_size-lookahead-strstart); + + // Deal with !@#$% 64K limit: + if(more==0 && strstart==0 && lookahead==0){ + more = w_size; + } + else if(more==-1) { + // Very unlikely, but possible on 16 bit machine if strstart == 0 + // and lookahead == 1 (input done one byte at time) + more--; + + // If the window is almost full and there is insufficient lookahead, + // move the upper half to the lower one to make room in the upper half. + } + else if(strstart >= w_size+ w_size-MIN_LOOKAHEAD) { + System.arraycopy(window, w_size, window, 0, w_size); + match_start-=w_size; + strstart-=w_size; // we now have strstart >= MAX_DIST + block_start-=w_size; + + // Slide the hash table (could be avoided with 32 bit values + // at the expense of memory usage). We slide even when level == 0 + // to keep the hash table consistent if we switch back to level > 0 + // later. (Using level 0 permanently is not an optimal usage of + // zlib, so we don't care about this pathological case.) + + n = hash_size; + p=n; + do { + m = (head[--p]&0xffff); + head[p]=(m>=w_size ? (short)(m-w_size) : 0); + } + while (--n != 0); + + n = w_size; + p = n; + do { + m = (prev[--p]&0xffff); + prev[p] = (m >= w_size ? (short)(m-w_size) : 0); + // If n is not on any hash chain, prev[n] is garbage but + // its value will never be used. + } + while (--n!=0); + more += w_size; + } + + if (strm.avail_in == 0) return; + + // If there was no sliding: + // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + // more == window_size - lookahead - strstart + // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + // => more >= window_size - 2*WSIZE + 2 + // In the BIG_MEM or MMAP case (not yet supported), + // window_size == input_size + MIN_LOOKAHEAD && + // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + // Otherwise, window_size == 2*WSIZE so more >= 2. + // If there was sliding, more >= WSIZE. So in all cases, more >= 2. + + n = strm.read_buf(window, strstart + lookahead, more); + lookahead += n; + + // Initialize the hash value now that we have some input: + if(lookahead >= MIN_MATCH) { + ins_h = window[strstart]&0xff; + ins_h=(((ins_h)<= MIN_MATCH){ + ins_h=(((ins_h)<=MIN_MATCH){ + // check_match(strstart, match_start, match_length); + + bflush=_tr_tally(strstart-match_start, match_length-MIN_MATCH); + + lookahead -= match_length; + + // Insert new strings in the hash table only if the match length + // is not too large. This saves time but degrades compression. + if(match_length <= max_lazy_match && + lookahead >= MIN_MATCH) { + match_length--; // string at strstart already in hash table + do{ + strstart++; + + ins_h=((ins_h<= MIN_MATCH) { + ins_h=(((ins_h)< 4096))) { + + // If prev_match is also MIN_MATCH, match_start is garbage + // but we will ignore the current match anyway. + match_length = MIN_MATCH-1; + } + } + + // If there was a match at the previous step and the current + // match is not better, output the previous match: + if(prev_length >= MIN_MATCH && match_length <= prev_length) { + int max_insert = strstart + lookahead - MIN_MATCH; + // Do not insert strings in hash table beyond this. + + // check_match(strstart-1, prev_match, prev_length); + + bflush=_tr_tally(strstart-1-prev_match, prev_length - MIN_MATCH); + + // Insert in hash table all strings up to the end of the match. + // strstart-1 and strstart are already inserted. If there is not + // enough lookahead, the last two strings are not inserted in + // the hash table. + lookahead -= prev_length-1; + prev_length -= 2; + do{ + if(++strstart <= max_insert) { + ins_h=(((ins_h)<(w_size-MIN_LOOKAHEAD) ? + strstart-(w_size-MIN_LOOKAHEAD) : 0; + int nice_match=this.nice_match; + + // Stop when cur_match becomes <= limit. To simplify the code, + // we prevent matches with the string of window index 0. + + int wmask = w_mask; + + int strend = strstart + MAX_MATCH; + byte scan_end1 = window[scan+best_len-1]; + byte scan_end = window[scan+best_len]; + + // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + // It is easy to get rid of this optimization if necessary. + + // Do not waste too much time if we already have a good match: + if (prev_length >= good_match) { + chain_length >>= 2; + } + + // Do not look for matches beyond the end of the input. This is necessary + // to make deflate deterministic. + if (nice_match > lookahead) nice_match = lookahead; + + do { + match = cur_match; + + // Skip to next match if the match length cannot increase + // or if the match length is less than 2: + if (window[match+best_len] != scan_end || + window[match+best_len-1] != scan_end1 || + window[match] != window[scan] || + window[++match] != window[scan+1]) continue; + + // The check at best_len-1 can be removed because it will be made + // again later. (This heuristic is not always a win.) + // It is not necessary to compare scan[2] and match[2] since they + // are always equal when the other bytes match, given that + // the hash keys are equal and that HASH_BITS >= 8. + scan += 2; match++; + + // We check for insufficient lookahead only every 8th comparison; + // the 256th check will be made at strstart+258. + do { + } while (window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + window[++scan] == window[++match] && + scan < strend); + + len = MAX_MATCH - strend - scan; + scan = strend - MAX_MATCH; + + if(len>best_len) { + match_start = cur_match; + best_len = len; + if (len >= nice_match) break; + scan_end1 = window[scan+best_len-1]; + scan_end = window[scan+best_len]; + } + + } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit + && --chain_length != 0); + + if (best_len <= lookahead) return best_len; + return lookahead; + } + + int deflateInit(int level, int bits, int memlevel){ + return deflateInit(level, Z_DEFLATED, bits, memlevel, + Z_DEFAULT_STRATEGY); + } + + int deflateInit(int level, int bits){ + return deflateInit(level, Z_DEFLATED, bits, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY); + } + int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + private int deflateInit(int level, int method, int windowBits, + int memLevel, int strategy){ + int wrap = 1; + // byte[] my_version=ZLIB_VERSION; + + // + // if (version == null || version[0] != my_version[0] + // || stream_size != sizeof(z_stream)) { + // return Z_VERSION_ERROR; + // } + + strm.msg = null; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { // undocumented feature: suppress zlib header + wrap = 0; + windowBits = -windowBits; + } + else if(windowBits > 15){ + wrap = 2; + windowBits -= 16; + strm.adler=new CRC32(); + } + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || + method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + strm.dstate = this; + + this.wrap = wrap; + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH); + + window = new byte[w_size*2]; + prev = new short[w_size]; + head = new short[hash_size]; + + lit_bufsize = 1 << (memLevel + 6); // 16K elements by default + + // We overlay pending_buf and d_buf+l_buf. This works since the average + // output size for (length,distance) codes is <= 24 bits. + pending_buf = new byte[lit_bufsize*3]; + pending_buf_size = lit_bufsize*3; + + d_buf = lit_bufsize; + l_buf = new byte[lit_bufsize]; + + this.level = level; + + this.strategy = strategy; + this.method = (byte)method; + + return deflateReset(); + } + + int deflateReset(){ + strm.total_in = strm.total_out = 0; + strm.msg = null; // + strm.data_type = Z_UNKNOWN; + + pending = 0; + pending_out = 0; + + if(wrap < 0){ + wrap = -wrap; + } + status = (wrap==0) ? BUSY_STATE : INIT_STATE; + strm.adler.reset(); + + last_flush = Z_NO_FLUSH; + + tr_init(); + lm_init(); + return Z_OK; + } + + int deflateEnd(){ + if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){ + return Z_STREAM_ERROR; + } + // Deallocate in reverse order of allocations: + pending_buf=null; + l_buf=null; + head=null; + prev=null; + window=null; + // free + // dstate=null; + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; + } + + int deflateParams(int _level, int _strategy){ + int err=Z_OK; + + if(_level == Z_DEFAULT_COMPRESSION){ + _level = 6; + } + if(_level < 0 || _level > 9 || + _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + + if(config_table[level].func!=config_table[_level].func && + strm.total_in != 0) { + // Flush the last buffer: + err = strm.deflate(Z_PARTIAL_FLUSH); + } + + if(level != _level) { + level = _level; + max_lazy_match = config_table[level].max_lazy; + good_match = config_table[level].good_length; + nice_match = config_table[level].nice_length; + max_chain_length = config_table[level].max_chain; + } + strategy = _strategy; + return err; + } + + int deflateSetDictionary (byte[] dictionary, int dictLength){ + int length = dictLength; + int index=0; + + if(dictionary == null || status != INIT_STATE) + return Z_STREAM_ERROR; + + strm.adler.update(dictionary, 0, dictLength); + + if(length < MIN_MATCH) return Z_OK; + if(length > w_size-MIN_LOOKAHEAD){ + length = w_size-MIN_LOOKAHEAD; + index=dictLength-length; // use the tail of the dictionary + } + System.arraycopy(dictionary, index, window, 0, length); + strstart = length; + block_start = length; + + // Insert all strings in the hash table (except for the last two bytes). + // s->lookahead stays null, so s->ins_h will be recomputed at the next + // call of fill_window. + + ins_h = window[0]&0xff; + ins_h=(((ins_h)<Z_FINISH || flush<0){ + return Z_STREAM_ERROR; + } + + if(strm.next_out == null || + (strm.next_in == null && strm.avail_in != 0) || + (status == FINISH_STATE && flush != Z_FINISH)) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; + return Z_STREAM_ERROR; + } + if(strm.avail_out == 0){ + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + old_flush = last_flush; + last_flush = flush; + + // Write the zlib header + if(status == INIT_STATE) { + if(wrap == 2){ + getGZIPHeader().put(this); + status=BUSY_STATE; + strm.adler.reset(); + } + else{ + int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; + int level_flags=((level-1)&0xff)>>1; + + if(level_flags>3) level_flags=3; + header |= (level_flags<<6); + if(strstart!=0) header |= PRESET_DICT; + header+=31-(header % 31); + + status=BUSY_STATE; + putShortMSB(header); + + + // Save the adler32 of the preset dictionary: + if(strstart!=0){ + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + strm.adler.reset(); + } + } + + // Flush as much pending output as possible + if(pending != 0) { + strm.flush_pending(); + if(strm.avail_out == 0) { + // Since avail_out is 0, deflate will be called again with + // more output space, but possibly with both pending and + // avail_in equal to zero. There won't be anything to do, + // but this is not an error situation so make sure we + // return OK instead of BUF_ERROR at next call of deflate: + last_flush = -1; + return Z_OK; + } + + // Make sure there is something to do and avoid duplicate consecutive + // flushes. For repeated and useless calls with Z_FINISH, we keep + // returning Z_STREAM_END instead of Z_BUFF_ERROR. + } + else if(strm.avail_in==0 && flush <= old_flush && + flush != Z_FINISH) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // User must not provide more input after the first FINISH: + if(status == FINISH_STATE && strm.avail_in != 0) { + strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; + return Z_BUF_ERROR; + } + + // Start a new block or continue the current one. + if(strm.avail_in!=0 || lookahead!=0 || + (flush != Z_NO_FLUSH && status != FINISH_STATE)) { + int bstate=-1; + switch(config_table[level].func){ + case STORED: + bstate = deflate_stored(flush); + break; + case FAST: + bstate = deflate_fast(flush); + break; + case SLOW: + bstate = deflate_slow(flush); + break; + default: + } + + if (bstate==FinishStarted || bstate==FinishDone) { + status = FINISH_STATE; + } + if (bstate==NeedMore || bstate==FinishStarted) { + if(strm.avail_out == 0) { + last_flush = -1; // avoid BUF_ERROR next call, see above + } + return Z_OK; + // If flush != Z_NO_FLUSH && avail_out == 0, the next call + // of deflate should use the same flush parameter to make sure + // that the flush is complete. So we don't have to output an + // empty block here, this will be done at next call. This also + // ensures that for a very small output buffer, we emit at most + // one empty block. + } + + if (bstate==BlockDone) { + if(flush == Z_PARTIAL_FLUSH) { + _tr_align(); + } + else { // FULL_FLUSH or SYNC_FLUSH + _tr_stored_block(0, 0, false); + // For a full flush, this empty block will be recognized + // as a special marker by inflate_sync(). + if(flush == Z_FULL_FLUSH) { + //state.head[s.hash_size-1]=0; + for(int i=0; i>8)&0xff)); + put_byte((byte)((adler>>16)&0xff)); + put_byte((byte)((adler>>24)&0xff)); + put_byte((byte)(strm.total_in&0xff)); + put_byte((byte)((strm.total_in>>8)&0xff)); + put_byte((byte)((strm.total_in>>16)&0xff)); + put_byte((byte)((strm.total_in>>24)&0xff)); + + getGZIPHeader().setCRC(adler); + } + else{ + // Write the zlib trailer (adler32) + long adler=strm.adler.getValue(); + putShortMSB((int)(adler>>>16)); + putShortMSB((int)(adler&0xffff)); + } + + strm.flush_pending(); + + // If avail_out is zero, the application will call deflate again + // to flush the rest. + + if(wrap > 0) wrap = -wrap; // write the trailer only once! + return pending != 0 ? Z_OK : Z_STREAM_END; + } + + static int deflateCopy(ZStream dest, ZStream src){ + + if(src.dstate == null){ + return Z_STREAM_ERROR; + } + + if(src.next_in!=null){ + dest.next_in = new byte[src.next_in.length]; + System.arraycopy(src.next_in, 0, dest.next_in, 0, src.next_in.length); + } + dest.next_in_index = src.next_in_index; + dest.avail_in = src.avail_in; + dest.total_in = src.total_in; + + if(src.next_out!=null){ + dest.next_out = new byte[src.next_out.length]; + System.arraycopy(src.next_out, 0, dest.next_out ,0 , src.next_out.length); + } + + dest.next_out_index = src.next_out_index; + dest.avail_out = src.avail_out; + dest.total_out = src.total_out; + + dest.msg = src.msg; + dest.data_type = src.data_type; + dest.adler = src.adler.copy(); + + try{ + dest.dstate = (Deflate)src.dstate.clone(); + dest.dstate.strm = dest; + } + catch(CloneNotSupportedException e){ + // + } + return Z_OK; + } + + @Override + public Object clone() throws CloneNotSupportedException { + Deflate dest = (Deflate)super.clone(); + + dest.pending_buf = dup(dest.pending_buf); + dest.l_buf = dup(dest.l_buf); + dest.window = dup(dest.window); + + dest.prev = dup(dest.prev); + dest.head = dup(dest.head); + dest.dyn_ltree = dup(dest.dyn_ltree); + dest.dyn_dtree = dup(dest.dyn_dtree); + dest.bl_tree = dup(dest.bl_tree); + + dest.bl_count = dup(dest.bl_count); + dest.next_code = dup(dest.next_code); + dest.heap = dup(dest.heap); + dest.depth = dup(dest.depth); + + dest.l_desc.dyn_tree = dest.dyn_ltree; + dest.d_desc.dyn_tree = dest.dyn_dtree; + dest.bl_desc.dyn_tree = dest.bl_tree; + + /* + dest.l_desc.stat_desc = StaticTree.static_l_desc; + dest.d_desc.stat_desc = StaticTree.static_d_desc; + dest.bl_desc.stat_desc = StaticTree.static_bl_desc; + */ + + if(dest.gheader!=null){ + dest.gheader = (GZIPHeader)dest.gheader.clone(); + } + + return dest; + } + + private byte[] dup(byte[] buf){ + byte[] foo = new byte[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private short[] dup(short[] buf){ + short[] foo = new short[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + private int[] dup(int[] buf){ + int[] foo = new int[buf.length]; + System.arraycopy(buf, 0, foo, 0, foo.length); + return foo; + } + + synchronized GZIPHeader getGZIPHeader(){ + if(gheader==null){ + gheader = new GZIPHeader(); + } + return gheader; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflater.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflater.java new file mode 100644 index 00000000..f947a704 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Deflater.java @@ -0,0 +1,174 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class Deflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + private boolean finished = false; + + Deflater(){ + super(); + } + + Deflater(int level) throws GZIPException { + this(level, MAX_WBITS); + } + + Deflater(int level, boolean nowrap) throws GZIPException { + this(level, MAX_WBITS, nowrap); + } + + Deflater(int level, int bits) throws GZIPException { + this(level, bits, false); + } + + Deflater(int level, int bits, boolean nowrap) throws GZIPException { + super(); + int ret = init(level, bits, nowrap); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + Deflater(int level, int bits, int memlevel, JZlib.WrapperType wrapperType) throws GZIPException { + super(); + int ret = init(level, bits, memlevel, wrapperType); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + Deflater(int level, int bits, int memlevel) throws GZIPException { + super(); + int ret = init(level, bits, memlevel); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + int init(int level){ + return init(level, MAX_WBITS); + } + int init(int level, boolean nowrap){ + return init(level, MAX_WBITS, nowrap); + } + int init(int level, int bits){ + return init(level, bits, false); + } + int init(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ + if(bits < 9 || bits > 15){ + return Z_STREAM_ERROR; + } + if(wrapperType == JZlib.W_NONE) { + bits *= -1; + } + else if(wrapperType == JZlib.W_GZIP) { + bits += 16; + } + else if(wrapperType == JZlib.W_ANY) { + return Z_STREAM_ERROR; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return init(level, bits, memlevel); + } + int init(int level, int bits, int memlevel){ + finished = false; + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } + int init(int level, int bits, boolean nowrap){ + finished = false; + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); + } + + @Override + int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + int ret = dstate.deflate(flush); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + @Override + int end(){ + finished = true; + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + free(); + return ret; + } + int params(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(level, strategy); + } + int setDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(dictionary, dictLength); + } + + @Override + boolean finished(){ + return finished; + } + + int copy(Deflater src){ + this.finished = src.finished; + return Deflate.deflateCopy(this, src); + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java new file mode 100644 index 00000000..df89ffa1 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/DeflaterOutputStream.java @@ -0,0 +1,186 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 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.jzlib; +import java.io.*; + +final class DeflaterOutputStream extends FilterOutputStream { + + protected final Deflater deflater; + + protected byte[] buffer; + + private boolean closed = false; + + private boolean syncFlush = false; + + private final byte[] buf1 = new byte[1]; + + protected boolean mydeflater = false; + + private boolean close_out = true; + + protected static final int DEFAULT_BUFSIZE = 512; + + DeflaterOutputStream(OutputStream out) throws IOException { + this(out, + new Deflater(JZlib.Z_DEFAULT_COMPRESSION), + DEFAULT_BUFSIZE, true); + mydeflater = true; + } + + DeflaterOutputStream(OutputStream out, Deflater def) throws IOException { + this(out, def, DEFAULT_BUFSIZE, true); + } + + DeflaterOutputStream(OutputStream out, + Deflater deflater, + int size) throws IOException { + this(out, deflater, size, true); + } + DeflaterOutputStream(OutputStream out, + Deflater deflater, + int size, + boolean close_out) throws IOException { + super(out); + if (out == null || deflater == null) { + throw new NullPointerException(); + } + else if (size <= 0) { + throw new IllegalArgumentException("buffer size must be greater than 0"); + } + this.deflater = deflater; + buffer = new byte[size]; + this.close_out = close_out; + } + + @Override + public void write(int b) throws IOException { + buf1[0] = (byte)(b & 0xff); + write(buf1, 0, 1); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (deflater.finished()) { + throw new IOException("finished"); + } + else if (off<0 || len<0 || off+len>b.length) { + throw new IndexOutOfBoundsException(); + } + else if (len == 0) { + return; + } + else { + int flush = syncFlush ? JZlib.Z_SYNC_FLUSH : JZlib.Z_NO_FLUSH; + deflater.setInput(b, off, len, true); + while (deflater.avail_in>0) { + int err = deflate(flush); + if (err == JZlib.Z_STREAM_END) + break; + } + } + } + + void finish() throws IOException { + while (!deflater.finished()) { + deflate(JZlib.Z_FINISH); + } + } + + @Override + public void close() throws IOException { + if (!closed) { + finish(); + if (mydeflater){ + deflater.end(); + } + if(close_out) + out.close(); + closed = true; + } + } + + @SuppressWarnings("fallthrough") + protected int deflate(int flush) throws IOException { + deflater.setOutput(buffer, 0, buffer.length); + int err = deflater.deflate(flush); + switch(err) { + case JZlib.Z_OK: + case JZlib.Z_STREAM_END: + break; + case JZlib.Z_BUF_ERROR: + if(deflater.avail_in<=0 && flush!=JZlib.Z_FINISH){ + // flush() without any data + break; + } + default: + throw new IOException("failed to deflate: error="+err+" avail_out="+deflater.avail_out); + } + int len = deflater.next_out_index; + if (len > 0) { + out.write(buffer, 0, len); + } + return err; + } + + @Override + public void flush() throws IOException { + if (syncFlush && !deflater.finished()) { + while (true) { + int err = deflate(JZlib.Z_SYNC_FLUSH); + if (deflater.next_out_index < buffer.length) + break; + if (err == JZlib.Z_STREAM_END) + break; + } + } + out.flush(); + } + + long getTotalIn() { + return deflater.getTotalIn(); + } + + long getTotalOut() { + return deflater.getTotalOut(); + } + + void setSyncFlush(boolean syncFlush){ + this.syncFlush = syncFlush; + } + + boolean getSyncFlush(){ + return this.syncFlush; + } + + Deflater getDeflater(){ + return deflater; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java new file mode 100644 index 00000000..97512b6f --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPException.java @@ -0,0 +1,47 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +import java.io.IOException; + +final class GZIPException extends IOException { + private static final long serialVersionUID=-1L; + GZIPException() { + super(); + } + GZIPException(String s) { + super(s); + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java new file mode 100644 index 00000000..6469e265 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/GZIPHeader.java @@ -0,0 +1,194 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +/** + * @see http://www.ietf.org/rfc/rfc1952.txt + */ +final class GZIPHeader implements Cloneable { + + static final byte OS_MSDOS = (byte) 0x00; + static final byte OS_AMIGA = (byte) 0x01; + static final byte OS_VMS = (byte) 0x02; + static final byte OS_UNIX = (byte) 0x03; + static final byte OS_ATARI = (byte) 0x05; + static final byte OS_OS2 = (byte) 0x06; + static final byte OS_MACOS = (byte) 0x07; + static final byte OS_TOPS20 = (byte) 0x0a; + static final byte OS_WIN32 = (byte) 0x0b; + static final byte OS_VMCMS = (byte) 0x04; + static final byte OS_ZSYSTEM = (byte) 0x08; + static final byte OS_CPM = (byte) 0x09; + static final byte OS_QDOS = (byte) 0x0c; + static final byte OS_RISCOS = (byte) 0x0d; + static final byte OS_UNKNOWN = (byte) 0xff; + + boolean text = false; + private boolean fhcrc = false; + int xflags; + int os = 255; + byte[] extra; + byte[] name; + byte[] comment; + int hcrc; + long crc; + boolean done = false; + long mtime = 0; + + void setModifiedTime(long mtime) { + this.mtime = mtime; + } + + long getModifiedTime() { + return mtime; + } + + void setOS(int os) { + if((0<=os && os <=13) || os==255) + this.os=os; + else + throw new IllegalArgumentException("os: "+os); + } + + int getOS(){ + return os; + } + + void setName(String name) { + this.name=name.getBytes(StandardCharsets.ISO_8859_1); + } + + String getName(){ + if(name==null) return ""; + return new String(name, StandardCharsets.ISO_8859_1); + } + + void setComment(String comment) { + this.comment=comment.getBytes(StandardCharsets.ISO_8859_1); + } + + String getComment(){ + if(comment==null) return ""; + return new String(comment, StandardCharsets.ISO_8859_1); + } + + void setCRC(long crc){ + this.crc = crc; + } + + long getCRC(){ + return crc; + } + + void put(Deflate d){ + int flag = 0; + if(text){ + flag |= 1; // FTEXT + } + if(fhcrc){ + flag |= 2; // FHCRC + } + if(extra!=null){ + flag |= 4; // FEXTRA + } + if(name!=null){ + flag |= 8; // FNAME + } + if(comment!=null){ + flag |= 16; // FCOMMENT + } + int xfl = 0; + if(d.level == JZlib.Z_BEST_SPEED){ + xfl |= 4; + } + else if (d.level == JZlib.Z_BEST_COMPRESSION){ + xfl |= 2; + } + + d.put_short((short)0x8b1f); // ID1 ID2 + d.put_byte((byte)8); // CM(Compression Method) + d.put_byte((byte)flag); + d.put_byte((byte)mtime); + d.put_byte((byte)(mtime>>8)); + d.put_byte((byte)(mtime>>16)); + d.put_byte((byte)(mtime>>24)); + d.put_byte((byte)xfl); + d.put_byte((byte)os); + + if(extra!=null){ + d.put_byte((byte)extra.length); + d.put_byte((byte)(extra.length>>8)); + d.put_byte(extra, 0, extra.length); + } + + if(name!=null){ + d.put_byte(name, 0, name.length); + d.put_byte((byte)0); + } + + if(comment!=null){ + d.put_byte(comment, 0, comment.length); + d.put_byte((byte)0); + } + } + + @Override + public Object clone() throws CloneNotSupportedException { + GZIPHeader gheader = (GZIPHeader)super.clone(); + byte[] tmp; + if(gheader.extra!=null){ + tmp=new byte[gheader.extra.length]; + System.arraycopy(gheader.extra, 0, tmp, 0, tmp.length); + gheader.extra = tmp; + } + + if(gheader.name!=null){ + tmp=new byte[gheader.name.length]; + System.arraycopy(gheader.name, 0, tmp, 0, tmp.length); + gheader.name = tmp; + } + + if(gheader.comment!=null){ + tmp=new byte[gheader.comment.length]; + System.arraycopy(gheader.comment, 0, tmp, 0, tmp.length); + gheader.comment = tmp; + } + + return gheader; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java new file mode 100644 index 00000000..ad6514d9 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfBlocks.java @@ -0,0 +1,615 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class InfBlocks{ + static final private int MANY=1440; + + // And'ing with mask[n] masks the lower n bits + static final private int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + // Table for deflate from PKZIP's appnote.txt. + static final int[] border = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + }; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final private int TYPE=0; // get type bits (3, including end bit) + static final private int LENS=1; // get lengths for stored + static final private int STORED=2;// processing stored block + static final private int TABLE=3; // get table lengths + static final private int BTREE=4; // get bit lengths tree for a dynamic block + static final private int DTREE=5; // get length, distance trees for a dynamic block + static final private int CODES=6; // processing fixed or dynamic block + static final private int DRY=7; // output remaining window bytes + static final private int DONE=8; // finished last block, done + static final private int BAD=9; // ot a data error--stuck here + + int mode; // current inflate_block mode + + int left; // if STORED, bytes left to copy + + int table; // table lengths (14 bits) + int index; // index into blens (or border) + int[] blens; // bit lengths of codes + int[] bb=new int[1]; // bit length tree depth + int[] tb=new int[1]; // bit length decoding tree + + int[] bl=new int[1]; + int[] bd=new int[1]; + + int[][] tl=new int[1][]; + int[][] td=new int[1][]; + int[] tli=new int[1]; // tl_index + int[] tdi=new int[1]; // td_index + + private final InfCodes codes; // if CODES, current state + + int last; // true if this block is the last block + + // mode independent information + int bitk; // bits in bit buffer + int bitb; // bit buffer + int[] hufts; // single malloc for tree space + byte[] window; // sliding window + int end; // one byte after sliding window + int read; // window read pointer + int write; // window write pointer + private boolean check; + + private final InfTree inftree=new InfTree(); + + private final ZStream z; + + InfBlocks(ZStream z, int w){ + this.z=z; + this.codes=new InfCodes(this.z, this); + hufts=new int[MANY*3]; + window=new byte[w]; + end=w; + this.check = (z.istate.wrap==0) ? false : true; + mode = TYPE; + reset(); + } + + void reset(){ + if(mode==BTREE || mode==DTREE){ + } + if(mode==CODES){ + codes.free(z); + } + mode=TYPE; + bitk=0; + bitb=0; + read=write=0; + if(check){ + z.adler.reset(); + } + } + + @SuppressWarnings("fallthrough") + int proc(int r){ + int t; // temporary storage + int b; // bit buffer + int k; // bits in bit buffer + int p; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + + // copy input/output information to locals (UPDATE macro restores) + {p=z.next_in_index;n=z.avail_in;b=bitb;k=bitk;} + {q=write;m=(q>> 1){ + case 0: // stored + {b>>>=(3);k-=(3);} + t = k & 7; // go to byte boundary + + {b>>>=(t);k-=(t);} + mode = LENS; // get length of stored block + break; + case 1: // fixed + InfTree.inflate_trees_fixed(bl, bd, tl, td, z); + codes.init(bl[0], bd[0], tl[0], 0, td[0], 0); + + {b>>>=(3);k-=(3);} + + mode = CODES; + break; + case 2: // dynamic + + {b>>>=(3);k-=(3);} + + mode = TABLE; + break; + case 3: // illegal + + {b>>>=(3);k-=(3);} + mode = BAD; + z.msg = "invalid block type"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + break; + case LENS: + + while(k<(32)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>> 16) & 0xffff) != (b & 0xffff)){ + mode = BAD; + z.msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + left = (b & 0xffff); + b = k = 0; // dump bits + mode = left!=0 ? STORED : (last!=0 ? DRY : TYPE); + break; + case STORED: + if (n == 0){ + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + if(m==0){ + if(q==end&&read!=0){ + q=0; m=(qn) t = n; + if(t>m) t = m; + System.arraycopy(z.next_in, p, window, q, t); + p += t; n -= t; + q += t; m -= t; + if ((left -= t) != 0) + break; + mode = last!=0 ? DRY : TYPE; + break; + case TABLE: + + while(k<(14)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)< 29 || ((t >> 5) & 0x1f) > 29) + { + mode = BAD; + z.msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if(blens==null || blens.length>>=(14);k-=(14);} + + index = 0; + mode = BTREE; + case BTREE: + while (index < 4 + (table >>> 10)){ + while(k<(3)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(3);k-=(3);} + } + + while(index < 19){ + blens[border[index++]] = 0; + } + + bb[0] = 7; + t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z); + if (t != Z_OK){ + r = t; + if (r == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + index = 0; + mode = DTREE; + case DTREE: + while (true){ + t = table; + if(!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))){ + break; + } + + int[] h; + int i, j, c; + + t = bb[0]; + + while(k<(t)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + blens[index++] = c; + } + else { // c == 16..18 + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + + while(k<(t+i)){ + if(n!=0){ + r=Z_OK; + } + else{ + bitb=b; bitk=k; + z.avail_in=n; + z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + }; + n--; + b|=(z.next_in[p++]&0xff)<>>=(t);k-=(t); + + j += (b & inflate_mask[i]); + + b>>>=(i);k-=(i); + + i = index; + t = table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)){ + blens=null; + mode = BAD; + z.msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + + c = c == 16 ? blens[i-1] : 0; + do{ + blens[i++] = c; + } + while (--j!=0); + index = i; + } + } + + tb[0]=-1; + { + bl[0] = 9; // must be <= 9 for lookahead assumptions + bd[0] = 6; // must be <= 9 for lookahead assumptions + t = table; + t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), + 1 + ((t >> 5) & 0x1f), + blens, bl, bd, tli, tdi, hufts, z); + + if (t != Z_OK){ + if (t == Z_DATA_ERROR){ + blens=null; + mode = BAD; + } + r = t; + + bitb=b; bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + return inflate_flush(r); + } + codes.init(bl[0], bd[0], hufts, tli[0], hufts, tdi[0]); + } + mode = CODES; + case CODES: + bitb=b; bitk=k; + z.avail_in=n; z.total_in+=p-z.next_in_index;z.next_in_index=p; + write=q; + + if ((r = codes.proc(r)) != Z_STREAM_END){ + return inflate_flush(r); + } + r = Z_OK; + codes.free(z); + + p=z.next_in_index; n=z.avail_in;b=bitb;k=bitk; + q=write;m=(q z.avail_out) n = z.avail_out; + if(n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy as far as end of window + System.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + + // see if more to copy at beginning of window + if (q == end){ + // wrap pointers + q = 0; + if (write == end) + write = 0; + + // compute bytes to copy + n = write - q; + if (n > z.avail_out) n = z.avail_out; + if (n!=0 && r == Z_BUF_ERROR) r = Z_OK; + + // update counters + z.avail_out -= n; + z.total_out += n; + + // update check information + if(check && n>0){ + z.adler.update(window, q, n); + } + + // copy + System.arraycopy(window, q, z.next_out, p, n); + p += n; + q += n; + } + + // update pointers + z.next_out_index = p; + read = q; + + // done + return r; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java new file mode 100644 index 00000000..4f411759 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfCodes.java @@ -0,0 +1,611 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class InfCodes{ + + static final private int[] inflate_mask = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, + 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, + 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, + 0x00007fff, 0x0000ffff + }; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + // waiting for "i:"=input, + // "o:"=output, + // "x:"=nothing + static final private int START=0; // x: set up for LEN + static final private int LEN=1; // i: get length/literal/eob next + static final private int LENEXT=2; // i: getting length extra (have base) + static final private int DIST=3; // i: get distance next + static final private int DISTEXT=4;// i: getting distance extra + static final private int COPY=5; // o: copying bytes in window, waiting for space + static final private int LIT=6; // o: got literal, waiting for output space + static final private int WASH=7; // o: got eob, possibly still output waiting + static final private int END=8; // x: got eob and all data flushed + static final private int BADCODE=9;// x: got error + + int mode; // current inflate_codes mode + + // mode dependent information + int len; + + int[] tree; // pointer into tree + int tree_index=0; + int need; // bits needed + + int lit; + + // if EXT or COPY, where and how much + int get; // bits to get for extra + int dist; // distance back to copy from + + byte lbits; // ltree bits decoded per branch + byte dbits; // dtree bits decoder per branch + int[] ltree; // literal/length/eob tree + int ltree_index; // literal/length/eob tree + int[] dtree; // distance tree + int dtree_index; // distance tree + + private final ZStream z; + private final InfBlocks s; + InfCodes(ZStream z, InfBlocks s){ + this.z=z; + this.s=s; + } + + void init(int bl, int bd, + int[] tl, int tl_index, + int[] td, int td_index){ + mode=START; + lbits=(byte)bl; + dbits=(byte)bd; + ltree=tl; + ltree_index=tl_index; + dtree = td; + dtree_index=td_index; + tree=null; + } + + @SuppressWarnings("fallthrough") + int proc(int r){ + int j; // temporary storage + int[] t; // temporary pointer + int tindex; // temporary pointer + int e; // extra bits or operation + int b=0; // bit buffer + int k=0; // bits in bit buffer + int p=0; // input data pointer + int n; // bytes available there + int q; // output window write pointer + int m; // bytes to end of window or read pointer + int f; // pointer to copy strings from + + // copy input/output information to locals (UPDATE macro restores) + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q= 258 && n >= 10){ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + r = inflate_fast(lbits, dbits, + ltree, ltree_index, + dtree, dtree_index, + s, z); + + p=z.next_in_index;n=z.avail_in;b=s.bitb;k=s.bitk; + q=s.write;m=q>>=(tree[tindex+1]); + k-=(tree[tindex+1]); + + e=tree[tindex]; + + if(e == 0){ // literal + lit = tree[tindex+2]; + mode = LIT; + break; + } + if((e & 16)!=0 ){ // length + get = e & 15; + len = tree[tindex+2]; + mode = LENEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3+tree[tindex+2]; + break; + } + if ((e & 32)!=0){ // end of block + mode = WASH; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case LENEXT: // i: getting length extra (have base) + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + need = dbits; + tree = dtree; + tree_index=dtree_index; + mode = DIST; + case DIST: // i: get distance next + j = need; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=tree[tindex+1]; + k-=tree[tindex+1]; + + e = (tree[tindex]); + if((e & 16)!=0){ // distance + get = e & 15; + dist = tree[tindex+2]; + mode = DISTEXT; + break; + } + if ((e & 64) == 0){ // next table + need = e; + tree_index = tindex/3 + tree[tindex+2]; + break; + } + mode = BADCODE; // invalid code + z.msg = "invalid distance code"; + r = Z_DATA_ERROR; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + + case DISTEXT: // i: getting distance extra + j = get; + + while(k<(j)){ + if(n!=0)r=Z_OK; + else{ + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + return s.inflate_flush(r); + } + n--; b|=(z.next_in[p++]&0xff)<>=j; + k-=j; + + mode = COPY; + case COPY: // o: copying bytes in window, waiting for space + f = q - dist; + while(f < 0){ // modulo window size-"while" instead + f += s.end; // of "if" handles invalid distances + } + while (len!=0){ + + if(m==0){ + if(q==s.end&&s.read!=0){q=0;m=q 7){ // return unused byte, if any + k -= 8; + n++; + p--; // can always return one + } + + s.write=q; r=s.inflate_flush(r); + q=s.write;m=q= 258 && n >= 10 + // get literal/length code + while(k<(20)){ // max bits for literal/length code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++] = (byte)tp[tp_index_t_3+2]; + m--; + continue; + } + do { + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + e &= 15; + c = tp[tp_index_t_3+2] + (b & inflate_mask[e]); + + b>>=e; k-=e; + + // decode distance base of block to copy + while(k<(15)){ // max bits for distance code + n--; + b|=(z.next_in[p++]&0xff)<>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + if((e&16)!=0){ + // get extra bits to add to distance base + e &= 15; + while(k<(e)){ // get extra bits (up to 13) + n--; + b|=(z.next_in[p++]&0xff)<>=(e); k-=(e); + + // do the copy + m -= c; + if (q >= d){ // offset before dest + // just copy + r=q-d; + if(q-r>0 && 2>(q-r)){ + s.window[q++]=s.window[r++]; // minimum count is three, + s.window[q++]=s.window[r++]; // so unroll loop a little + c-=2; + } + else{ + System.arraycopy(s.window, r, s.window, q, 2); + q+=2; r+=2; c-=2; + } + } + else{ // else offset after destination + r=q-d; + do{ + r+=s.end; // force pointer in window + }while(r<0); // covers invalid distances + e=s.end-r; + if(c>e){ // if source crosses, + c-=e; // wrapped copy + if(q-r>0 && e>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--e!=0); + } + else{ + System.arraycopy(s.window, r, s.window, q, e); + q+=e; r+=e; e=0; + } + r = 0; // copy rest from start of window + } + + } + + // copy all or what's left + if(q-r>0 && c>(q-r)){ + do{s.window[q++] = s.window[r++];} + while(--c!=0); + } + else{ + System.arraycopy(s.window, r, s.window, q, c); + q+=c; r+=c; c=0; + } + break; + } + else if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + e=tp[tp_index_t_3]; + } + else{ + z.msg = "invalid distance code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + break; + } + + if((e&64)==0){ + t+=tp[tp_index_t_3+2]; + t+=(b&inflate_mask[e]); + tp_index_t_3=(tp_index+t)*3; + if((e=tp[tp_index_t_3])==0){ + + b>>=(tp[tp_index_t_3+1]); k-=(tp[tp_index_t_3+1]); + + s.window[q++]=(byte)tp[tp_index_t_3+2]; + m--; + break; + } + } + else if((e&32)!=0){ + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_STREAM_END; + } + else{ + z.msg="invalid literal/length code"; + + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_DATA_ERROR; + } + } + while(true); + } + while(m>=258 && n>= 10); + + // not enough input or output--restore pointers and return + c=z.avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3; + + s.bitb=b;s.bitk=k; + z.avail_in=n;z.total_in+=p-z.next_in_index;z.next_in_index=p; + s.write=q; + + return Z_OK; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfTree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfTree.java new file mode 100644 index 00000000..409672cf --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InfTree.java @@ -0,0 +1,518 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000,2001,2002,2003 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class InfTree{ + + static final private int MANY=1440; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + static final int fixed_bl = 9; + static final int fixed_bd = 5; + + static final int[] fixed_tl = { + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,192, + 80,7,10, 0,8,96, 0,8,32, 0,9,160, + 0,8,0, 0,8,128, 0,8,64, 0,9,224, + 80,7,6, 0,8,88, 0,8,24, 0,9,144, + 83,7,59, 0,8,120, 0,8,56, 0,9,208, + 81,7,17, 0,8,104, 0,8,40, 0,9,176, + 0,8,8, 0,8,136, 0,8,72, 0,9,240, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,200, + 81,7,13, 0,8,100, 0,8,36, 0,9,168, + 0,8,4, 0,8,132, 0,8,68, 0,9,232, + 80,7,8, 0,8,92, 0,8,28, 0,9,152, + 84,7,83, 0,8,124, 0,8,60, 0,9,216, + 82,7,23, 0,8,108, 0,8,44, 0,9,184, + 0,8,12, 0,8,140, 0,8,76, 0,9,248, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,196, + 81,7,11, 0,8,98, 0,8,34, 0,9,164, + 0,8,2, 0,8,130, 0,8,66, 0,9,228, + 80,7,7, 0,8,90, 0,8,26, 0,9,148, + 84,7,67, 0,8,122, 0,8,58, 0,9,212, + 82,7,19, 0,8,106, 0,8,42, 0,9,180, + 0,8,10, 0,8,138, 0,8,74, 0,9,244, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,204, + 81,7,15, 0,8,102, 0,8,38, 0,9,172, + 0,8,6, 0,8,134, 0,8,70, 0,9,236, + 80,7,9, 0,8,94, 0,8,30, 0,9,156, + 84,7,99, 0,8,126, 0,8,62, 0,9,220, + 82,7,27, 0,8,110, 0,8,46, 0,9,188, + 0,8,14, 0,8,142, 0,8,78, 0,9,252, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,194, + 80,7,10, 0,8,97, 0,8,33, 0,9,162, + 0,8,1, 0,8,129, 0,8,65, 0,9,226, + 80,7,6, 0,8,89, 0,8,25, 0,9,146, + 83,7,59, 0,8,121, 0,8,57, 0,9,210, + 81,7,17, 0,8,105, 0,8,41, 0,9,178, + 0,8,9, 0,8,137, 0,8,73, 0,9,242, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,202, + 81,7,13, 0,8,101, 0,8,37, 0,9,170, + 0,8,5, 0,8,133, 0,8,69, 0,9,234, + 80,7,8, 0,8,93, 0,8,29, 0,9,154, + 84,7,83, 0,8,125, 0,8,61, 0,9,218, + 82,7,23, 0,8,109, 0,8,45, 0,9,186, + 0,8,13, 0,8,141, 0,8,77, 0,9,250, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,198, + 81,7,11, 0,8,99, 0,8,35, 0,9,166, + 0,8,3, 0,8,131, 0,8,67, 0,9,230, + 80,7,7, 0,8,91, 0,8,27, 0,9,150, + 84,7,67, 0,8,123, 0,8,59, 0,9,214, + 82,7,19, 0,8,107, 0,8,43, 0,9,182, + 0,8,11, 0,8,139, 0,8,75, 0,9,246, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,206, + 81,7,15, 0,8,103, 0,8,39, 0,9,174, + 0,8,7, 0,8,135, 0,8,71, 0,9,238, + 80,7,9, 0,8,95, 0,8,31, 0,9,158, + 84,7,99, 0,8,127, 0,8,63, 0,9,222, + 82,7,27, 0,8,111, 0,8,47, 0,9,190, + 0,8,15, 0,8,143, 0,8,79, 0,9,254, + 96,7,256, 0,8,80, 0,8,16, 84,8,115, + 82,7,31, 0,8,112, 0,8,48, 0,9,193, + + 80,7,10, 0,8,96, 0,8,32, 0,9,161, + 0,8,0, 0,8,128, 0,8,64, 0,9,225, + 80,7,6, 0,8,88, 0,8,24, 0,9,145, + 83,7,59, 0,8,120, 0,8,56, 0,9,209, + 81,7,17, 0,8,104, 0,8,40, 0,9,177, + 0,8,8, 0,8,136, 0,8,72, 0,9,241, + 80,7,4, 0,8,84, 0,8,20, 85,8,227, + 83,7,43, 0,8,116, 0,8,52, 0,9,201, + 81,7,13, 0,8,100, 0,8,36, 0,9,169, + 0,8,4, 0,8,132, 0,8,68, 0,9,233, + 80,7,8, 0,8,92, 0,8,28, 0,9,153, + 84,7,83, 0,8,124, 0,8,60, 0,9,217, + 82,7,23, 0,8,108, 0,8,44, 0,9,185, + 0,8,12, 0,8,140, 0,8,76, 0,9,249, + 80,7,3, 0,8,82, 0,8,18, 85,8,163, + 83,7,35, 0,8,114, 0,8,50, 0,9,197, + 81,7,11, 0,8,98, 0,8,34, 0,9,165, + 0,8,2, 0,8,130, 0,8,66, 0,9,229, + 80,7,7, 0,8,90, 0,8,26, 0,9,149, + 84,7,67, 0,8,122, 0,8,58, 0,9,213, + 82,7,19, 0,8,106, 0,8,42, 0,9,181, + 0,8,10, 0,8,138, 0,8,74, 0,9,245, + 80,7,5, 0,8,86, 0,8,22, 192,8,0, + 83,7,51, 0,8,118, 0,8,54, 0,9,205, + 81,7,15, 0,8,102, 0,8,38, 0,9,173, + 0,8,6, 0,8,134, 0,8,70, 0,9,237, + 80,7,9, 0,8,94, 0,8,30, 0,9,157, + 84,7,99, 0,8,126, 0,8,62, 0,9,221, + 82,7,27, 0,8,110, 0,8,46, 0,9,189, + 0,8,14, 0,8,142, 0,8,78, 0,9,253, + 96,7,256, 0,8,81, 0,8,17, 85,8,131, + 82,7,31, 0,8,113, 0,8,49, 0,9,195, + 80,7,10, 0,8,97, 0,8,33, 0,9,163, + 0,8,1, 0,8,129, 0,8,65, 0,9,227, + 80,7,6, 0,8,89, 0,8,25, 0,9,147, + 83,7,59, 0,8,121, 0,8,57, 0,9,211, + 81,7,17, 0,8,105, 0,8,41, 0,9,179, + 0,8,9, 0,8,137, 0,8,73, 0,9,243, + 80,7,4, 0,8,85, 0,8,21, 80,8,258, + 83,7,43, 0,8,117, 0,8,53, 0,9,203, + 81,7,13, 0,8,101, 0,8,37, 0,9,171, + 0,8,5, 0,8,133, 0,8,69, 0,9,235, + 80,7,8, 0,8,93, 0,8,29, 0,9,155, + 84,7,83, 0,8,125, 0,8,61, 0,9,219, + 82,7,23, 0,8,109, 0,8,45, 0,9,187, + 0,8,13, 0,8,141, 0,8,77, 0,9,251, + 80,7,3, 0,8,83, 0,8,19, 85,8,195, + 83,7,35, 0,8,115, 0,8,51, 0,9,199, + 81,7,11, 0,8,99, 0,8,35, 0,9,167, + 0,8,3, 0,8,131, 0,8,67, 0,9,231, + 80,7,7, 0,8,91, 0,8,27, 0,9,151, + 84,7,67, 0,8,123, 0,8,59, 0,9,215, + 82,7,19, 0,8,107, 0,8,43, 0,9,183, + 0,8,11, 0,8,139, 0,8,75, 0,9,247, + 80,7,5, 0,8,87, 0,8,23, 192,8,0, + 83,7,51, 0,8,119, 0,8,55, 0,9,207, + 81,7,15, 0,8,103, 0,8,39, 0,9,175, + 0,8,7, 0,8,135, 0,8,71, 0,9,239, + 80,7,9, 0,8,95, 0,8,31, 0,9,159, + 84,7,99, 0,8,127, 0,8,63, 0,9,223, + 82,7,27, 0,8,111, 0,8,47, 0,9,191, + 0,8,15, 0,8,143, 0,8,79, 0,9,255 + }; + static final int[] fixed_td = { + 80,5,1, 87,5,257, 83,5,17, 91,5,4097, + 81,5,5, 89,5,1025, 85,5,65, 93,5,16385, + 80,5,3, 88,5,513, 84,5,33, 92,5,8193, + 82,5,9, 90,5,2049, 86,5,129, 192,5,24577, + 80,5,2, 87,5,385, 83,5,25, 91,5,6145, + 81,5,7, 89,5,1537, 85,5,97, 93,5,24577, + 80,5,4, 88,5,769, 84,5,49, 92,5,12289, + 82,5,13, 90,5,3073, 86,5,193, 192,5,24577 + }; + + // Tables for deflate from PKZIP's appnote.txt. + static final int[] cplens = { // Copy lengths for literal codes 257..285 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 + }; + + // see note #13 above about 258 + static final int[] cplext = { // Extra bits for literal codes 257..285 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid + }; + + static final int[] cpdist = { // Copy offsets for distance codes 0..29 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577 + }; + + static final int[] cpdext = { // Extra bits for distance codes + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + // If BMAX needs to be larger than 16, then h and x[] should be uLong. + static final int BMAX=15; // maximum bit length of any code + + int[] hn = null; // hufts used in space + int[] v = null; // work area for huft_build + int[] c = null; // bit length count table + int[] r = null; // table entry for structure assignment + int[] u = null; // table stack + int[] x = null; // bit offsets, then code stack + + private int huft_build(int[] b, // code lengths in bits (all assumed <= BMAX) + int bindex, + int n, // number of codes (assumed <= 288) + int s, // number of simple-valued codes (0..s-1) + int[] d, // list of base values for non-simple codes + int[] e, // list of extra bits for non-simple codes + int[] t, // result: starting table + int[] m, // maximum lookup bits, returns actual + int[] hp,// space for trees + int[] hn,// hufts used in space + int[] v // working area: values in order of bit length + ){ + // Given a list of code lengths and a maximum table size, make a set of + // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + // if the given code set is incomplete (the tables are still built in this + // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of + // lengths), or Z_MEM_ERROR if not enough memory. + + int a; // counter for codes of length k + int f; // i repeats in table every f entries + int g; // maximum code length + int h; // table level + int i; // counter, current code + int j; // counter + int k; // number of bits in current code + int l; // bits per table (returned in m) + int mask; // (1 << w) - 1, to avoid cc -O bug on HP + int p; // pointer into c[], b[], or v[] + int q; // points to current table + int w; // bits before this table == (l * h) + int xp; // pointer into x + int y; // number of dummy codes added + int z; // number of entries in current table + + // Generate counts for each bit length + + p = 0; i = n; + do { + c[b[bindex+p]]++; p++; i--; // assume all entries <= BMAX + }while(i!=0); + + if(c[0] == n){ // null input--all zero length codes + t[0] = -1; + m[0] = 0; + return Z_OK; + } + + // Find minimum and maximum length, bound *m by those + l = m[0]; + for (j = 1; j <= BMAX; j++) + if(c[j]!=0) break; + k = j; // minimum code length + if(l < j){ + l = j; + } + for (i = BMAX; i!=0; i--){ + if(c[i]!=0) break; + } + g = i; // maximum code length + if(l > i){ + l = i; + } + m[0] = l; + + // Adjust last length count to fill out codes, if needed + for (y = 1 << j; j < i; j++, y <<= 1){ + if ((y -= c[j]) < 0){ + return Z_DATA_ERROR; + } + } + if ((y -= c[i]) < 0){ + return Z_DATA_ERROR; + } + c[i] += y; + + // Generate starting offsets into the value table for each length + x[1] = j = 0; + p = 1; xp = 2; + while (--i!=0) { // note that i == g from above + x[xp] = (j += c[p]); + xp++; + p++; + } + + // Make a table of values in order of bit lengths + i = 0; p = 0; + do { + if ((j = b[bindex+p]) != 0){ + v[x[j]++] = i; + } + p++; + } + while (++i < n); + n = x[g]; // set n to length of v + + // Generate the Huffman codes and for each, make the table entries + x[0] = i = 0; // first Huffman code is zero + p = 0; // grab values in bit order + h = -1; // no tables yet--level -1 + w = -l; // bits decoded == (l * h) + u[0] = 0; // just to keep compilers happy + q = 0; // ditto + z = 0; // ditto + + // go through the bit lengths (k already is bits in shortest code) + for (; k <= g; k++){ + a = c[k]; + while (a--!=0){ + // here i is the Huffman code of length k bits for value *p + // make tables up to required level + while (k > w + l){ + h++; + w += l; // previous table always l bits + // compute minimum size table less than or equal to l bits + z = g - w; + z = (z > l) ? l : z; // table size upper limit + if((f=1<<(j=k-w))>a+1){ // try a k-w bit table + // too few codes for k-w bit table + f -= a + 1; // deduct codes from patterns left + xp = k; + if(j < z){ + while (++j < z){ // try smaller tables up to z bits + if((f <<= 1) <= c[++xp]) + break; // enough codes to use up j bits + f -= c[xp]; // else deduct codes from patterns + } + } + } + z = 1 << j; // table entries for j-bit table + + // allocate new table + if (hn[0] + z > MANY){ // (note: doesn't matter for fixed) + return Z_DATA_ERROR; // overflow of MANY + } + u[h] = q = /*hp+*/ hn[0]; // DEBUG + hn[0] += z; + + // connect to last table, if there is one + if(h!=0){ + x[h]=i; // save pattern for backing up + r[0]=(byte)j; // bits in this table + r[1]=(byte)l; // bits to dump before this table + j=i>>>(w - l); + r[2] = q - u[h-1] - j; // offset to this table + System.arraycopy(r, 0, hp, (u[h-1]+j)*3, 3); // connect to last table + } + else{ + t[0] = q; // first table is returned result + } + } + + // set up table entry in r + r[1] = (byte)(k - w); + if (p >= n){ + r[0] = 128 + 64; // out of values--invalid code + } + else if (v[p] < s){ + r[0] = (byte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block + r[2] = v[p++]; // simple code is just the value + } + else{ + r[0]=(byte)(e[v[p]-s]+16+64); // non-simple--look up in lists + r[2]=d[v[p++] - s]; + } + + // fill code-like entries with r + f=1<<(k-w); + for (j=i>>>w;j>>= 1){ + i ^= j; + } + i ^= j; + + // backup over finished tables + mask = (1 << w) - 1; // needed on HP, cc -O bug + while ((i & mask) != x[h]){ + h--; // don't need to update q + w -= l; + mask = (1 << w) - 1; + } + } + } + // Return Z_BUF_ERROR if we were given an incomplete table + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; + } + + int inflate_trees_bits(int[] c, // 19 code lengths + int[] bb, // bits tree desired/actual depth + int[] tb, // bits tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + initWorkArea(19); + hn[0]=0; + result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed dynamic bit lengths tree"; + } + else if(result == Z_BUF_ERROR || bb[0] == 0){ + z.msg = "incomplete dynamic bit lengths tree"; + result = Z_DATA_ERROR; + } + return result; + } + + int inflate_trees_dynamic(int nl, // number of literal/length codes + int nd, // number of distance codes + int[] c, // that many (total) code lengths + int[] bl, // literal desired/actual bit depth + int[] bd, // distance desired/actual bit depth + int[] tl, // literal/length tree result + int[] td, // distance tree result + int[] hp, // space for trees + ZStream z // for messages + ){ + int result; + + // build literal/length tree + initWorkArea(288); + hn[0]=0; + result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (result != Z_OK || bl[0] == 0){ + if(result == Z_DATA_ERROR){ + z.msg = "oversubscribed literal/length tree"; + } + else if (result != Z_MEM_ERROR){ + z.msg = "incomplete literal/length tree"; + result = Z_DATA_ERROR; + } + return result; + } + + // build distance tree + initWorkArea(288); + result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + + if (result != Z_OK || (bd[0] == 0 && nl > 257)){ + if (result == Z_DATA_ERROR){ + z.msg = "oversubscribed distance tree"; + } + else if (result == Z_BUF_ERROR) { + z.msg = "incomplete distance tree"; + result = Z_DATA_ERROR; + } + else if (result != Z_MEM_ERROR){ + z.msg = "empty distance tree with lengths"; + result = Z_DATA_ERROR; + } + return result; + } + + return Z_OK; + } + + static int inflate_trees_fixed(int[] bl, //literal desired/actual bit depth + int[] bd, //distance desired/actual bit depth + int[][] tl,//literal/length tree result + int[][] td,//distance tree result + ZStream z //for memory allocation + ){ + bl[0]=fixed_bl; + bd[0]=fixed_bd; + tl[0]=fixed_tl; + td[0]=fixed_td; + return Z_OK; + } + + private void initWorkArea(int vsize){ + if(hn==null){ + hn=new int[1]; + v=new int[vsize]; + c=new int[BMAX+1]; + r=new int[3]; + u=new int[BMAX]; + x=new int[BMAX+1]; + } + if(v.length> 4) + 1; + if(w < 48) + w &= 15; + } + + if(w<8 ||w>15){ + inflateEnd(); + return Z_STREAM_ERROR; + } + if(blocks != null && wbits != w){ + blocks.free(); + blocks=null; + } + + // set window size + wbits=w; + + this.blocks=new InfBlocks(z, 1<>8))&0xff; + + if(((wrap&1)==0 || // check if zlib header allowed + (((this.method << 8)+b) % 31)!=0) && + (this.method&0xf)!=Z_DEFLATED){ + if(wrap == 4){ + z.next_in_index -= 2; + z.avail_in += 2; + z.total_in -= 2; + wrap = 0; + this.mode = BLOCKS; + break; + } + this.mode = BAD; + z.msg = "incorrect header check"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if((this.method&0xf)!=Z_DEFLATED){ + this.mode = BAD; + z.msg="unknown compression method"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + if(wrap == 4){ + wrap = 1; + } + + if((this.method>>4)+8>this.wbits){ + this.mode = BAD; + z.msg="invalid window size"; + // since zlib 1.2, it is allowted to inflateSync for this case. + /* + this.marker = 5; // can't try inflateSync + */ + break; + } + + z.adler=new Adler32(); + + if((b&PRESET_DICT)==0){ + this.mode = BLOCKS; + break; + } + this.mode = DICT4; + case DICT4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=DICT3; + case DICT3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode=DICT2; + case DICT2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode=DICT1; + case DICT1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need += (z.next_in[z.next_in_index++]&0xffL); + z.adler.reset(this.need); + this.mode = DICT0; + return Z_NEED_DICT; + case DICT0: + this.mode = BAD; + z.msg = "need dictionary"; + this.marker = 0; // can try inflateSync + return Z_STREAM_ERROR; + case BLOCKS: + r = this.blocks.proc(r); + if(r == Z_DATA_ERROR){ + this.mode = BAD; + this.marker = 0; // can try inflateSync + break; + } + if(r == Z_OK){ + r = f; + } + if(r != Z_STREAM_END){ + return r; + } + r = f; + this.was=z.adler.getValue(); + this.blocks.reset(); + if(this.wrap==0){ + this.mode=DONE; + break; + } + this.mode=CHECK4; + case CHECK4: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; + this.mode=CHECK3; + case CHECK3: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; + this.mode = CHECK2; + case CHECK2: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; + this.mode = CHECK1; + case CHECK1: + + if(z.avail_in==0)return r;r=f; + + z.avail_in--; z.total_in++; + this.need+=(z.next_in[z.next_in_index++]&0xffL); + + if(flags!=0){ // gzip + this.need = ((this.need&0xff000000)>>24 | + (this.need&0x00ff0000)>>8 | + (this.need&0x0000ff00)<<8 | + (this.need&0x0000ffff)<<24)&0xffffffffL; + } + + if(((int)(this.was)) != ((int)(this.need))){ + z.msg = "incorrect data check"; + // chack is delayed + /* + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + */ + } + else if(flags!=0 && gheader!=null){ + gheader.crc = this.need; + } + + this.mode = LENGTH; + case LENGTH: + if (wrap!=0 && flags!=0) { + + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + + if (this.need != (z.total_out & 0xffffffffL)) { + z.msg = "incorrect length check"; + this.mode = BAD; + break; + } + z.msg = null; + } + else { + if(z.msg!=null && z.msg.equals("incorrect data check")){ + this.mode = BAD; + this.marker = 5; // can't try inflateSync + break; + } + } + + this.mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + + case FLAGS: + + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + + flags = ((int)this.need)&0xffff; + + if ((flags & 0xff) != Z_DEFLATED) { + z.msg = "unknown compression method"; + this.mode = BAD; + break; + } + if ((flags & 0xe000)!=0) { + z.msg = "unknown header flags set"; + this.mode = BAD; + break; + } + + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + + this.mode = TIME; + + case TIME: + try { r=readBytes(4, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.setModifiedTime(this.need); + } + if ((flags & 0x0200)!=0){ + checksum(4, this.need); + } + this.mode = OS; + case OS: + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.xflags = ((int)this.need)&0xff; + gheader.os = (((int)this.need)>>8)&0xff; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + this.mode = EXLEN; + case EXLEN: + if ((flags & 0x0400)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.extra = new byte[((int)this.need)&0xffff]; + } + if ((flags & 0x0200)!=0){ + checksum(2, this.need); + } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = EXTRA; + + case EXTRA: + if ((flags & 0x0400)!=0) { + try { + r=readBytes(r, f); + if(gheader!=null){ + byte[] foo = tmp_string.toByteArray(); + tmp_string=null; + if(foo.length == gheader.extra.length){ + System.arraycopy(foo, 0, gheader.extra, 0, foo.length); + } + else{ + z.msg = "bad extra field length"; + this.mode = BAD; + break; + } + } + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.extra=null; + } + this.mode = NAME; + case NAME: + if ((flags & 0x0800)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.name=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.name=null; + } + this.mode = COMMENT; + case COMMENT: + if ((flags & 0x1000)!=0) { + try { + r=readString(r, f); + if(gheader!=null){ + gheader.comment=tmp_string.toByteArray(); + } + tmp_string=null; + } + catch(Return e){ return e.r; } + } + else if(gheader!=null){ + gheader.comment=null; + } + this.mode = HCRC; + case HCRC: + if ((flags & 0x0200)!=0) { + try { r=readBytes(2, r, f); } + catch(Return e){ return e.r; } + if(gheader!=null){ + gheader.hcrc=(int)(this.need&0xffff); + } + if(this.need != (z.adler.getValue()&0xffffL)){ + this.mode = BAD; + z.msg = "header crc mismatch"; + this.marker = 5; // can't try inflateSync + break; + } + } + z.adler = new CRC32(); + + this.mode = BLOCKS; + break; + default: + return Z_STREAM_ERROR; + } + } + } + + int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(z==null || (this.mode != DICT0 && this.wrap != 0)){ + return Z_STREAM_ERROR; + } + + int index=0; + int length = dictLength; + + if(this.mode==DICT0){ + long adler_need=z.adler.getValue(); + z.adler.reset(); + z.adler.update(dictionary, 0, dictLength); + if(z.adler.getValue()!=adler_need){ + return Z_DATA_ERROR; + } + } + + z.adler.reset(); + + if(length >= (1<0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + this.need = this.need | + ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); + need_bytes--; + } + if(n==2){ + this.need&=0xffffL; + } + else if(n==4) { + this.need&=0xffffffffL; + } + need_bytes=-1; + return r; + } + static class Return extends Exception{ + private static final long serialVersionUID=-1L; + int r; + Return(int r){this.r=r; } + } + + private ByteArrayOutputStream tmp_string = null; + private int readString(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new ByteArrayOutputStream(); + } + int b=0; + do { + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + }while(b!=0); + return r; + } + + private int readBytes(int r, int f) throws Return{ + if(tmp_string == null){ + tmp_string=new ByteArrayOutputStream(); + } + int b=0; + while(this.need>0){ + if(z.avail_in==0){ throw new Return(r); }; r=f; + z.avail_in--; z.total_in++; + b = z.next_in[z.next_in_index]; + tmp_string.write(z.next_in, z.next_in_index, 1); + z.adler.update(z.next_in, z.next_in_index, 1); + z.next_in_index++; + this.need--; + } + return r; + } + + private void checksum(int n, long v){ + for(int i=0; i>=8; + } + z.adler.update(crcbuf, 0, n); + } + + GZIPHeader getGZIPHeader(){ + return gheader; + } + + boolean inParsingHeader(){ + switch(mode){ + case HEAD: + case DICT4: + case DICT3: + case DICT2: + case DICT1: + case FLAGS: + case TIME: + case OS: + case EXLEN: + case EXTRA: + case NAME: + case COMMENT: + case HCRC: + return true; + default: + return false; + } + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflater.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflater.java new file mode 100644 index 00000000..84d22ce8 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Inflater.java @@ -0,0 +1,189 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class Inflater extends ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + private int param_w = -1; + private JZlib.WrapperType param_wrapperType = null; + private boolean param_nowrap = false; + + Inflater() { + super(); + init(); + } + + Inflater(JZlib.WrapperType wrapperType) throws GZIPException { + this(DEF_WBITS, wrapperType); + } + + Inflater(int w, JZlib.WrapperType wrapperType) throws GZIPException { + super(); + param_w = w; + param_wrapperType = wrapperType; + int ret = init(w, wrapperType); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + Inflater(int w) throws GZIPException { + this(w, false); + } + + Inflater(boolean nowrap) throws GZIPException { + this(DEF_WBITS, nowrap); + } + + Inflater(int w, boolean nowrap) throws GZIPException { + super(); + param_w = w; + param_nowrap = nowrap; + int ret = init(w, nowrap); + if(ret!=Z_OK) + throw new GZIPException(ret+": "+msg); + } + + void reset() { + finished = false; + if(param_wrapperType != null){ + init(param_w, param_wrapperType); + } + else { + init(param_w, param_nowrap); + } + } + + private boolean finished = false; + + int init(){ + return init(DEF_WBITS); + } + + int init(JZlib.WrapperType wrapperType){ + return init(DEF_WBITS, wrapperType); + } + + int init(int w, JZlib.WrapperType wrapperType) { + boolean nowrap = false; + if(wrapperType == JZlib.W_NONE){ + nowrap = true; + } + else if(wrapperType == JZlib.W_GZIP) { + w += 16; + } + else if(wrapperType == JZlib.W_ANY) { + w |= Inflate.INFLATE_ANY; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return init(w, nowrap); + } + + int init(boolean nowrap){ + return init(DEF_WBITS, nowrap); + } + + int init(int w){ + return init(w, false); + } + + int init(int w, boolean nowrap){ + finished = false; + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + @Override + int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + int ret = istate.inflate(f); + if(ret == Z_STREAM_END) + finished = true; + return ret; + } + + @Override + int end(){ + finished = true; + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + + int sync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + + int syncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + + int setDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + + @Override + boolean finished(){ + return istate.mode==12 /*DONE*/; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java new file mode 100644 index 00000000..2dcbf82f --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/InflaterInputStream.java @@ -0,0 +1,255 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2011 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.jzlib; +import java.io.*; + +final class InflaterInputStream extends FilterInputStream { + protected final Inflater inflater; + protected byte[] buf; + + private boolean closed = false; + + protected boolean eof = false; + + private boolean close_in = true; + + protected static final int DEFAULT_BUFSIZE = 512; + + InflaterInputStream(InputStream in) throws IOException { + this(in, false); + } + + InflaterInputStream(InputStream in, boolean nowrap) throws IOException { + this(in, new Inflater(nowrap)); + myinflater = true; + } + + InflaterInputStream(InputStream in, Inflater inflater) throws IOException { + this(in, inflater, DEFAULT_BUFSIZE); + } + + InflaterInputStream(InputStream in, + Inflater inflater, int size) throws IOException { + this(in, inflater, size, true); + } + + InflaterInputStream(InputStream in, + Inflater inflater, + int size, boolean close_in) throws IOException { + super(in); + if (in == null || inflater == null) { + throw new NullPointerException(); + } + else if (size <= 0) { + throw new IllegalArgumentException("buffer size must be greater than 0"); + } + this.inflater = inflater; + buf = new byte[size]; + this.close_in = close_in; + } + + protected boolean myinflater = false; + + private byte[] byte1 = new byte[1]; + + @Override + public int read() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + return read(byte1, 0, 1) == -1 ? -1 : byte1[0] & 0xff; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { throw new IOException("Stream closed"); } + if (b == null) { + throw new NullPointerException(); + } + else if (off < 0 || len < 0 || len > b.length - off) { + throw new IndexOutOfBoundsException(); + } + else if (len == 0) { + return 0; + } + else if (eof) { + return -1; + } + + int n = 0; + inflater.setOutput(b, off, len); + while(!eof) { + if(inflater.avail_in==0) + fill(); + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + n += inflater.next_out_index - off; + off = inflater.next_out_index; + switch(err) { + case JZlib.Z_DATA_ERROR: + throw new IOException(inflater.msg); + case JZlib.Z_STREAM_END: + case JZlib.Z_NEED_DICT: + eof = true; + if(err == JZlib.Z_NEED_DICT) + return -1; + break; + default: + } + if(inflater.avail_out==0) + break; + } + return n; + } + + @Override + public int available() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + if (eof) { + return 0; + } + else { + return 1; + } + } + + private byte[] b = new byte[512]; + + @Override + public long skip(long n) throws IOException { + if (n < 0) { + throw new IllegalArgumentException("negative skip length"); + } + + if (closed) { throw new IOException("Stream closed"); } + + int max = (int)Math.min(n, Integer.MAX_VALUE); + int total = 0; + while (total < max) { + int len = max - total; + if (len > b.length) { + len = b.length; + } + len = read(b, 0, len); + if (len == -1) { + eof = true; + break; + } + total += len; + } + return total; + } + + @Override + public void close() throws IOException { + if (!closed) { + if (myinflater) + inflater.end(); + if(close_in) + in.close(); + closed = true; + } + } + + protected void fill() throws IOException { + if (closed) { throw new IOException("Stream closed"); } + int len = in.read(buf, 0, buf.length); + if (len == -1) { + if(inflater.istate.wrap == 0 && + !inflater.finished()){ + buf[0]=0; + len=1; + } + else if(inflater.istate.was != -1){ // in reading trailer + throw new IOException("footer is not found"); + } + else{ + throw new EOFException("Unexpected end of ZLIB input stream"); + } + } + inflater.setInput(buf, 0, len, true); + } + + @Override + public boolean markSupported() { + return false; + } + + @Override + public synchronized void mark(int readlimit) { + } + + @Override + public synchronized void reset() throws IOException { + throw new IOException("mark/reset not supported"); + } + + long getTotalIn() { + return inflater.getTotalIn(); + } + + long getTotalOut() { + return inflater.getTotalOut(); + } + + byte[] getAvailIn() { + if(inflater.avail_in<=0) + return null; + byte[] tmp = new byte[inflater.avail_in]; + System.arraycopy(inflater.next_in, inflater.next_in_index, + tmp, 0, inflater.avail_in); + return tmp; + } + + void readHeader() throws IOException { + + byte[] empty = "".getBytes(); + inflater.setInput(empty, 0, 0, false); + inflater.setOutput(empty, 0, 0); + + int err = inflater.inflate(JZlib.Z_NO_FLUSH); + if(!inflater.istate.inParsingHeader()){ + return; + } + + byte[] b1 = new byte[1]; + do{ + int i = in.read(b1); + if(i<=0) + throw new IOException("no input"); + inflater.setInput(b1); + err = inflater.inflate(JZlib.Z_NO_FLUSH); + if(err!=0/*Z_OK*/) + throw new IOException(inflater.msg); + } + while(inflater.istate.inParsingHeader()); + } + + Inflater getInflater(){ + return inflater; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/JZlib.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/JZlib.java new file mode 100644 index 00000000..1d127559 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/JZlib.java @@ -0,0 +1,92 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class JZlib{ + private static final String version="1.1.3"; + static String version(){return version;} + + static final int MAX_WBITS=15; // 32K LZ77 window + static final int DEF_WBITS=MAX_WBITS; + + enum WrapperType { + NONE, ZLIB, GZIP, ANY + } + + static final WrapperType W_NONE = WrapperType.NONE; + static final WrapperType W_ZLIB = WrapperType.ZLIB; + static final WrapperType W_GZIP = WrapperType.GZIP; + static final WrapperType W_ANY = WrapperType.ANY; + + // compression levels + static final int Z_NO_COMPRESSION=0; + static final int Z_BEST_SPEED=1; + static final int Z_BEST_COMPRESSION=9; + static final int Z_DEFAULT_COMPRESSION=(-1); + + // compression strategy + static final int Z_FILTERED=1; + static final int Z_HUFFMAN_ONLY=2; + static final int Z_DEFAULT_STRATEGY=0; + + static final int Z_NO_FLUSH=0; + static final int Z_PARTIAL_FLUSH=1; + static final int Z_SYNC_FLUSH=2; + static final int Z_FULL_FLUSH=3; + static final int Z_FINISH=4; + + static final int Z_OK=0; + static final int Z_STREAM_END=1; + static final int Z_NEED_DICT=2; + static final int Z_ERRNO=-1; + static final int Z_STREAM_ERROR=-2; + static final int Z_DATA_ERROR=-3; + static final int Z_MEM_ERROR=-4; + static final int Z_BUF_ERROR=-5; + static final int Z_VERSION_ERROR=-6; + + // The three kinds of block type + static final byte Z_BINARY = 0; + static final byte Z_ASCII = 1; + static final byte Z_UNKNOWN = 2; + + static long adler32_combine(long adler1, long adler2, long len2){ + return Adler32.combine(adler1, adler2, len2); + } + + static long crc32_combine(long crc1, long crc2, long len2){ + return CRC32.combine(crc1, crc2, len2); + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java new file mode 100644 index 00000000..219c72b4 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/StaticTree.java @@ -0,0 +1,148 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class StaticTree{ + static final private int MAX_BITS=15; + + static final private int BL_CODES=19; + static final private int D_CODES=30; + static final private int LITERALS=256; + static final private int LENGTH_CODES=29; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + + // Bit length codes must not exceed MAX_BL_BITS bits + static final int MAX_BL_BITS=7; + + static final short[] static_ltree = { + 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, + 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, + 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, + 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, + 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, + 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, + 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, + 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, + 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, + 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, + 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, + 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, + 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, + 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, + 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, + 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, + 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, + 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, + 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, + 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, + 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, + 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, + 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, + 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, + 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, + 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, + 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, + 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, + 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, + 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, + 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, + 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, + 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, + 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, + 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, + 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, + 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, + 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, + 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, + 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, + 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, + 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, + 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, + 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, + 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, + 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, + 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, + 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, + 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, + 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, + 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, + 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, + 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, + 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, + 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, + 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, + 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, + 163, 8, 99, 8, 227, 8 + }; + + static final short[] static_dtree = { + 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, + 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, + 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, + 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, + 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, + 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 + }; + + static StaticTree static_l_desc = + new StaticTree(static_ltree, Tree.extra_lbits, + LITERALS+1, L_CODES, MAX_BITS); + + static StaticTree static_d_desc = + new StaticTree(static_dtree, Tree.extra_dbits, + 0, D_CODES, MAX_BITS); + + static StaticTree static_bl_desc = + new StaticTree(null, Tree.extra_blbits, + 0, BL_CODES, MAX_BL_BITS); + + short[] static_tree; // static tree or null + int[] extra_bits; // extra bits for each code or null + int extra_base; // base index for extra_bits + int elems; // max number of elements in the tree + int max_length; // max bit length for the codes + + private StaticTree(short[] static_tree, + int[] extra_bits, + int extra_base, + int elems, + int max_length){ + this.static_tree=static_tree; + this.extra_bits=extra_bits; + this.extra_base=extra_base; + this.elems=elems; + this.max_length=max_length; + } +} diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Tree.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Tree.java new file mode 100644 index 00000000..1bb87be2 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/Tree.java @@ -0,0 +1,367 @@ +/* -*-mode:java; c-basic-offset:2; -*- */ +/* +Copyright (c) 2000,2001,2002,2003 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +final class Tree{ + static final private int MAX_BITS=15; + static final private int BL_CODES=19; + static final private int D_CODES=30; + static final private int LITERALS=256; + static final private int LENGTH_CODES=29; + static final private int L_CODES=(LITERALS+1+LENGTH_CODES); + static final private int HEAP_SIZE=(2*L_CODES+1); + + // Bit length codes must not exceed MAX_BL_BITS bits + static final int MAX_BL_BITS=7; + + // end of block literal code + static final int END_BLOCK=256; + + // repeat previous bit length 3-6 times (2 bits of repeat count) + static final int REP_3_6=16; + + // repeat a zero length 3-10 times (3 bits of repeat count) + static final int REPZ_3_10=17; + + // repeat a zero length 11-138 times (7 bits of repeat count) + static final int REPZ_11_138=18; + + // extra bits for each length code + static final int[] extra_lbits={ + 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0 + }; + + // extra bits for each distance code + static final int[] extra_dbits={ + 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 + }; + + // extra bits for each bit length code + static final int[] extra_blbits={ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7 + }; + + static final byte[] bl_order={ + 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + + + // The lengths of the bit length codes are sent in order of decreasing + // probability, to avoid transmitting the lengths for unused bit + // length codes. + + static final int Buf_size=8*2; + + // see definition of array dist_code below + static final int DIST_CODE_LEN=512; + + static final byte[] _dist_code = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, + 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 + }; + + static final byte[] _length_code={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 + }; + + static final int[] base_length = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 160, 192, 224, 0 + }; + + static final int[] base_dist = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 + }; + + // Mapping from a distance to a distance code. dist is the distance - 1 and + // must not have side effects. _dist_code[256] and _dist_code[257] are never + // used. + static int d_code(int dist){ + return ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>>7)]); + } + + short[] dyn_tree; // the dynamic tree + int max_code; // largest code with non zero frequency + StaticTree stat_desc; // the corresponding static tree + + // Compute the optimal bit lengths for a tree and update the total bit length + // for the current block. + // IN assertion: the fields freq and dad are set, heap[heap_max] and + // above are the tree nodes sorted by increasing frequency. + // OUT assertions: the field len is set to the optimal bit length, the + // array bl_count contains the frequencies for each bit length. + // The length opt_len is updated; static_len is also updated if stree is + // not null. + void gen_bitlen(Deflate s){ + short[] tree = dyn_tree; + short[] stree = stat_desc.static_tree; + int[] extra = stat_desc.extra_bits; + int base = stat_desc.extra_base; + int max_length = stat_desc.max_length; + int h; // heap index + int n, m; // iterate over the tree elements + int bits; // bit length + int xbits; // extra bits + short f; // frequency + int overflow = 0; // number of elements with bit length too large + + for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0; + + // In a first pass, compute the optimal bit lengths (which may + // overflow in the case of the bit length tree). + tree[s.heap[s.heap_max]*2+1] = 0; // root of the heap + + for(h=s.heap_max+1; h max_length){ bits = max_length; overflow++; } + tree[n*2+1] = (short)bits; + // We overwrite tree[n*2+1] which is no longer needed + + if (n > max_code) continue; // not a leaf node + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n*2]; + s.opt_len += f * (bits + xbits); + if (stree!=null) s.static_len += f * (stree[n*2+1] + xbits); + } + if (overflow == 0) return; + + // This happens for example on obj2 and pic of the Calgary corpus + // Find the first bit length which could increase: + do { + bits = max_length-1; + while(s.bl_count[bits]==0) bits--; + s.bl_count[bits]--; // move one leaf down the tree + s.bl_count[bits+1]+=2; // move one overflow item as its brother + s.bl_count[max_length]--; + // The brother of the overflow item also moves one step up, + // but this does not affect bl_count[max_length] + overflow -= 2; + } + while (overflow > 0); + + for (bits = max_length; bits != 0; bits--) { + n = s.bl_count[bits]; + while (n != 0) { + m = s.heap[--h]; + if (m > max_code) continue; + if (tree[m*2+1] != bits) { + s.opt_len += ((long)bits - (long)tree[m*2+1])*(long)tree[m*2]; + tree[m*2+1] = (short)bits; + } + n--; + } + } + } + + // Construct one Huffman tree and assigns the code bit strings and lengths. + // Update the total bit length for the current block. + // IN assertion: the field freq is set for all tree elements. + // OUT assertions: the fields len and code are set to the optimal bit length + // and corresponding code. The length opt_len is updated; static_len is + // also updated if stree is not null. The field max_code is set. + void build_tree(Deflate s){ + short[] tree=dyn_tree; + short[] stree=stat_desc.static_tree; + int elems=stat_desc.elems; + int n, m; // iterate over heap elements + int max_code=-1; // largest code with non zero frequency + int node; // new node being created + + // Construct the initial heap, with least frequent element in + // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + // heap[0] is not used. + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for(n=0; n=1; n--) + s.pqdownheap(tree, n); + + // Construct the Huffman tree by repeatedly combining the least two + // frequent nodes. + + node=elems; // next internal node of the tree + do{ + // n = node of least frequency + n=s.heap[1]; + s.heap[1]=s.heap[s.heap_len--]; + s.pqdownheap(tree, 1); + m=s.heap[1]; // m = node of next least frequency + + s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency + s.heap[--s.heap_max] = m; + + // Create a new node father of n and m + tree[node*2] = (short)(tree[n*2] + tree[m*2]); + s.depth[node] = (byte)(Math.max(s.depth[n],s.depth[m])+1); + tree[n*2+1] = tree[m*2+1] = (short)node; + + // and insert the new node in the heap + s.heap[1] = node++; + s.pqdownheap(tree, 1); + } + while(s.heap_len>=2); + + s.heap[--s.heap_max] = s.heap[1]; + + // At this point, the fields freq and dad are set. We can now + // generate the bit lengths. + + gen_bitlen(s); + + // The field len is now set, we can generate the bit codes + gen_codes(tree, max_code, s.bl_count, s.next_code); + } + + // Generate the codes for a given tree and bit counts (which need not be + // optimal). + // IN assertion: the array bl_count contains the bit length statistics for + // the given tree and the field len is set for all tree elements. + // OUT assertion: the field code is set for all tree elements of non + // zero code length. + private final static void gen_codes( + short[] tree, // the tree to decorate + int max_code, // largest code with non zero frequency + short[] bl_count, // number of codes at each bit length + short[] next_code){ + short code = 0; // running code value + int bits; // bit index + int n; // code index + + // The distribution counts are first used to generate the code values + // without bit reversal. + next_code[0]=0; + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (short)((code + bl_count[bits-1]) << 1); + } + + // Check that the bit counts in bl_count are consistent. The last code + // must be all ones. + //Assert (code + bl_count[MAX_BITS]-1 == (1<>>=1; + res<<=1; + } + while(--len>0); + return res>>>1; + } +} + diff --git a/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/ZStream.java b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/ZStream.java new file mode 100644 index 00000000..efa79b41 --- /dev/null +++ b/src/java/JavaFileStorage/app/src/main/java/com/jcraft/jsch/jzlib/ZStream.java @@ -0,0 +1,369 @@ +/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */ +/* +Copyright (c) 2000-2011 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. + */ +/* + * This program is based on zlib-1.1.3, so all credit should go authors + * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) + * and contributors of zlib. + */ + +package com.jcraft.jsch.jzlib; + +class ZStream{ + + static final private int MAX_WBITS=15; // 32K LZ77 window + static final private int DEF_WBITS=MAX_WBITS; + + static final private int Z_NO_FLUSH=0; + static final private int Z_PARTIAL_FLUSH=1; + static final private int Z_SYNC_FLUSH=2; + static final private int Z_FULL_FLUSH=3; + static final private int Z_FINISH=4; + + static final private int MAX_MEM_LEVEL=9; + + static final private int Z_OK=0; + static final private int Z_STREAM_END=1; + static final private int Z_NEED_DICT=2; + static final private int Z_ERRNO=-1; + static final private int Z_STREAM_ERROR=-2; + static final private int Z_DATA_ERROR=-3; + static final private int Z_MEM_ERROR=-4; + static final private int Z_BUF_ERROR=-5; + static final private int Z_VERSION_ERROR=-6; + + byte[] next_in; // next input byte + int next_in_index; + int avail_in; // number of bytes available at next_in + long total_in; // total nb of input bytes read so far + + byte[] next_out; // next output byte should be put there + int next_out_index; + int avail_out; // remaining free space at next_out + long total_out; // total nb of bytes output so far + + String msg; + + Deflate dstate; + Inflate istate; + + int data_type; // best guess about the data type: ascii or binary + + Checksum adler; + + ZStream(){ + this(new Adler32()); + } + + ZStream(Checksum adler){ + this.adler=adler; + } + + int inflateInit(){ + return inflateInit(DEF_WBITS); + } + int inflateInit(boolean nowrap){ + return inflateInit(DEF_WBITS, nowrap); + } + int inflateInit(int w){ + return inflateInit(w, false); + } + int inflateInit(JZlib.WrapperType wrapperType) { + return inflateInit(DEF_WBITS, wrapperType); + } + int inflateInit(int w, JZlib.WrapperType wrapperType) { + boolean nowrap = false; + if(wrapperType == JZlib.W_NONE){ + nowrap = true; + } + else if(wrapperType == JZlib.W_GZIP) { + w += 16; + } + else if(wrapperType == JZlib.W_ANY) { + w |= Inflate.INFLATE_ANY; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return inflateInit(w, nowrap); + } + int inflateInit(int w, boolean nowrap){ + istate=new Inflate(this); + return istate.inflateInit(nowrap?-w:w); + } + + int inflate(int f){ + if(istate==null) return Z_STREAM_ERROR; + return istate.inflate(f); + } + int inflateEnd(){ + if(istate==null) return Z_STREAM_ERROR; + int ret=istate.inflateEnd(); +// istate = null; + return ret; + } + int inflateSync(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSync(); + } + int inflateSyncPoint(){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSyncPoint(); + } + int inflateSetDictionary(byte[] dictionary, int dictLength){ + if(istate == null) + return Z_STREAM_ERROR; + return istate.inflateSetDictionary(dictionary, dictLength); + } + boolean inflateFinished(){ + return istate.mode==12 /*DONE*/; + } + + int deflateInit(int level){ + return deflateInit(level, MAX_WBITS); + } + int deflateInit(int level, boolean nowrap){ + return deflateInit(level, MAX_WBITS, nowrap); + } + int deflateInit(int level, int bits){ + return deflateInit(level, bits, false); + } + int deflateInit(int level, int bits, int memlevel, JZlib.WrapperType wrapperType){ + if(bits < 9 || bits > 15){ + return Z_STREAM_ERROR; + } + if(wrapperType == JZlib.W_NONE) { + bits *= -1; + } + else if(wrapperType == JZlib.W_GZIP) { + bits += 16; + } + else if(wrapperType == JZlib.W_ANY) { + return Z_STREAM_ERROR; + } + else if(wrapperType == JZlib.W_ZLIB) { + } + return this.deflateInit(level, bits, memlevel); + } + int deflateInit(int level, int bits, int memlevel){ + dstate=new Deflate(this); + return dstate.deflateInit(level, bits, memlevel); + } + int deflateInit(int level, int bits, boolean nowrap){ + dstate=new Deflate(this); + return dstate.deflateInit(level, nowrap?-bits:bits); + } + int deflate(int flush){ + if(dstate==null){ + return Z_STREAM_ERROR; + } + return dstate.deflate(flush); + } + int deflateEnd(){ + if(dstate==null) return Z_STREAM_ERROR; + int ret=dstate.deflateEnd(); + dstate=null; + return ret; + } + int deflateParams(int level, int strategy){ + if(dstate==null) return Z_STREAM_ERROR; + return dstate.deflateParams(level, strategy); + } + int deflateSetDictionary (byte[] dictionary, int dictLength){ + if(dstate == null) + return Z_STREAM_ERROR; + return dstate.deflateSetDictionary(dictionary, dictLength); + } + + // Flush as much pending output as possible. All deflate() output goes + // through this function so some applications may wish to modify it + // to avoid allocating a large strm->next_out buffer and copying into it. + // (See also read_buf()). + void flush_pending(){ + int len=dstate.pending; + + if(len>avail_out) len=avail_out; + if(len==0) return; + + if(dstate.pending_buf.length<=dstate.pending_out || + next_out.length<=next_out_index || + dstate.pending_buf.length<(dstate.pending_out+len) || + next_out.length<(next_out_index+len)){ + //System.out.println(dstate.pending_buf.length+", "+dstate.pending_out+ + // ", "+next_out.length+", "+next_out_index+", "+len); + //System.out.println("avail_out="+avail_out); + } + + System.arraycopy(dstate.pending_buf, dstate.pending_out, + next_out, next_out_index, len); + + next_out_index+=len; + dstate.pending_out+=len; + total_out+=len; + avail_out-=len; + dstate.pending-=len; + if(dstate.pending==0){ + dstate.pending_out=0; + } + } + + // Read a new buffer from the current input stream, update the adler32 + // and total number of bytes read. All deflate() input goes through + // this function so some applications may wish to modify it to avoid + // allocating a large strm->next_in buffer and copying from it. + // (See also flush_pending()). + int read_buf(byte[] buf, int start, int size) { + int len=avail_in; + + if(len>size) len=size; + if(len==0) return 0; + + avail_in-=len; + + if(dstate.wrap!=0) { + adler.update(next_in, next_in_index, len); + } + System.arraycopy(next_in, next_in_index, buf, start, len); + next_in_index += len; + total_in += len; + return len; + } + + long getAdler(){ + return adler.getValue(); + } + + void free(){ + next_in=null; + next_out=null; + msg=null; + } + + void setOutput(byte[] buf){ + setOutput(buf, 0, buf.length); + } + + void setOutput(byte[] buf, int off, int len){ + next_out = buf; + next_out_index = off; + avail_out = len; + } + + void setInput(byte[] buf){ + setInput(buf, 0, buf.length, false); + } + + void setInput(byte[] buf, boolean append){ + setInput(buf, 0, buf.length, append); + } + + void setInput(byte[] buf, int off, int len, boolean append){ + if(len<=0 && append && next_in!=null) return; + + if(avail_in>0 && append){ + byte[] tmp = new byte[avail_in+len]; + System.arraycopy(next_in, next_in_index, tmp, 0, avail_in); + System.arraycopy(buf, off, tmp, avail_in, len); + next_in=tmp; + next_in_index=0; + avail_in+=len; + } + else{ + next_in=buf; + next_in_index=off; + avail_in=len; + } + } + + byte[] getNextIn(){ + return next_in; + } + + void setNextIn(byte[] next_in){ + this.next_in = next_in; + } + + int getNextInIndex(){ + return next_in_index; + } + + void setNextInIndex(int next_in_index){ + this.next_in_index = next_in_index; + } + + int getAvailIn(){ + return avail_in; + } + + void setAvailIn(int avail_in){ + this.avail_in = avail_in; + } + + byte[] getNextOut(){ + return next_out; + } + + void setNextOut(byte[] next_out){ + this.next_out = next_out; + } + + int getNextOutIndex(){ + return next_out_index; + } + + void setNextOutIndex(int next_out_index){ + this.next_out_index = next_out_index; + } + + int getAvailOut(){ + return avail_out; + + } + + void setAvailOut(int avail_out){ + this.avail_out = avail_out; + } + + long getTotalOut(){ + return total_out; + } + + long getTotalIn(){ + return total_in; + } + + String getMessage(){ + return msg; + } + + // Those methods are expected to be override by Inflater and Deflater. + // In the future, they will become abstract methods. + int end(){ return Z_OK; } + boolean finished(){ return false; } +}