/* * Copyright 2012-2013 Mathias Herberts * * Licensed 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.geoxp.oss.client; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import org.bouncycastle.util.encoders.Hex; import com.geoxp.oss.CryptoHelper; import com.geoxp.oss.MasterSecretGenerator; import com.geoxp.oss.OSS; import com.geoxp.oss.OSSException; public class OSSRekey { public static void main(String[] args) throws Exception { if (args.length < 3) { throw new OSSException("Usage: OSSRekey CURRENT_MASTER_SECRET_NAMED_PIPE NEW_MASTER_SECRET_NAMED_PIPE SUFFIX"); } String suffix = args[2]; // // Read current and new master secrets // byte[] buf = new byte[1024]; ByteArrayOutputStream currentMasterSecret = new ByteArrayOutputStream(); ByteArrayOutputStream newMasterSecret = new ByteArrayOutputStream(); InputStream is = new FileInputStream(args[0]); while (true) { int len = is.read(buf); if (len < 0) { break; } currentMasterSecret.write(buf, 0, len); } is.close(); is = new FileInputStream(args[1]); while(true) { int len = is.read(buf); if (len < 0) { break; } newMasterSecret.write(buf, 0, len); } is.close(); // // unwrap both current and new master secrets with the internal control KEK // byte[] currentMS = CryptoHelper.unwrapAES( MasterSecretGenerator.getMasterSecretWrappingKey(), currentMasterSecret.toByteArray()); byte[] newMS = CryptoHelper.unwrapAES( MasterSecretGenerator.getMasterSecretWrappingKey(), newMasterSecret.toByteArray()); // // loop on a list of secret files to rekey, provided on stdin // BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ByteArrayOutputStream baos = new ByteArrayOutputStream(); long nano = System.nanoTime(); int count = 0; while (true) { String line = br.readLine(); if (null == line) { break; } // // Read data wrapped with current master secret // baos.reset(); is = new FileInputStream(line); while (true) { int len = is.read(buf); if (len < 0) { break; } baos.write(buf, 0, len); } is.close(); // // Unwrap data with current master secret // byte[] data = CryptoHelper.unwrapBlob(currentMS, baos.toByteArray()); if (null == data) { throw new OSSException("Unable to unwrap data in '" + line + "'"); } // // Wrap data with new master secret and write it to the suffixed file // OutputStream os = new FileOutputStream(line + suffix); os.write(CryptoHelper.wrapBlob(newMS, data)); os.close(); count++; } nano = System.nanoTime() - nano; System.out.println("Rekeyed " + count + " files in " + (nano / 1000000.0) + " ms."); } }