Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/security/mscapi/CSignature.java
32288 views
/*1* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.mscapi;2627import java.nio.ByteBuffer;28import java.security.*;29import java.security.interfaces.ECPublicKey;30import java.security.interfaces.RSAPublicKey;31import java.security.spec.AlgorithmParameterSpec;32import java.math.BigInteger;33import java.security.spec.MGF1ParameterSpec;34import java.security.spec.PSSParameterSpec;35import java.util.Locale;3637import sun.security.rsa.RSAKeyFactory;38import sun.security.util.ECUtil;39import sun.security.util.KeyUtil;4041/**42* Signature implementation.43*44* Objects should be instantiated by calling Signature.getInstance() using the45* following algorithm names:46*47* . "NONEwithRSA"48* . "SHA1withRSA"49* . "SHA256withRSA"50* . "SHA384withRSA"51* . "SHA512withRSA"52* . "MD5withRSA"53* . "MD2withRSA"54* . "RSASSA-PSS"55* . "SHA1withECDSA"56* . "SHA224withECDSA"57* . "SHA256withECDSA"58* . "SHA384withECDSA"59* . "SHA512withECDSA"60*61* NOTE: RSA keys must be at least 512 bits long.62*63* NOTE: NONEwithRSA must be supplied with a pre-computed message digest.64* Only the following digest algorithms are supported: MD5, SHA-1,65* SHA-256, SHA-384, SHA-512 and a special-purpose digest66* algorithm which is a concatenation of SHA-1 and MD5 digests.67*68* @since 1.669* @author Stanley Man-Kit Ho70*/71abstract class CSignature extends SignatureSpi {72// private key algorithm name73protected String keyAlgorithm;7475// message digest implementation we use76protected MessageDigest messageDigest;7778// message digest name79protected String messageDigestAlgorithm;8081// flag indicating whether the digest has been reset82protected boolean needsReset;8384// the signing key85protected CPrivateKey privateKey = null;8687// the verification key88protected CPublicKey publicKey = null;8990/**91* Constructs a new CSignature. Used by subclasses.92*/93CSignature(String keyName, String digestName) {9495this.keyAlgorithm = keyName;96if (digestName != null) {97try {98messageDigest = MessageDigest.getInstance(digestName);99// Get the digest's canonical name100messageDigestAlgorithm = messageDigest.getAlgorithm();101} catch (NoSuchAlgorithmException e) {102throw new ProviderException(e);103}104} else {105messageDigest = null;106messageDigestAlgorithm = null;107}108needsReset = false;109}110111static class RSA extends CSignature {112113public RSA(String digestAlgorithm) {114super("RSA", digestAlgorithm);115}116117// initialize for signing. See JCA doc118@Override119protected void engineInitSign(PrivateKey key) throws InvalidKeyException {120if (key == null) {121throw new InvalidKeyException("Key cannot be null");122}123if ((key instanceof CPrivateKey) == false124|| !key.getAlgorithm().equalsIgnoreCase("RSA")) {125throw new InvalidKeyException("Key type not supported: "126+ key.getClass() + " " + key.getAlgorithm());127}128privateKey = (CPrivateKey) key;129130// Check against the local and global values to make sure131// the sizes are ok. Round up to nearest byte.132RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7),133null, CKeyPairGenerator.RSA.KEY_SIZE_MIN,134CKeyPairGenerator.RSA.KEY_SIZE_MAX);135136this.publicKey = null;137resetDigest();138}139140// initialize for signing. See JCA doc141@Override142protected void engineInitVerify(PublicKey key) throws InvalidKeyException {143if (key == null) {144throw new InvalidKeyException("Key cannot be null");145}146// This signature accepts only RSAPublicKey147if ((key instanceof RSAPublicKey) == false) {148throw new InvalidKeyException("Key type not supported: "149+ key.getClass());150}151152153if ((key instanceof CPublicKey) == false) {154155// convert key to MSCAPI format156java.security.interfaces.RSAPublicKey rsaKey =157(java.security.interfaces.RSAPublicKey) key;158159BigInteger modulus = rsaKey.getModulus();160BigInteger exponent = rsaKey.getPublicExponent();161162// Check against the local and global values to make sure163// the sizes are ok. Round up to the nearest byte.164RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),165exponent, -1, CKeyPairGenerator.RSA.KEY_SIZE_MAX);166167byte[] modulusBytes = modulus.toByteArray();168byte[] exponentBytes = exponent.toByteArray();169170// Adjust key length due to sign bit171int keyBitLength = (modulusBytes[0] == 0)172? (modulusBytes.length - 1) * 8173: modulusBytes.length * 8;174175byte[] keyBlob = generatePublicKeyBlob(176keyBitLength, modulusBytes, exponentBytes);177178try {179publicKey = importPublicKey("RSA", keyBlob, keyBitLength);180181} catch (KeyStoreException e) {182throw new InvalidKeyException(e);183}184185} else {186publicKey = (CPublicKey) key;187}188189this.privateKey = null;190resetDigest();191}192193/**194* Returns the signature bytes of all the data195* updated so far.196* The format of the signature depends on the underlying197* signature scheme.198*199* @return the signature bytes of the signing operation's result.200*201* @exception SignatureException if the engine is not202* initialized properly or if this signature algorithm is unable to203* process the input data provided.204*/205@Override206protected byte[] engineSign() throws SignatureException {207208byte[] hash = getDigestValue();209210if (privateKey.getHCryptKey() == 0) {211return signCngHash(1, hash, hash.length,2120,213this instanceof NONEwithRSA ? null : messageDigestAlgorithm,214privateKey.getHCryptProvider(), 0);215} else {216// Omit the hash OID when generating a NONEwithRSA signature217boolean noHashOID = this instanceof NONEwithRSA;218// Sign hash using MS Crypto APIs219byte[] result = signHash(noHashOID, hash, hash.length,220messageDigestAlgorithm, privateKey.getHCryptProvider(),221privateKey.getHCryptKey());222223// Convert signature array from little endian to big endian224return convertEndianArray(result);225}226}227228/**229* Verifies the passed-in signature.230*231* @param sigBytes the signature bytes to be verified.232*233* @return true if the signature was verified, false if not.234*235* @exception SignatureException if the engine is not236* initialized properly, the passed-in signature is improperly237* encoded or of the wrong type, if this signature algorithm is unable to238* process the input data provided, etc.239*/240@Override241protected boolean engineVerify(byte[] sigBytes)242throws SignatureException {243byte[] hash = getDigestValue();244245if (publicKey.getHCryptKey() == 0) {246return verifyCngSignedHash(2471, hash, hash.length,248sigBytes, sigBytes.length,2490,250messageDigestAlgorithm,251publicKey.getHCryptProvider(),2520);253} else {254return verifySignedHash(hash, hash.length,255messageDigestAlgorithm, convertEndianArray(sigBytes),256sigBytes.length, publicKey.getHCryptProvider(),257publicKey.getHCryptKey());258}259}260261/**262* Generates a public-key BLOB from a key's components.263*/264// used by CRSACipher265static native byte[] generatePublicKeyBlob(266int keyBitLength, byte[] modulus, byte[] publicExponent)267throws InvalidKeyException;268269}270271// Nested class for NONEwithRSA signatures272public static final class NONEwithRSA extends RSA {273274// the longest supported digest is 512 bits (SHA-512)275private static final int RAW_RSA_MAX = 64;276277private final byte[] precomputedDigest;278private int offset = 0;279280public NONEwithRSA() {281super(null);282precomputedDigest = new byte[RAW_RSA_MAX];283}284285// Stores the precomputed message digest value.286@Override287protected void engineUpdate(byte b) throws SignatureException {288if (offset >= precomputedDigest.length) {289offset = RAW_RSA_MAX + 1;290return;291}292precomputedDigest[offset++] = b;293}294295// Stores the precomputed message digest value.296@Override297protected void engineUpdate(byte[] b, int off, int len)298throws SignatureException {299if (len > (precomputedDigest.length - offset)) {300offset = RAW_RSA_MAX + 1;301return;302}303System.arraycopy(b, off, precomputedDigest, offset, len);304offset += len;305}306307// Stores the precomputed message digest value.308@Override309protected void engineUpdate(ByteBuffer byteBuffer) {310int len = byteBuffer.remaining();311if (len <= 0) {312return;313}314if (len > (precomputedDigest.length - offset)) {315offset = RAW_RSA_MAX + 1;316return;317}318byteBuffer.get(precomputedDigest, offset, len);319offset += len;320}321322@Override323protected void resetDigest(){324offset = 0;325}326327// Returns the precomputed message digest value.328@Override329protected byte[] getDigestValue() throws SignatureException {330if (offset > RAW_RSA_MAX) {331throw new SignatureException("Message digest is too long");332}333334// Determine the digest algorithm from the digest length335if (offset == 20) {336setDigestName("SHA1");337} else if (offset == 36) {338setDigestName("SHA1+MD5");339} else if (offset == 32) {340setDigestName("SHA-256");341} else if (offset == 48) {342setDigestName("SHA-384");343} else if (offset == 64) {344setDigestName("SHA-512");345} else if (offset == 16) {346setDigestName("MD5");347} else {348throw new SignatureException(349"Message digest length is not supported");350}351352byte[] result = new byte[offset];353System.arraycopy(precomputedDigest, 0, result, 0, offset);354offset = 0;355356return result;357}358}359360public static final class SHA1withRSA extends RSA {361public SHA1withRSA() {362super("SHA1");363}364}365366public static final class SHA256withRSA extends RSA {367public SHA256withRSA() {368super("SHA-256");369}370}371372public static final class SHA384withRSA extends RSA {373public SHA384withRSA() {374super("SHA-384");375}376}377378public static final class SHA512withRSA extends RSA {379public SHA512withRSA() {380super("SHA-512");381}382}383384public static final class MD5withRSA extends RSA {385public MD5withRSA() {386super("MD5");387}388}389390public static final class MD2withRSA extends RSA {391public MD2withRSA() {392super("MD2");393}394}395396public static final class SHA1withECDSA extends ECDSA {397public SHA1withECDSA() {398super("SHA-1");399}400}401402public static final class SHA224withECDSA extends ECDSA {403public SHA224withECDSA() {404super("SHA-224");405}406}407408public static final class SHA256withECDSA extends ECDSA {409public SHA256withECDSA() {410super("SHA-256");411}412}413414public static final class SHA384withECDSA extends ECDSA {415public SHA384withECDSA() {416super("SHA-384");417}418}419420public static final class SHA512withECDSA extends ECDSA {421public SHA512withECDSA() {422super("SHA-512");423}424}425426static class ECDSA extends CSignature {427428public ECDSA(String messageDigestAlgorithm) {429super("EC", messageDigestAlgorithm);430}431432// initialize for signing. See JCA doc433@Override434protected void engineInitSign(PrivateKey key) throws InvalidKeyException {435if (key == null) {436throw new InvalidKeyException("Key cannot be null");437}438if ((key instanceof CPrivateKey) == false439|| !key.getAlgorithm().equalsIgnoreCase("EC")) {440throw new InvalidKeyException("Key type not supported: "441+ key.getClass() + " " + key.getAlgorithm());442}443privateKey = (CPrivateKey) key;444445this.publicKey = null;446resetDigest();447}448449// initialize for signing. See JCA doc450@Override451protected void engineInitVerify(PublicKey key) throws InvalidKeyException {452if (key == null) {453throw new InvalidKeyException("Key cannot be null");454}455// This signature accepts only ECPublicKey456if ((key instanceof ECPublicKey) == false) {457throw new InvalidKeyException("Key type not supported: "458+ key.getClass());459}460461if ((key instanceof CPublicKey) == false) {462try {463publicKey = importECPublicKey("EC",464CKey.generateECBlob(key),465KeyUtil.getKeySize(key));466} catch (KeyStoreException e) {467throw new InvalidKeyException(e);468}469} else {470publicKey = (CPublicKey) key;471}472473this.privateKey = null;474resetDigest();475}476477@Override478protected byte[] engineSign() throws SignatureException {479byte[] hash = getDigestValue();480byte[] raw = signCngHash(0, hash, hash.length,4810,482null,483privateKey.getHCryptProvider(), 0);484return ECUtil.encodeSignature(raw);485}486487@Override488protected boolean engineVerify(byte[] sigBytes) throws SignatureException {489byte[] hash = getDigestValue();490sigBytes = ECUtil.decodeSignature(sigBytes);491return verifyCngSignedHash(4920,493hash, hash.length,494sigBytes, sigBytes.length,4950,496null,497publicKey.getHCryptProvider(),4980499);500}501}502503public static final class PSS extends RSA {504505private PSSParameterSpec pssParams = null;506507// Workaround: Cannot import raw public key to CNG. This signature508// will be used for verification if key is not from MSCAPI.509private Signature fallbackSignature;510511public PSS() {512super(null);513}514515@Override516protected void engineInitSign(PrivateKey key) throws InvalidKeyException {517super.engineInitSign(key);518fallbackSignature = null;519}520521@Override522protected void engineInitVerify(PublicKey key) throws InvalidKeyException {523if (key == null) {524throw new InvalidKeyException("Key cannot be null");525}526// This signature accepts only RSAPublicKey527if ((key instanceof java.security.interfaces.RSAPublicKey) == false) {528throw new InvalidKeyException("Key type not supported: "529+ key.getClass());530}531532this.privateKey = null;533534if (key instanceof CPublicKey) {535fallbackSignature = null;536publicKey = (CPublicKey) key;537} else {538if (fallbackSignature == null) {539try {540fallbackSignature = Signature.getInstance(541"RSASSA-PSS", "SunRsaSign");542} catch (NoSuchAlgorithmException | NoSuchProviderException e) {543throw new InvalidKeyException("Invalid key", e);544}545}546fallbackSignature.initVerify(key);547if (pssParams != null) {548try {549fallbackSignature.setParameter(pssParams);550} catch (InvalidAlgorithmParameterException e) {551throw new InvalidKeyException("Invalid params", e);552}553}554publicKey = null;555}556resetDigest();557}558559@Override560protected void engineUpdate(byte b) throws SignatureException {561ensureInit();562if (fallbackSignature != null) {563fallbackSignature.update(b);564} else {565messageDigest.update(b);566}567needsReset = true;568}569570@Override571protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {572ensureInit();573if (fallbackSignature != null) {574fallbackSignature.update(b, off, len);575} else {576messageDigest.update(b, off, len);577}578needsReset = true;579}580581@Override582protected void engineUpdate(ByteBuffer input) {583try {584ensureInit();585} catch (SignatureException se) {586// hack for working around API bug587throw new RuntimeException(se.getMessage());588}589if (fallbackSignature != null) {590try {591fallbackSignature.update(input);592} catch (SignatureException se) {593// hack for working around API bug594throw new RuntimeException(se.getMessage());595}596} else {597messageDigest.update(input);598}599needsReset = true;600}601602@Override603protected byte[] engineSign() throws SignatureException {604ensureInit();605byte[] hash = getDigestValue();606return signCngHash(2, hash, hash.length,607pssParams.getSaltLength(),608((MGF1ParameterSpec)609pssParams.getMGFParameters()).getDigestAlgorithm(),610privateKey.getHCryptProvider(), privateKey.getHCryptKey());611}612613@Override614protected boolean engineVerify(byte[] sigBytes) throws SignatureException {615ensureInit();616if (fallbackSignature != null) {617needsReset = false;618return fallbackSignature.verify(sigBytes);619} else {620byte[] hash = getDigestValue();621return verifyCngSignedHash(6222, hash, hash.length,623sigBytes, sigBytes.length,624pssParams.getSaltLength(),625((MGF1ParameterSpec)626pssParams.getMGFParameters()).getDigestAlgorithm(),627publicKey.getHCryptProvider(),628publicKey.getHCryptKey()629);630}631}632633@Override634protected void engineSetParameter(AlgorithmParameterSpec params)635throws InvalidAlgorithmParameterException {636if (needsReset) {637throw new ProviderException638("Cannot set parameters during operations");639}640this.pssParams = validateSigParams(params);641if (fallbackSignature != null) {642fallbackSignature.setParameter(params);643}644}645646@Override647protected AlgorithmParameters engineGetParameters() {648AlgorithmParameters ap = null;649if (this.pssParams != null) {650try {651ap = AlgorithmParameters.getInstance("RSASSA-PSS");652ap.init(this.pssParams);653} catch (GeneralSecurityException gse) {654throw new ProviderException(gse.getMessage());655}656}657return ap;658}659660private void ensureInit() throws SignatureException {661if (this.privateKey == null && this.publicKey == null662&& fallbackSignature == null) {663throw new SignatureException("Missing key");664}665if (this.pssParams == null) {666// Parameters are required for signature verification667throw new SignatureException668("Parameters required for RSASSA-PSS signatures");669}670if (fallbackSignature == null && messageDigest == null) {671// This could happen if initVerify(softKey), setParameter(),672// and initSign() were called. No messageDigest. Create it.673try {674messageDigest = MessageDigest675.getInstance(pssParams.getDigestAlgorithm());676} catch (NoSuchAlgorithmException e) {677throw new SignatureException(e);678}679}680}681682/**683* Validate the specified Signature PSS parameters.684*/685private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)686throws InvalidAlgorithmParameterException {687688if (p == null) {689throw new InvalidAlgorithmParameterException690("Parameters cannot be null");691}692693if (!(p instanceof PSSParameterSpec)) {694throw new InvalidAlgorithmParameterException695("parameters must be type PSSParameterSpec");696}697698// no need to validate again if same as current signature parameters699PSSParameterSpec params = (PSSParameterSpec) p;700if (params == this.pssParams) return params;701702// now sanity check the parameter values703if (!(params.getMGFAlgorithm().equalsIgnoreCase("MGF1"))) {704throw new InvalidAlgorithmParameterException("Only supports MGF1");705706}707708if (params.getTrailerField() != PSSParameterSpec.TRAILER_FIELD_BC) {709throw new InvalidAlgorithmParameterException710("Only supports TrailerFieldBC(1)");711}712713AlgorithmParameterSpec algSpec = params.getMGFParameters();714if (!(algSpec instanceof MGF1ParameterSpec)) {715throw new InvalidAlgorithmParameterException716("Only support MGF1ParameterSpec");717}718719MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec)algSpec;720721String msgHashAlg = params.getDigestAlgorithm()722.toLowerCase(Locale.ROOT).replaceAll("-", "");723if (msgHashAlg.equals("sha")) {724msgHashAlg = "sha1";725}726String mgf1HashAlg = mgfSpec.getDigestAlgorithm()727.toLowerCase(Locale.ROOT).replaceAll("-", "");728if (mgf1HashAlg.equals("sha")) {729mgf1HashAlg = "sha1";730}731732if (!mgf1HashAlg.equals(msgHashAlg)) {733throw new InvalidAlgorithmParameterException734("MGF1 hash must be the same as message hash");735}736737return params;738}739}740741/**742* Sign hash using CNG API with HCRYPTKEY.743* @param type 0 no padding, 1, pkcs1, 2, pss744*/745native static byte[] signCngHash(746int type, byte[] hash,747int hashSize, int saltLength, String hashAlgorithm,748long hCryptProv, long nCryptKey)749throws SignatureException;750751/**752* Verify a signed hash using CNG API with HCRYPTKEY.753* @param type 0 no padding, 1, pkcs1, 2, pss754*/755private native static boolean verifyCngSignedHash(756int type, byte[] hash, int hashSize,757byte[] signature, int signatureSize,758int saltLength, String hashAlgorithm,759long hCryptProv, long hKey) throws SignatureException;760761/**762* Resets the message digest if needed.763*/764protected void resetDigest() {765if (needsReset) {766if (messageDigest != null) {767messageDigest.reset();768}769needsReset = false;770}771}772773protected byte[] getDigestValue() throws SignatureException {774needsReset = false;775return messageDigest.digest();776}777778protected void setDigestName(String name) {779messageDigestAlgorithm = name;780}781782/**783* Updates the data to be signed or verified784* using the specified byte.785*786* @param b the byte to use for the update.787*788* @exception SignatureException if the engine is not initialized789* properly.790*/791@Override792protected void engineUpdate(byte b) throws SignatureException {793messageDigest.update(b);794needsReset = true;795}796797/**798* Updates the data to be signed or verified, using the799* specified array of bytes, starting at the specified offset.800*801* @param b the array of bytes802* @param off the offset to start from in the array of bytes803* @param len the number of bytes to use, starting at offset804*805* @exception SignatureException if the engine is not initialized806* properly807*/808@Override809protected void engineUpdate(byte[] b, int off, int len)810throws SignatureException {811messageDigest.update(b, off, len);812needsReset = true;813}814815/**816* Updates the data to be signed or verified, using the817* specified ByteBuffer.818*819* @param input the ByteBuffer820*/821@Override822protected void engineUpdate(ByteBuffer input) {823messageDigest.update(input);824needsReset = true;825}826827/**828* Convert array from big endian to little endian, or vice versa.829*/830private static byte[] convertEndianArray(byte[] byteArray) {831if (byteArray == null || byteArray.length == 0)832return byteArray;833834byte [] retval = new byte[byteArray.length];835836// make it big endian837for (int i=0;i < byteArray.length;i++)838retval[i] = byteArray[byteArray.length - i - 1];839840return retval;841}842843/**844* Sign hash using Microsoft Crypto API with HCRYPTKEY.845* The returned data is in little-endian.846*/847private native static byte[] signHash(boolean noHashOID, byte[] hash,848int hashSize, String hashAlgorithm, long hCryptProv, long hCryptKey)849throws SignatureException;850851/**852* Verify a signed hash using Microsoft Crypto API with HCRYPTKEY.853*/854private native static boolean verifySignedHash(byte[] hash, int hashSize,855String hashAlgorithm, byte[] signature, int signatureSize,856long hCryptProv, long hCryptKey) throws SignatureException;857858/**859* Sets the specified algorithm parameter to the specified860* value. This method supplies a general-purpose mechanism through861* which it is possible to set the various parameters of this object.862* A parameter may be any settable parameter for the algorithm, such as863* a parameter size, or a source of random bits for signature generation864* (if appropriate), or an indication of whether or not to perform865* a specific but optional computation. A uniform algorithm-specific866* naming scheme for each parameter is desirable but left unspecified867* at this time.868*869* @param param the string identifier of the parameter.870*871* @param value the parameter value.872*873* @exception InvalidParameterException if <code>param</code> is an874* invalid parameter for this signature algorithm engine,875* the parameter is already set876* and cannot be set again, a security exception occurs, and so on.877*878* @deprecated Replaced by {@link879* #engineSetParameter(java.security.spec.AlgorithmParameterSpec)880* engineSetParameter}.881*/882@Override883@Deprecated884protected void engineSetParameter(String param, Object value)885throws InvalidParameterException {886throw new InvalidParameterException("Parameter not supported");887}888889/**890* Sets this signature engine with the specified algorithm parameter.891*892* @param params the parameters893*894* @exception InvalidAlgorithmParameterException if the given895* parameter is invalid896*/897@Override898protected void engineSetParameter(AlgorithmParameterSpec params)899throws InvalidAlgorithmParameterException {900if (params != null) {901throw new InvalidAlgorithmParameterException("No parameter accepted");902}903}904905/**906* Gets the value of the specified algorithm parameter.907* This method supplies a general-purpose mechanism through which it908* is possible to get the various parameters of this object. A parameter909* may be any settable parameter for the algorithm, such as a parameter910* size, or a source of random bits for signature generation (if911* appropriate), or an indication of whether or not to perform a912* specific but optional computation. A uniform algorithm-specific913* naming scheme for each parameter is desirable but left unspecified914* at this time.915*916* @param param the string name of the parameter.917*918* @return the object that represents the parameter value, or null if919* there is none.920*921* @exception InvalidParameterException if <code>param</code> is an922* invalid parameter for this engine, or another exception occurs while923* trying to get this parameter.924*925* @deprecated926*/927@Override928@Deprecated929protected Object engineGetParameter(String param)930throws InvalidParameterException {931throw new InvalidParameterException("Parameter not supported");932}933934/**935* Gets the algorithm parameter from this signature engine.936*937* @return the parameter, or null if no parameter is used.938*/939@Override940protected AlgorithmParameters engineGetParameters() {941return null;942}943944/**945* Imports a public-key BLOB.946*/947// used by CRSACipher948static native CPublicKey importPublicKey(949String alg, byte[] keyBlob, int keySize) throws KeyStoreException;950951static native CPublicKey importECPublicKey(952String alg, byte[] keyBlob, int keySize) throws KeyStoreException;953}954955956