Summary
-------
Change the specification for Signature.getParameters() and SignatureSpi.engineGetParameters() to return null when getting parameters are not supported by the underlying provider.
Problem
-------
The Signature setParameter/getParameters and SignatureSpi engineSetParameter/engineGetParameters methods are too strictly related. The setting parameters says that if initialized, the getting parameters must return the parameters back. This requirement assumes the Signature parameters, using AlgorithmParameterSpec, are related to the parameters of the algorithm instead of parameters of the Signature operation. The getting parameters methods returns AlgorithmParameters, which are for parameters related to the algorithm.
This was observed during EdDSA code review. With EdDSA using Signature, the algorithm parameters are specification defined and internal. The parameters used by setParameter() are an AlgorithmParameterSpec for the signature operation only, however getParameters() returns AlgorithmParameters, which in EdDSA's case would be the internal parameters, and wouldn't be the same parameters initialized by setParameters.
Solution
--------
The most compatible solution is to return null if the getParameters() or engineGetParameters() operations are not supported. The API specifies it can return null, so applications should be better prepared to handle it.
It was decided that throwing UnsupportedOperationException was not the best choice for compatibility. The API has existed since JDK 1.4 and was never marked as throwing an exception despite the SPI supporting the exception. It is unlikely applications have a catch for this exception around the code.
Specification
-------------
Change the specification of Signature.getParameters as follows:
/**
* Returns the parameters used with this signature object.
*
- * <p> If this signature has been previously initialized with parameters
- * (by calling the {@code setParameter} method), this method returns
- * the same parameters. If this signature has not been initialized with
- * parameters, this method may return a combination of default and
- * randomly generated parameter values if the underlying
- * signature implementation supports it and can successfully generate
- * them. Otherwise, {@code null} is returned.
+ * <p> If this signature has been initialized with parameters
+ * (by calling {@link #setParameter(AlgorithmParameterSpec)} or
+ * {@link #setParameter(String, Object)}) and the underlying signature
+ * implementation supports returning the parameters as
+ * {@code AlgorithmParameters}, this method returns the same parameters.
+ * If the parameters were not set, this method may return a combination
+ * of default and randomly generated parameter values if the
+ * underlying signature implementation supports it and can successfully
+ * generate them. Otherwise, {@code null} is returned.
*
* @return the parameters used with this signature, or {@code null}
*
* @see #setParameter(AlgorithmParameterSpec)
Note: SignatureSpi.engineGetParameters() will say the same, just replacing "signature" with "signature engine" where appropriate.