/*
|
* The contents of this file are subject to the terms of the Common Development and
|
* Distribution License (the License). You may not use this file except in compliance with the
|
* License.
|
*
|
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
|
* specific language governing permission and limitations under the License.
|
*
|
* When distributing Covered Software, include this CDDL Header Notice in each file and include
|
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
|
* Header, with the fields enclosed by brackets [] replaced by your own identifying
|
* information: "Portions Copyright [year] [name of copyright owner]".
|
*
|
* Copyright 2006-2008 Sun Microsystems, Inc.
|
* Portions Copyright 2014-2015 ForgeRock AS.
|
*/
|
package org.opends.server.loggers;
|
|
//import java.io.BufferedInputStream;
|
import java.io.File;
|
//import java.io.FileInputStream;
|
//import java.io.RandomAccessFile;
|
//import java.security.MessageDigest;
|
//import java.security.PrivateKey;
|
//import java.security.PublicKey;
|
//import java.security.Signature;
|
//import java.security.cert.X509Certificate;
|
//import javax.net.ssl.KeyManager;
|
//import javax.net.ssl.X509KeyManager;
|
|
//import org.opends.server.core.DirectoryServer;
|
|
/**
|
* This class implements a post rotation action that signs
|
* the file.
|
*/
|
class SignatureAction implements PostRotationAction
|
{
|
|
private static final String delimiter = "---------";
|
private File originalFile;
|
private String signatureAlgorithm = "SHA1withRSA";
|
private String digestAlgorithm = "SHA";
|
private String alias;
|
|
/**
|
* Create the signature action based on the log file name,
|
* and the certificate alias to use for signing.
|
*
|
* @param origFile The source file name to sign.
|
* @param alias The certificate alias to use for signing.
|
*/
|
SignatureAction(String origFile, String alias)
|
{
|
this.originalFile = new File(origFile);
|
this.alias = alias;
|
}
|
|
/**
|
* Create the signature action based on the log file name,
|
* the signature algorithm, the digest algorithm, and the certificate alias
|
* to use for signing.
|
*
|
* @param origFile The source file name to sign.
|
* @param sigAlg The signature algorithm to use.
|
* @param digestAlg The MD5 digest algorithm to use.
|
* @param alias The certificate alias to use for signing.
|
*/
|
SignatureAction(String origFile, String sigAlg, String digestAlg,
|
String alias)
|
{
|
this.originalFile = new File(origFile);
|
this.signatureAlgorithm = sigAlg;
|
this.digestAlgorithm = digestAlg;
|
this.alias = alias;
|
}
|
|
/**
|
* The signature action that is executed. Returns true if the
|
* action succeeded and false otherwise.
|
*
|
* @return <CODE>true</CODE> if the signature was generated successfully, or
|
* <CODE>false</CODE> if not.
|
*/
|
public boolean execute()
|
{
|
// FIXME -- It is currently not possible to sign on rotate because of the
|
// way that they key manager providers are defined. However, this function
|
// wasn't implemented in an ideal fashion anyway, so the signing capability
|
// should remain disabled until the rotation action mechanism is rewritten.
|
// The original code has been preserved here for reference purposes.
|
return false;
|
//
|
// FileInputStream fis = null;
|
// boolean inputStreamOpen = false;
|
// try
|
// {
|
// KeyManager[] keyMgrs =
|
// DirectoryServer.getKeyManagerProvider().getKeyManagers();
|
// if(keyMgrs.length == 0)
|
// {
|
// // No keys available.
|
// // FIXME - Log in error log.
|
// System.err.println("No private key available to sign with.");
|
// return false;
|
// }
|
// X509KeyManager mgr = (X509KeyManager) keyMgrs[0];
|
// PrivateKey priv = mgr.getPrivateKey(alias);
|
//
|
// Signature sig = Signature.getInstance(signatureAlgorithm);
|
// sig.initSign(priv);
|
//
|
// MessageDigest md = MessageDigest.getInstance(digestAlgorithm);
|
// md.reset();
|
//
|
// fis = new FileInputStream(originalFile);
|
// inputStreamOpen = true;
|
// BufferedInputStream bufin = new BufferedInputStream(fis);
|
// byte[] buffer = new byte[1024];
|
// int len;
|
// while (bufin.available() != 0)
|
// {
|
// len = bufin.read(buffer);
|
// md.update(buffer, 0, len);
|
// }
|
// bufin.close();
|
//
|
// // Create a hash of the log file contents.
|
// byte[] hash = md.digest();
|
// // printBytes(hash);
|
// sig.update(hash);
|
//
|
// // Sign the hash.
|
// byte[] realSig = sig.sign();
|
// // printBytes(realSig);
|
//
|
// // Append the signature to the end of the file.
|
// RandomAccessFile raf = new RandomAccessFile(originalFile, "rw");
|
// raf.seek(raf.length());
|
// raf.write(delimiter.getBytes());
|
// raf.write("\n".getBytes());
|
// raf.write(realSig);
|
//
|
// return true;
|
// } catch(Exception ioe)
|
// {
|
// assert debugException(CLASS_NAME, "execute", ioe);
|
// if(inputStreamOpen)
|
// {
|
// try
|
// {
|
// fis.close();
|
// } catch(Exception fe)
|
// {
|
// assert debugException(CLASS_NAME, "execute", fe);
|
// // Cannot do much. Ignore.
|
// }
|
// }
|
// return false;
|
// }
|
}
|
|
|
/**
|
* Verify the signature int the log file. Returns true if the
|
* the signature is valid and false otherwise.
|
*
|
* @return <CODE>true</CODE> if the signature is valid, or <CODE>false</CODE>
|
* if not.
|
*/
|
public boolean verify()
|
{
|
// FIXME -- It is currently not possible to sign on rotate because of the
|
// way that they key manager providers are defined. However, this function
|
// wasn't implemented in an ideal fashion anyway, so the signing capability
|
// should remain disabled until the rotation action mechanism is rewritten.
|
// The original code has been preserved here for reference purposes.
|
return false;
|
// RandomAccessFile inFile = null;
|
// boolean inputStreamOpen = false;
|
// try
|
// {
|
// KeyManager[] keyMgrs =
|
// DirectoryServer.getKeyManagerProvider().getKeyManagers();
|
//
|
// if(keyMgrs.length == 0)
|
// {
|
// // No keys available.
|
// // FIXME - Log in error log.
|
// System.err.println("No public key available to verify signature.");
|
// return false;
|
// }
|
//
|
// X509KeyManager mgr = (X509KeyManager) keyMgrs[0];
|
// X509Certificate[] certChain = mgr.getCertificateChain(alias);
|
//
|
// if(certChain == null || certChain.length == 0)
|
// {
|
// System.err.println("Cannot find the public key for the signature.");
|
// return false;
|
// }
|
//
|
// PublicKey pubKey = certChain[0].getPublicKey();
|
//
|
// Signature sig = Signature.getInstance(signatureAlgorithm);
|
// sig.initVerify(pubKey);
|
//
|
// MessageDigest md = MessageDigest.getInstance(digestAlgorithm);
|
// md.reset();
|
//
|
// inFile = new RandomAccessFile(originalFile, "r");
|
// inputStreamOpen = true;
|
// String line = null;
|
// while ((line = inFile.readLine()) != null)
|
// {
|
// if(line.equals(delimiter))
|
// {
|
// break;
|
// }
|
// // int len = line.length();
|
// // md.update(line.getBytes(), 0, len);
|
// byte[] b = (line + "\n").getBytes();
|
// md.update(b);
|
// }
|
//
|
// // Read signature
|
// byte[] sigToVerify = new byte[128];
|
// int val = inFile.read(sigToVerify, 0, 128);
|
// // printBytes(sigToVerify);
|
//
|
// // Create a hash of the log file contents.
|
// byte[] hash = md.digest();
|
// // printBytes(hash);
|
// sig.update(hash);
|
//
|
//
|
// // Verify the hash.
|
// boolean verifies = sig.verify(sigToVerify);
|
//
|
// return verifies;
|
// } catch(Exception ioe)
|
// {
|
// assert debugException(CLASS_NAME, "execute", ioe);
|
// if(inputStreamOpen)
|
// {
|
// try
|
// {
|
// inFile.close();
|
// } catch(Exception fe)
|
// {
|
// assert debugException(CLASS_NAME, "execute", fe);
|
// // Cannot do much. Ignore.
|
// }
|
// }
|
// return false;
|
// }
|
}
|
|
|
|
/**
|
* Prints a representation of the contents of the provided byte array to
|
* standard output.
|
*
|
* @param bArray The array containing the data to be printed.
|
*/
|
private void printBytes(byte[] bArray)
|
{
|
for(int i = 0; i < bArray.length; i++)
|
{
|
System.out.print(Integer.toHexString(bArray[i]));
|
}
|
System.out.println("");
|
}
|
|
|
}
|