/** * Loads the keystore from the Keychain. * * @param stream Ignored - here for API compatibility. * @param password Ignored - if user needs to unlock keychain Security framework will post any * dialogs. * @exception IOException if there is an I/O or format problem with the keystore data * @exception NoSuchAlgorithmException if the algorithm used to check the integrity of the * keystore cannot be found * @exception CertificateException if any of the certificates in the keystore could not be loaded */ public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { permissionCheck(); // Release any stray keychain references before clearing out the entries. synchronized (entries) { for (Enumeration<String> e = entries.keys(); e.hasMoreElements(); ) { String alias = e.nextElement(); Object entry = entries.get(alias); if (entry instanceof TrustedCertEntry) { if (((TrustedCertEntry) entry).certRef != 0) { _releaseKeychainItemRef(((TrustedCertEntry) entry).certRef); } } else { KeyEntry keyEntry = (KeyEntry) entry; if (keyEntry.chain != null) { for (int i = 0; i < keyEntry.chain.length; i++) { if (keyEntry.chainRefs[i] != 0) { _releaseKeychainItemRef(keyEntry.chainRefs[i]); } } if (keyEntry.keyRef != 0) { _releaseKeychainItemRef(keyEntry.keyRef); } } } } entries.clear(); _scanKeychain(); } }
/** * Returns the (alias) name of the first keystore entry whose certificate matches the given * certificate. * * <p>This method attempts to match the given certificate with each keystore entry. If the entry * being considered is a <i>trusted certificate entry</i>, the given certificate is compared to * that entry's certificate. If the entry being considered is a <i>key entry</i>, the given * certificate is compared to the first element of that entry's certificate chain (if a chain * exists). * * @param cert the certificate to match with. * @return the (alias) name of the first entry with matching certificate, or null if no such entry * exists in this keystore. */ public String engineGetCertificateAlias(Certificate cert) { permissionCheck(); Certificate certElem; for (Enumeration<String> e = entries.keys(); e.hasMoreElements(); ) { String alias = e.nextElement(); Object entry = entries.get(alias); if (entry instanceof TrustedCertEntry) { certElem = ((TrustedCertEntry) entry).cert; } else { KeyEntry ke = (KeyEntry) entry; if (ke.chain == null || ke.chain.length == 0) { continue; } certElem = ke.chain[0]; } if (certElem.equals(cert)) { return alias; } } return null; }
/** * Stores this keystore to the given output stream, and protects its integrity with the given * password. * * @param stream Ignored. the output stream to which this keystore is written. * @param password the password to generate the keystore integrity check * @exception IOException if there was an I/O problem with data * @exception NoSuchAlgorithmException if the appropriate data integrity algorithm could not be * found * @exception CertificateException if any of the certificates included in the keystore data could * not be stored */ public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { permissionCheck(); // Delete items that do have a keychain item ref. for (Enumeration<String> e = deletedEntries.keys(); e.hasMoreElements(); ) { String alias = e.nextElement(); Object entry = deletedEntries.get(alias); if (entry instanceof TrustedCertEntry) { if (((TrustedCertEntry) entry).certRef != 0) { _removeItemFromKeychain(((TrustedCertEntry) entry).certRef); _releaseKeychainItemRef(((TrustedCertEntry) entry).certRef); } } else { Certificate certElem; KeyEntry keyEntry = (KeyEntry) entry; if (keyEntry.chain != null) { for (int i = 0; i < keyEntry.chain.length; i++) { if (keyEntry.chainRefs[i] != 0) { _removeItemFromKeychain(keyEntry.chainRefs[i]); _releaseKeychainItemRef(keyEntry.chainRefs[i]); } } if (keyEntry.keyRef != 0) { _removeItemFromKeychain(keyEntry.keyRef); _releaseKeychainItemRef(keyEntry.keyRef); } } } } // Add all of the certs or keys in the added entries. // No need to check for 0 refs, as they are in the added list. for (Enumeration<String> e = addedEntries.keys(); e.hasMoreElements(); ) { String alias = e.nextElement(); Object entry = addedEntries.get(alias); if (entry instanceof TrustedCertEntry) { TrustedCertEntry tce = (TrustedCertEntry) entry; Certificate certElem; certElem = tce.cert; tce.certRef = addCertificateToKeychain(alias, certElem); } else { KeyEntry keyEntry = (KeyEntry) entry; if (keyEntry.chain != null) { for (int i = 0; i < keyEntry.chain.length; i++) { keyEntry.chainRefs[i] = addCertificateToKeychain(alias, keyEntry.chain[i]); } keyEntry.keyRef = _addItemToKeychain(alias, false, keyEntry.protectedPrivKey, keyEntry.password); } } } // Clear the added and deletedEntries hashtables here, now that we're done with the updates. // For the deleted entries, we freed up the native references above. deletedEntries.clear(); addedEntries.clear(); }