<commit_before>/*
 * 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 org.apache.jmeter.util.keystore;

import java.io.InputStream;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;

/**
 * Use this Keystore for JMeter specific KeyStores.
 *
 */
public abstract class JmeterKeyStore {

    /**
     * Process the input stream
     */
    public abstract void load(InputStream is, String password) throws Exception;

    /**
     * Get the ordered certificate chain for a specific alias.
     */
    public abstract X509Certificate[] getCertificateChain(String alias);

    /**
     * Get the next or only alias.
     * @return the next or only alias.
     */
    public abstract String getAlias();

    public abstract int getAliasCount();

    public abstract String getAlias(int index);

    /**
     * Return the private Key for a specific alias
     */
    public abstract PrivateKey getPrivateKey(String alias);

    public static final JmeterKeyStore getInstance(String type) throws Exception {
        // JAVA 1.4 now handles all keystore types, so just use default
        return new DefaultKeyStore(type);
    }
    
    /**
     * @param startIndex the startIndex to set
     */
    public abstract void setAliasStartIndex(int startIndex);

    /**
     * @return the endIndex
     */
    public abstract int getAliasEndIndex();

    /**
     * @param endIndex the endIndex to set
     */
    public abstract void setAliasEndIndex(int endIndex);
    
    /**
     * @return int index of start alias in keystore
     */
    public abstract int getAliasStartIndex();
}<commit_msg>Bug 52131 - Eliminate DefaultKeyStore and simplify code - part 1<commit_after>/*
 * 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 org.apache.jmeter.util.keystore;

import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;

import org.apache.jmeter.util.JMeterUtils;

/**
 * Use this Keystore for JMeter specific KeyStores.
 *
 */
public class JmeterKeyStore {

    private X509Certificate[][] certChains;
    private PrivateKey[] keys;
    private String[] names;
    protected final KeyStore store;
    private int last_user;
    protected static final String KEY_STORE_START_INDEX = "https.keyStoreStartIndex";
    protected static final String KEY_STORE_END_INDEX = "https.keyStoreEndIndex";
    protected int startIndex;
    protected int endIndex;

    public JmeterKeyStore(String type) throws Exception {
        this.store = KeyStore.getInstance(type);
        startIndex = JMeterUtils.getPropDefault(KEY_STORE_START_INDEX, 0);
        endIndex = JMeterUtils.getPropDefault(KEY_STORE_END_INDEX, 0);
    }

    /**
     * Process the input stream
     */
    public void load(InputStream is, String pword) throws Exception {
        store.load(is, pword.toCharArray());
    
        ArrayList<String> v_names = new ArrayList<String>();
        ArrayList<PrivateKey> v_keys = new ArrayList<PrivateKey>();
        ArrayList<X509Certificate[]> v_certChains = new ArrayList<X509Certificate[]>();
    
        if (null != is){ // No point checking an empty keystore
            PrivateKey _key = null;
            int index = 0;
            Enumeration<String> aliases = store.aliases();
            while (aliases.hasMoreElements()) {
                String alias = aliases.nextElement();
                if (store.isKeyEntry(alias)) {
                    if ((index >= startIndex && index <= endIndex)) {
                        _key = (PrivateKey) store.getKey(alias, pword.toCharArray());
                        if (null == _key) {
                            throw new Exception("No key found for alias: " + alias); // Should not happen
                        }
                        Certificate[] chain = store.getCertificateChain(alias);
                        if (null == chain) {
                            throw new Exception("No certificate chain found for alias: " + alias);
                        }
                        v_names.add(alias);
                        v_keys.add(_key);
                        X509Certificate[] x509certs = new X509Certificate[chain.length];
                        for (int i = 0; i < x509certs.length; i++) {
                            x509certs[i] = (X509Certificate)chain[i];
                        }
                        v_certChains.add(x509certs);
                    }
                }
                index++;
            }
    
            if (null == _key) {
                throw new Exception("No key(s) found");
            }
        }
    
        /*
         * Note: if is == null, the arrays will be empty
         */
        int v_size = v_names.size();
    
        this.names = new String[v_size];
        this.names = v_names.toArray(names);
    
        this.keys = new PrivateKey[v_size];
        this.keys = v_keys.toArray(keys);
    
        this.certChains = new X509Certificate[v_size][];
        this.certChains = v_certChains.toArray(certChains);
    }


    /**
     * Get the ordered certificate chain for a specific alias.
     */
    public final X509Certificate[] getCertificateChain(String alias) {
        int entry = findAlias(alias);
        if (entry >=0) {
            return this.certChains[entry];
        }
        return null;
    }

    /**
     * Get the next or only alias.
     * @return the next or only alias.
     */
    public final String getAlias() {
        int length = this.names.length;
        if (length == 0) { // i.e. is == null
            return null;
        }
        return this.names[getNextIndex(length)];
    }

    public int getAliasCount() {
        return this.names.length;
    }

    public final String getAlias(int index) {
        int length = this.names.length;
        if (length == 0 && index == 0) { // i.e. is == null
            return null;
        }
        if (index >= length || index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        return this.names[index];
    }

    /**
     * Return the private Key for a specific alias
     */
    public final PrivateKey getPrivateKey(String alias) {
        int entry = findAlias(alias);
        if (entry >=0) {
            return this.keys[entry];
        }
        return null;
    }

    public static final JmeterKeyStore getInstance(String type) throws Exception {
        // JAVA 1.4 now handles all keystore types, so just use default
        return new JmeterKeyStore(type);
    }
    
    /**
     * @param startIndex the startIndex to set
     */
    public void setAliasStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    /**
     * @return the endIndex
     */
    public int getAliasEndIndex() {
        return endIndex;
    }

    /**
     * @param endIndex the endIndex to set
     */
    public void setAliasEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }
    /**
     * @return the startIndex
     */
    public int getAliasStartIndex() {
        return startIndex;
    }

    private int findAlias(String alias) {
        for(int i = 0; i < names.length; i++) {
            if (alias.equals(names[i])){
                return i;
            }
        }
        return -1;
    }

    private int getNextIndex(int length) {
        synchronized(this) {
            last_user ++;
            if (last_user >= length) {
                last_user = 0;
            }
            return last_user;
        }
    }

}
{'fraction_non_alphanumeric': 0.08919156414762741, 'fraction_numerical': 0.008347978910369069, 'mean_word_length': 2.134251290877797, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2141010', 'n_tokens_mistral': 2491, 'n_tokens_neox': 2372, 'n_words': 797}