1 module hunt.security.AlgorithmParameters;
2 
3 import hunt.security.spec.AlgorithmParameterSpec;
4 import hunt.security.Provider;
5 
6 import hunt.Exceptions;
7 
8 import std.array;
9 
10 /**
11  * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
12  * for the {@code AlgorithmParameters} class, which is used to manage
13  * algorithm parameters.
14  *
15  * <p> All the abstract methods in this class must be implemented by each
16  * cryptographic service provider who wishes to supply parameter management
17  * for a particular algorithm.
18  *
19  * @author Jan Luehe
20  *
21  *
22  * @see AlgorithmParameters
23  * @see java.security.spec.AlgorithmParameterSpec
24  * @see java.security.spec.DSAParameterSpec
25  *
26  * @since 1.2
27  */
28 
29 abstract class AlgorithmParametersSpi {
30 
31     /**
32      * Initializes this parameters object using the parameters
33      * specified in {@code paramSpec}.
34      *
35      * @param paramSpec the parameter specification.
36      *
37      * @exception InvalidParameterSpecException if the given parameter
38      * specification is inappropriate for the initialization of this parameter
39      * object.
40      */
41     protected abstract void engineInit(AlgorithmParameterSpec paramSpec);
42 
43     /**
44      * Imports the specified parameters and decodes them
45      * according to the primary decoding format for parameters.
46      * The primary decoding format for parameters is ASN.1, if an ASN.1
47      * specification for this type of parameters exists.
48      *
49      * @param params the encoded parameters.
50      *
51      * @exception IOException on decoding errors
52      */
53     protected abstract void engineInit(byte[] params)
54         ;
55 
56     /**
57      * Imports the parameters from {@code params} and
58      * decodes them according to the specified decoding format.
59      * If {@code format} is null, the
60      * primary decoding format for parameters is used. The primary decoding
61      * format is ASN.1, if an ASN.1 specification for these parameters
62      * exists.
63      *
64      * @param params the encoded parameters.
65      *
66      * @param format the name of the decoding format.
67      *
68      * @exception IOException on decoding errors
69      */
70     protected abstract void engineInit(byte[] params, string format)
71         ;
72 
73     /**
74      * Returns a (transparent) specification of this parameters
75      * object.
76      * {@code paramSpec} identifies the specification class in which
77      * the parameters should be returned. It could, for example, be
78      * {@code DSAParameterSpec.class}, to indicate that the
79      * parameters should be returned in an instance of the
80      * {@code DSAParameterSpec} class.
81      *
82      * @param <T> the type of the parameter specification to be returned
83      *
84      * @param paramSpec the specification class in which
85      * the parameters should be returned.
86      *
87      * @return the parameter specification.
88      *
89      * @exception InvalidParameterSpecException if the requested parameter
90      * specification is inappropriate for this parameter object.
91      */
92     // protected abstract
93     //     <T extends AlgorithmParameterSpec>
94     //     T engineGetParameterSpec(Class<T> paramSpec);
95 
96     /**
97      * Returns the parameters in their primary encoding format.
98      * The primary encoding format for parameters is ASN.1, if an ASN.1
99      * specification for this type of parameters exists.
100      *
101      * @return the parameters encoded using their primary encoding format.
102      *
103      * @exception IOException on encoding errors.
104      */
105     protected abstract byte[] engineGetEncoded() ;
106 
107     /**
108      * Returns the parameters encoded in the specified format.
109      * If {@code format} is null, the
110      * primary encoding format for parameters is used. The primary encoding
111      * format is ASN.1, if an ASN.1 specification for these parameters
112      * exists.
113      *
114      * @param format the name of the encoding format.
115      *
116      * @return the parameters encoded using the specified encoding scheme.
117      *
118      * @exception IOException on encoding errors.
119      */
120     protected abstract byte[] engineGetEncoded(string format);
121 
122     /**
123      * Returns a formatted string describing the parameters.
124      *
125      * @return a formatted string describing the parameters.
126      */
127     protected abstract string engineToString();
128 }
129 
130 
131 /**
132  * This class is used as an opaque representation of cryptographic parameters.
133  *
134  * <p>An {@code AlgorithmParameters} object for managing the parameters
135  * for a particular algorithm can be obtained by
136  * calling one of the {@code getInstance} factory methods
137  * (static methods that return instances of a given class).
138  *
139  * <p>Once an {@code AlgorithmParameters} object is obtained, it must be
140  * initialized via a call to {@code init}, using an appropriate parameter
141  * specification or parameter encoding.
142  *
143  * <p>A transparent parameter specification is obtained from an
144  * {@code AlgorithmParameters} object via a call to
145  * {@code getParameterSpec}, and a byte encoding of the parameters is
146  * obtained via a call to {@code getEncoded}.
147  *
148  * <p> Every implementation of the Java platform is required to support the
149  * following standard {@code AlgorithmParameters} algorithms:
150  * <ul>
151  * <li>{@code AES}</li>
152  * <li>{@code DES}</li>
153  * <li>{@code DESede}</li>
154  * <li>{@code DiffieHellman}</li>
155  * <li>{@code DSA}</li>
156  * </ul>
157  * These algorithms are described in the <a href=
158  * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
159  * AlgorithmParameters section</a> of the
160  * Java Cryptography Architecture Standard Algorithm Name Documentation.
161  * Consult the release documentation for your implementation to see if any
162  * other algorithms are supported.
163  *
164  * @author Jan Luehe
165  *
166  *
167  * @see java.security.spec.AlgorithmParameterSpec
168  * @see java.security.spec.DSAParameterSpec
169  * @see KeyPairGenerator
170  *
171  * @since 1.2
172  */
173 
174 class AlgorithmParameters {
175 
176     // The provider
177     private Provider provider;
178 
179     // The provider implementation (delegate)
180     private AlgorithmParametersSpi paramSpi;
181 
182     // The algorithm
183     private string algorithm;
184 
185     // Has this object been initialized?
186     private bool initialized = false;
187 
188     /**
189      * Creates an AlgorithmParameters object.
190      *
191      * @param paramSpi the delegate
192      * @param provider the provider
193      * @param algorithm the algorithm
194      */
195     protected this(AlgorithmParametersSpi paramSpi,
196                                   Provider provider, string algorithm)
197     {
198         this.paramSpi = paramSpi;
199         this.provider = provider;
200         this.algorithm = algorithm;
201     }
202 
203     /**
204      * Returns the name of the algorithm associated with this parameter object.
205      *
206      * @return the algorithm name.
207      */
208     final string getAlgorithm() {
209         return this.algorithm;
210     }
211 
212     /**
213      * Returns a parameter object for the specified algorithm.
214      *
215      * <p> This method traverses the list of registered security Providers,
216      * starting with the most preferred Provider.
217      * A new AlgorithmParameters object encapsulating the
218      * AlgorithmParametersSpi implementation from the first
219      * Provider that supports the specified algorithm is returned.
220      *
221      * <p> Note that the list of registered providers may be retrieved via
222      * the {@link Security#getProviders() Security.getProviders()} method.
223      *
224      * <p> The returned parameter object must be initialized via a call to
225      * {@code init}, using an appropriate parameter specification or
226      * parameter encoding.
227      *
228      * @param algorithm the name of the algorithm requested.
229      * See the AlgorithmParameters section in the <a href=
230      * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
231      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
232      * for information about standard algorithm names.
233      *
234      * @return the new parameter object.
235      *
236      * @exception NoSuchAlgorithmException if no Provider supports an
237      *          AlgorithmParametersSpi implementation for the
238      *          specified algorithm.
239      *
240      * @see Provider
241      */
242     static AlgorithmParameters getInstance(string algorithm) {
243         try {
244             // Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
245             //                                  (string)null);
246             // return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
247             //                                (Provider)objs[1],
248             //                                algorithm);
249             implementationMissing();
250             AlgorithmParametersSpi p;      
251             return new AlgorithmParameters(p, null, algorithm);
252         } catch(NoSuchProviderException e) {
253             throw new NoSuchAlgorithmException(algorithm ~ " not found");
254         }
255     }
256 
257     /**
258      * Returns a parameter object for the specified algorithm.
259      *
260      * <p> A new AlgorithmParameters object encapsulating the
261      * AlgorithmParametersSpi implementation from the specified provider
262      * is returned.  The specified provider must be registered
263      * in the security provider list.
264      *
265      * <p> Note that the list of registered providers may be retrieved via
266      * the {@link Security#getProviders() Security.getProviders()} method.
267      *
268      * <p>The returned parameter object must be initialized via a call to
269      * {@code init}, using an appropriate parameter specification or
270      * parameter encoding.
271      *
272      * @param algorithm the name of the algorithm requested.
273      * See the AlgorithmParameters section in the <a href=
274      * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
275      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
276      * for information about standard algorithm names.
277      *
278      * @param provider the name of the provider.
279      *
280      * @return the new parameter object.
281      *
282      * @exception NoSuchAlgorithmException if an AlgorithmParametersSpi
283      *          implementation for the specified algorithm is not
284      *          available from the specified provider.
285      *
286      * @exception NoSuchProviderException if the specified provider is not
287      *          registered in the security provider list.
288      *
289      * @exception IllegalArgumentException if the provider name is null
290      *          or empty.
291      *
292      * @see Provider
293      */
294     // static AlgorithmParameters getInstance(string algorithm,
295     //                                               string provider)
296     // {
297     //     // if (provider.empty)
298     //     //     throw new IllegalArgumentException("missing provider");
299     //     // Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
300     //     //                                  provider);
301     //     return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
302     //                                    (Provider)objs[1],
303     //                                    algorithm);
304     // }
305 
306     /**
307      * Returns a parameter object for the specified algorithm.
308      *
309      * <p> A new AlgorithmParameters object encapsulating the
310      * AlgorithmParametersSpi implementation from the specified Provider
311      * object is returned.  Note that the specified Provider object
312      * does not have to be registered in the provider list.
313      *
314      * <p>The returned parameter object must be initialized via a call to
315      * {@code init}, using an appropriate parameter specification or
316      * parameter encoding.
317      *
318      * @param algorithm the name of the algorithm requested.
319      * See the AlgorithmParameters section in the <a href=
320      * "{@docRoot}/../technotes/guides/security/StandardNames.html#AlgorithmParameters">
321      * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
322      * for information about standard algorithm names.
323      *
324      * @param provider the name of the provider.
325      *
326      * @return the new parameter object.
327      *
328      * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi
329      *          implementation for the specified algorithm is not available
330      *          from the specified Provider object.
331      *
332      * @exception IllegalArgumentException if the provider is null.
333      *
334      * @see Provider
335      *
336      * @since 1.4
337      */
338     // static AlgorithmParameters getInstance(string algorithm,
339     //                                               Provider provider)
340     // {
341     //     if (provider is null)
342     //         throw new IllegalArgumentException("missing provider");
343     //     Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
344     //                                      provider);
345     //     return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
346     //                                    (Provider)objs[1],
347     //                                    algorithm);
348     // }
349 
350     /**
351      * Returns the provider of this parameter object.
352      *
353      * @return the provider of this parameter object
354      */
355     final Provider getProvider() {
356         return this.provider;
357     }
358 
359     /**
360      * Initializes this parameter object using the parameters
361      * specified in {@code paramSpec}.
362      *
363      * @param paramSpec the parameter specification.
364      *
365      * @exception InvalidParameterSpecException if the given parameter
366      * specification is inappropriate for the initialization of this parameter
367      * object, or if this parameter object has already been initialized.
368      */
369     final void initilize(AlgorithmParameterSpec paramSpec)
370     {
371         if (this.initialized)
372             // throw new InvalidParameterSpecException("already initialized");
373             throw new Exception("already initialized");
374         paramSpi.engineInit(paramSpec);
375         this.initialized = true;
376     }
377 
378     /**
379      * Imports the specified parameters and decodes them according to the
380      * primary decoding format for parameters. The primary decoding
381      * format for parameters is ASN.1, if an ASN.1 specification for this type
382      * of parameters exists.
383      *
384      * @param params the encoded parameters.
385      *
386      * @exception IOException on decoding errors, or if this parameter object
387      * has already been initialized.
388      */
389     final void initilize(byte[] params) {
390         if (this.initialized)
391             throw new IOException("already initialized");
392         paramSpi.engineInit(params);
393         this.initialized = true;
394     }
395 
396     /**
397      * Imports the parameters from {@code params} and decodes them
398      * according to the specified decoding scheme.
399      * If {@code format} is null, the
400      * primary decoding format for parameters is used. The primary decoding
401      * format is ASN.1, if an ASN.1 specification for these parameters
402      * exists.
403      *
404      * @param params the encoded parameters.
405      *
406      * @param format the name of the decoding scheme.
407      *
408      * @exception IOException on decoding errors, or if this parameter object
409      * has already been initialized.
410      */
411     final void initilize(byte[] params, string format) {
412         if (this.initialized)
413             throw new IOException("already initialized");
414         paramSpi.engineInit(params, format);
415         this.initialized = true;
416     }
417 
418     /**
419      * Returns a (transparent) specification of this parameter object.
420      * {@code paramSpec} identifies the specification class in which
421      * the parameters should be returned. It could, for example, be
422      * {@code DSAParameterSpec.class}, to indicate that the
423      * parameters should be returned in an instance of the
424      * {@code DSAParameterSpec} class.
425      *
426      * @param <T> the type of the parameter specification to be returrned
427      * @param paramSpec the specification class in which
428      * the parameters should be returned.
429      *
430      * @return the parameter specification.
431      *
432      * @exception InvalidParameterSpecException if the requested parameter
433      * specification is inappropriate for this parameter object, or if this
434      * parameter object has not been initialized.
435      */
436     // final <T extends AlgorithmParameterSpec>
437     //     T getParameterSpec(Class<T> paramSpec)
438     //     throws InvalidParameterSpecException
439     // {
440     //     if (this.initialized == false) {
441     //         throw new InvalidParameterSpecException("not initialized");
442     //     }
443     //     return paramSpi.engineGetParameterSpec(paramSpec);
444     // }
445 
446     /**
447      * Returns the parameters in their primary encoding format.
448      * The primary encoding format for parameters is ASN.1, if an ASN.1
449      * specification for this type of parameters exists.
450      *
451      * @return the parameters encoded using their primary encoding format.
452      *
453      * @exception IOException on encoding errors, or if this parameter object
454      * has not been initialized.
455      */
456     final byte[] getEncoded()
457     {
458         if (this.initialized == false) {
459             throw new IOException("not initialized");
460         }
461         return paramSpi.engineGetEncoded();
462     }
463 
464     /**
465      * Returns the parameters encoded in the specified scheme.
466      * If {@code format} is null, the
467      * primary encoding format for parameters is used. The primary encoding
468      * format is ASN.1, if an ASN.1 specification for these parameters
469      * exists.
470      *
471      * @param format the name of the encoding format.
472      *
473      * @return the parameters encoded using the specified encoding scheme.
474      *
475      * @exception IOException on encoding errors, or if this parameter object
476      * has not been initialized.
477      */
478     final byte[] getEncoded(string format)
479     {
480         if (this.initialized == false) {
481             throw new IOException("not initialized");
482         }
483         return paramSpi.engineGetEncoded(format);
484     }
485 
486     /**
487      * Returns a formatted string describing the parameters.
488      *
489      * @return a formatted string describing the parameters, or null if this
490      * parameter object has not been initialized.
491      */
492     final override string toString() {
493         if (this.initialized == false) {
494             return null;
495         }
496         return paramSpi.engineToString();
497     }
498 }