1 package com.knowgate.jcifs.smb; 2 3 import java.security.MessageDigest ; 4 import java.security.NoSuchAlgorithmException ; 5 import java.io.IOException ; 6 7 import com.knowgate.debug.*; 8 import com.knowgate.misc.Gadgets; 9 import com.knowgate.jcifs.Config; 10 11 14 15 public class SigningDigest { 16 17 private static final int LM_COMPATIBILITY = Config.getInt( "jcifs.smb.lmCompatibility", 0); 18 19 20 private MessageDigest digest; 21 private byte[] macSigningKey; 22 private int updates; 23 private int signSequence; 24 25 public SigningDigest( SmbTransport transport, 26 NtlmPasswordAuthentication auth ) throws SmbException { 27 try { 28 digest = MessageDigest.getInstance("MD5"); 29 } catch (NoSuchAlgorithmException ex) { 30 if( DebugFile.trace ) 31 new ErrorHandler(ex); 32 throw new SmbException( "MD5", ex ); 33 } 34 35 try { 36 switch (LM_COMPATIBILITY) { 37 case 0: 38 case 1: 39 case 2: 40 macSigningKey = new byte[40]; 41 auth.getUserSessionKey(transport.server.encryptionKey, macSigningKey, 0); 42 System.arraycopy(auth.getUnicodeHash(transport.server.encryptionKey), 43 0, macSigningKey, 16, 24); 44 break; 45 case 3: 46 case 4: 47 case 5: 48 macSigningKey = new byte[16]; 49 auth.getUserSessionKey(transport.server.encryptionKey, macSigningKey, 0); 50 break; 51 default: 52 macSigningKey = new byte[40]; 53 auth.getUserSessionKey(transport.server.encryptionKey, macSigningKey, 0); 54 System.arraycopy(auth.getUnicodeHash(transport.server.encryptionKey), 55 0, macSigningKey, 16, 24); 56 break; 57 } 58 } catch( Exception ex ) { 59 throw new SmbException( "", ex ); 60 } 61 if( DebugFile.trace ) { 62 DebugFile.writeln( "LM_COMPATIBILITY=" + LM_COMPATIBILITY ); 63 } 64 } 65 66 public void update( byte[] input, int offset, int len ) { 67 if( DebugFile.trace ) { 68 DebugFile.writeln( "update: " + updates + " " + offset + ":" + len ); 69 } 70 if( len == 0 ) { 71 return; 72 } 73 digest.update( input, offset, len ); 74 updates++; 75 } 76 public byte[] digest() { 77 byte[] b; 78 79 b = digest.digest(); 80 81 if( DebugFile.trace ) { 82 DebugFile.writeln( "digest: " ); 83 } 84 updates = 0; 85 86 return b; 87 } 88 89 99 void sign(byte[] data, int offset, int length, 100 ServerMessageBlock request, ServerMessageBlock response) { 101 request.signSeq = signSequence; 102 if( response != null ) { 103 response.signSeq = signSequence + 1; 104 response.verifyFailed = false; 105 } 106 107 try { 108 update(macSigningKey, 0, macSigningKey.length); 109 int index = offset + ServerMessageBlock.SIGNATURE_OFFSET; 110 for (int i = 0; i < 8; i++) data[index + i] = 0; 111 ServerMessageBlock.writeInt4(signSequence, data, index); 112 update(data, offset, length); 113 System.arraycopy(digest(), 0, data, index, 8); 114 } catch (Exception ex) { 115 if( DebugFile.trace ) 116 new ErrorHandler(ex); 117 } finally { 118 signSequence += 2; 119 } 120 } 121 122 130 boolean verify(byte[] data, int offset, ServerMessageBlock response) { 131 update(macSigningKey, 0, macSigningKey.length); 132 int index = offset; 133 update(data, index, ServerMessageBlock.SIGNATURE_OFFSET); 134 index += ServerMessageBlock.SIGNATURE_OFFSET; 135 byte[] sequence = new byte[8]; 136 ServerMessageBlock.writeInt4(response.signSeq, sequence, 0); 137 update(sequence, 0, sequence.length); 138 index += 8; 139 if( response.command == ServerMessageBlock.SMB_COM_READ_ANDX ) { 140 142 SmbComReadAndXResponse raxr = (SmbComReadAndXResponse)response; 143 int length = response.length - raxr.dataLength; 144 update(data, index, length - ServerMessageBlock.SIGNATURE_OFFSET - 8); 145 update(raxr.b, raxr.off, raxr.dataLength); 146 } else { 147 update(data, index, response.length - ServerMessageBlock.SIGNATURE_OFFSET - 8); 148 } 149 byte[] signature = digest(); 150 for (int i = 0; i < 8; i++) { 151 if (signature[i] != data[offset + ServerMessageBlock.SIGNATURE_OFFSET + i]) { 152 if( DebugFile.trace ) { 153 DebugFile.writeln( "signature verification failure" ); 154 } 155 return response.verifyFailed = true; 156 } 157 } 158 159 return response.verifyFailed = false; 160 } 161 } 162 163 | Popular Tags |