8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of the Common Development and Distribution License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the License). You may not use this file except in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the License at
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * opensso/legal/CDDLv1.0.txt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at opensso/legal/CDDLv1.0.txt.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below the CDDL Header,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the fields enclosed by brackets [] replaced by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * your own identifying information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * $Id: LogSign.java,v 1.4 2008/06/25 05:43:38 qcheng Exp $
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Portions Copyrighted [2011] [ForgeRock AS]
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpackage com.sun.identity.log.secure;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Arrays;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Vector;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.logging.Handler;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.log.LogConstants;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.log.Logger;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.log.spi.Debug;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This class is logging signature that generates with the MAC value for each
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * log entry.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpublic class LogSign {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private String name;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private Logger logger;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Constructor
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param log A string representing the name of the logger.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public LogSign(String log) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster name = log;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Reads the header from the log file and interprets its contents.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * It finds out the position of the Signature and MAC fields.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param recordListHeader A string array that contains the header
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * entries as strings.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void readHeader(String[] recordListHeader){
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Vector header = new Vector(recordListHeader.length);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Extracting the field names as header from the first line of the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // returned string array.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster header.addAll(Arrays.asList(recordListHeader));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* Getting the position of the Signature field in the array.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This is required to check if the record is a signature or a
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * normal logrecord. If it is a signature then the signature
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * has to be verified, else the MAC on that line has to be
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * verified.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String signFieldName = LogConstants.SIGNATURE_FIELDNAME;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for(int j = 0; j < header.size(); j++){
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if((((String)header.get(j))).equalsIgnoreCase(signFieldName)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The actual sign method that creates the signature by taking the last
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * generated MAC and the last Signature in the log file and then using that
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to create the next signature that is to be written to the file.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return A String repersentation of the actual byte array signature.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @throws Exception if it fails to sign the mac value
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public synchronized String sign()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws Exception {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Get instance of the Logger for which the signing operation is
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to be done.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster logger = (com.sun.identity.log.Logger)Logger.getLogger(name);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Handler[] handlers = logger.getHandlers();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SecureLogHelper helper =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ((com.sun.identity.log.handlers.SecureFileHandler)handlers[0]).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster getSecureLogHelper();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the lastMAC and the last Signature from the secure store.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // There is a problem since the getLastMAC function returns the MAC
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // of the record prior to the last record.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster byte[] prevMAC = new byte[1];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster prevMAC = helper.getLastMAC();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if(prevMAC == null){
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (Debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Debug.warning(name+"Prev MAC = null");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (Debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Debug.message(name+"prevMAC = " + helper.toHexString(prevMAC));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster byte[] newMAC;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster byte [] prevSign = helper.getLastSignatureBytes();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if((prevSign == null) || (prevSign.length == 0) ) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster newMAC = new byte[prevMAC.length];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster System.arraycopy(prevMAC, 0, newMAC, 0, prevMAC.length);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster newMAC = new byte[prevMAC.length + prevSign.length];
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster System.arraycopy(prevMAC, 0, newMAC, 0, prevMAC.length);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster System.arraycopy(prevSign, 0, newMAC, prevMAC.length,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster prevSign.length);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Sign the newly generated MAC
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster byte[] curSign = helper.signMAC(newMAC);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String sign = helper.toHexString(curSign);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return sign;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}