001/* 002 * Copyright (C) 2012 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019package org.crsh.auth; 020 021import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider; 022import org.apache.sshd.common.util.SecurityUtils; 023import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 024import org.bouncycastle.openssl.PEMException; 025import org.bouncycastle.openssl.PEMKeyPair; 026import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; 027import org.crsh.ssh.util.KeyPairUtils; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030import java.io.FileInputStream; 031import java.io.InputStreamReader; 032import java.security.KeyPair; 033import java.security.PublicKey; 034import java.util.ArrayList; 035import java.util.List; 036 037/** 038 * A modified version of {@link org.apache.sshd.common.keyprovider.FileKeyPairProvider} that only load public keys 039 * either as {@link KeyPair} or as {@link PublicKey}. 040 * 041 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> 042 */ 043class FilePublicKeyProvider extends AbstractKeyPairProvider { 044 045 /** . */ 046 private static final Logger LOG = LoggerFactory.getLogger(FilePublicKeyProvider.class); 047 048 /** . */ 049 private String[] files; 050 051 FilePublicKeyProvider(String[] files) { 052 this.files = files; 053 } 054 055 public Iterable<KeyPair> loadKeys() { 056 if (!SecurityUtils.isBouncyCastleRegistered()) { 057 throw new IllegalStateException("BouncyCastle must be registered as a JCE provider"); 058 } 059 List<KeyPair> keys = new ArrayList<KeyPair>(); 060 for (String file : files) { 061 try { 062 Object o = KeyPairUtils.readKey(new InputStreamReader(new FileInputStream(file))); 063 if (o instanceof KeyPair) { 064 keys.add(new KeyPair(((KeyPair)o).getPublic(), null)); 065 } else if (o instanceof PublicKey) { 066 keys.add(new KeyPair((PublicKey)o, null)); 067 } else if (o instanceof PEMKeyPair) { 068 PEMKeyPair keyPair = (PEMKeyPair)o; 069 keys.add(convertPemKeyPair(keyPair)); 070 } else if (o instanceof SubjectPublicKeyInfo) { 071 PEMKeyPair keyPair = new PEMKeyPair((SubjectPublicKeyInfo) o, null); 072 keys.add(convertPemKeyPair(keyPair)); 073 } else { 074 throw new UnsupportedOperationException(String.format("Key type %s not supported.", o.getClass().getName())); 075 } 076 } 077 catch (Exception e) { 078 LOG.info("Unable to read key {}: {}", file, e); 079 } 080 } 081 return keys; 082 } 083 084 private KeyPair convertPemKeyPair(PEMKeyPair pemKeyPair) throws PEMException { 085 JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); 086 return new KeyPair(converter.getPublicKey(pemKeyPair.getPublicKeyInfo()), null); 087 } 088 089}