001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.crypto;
018
019 import java.io.ByteArrayInputStream;
020 import java.io.ByteArrayOutputStream;
021 import java.io.IOException;
022 import java.security.KeyStore;
023 import java.security.Provider;
024 import java.security.Security;
025 import java.security.cert.Certificate;
026 import java.security.cert.CertificateFactory;
027 import java.util.Collections;
028 import java.util.HashSet;
029 import java.util.Set;
030 import java.util.TreeSet;
031
032 /**
033 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
034 */
035 public class KeystoreUtil {
036 /**
037 * All KeyStore types available.
038 */
039 public static final Set<String> keystoreTypes;
040 /**
041 * The keystore types which allow an empty keystore saved to disk.
042 */
043 public static final Set<String> emptyKeystoreTypes;
044 /**
045 * The keystore types which allow certificate entries.
046 */
047 public static final Set<String> certKeystoreTypes;
048 /**
049 * The default keystore type.
050 */
051 public static final String defaultType;
052
053 static {
054 Set<String> ignoreKeystores = new HashSet<String>();
055 ignoreKeystores.add("windows-my");
056 ignoreKeystores.add("windows-root");
057
058 TreeSet<String> tempKeystoreTypes = new TreeSet<String>();
059 TreeSet<String> tempEmptyKeystoreTypes = new TreeSet<String>();
060 TreeSet<String> tempCertKeystoreTypes = new TreeSet<String>();
061 String tempDefaultType = null;
062 Provider[] providers = Security.getProviders();
063 char[] password = "emptypassword".toCharArray();
064
065 // Certificate used to check if a keystore allows storing trusted
066 String sampleCertText = "-----BEGIN CERTIFICATE-----\n"
067 +"MIIBpzCCAVECBgEV+CystzANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQDEwJNZTEQMA4GA1UECxMH\n"
068 +"TXkgVW5pdDEPMA0GA1UEChMGTXkgT3JnMRAwDgYDVQQHEwdNeSBDaXR5MQswCQYDVQQIEwJBUDEL\n"
069 +"MAkGA1UEBhMCSU4wHhcNMDcxMDMxMjIyNjU4WhcNMTcxMDI4MjIyNjU4WjBcMQswCQYDVQQDEwJN\n"
070 +"ZTEQMA4GA1UECxMHTXkgVW5pdDEPMA0GA1UEChMGTXkgT3JnMRAwDgYDVQQHEwdNeSBDaXR5MQsw\n"
071 +"CQYDVQQIEwJBUDELMAkGA1UEBhMCSU4wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAlN7IscUYq5U9\n"
072 +"d1TYVJaj5RQJLg39Gz9R9hB0hhOULSHOxeE0utTJvgBQcf+f39FgbGIdriJniyoubtCXGfSpxwID\n"
073 +"AQABMA0GCSqGSIb3DQEBBAUAA0EACQN6ScbxzAjrrQ3Ciy8I7/qsgpQo4Nuhfo5cAU4rvcKnujs6\n"
074 +"uGHAJrHMF/ROGl6kPZvFeoGXk5qjyKs8Kx5MJA==\n"
075 +"-----END CERTIFICATE-----";
076 Certificate sampleCert = null;
077
078 try {
079 CertificateFactory certFac = CertificateFactory.getInstance("X.509");
080 sampleCert = certFac.generateCertificate(new ByteArrayInputStream(sampleCertText.getBytes()));
081 } catch (Throwable ignored) {
082 }
083 for(Provider provider: providers) {
084 for(Provider.Service service: provider.getServices()) {
085 String type = service.getAlgorithm();
086 if (service.getType().equals("KeyStore") &&
087 !ignoreKeystores.contains(type.toLowerCase())) {
088
089 tempKeystoreTypes.add(type);
090 if(type.equalsIgnoreCase(KeyStore.getDefaultType())) {
091 tempDefaultType = type;
092 }
093
094 ByteArrayOutputStream baos = null;
095 KeyStore ks = null;
096 try {
097 ks = KeyStore.getInstance(type);
098 ks.load(null);
099 baos = new ByteArrayOutputStream();
100 // Check if an empty keystore can be saved.
101 ks.store(baos, password);
102 tempEmptyKeystoreTypes.add(type);
103 } catch(Throwable ignored) {
104 } finally {
105 if(baos != null) {
106 try {baos.close();} catch(IOException ignored){}
107 }
108 }
109
110 try {
111 // Check if the keystore allows storing of certificate entries.
112 ks.setCertificateEntry("samplecert", sampleCert);
113 tempCertKeystoreTypes.add(type);
114 } catch(Throwable ignored) {
115 }
116 }
117 }
118 }
119
120 keystoreTypes = Collections.unmodifiableSortedSet(tempKeystoreTypes);
121 emptyKeystoreTypes = Collections.unmodifiableSortedSet(tempEmptyKeystoreTypes);
122 certKeystoreTypes = Collections.unmodifiableSortedSet(tempCertKeystoreTypes);
123 defaultType = tempDefaultType;
124 }
125 }