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 }