0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: /**
0019: * @author Vera Y. Petrashkova
0020: * @version $Revision$
0021: */package java.security;
0022:
0023: import java.io.File;
0024: import java.io.FileInputStream;
0025: import java.io.IOException;
0026: import java.io.InputStream;
0027: import java.io.OutputStream;
0028: import java.security.cert.Certificate;
0029: import java.security.cert.CertificateException;
0030: import java.security.cert.X509Certificate;
0031: import java.util.Arrays;
0032: import java.util.Date;
0033: import java.util.Enumeration;
0034:
0035: import javax.crypto.SecretKey;
0036: import javax.security.auth.DestroyFailedException;
0037: import javax.security.auth.Destroyable;
0038: import javax.security.auth.callback.CallbackHandler;
0039:
0040: import org.apache.harmony.security.fortress.Engine;
0041: import org.apache.harmony.security.internal.nls.Messages;
0042:
0043: public class KeyStore {
0044:
0045: // Store KeyStore SERVICE name
0046: private static final String SERVICE = "KeyStore"; //$NON-NLS-1$
0047:
0048: // Used to access common engine functionality
0049: private static Engine engine = new Engine(SERVICE);
0050:
0051: // Store KeyStore property name
0052: private static final String PROPERTYNAME = "keystore.type"; //$NON-NLS-1$
0053:
0054: // Store default KeyStore type
0055: private static final String DEFAULT_KEYSTORE_TYPE = "jks"; //$NON-NLS-1$
0056:
0057: // Message to report about non-initialized key store object
0058: private static final String NOTINITKEYSTORE = Messages
0059: .getString("security.4F"); //$NON-NLS-1$
0060:
0061: // Store KeyStore state (initialized or not)
0062: private boolean isInit;
0063:
0064: // Store used KeyStoreSpi
0065: private final KeyStoreSpi implSpi;
0066:
0067: // Store used provider
0068: private final Provider provider;
0069:
0070: // Store used type
0071: private final String type;
0072:
0073: protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider,
0074: String type) {
0075: this .type = type;
0076: this .provider = provider;
0077: this .implSpi = keyStoreSpi;
0078: isInit = false;
0079: }
0080:
0081: /**
0082: * @throws NullPointerException if type is null
0083: */
0084: public static KeyStore getInstance(String type)
0085: throws KeyStoreException {
0086: if (type == null) {
0087: throw new NullPointerException(Messages
0088: .getString("security.07")); //$NON-NLS-1$
0089: }
0090: synchronized (engine) {
0091: try {
0092: engine.getInstance(type, null);
0093: return new KeyStore((KeyStoreSpi) engine.spi,
0094: engine.provider, type);
0095: } catch (NoSuchAlgorithmException e) {
0096: throw new KeyStoreException(e.getMessage());
0097: }
0098: }
0099: }
0100:
0101: /**
0102: *
0103: *
0104: * @throws NullPointerException if type is null (instead of
0105: * NoSuchAlgorithmException) as in 1.4 release
0106: */
0107: public static KeyStore getInstance(String type, String provider)
0108: throws KeyStoreException, NoSuchProviderException {
0109: if ((provider == null) || (provider.length() == 0)) {
0110: throw new IllegalArgumentException(Messages
0111: .getString("security.02")); //$NON-NLS-1$
0112: }
0113: Provider impProvider = Security.getProvider(provider);
0114: if (impProvider == null) {
0115: throw new NoSuchProviderException(provider);
0116: }
0117: try {
0118: return getInstance(type, impProvider);
0119: } catch (Exception e) {
0120: throw new KeyStoreException(e.getMessage(), e);
0121: }
0122: }
0123:
0124: /**
0125: *
0126: *
0127: * throws NullPointerException if type is null (instead of
0128: * NoSuchAlgorithmException) as in 1.4 release
0129: */
0130: public static KeyStore getInstance(String type, Provider provider)
0131: throws KeyStoreException {
0132: // check parameters
0133: if (provider == null) {
0134: throw new IllegalArgumentException(Messages
0135: .getString("security.04")); //$NON-NLS-1$
0136: }
0137: if (type == null) {
0138: throw new NullPointerException(Messages
0139: .getString("security.07")); //$NON-NLS-1$
0140: }
0141: // return KeyStore instance
0142: synchronized (engine) {
0143: try {
0144: engine.getInstance(type, provider, null);
0145: return new KeyStore((KeyStoreSpi) engine.spi, provider,
0146: type);
0147: } catch (Exception e) {
0148: // override exception
0149: throw new KeyStoreException(e.getMessage());
0150: }
0151: }
0152: }
0153:
0154: /**
0155: *
0156: *
0157: */
0158: public static final String getDefaultType() {
0159: String dt = AccessController
0160: .doPrivileged(new PrivilegedAction<String>() {
0161: public String run() {
0162: return Security.getProperty(PROPERTYNAME);
0163: }
0164: });
0165: return (dt == null ? DEFAULT_KEYSTORE_TYPE : dt);
0166: }
0167:
0168: /**
0169: *
0170: *
0171: */
0172: public final Provider getProvider() {
0173: return provider;
0174: }
0175:
0176: /**
0177: *
0178: *
0179: */
0180: public final String getType() {
0181: return type;
0182: }
0183:
0184: /**
0185: *
0186: *
0187: */
0188: public final Key getKey(String alias, char[] password)
0189: throws KeyStoreException, NoSuchAlgorithmException,
0190: UnrecoverableKeyException {
0191: if (!isInit) {
0192: throw new KeyStoreException(NOTINITKEYSTORE);
0193: }
0194: return implSpi.engineGetKey(alias, password);
0195: }
0196:
0197: /**
0198: *
0199: *
0200: */
0201: public final Certificate[] getCertificateChain(String alias)
0202: throws KeyStoreException {
0203: if (!isInit) {
0204: throw new KeyStoreException(NOTINITKEYSTORE);
0205: }
0206: return implSpi.engineGetCertificateChain(alias);
0207: }
0208:
0209: /**
0210: *
0211: *
0212: */
0213: public final Certificate getCertificate(String alias)
0214: throws KeyStoreException {
0215: if (!isInit) {
0216: throw new KeyStoreException(NOTINITKEYSTORE);
0217: }
0218: return implSpi.engineGetCertificate(alias);
0219: }
0220:
0221: /**
0222: *
0223: *
0224: */
0225: public final Date getCreationDate(String alias)
0226: throws KeyStoreException {
0227: if (!isInit) {
0228: throw new KeyStoreException(NOTINITKEYSTORE);
0229: }
0230: return implSpi.engineGetCreationDate(alias);
0231: }
0232:
0233: /**
0234: *
0235: *
0236: * 1.4.2 and 1.5 releases throw unspecified NullPointerException -
0237: * when alias is null IllegalArgumentException - when password is null
0238: * IllegalArgumentException - when key is instance of PrivateKey and chain
0239: * is null or empty
0240: */
0241: public final void setKeyEntry(String alias, Key key,
0242: char[] password, Certificate[] chain)
0243: throws KeyStoreException {
0244: if (!isInit) {
0245: throw new KeyStoreException(NOTINITKEYSTORE);
0246: }
0247:
0248: // Certificate chain is required for PrivateKey
0249: if (null != key && key instanceof PrivateKey
0250: && (chain == null || chain.length == 0)) {
0251: throw new IllegalArgumentException(Messages
0252: .getString("security.52")); //$NON-NLS-1$
0253: }
0254: implSpi.engineSetKeyEntry(alias, key, password, chain);
0255: }
0256:
0257: /**
0258: *
0259: *
0260: */
0261: public final void setKeyEntry(String alias, byte[] key,
0262: Certificate[] chain) throws KeyStoreException {
0263: if (!isInit) {
0264: throw new KeyStoreException(NOTINITKEYSTORE);
0265: }
0266: implSpi.engineSetKeyEntry(alias, key, chain);
0267: }
0268:
0269: /**
0270: *
0271: *
0272: * 1.4.2 and 1.5 releases throw unspecified NullPointerException
0273: * when alias is null
0274: */
0275: public final void setCertificateEntry(String alias, Certificate cert)
0276: throws KeyStoreException {
0277: if (!isInit) {
0278: throw new KeyStoreException(NOTINITKEYSTORE);
0279: }
0280: implSpi.engineSetCertificateEntry(alias, cert);
0281: }
0282:
0283: /**
0284: *
0285: *
0286: * 1.4.2 and 1.5 releases throw NullPointerException when alias is null
0287: */
0288: public final void deleteEntry(String alias)
0289: throws KeyStoreException {
0290: if (!isInit) {
0291: throw new KeyStoreException(NOTINITKEYSTORE);
0292: }
0293: if (alias == null) {
0294: throw new NullPointerException(Messages
0295: .getString("security.3F")); //$NON-NLS-1$
0296: }
0297: implSpi.engineDeleteEntry(alias);
0298: }
0299:
0300: /**
0301: *
0302: */
0303: public final Enumeration<String> aliases() throws KeyStoreException {
0304: if (!isInit) {
0305: throw new KeyStoreException(NOTINITKEYSTORE);
0306: }
0307: return implSpi.engineAliases();
0308: }
0309:
0310: /**
0311: *
0312: *
0313: * 1.4.2 and 1.5 releases throw unspecified NullPointerException when
0314: * alias is null
0315: */
0316: public final boolean containsAlias(String alias)
0317: throws KeyStoreException {
0318: if (!isInit) {
0319: throw new KeyStoreException(NOTINITKEYSTORE);
0320: }
0321: if (alias == null) {
0322: throw new NullPointerException(Messages
0323: .getString("security.3F")); //$NON-NLS-1$
0324: }
0325: return implSpi.engineContainsAlias(alias);
0326: }
0327:
0328: /**
0329: *
0330: *
0331: */
0332: public final int size() throws KeyStoreException {
0333: if (!isInit) {
0334: throw new KeyStoreException(NOTINITKEYSTORE);
0335: }
0336: return implSpi.engineSize();
0337: }
0338:
0339: /**
0340: *
0341: *
0342: * jdk1.4.2 and 1.5 releases throw unspecified NullPointerException
0343: * when alias is null
0344: */
0345: public final boolean isKeyEntry(String alias)
0346: throws KeyStoreException {
0347: if (!isInit) {
0348: throw new KeyStoreException(NOTINITKEYSTORE);
0349: }
0350: if (alias == null) {
0351: throw new NullPointerException(Messages
0352: .getString("security.3F")); //$NON-NLS-1$
0353: }
0354: return implSpi.engineIsKeyEntry(alias);
0355: }
0356:
0357: /**
0358: *
0359: *
0360: * jdk1.4.2 and 1.5 releases throw unspecified NullPointerException
0361: * when alias is null
0362: */
0363: public final boolean isCertificateEntry(String alias)
0364: throws KeyStoreException {
0365: if (!isInit) {
0366: throw new KeyStoreException(NOTINITKEYSTORE);
0367: }
0368: if (alias == null) {
0369: throw new NullPointerException(Messages
0370: .getString("security.3F")); //$NON-NLS-1$
0371: }
0372: return implSpi.engineIsCertificateEntry(alias);
0373: }
0374:
0375: /**
0376: *
0377: *
0378: */
0379: public final String getCertificateAlias(Certificate cert)
0380: throws KeyStoreException {
0381: if (!isInit) {
0382: throw new KeyStoreException(NOTINITKEYSTORE);
0383: }
0384: return implSpi.engineGetCertificateAlias(cert);
0385: }
0386:
0387: /**
0388: *
0389: *
0390: * throws IOException when stream or password is null
0391: */
0392: public final void store(OutputStream stream, char[] password)
0393: throws KeyStoreException, IOException,
0394: NoSuchAlgorithmException, CertificateException {
0395: if (!isInit) {
0396: throw new KeyStoreException(NOTINITKEYSTORE);
0397: }
0398:
0399: //Just delegate stream and password to implSpi
0400: implSpi.engineStore(stream, password);
0401: }
0402:
0403: /**
0404: *
0405: *
0406: */
0407: public final void store(LoadStoreParameter param)
0408: throws KeyStoreException, IOException,
0409: NoSuchAlgorithmException, CertificateException {
0410: if (!isInit) {
0411: throw new KeyStoreException(NOTINITKEYSTORE);
0412: }
0413: implSpi.engineStore(param);
0414: }
0415:
0416: /**
0417: *
0418: *
0419: */
0420: public final void load(InputStream stream, char[] password)
0421: throws IOException, NoSuchAlgorithmException,
0422: CertificateException {
0423: implSpi.engineLoad(stream, password);
0424: isInit = true;
0425: }
0426:
0427: /**
0428: *
0429: *
0430: */
0431: public final void load(LoadStoreParameter param)
0432: throws IOException, NoSuchAlgorithmException,
0433: CertificateException {
0434: implSpi.engineLoad(param);
0435: isInit = true;
0436: }
0437:
0438: /**
0439: *
0440: *
0441: */
0442: public final Entry getEntry(String alias, ProtectionParameter param)
0443: throws NoSuchAlgorithmException,
0444: UnrecoverableEntryException, KeyStoreException {
0445: if (alias == null) {
0446: throw new NullPointerException(Messages
0447: .getString("security.3F")); //$NON-NLS-1$
0448: }
0449: if (!isInit) {
0450: throw new KeyStoreException(NOTINITKEYSTORE);
0451: }
0452: return implSpi.engineGetEntry(alias, param);
0453: }
0454:
0455: /**
0456: *
0457: *
0458: * 1.5 release throws unspecified NullPointerException when alias or
0459: * entry is null
0460: */
0461: public final void setEntry(String alias, Entry entry,
0462: ProtectionParameter param) throws KeyStoreException {
0463: if (!isInit) {
0464: throw new KeyStoreException(NOTINITKEYSTORE);
0465: }
0466: if (alias == null) {
0467: throw new NullPointerException(Messages
0468: .getString("security.3F")); //$NON-NLS-1$
0469: }
0470: if (entry == null) {
0471: throw new NullPointerException(Messages
0472: .getString("security.39")); //$NON-NLS-1$
0473: }
0474: implSpi.engineSetEntry(alias, entry, param);
0475: }
0476:
0477: /**
0478: *
0479: */
0480: public final boolean entryInstanceOf(String alias,
0481: Class<? extends KeyStore.Entry> entryClass)
0482: throws KeyStoreException {
0483: if (alias == null) {
0484: throw new NullPointerException(Messages
0485: .getString("security.3F")); //$NON-NLS-1$
0486: }
0487: if (entryClass == null) {
0488: throw new NullPointerException(Messages
0489: .getString("security.40")); //$NON-NLS-1$
0490: }
0491:
0492: if (!isInit) {
0493: throw new KeyStoreException(NOTINITKEYSTORE);
0494: }
0495: return implSpi.engineEntryInstanceOf(alias, entryClass);
0496: }
0497:
0498: /**
0499: *
0500: *
0501: *
0502: */
0503: public abstract static class Builder {
0504: /**
0505: *
0506: *
0507: */
0508: protected Builder() {
0509: }
0510:
0511: /**
0512: *
0513: *
0514: */
0515: public abstract KeyStore getKeyStore() throws KeyStoreException;
0516:
0517: /**
0518: *
0519: *
0520: */
0521: public abstract ProtectionParameter getProtectionParameter(
0522: String alise) throws KeyStoreException;
0523:
0524: /**
0525: *
0526: *
0527: */
0528: public static Builder newInstance(KeyStore keyStore,
0529: ProtectionParameter protectionParameter) {
0530: if (keyStore == null) {
0531: throw new NullPointerException(Messages
0532: .getString("security.41")); //$NON-NLS-1$
0533: }
0534: if (protectionParameter == null) {
0535: throw new NullPointerException(Messages
0536: .getString("security.42")); //$NON-NLS-1$
0537: }
0538:
0539: if (!keyStore.isInit) {
0540: throw new IllegalArgumentException(NOTINITKEYSTORE);
0541: }
0542: return new BuilderImpl(keyStore, protectionParameter, null,
0543: null, null, null);
0544: }
0545:
0546: /**
0547: *
0548: *
0549: */
0550: public static Builder newInstance(String type,
0551: Provider provider, File file,
0552: ProtectionParameter protectionParameter) {
0553: // check null parameters
0554: if (type == null) {
0555: throw new NullPointerException(Messages
0556: .getString("security.07")); //$NON-NLS-1$
0557: }
0558: if (protectionParameter == null) {
0559: throw new NullPointerException(Messages
0560: .getString("security.42")); //$NON-NLS-1$
0561: }
0562: if (file == null) {
0563: throw new NullPointerException(Messages
0564: .getString("security.43")); //$NON-NLS-1$
0565: }
0566: // protection parameter should be PasswordProtection or
0567: // CallbackHandlerProtection
0568: if (!(protectionParameter instanceof PasswordProtection)
0569: && !(protectionParameter instanceof CallbackHandlerProtection)) {
0570: throw new IllegalArgumentException(Messages
0571: .getString("security.35")); //$NON-NLS-1$
0572: }
0573: // check file parameter
0574: if (!file.exists()) {
0575: throw new IllegalArgumentException(Messages.getString(
0576: "security.44", file.getName())); //$NON-NLS-1$
0577: }
0578: if (!file.isFile()) {
0579: throw new IllegalArgumentException(Messages.getString(
0580: "security.45", file.getName())); //$NON-NLS-1$
0581: }
0582: // create new instance
0583: return new BuilderImpl(null, protectionParameter, file,
0584: type, provider, AccessController.getContext());
0585: }
0586:
0587: /**
0588: *
0589: *
0590: */
0591: public static Builder newInstance(String type,
0592: Provider provider,
0593: ProtectionParameter protectionParameter) {
0594: if (type == null) {
0595: throw new NullPointerException(Messages
0596: .getString("security.07")); //$NON-NLS-1$
0597: }
0598: if (protectionParameter == null) {
0599: throw new NullPointerException(Messages
0600: .getString("security.42")); //$NON-NLS-1$
0601: }
0602: return new BuilderImpl(null, protectionParameter, null,
0603: type, provider, AccessController.getContext());
0604: }
0605:
0606: /*
0607: * This class is implementation of abstract class KeyStore.Builder
0608: *
0609: * @author Vera Petrashkova
0610: *
0611: */
0612: private static class BuilderImpl extends Builder {
0613: // Store used KeyStore
0614: private KeyStore keyStore;
0615:
0616: // Store used ProtectionParameter
0617: private ProtectionParameter protParameter;
0618:
0619: // Store used KeyStore type
0620: private final String typeForKeyStore;
0621:
0622: // Store used KeyStore provider
0623: private final Provider providerForKeyStore;
0624:
0625: // Store used file for KeyStore loading
0626: private final File fileForLoad;
0627:
0628: // Store getKeyStore method was invoked or not for KeyStoreBuilder
0629: private boolean isGetKeyStore = false;
0630:
0631: // Store last Exception in getKeyStore()
0632: private KeyStoreException lastException;
0633:
0634: // Store AccessControlContext which is used in getKeyStore() method
0635: private final AccessControlContext accControlContext;
0636:
0637: //
0638: // Constructor BuilderImpl initializes private fields: keyStore,
0639: // protParameter, typeForKeyStore providerForKeyStore fileForLoad,
0640: // isGetKeyStore
0641: //
0642: BuilderImpl(KeyStore ks, ProtectionParameter pp, File file,
0643: String type, Provider provider,
0644: AccessControlContext context) {
0645: super ();
0646: keyStore = ks;
0647: protParameter = pp;
0648: fileForLoad = file;
0649: typeForKeyStore = type;
0650: providerForKeyStore = provider;
0651: isGetKeyStore = false;
0652: lastException = null;
0653: accControlContext = context;
0654: }
0655:
0656: //
0657: // Implementation of abstract getKeyStore() method If
0658: // KeyStoreBuilder encapsulates KeyStore object then this object is
0659: // returned
0660: //
0661: // If KeyStoreBuilder encapsulates KeyStore type and provider then
0662: // KeyStore is created using these parameters. If KeyStoreBuilder
0663: // encapsulates file and ProtectionParameter then KeyStore data are
0664: // loaded from FileInputStream that is created on file. If file is
0665: // not defined then KeyStore object is initialized with null
0666: // InputStream and null password.
0667: //
0668: // Result KeyStore object is returned.
0669: //
0670: public synchronized KeyStore getKeyStore()
0671: throws KeyStoreException {
0672: // If KeyStore was created but in final block some exception was
0673: // thrown
0674: // then it was stored in lastException variable and will be
0675: // thrown
0676: // all subsequent calls of this method.
0677: if (lastException != null) {
0678: throw lastException;
0679: }
0680: if (keyStore != null) {
0681: isGetKeyStore = true;
0682: return keyStore;
0683: }
0684:
0685: try {
0686: final KeyStore ks;
0687: final char[] passwd;
0688:
0689: // get KeyStore instance using type or type and provider
0690: ks = (providerForKeyStore == null ? KeyStore
0691: .getInstance(typeForKeyStore) : KeyStore
0692: .getInstance(typeForKeyStore,
0693: providerForKeyStore));
0694: // protection parameter should be PasswordProtection
0695: // or CallbackHandlerProtection
0696: if (protParameter instanceof PasswordProtection) {
0697: passwd = ((PasswordProtection) protParameter)
0698: .getPassword();
0699: } else if (protParameter instanceof CallbackHandlerProtection) {
0700: passwd = KeyStoreSpi
0701: .getPasswordFromCallBack(protParameter);
0702: } else {
0703: throw new KeyStoreException(Messages
0704: .getString("security.35")); //$NON-NLS-1$
0705: }
0706:
0707: // load KeyStore from file
0708: AccessController.doPrivileged(
0709: new PrivilegedExceptionAction<Object>() {
0710: public Object run() throws Exception {
0711: if (fileForLoad != null) {
0712: FileInputStream fis = null;
0713: try {
0714: fis = new FileInputStream(
0715: fileForLoad);
0716: ks.load(fis, passwd);
0717: } finally {
0718: // close file input stream
0719: if (fis != null) {
0720: fis.close();
0721: }
0722: }
0723: } else {
0724: ks.load(new TmpLSParameter(
0725: protParameter));
0726: }
0727: return null;
0728: }
0729: }, accControlContext);
0730:
0731: isGetKeyStore = true;
0732: keyStore = ks;
0733: return keyStore;
0734: } catch (KeyStoreException e) {
0735: // Store exception
0736: throw lastException = e;
0737: } catch (Exception e) {
0738: // Override exception
0739: throw lastException = new KeyStoreException(e);
0740: }
0741: }
0742:
0743: //
0744: // This is implementation of abstract method
0745: // getProtectionParameter(String alias)
0746: //
0747: // Return: ProtectionParameter to get Entry which was saved in
0748: // KeyStore with defined alias
0749: //
0750: public synchronized ProtectionParameter getProtectionParameter(
0751: String alias) throws KeyStoreException {
0752: if (alias == null) {
0753: throw new NullPointerException(Messages
0754: .getString("security.3F")); //$NON-NLS-1$
0755: }
0756: if (!isGetKeyStore) {
0757: throw new IllegalStateException(Messages
0758: .getString("security.46")); //$NON-NLS-1$
0759: }
0760: return protParameter;
0761: }
0762: }
0763:
0764: /*
0765: * Implementation of LoadStoreParameter interface
0766: *
0767: * @author Vera Petrashkova
0768: */
0769: private static class TmpLSParameter implements
0770: LoadStoreParameter {
0771:
0772: // Store used protection parameter
0773: private final ProtectionParameter protPar;
0774:
0775: /**
0776: * Creates TmpLoadStoreParameter object
0777: */
0778: public TmpLSParameter(ProtectionParameter protPar) {
0779: this .protPar = protPar;
0780: }
0781:
0782: /**
0783: * This method returns protection parameter
0784: */
0785: public ProtectionParameter getProtectionParameter() {
0786: return protPar;
0787: }
0788: }
0789: }
0790:
0791: /**
0792: *
0793: *
0794: *
0795: */
0796: public static class CallbackHandlerProtection implements
0797: ProtectionParameter {
0798: // Store CallbackHandler
0799: private final CallbackHandler callbackHandler;
0800:
0801: /**
0802: *
0803: *
0804: */
0805: public CallbackHandlerProtection(CallbackHandler handler) {
0806: if (handler == null) {
0807: throw new NullPointerException(Messages
0808: .getString("security.47")); //$NON-NLS-1$
0809: }
0810: this .callbackHandler = handler;
0811: }
0812:
0813: /**
0814: *
0815: *
0816: */
0817: public CallbackHandler getCallbackHandler() {
0818: return callbackHandler;
0819: }
0820: }
0821:
0822: /**
0823: *
0824: *
0825: *
0826: */
0827: public static interface Entry {
0828: }
0829:
0830: /**
0831: *
0832: *
0833: *
0834: */
0835: public static interface LoadStoreParameter {
0836: /**
0837: *
0838: *
0839: */
0840: public ProtectionParameter getProtectionParameter();
0841: }
0842:
0843: /**
0844: *
0845: *
0846: *
0847: */
0848: public static class PasswordProtection implements
0849: ProtectionParameter, Destroyable {
0850:
0851: // Store password
0852: private char[] password;
0853:
0854: private boolean isDestroyed = false;
0855:
0856: /**
0857: *
0858: *
0859: */
0860: public PasswordProtection(char[] password) {
0861: if (password != null) {
0862: this .password = password.clone();
0863: }
0864: }
0865:
0866: /**
0867: *
0868: *
0869: */
0870: public synchronized char[] getPassword() {
0871: if (isDestroyed) {
0872: throw new IllegalStateException(Messages
0873: .getString("security.36")); //$NON-NLS-1$
0874: }
0875: return password;
0876: }
0877:
0878: /**
0879: *
0880: *
0881: */
0882: public synchronized void destroy()
0883: throws DestroyFailedException {
0884: isDestroyed = true;
0885: if (password != null) {
0886: Arrays.fill(password, '\u0000');
0887: password = null;
0888: }
0889: }
0890:
0891: /**
0892: *
0893: *
0894: */
0895: public synchronized boolean isDestroyed() {
0896: return isDestroyed;
0897: }
0898: }
0899:
0900: /**
0901: *
0902: *
0903: *
0904: */
0905: public static interface ProtectionParameter {
0906: }
0907:
0908: /**
0909: *
0910: *
0911: *
0912: */
0913: public static final class PrivateKeyEntry implements Entry {
0914: // Store Certificate chain
0915: private Certificate[] chain;
0916:
0917: // Store PrivateKey
0918: private PrivateKey privateKey;
0919:
0920: /**
0921: *
0922: *
0923: */
0924: public PrivateKeyEntry(PrivateKey privateKey,
0925: Certificate[] chain) {
0926: if (privateKey == null) {
0927: throw new NullPointerException(Messages
0928: .getString("security.48")); //$NON-NLS-1$
0929: }
0930: if (chain == null) {
0931: throw new NullPointerException(Messages
0932: .getString("security.49")); //$NON-NLS-1$
0933: }
0934:
0935: if (chain.length == 0) {
0936: throw new IllegalArgumentException(Messages
0937: .getString("security.4A")); //$NON-NLS-1$
0938: }
0939: // Match algorithm of private key and algorithm of public key from
0940: // the end certificate
0941: String s = chain[0].getType();
0942: if (!(chain[0].getPublicKey().getAlgorithm())
0943: .equals(privateKey.getAlgorithm())) {
0944: throw new IllegalArgumentException(Messages
0945: .getString("security.4B")); //$NON-NLS-1$
0946: }
0947: // Match certificate types
0948: for (int i = 1; i < chain.length; i++) {
0949: if (!s.equals(chain[i].getType())) {
0950: throw new IllegalArgumentException(Messages
0951: .getString("security.4C")); //$NON-NLS-1$
0952: }
0953: }
0954: // clone chain - this.chain = (Certificate[])chain.clone();
0955: boolean isAllX509Certificates = true;
0956: // assert chain length > 0
0957: for (Certificate cert : chain) {
0958: if (!(cert instanceof X509Certificate)) {
0959: isAllX509Certificates = false;
0960: break;
0961: }
0962: }
0963:
0964: if (isAllX509Certificates) {
0965: this .chain = new X509Certificate[chain.length];
0966: } else {
0967: this .chain = new Certificate[chain.length];
0968: }
0969: System.arraycopy(chain, 0, this .chain, 0, chain.length);
0970: this .privateKey = privateKey;
0971: }
0972:
0973: /**
0974: *
0975: *
0976: */
0977: public PrivateKey getPrivateKey() {
0978: return privateKey;
0979: }
0980:
0981: /**
0982: *
0983: *
0984: */
0985: public Certificate[] getCertificateChain() {
0986: return chain.clone();
0987: }
0988:
0989: /**
0990: *
0991: *
0992: */
0993: public Certificate getCertificate() {
0994: return chain[0];
0995: }
0996:
0997: /**
0998: *
0999: *
1000: */
1001: public String toString() {
1002: StringBuffer sb = new StringBuffer(
1003: "PrivateKeyEntry: number of elements in certificate chain is "); //$NON-NLS-1$
1004: sb.append(Integer.toString(chain.length));
1005: sb.append("\n"); //$NON-NLS-1$
1006: for (int i = 0; i < chain.length; i++) {
1007: sb.append(chain[i].toString());
1008: sb.append("\n"); //$NON-NLS-1$
1009: }
1010: return sb.toString();
1011: }
1012: }
1013:
1014: /**
1015: *
1016: *
1017: *
1018: */
1019: public static final class SecretKeyEntry implements Entry {
1020:
1021: // Store SecretKey
1022: private final SecretKey secretKey;
1023:
1024: /**
1025: *
1026: *
1027: */
1028: public SecretKeyEntry(SecretKey secretKey) {
1029: if (secretKey == null) {
1030: throw new NullPointerException(Messages
1031: .getString("security.4D")); //$NON-NLS-1$
1032: }
1033: this .secretKey = secretKey;
1034: }
1035:
1036: /**
1037: *
1038: *
1039: */
1040: public SecretKey getSecretKey() {
1041: return secretKey;
1042: }
1043:
1044: /**
1045: *
1046: *
1047: */
1048: public String toString() {
1049: StringBuffer sb = new StringBuffer(
1050: "SecretKeyEntry: algorithm - "); //$NON-NLS-1$
1051: sb.append(secretKey.getAlgorithm());
1052: return sb.toString();
1053: }
1054: }
1055:
1056: /**
1057: *
1058: *
1059: *
1060: */
1061: public static final class TrustedCertificateEntry implements Entry {
1062:
1063: // Store trusted Certificate
1064: private final Certificate trustCertificate;
1065:
1066: /**
1067: *
1068: *
1069: */
1070: public TrustedCertificateEntry(Certificate trustCertificate) {
1071: if (trustCertificate == null) {
1072: throw new NullPointerException(Messages
1073: .getString("security.4E")); //$NON-NLS-1$
1074: }
1075: this .trustCertificate = trustCertificate;
1076: }
1077:
1078: /**
1079: *
1080: *
1081: */
1082: public Certificate getTrustedCertificate() {
1083: return trustCertificate;
1084: }
1085:
1086: /**
1087: *
1088: *
1089: */
1090: public String toString() {
1091: return "Trusted certificate entry:\n" + trustCertificate; //$NON-NLS-1$
1092: }
1093: }
1094: }
|