From 31e921b02810218d51ce5883d4cf921518750c7b Mon Sep 17 00:00:00 2001 From: Doug Kelly Date: Tue, 23 Feb 2016 14:04:53 -0600 Subject: [PATCH] HostKeyProvider: Use AbstractFileKeyPairProvider MINA SSHD didn't remove the FileKeyPairProvider in SSHD-1.0.0; it apparently got refactored a bit. By changing how HostKeyProvider works, we can take advantage of their new API and remove our copy of FileKeyPairProvider. Inspired-By: Lyor Goldstein Change-Id: Idfdcb947740a455619a9b6de2b07a4b1df7b1437 --- gerrit-sshd/BUCK | 1 - .../gerrit/sshd/FileKeyPairProvider.java | 150 ------------------ .../google/gerrit/sshd/HostKeyProvider.java | 15 +- .../src/main/resources/log4j.properties | 2 +- 4 files changed, 10 insertions(+), 158 deletions(-) delete mode 100644 gerrit-sshd/src/main/java/com/google/gerrit/sshd/FileKeyPairProvider.java diff --git a/gerrit-sshd/BUCK b/gerrit-sshd/BUCK index e8db32b0dc..686a52aecf 100644 --- a/gerrit-sshd/BUCK +++ b/gerrit-sshd/BUCK @@ -32,7 +32,6 @@ java_library( '@jgit//org.eclipse.jgit.archive:jgit-archive', ], provided_deps = [ - '//lib/bouncycastle:bcpkix', '//lib/bouncycastle:bcprov', ], visibility = ['PUBLIC'], diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/FileKeyPairProvider.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/FileKeyPairProvider.java deleted file mode 100644 index 8966b5f2cf..0000000000 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/FileKeyPairProvider.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package com.google.gerrit.sshd; - -import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider; -import org.apache.sshd.common.util.SecurityUtils; -import org.bouncycastle.openssl.PEMDecryptorProvider; -import org.bouncycastle.openssl.PEMEncryptedKeyPair; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.PasswordFinder; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; -import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder; - -import java.io.FileInputStream; -import java.io.InputStreamReader; -import java.security.KeyPair; -import java.util.Arrays; -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * This host key provider loads private keys from the specified files. - * - * Note that this class has a direct dependency on BouncyCastle and won't work - * unless it has been correctly registered as a security provider. - * - * @author Apache MINA SSHD Project - */ -public class FileKeyPairProvider extends AbstractKeyPairProvider { - - private String[] files; - private PasswordFinder passwordFinder; - - public FileKeyPairProvider() { - } - - public FileKeyPairProvider(String[] files) { - this.files = files; - } - - public FileKeyPairProvider(String[] files, PasswordFinder passwordFinder) { - this.files = files; - this.passwordFinder = passwordFinder; - } - - public String[] getFiles() { - return files; - } - - public void setFiles(String[] files) { - this.files = files; - } - - public PasswordFinder getPasswordFinder() { - return passwordFinder; - } - - public void setPasswordFinder(PasswordFinder passwordFinder) { - this.passwordFinder = passwordFinder; - } - - @Override - public Iterable loadKeys() { - if (!SecurityUtils.isBouncyCastleRegistered()) { - throw new IllegalStateException("BouncyCastle must be registered as a JCE provider"); - } - return new Iterable() { - @Override - public Iterator iterator() { - return new Iterator() { - private final Iterator iterator = Arrays.asList(files).iterator(); - private KeyPair nextKeyPair; - private boolean nextKeyPairSet = false; - @Override - public boolean hasNext() { - return nextKeyPairSet || setNextObject(); - } - @Override - public KeyPair next() { - if (!nextKeyPairSet) { - if (!setNextObject()) { - throw new NoSuchElementException(); - } - } - nextKeyPairSet = false; - return nextKeyPair; - } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - private boolean setNextObject() { - while (iterator.hasNext()) { - String file = iterator.next(); - nextKeyPair = doLoadKey(file); - if (nextKeyPair != null) { - nextKeyPairSet = true; - return true; - } - } - return false; - } - - }; - } - }; - } - - protected KeyPair doLoadKey(String file) { - try (PEMParser r = new PEMParser(new InputStreamReader( - new FileInputStream(file)))) { - Object o = r.readObject(); - JcaPEMKeyConverter pemConverter = new JcaPEMKeyConverter(); - pemConverter.setProvider("BC"); - if (passwordFinder != null && o instanceof PEMEncryptedKeyPair) { - JcePEMDecryptorProviderBuilder decryptorBuilder = new JcePEMDecryptorProviderBuilder(); - PEMDecryptorProvider pemDecryptor = decryptorBuilder.build(passwordFinder.getPassword()); - o = pemConverter.getKeyPair(((PEMEncryptedKeyPair) o).decryptKeyPair(pemDecryptor)); - } - - if (o instanceof PEMKeyPair) { - o = pemConverter.getKeyPair((PEMKeyPair)o); - return (KeyPair) o; - } else if (o instanceof KeyPair) { - return (KeyPair) o; - } - } catch (Exception e) { - log.warn("Unable to read key " + file, e); - } - return null; - } - -} diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java index 41640e8eda..6da8fd64cc 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/HostKeyProvider.java @@ -19,10 +19,12 @@ import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.ProvisionException; +import org.apache.sshd.common.keyprovider.AbstractFileKeyPairProvider; import org.apache.sshd.common.keyprovider.KeyPairProvider; import org.apache.sshd.common.util.SecurityUtils; import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; +import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -42,12 +44,12 @@ class HostKeyProvider implements Provider { Path rsaKey = site.ssh_rsa; Path dsaKey = site.ssh_dsa; - final List stdKeys = new ArrayList<>(2); + final List stdKeys = new ArrayList<>(2); if (Files.exists(rsaKey)) { - stdKeys.add(rsaKey.toAbsolutePath().toString()); + stdKeys.add(rsaKey.toAbsolutePath().toFile()); } if (Files.exists(dsaKey)) { - stdKeys.add(dsaKey.toAbsolutePath().toString()); + stdKeys.add(dsaKey.toAbsolutePath().toFile()); } if (Files.exists(objKey)) { @@ -60,7 +62,7 @@ class HostKeyProvider implements Provider { // Both formats of host key exist, we don't know which format // should be authoritative. Complain and abort. // - stdKeys.add(objKey.toAbsolutePath().toString()); + stdKeys.add(objKey.toAbsolutePath().toFile()); throw new ProvisionException("Multiple host keys exist: " + stdKeys); } @@ -72,8 +74,9 @@ class HostKeyProvider implements Provider { throw new ProvisionException("Bouncy Castle Crypto not installed;" + " needed to read server host keys: " + stdKeys + ""); } - return new FileKeyPairProvider(stdKeys - .toArray(new String[stdKeys.size()])); + AbstractFileKeyPairProvider kp = SecurityUtils.createFileKeyPairProvider(); + kp.setFiles(stdKeys); + return kp; } } } diff --git a/gerrit-war/src/main/resources/log4j.properties b/gerrit-war/src/main/resources/log4j.properties index 8bc9bb2b7a..bc5e575597 100644 --- a/gerrit-war/src/main/resources/log4j.properties +++ b/gerrit-war/src/main/resources/log4j.properties @@ -23,7 +23,7 @@ log4j.appender.stderr.layout.ConversionPattern=[%d] [%t] %-5p %c %x: %m%n log4j.logger.org.apache.mina=WARN log4j.logger.org.apache.sshd.common=WARN log4j.logger.org.apache.sshd.server=WARN -log4j.logger.org.apache.sshd.common.keyprovider.FileKeyPairProvider=INFO +log4j.logger.org.apache.sshd.common.keyprovider.AbstractFileKeyPairProvider=INFO log4j.logger.com.google.gerrit.sshd.GerritServerSession=WARN # Silence non-critical messages from mime-util.