Clover Coverage Report
Coverage timestamp: Sun Mar 23 2008 08:24:39 GMT
525   1,414   124   10.94
148   840   0.33   48
48     3.56  
1    
 
 
  LogFileReader       Line # 83 525 124 48.4% 0.48404992
 
No Tests
 
1    /*
2    * Copyright (c) 2006, University of Kent
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    *
8    * Redistributions of source code must retain the above copyright notice, this
9    * list of conditions and the following disclaimer.
10    *
11    * Redistributions in binary form must reproduce the above copyright notice,
12    * this list of conditions and the following disclaimer in the documentation
13    * and/or other materials provided with the distribution.
14    *
15    * 1. Neither the name of the University of Kent nor the names of its
16    * contributors may be used to endorse or promote products derived from this
17    * software without specific prior written permission.
18    *
19    * 2. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20    * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21    * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22    * PURPOSE ARE DISCLAIMED.
23    *
24    * 3. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31    * POSSIBILITY OF SUCH DAMAGE.
32    *
33    * 4. YOU AGREE THAT THE EXCLUSIONS IN PARAGRAPHS 2 AND 3 ABOVE ARE REASONABLE
34    * IN THE CIRCUMSTANCES. IN PARTICULAR, YOU ACKNOWLEDGE (1) THAT THIS
35    * SOFTWARE HAS BEEN MADE AVAILABLE TO YOU FREE OF CHARGE, (2) THAT THIS
36    * SOFTWARE IS NOT "PRODUCT" QUALITY, BUT HAS BEEN PRODUCED BY A RESEARCH
37    * GROUP WHO DESIRE TO MAKE THIS SOFTWARE FREELY AVAILABLE TO PEOPLE WHO WISH
38    * TO USE IT, AND (3) THAT BECAUSE THIS SOFTWARE IS NOT OF "PRODUCT" QUALITY
39    * IT IS INEVITABLE THAT THERE WILL BE BUGS AND ERRORS, AND POSSIBLY MORE
40    * SERIOUS FAULTS, IN THIS SOFTWARE.
41    *
42    * 5. This license is governed, except to the extent that local laws
43    * necessarily apply, by the laws of England and Wales.
44    */
45   
46    package issrg.SAWS;
47   
48    import iaik.asn1.*;
49    import iaik.asn1.structures.AlgorithmID;
50    import iaik.utils.Util;
51   
52    import issrg.SAWS.callback.SAWSGUICallbackHandler;
53    import issrg.SAWS.util.SAWSLogWriter;
54   
55    import java.io.*;
56    import java.util.*;
57    import java.lang.*;
58    import java.math.*;
59   
60    import org.w3c.dom.*;
61    import org.xml.sax.*;
62    import javax.xml.parsers.*;
63    import org.apache.soap.util.xml.*;
64   
65    import java.security.*;
66    import javax.crypto.*;
67    import javax.crypto.spec.*;
68    import java.security.AlgorithmParameters;
69    import java.security.interfaces.*;
70   
71    import javax.security.auth.callback.Callback;
72    import javax.security.auth.callback.CallbackHandler;
73   
74    import issrg.SAWS.callback.SAWSTextOutputCallback;
75   
76    /**
77    * This is the log file reading class
78    *
79    * @author W. Xu
80    * @version 0.1, Oct. 2005
81    */
82   
 
83    public class LogFileReader
84    {
85   
86    private SecretKey sawsSecretKeyFromLog = null;
87    private PrivateKey userPrivateKey = null;
88    private PrivateKey sawsPrivateKey = null;
89    private boolean logEndFlag = false;
90   
91    private boolean accumulatedRecordMetFlag = false; // added
92   
93    private int currentSNCheck=0;
94    private String errorMsg = null;
95    private byte[] accumulatedHashFromLog = null;
96    private byte[] signatureFromLog = null;
97    private byte[] secureRandomBytes = null;
98    private java.security.cert.Certificate certFromLog = null;
99   
100    // for verifying the log file
101    private byte[] accumulatedHashByCalc = null;
102    private java.security.MessageDigest accMD = null;
103    private File CurrentLogFile = null;
104    private String logFileRoot = null;
105    private String logFileNameForLastLog = null;
106    private byte[] accumulatedHashForLastLog = null;
107    private byte [] signatureForLastLog = null;
108    Vector recordBlockList = new Vector();
109    private StringBuffer allReadingResult = new StringBuffer();
110   
111    private byte[] accumulatedHashForLogHeader = null; //accumulated hash for the log file header generated by calculation
112    private byte[] headerSignature = null; //the signature of the log file's header
113   
114    private int debugLevel = 0;
115    private byte userID;
116   
117    private CallbackHandler callbackHandler = new SAWSGUICallbackHandler();
118   
119    //adding log4j logging
120   
121    /**
122    * @aggregation composite
123    */
124    private static SAWSLogWriter sawsDebugLog = new SAWSLogWriter(LogFileReader.class.getName());
125    private byte accHashAlgorithmID = -1;
126    String hashAlgorithmName = null;
127   
 
128  28 toggle public Vector getRecordBlockList(){
129  28 return recordBlockList;
130    }
131   
 
132  0 toggle public String getAllCheckingResult(){
133  0 return allReadingResult.toString();
134    }
135   
 
136  28 toggle public String getPreviousLogfileName(){
137  28 return logFileNameForLastLog;
138    }
139   
140    /**
141    * This method is the constructor of LogFileReader.
142    *
143    */
 
144  0 toggle public LogFileReader(int debugLevel) {
145  0 this.debugLevel = debugLevel;
146    }
147   
 
148  0 toggle public LogFileReader(int debugLevel, byte userID){
149  0 this.debugLevel = debugLevel;
150  0 this.userID = userID;
151    }
152   
 
153  28 toggle public LogFileReader(int debugLevel, CallbackHandler ch) {
154  28 this.debugLevel = debugLevel;
155  28 this.callbackHandler = ch;
156    }
157   
 
158  0 toggle public LogFileReader(int debugLevel, byte userID, CallbackHandler ch) {
159  0 this.debugLevel = debugLevel;
160  0 this.userID = userID;
161  0 this.callbackHandler = ch;
162    }
163   
164    /**
165    * Method that sets the callback handler for the class. If the handler
166    * is null, the class will keep using the default callback handler.
167    *
168    * @param ch The callback handler.
169    */
 
170  0 toggle public void setCallbackHandler(CallbackHandler ch) {
171  0 if (ch != null) {
172  0 this.callbackHandler = ch;
173    }
174    }
175   
176    /**
177    * This method is to initialise the MessageDigest for accumulated hash computation.
178    *
179    * @param null
180    *
181    * @return null.
182    */
 
183  28 toggle public void setLogFilename(String logRoot, String logFilename) throws logReadingException {
184  28 if (debugLevel > SAWSConstant.NoInfo) {
185    //System.err.println("\nIn initAccMD in LogFileReader: The log root is " + logRoot + "; the log Filename is " + logFilename);
186    //adding log4j logging
187  0 sawsDebugLog.write("\nIn initAccMD in LogFileReader: The log root is " + logRoot + "; the log Filename is " + logFilename);
188    }
189  28 logFileRoot = logRoot;
190  28 CurrentLogFile = new File(logRoot, logFilename);
191  28 if (debugLevel > SAWSConstant.NoInfo) {
192    //System.err.println("\nIn initAccMD in LogFileReader: The whole log name is " +
193    // "" + logRoot+logFilename);
194    //adding log4j logging
195  0 sawsDebugLog.write("\nIn initAccMD in LogFileReader: The whole log name is " +
196    "" + logRoot+logFilename);
197    }
198  28 logEndFlag = false; //init
199  28 accumulatedRecordMetFlag = false;
200   
201   
202  28 this.accHashAlgorithmID = this.getAccumulatedHashAlgorithm(this.CurrentLogFile);
203  28 if ((this.accHashAlgorithmID >= 0) && (this.accHashAlgorithmID < SAWSConstant.HASH_ALG_NAMES.length)) {
204  28 this.hashAlgorithmName = SAWSConstant.HASH_ALG_NAMES[this.accHashAlgorithmID];
205    } else {
206  0 this.showMessage("Hash Algorithm not supported. SAWS will stop.",
207    SAWSTextOutputCallback.ERROR);
208    //System.err.println("Hash Algorithm not supported. SAWS will stop.");
209  0 if (debugLevel > SAWSConstant.NoInfo) {
210  0 sawsDebugLog.write("Hash Algorithm not supported. Algorithm ID: " + this.accHashAlgorithmID);
211    }
212  0 System.exit(-1);
213    }
214   
215  28 try{
216  28 accMD = java.security.MessageDigest.getInstance(this.hashAlgorithmName);
217    } catch (Exception e) {
218  0 this.showMessage("Accumulated hash error. SAWS will stop.",
219    SAWSTextOutputCallback.ERROR);
220    //System.err.println("Accumulated hash error. SAWS will stop.");
221  0 if (debugLevel > SAWSConstant.NoInfo) {
222    //e.printStackTrace(System.err);
223    //adding log4j logging
224  0 sawsDebugLog.write(e.toString());
225    }
226  0 System.exit(-1);
227    }
228  28 accMD.update(logFilename.getBytes());
229    }
230   
231   
232    /**
233    * This method is to reset the MessageDigest for accumulated hash computation.
234    *
235    */
 
236  0 toggle public void resetAccMD() {
237  0 try{
238  0 accMD.reset();
239    } catch (Exception e) {
240  0 this.showMessage("Accumulated hash reset error. SAWS will stop.",
241    SAWSTextOutputCallback.ERROR);
242    //System.err.println("Accumulated hash reset error. SAWS will stop.");
243  0 if (debugLevel > SAWSConstant.NoInfo)
244    //e.printStackTrace(System.err);
245    //adding log4j logging
246  0 sawsDebugLog.write(e.toString() + "\nAccumulated hash reset error.");
247  0 System.exit(-1);
248    }
249  0 logEndFlag = false;
250  0 accumulatedRecordMetFlag = false;
251    }
252   
253    /**
254    * This method is to asymmetric-decrypt a Record block
255    *
256    * @param body is the log record block
257    * @param privateKey is the private key
258    *
259    * @return decrypted byte []
260    */
 
261  56 toggle public byte[] ADecryptRecordBodyByPrivateKey (byte[] body, PrivateKey privateKey) throws logReadingException {
262  56 byte[] decipherText = null;
263  56 try{
264  56 javax.crypto.Cipher c1 = javax.crypto.Cipher.getInstance(privateKey.getAlgorithm()); //RSA DSA
265  56 c1.init(Cipher.DECRYPT_MODE, privateKey);
266   
267  56 decipherText = c1.doFinal(body);
268    }
269    catch (Exception e){
270  0 if ( debugLevel > SAWSConstant.VerboseInfo)
271    //e.printStackTrace(System.err);
272    //adding log4j logging
273  0 sawsDebugLog.write(e.toString());
274  0 throw new logReadingException(SAWSConstant.ADecryptErrCode);
275    }
276  56 return(decipherText);
277    }
278   
279    /**
280    * This method is to symmetric-decrypt a Record block: log message .
281    * sawsSecretKeyFromLog is used within this method.
282    *
283    * @param body is the encrypted log record block with the symmetric key
284    *
285    * @return decrypted byte []
286    */
 
287  160 toggle public byte[] SDecryptRecordBody(byte[] body)
288    {
289  160 byte[] decipherText = null;
290  160 try{
291  160 Cipher cipher = Cipher.getInstance("AES");
292  160 cipher.init(Cipher.DECRYPT_MODE, sawsSecretKeyFromLog);
293  160 decipherText = cipher.doFinal(body);
294    } catch (Exception e) {
295  0 this.showMessage("Accumulated hash error. SAWS will stop.",
296    SAWSTextOutputCallback.ERROR);
297    //System.err.println("Accumulated hash error. SAWS will stop.");
298  0 if (debugLevel > SAWSConstant.NoInfo)
299    //e.printStackTrace(System.err);
300    //adding log4j logging
301  0 sawsDebugLog.write(e + "\nAccumulated hash error.");
302  0 System.exit(-1);
303    }
304  160 return(decipherText);
305    }
306   
307    /**
308    * This method is to read a Record block (only body): log message .
309    *
310    * @param raf is the random access file to be read
311    * @param offset is offset
312    * @param len is the length to be read
313    *
314    * @return bytes of the record body.
315    */
 
316  596 toggle public byte[] readRecordBodyFromRAF(RandomAccessFile raf, int offset, int len) throws logReadingException
317    {
318  596 byte [] thisRecord = new byte[len];
319   
320  596 try{
321  596 long pos = raf.getFilePointer();
322  596 raf.seek( pos + offset);
323  596 int lenRead = raf.read(thisRecord,0,len); //Read in the record in the encrypted format
324  596 if (lenRead < len) { // reading error, log format wrong
325  0 throw new logReadingException(pos, currentSNCheck, accMD, accumulatedHashByCalc,
326    SAWSConstant.LogFileBodyReadingErrCode); // could not recover
327    }
328   
329    } catch (Exception e) {
330  0 this.showMessage("Reading record body error. SAWS will stop.",
331    SAWSTextOutputCallback.ERROR);
332    //System.err.println("Reading record body error. SAWS will stop.");
333  0 if (debugLevel > SAWSConstant.NoInfo)
334    //e.printStackTrace(System.err);
335    //adding log4j logging
336  0 sawsDebugLog.write(e + "\nReading record body error.");
337  0 System.exit(-1);
338    }
339   
340  596 return (thisRecord);
341    }
342   
343    /**
344    * This method is to move the RAF pointer by a distance of len
345    *
346    * @param raf is the RAF file
347    * @param offset is the offset
348    *
349    * @return null
350    */
 
351  28 toggle public void shiftRAFPointer(RandomAccessFile raf, int offset)
352    {
353  28 try{
354  28 raf.seek(raf.getFilePointer()+offset);
355    } catch (Exception e) {
356  0 this.showMessage("Shifting log file pointer error. SAWS will stop.",
357    SAWSTextOutputCallback.ERROR);
358    //System.err.println("Shifting log file pointer error. SAWS will stop.");
359  0 if (debugLevel > SAWSConstant.NoInfo)
360    //e.printStackTrace(System.err);
361    //adding log4j logging
362  0 sawsDebugLog.write(e + "\nShifting log file pointer error.");
363  0 System.exit(-1);
364    }
365  28 return;
366    }
367   
368   
369    /**
370    * This method is to read a Record Hash: 20 bytes
371    *
372    * @param raf is the random access file
373    *
374    * @return bytes of the record hash (20 bytes).
375    */
 
376  540 toggle public byte[] readRecordHashFromRAF(RandomAccessFile raf) throws logReadingException
377    {
378  540 byte [] thisHash = null;
379  540 int hashLength = SAWSConstant.HashLength[this.accHashAlgorithmID];
380   
381  540 try{
382  540 long pos = raf.getFilePointer();
383  540 thisHash= new byte[hashLength];
384  540 int length = raf.read(thisHash,0,hashLength); //Read in the record in the encrypted format
385  540 if (length < hashLength) {
386  0 throw new logReadingException(pos, currentSNCheck, accMD, accumulatedHashByCalc,
387    SAWSConstant.LogFileHashReadingErrCode); // could not recover
388    }
389   
390    } catch (Exception e) {
391  0 this.showMessage("Reading log record hash error. SAWS will stop.",
392    SAWSTextOutputCallback.ERROR);
393    //System.err.println("Reading log record hash error. SAWS will stop.");
394  0 if (debugLevel > SAWSConstant.NoInfo)
395    //e.printStackTrace(System.err);
396    //adding log4j logging
397  0 sawsDebugLog.write(e + "\nReading log record hash error.");
398  0 System.exit(-1);
399    }
400  540 return (thisHash);
401    }
402   
403   
404    /**
405    * This method is to get SN from a Record header.
406    *
407    * @param recordHeader record header
408    *
409    * @return byte SN of the record header.
410    */
 
411  540 toggle public int getSNFromRecordHeader(byte[] recordHeader)
412    {
413  540 byte [] snBytes = new byte[4];
414  540 System.arraycopy(recordHeader,4,snBytes,0,4);
415  540 return (utility.byteArrayToInt(snBytes) );
416    }
417   
418    /**
419    * This method is to get record type from a Record header.
420    *
421    * @param recordHeader record header
422    *
423    * @return byte of the record type.
424    */
 
425  624 toggle public byte getRecordTypeFromRecordHeader(byte[] recordHeader)
426    {
427  624 return recordHeader[8] ;
428    }
429   
430    /*
431    * This method is to get hash algorithm ID from a Record header.
432    *
433    * @param recordHeader record header
434    *
435    * @return byte of the hash algorithm identification.
436   
437    public byte getHashAlgorithmFromRecordHeader(byte[] recordHeader)
438    {
439    return recordHeader[27] ;
440    }
441    */
442    /**
443    * This method is to get the user ID from a Record header.
444    *
445    * @param recordHeader record header
446    *
447    * @return byte of the user id.
448    */
 
449  300 toggle public byte getUserIDFromRecordHeader(byte[] recordHeader)
450    {
451  300 return recordHeader[9] ;
452    }
453   
454    /**
455    * This method is to get encryption flag from a Record header.
456    *
457    * @param recordHeader record header
458    *
459    * @return byte of the encryption flag
460    */
 
461  1024 toggle public byte getEncryptionFlagFromRecordHeader(byte[] recordHeader)
462    {
463  1024 return recordHeader[10];
464    }
465   
466    /**
467    * This method is to get timestamp from a Record header.
468    *
469    * @param recordHeader record header
470    *
471    * @return bytes of the timestamp (8 bytes)
472    */
 
473  540 toggle public long getTimestampFromRecordHeader(byte[] recordHeader)
474    {
475  540 byte [] tsBytes = new byte[8];
476  540 System.arraycopy(recordHeader,11,tsBytes,0,8);
477  540 return (utility.byteArrayToLong(tsBytes) );
478    }
479   
480    /**
481    * This method is to get LastRecordLength from a Record header.
482    *
483    * @param recordHeader record header
484    *
485    * @return length of the LastRecordLength
486    */
 
487  540 toggle public int getLastRecordLengthFromRecordHeader(byte[] recordHeader)
488    {
489  540 byte [] tsBytes = new byte[4];
490  540 System.arraycopy(recordHeader,19,tsBytes,0,4);
491  540 return (utility.byteArrayToInt(tsBytes) );
492    }
493   
494    /**
495    * This method is to get this record length from a Record header.
496    *
497    * @param recordHeader record header
498    *
499    * @return length of this record
500    */
 
501  624 toggle public int getThisRecordLengthFromRecordHeader(byte[] recordHeader)
502    {
503  624 byte [] tsBytes = new byte[4];
504  624 System.arraycopy(recordHeader,23,tsBytes,0,4);
505  624 return (utility.byteArrayToInt(tsBytes) );
506    }
507   
508    /**
509    * This method is to read one complete log record from a RAF. This is used by SAWS VT who does not
510    * have the secure random number.
511    *
512    * @param raf1 is the RAF file
513    *
514    * @return String result. Return null if end of file is reached.
515    */
 
516  0 toggle public String readOneRecordFromRAF(RandomAccessFile raf1) throws logReadingException{
517  0 return readOneRecordFromRAF(raf1, null);
518   
519    }
520   
521    /**
522    * This method is to read one complete log record from a RAF.
523    *
524    * @param raf1 is the RAF file
525    * @param secureRandomBytes is the secure number used for secure hash
526    *
527    * @return String result. Return null if end of file is reached.
528    */
 
529  540 toggle public String readOneRecordFromRAF(RandomAccessFile raf1, byte[] secureRandomBytes) throws logReadingException {
530  540 java.security.MessageDigest md = null;
531   
532  540 try{
533  540 md = java.security.MessageDigest.getInstance(this.hashAlgorithmName);
534    } catch (Exception e) {
535  0 this.showMessage("Message Digest error. SAWS will stop.",
536    SAWSTextOutputCallback.ERROR);
537    //System.err.println("Message Digest error. SAWS will stop.");
538  0 if (debugLevel > SAWSConstant.NoInfo)
539    //e.printStackTrace(System.err);
540    //adding log4j logging
541  0 sawsDebugLog.write(e.toString());
542  0 System.exit(-1);
543    }
544   
545  540 byte[] h1 = readRecordHeaderFromRAF(raf1);
546  0 if (h1 == null) return null;
547   
548  540 int thisRecordLength = getThisRecordLengthFromRecordHeader(h1);
549  540 StringBuffer temp = new StringBuffer();
550   
551  540 currentSNCheck = getSNFromRecordHeader(h1);
552  540 temp.append ("\nSN: " + currentSNCheck);
553  540 byte recordType = (byte)getRecordTypeFromRecordHeader(h1);
554   
555  540 temp.append("\ngetRecordTypeFromRecordHeader: " +
556    SAWSConstant.getRecordTypeString( recordType ) );
557  540 temp.append("\ngetEncryptionFlag: " +
558    getEncryptionTypeString( getEncryptionFlagFromRecordHeader(h1)) );
559  540 temp.append("\ngetTimestamp: " + (new Date(getTimestampFromRecordHeader(h1))).toString() );
560  540 temp.append("\ngetLastRecordLength: " + getLastRecordLengthFromRecordHeader(h1));
561  540 temp.append("\ngetThisRecordLength: " + thisRecordLength );
562   
563  540 byte[] body = null;
564  540 byte[] hash1 = null;
565   
566    //if (recordType != SAWSConstant.SAWSHashAlgorithmType) {
567  540 body = readRecordBodyFromRAF(raf1, 0,thisRecordLength
568    -SAWSConstant.HashLength[this.accHashAlgorithmID]-SAWSConstant.HeaderLength);
569  540 hash1 = readRecordHashFromRAF(raf1);
570    /*} else {
571    body = readRecordBodyFromRAF(raf1, 0,thisRecordLength - SAWSConstant.HeaderLength);
572    }*/
573   
574  540 byte[] decryptedBody = null;
575  540 byte[] newAccumulatedHashByCalc = null;
576   
577  540 if ( recordType == SAWSConstant.SAWSAccumulatedHashType ) {
578  28 accumulatedRecordMetFlag = true;
579  28 accumulatedHashFromLog = body;
580  512 } else if (recordType == SAWSConstant.SAWSLogFileSignatureType) {
581  28 signatureFromLog = body;
582  28 if ( accumulatedRecordMetFlag )
583  28 logEndFlag = true;
584    } else {
585   
586  484 if (recordType == SAWSConstant.SAWSCertificateType ) {
587  28 ByteArrayInputStream bais = new ByteArrayInputStream(body);
588  28 java.security.cert.CertificateFactory cf = null;
589   
590  28 try {
591  28 cf = java.security.cert.CertificateFactory.getInstance("X.509");
592  28 certFromLog = cf.generateCertificate(bais); // get saws cert key back from log
593    } catch (Exception e3){
594  0 e3.printStackTrace(System.err);
595    }
596    }
597   
598  484 if ( (sawsSecretKeyFromLog == null )
599    && (recordType == SAWSConstant.SymmetricEncryptionKeyType)
600    && (getUserIDFromRecordHeader(h1) != SAWSConstant.USERSAWS )
601    && (userPrivateKey != null) ) {
602  0 byte[] rawKey1 = ADecryptRecordBodyByPrivateKey(body, userPrivateKey);
603  0 if (rawKey1 != null) {
604  0 sawsSecretKeyFromLog = new SecretKeySpec(rawKey1, "AES");
605    }
606  0 logFileNameForLastLog = null;
607    }
608   
609  484 if ((recordType == SAWSConstant.SymmetricEncryptionKeyType)
610    && (getUserIDFromRecordHeader(h1) == SAWSConstant.USERSAWS ) && (sawsPrivateKey != null) ) {
611  28 byte[] rawKey1 = ADecryptRecordBodyByPrivateKey(body, sawsPrivateKey);
612  28 sawsSecretKeyFromLog = new SecretKeySpec(rawKey1, "AES");
613  28 logFileNameForLastLog = null;
614    }
615   
616  484 byte [] clearMessageBlock = null;
617   
618  484 if (getEncryptionFlagFromRecordHeader(h1) == SAWSConstant.SymmetricEncryptionFlag) {
619  160 clearMessageBlock = SDecryptRecordBody( body );
620    } else {
621  324 clearMessageBlock = body;
622    }
623   
624  484 if (recordType == SAWSConstant.SAWSLastFileType ) {
625  28 extractLastLogInfo(clearMessageBlock);
626    }
627   
628  484 if ( recordType == SAWSConstant.SAWSClientLogDataType) {
629  160 temp.append("\n" + new String(clearMessageBlock) );
630  160 RecordBlock rb = new RecordBlock(clearMessageBlock, getUserIDFromRecordHeader(h1) );
631  160 recordBlockList.addElement(rb);
632    } // ***********************************************************
633   
634  484 if (recordType == SAWSConstant.SysAuditorNotificationType ) {
635  0 temp.append("\n" + new String(clearMessageBlock) );
636    }
637   
638  484 int thisRecordLength2 = 0;
639  484 byte[] thisLogRecord2 = null;
640   
641  484 if (recordType == SAWSConstant.SAWSHashAlgorithmType) {
642  28 temp.append("\ngetHashAlgorithm: " + this.hashAlgorithmName );
643    }
644    /*
645    thisRecordLength2 = h1.length + body.length;
646    thisLogRecord2 = new byte[thisRecordLength2];
647   
648    System.arraycopy(h1, 0, thisLogRecord2, 0, h1.length);
649    System.arraycopy(body, 0, thisLogRecord2, h1.length, body.length);
650   
651    } else {*/
652  484 thisRecordLength2 = h1.length + body.length + hash1.length;
653  484 thisLogRecord2 = new byte[thisRecordLength2];
654   
655  484 System.arraycopy(h1, 0, thisLogRecord2, 0, h1.length); //
656  484 System.arraycopy(body, 0, thisLogRecord2, h1.length, body.length); //
657  484 System.arraycopy(hash1, 0, thisLogRecord2, h1.length + body.length, hash1.length);
658    //}
659   
660  484 if ( !accumulatedRecordMetFlag) {
661  484 accMD.update(thisLogRecord2);
662  484 try{
663  484 java.security.MessageDigest tc1 =(java.security.MessageDigest) accMD.clone();
664  484 accumulatedHashByCalc = tc1.digest();
665    } catch(Exception e4) {
666  0 this.showMessage("Accumulated hash error. SAWS will stop.",
667    SAWSTextOutputCallback.ERROR);
668    //System.err.println("Accumulated hash error. SAWS will stop.");
669  0 if (debugLevel > SAWSConstant.NoInfo) {
670    //e4.printStackTrace(System.err);
671    //adding log4j logging
672  0 sawsDebugLog.write(e4.toString());
673    }
674  0 System.exit(-1);
675    }
676   
677  484 if (recordType == SAWSConstant.SAWSHeaderSignatureType) {
678  28 this.accumulatedHashForLogHeader = this.accumulatedHashByCalc;
679  28 this.headerSignature = body;
680    }
681    }
682    }
683   
684   
685  540 temp.append("\nrecord length: " + thisRecordLength );
686   
687  540 if (/*(recordType != SAWSConstant.SAWSHashAlgorithmType) && */(secureRandomBytes != null)){
688  540 md.reset();
689  540 md.update(h1);
690  540 md.update(body);
691  540 md.update(secureRandomBytes);
692  540 byte[] digest = md.digest();
693   
694  540 String s1 = new sun.misc.BASE64Encoder().encode(digest);
695  540 String s2 = new sun.misc.BASE64Encoder().encode(hash1);
696  540 if (s1.compareTo(s2) == 0) {
697  540 temp.append("\nThe secure hash of this log record is verified");
698    } else {
699  0 throw new logReadingException(SAWSConstant.SecureHashNotCorrect, currentSNCheck); // could not recover
700    }
701    }
702   
703  540 try {
704  540 if (raf1.getFilePointer() < raf1.length()-1 ) {
705  512 return temp.toString(); // end of file is not reached.
706    } else {
707  28 return null; //end of file is reached.
708    }
709   
710    } catch (Exception e) {
711  0 this.showMessage("Log file get file pointer error. SAWS will stop.",
712    SAWSTextOutputCallback.ERROR);
713    //System.err.println("Log file get file pointer error. SAWS will stop.");
714  0 if (debugLevel > SAWSConstant.NoInfo)
715    //e.printStackTrace(System.err);
716    //adding log4j logging
717  0 sawsDebugLog.write(e.toString());
718  0 System.exit(-1);
719    }
720  0 return temp.toString() ;
721    }
722   
723   
724    /**
725    * This method is to read a Record header from a random access file.
726    *
727    * @param raf1 is the RAF file
728    *
729    * @return bytes of the record header.
730    */
 
731  624 toggle public byte[] readRecordHeaderFromRAF (RandomAccessFile raf1) throws logReadingException {
732  624 long currentPos = 0, length;
733  624 byte [] thisRecordHeader = null;
734  624 boolean flag = false;
735   
736  624 try{
737  624 currentPos = raf1.getFilePointer();
738  624 length = raf1.length();
739   
740  624 thisRecordHeader= new byte[SAWSConstant.HeaderLength];
741  624 int length1 = raf1.read(thisRecordHeader,0,SAWSConstant.HeaderLength); //Read in the record header
742  624 if ( (length1 == -1) || ( length1 == 0 ) ){ // log incomplete error
743  0 throw new logReadingException(currentPos, currentSNCheck, accMD, accumulatedHashByCalc,
744    SAWSConstant.LogFileIncompleteErrCode); // could recover
745    }
746  624 if ((length1 < SAWSConstant.HeaderLength) ) {
747  0 throw new logReadingException(currentPos, currentSNCheck, accMD, accumulatedHashByCalc,
748    SAWSConstant.LogFileFormatErrCode); // can't recover
749    }
750    } catch (IOException e4) {
751  0 try{
752  0 raf1.close();
753    } catch(Exception e2){
754  0 e2.printStackTrace(System.err);
755    }
756  0 throw new logReadingException(currentPos, currentSNCheck, accMD, accumulatedHashByCalc,
757    SAWSConstant.LogFileReadingErrCode); // can't recover
758    }
759  624 return (thisRecordHeader);
760    }
761   
762   
763    /**
764    * This method is to set VT private key.
765    *
766    * @param pk is the VT private key
767    */
 
768  0 toggle public void setUserPrivateKey(PrivateKey pk){
769  0 userPrivateKey = pk;
770    }
771   
772    /**
773    * This method is to set saws private key.
774    *
775    * @param pk is the saws private key
776    */
 
777  28 toggle public void setSAWSPrivateKey(PrivateKey pk){
778  28 sawsPrivateKey = pk;
779    }
780   
781    /**
782    * This method is to extract LastLogRecord information
783    *
784    * @param body is the LastLogRecord body
785    */
 
786  28 toggle private void extractLastLogInfo(byte[] body ){
787  28 byte[] baLen = new byte[4];
788  28 byte [] temp = null;
789   
790  28 System.arraycopy(body, 0, baLen, 0, 4);
791  28 int iLen1 = utility.byteArrayToInt(baLen);
792  28 temp = new byte[iLen1];
793  28 System.arraycopy(body, 4, temp, 0, iLen1 );
794  28 logFileNameForLastLog = new String(temp);
795   
796  28 System.arraycopy(body, 4 + iLen1, baLen, 0, 4);
797  28 int iLen2 = utility.byteArrayToInt(baLen);
798  28 temp = new byte[iLen2];
799  28 System.arraycopy(body, 4 + iLen1 + 4, temp, 0, iLen2 );
800  28 accumulatedHashForLastLog = temp;
801   
802  28 System.arraycopy(body, 4 + iLen1 + 4 + iLen2, baLen, 0, 4);
803  28 int iLen3 = utility.byteArrayToInt(baLen);
804  28 temp = new byte[iLen3];
805  28 System.arraycopy(body, 4 + iLen1 + 4 + iLen2 + 4, temp, 0, iLen3 );
806  28 signatureForLastLog = temp;
807   
808  28 String s1 = new String(accumulatedHashForLastLog);
809  28 if (s1.compareTo("null") == 0){
810  6 logFileNameForLastLog = null;
811  6 if (debugLevel > 0)
812    //System.err.println("This is the very first log file. There is no more previous log file existing. ");
813    //adding log4j logging
814  0 sawsDebugLog.write("This is the very first log file. There is no more previous log file existing. ");
815    } else
816  22 if (debugLevel > 0)
817    //System.err.println("Last log file name stored in this log is: " + logFileNameForLastLog);
818    //adding log4j logging
819  0 sawsDebugLog.write("Last log file name stored in this log is: " + logFileNameForLastLog);
820   
821   
822    }
823   
824    /**
825    * This method is to return accumulated hash got by calculation during verification.
826    *
827    */
 
828  56 toggle public byte[] getAccumulatedHashByCalc(){
829  56 return accumulatedHashByCalc ;
830    }
831   
832    /**
833    * This method is to return accumulated hash stored in the log file
834    *
835    */
 
836  56 toggle public byte[] getAccumulatedHashFromLog(){
837  56 return accumulatedHashFromLog;
838    }
839   
840    /**
841    * This method is to return signature from the log file
842    *
843    */
 
844  56 toggle public byte[] getSignatureFromLog(){
845  56 return signatureFromLog;
846    }
847   
848    /**
849    * This method is to return the certificate in the log file
850    *
851    */
 
852  28 toggle public java.security.cert.Certificate getCertFromLog(){
853  28 return certFromLog;
854    }
855   
856    /**
857    * Method to check if the signature of the log file's header is valid.
858    *
859    * @return 0, if the signature if valid or -1, if not.
860    */
 
861  0 toggle private int checkHeaderSignature() throws logReadingException {
862  0 int result = -1;
863   
864    // the public key extracted from the certificate cert1 is used to verify the signature
865  0 String signingAlgName = this.certFromLog.getPublicKey().getAlgorithm();
866   
867  0 try{
868  0 Signature sig = Signature.getInstance(signingAlgName);
869  0 sig.initVerify(this.certFromLog.getPublicKey());
870  0 sig.update(this.accumulatedHashForLogHeader);
871  0 boolean vr = sig.verify(this.headerSignature);
872   
873  0 if (vr) {
874  0 allReadingResult.append("\nThe Log's Header signature is valid.");
875  0 result = 0;
876    }
877  0 if (debugLevel > SAWSConstant.NoInfo)
878  0 sawsDebugLog.write("\nSignature of the log's header is " + vr);
879    } catch (Exception e4){
880  0 throw new logReadingException( SAWSConstant.HeaderSignatureIsNotValid); // can't recover
881    }
882   
883  0 return result;
884    }
885   
886    /**
887    * This method is to verify the signature of the log file
888    *
889    * @param sawsCAPublicKey is the saws public key.
890    *
891    */
 
892  28 toggle public int checkSignature(PublicKey sawsCAPublicKey) throws logReadingException {
893  28 int result = 0;
894  28 if (logEndFlag) {
895  28 String accCalc = new sun.misc.BASE64Encoder().encode(getAccumulatedHashByCalc());
896  28 String accLog = new sun.misc.BASE64Encoder().encode(getAccumulatedHashFromLog());
897  28 if (accCalc.compareTo(accLog)==0) {
898  28 allReadingResult.append("\nThe accumulated hash by calculation is the same as the accumulated hash stored in the log file.");
899  28 if (debugLevel > SAWSConstant.NoInfo)
900    //System.err.println("The accumulated hash by calc is the same as the accumulated hash in log." );
901    //adding log4j logging
902  0 sawsDebugLog.write("The accumulated hash by calc is the same as the accumulated hash in log.");
903    }
904    else{
905  0 int isValid = this.checkHeaderSignature();
906  0 if (isValid == 0) {
907  0 if (debugLevel > SAWSConstant.NoInfo)
908  0 sawsDebugLog.write("Header signature valid. The body of the log file must be corrupted.");
909  0 throw new logReadingException( SAWSConstant.CalculatedAccHashNotEqualsAccHashInLog); // can't recover
910    } else {
911  0 if (debugLevel > SAWSConstant.NoInfo)
912  0 sawsDebugLog.write("Header signature is not valid. The header of the log file must be corrupted.");
913  0 throw new logReadingException( SAWSConstant.HeaderSignatureIsNotValid); // can't recover
914    }
915    }
916    }
917   
918  28 byte [] lastAccumulatedHash = getAccumulatedHashByCalc();
919  28 byte [] lastSignature = getSignatureFromLog();
920  28 java.security.cert.Certificate cert1 = getCertFromLog();
921   
922    // sawsCAPublicKey is first used to verify that the certificate cert1 got from the log file is valid;
923  28 try {
924  28 cert1.verify(sawsCAPublicKey);
925  28 allReadingResult.append("\nThe PKC in this log file is verified.");
926  28 if (debugLevel > SAWSConstant.NoInfo)
927    //System.err.println("\nYes, saws certificate is valid!\n");
928    //adding log4j logging
929  0 sawsDebugLog.write("\nYes, saws certificate is valid!\n");
930    } catch (Exception e3){
931  0 throw new logReadingException( SAWSConstant.CertificateInLogIsNotValidAgainstRootCA); // can't recover
932    }
933   
934    // then the public key extracted from the certificate cert1 is used to verify the signature
935    //String signingAlgName = ((java.security.cert.X509Certificate )cert1).getSigAlgName();
936  28 String signingAlgName = cert1.getPublicKey().getAlgorithm();
937   
938  28 try{
939  28 if (debugLevel > SAWSConstant.NoInfo)
940    //System.err.println("In the beginning: " + signingAlgName);
941    //adding log4j logging
942  0 sawsDebugLog.write("In the beginning: " + signingAlgName);
943  28 Signature sig2 = Signature.getInstance(signingAlgName); //("SHA1withRSA");
944  28 sig2.initVerify(cert1.getPublicKey());
945  28 sig2.update(lastAccumulatedHash);
946  28 boolean vr = sig2.verify(lastSignature);
947  28 if (debugLevel > SAWSConstant.NoInfo)
948    //System.err.println("\nSignature of the log file is " + vr );
949    //adding log4j logging
950  0 sawsDebugLog.write("\nSignature of the log file is " + vr);
951    } catch (Exception e4){
952  0 throw new logReadingException( SAWSConstant.SignatureIsNotValid); // can't recover
953    }
954   
955  28 return result;
956    }
957   
 
958  0 toggle public int checkLogFile( ) throws logReadingException {
959  0 return checkLogFile(null);
960    }
961   
962    /**
963    * This method is for checking a log file.
964    *
965    * @param logFile is File to be checked.
966    * @param secureRandomBytes is the secure number used for checking secure hashes
967    *
968    * @return int 0: true, otherwise: false.
969    */
 
970  28 toggle public int checkLogFile(byte[] secureRandomBytes ) throws logReadingException {
971  28 RandomAccessFile raf1 = null;
972   
973  28 if (debugLevel > SAWSConstant.NoInfo)
974    //System.err.println("\nNow checking log file: " + CurrentLogFile.getPath());
975    //adding log4j logging
976  0 sawsDebugLog.write("\nNow checking log file: " + CurrentLogFile.getPath());
977  28 try{
978  28 raf1 = new RandomAccessFile(CurrentLogFile, "r");
979    } catch (Exception e1){
980  0 this.showMessage("Open log file error: " + CurrentLogFile.getPath(),
981    SAWSTextOutputCallback.ERROR);
982    //System.err.println("Open log file error: " + CurrentLogFile.getPath());
983  0 if (debugLevel > SAWSConstant.NoInfo)
984    //e1.printStackTrace(System.err);
985    //adding log4j logging
986  0 sawsDebugLog.write(e1.toString());
987    }
988   
989  28 for(int i=0;; ++i) {
990  568 if (logEndFlag == true ) break;
991  540 String temp = readOneRecordFromRAF(raf1, secureRandomBytes);
992  540 allReadingResult.append(temp);
993  540 if (debugLevel > SAWSConstant.NoInfo)
994    //System.out.println(temp);
995    //adding log4j logging
996  0 sawsDebugLog.write(temp);
997  540 if(currentSNCheck != i ){
998  0 throw new logReadingException( SAWSConstant.SNNotCorrectInLog, i); // can't recover
999    }
1000    }
1001   
1002  28 try{
1003  28 raf1.close();
1004    } catch (Exception e1){
1005  0 if (debugLevel > SAWSConstant.NoInfo)
1006    //e1.printStackTrace(System.err);
1007    //adding log4j logging
1008  0 sawsDebugLog.write(e1.toString());
1009    }
1010   
1011  28 return 0;
1012    }
1013   
1014    /**
1015    * This method is to find the previous log file name stored in this log file.
1016    *
1017    * @param secureRandomBytes is secure random bytes.
1018    *
1019    * @return String the previous log file name.
1020    */
 
1021  0 toggle public String findPreviousLogfileName(byte[] secureRandomBytes ) throws logReadingException {
1022  0 String pLogName = null;
1023  0 RandomAccessFile raf1 = null;
1024  0 if (debugLevel > SAWSConstant.NoInfo)
1025    //System.err.println("\nNow checking log file: " + CurrentLogFile.getPath());
1026    //adding log4j logging
1027  0 sawsDebugLog.write("\nNow checking log file: " + CurrentLogFile.getPath());
1028   
1029  0 try{
1030  0 raf1 = new RandomAccessFile(CurrentLogFile, "r");
1031    } catch (Exception e1){
1032  0 e1.printStackTrace(System.err);
1033    }
1034   
1035  0 for(int i=0;; ++i) {
1036  0 if (logEndFlag == true || logFileNameForLastLog!= null) break;
1037  0 readOneRecordFromRAF(raf1, secureRandomBytes);
1038  0 if(currentSNCheck != i ){
1039  0 throw new logReadingException( SAWSConstant.SNNotCorrectInLog, i); // can't recover
1040    }
1041    }
1042   
1043  0 try{
1044  0 raf1.close();
1045    } catch (Exception e1){
1046  0 e1.printStackTrace(System.err);
1047    }
1048   
1049  0 return logFileNameForLastLog;
1050    }
1051   
1052    /**
1053    * This method is to return the current SN
1054    */
 
1055  28 toggle public int getCurrentSN(){
1056  28 return currentSNCheck;
1057    }
1058   
1059   
1060    /**
1061    * This method is to return the SAWS certificate stored in the log file.
1062    *
1063    * @param CurrentLogFile is the current log file
1064    *
1065    * @return the certificate.
1066    */
 
1067  0 toggle public java.security.cert.Certificate getCert(File CurrentLogFile) throws logReadingException{
1068   
1069  0 RandomAccessFile raf = null;
1070  0 this.CurrentLogFile = CurrentLogFile;
1071  0 try{
1072  0 raf = new RandomAccessFile(this.CurrentLogFile, "r");
1073    } catch (Exception e1){
1074  0 e1.printStackTrace(System.err);
1075    }
1076   
1077  0 byte [] body = null;
1078  0 boolean flag = true;
1079  0 do {
1080  0 byte[] hTemp = null;
1081  0 hTemp = readRecordHeaderFromRAF(raf);
1082  0 int thisRecordLength = getThisRecordLengthFromRecordHeader(hTemp);
1083  0 if (getRecordTypeFromRecordHeader(hTemp) != SAWSConstant.SAWSCertificateType ) {
1084  0 shiftRAFPointer(raf, thisRecordLength-SAWSConstant.HeaderLength);
1085  0 continue;
1086    } else {
1087  0 body = readRecordBodyFromRAF(raf, 0,thisRecordLength - SAWSConstant.HashLength[this.accHashAlgorithmID] - SAWSConstant.HeaderLength);
1088  0 break;
1089    }
1090  0 } while (flag == true);
1091   
1092  0 try{
1093  0 raf.close();
1094    } catch (Exception e){
1095  0 e.printStackTrace(System.err);
1096    }
1097   
1098  0 ByteArrayInputStream bais = new ByteArrayInputStream(body);
1099  0 java.security.cert.CertificateFactory cf = null;
1100  0 java.security.cert.Certificate cert1 = null; // get saws cert key back from log
1101   
1102  0 try {
1103  0 cf = java.security.cert.CertificateFactory.getInstance("X.509");
1104  0 cert1 = cf.generateCertificate(bais); // get saws cert key back from log
1105    } catch (Exception e3){
1106  0 e3.printStackTrace(System.err);
1107    }
1108   
1109  0 return cert1;
1110    }
1111   
1112    /**
1113    * This method is to read the secure random number from the log file
1114    * with the given private key.
1115    *
1116    * @param CurrentLogFile is the log file
1117    * @param is the private key
1118    *
1119    * @return byte[] is the secure random number.
1120    */
 
1121  28 toggle public byte[] getSecureRandomNumber(PrivateKey privateKey) throws logReadingException {
1122   
1123  28 RandomAccessFile raf = null;
1124  28 try{
1125  28 raf = new RandomAccessFile(this.CurrentLogFile, "r");
1126    } catch (Exception e1){
1127  0 e1.printStackTrace(System.err);
1128    }
1129   
1130  28 byte [] decryptedBody = null;
1131  28 boolean flag = true;
1132  28 do {
1133  56 byte[] hTemp = null;
1134  56 hTemp = readRecordHeaderFromRAF(raf);
1135    //byte hashAlgID = this.getHashAlgorithmFromRecordHeader(hTemp);
1136  56 int thisRecordLength = getThisRecordLengthFromRecordHeader(hTemp);
1137  56 if (getRecordTypeFromRecordHeader(hTemp) != SAWSConstant.SAWSSecretRandomNumberType ) {
1138  28 shiftRAFPointer(raf, thisRecordLength-SAWSConstant.HeaderLength);
1139  28 continue;
1140    } else {
1141  28 byte[] body = readRecordBodyFromRAF(raf, 0,thisRecordLength - SAWSConstant.HashLength[this.accHashAlgorithmID] - SAWSConstant.HeaderLength);
1142  28 decryptedBody = ADecryptRecordBodyByPrivateKey(body, privateKey);
1143  28 break;
1144    }
1145  28 } while (flag == true);
1146   
1147  28 try{
1148  28 raf.close();
1149    } catch (Exception e){
1150  0 e.printStackTrace(System.err);
1151    }
1152   
1153  28 return decryptedBody;
1154    }
1155   
 
1156  0 toggle public SecretKey getSymmetricKey(){
1157  0 return sawsSecretKeyFromLog;
1158    }
1159   
1160    /**
1161    * This method is to read the symmetric key (byte[]) from the log file
1162    * with the given private key.
1163    *
1164    * @param CurrentLogFile is the log file
1165    * @param is the private key
1166    * @return byte[] is the symmetric key.
1167    */
 
1168  0 toggle public byte[] getSymmetricKey(File CurrentLogFile,PrivateKey privateKey) throws logReadingException {
1169  0 RandomAccessFile raf = null;
1170  0 this.CurrentLogFile = CurrentLogFile;
1171  0 try{
1172  0 raf = new RandomAccessFile(this.CurrentLogFile, "r");
1173    } catch (Exception e){
1174  0 e.printStackTrace(System.err);
1175    }
1176   
1177  0 byte [] decryptedBody = null;
1178  0 boolean flag = true;
1179  0 do {
1180  0 byte[] hTemp = null;
1181  0 hTemp = readRecordHeaderFromRAF(raf);
1182    //byte hashAlgID = this.getHashAlgorithmFromRecordHeader(hTemp);
1183  0 int thisRecordLength = getThisRecordLengthFromRecordHeader(hTemp);
1184  0 if (getRecordTypeFromRecordHeader(hTemp) != SAWSConstant.SymmetricEncryptionKeyType ) {
1185  0 shiftRAFPointer(raf, thisRecordLength-SAWSConstant.HeaderLength);
1186  0 continue;
1187    } else {
1188  0 byte[] body = readRecordBodyFromRAF(raf, 0,thisRecordLength - SAWSConstant.HashLength[this.accHashAlgorithmID] - SAWSConstant.HeaderLength);
1189  0 decryptedBody = ADecryptRecordBodyByPrivateKey(body, privateKey);
1190  0 break;
1191    }
1192  0 } while (flag == true);
1193   
1194  0 try{
1195  0 raf.close();
1196    } catch (Exception e){
1197  0 e.printStackTrace(System.err);
1198    }
1199   
1200  0 return decryptedBody;
1201    }
1202   
1203    /**
1204    * This method is to read the AccumulatedHash (byte[]) from the log file
1205    *
1206    * @param CurrentLogFile is the log file
1207    * @param is the private key
1208    *
1209    * @return byte[] the accumualted hash.
1210    */
 
1211  0 toggle public byte[] getAccumulatedHash(File CurrentLogFile) throws logReadingException {
1212  0 RandomAccessFile raf = null;
1213  0 this.CurrentLogFile = CurrentLogFile;
1214  0 try{
1215  0 raf = new RandomAccessFile(this.CurrentLogFile, "r");
1216    } catch (Exception e){
1217  0 e.printStackTrace(System.err);
1218    }
1219   
1220  0 byte [] accumulatedHash1 = null;
1221  0 boolean flag = true;
1222  0 do {
1223  0 byte[] hTemp = null;
1224  0 hTemp = readRecordHeaderFromRAF(raf);
1225    //byte hashAlgID = this.getHashAlgorithmFromRecordHeader(hTemp);
1226  0 int thisRecordLength = getThisRecordLengthFromRecordHeader(hTemp);
1227  0 if (getRecordTypeFromRecordHeader(hTemp) != SAWSConstant.SAWSAccumulatedHashType ) {
1228  0 shiftRAFPointer(raf, thisRecordLength-SAWSConstant.HeaderLength);
1229  0 continue;
1230    } else {
1231  0 byte[] body = readRecordBodyFromRAF(raf, 0,thisRecordLength - SAWSConstant.HashLength[this.accHashAlgorithmID] - SAWSConstant.HeaderLength);
1232  0 accumulatedHash1 = body;
1233  0 break;
1234    }
1235  0 } while (flag == true);
1236   
1237  0 try{
1238  0 raf.close();
1239    } catch (Exception e){
1240  0 e.printStackTrace(System.err);
1241    }
1242   
1243  0 return accumulatedHash1;
1244    }
1245   
1246    /**
1247    * This method is to read the AccumulatedHash (byte[]) from the log file
1248    *
1249    * @param CurrentLogFile is the log file
1250    *
1251    * @return byte[] the accumualted hash.
1252    */
 
1253  28 toggle public byte getAccumulatedHashAlgorithm(File CurrentLogFile) throws logReadingException {
1254  28 RandomAccessFile raf = null;
1255  28 this.CurrentLogFile = CurrentLogFile;
1256  28 try{
1257  28 raf = new RandomAccessFile(this.CurrentLogFile, "r");
1258    } catch (Exception e){
1259  0 e.printStackTrace(System.err);
1260    }
1261   
1262  28 byte [] accumulatedHashAlg = null;
1263  28 boolean flag = true;
1264  28 do {
1265  28 byte[] hTemp = null;
1266  28 hTemp = readRecordHeaderFromRAF(raf);
1267   
1268  28 int thisRecordLength = getThisRecordLengthFromRecordHeader(hTemp);
1269  28 if (getRecordTypeFromRecordHeader(hTemp) != SAWSConstant.SAWSHashAlgorithmType ) {
1270  0 shiftRAFPointer(raf, thisRecordLength-SAWSConstant.HeaderLength);
1271  0 continue;
1272    } else {
1273  28 byte[] body = readRecordBodyFromRAF(raf, 0, 1);//thisRecordLength/* - SAWSConstant.HashLength[hashAlgID]*/ - SAWSConstant.HeaderLength);
1274  28 accumulatedHashAlg = body;
1275  28 break;
1276    }
1277  0 } while (flag == true);
1278   
1279  28 try{
1280  28 raf.close();
1281    } catch (Exception e){
1282  0 e.printStackTrace(System.err);
1283    }
1284   
1285  28 return accumulatedHashAlg[0];
1286    }
1287   
1288    /**
1289    * This method is to read the signature of the complete log (byte[]) from the log file
1290    *
1291    * @param CurrentLogFile is the log file
1292    * @param is the private key
1293    *
1294    * @return byte[] is the signature.
1295    */
 
1296  0 toggle public byte[] getLogFileSignature(File CurrentLogFile) throws logReadingException{
1297  0 RandomAccessFile raf = null;
1298  0 this.CurrentLogFile = CurrentLogFile;
1299  0 try{
1300  0 raf = new RandomAccessFile(this.CurrentLogFile, "r");
1301    } catch (Exception e){
1302  0 e.printStackTrace(System.err);
1303    }
1304   
1305  0 byte [] sigBody = null;
1306  0 boolean flag = true;
1307  0 do {
1308  0 byte[] hTemp = null;
1309  0 hTemp = readRecordHeaderFromRAF(raf);
1310    //byte hashAlgID = this.getHashAlgorithmFromRecordHeader(hTemp);
1311  0 int thisRecordLength = getThisRecordLengthFromRecordHeader(hTemp);
1312  0 if (getRecordTypeFromRecordHeader(hTemp) != SAWSConstant.SAWSLogFileSignatureType) {
1313  0 shiftRAFPointer(raf, thisRecordLength-SAWSConstant.HeaderLength);
1314  0 continue;
1315    } else {
1316  0 byte[] body = readRecordBodyFromRAF(raf, 0,thisRecordLength - SAWSConstant.HashLength[this.accHashAlgorithmID]
1317    - SAWSConstant.HeaderLength);
1318  0 sigBody = body;
1319  0 break;
1320    }
1321  0 } while (flag == true);
1322   
1323  0 try{
1324  0 raf.close();
1325    } catch (Exception e){
1326  0 e.printStackTrace(System.err);
1327    }
1328   
1329  0 return sigBody;
1330    }
1331   
1332    /**
1333    * This method is to read the signature of the log file's header (byte[]) from the log file.
1334    *
1335    * @param CurrentLogFile is the log file
1336    * @param is the private key
1337    *
1338    * @return byte[] is the signature.
1339    */
 
1340  0 toggle public byte[] getHeaderSignature(File CurrentLogFile) throws logReadingException{
1341  0 RandomAccessFile raf = null;
1342  0 this.CurrentLogFile = CurrentLogFile;
1343  0 try{
1344  0 raf = new RandomAccessFile(this.CurrentLogFile, "r");
1345    } catch (Exception e){
1346  0 e.printStackTrace(System.err);
1347    }
1348   
1349  0 byte [] sigBody = null;
1350  0 boolean flag = true;
1351  0 do {
1352  0 byte[] hTemp = null;
1353  0 hTemp = readRecordHeaderFromRAF(raf);
1354    //byte hashAlgID = this.getHashAlgorithmFromRecordHeader(hTemp);
1355  0 int thisRecordLength = getThisRecordLengthFromRecordHeader(hTemp);
1356  0 if (getRecordTypeFromRecordHeader(hTemp) != SAWSConstant.SAWSHeaderSignatureType) {
1357  0 shiftRAFPointer(raf, thisRecordLength-SAWSConstant.HeaderLength);
1358  0 continue;
1359    } else {
1360  0 byte[] body = readRecordBodyFromRAF(raf, 0,thisRecordLength - SAWSConstant.HashLength[this.accHashAlgorithmID]
1361    - SAWSConstant.HeaderLength);
1362  0 sigBody = body;
1363  0 break;
1364    }
1365  0 } while (flag == true);
1366   
1367  0 try{
1368  0 raf.close();
1369    } catch (Exception e){
1370  0 e.printStackTrace(System.err);
1371    }
1372   
1373  0 return sigBody;
1374    }
1375   
1376    /**
1377    * This method is to give the encrytion type according to the type value
1378    *
1379    * @param
1380    *
1381    * @return String of the encryption type.
1382    */
 
1383  540 toggle private String getEncryptionTypeString(byte encryptionTypeIn){
1384  540 String enType = null;
1385  540 switch (encryptionTypeIn) {
1386  140 case SAWSConstant.AsymmetricEncryptionFlag: enType = new String("AsymmetricEncryptionFlag"); break;
1387  160 case SAWSConstant.SymmetricEncryptionFlag: enType = new String("SymmetricEncryptionFlag"); break;
1388  240 case SAWSConstant.NoEncryptionFlag: enType = new String("NoEncryptionFlag"); break;
1389  0 default: enType = new String("Wrong type");
1390    }
1391  540 return enType;
1392    }
1393   
1394    /**
1395    * Method to create the callback (SAWSTextOutputCallback) with the message to be
1396    * presented to the user and send it to the callback handler.
1397    *
1398    * @param message The message to be presented.
1399    * @param type The type of the message (SAWSTextOutputCallback.WARNING,
1400    * SAWSTextOutputCallback.ERROR, SAWSTextOutputCallback.INFORMATION)
1401    */
 
1402  0 toggle private void showMessage(String message, int type) {
1403  0 Callback[] cbs = new Callback[1];
1404  0 cbs[0] = new SAWSTextOutputCallback(type, message);
1405  0 try {
1406  0 this.callbackHandler.handle(cbs);
1407    }
1408    catch (Exception e) {
1409  0 System.err.println(e.getMessage());
1410  0 sawsDebugLog.write(e);
1411    }
1412    }
1413   
1414    }