1 20 21 22 23 24 25 package org.snmp4j.security; 26 27 import java.security.MessageDigest ; 28 import org.snmp4j.log.*; 29 import org.snmp4j.smi.OctetString; 30 31 38 39 public abstract class AuthGeneric 40 implements AuthenticationProtocol { 41 42 private static final LogAdapter logger = LogFactory.getLogger(AuthGeneric.class); 43 private int digestLength; 44 private String protoName; 45 46 public AuthGeneric(String protoName, int digestLength) { 47 this.protoName = protoName; 48 this.digestLength = digestLength; 49 } 50 51 public int getDigestLength() { 52 return digestLength; 53 } 54 55 61 protected MessageDigest getDigestObject() { 62 MessageDigest md; 63 try { 64 md = MessageDigest.getInstance(protoName); 65 } 66 catch (java.security.NoSuchAlgorithmException e) { 67 throw new InternalError (protoName + " not supported in this VM."); 68 } 69 return md; 71 } 72 73 public boolean authenticate(byte[] authenticationKey, 74 byte[] message, 75 int messageOffset, 76 int messageLength, 77 ByteArrayWindow digest) { 78 MessageDigest md = getDigestObject(); 79 80 byte[] newDigest; 81 byte[] k_ipad = new byte[64]; 82 byte[] k_opad = new byte[64]; 83 84 for (int i = 0; i < MESSAGE_AUTHENTICATION_CODE_LENGTH; ++i) { 86 digest.set(i, (byte)0); 87 } 88 89 99 100 for (int i = 0; i < authenticationKey.length; ++i) { 101 k_ipad[i] = (byte) (authenticationKey[i] ^ 0x36); 102 k_opad[i] = (byte) (authenticationKey[i] ^ 0x5c); 103 } 104 for (int i = authenticationKey.length; i < 64; ++i) { 105 k_ipad[i] = 0x36; 106 k_opad[i] = 0x5c; 107 } 108 109 110 md.update(k_ipad); 111 md.update(message, messageOffset, messageLength); 112 newDigest = md.digest(); 113 114 md.reset(); 115 md.update(k_opad); 116 md.update(newDigest); 117 newDigest = md.digest(); 118 119 for (int i = 0; i < 12; ++i) { 121 digest.set(i, newDigest[i]); 122 } 123 return true; 124 } 125 126 public boolean isAuthentic(byte[] authenticationKey, 127 byte[] message, 128 int messageOffset, 129 int messageLength, 130 ByteArrayWindow digest) { 131 ByteArrayWindow origDigest = 133 new ByteArrayWindow(new byte[MESSAGE_AUTHENTICATION_CODE_LENGTH], 0, 134 MESSAGE_AUTHENTICATION_CODE_LENGTH); 135 System.arraycopy(digest.getValue(), digest.getOffset(), 136 origDigest.getValue(), 0, 137 MESSAGE_AUTHENTICATION_CODE_LENGTH); 138 139 if (!authenticate(authenticationKey, message, messageOffset, 141 messageLength, digest)) { 142 return false; 143 } 144 return digest.equals(origDigest, 12); 145 } 146 147 public byte[] changeDelta(byte[] oldKey, 148 byte[] newKey, 149 byte[] random) { 150 153 MessageDigest md5 = getDigestObject(); 154 155 if (logger.isDebugEnabled()) { 156 logger.debug(protoName + "oldKey: " + new OctetString(oldKey).toHexString()); 157 logger.debug(protoName + "newKey: " + new OctetString(newKey).toHexString()); 158 logger.debug(protoName + "random: " + new OctetString(random).toHexString()); 159 } 160 161 md5.update(oldKey); 165 md5.update(random); 166 byte[] digest = md5.digest(); 167 168 byte[] keyChange = new byte[random.length + newKey.length]; 170 for (int i = 0; i < random.length; ++i) { 171 keyChange[i] = random[i]; 172 } 173 for (int i = random.length; i < random.length + newKey.length; ++i) { 174 keyChange[i] = newKey[i - random.length]; 175 } 176 for (int j = oldKey.length; j < keyChange.length; j++) { 177 keyChange[j] ^= digest[j - oldKey.length]; 178 } 179 180 if (logger.isDebugEnabled()) { 181 logger.debug(protoName + "keyChange:" + 182 new OctetString(keyChange).toHexString()); 183 } 184 185 return keyChange; 186 } 187 188 public byte[] passwordToKey(OctetString passwordString, byte[] engineID) { 189 190 MessageDigest md = getDigestObject(); 191 192 byte[] digest; 193 byte[] buf = new byte[64]; 194 int password_index = 0; 195 int count = 0; 196 byte[] password = passwordString.getValue(); 197 198 199 while (count < 1048576) { 200 for (int i = 0; i < 64; ++i) { 201 202 203 buf[i] = password[password_index++ % password.length]; 204 } 205 md.update(buf); 206 count += 64; 207 } 208 digest = md.digest(); 209 if (logger.isDebugEnabled()) { 210 logger.debug(protoName + "First digest: " + 211 new OctetString(digest).toHexString()); 212 } 213 214 215 216 217 218 md.reset(); 219 md.update(digest); 220 md.update(engineID); 221 md.update(digest); 222 digest = md.digest(); 223 if (logger.isDebugEnabled()) { 224 logger.debug(protoName + "localized key: " + 225 new OctetString(digest).toHexString()); 226 } 227 228 return digest; 229 } 230 231 public byte[] hash(byte[] data) { 232 MessageDigest md = getDigestObject(); 233 md.update(data); 234 return md.digest(); 235 } 236 237 public byte[] hash(byte[] data, int offset, int length) { 238 MessageDigest md = getDigestObject(); 239 md.update(data, offset, length); 240 return md.digest(); 241 } 242 243 } 244 | Popular Tags |