1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.security.cert;
19
20import java.security.InvalidAlgorithmParameterException;
21import java.security.NoSuchAlgorithmException;
22import java.security.NoSuchProviderException;
23import java.security.Provider;
24import java.security.Security;
25import org.apache.harmony.security.fortress.Engine;
26
27/**
28 * This class implements the functionality of a builder for an unverified
29 * <i>Certification Path</i>s from a specified certificate to a trust anchor.
30 */
31public class CertPathBuilder {
32
33    // Store CertPathBuilder service name
34    private static final String SERVICE = "CertPathBuilder";
35
36    // Used to access common engine functionality
37    private static final Engine ENGINE = new Engine(SERVICE);
38
39    // Store default property name
40    private static final String PROPERTYNAME = "certpathbuilder.type";
41
42    // Default value of CertPathBuilder type. It returns if certpathbuild.type
43    // property is not defined in java.security file
44    private static final String DEFAULTPROPERTY = "PKIX";
45
46    // Store used provider
47    private final Provider provider;
48
49    // Store spi implementation
50    private final CertPathBuilderSpi spiImpl;
51
52    // Store algorithm name
53    private final String algorithm;
54
55    /**
56     * Creates a new {@code CertPathBuilder}.
57     *
58     * @param builderSpi
59     *            the implementation delegate.
60     * @param provider
61     *            the provider.
62     * @param algorithm
63     *            the desired algorithm available at the provider.
64     */
65    protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider,
66            String algorithm) {
67        this.provider = provider;
68        this.algorithm = algorithm;
69        this.spiImpl = builderSpi;
70    }
71
72    /**
73     * Returns the algorithm name of this instance.
74     *
75     * @return the algorithm name of this instance.
76     */
77    public final String getAlgorithm() {
78        return algorithm;
79    }
80
81    /**
82     * Returns the provider of this instance.
83     *
84     * @return the provider of this instance.
85     */
86    public final Provider getProvider() {
87        return provider;
88    }
89
90    /**
91     * Creates a new {@code CertPathBuilder} instance with the specified
92     * algorithm.
93     *
94     * @param algorithm
95     *            the name of the algorithm.
96     * @return a builder for the requested algorithm.
97     * @throws NullPointerException
98     *             if the algorithm is {@code null}.
99     * @throws NoSuchAlgorithmException
100     *             if no installed provider can provide the algorithm.
101     */
102    public static CertPathBuilder getInstance(String algorithm)
103            throws NoSuchAlgorithmException {
104        if (algorithm == null) {
105            throw new NullPointerException("algorithm == null");
106        }
107        Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
108        return new CertPathBuilder((CertPathBuilderSpi) sap.spi, sap.provider, algorithm);
109    }
110
111    /**
112     * Creates a new {@code CertPathBuilder} instance from the specified
113     * provider providing the specified algorithm.
114     *
115     * @param algorithm
116     *            the name of the algorithm.
117     * @param provider
118     *            the name of the provider.
119     * @return a builder for the requested algorithm.
120     * @throws NoSuchAlgorithmException
121     *             if the specified provider cannot provide the algorithm.
122     * @throws NoSuchProviderException
123     *             if no provider with the specified name can be found.
124     * @throws NullPointerException
125     *             if algorithm is {@code null}.
126     * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()}
127     */
128    public static CertPathBuilder getInstance(String algorithm, String provider)
129            throws NoSuchAlgorithmException, NoSuchProviderException {
130        if (provider == null || provider.isEmpty()) {
131            throw new IllegalArgumentException("provider == null || provider.isEmpty()");
132        }
133        Provider impProvider = Security.getProvider(provider);
134        if (impProvider == null) {
135            throw new NoSuchProviderException(provider);
136        }
137        return getInstance(algorithm, impProvider);
138
139    }
140
141    /**
142     * Creates a new {@code CertPathBuilder} instance from the specified
143     * provider providing the specified algorithm.
144     *
145     * @param algorithm
146     *            the name of the algorithm.
147     * @param provider
148     *            the provider.
149     * @return a builder for the requested algorithm
150     * @throws NoSuchAlgorithmException
151     *             if the specified provider cannot provide the algorithm.
152     * @throws IllegalArgumentException if {@code provider == null}
153     * @throws NullPointerException
154     *             if algorithm is {@code null}.
155     */
156    public static CertPathBuilder getInstance(String algorithm,
157            Provider provider) throws NoSuchAlgorithmException {
158        if (provider == null) {
159            throw new IllegalArgumentException("provider == null");
160        }
161        if (algorithm == null) {
162            throw new NullPointerException("algorithm == null");
163        }
164        Object spi = ENGINE.getInstance(algorithm, provider, null);
165        return new CertPathBuilder((CertPathBuilderSpi) spi, provider, algorithm);
166    }
167
168    /**
169     * Builds a certification path with the specified algorithm parameters.
170     *
171     * @param params
172     *            the algorithm parameters.
173     * @return the built certification path.
174     * @throws CertPathBuilderException
175     *             if the build fails.
176     * @throws InvalidAlgorithmParameterException
177     *             if the specified parameters cannot be used to build with this
178     *             builder.
179     * @see CertPathBuilderResult
180     */
181    public final CertPathBuilderResult build(CertPathParameters params)
182            throws CertPathBuilderException, InvalidAlgorithmParameterException {
183        return spiImpl.engineBuild(params);
184    }
185
186    /**
187     * Returns the default {@code CertPathBuilder} type from the <i>Security
188     * Properties</i>.
189     *
190     * @return the default {@code CertPathBuilder} type from the <i>Security
191     *         Properties</i>, or the string "{@code PKIX}" if it cannot be
192     *         determined.
193     */
194    public static final String getDefaultType() {
195        String defaultType = Security.getProperty(PROPERTYNAME);
196        return (defaultType != null ? defaultType : DEFAULTPROPERTY);
197    }
198}
199