001 /*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License"). You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at
010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 * Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 * Copyright 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.loggers;
028
029 //import java.io.BufferedInputStream;
030 import java.io.File;
031 //import java.io.FileInputStream;
032 //import java.io.RandomAccessFile;
033 //import java.security.MessageDigest;
034 //import java.security.PrivateKey;
035 //import java.security.PublicKey;
036 //import java.security.Signature;
037 //import java.security.cert.X509Certificate;
038 //import javax.net.ssl.KeyManager;
039 //import javax.net.ssl.X509KeyManager;
040
041 //import org.opends.server.core.DirectoryServer;
042
043 /**
044 * This class implements a post rotation action that signs
045 * the file.
046 */
047 public class SignatureAction implements PostRotationAction
048 {
049
050 private static final String delimiter = "---------";
051 private File originalFile;
052 private String signatureAlgorithm = "SHA1withRSA";
053 private String digestAlgorithm = "SHA";
054 private String alias = null;
055
056 /**
057 * Create the signature action based on the log file name,
058 * and the certificate alias to use for signing.
059 *
060 * @param origFile The source file name to sign.
061 * @param alias The certificate alias to use for signing.
062 */
063 public SignatureAction(String origFile, String alias)
064 {
065 this.originalFile = new File(origFile);
066 this.alias = alias;
067 }
068
069 /**
070 * Create the signature action based on the log file name,
071 * the signature algorithm, the digest algorithm, and the certificate alias
072 * to use for signing.
073 *
074 * @param origFile The source file name to sign.
075 * @param sigAlg The signature algorithm to use.
076 * @param digestAlg The MD5 digest algorithm to use.
077 * @param alias The certificate alias to use for signing.
078 */
079 public SignatureAction(String origFile, String sigAlg, String digestAlg,
080 String alias)
081 {
082 this.originalFile = new File(origFile);
083 this.signatureAlgorithm = sigAlg;
084 this.digestAlgorithm = digestAlg;
085 this.alias = alias;
086 }
087
088 /**
089 * The signature action that is executed. Returns true if the
090 * action succeeded and false otherwise.
091 *
092 * @return <CODE>true</CODE> if the signature was generated successfully, or
093 * <CODE>false</CODE> if not.
094 */
095 public boolean execute()
096 {
097 // FIXME -- It is currently not possible to sign on rotate because of the
098 // way that they key manager providers are defined. However, this function
099 // wasn't implemented in an ideal fashion anyway, so the signing capability
100 // should remain disabled until the rotation action mechanism is rewritten.
101 // The original code has been preserved here for reference purposes.
102 return false;
103 //
104 // FileInputStream fis = null;
105 // boolean inputStreamOpen = false;
106 // try
107 // {
108 // KeyManager[] keyMgrs =
109 // DirectoryServer.getKeyManagerProvider().getKeyManagers();
110 // if(keyMgrs.length == 0)
111 // {
112 // // No keys available.
113 // // FIXME - Log in error log.
114 // System.err.println("No private key available to sign with.");
115 // return false;
116 // }
117 // X509KeyManager mgr = (X509KeyManager) keyMgrs[0];
118 // PrivateKey priv = mgr.getPrivateKey(alias);
119 //
120 // Signature sig = Signature.getInstance(signatureAlgorithm);
121 // sig.initSign(priv);
122 //
123 // MessageDigest md = MessageDigest.getInstance(digestAlgorithm);
124 // md.reset();
125 //
126 // fis = new FileInputStream(originalFile);
127 // inputStreamOpen = true;
128 // BufferedInputStream bufin = new BufferedInputStream(fis);
129 // byte[] buffer = new byte[1024];
130 // int len;
131 // while (bufin.available() != 0)
132 // {
133 // len = bufin.read(buffer);
134 // md.update(buffer, 0, len);
135 // }
136 // bufin.close();
137 //
138 // // Create a hash of the log file contents.
139 // byte[] hash = md.digest();
140 // // printBytes(hash);
141 // sig.update(hash);
142 //
143 // // Sign the hash.
144 // byte[] realSig = sig.sign();
145 // // printBytes(realSig);
146 //
147 // // Append the signature to the end of the file.
148 // RandomAccessFile raf = new RandomAccessFile(originalFile, "rw");
149 // raf.seek(raf.length());
150 // raf.write(delimiter.getBytes());
151 // raf.write("\n".getBytes());
152 // raf.write(realSig);
153 //
154 // return true;
155 // } catch(Exception ioe)
156 // {
157 // assert debugException(CLASS_NAME, "execute", ioe);
158 // if(inputStreamOpen)
159 // {
160 // try
161 // {
162 // fis.close();
163 // } catch(Exception fe)
164 // {
165 // assert debugException(CLASS_NAME, "execute", fe);
166 // // Cannot do much. Ignore.
167 // }
168 // }
169 // return false;
170 // }
171 }
172
173
174 /**
175 * Verify the signature int the log file. Returns true if the
176 * the signature is valid and false otherwise.
177 *
178 * @return <CODE>true</CODE> if the signature is valid, or <CODE>false</CODE>
179 * if not.
180 */
181 public boolean verify()
182 {
183 // FIXME -- It is currently not possible to sign on rotate because of the
184 // way that they key manager providers are defined. However, this function
185 // wasn't implemented in an ideal fashion anyway, so the signing capability
186 // should remain disabled until the rotation action mechanism is rewritten.
187 // The original code has been preserved here for reference purposes.
188 return false;
189 // RandomAccessFile inFile = null;
190 // boolean inputStreamOpen = false;
191 // try
192 // {
193 // KeyManager[] keyMgrs =
194 // DirectoryServer.getKeyManagerProvider().getKeyManagers();
195 //
196 // if(keyMgrs.length == 0)
197 // {
198 // // No keys available.
199 // // FIXME - Log in error log.
200 // System.err.println("No public key available to verify signature.");
201 // return false;
202 // }
203 //
204 // X509KeyManager mgr = (X509KeyManager) keyMgrs[0];
205 // X509Certificate[] certChain = mgr.getCertificateChain(alias);
206 //
207 // if(certChain == null || certChain.length == 0)
208 // {
209 // System.err.println("Cannot find the public key for the signature.");
210 // return false;
211 // }
212 //
213 // PublicKey pubKey = certChain[0].getPublicKey();
214 //
215 // Signature sig = Signature.getInstance(signatureAlgorithm);
216 // sig.initVerify(pubKey);
217 //
218 // MessageDigest md = MessageDigest.getInstance(digestAlgorithm);
219 // md.reset();
220 //
221 // inFile = new RandomAccessFile(originalFile, "r");
222 // inputStreamOpen = true;
223 // String line = null;
224 // while ((line = inFile.readLine()) != null)
225 // {
226 // if(line.equals(delimiter))
227 // {
228 // break;
229 // }
230 // // int len = line.length();
231 // // md.update(line.getBytes(), 0, len);
232 // byte[] b = (line + "\n").getBytes();
233 // md.update(b);
234 // }
235 //
236 // // Read signature
237 // byte[] sigToVerify = new byte[128];
238 // int val = inFile.read(sigToVerify, 0, 128);
239 // // printBytes(sigToVerify);
240 //
241 // // Create a hash of the log file contents.
242 // byte[] hash = md.digest();
243 // // printBytes(hash);
244 // sig.update(hash);
245 //
246 //
247 // // Verify the hash.
248 // boolean verifies = sig.verify(sigToVerify);
249 //
250 // return verifies;
251 // } catch(Exception ioe)
252 // {
253 // assert debugException(CLASS_NAME, "execute", ioe);
254 // if(inputStreamOpen)
255 // {
256 // try
257 // {
258 // inFile.close();
259 // } catch(Exception fe)
260 // {
261 // assert debugException(CLASS_NAME, "execute", fe);
262 // // Cannot do much. Ignore.
263 // }
264 // }
265 // return false;
266 // }
267 }
268
269
270
271 /**
272 * Prints a representation of the contents of the provided byte array to
273 * standard output.
274 *
275 * @param bArray The array containing the data to be printed.
276 */
277 private void printBytes(byte[] bArray)
278 {
279 for(int i = 0; i < bArray.length; i++)
280 {
281 System.out.print(Integer.toHexString((int)bArray[i]));
282 }
283 System.out.println("");
284 }
285
286
287 }
288