package org.openstack.atlas.util.ca.util.fileio;
import org.openstack.atlas.util.ca.util.X509MapValue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bouncycastle.jce.provider.X509CertificateObject;
import org.openstack.atlas.util.ca.PemUtils;
import org.openstack.atlas.util.ca.primitives.PemBlock;
import org.openstack.atlas.util.ca.primitives.RsaConst;
import org.openstack.atlas.util.ca.exceptions.CapManUtilException;
import org.openstack.atlas.util.ca.exceptions.FileUtilsException;
public class RsaFileUtils {
private static final int BUFFSIZE = 64 * 1024;
static {
RsaConst.init();
}
public static byte[] readFileToByteArray(String fileName) throws FileNotFoundException, IOException {
byte[] data;
String fmt;
String msg;
FileInputStream fis;
InputStreamReader isr;
File file;
file = new File(fileName);
long flen = file.length();
if (flen > Integer.MAX_VALUE) {
fmt = "can not read more then %d bytes\n";
msg = String.format(fmt, Integer.MAX_VALUE);
throw new IOException(msg);
}
fis = new FileInputStream(file);
data = new byte[(int) flen];
fis.read(data, 0, (int) flen); // FAil
fis.close();
return data;
}
public static void writeFileFromByteArray(String fileName, byte[] data) throws IOException {
File file;
FileOutputStream fs;
DataOutputStream ds;
file = new File(fileName);
fs = new FileOutputStream(file);
ds = new DataOutputStream(fs);
ds.write(data);
ds.flush();
ds.close();
fs.close();
}
public static byte[] readFile(String fileName) throws FileNotFoundException, IOException {
File file = new File(fileName);
byte[] bytes = readFile(file);
return bytes;
}
public static byte[] readFileFromClassPath(String fileName) throws IOException {
InputStream is = RsaFileUtils.class.getResourceAsStream(fileName);
return readInputStream(is);
}
public static byte[] readInputStream(InputStream is) throws IOException {
byte[] bytesOut;
byte[] buff;
int nbytes;
ByteArrayOutputStream os = new ByteArrayOutputStream();
while (true) {
buff = new byte[BUFFSIZE];
nbytes = is.read(buff);
if (nbytes < 0) {
break;
}
os.write(buff, 0, nbytes);
}
bytesOut = os.toByteArray();
is.close();
os.close();
return bytesOut;
}
public static byte[] readFile(File file) throws FileNotFoundException, IOException {
FileInputStream is = new FileInputStream(file);
return readInputStream(is);
}
// for jython
public static List<File> dirWalk(String dirFileName, String patternString) {
File dirFile = new File(dirFileName);
Pattern p = (patternString == null) ? null : Pattern.compile(patternString);
return dirWalk(dirFile, p);
}
// Warning Beware of dirwalk on directories containing directory links
// A link such as "ln -s .. x" will cause circular walks.
public static List<File> dirWalk(File dirFile, Pattern fnPattern) {
List<File> files = new ArrayList<File>();
if (!dirFile.canRead() || !dirFile.isDirectory()) {
return files;// Return empty list if directory is unreadable
}
File[] scanFiles = dirFile.listFiles();
for (int i = 0; i < scanFiles.length; i++) {
File curFile = scanFiles[i];
String fullPath = curFile.getAbsolutePath();
if (!curFile.canRead()) {
continue; // Don't attempt to list unreadable files
}
if (curFile.isDirectory()) {
files.addAll(dirWalk(curFile, fnPattern));
}
if (curFile.isFile()) {
if (fnPattern != null) {
Matcher m = fnPattern.matcher(fullPath);
if (!m.matches()) { // If this didn't match the pattern re then skip it;
continue;
}
}
files.add(curFile);
}
}
return files;
}
// For Jython
public static List<X509MapValue> readX509File(String fileName) throws FileNotFoundException, IOException {
File file = new File(fileName);
return readX509FileToMapVals(file);
}
public static List<X509MapValue> readX509FileToMapVals(File file) throws FileNotFoundException, IOException {
List<X509MapValue> valMapList = new ArrayList<X509MapValue>();
byte[] pemBytes = readFile(file);
List<PemBlock> blocks = PemUtils.parseMultiPem(pemBytes);
for (PemBlock block : blocks) {
Object decodedObj = block.getDecodedObject();
if (decodedObj == null) {
continue;
}
if (!(decodedObj instanceof X509Certificate)) {
continue;
}
X509CertificateObject x509obj = (X509CertificateObject) block.getDecodedObject();
X509MapValue valMap = new X509MapValue(x509obj, file.getAbsolutePath(), block.getLineNum());
valMapList.add(valMap);
}
return valMapList;
}
public static List<X509MapValue> readX509FilesToMapVals(Collection<File> files) {
List<X509MapValue> mapVals = new ArrayList<X509MapValue>();
for (File file : files) {
List<X509MapValue> fileMapVals;
try {
fileMapVals = readX509FileToMapVals(file);
} catch (FileNotFoundException ex) {
String msg = String.format("File not found %s SKIPPING x509 read\n", file.getAbsolutePath());
Logger.getLogger(RsaFileUtils.class.getName()).log(Level.WARNING, msg, ex);
continue;
} catch (IOException ex) {
Logger.getLogger(RsaFileUtils.class.getName()).log(Level.WARNING, null, ex);
continue;
}
mapVals.addAll(fileMapVals);
}
return mapVals;
}
public static String expandUser(String pathIn) {
if (pathIn == null) {
return pathIn;
}
return pathIn.replace("~", System.getProperty("user.home"));
}
public static String[] splitPath(String pathName) {
List<String> pathList = new ArrayList<String>();
File file = new File(pathName);
while (true) {
if (file == null) {
break;
}
String name = file.getName();
pathList.add(name);
file = file.getParentFile();
}
Collections.reverse(pathList);
return pathList.toArray(new String[pathList.size()]);
}
public static String joinPath(String firstPart, String secondPart) {
return splitPathToString(joinPath(splitPath(firstPart), splitPath(secondPart)));
}
public static String[] joinPath(String[] firstPart, String[] secondPart) {
int firstLen = firstPart.length;
int secondLen = secondPart.length;
int i;
String[] newPath = new String[firstLen + secondLen];
for (i = 0; i < firstLen; i++) {
newPath[i] = firstPart[i];
}
for (i = 0; i < secondLen; i++) {
newPath[i + firstLen] = secondPart[i];
}
return newPath;
}
public static String splitPathToString(String[] splitPath) {
StringBuilder sb = new StringBuilder();
if (splitPath.length == 0) {
return null;
}
if (splitPath.length == 1) {
return splitPath[0];
}
for (int i = 0; i < splitPath.length - 1; i++) {
sb.append(splitPath[i]).append(File.separator);
}
sb.append(splitPath[splitPath.length - 1]);
return sb.toString();
}
public static String rebaseSplitPath(String srcBase, String srcPath, String dstBase) throws FileUtilsException {
String[] srcBaseArr = splitPath(srcBase);
String[] srcPathArr = splitPath(srcPath);
String[] dstBaseArr = splitPath(dstBase);
String[] rebasedPath = rebaseSplitPath(srcBaseArr, srcPathArr, dstBaseArr);
String rebasePathString = splitPathToString(rebasedPath);
return rebasePathString;
}
public static String[] rebaseSplitPath(String[] srcBase, String[] srcPath, String[] dstBase) throws FileUtilsException {
int srcBaseLen = srcBase.length;
int srcPathLen = srcPath.length;
int dstBaseLen = dstBase.length;
int i;
int j;
if (srcPathLen < srcBaseLen) {
throw new FileUtilsException("srcPath is smaller then srcBase");
}
for (i = 0; i < srcBaseLen; i++) {
if (!srcBase[i].equals(srcPath[i])) {
throw new FileUtilsException("srcPath does not include srcBase");
}
}
int deltaLen = srcPathLen - srcBaseLen;
int rebasedLength = dstBaseLen + deltaLen;
String[] rebasedPath = new String[rebasedLength];
System.arraycopy(dstBase, 0, rebasedPath, 0, dstBaseLen);
System.arraycopy(srcPath, srcBaseLen, rebasedPath, dstBaseLen, srcPathLen - srcBaseLen);
return rebasedPath;
}
public static String[] stripBeginingPath(String[] splitPath, int nTimes) {
if (splitPath.length <= nTimes) {
return new String[0];
}
int newLength = splitPath.length - nTimes;
String[] newPath = new String[newLength];
for (int i = 0; i < newLength; i++) {
newPath[i] = splitPath[nTimes + i];
}
return newPath;
}
public static String[] stripEndPath(String[] splitPath, int nTimes) {
if (splitPath.length <= nTimes) {
return new String[0];
}
int newLen = splitPath.length - nTimes;
String[] newPath = new String[newLen];
System.arraycopy(splitPath, 0, newPath, 0, newLen);
return newPath;
}
}