/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package java.security; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.util.Date; import java.util.Enumeration; import javax.crypto.SecretKey; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.PasswordCallback; /** * {@code KeyStoreSpi} is the Service Provider Interface (SPI) definition for * {@link KeyStore}. * * @see KeyStore */ public abstract class KeyStoreSpi { /** * Returns the key with the given alias, using the password to recover the * key from the store. * * @param alias * the alias for the entry. * @param password * the password used to recover the key. * @return the key with the specified alias, or {@code null} if the * specified alias is not bound to an entry. * @throws NoSuchAlgorithmException * if the algorithm for recovering the key is not available. * @throws UnrecoverableKeyException * if the key can not be recovered. */ public abstract Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException; /** * Returns the certificate chain for the entry with the given alias. * * @param alias * the alias for the entry * @return the certificate chain for the entry with the given alias, or * {@code null} if the specified alias is not bound to an entry. */ public abstract Certificate[] engineGetCertificateChain(String alias); /** * Returns the trusted certificate for the entry with the given alias. * * @param alias * the alias for the entry. * @return the trusted certificate for the entry with the given alias, or * {@code null} if the specified alias is not bound to an entry. */ public abstract Certificate engineGetCertificate(String alias); /** * Returns the creation date of the entry with the given alias. * * @param alias * the alias for the entry. * @return the creation date, or {@code null} if the specified alias is not * bound to an entry. */ public abstract Date engineGetCreationDate(String alias); /** * Associates the given alias with the key, password and certificate chain. *
* If the specified alias already exists, it will be reassigned. * * @param alias * the alias for the key. * @param key * the key. * @param password * the password. * @param chain * the certificate chain. * @throws KeyStoreException * if the specified key can not be protected, or if this * operation fails for another reason. * @throws IllegalArgumentException * if {@code key} is a {@code PrivateKey} and {@code chain} does * not contain any certificates. */ public abstract void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException; /** * Associates the given alias with a key and a certificate chain. *
* If the specified alias already exists, it will be reassigned. * * @param alias * the alias for the key. * @param key * the key in an encoded format. * @param chain * the certificate chain. * @throws KeyStoreException * if this operation fails. * @throws IllegalArgumentException * if {@code key} is a {@code PrivateKey} and {@code chain} * does. */ public abstract void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException; /** * Associates the given alias with a certificate. *
* If the specified alias already exists, it will be reassigned.
*
* @param alias
* the alias for the certificate.
* @param cert
* the certificate.
* @throws KeyStoreException
* if an existing alias is not associated to an entry containing
* a trusted certificate, or this method fails for any other
* reason.
*/
public abstract void engineSetCertificateEntry(String alias,
Certificate cert) throws KeyStoreException;
/**
* Deletes the entry identified with the given alias from this {@code
* KeyStoreSpi}.
*
* @param alias
* the alias for the entry.
* @throws KeyStoreException
* if the entry can not be deleted.
*/
public abstract void engineDeleteEntry(String alias)
throws KeyStoreException;
/**
* Returns an {@code Enumeration} over all alias names stored in this
* {@code KeyStoreSpi}.
*
* @return an {@code Enumeration} over all alias names stored in this
* {@code KeyStoreSpi}.
*/
public abstract Enumeration
* If the specified alias already exists, it will be reassigned.
*
* @param alias
* the alias for the entry.
* @param entry
* the entry to store.
* @param protParam
* the {@code ProtectionParameter} to protect the entry.
* @throws KeyStoreException
* if this operation fails.
*/
public void engineSetEntry(String alias, KeyStore.Entry entry,
KeyStore.ProtectionParameter protParam) throws KeyStoreException {
if (entry == null) {
throw new KeyStoreException("entry == null");
}
if (engineContainsAlias(alias)) {
engineDeleteEntry(alias);
}
if (entry instanceof KeyStore.TrustedCertificateEntry) {
KeyStore.TrustedCertificateEntry trE = (KeyStore.TrustedCertificateEntry) entry;
engineSetCertificateEntry(alias, trE.getTrustedCertificate());
return;
}
char[] passW = null;
if (protParam != null) {
if (protParam instanceof KeyStore.PasswordProtection) {
try {
passW = ((KeyStore.PasswordProtection) protParam).getPassword();
} catch (IllegalStateException ee) {
throw new KeyStoreException("Password was destroyed", ee);
}
} else if (protParam instanceof KeyStore.CallbackHandlerProtection) {
try {
passW = getPasswordFromCallBack(protParam);
} catch (Exception e) {
throw new KeyStoreException(e);
}
} else {
throw new KeyStoreException("protParam should be PasswordProtection or "
+ "CallbackHandlerProtection");
}
}
if (entry instanceof KeyStore.PrivateKeyEntry) {
KeyStore.PrivateKeyEntry prE = (KeyStore.PrivateKeyEntry) entry;
engineSetKeyEntry(alias, prE.getPrivateKey(), passW, prE
.getCertificateChain());
return;
}
if (entry instanceof KeyStore.SecretKeyEntry) {
KeyStore.SecretKeyEntry skE = (KeyStore.SecretKeyEntry) entry;
engineSetKeyEntry(alias, skE.getSecretKey(), passW, null);
// engineSetKeyEntry(alias, skE.getSecretKey().getEncoded(), null);
return;
}
throw new KeyStoreException("Entry object is neither PrivateKeyObject nor SecretKeyEntry "
+ "nor TrustedCertificateEntry: " + entry);
}
/**
* Indicates whether the entry for the given alias is assignable to the
* provided {@code Class}.
*
* @param alias
* the alias for the entry.
* @param entryClass
* the type of the entry.
* @return {@code true} if the {@code Entry} for the alias is assignable to
* the specified {@code entryClass}.
*/
public boolean engineEntryInstanceOf(String alias,
Class extends KeyStore.Entry> entryClass) {
if (!engineContainsAlias(alias)) {
return false;
}
try {
if (engineIsCertificateEntry(alias)) {
return entryClass
.isAssignableFrom(Class
.forName("java.security.KeyStore$TrustedCertificateEntry"));
}
if (engineIsKeyEntry(alias)) {
if (entryClass.isAssignableFrom(Class
.forName("java.security.KeyStore$PrivateKeyEntry"))) {
return engineGetCertificate(alias) != null;
}
if (entryClass.isAssignableFrom(Class
.forName("java.security.KeyStore$SecretKeyEntry"))) {
return engineGetCertificate(alias) == null;
}
}
} catch (ClassNotFoundException ignore) {}
return false;
}
/*
* This method returns password which is encapsulated in
* CallbackHandlerProtection object If there is no implementation of
* CallbackHandler then this method returns null
*/
static char[] getPasswordFromCallBack(KeyStore.ProtectionParameter protParam)
throws UnrecoverableEntryException {
if (protParam == null) {
return null;
}
if (!(protParam instanceof KeyStore.CallbackHandlerProtection)) {
throw new UnrecoverableEntryException("Incorrect ProtectionParameter");
}
String clName = Security.getProperty("auth.login.defaultCallbackHandler");
if (clName == null) {
throw new UnrecoverableEntryException("Default CallbackHandler was not defined");
}
try {
Class> cl = Class.forName(clName);
CallbackHandler cbHand = (CallbackHandler) cl.newInstance();
PasswordCallback[] pwCb = { new PasswordCallback("password: ", true) };
cbHand.handle(pwCb);
return pwCb[0].getPassword();
} catch (Exception e) {
throw new UnrecoverableEntryException(e.toString());
}
}
}