264 * @param msUID the UID if the MIDlet suite being authenticated |
264 * @param msUID the UID if the MIDlet suite being authenticated |
265 * @param oldMSUID the UID if the MIDlet suite being updated |
265 * @param oldMSUID the UID if the MIDlet suite being updated |
266 * (if applicable) |
266 * (if applicable) |
267 * @param appJARPath the path to the JAR being authenticated |
267 * @param appJARPath the path to the JAR being authenticated |
268 */ |
268 */ |
269 public AuthenticationCredentials[] authenticateJar( |
269 public void authenticateJar( |
|
270 StorageSession storageSession, |
270 Uid msUID, |
271 Uid msUID, |
271 Uid oldMSUID, |
272 Uid oldMSUID, |
272 String appJARPath, |
273 String appJARPath, |
273 boolean drmContent) |
274 boolean drmContent) |
274 { |
275 { |
275 AuthenticationStorageData data = null; |
276 AuthenticationStorageData data = null; |
276 Credentials selectedCredentials = null; |
|
277 try |
277 try |
278 { |
278 { |
279 Vector allAuthCredentials = (Vector)iAuthCredentials.get(msUID); |
279 Vector allAuthCredentials = (Vector)iAuthCredentials.get(msUID); |
280 String jarHash = null; |
280 String jarHash = _computeHash(appJARPath); |
281 try |
|
282 { |
|
283 jarHash = _computeHash(appJARPath); |
|
284 }catch(AuthenticationException e) {} |
|
285 if (jarHash == null || jarHash.length() == 0) |
281 if (jarHash == null || jarHash.length() == 0) |
286 { |
282 { |
287 // could not compute hash for the given application |
283 // could not compute hash for the given application |
288 Logger.logWarning("Could not compute hash for " + appJARPath); |
284 Logger.logWarning("Could not compute hash for " + appJARPath); |
289 throw new InstallerSecurityException( |
285 throw new InstallerSecurityException( |
305 jarHash, |
301 jarHash, |
306 null /*rootHashValue*/, |
302 null /*rootHashValue*/, |
307 null /*validatedChainIndexes*/, |
303 null /*validatedChainIndexes*/, |
308 null /* jarPath*/, |
304 null /* jarPath*/, |
309 iSecurityWarningsMode); |
305 iSecurityWarningsMode); |
310 selectedCredentials = new Credentials( |
|
311 data.getProtectionDomain(), |
|
312 data.getProtectionDomainCategory(), |
|
313 jarHash, |
|
314 null /* root hash */, |
|
315 -1 /* validated chain index*/, |
|
316 null /* signing cert */); |
|
317 verifyUpdate( |
306 verifyUpdate( |
318 new Credentials[] {selectedCredentials}, |
307 new Credentials[] {new Credentials( |
|
308 data.getProtectionDomain(), |
|
309 data.getProtectionDomainCategory(), |
|
310 jarHash, |
|
311 null /* root hash */, |
|
312 -1 /* validated chain index*/, |
|
313 null /* signing cert */) |
|
314 }, |
319 oldMSUID); |
315 oldMSUID); |
320 } |
316 } |
321 else |
317 else |
322 { |
318 { |
323 // get the authentication credential candidates and select the right |
319 // get the authentication credential candidates and select the right |
326 String protectionDomainName = null; |
322 String protectionDomainName = null; |
327 String protectionDomainCategory = null; |
323 String protectionDomainCategory = null; |
328 String jarHashValue = null; |
324 String jarHashValue = null; |
329 String rootHashValue = null; |
325 String rootHashValue = null; |
330 Vector validatedChainIndexes = new Vector(); |
326 Vector validatedChainIndexes = new Vector(); |
331 selectedCredentials = selectCredentials(jarHash, allAuthCredentials, validatedChainIndexes); |
327 Credentials selectedCredentials = selectCredentials(jarHash, allAuthCredentials, validatedChainIndexes); |
332 if (selectedCredentials == null |
328 if (selectedCredentials == null |
333 || selectedCredentials.getProtectionDomainName() == null) |
329 || selectedCredentials.getProtectionDomainName() == null) |
334 { |
330 { |
335 if (!drmContent) |
331 if (!drmContent) |
336 { |
332 { |
376 selectedCredentials.jarHashValue, |
372 selectedCredentials.jarHashValue, |
377 selectedCredentials.rootHashValue, |
373 selectedCredentials.rootHashValue, |
378 validatedChainIndexes, |
374 validatedChainIndexes, |
379 iSecurityWarningsMode); |
375 iSecurityWarningsMode); |
380 } |
376 } |
|
377 |
|
378 writeAuthenticationStorageData(storageSession, msUID, data, (oldMSUID != null && oldMSUID.equals(msUID))); |
381 } |
379 } |
382 finally |
380 finally |
383 { |
381 { |
384 // remove all the auth credentials with the selection |
382 // remove all the auth credentials with the selection |
385 if (data != null) |
383 if (data != null) |
386 { |
384 { |
387 iSelectedAuthCredentials.put(msUID, data); |
385 iSelectedAuthCredentials.put(msUID, data); |
388 } |
386 } |
389 } |
387 } |
390 return new AuthenticationCredentials[] {selectedCredentials}; |
388 } |
391 } |
389 |
392 |
390 /** |
393 /** |
391 */ |
394 */ |
392 public void authenticateJar( |
395 public AuthenticationCredentials[] authenticateJar( |
393 StorageSession storageSession, |
396 Uid uid, |
394 Uid uid, |
397 Uid oldUid, |
395 Uid oldUid, |
398 ProtectionDomain protectionDomain, |
396 ProtectionDomain protectionDomain, |
399 String appJARPath) |
397 String appJARPath) |
400 { |
398 { |
401 Credentials selectedCredentials = null; |
|
402 if (protectionDomain == null |
399 if (protectionDomain == null |
403 || (!protectionDomain.equals(ProtectionDomain.getManufacturerDomain()) |
400 || (!protectionDomain.equals(ProtectionDomain.getManufacturerDomain()) |
404 && !protectionDomain.equals(ProtectionDomain.getOperatorDomain()) |
401 && !protectionDomain.equals(ProtectionDomain.getOperatorDomain()) |
405 && !protectionDomain.equals(ProtectionDomain.getIdentifiedThirdPartyDomain()) |
402 && !protectionDomain.equals(ProtectionDomain.getIdentifiedThirdPartyDomain()) |
406 && !protectionDomain.equals(ProtectionDomain.getUnidentifiedThirdPartyDomain()))) |
403 && !protectionDomain.equals(ProtectionDomain.getUnidentifiedThirdPartyDomain()))) |
411 null, /* no params for short msg */ |
408 null, /* no params for short msg */ |
412 InstallerDetailedErrorMessage.INTERNAL_ERROR, |
409 InstallerDetailedErrorMessage.INTERNAL_ERROR, |
413 new String[] {"Unknown protection domain " + protectionDomain}, |
410 new String[] {"Unknown protection domain " + protectionDomain}, |
414 OtaStatusCode.INTERNAL_ERROR); |
411 OtaStatusCode.INTERNAL_ERROR); |
415 } |
412 } |
416 String jarHash = null; |
413 String jarHash = _computeHash(appJARPath); |
417 try |
|
418 { |
|
419 jarHash = _computeHash(appJARPath); |
|
420 }catch(AuthenticationException e) {} |
|
421 if (jarHash == null || jarHash.length() == 0) |
414 if (jarHash == null || jarHash.length() == 0) |
422 { |
415 { |
423 // could not compute hash for the given application |
416 // could not compute hash for the given application |
424 Logger.logWarning("Could not compute hash for " + appJARPath); |
417 Logger.logWarning("Could not compute hash for " + appJARPath); |
425 throw new InstallerSecurityException( |
418 throw new InstallerSecurityException( |
435 jarHash, |
428 jarHash, |
436 null /*rootHashValue*/, |
429 null /*rootHashValue*/, |
437 null /*validatedChainIndexes*/, |
430 null /*validatedChainIndexes*/, |
438 null /* jarPath*/, |
431 null /* jarPath*/, |
439 iSecurityWarningsMode); |
432 iSecurityWarningsMode); |
440 selectedCredentials = new Credentials( |
|
441 data.getProtectionDomain(), |
|
442 data.getProtectionDomainCategory(), |
|
443 jarHash, |
|
444 null /* root hash */, |
|
445 -1 /* validated chain index*/, |
|
446 null /* signing cert */); |
|
447 verifyUpdate( |
433 verifyUpdate( |
448 new Credentials[] {selectedCredentials}, |
434 new Credentials[] {new Credentials( |
|
435 data.getProtectionDomain(), |
|
436 data.getProtectionDomainCategory(), |
|
437 jarHash, |
|
438 null /* root hash */, |
|
439 -1 /* validated chain index*/, |
|
440 null /* signing cert */) |
|
441 }, |
449 oldUid); |
442 oldUid); |
450 |
443 |
451 iSelectedAuthCredentials.put(uid, data); |
444 writeAuthenticationStorageData(storageSession, uid, data, (oldUid != null && oldUid.equals(uid))); |
452 |
|
453 return new AuthenticationCredentials[] {selectedCredentials}; |
|
454 } |
445 } |
455 |
446 |
456 /** |
447 /** |
457 * Registers a listener for ocsp events corresponding to the |
448 * Registers a listener for ocsp events corresponding to the |
458 * installation of a certain MIDlet suite |
449 * installation of a certain MIDlet suite |
580 } |
571 } |
581 iOcspEventListeners.remove(msUID); |
572 iOcspEventListeners.remove(msUID); |
582 } |
573 } |
583 |
574 |
584 /** |
575 /** |
585 * Writes to storage all the security data related to a certain MIDlet suite |
|
586 * |
|
587 * @param sessionID the JavaStorage session to be used when |
|
588 * writing the security data into storage |
|
589 * @param msUID the UID if the MIDlet suite whose security data is |
|
590 * being written |
|
591 */ |
|
592 public void addSecurityData(StorageSession storageSession, Uid msUID, Uid oldMsUID) |
|
593 { |
|
594 Logger.log("Write authentication data to storage"); |
|
595 AuthenticationStorageData authStorageData = |
|
596 (AuthenticationStorageData)iSelectedAuthCredentials.remove( |
|
597 msUID); |
|
598 writeAuthenticationStorageData(storageSession, msUID, authStorageData, |
|
599 (oldMsUID != null && oldMsUID.equals(msUID))); |
|
600 } |
|
601 |
|
602 /** |
|
603 * Returns the details of the certificates used for authenticating a |
576 * Returns the details of the certificates used for authenticating a |
604 * MIDlet suite. This method is used at installation time. |
577 * MIDlet suite. This method is used at installation time. |
605 * |
578 * |
606 * @param sessionID the JavaStorage session to be used when |
579 * @param sessionID the JavaStorage session to be used when |
607 * retrieving the certificates details |
580 * retrieving the certificates details |
678 * @param aMsUid the UID of the MIDlet suite whose media info is |
651 * @param aMsUid the UID of the MIDlet suite whose media info is |
679 * notified |
652 * notified |
680 * @param aMediaId the identifier of the media where the MIDlet |
653 * @param aMediaId the identifier of the media where the MIDlet |
681 * suite is installed |
654 * suite is installed |
682 */ |
655 */ |
683 public void setMediaId(Uid aMsUid, int aMediaId) |
656 public void setMediaId(StorageSession aStorageSession, Uid aMsUid, int aMediaId) |
684 { |
657 { |
685 // store the jar hash only if the suite was installed on a non-protected media |
658 // store the jar hash only if the suite was installed on a non-protected media |
686 if (isDriveProtected(aMediaId)) |
659 if (isDriveProtected(aMediaId)) |
687 { |
660 { |
688 AuthenticationStorageData authStorageData = |
661 SecurityStorage storage = new SecurityStorage(aStorageSession); |
689 (AuthenticationStorageData)iSelectedAuthCredentials.get( |
662 try |
690 aMsUid); |
663 { |
691 if (authStorageData != null) |
664 AuthenticationStorageData authStorageData = |
692 { |
665 (AuthenticationStorageData)iSelectedAuthCredentials.get( |
693 Logger.log("Suite installed on protected media -> the runtime tamper detection is disabled"); |
666 aMsUid); |
694 authStorageData.setJarHashValue(null); |
667 if (authStorageData != null) |
695 iSelectedAuthCredentials.put(aMsUid, authStorageData); |
668 { |
696 } |
669 Logger.log("Suite installed on protected media -> the runtime tamper detection is disabled"); |
|
670 authStorageData.setJarHashValue(null); |
|
671 storage.writeAuthenticationStorageData(aMsUid, |
|
672 authStorageData, |
|
673 true /* this is an update */); |
|
674 } |
|
675 } |
|
676 finally |
|
677 { |
|
678 iSelectedAuthCredentials.remove(aMsUid); |
|
679 } |
|
680 |
697 } |
681 } |
698 } |
682 } |
699 |
683 |
700 /** |
684 /** |
701 * Setter for the OCSP settings |
685 * Setter for the OCSP settings |
839 // do the tamper detection |
823 // do the tamper detection |
840 if (authStorageData.getJarHashValue() != null |
824 if (authStorageData.getJarHashValue() != null |
841 && authStorageData.getJarHashValue().length() > 0) |
825 && authStorageData.getJarHashValue().length() > 0) |
842 { |
826 { |
843 Logger.log(" Doing tamper detection"); |
827 Logger.log(" Doing tamper detection"); |
844 String computedJarHash = null; |
828 String computedJarHash = _computeHash(authStorageData.getJarPath()); |
845 try |
|
846 { |
|
847 computedJarHash = _computeHash(authStorageData.getJarPath()); |
|
848 }catch(AuthenticationException e) |
|
849 { |
|
850 if (e.getErrorCode() |
|
851 == AuthenticationException.JAR_NOT_FOUND) |
|
852 { |
|
853 Logger.logWarning(" Jar not found while trying to compute hash"); |
|
854 throw new RuntimeSecurityException( |
|
855 SecurityErrorMessage.JAR_NOT_FOUND, |
|
856 null, /* no params for short msg */ |
|
857 SecurityDetailedErrorMessage.JAR_NOT_FOUND, |
|
858 null /* no params for detailed msg */); |
|
859 } |
|
860 } |
|
861 // do the tampering check: compute the hash and compare it with the stored hash |
829 // do the tampering check: compute the hash and compare it with the stored hash |
862 if (computedJarHash == null || !computedJarHash.equals( |
830 if (computedJarHash == null || !computedJarHash.equals( |
863 authStorageData.getJarHashValue())) |
831 authStorageData.getJarHashValue())) |
864 { |
832 { |
865 Logger.logWarning(" Application has been tampered"); |
833 Logger.logWarning(" Application has been tampered"); |
1150 } |
1118 } |
1151 |
1119 |
1152 private boolean isDriveProtected(int aMediaId) |
1120 private boolean isDriveProtected(int aMediaId) |
1153 { |
1121 { |
1154 DriveInfo[] allDrives = DriveUtilities.getAllDrives(); |
1122 DriveInfo[] allDrives = DriveUtilities.getAllDrives(); |
1155 boolean driveFound = false; |
|
1156 if (allDrives != null) |
1123 if (allDrives != null) |
1157 { |
1124 { |
1158 for (int i=0; i<allDrives.length; i++) |
1125 for (int i=0; i<allDrives.length; i++) |
1159 { |
1126 { |
1160 if (aMediaId == allDrives[i].iId) |
1127 if (aMediaId == allDrives[i].iId) |