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.servicemix.soap.handlers.security;
018    
019    import java.io.IOException;
020    import java.io.InputStream;
021    import java.security.GeneralSecurityException;
022    import java.security.Key;
023    import java.security.KeyStore;
024    import java.security.KeyStoreException;
025    import java.security.PrivateKey;
026    import java.security.cert.Certificate;
027    import java.util.Collections;
028    import java.util.Enumeration;
029    import java.util.HashSet;
030    import java.util.List;
031    import java.util.Set;
032    
033    import org.apache.ws.security.components.crypto.CredentialException;
034    import org.springframework.core.io.Resource;
035    
036    public class StandaloneCrypto extends BaseCrypto {
037    
038        private Resource keyStoreUrl;
039        private String keyStoreType;
040        private String keyStorePassword;
041        private KeyStore keyStore;
042        private String keyPassword;
043        
044        /**
045         * @return the keyPassword
046         */
047        public String getKeyPassword() {
048            return keyPassword;
049        }
050    
051        /**
052         * @param keyPassword the keyPassword to set
053         */
054        public void setKeyPassword(String keyPassword) {
055            this.keyPassword = keyPassword;
056        }
057    
058        /**
059         * @return the keyStorePassword
060         */
061        public String getKeyStorePassword() {
062            return keyStorePassword;
063        }
064    
065        /**
066         * @param keyStorePassword the keyStorePassword to set
067         */
068        public void setKeyStorePassword(String keyStorePassword) {
069            this.keyStorePassword = keyStorePassword;
070        }
071    
072        /**
073         * @return the keyStoreType
074         */
075        public String getKeyStoreType() {
076            return keyStoreType;
077        }
078    
079        /**
080         * @param keyStoreType the keyStoreType to set
081         */
082        public void setKeyStoreType(String keyStoreType) {
083            this.keyStoreType = keyStoreType;
084        }
085    
086        /**
087         * @return the keyStoreUrl
088         */
089        public Resource getKeyStoreUrl() {
090            return keyStoreUrl;
091        }
092    
093        /**
094         * @param keyStoreUrl the keyStoreUrl to set
095         */
096        public void setKeyStoreUrl(Resource keyStoreUrl) {
097            this.keyStoreUrl = keyStoreUrl;
098        }
099    
100        protected String[] getAliases() throws KeyStoreException {
101            List aliases = Collections.list(loadKeyStore().aliases());
102            return (String[]) aliases.toArray(new String[aliases.size()]);
103        }
104    
105        protected Certificate getCertificate(String alias) throws KeyStoreException {
106            return loadKeyStore().getCertificate(alias);
107        }
108    
109        protected String getCertificateAlias(Certificate cert) throws KeyStoreException {
110            return loadKeyStore().getCertificateAlias(cert);
111        }
112    
113        protected Certificate[] getCertificateChain(String alias) throws KeyStoreException {
114            return loadKeyStore().getCertificateChain(alias);
115        }
116    
117        public PrivateKey getPrivateKey(String alias, String password) throws Exception {
118            // The password given here is a dummy password
119            // See WSSecurityHandler.DefaultHandler#processSignature
120            password = keyPassword;
121            if (password == null) {
122                password = keyStorePassword;
123            }
124            if (alias == null) {
125                throw new Exception("alias is null");
126            }
127            KeyStore keystore = loadKeyStore();
128            boolean b = keystore.isKeyEntry(alias);
129            if (!b) {
130                throw new Exception("Cannot find key for alias: " + alias);
131            }
132            Key keyTmp = keystore.getKey(alias, (password == null || password.length() == 0) ? new char[0] : password.toCharArray());
133            if (!(keyTmp instanceof PrivateKey)) {
134                throw new Exception("Key is not a private key, alias: " + alias);
135            }
136            return (PrivateKey) keyTmp;
137        }
138    
139        protected String[] getTrustCertificates() throws KeyStoreException {
140            KeyStore keystore = loadKeyStore();
141            Set hashSet = new HashSet();
142            Enumeration aliases = keystore.aliases();
143            while (aliases.hasMoreElements()) {
144                String alias = (String) aliases.nextElement();
145                if (keystore.isCertificateEntry(alias)) {
146                    hashSet.add(alias);
147                }
148            }
149            return (String[]) hashSet.toArray(new String[hashSet.size()]);
150        }
151        
152        /**
153         * Loads the the keystore.
154         *
155         * @throws CredentialException
156         */
157        public synchronized KeyStore loadKeyStore() throws KeyStoreException {
158            if (keyStore != null) {
159                return keyStore;
160            }
161            if (keyStoreUrl == null) {
162                throw new IllegalArgumentException("keyStoreUrl not specified in this StandaloneCrypto");
163            }
164            InputStream input = null;
165            try {
166                input = keyStoreUrl.getInputStream();
167                String provider = getProvider();
168                String type = keyStoreType != null ? keyStoreType : KeyStore.getDefaultType();
169                if (provider == null || provider.length() == 0) {
170                    keyStore = KeyStore.getInstance(type);
171                } else {
172                    keyStore = KeyStore.getInstance(type, provider);
173                }
174                keyStore.load(input, (keyStorePassword == null || keyStorePassword.length() == 0) ? new char[0] : keyStorePassword.toCharArray());
175                return keyStore;
176            } catch (IOException e) {
177                throw new KeyStoreException(e);
178            } catch (GeneralSecurityException e) {
179                throw new KeyStoreException(e);
180            } catch (Exception e) {
181                throw new KeyStoreException(e);
182            } finally {
183                if (input != null) {
184                    try { input.close(); } catch (Exception ignore) {} 
185                }
186            }
187        }
188    
189    }