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