OWASP dependency-check Command Line ToolでIO Exception: Connection resetの対処

[OWASP dependency-check](https://www.owasp.org/index.php/OWASP_Dependency_Check)というツールの実行でエラー（IO Exception: Connection reset）になったときの対応をまとめました。

ざっくりまとめると当該環境で使用していたJDKが脆弱性情報取得先のサイトが指定している暗号化スイートに対応できていなかったため起こったエラーでした。
当該環境のJDKに[BouncyCastle](https://www.bouncycastle.org/java.html)という、暗号化用のAPIを提供してくれるライブラリを追加して解決しました。

もともとはVulsとOWASP　dependency-checkの連携のために作業をしていました。
https://vuls.io/docs/ja/usage-scan-non-os-packages.html#usage-integrate-with-owasp-dependency-check-to-automatic-update-when-the-libraries-are-updated-experimental

## debug trace抜粋

```
ERROR - IO Exception: Connection reset
2018-03-08 10:28:05,137 org.owasp.dependencycheck.utils.Downloader:280
DEBUG - Exception details
java.net.SocketException: Connection reset
  at java.net.SocketInputStream.read(SocketInputStream.java:197)
  at java.net.SocketInputStream.read(SocketInputStream.java:122)
  at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
  at sun.security.ssl.InputRecord.read(InputRecord.java:480)
  at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:944)
  at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1342)
  at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1369)
  at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1353)
  at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
  at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
  at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
  at org.owasp.dependencycheck.utils.Downloader.getLastModified(Downloader.java:268)
  at org.owasp.dependencycheck.utils.Downloader.getLastModified(Downloader.java:235)
  at org.owasp.dependencycheck.data.update.NvdCveUpdater$TimestampRetriever.call(NvdCveUpdater.java:507)
  at org.owasp.dependencycheck.data.update.NvdCveUpdater$TimestampRetriever.call(NvdCveUpdater.java:480)
  at java.util.concurrent.FutureTask.run(FutureTask.java:262)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
  at java.lang.Thread.run(Thread.java:748)
```

同じシチュエーションのIssueがありました。
https://github.com/jeremylong/DependencyCheck/issues/561

長いですが、結局
https://github.com/jeremylong/DependencyCheck/issues/561#issuecomment-257045439
Bouncy Castleというものが足りないということでした。

最新のOpenJDKなら入ってるから大丈夫とのコメントも。
https://github.com/jeremylong/DependencyCheck/issues/561#issuecomment-267774165

## 原因

https://stackoverflow.com/questions/40305004/java-tls-connection-reset-using-some-jdks

脆弱性情報を提供してくれているnvd.nist.govが使っているTLS通信の暗号化スイートにJDKが対応できないため Connection resetになっていました。

## 対処

該当の暗号化スイートにJDKが対応できるようにすればOK。

やり方
https://stackoverflow.com/questions/31971499/ecdhe-cipher-suites-not-supported-on-openjdk-8-installed-on-ec2-linux-machine


## JDKにBouncyCastleを追加する

日本語の手順
https://www.intra-mart.jp/document/library/sso/public/im_sso_setup_guide/texts/install/login_server_config/security_provider/index.html

### 補足：AmazonLinuxでbcprov-jdkXX-YYY.jarを置く場所とjava.securityの場所

```
$ type java
java is /usr/bin/java
$ ls -lha /usr/bin/java
lrwxrwxrwx 1 root root 22  8月 13  2017 /usr/bin/java -> /etc/alternatives/java*
$ ls -lha /etc/alternatives/java
lrwxrwxrwx 1 root root 46  8月 13  2017 /etc/alternatives/java -> /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java*
$ cd /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/lib/ext # <- ココにbcprov-jdkXX-YYY.jarを配置
$ vim /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/lib/security/java.security # <- java.securityの場所
```

### 実際に行った手順


```
$ cd /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/lib/ext
$ sudo wget http://www.bouncycastle.org/download/bcprov-jdk15on-159.jar
$ sudo vim /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/lib/security/java.security
```

```diff
  #
  # List of providers and their preference orders (see above):
  #
  security.provider.1=sun.security.provider.Sun
  security.provider.2=sun.security.rsa.SunRsaSign
  security.provider.3=sun.security.ec.SunEC
  security.provider.4=com.sun.net.ssl.internal.ssl.Provider
  security.provider.5=com.sun.crypto.provider.SunJCE
  security.provider.6=sun.security.jgss.SunProvider
  security.provider.7=com.sun.security.sasl.Provider
  security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
  security.provider.9=sun.security.smartcardio.SunPCSC
+ security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider
  # the NSS security provider was not enabled for this build; it can be enabled
  # if NSS (libnss3) is available on the machine. The nss.cfg file may need
```

## 再度実行

```
$ ./dependency-check/bin/dependency-check.sh -f XML -o ./result.xml -s /web/current/api/current --project dev-api -l ./owasp.log
[ERROR] Exception from bundle-audit process: java.io.IOException: Cannot run program "bundle-audit" (in directory "/tmp/dctemp668de20e-5168-4592-ada8-6b73ba425d34"): error=2, そのようなファイルやディレクトリはありません. Disabling Ruby Bundle Audit Analyzer
```

エラーになりましたが、bundle-auditを実行できないという、スキャン対象の環境でRubyを使っているのが理由のエラーでした。

https://rubygems.org/gems/bundler-audit

ですので、ここまでで表題のエラーは解決しているはずです。

### bundler-auditをインストール

ついでにbundle-auditの設定も記述しておきます。簡単ですが。

```
$ sudo gem install bundler-audit
```

## 再々度実行

結果の出力先を/tmp/result.xmlに変えてます

```
$ ./dependency-check/bin/dependency-check.sh -f XML -o /tmp/result.xml -s /web/current/api/current --project dev-api -l ./owasp02.log
```

正常終了しました。

以上です。