1 11 package org.eclipse.update.internal.security; 12 13 import java.io.File ; 14 import java.io.IOException ; 15 import java.io.InputStream ; 16 import java.security.KeyStore ; 17 import java.security.KeyStoreException ; 18 import java.security.NoSuchAlgorithmException ; 19 import java.security.cert.Certificate ; 20 import java.security.cert.CertificateException ; 21 import java.util.ArrayList ; 22 import java.util.Enumeration ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.jar.JarEntry ; 26 import java.util.jar.JarFile ; 27 import java.util.zip.ZipException ; 28 29 import org.eclipse.core.runtime.CoreException; 30 import org.eclipse.core.runtime.IProgressMonitor; 31 import org.eclipse.osgi.util.NLS; 32 import org.eclipse.update.core.ContentReference; 33 import org.eclipse.update.core.IFeature; 34 import org.eclipse.update.core.IVerificationResult; 35 import org.eclipse.update.core.IVerifier; 36 import org.eclipse.update.core.InstallMonitor; 37 import org.eclipse.update.core.JarContentReference; 38 import org.eclipse.update.core.Utilities; 39 import org.eclipse.update.core.Verifier; 40 import org.eclipse.update.internal.core.Messages; 41 import org.eclipse.update.internal.core.UpdateCore; 42 import org.eclipse.update.internal.core.connection.ConnectionFactory; 43 44 51 52 public class JarVerifier extends Verifier { 53 54 private static final String MANIFEST = "META-INF"; 56 private JarVerificationResult result; 57 private List 58 trustedCertificates; 59 private boolean acceptUnsignedFiles; 60 private List 61 listOfKeystores; 62 private IProgressMonitor monitor; 63 private File jarFile; 64 65 private static byte[] buffer = new byte[8192]; 66 67 70 public JarVerifier() { 71 initialize(); 72 } 73 74 77 private List getKeyStores() throws CoreException { 78 if (listOfKeystores == null) { 79 listOfKeystores = new ArrayList (0); 80 KeyStores listOfKeystoreHandles = new KeyStores(); 81 InputStream in = null; 82 KeyStore keystore = null; 83 KeystoreHandle handle = null; 84 while (listOfKeystoreHandles.hasNext()) { 85 try { 86 handle = listOfKeystoreHandles.next(); 87 in = ConnectionFactory.get(handle.getLocation()).getInputStream(); 88 try { 89 keystore = KeyStore.getInstance(handle.getType()); 90 keystore.load(in, null); } catch (NoSuchAlgorithmException e) { 92 throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToFindEncryption, (new String [] { handle.getLocation().toExternalForm() })), e); 93 } catch (CertificateException e) { 94 throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToLoadCertificate, (new String [] { handle.getLocation().toExternalForm() })), e); 95 } catch (KeyStoreException e) { 96 throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToFindProviderForKeystore, (new String [] { handle.getType() })), e); 97 } finally { 98 if (in != null) { 99 try { 100 in.close(); 101 } catch (IOException e) { 102 } } 104 } 106 listOfKeystores.add(keystore); 108 } catch (IOException e) { 109 } 111 112 } 114 } 115 116 return listOfKeystores; 117 } 118 119 122 private void initialize() { 123 result = null; 124 trustedCertificates = null; 125 acceptUnsignedFiles = false; 126 listOfKeystores = null; 127 } 128 129 132 private void init(IFeature feature, ContentReference contentRef) throws CoreException { 133 jarFile = null; 134 if (contentRef instanceof JarContentReference) { 135 JarContentReference jarReference = (JarContentReference) contentRef; 136 try { 137 jarFile = jarReference.asFile(); 138 if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL) 139 UpdateCore.debug("Attempting to read JAR file:"+jarFile); 141 if (!jarFile.exists()) throw new IOException (); 143 JarFile jar = new JarFile (jarFile); 144 if (jar !=null){ 145 try { 146 jar.close(); 147 } catch (IOException ex) { 148 } 150 } 151 } catch (ZipException e){ 152 throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_InvalidJar, (new String [] { jarReference.toString() })), e); 153 } catch (IOException e) { 154 throw Utilities.newCoreException(NLS.bind(Messages.JarVerifier_UnableToAccessJar, (new String [] { jarReference.toString() })), e); 155 } 156 } 157 158 result = new JarVerificationResult(); 159 result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR); 160 result.setResultException(null); 161 result.setFeature(feature); 162 result.setContentReference(contentRef); 163 } 164 165 168 private boolean existsInKeystore(Certificate cert) throws CoreException { 169 try { 170 List keyStores = getKeyStores(); 171 if (!keyStores.isEmpty()) { 172 Iterator listOfKeystores = keyStores.iterator(); 173 while (listOfKeystores.hasNext()) { 174 KeyStore keystore = (KeyStore ) listOfKeystores.next(); 175 176 if (keystore.getCertificateAlias(cert) != null) { 177 return true; 178 } 179 } 180 } 181 } catch (KeyStoreException e) { 182 throw Utilities.newCoreException(Messages.JarVerifier_KeyStoreNotLoaded, e); 183 } 184 return false; 185 } 186 187 190 private List readJarFile(JarFile jarFile, String identifier) 191 throws IOException , InterruptedException { 192 List list = new ArrayList (); 193 194 Enumeration entries = jarFile.entries(); 195 JarEntry currentEntry = null; 196 InputStream in = null; 197 if (monitor != null) 198 monitor.setTaskName(NLS.bind(Messages.JarVerifier_Verify, (new String [] { identifier == null ? jarFile.getName(): identifier }))); 199 200 try { 201 while (entries.hasMoreElements()) { 202 currentEntry = (JarEntry ) entries.nextElement(); 203 list.add(currentEntry); 204 in = jarFile.getInputStream(currentEntry); 205 while ((in.read(buffer, 0, buffer.length)) != -1) { 206 } 208 if (in!=null) 209 in.close(); 210 } 211 } catch (IOException e) { 212 result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR); 213 result.setResultException(e); 214 } finally { 215 try { 216 if (in != null) 217 in.close(); 218 } catch (IOException e1) { 219 } 221 } 222 223 return list; 224 } 225 226 229 public void setMonitor(IProgressMonitor newMonitor) { 230 monitor = newMonitor; 231 } 232 233 236 public IVerificationResult verify( 237 IFeature feature, 238 ContentReference reference, 239 boolean isFeatureVerification, 240 InstallMonitor monitor) 241 throws CoreException { 242 243 if (reference == null) 244 return result; 245 246 if (getParent() != null) { 248 IVerificationResult vr = 249 getParent().verify(feature, reference, isFeatureVerification, monitor); 250 if (vr.getVerificationCode() != IVerificationResult.TYPE_ENTRY_UNRECOGNIZED) 251 return vr; 252 } 253 254 setMonitor(monitor); 256 init(feature, reference); 257 result.isFeatureVerification(isFeatureVerification); 258 259 if (jarFile!=null) { 260 result = verify(jarFile.getAbsolutePath(), reference.getIdentifier()); 261 } else { 262 result.setVerificationCode(IVerificationResult.TYPE_ENTRY_UNRECOGNIZED); 263 } 264 265 return result; 266 } 267 268 271 private JarVerificationResult verify(String file, String identifier) { 272 273 try { 274 275 verifyIntegrity(file, identifier); 277 278 281 result.alreadySeen(alreadyValidated()); 283 284 if (result.getVerificationCode() 286 == IVerificationResult.TYPE_ENTRY_SIGNED_UNRECOGNIZED) { 287 verifyAuthentication(); 288 } 289 290 if (result.getVerificationCode() 292 == IVerificationResult.TYPE_ENTRY_NOT_SIGNED) { 293 acceptUnsignedFiles = true; 294 } 295 296 } catch (Exception e) { 297 result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR); 298 result.setResultException(e); 299 } 300 301 if (monitor != null) { 302 monitor.worked(1); 303 if (monitor.isCanceled()) { 304 result.setVerificationCode(IVerificationResult.VERIFICATION_CANCELLED); 305 } 306 } 307 308 return result; 309 } 310 311 318 private void verifyAuthentication() throws CoreException { 319 320 CertificatePair[] entries = result.getRootCertificates(); 321 boolean certificateFound = false; 322 323 for (int i = 0; i < entries.length; i++) { 327 certificateFound = existsInKeystore(entries[i].getRoot()); 328 if (certificateFound) { 329 result.setVerificationCode(IVerificationResult.TYPE_ENTRY_SIGNED_RECOGNIZED); 330 result.setFoundCertificate(entries[i]); 331 return; 332 } 333 } 334 } 335 336 339 private void verifyIntegrity(String file, String identifier) { 340 341 JarFile jarFile = null; 342 343 try { 344 jarFile = new JarFile (file, true); 348 List filesInJar = readJarFile(jarFile, identifier); 349 350 if (jarFile.getManifest() != null) { 353 Iterator iter = filesInJar.iterator(); 354 boolean certificateFound = false; 355 while (iter.hasNext()) { 356 JarEntry currentJarEntry = (JarEntry ) iter.next(); 357 Certificate [] certs = currentJarEntry.getCertificates(); 358 if ((certs != null) && (certs.length != 0)) { 359 certificateFound = true; 360 result.addCertificates(certs); 361 } else { 362 String jarEntryName = currentJarEntry.getName(); 363 if (!jarEntryName.toUpperCase().startsWith(MANIFEST) 364 && !currentJarEntry.isDirectory()) { 365 break; 367 } 368 369 } 370 } 371 372 if (certificateFound) 373 result.setVerificationCode(IVerificationResult.TYPE_ENTRY_SIGNED_UNRECOGNIZED); 374 else 375 result.setVerificationCode(IVerificationResult.TYPE_ENTRY_NOT_SIGNED); 376 } else { 377 Exception e = new Exception (NLS.bind(Messages.JarVerifier_InvalidFile, (new String [] { file }))); 378 result.setResultException(e); 379 result.setVerificationCode(IVerificationResult.TYPE_ENTRY_NOT_SIGNED); 380 UpdateCore.warn(null,e); 381 } 382 } catch (SecurityException e) { 383 result.setVerificationCode(IVerificationResult.TYPE_ENTRY_CORRUPTED); 386 } catch (InterruptedException e) { 387 result.setVerificationCode(IVerificationResult.VERIFICATION_CANCELLED); 388 } catch (Exception e) { 389 result.setVerificationCode(IVerificationResult.UNKNOWN_ERROR); 390 result.setResultException(e); 391 } finally { 392 if (jarFile!=null){ 393 try {jarFile.close();} catch (IOException e){} 394 } 395 } 396 397 } 398 399 402 private boolean alreadyValidated() { 403 404 if (result.getVerificationCode() == IVerificationResult.TYPE_ENTRY_NOT_SIGNED) 405 return (acceptUnsignedFiles); 406 407 if (getTrustedCertificates() != null) { 408 Iterator iter = getTrustedCertificates().iterator(); 409 CertificatePair[] jarPairs = result.getRootCertificates(); 410 411 while (iter.hasNext()) { 413 CertificatePair trustedCertificate = (CertificatePair) iter.next(); 414 for (int i = 0; i < jarPairs.length; i++) { 415 if (trustedCertificate.equals(jarPairs[i])) { 416 return true; 417 } 418 } 419 } 420 421 for (int i = 0; i < jarPairs.length; i++) { 423 addTrustedCertificate(jarPairs[i]); 424 } 425 } 426 427 return false; 428 } 429 430 433 private void addTrustedCertificate(CertificatePair pair) { 434 if (trustedCertificates == null) 435 trustedCertificates = new ArrayList (); 436 if (pair != null) 437 trustedCertificates.add(pair); 438 } 439 440 443 private List getTrustedCertificates() { 444 if (trustedCertificates == null) 445 trustedCertificates = new ArrayList (); 446 return trustedCertificates; 447 } 448 449 452 public void setParent(IVerifier parentVerifier) { 453 super.setParent(parentVerifier); 454 initialize(); 455 } 456 457 } 458 | Popular Tags |