debug.println("Further warnings of this type will " + "be suppressed"); } new Exception("Call trace").printStackTrace(); } } Exception lastException = null; while ((firstService != null) || serviceIterator.hasNext()) { Service s; if (firstService != null) { s = firstService; firstService = null; } else { s = serviceIterator.next(); } if (isSpi(s) == false) { continue; } try { sigSpi = newInstance(s); provider = s.getProvider(); // not needed any more firstService = null; serviceIterator = null; return; } catch (NoSuchAlgorithmException e) { lastException = e; } } ProviderException e = new ProviderException ("Could not construct SignatureSpi instance"); if (lastException != null) { e.initCause(lastException); } throw e; } } private void chooseProvider(int type, Key key, SecureRandom random) throws InvalidKeyException { synchronized (lock) { if (sigSpi != null) { init(sigSpi, type, key, random); return; } Exception lastException = null; while ((firstService != null) || serviceIterator.hasNext()) { Service s; if (firstService != null) { s = firstService; firstService = null; } else { s = serviceIterator.next(); } // if provider says it does not support this key, ignore it if (s.supportsParameter(key) == false) { continue; } // if instance is not a SignatureSpi, ignore it if (isSpi(s) == false) { continue; } try { SignatureSpi spi = newInstance(s); init(spi, type, key, random); provider = s.getProvider(); sigSpi = spi; firstService = null; serviceIterator = null; return; } catch (Exception e) { // NoSuchAlgorithmException from newInstance() // InvalidKeyException from init() // RuntimeException (ProviderException) from init() if (lastException == null) { lastException = e; } } } // no working provider found, fail if (lastException instanceof InvalidKeyException) { throw (InvalidKeyException)lastException; } if (lastException instanceof RuntimeException) { throw (RuntimeException)lastException; } String k = (key != null) ? key.getClass().getName() : "(null)"; throw new InvalidKeyException ("No installed provider supports this key: " + k, lastException); } } private final static int I_PUB = 1; private final static int I_PRIV = 2; private final static int I_PRIV_SR = 3; private void init(SignatureSpi spi, int type, Key key, SecureRandom random) throws InvalidKeyException { switch (type) { case I_PUB: spi.engineInitVerify((PublicKey)key); break; case I_PRIV: spi.engineInitSign((PrivateKey)key); break; case I_PRIV_SR: spi.engineInitSign((PrivateKey)key, random); break; default: throw new AssertionError("Internal error: " + type); } } protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { if (sigSpi != null) { sigSpi.engineInitVerify(publicKey); } else { chooseProvider(I_PUB, publicKey, null); } } protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { if (sigSpi != null) { sigSpi.engineInitSign(privateKey); } else { chooseProvider(I_PRIV, privateKey, null); } } protected void engineInitSign(PrivateKey privateKey, SecureRandom sr) throws InvalidKeyException { if (sigSpi != null) { sigSpi.engineInitSign(privateKey, sr); } else { chooseProvider(I_PRIV_SR, privateKey, sr); } } protected void engineUpdate(byte b) throws SignatureException { chooseFirstProvider(); sigSpi.engineUpdate(b); } protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { chooseFirstProvider(); sigSpi.engineUpdate(b, off, len); } protected void engineUpdate(ByteBuffer data) { chooseFirstProvider(); sigSpi.engineUpdate(data); } protected byte[] engineSign() throws SignatureException { chooseFirstProvider(); return sigSpi.engineSign(); } protected int engineSign(byte[] outbuf, int offset, int len) throws SignatureException { chooseFirstProvider(); return sigSpi.engineSign(outbuf, offset, len); } protected boolean engineVerify(byte[] sigBytes) throws SignatureException { chooseFirstProvider(); return sigSpi.engineVerify(sigBytes); } protected boolean engineVerify(byte[] sigBytes, int offset, int length) throws SignatureException { chooseFirstProvider(); return sigSpi.engineVerify(sigBytes, offset, length); } protected void engineSetParameter(String param, Object value) throws InvalidParameterException { chooseFirstProvider(); sigSpi.engineSetParameter(param, value); } protected void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { chooseFirstProvider(); sigSpi.engineSetParameter(params); } protected Object engineGetParameter(String param) throws InvalidParameterException { chooseFirstProvider(); return sigSpi.engineGetParameter(param); } protected AlgorithmParameters engineGetParameters() { chooseFirstProvider(); return sigSpi.engineGetParameters(); } } // adapter for RSA/ECB/PKCS1Padding ciphers private static class CipherAdapter extends SignatureSpi { private final Cipher cipher; private ByteArrayOutputStream data; CipherAdapter(Cipher cipher) { this.cipher = cipher; } protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { cipher.init(Cipher.DECRYPT_MODE, publicKey); if (data == null) { data = new ByteArrayOutputStream(128); } else { data.reset(); } } protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { cipher.init(Cipher.ENCRYPT_MODE, privateKey); data = null; } protected void engineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { cipher.init(Cipher.ENCRYPT_MODE, privateKey, random); data = null; } protected void engineUpdate(byte b) throws SignatureException { engineUpdate(new byte[] {b}, 0, 1); } protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { if (data != null) { data.write(b, off, len); return; } byte[] out = cipher.update(b, off, len); if ((out != null) && (out.length != 0)) { throw new SignatureException ("Cipher unexpectedly returned data"); } } protected byte[] engineSign() throws SignatureException { try { return cipher.doFinal(); } catch (IllegalBlockSizeException e) { throw new SignatureException("doFinal() failed", e); } catch (BadPaddingException e) { throw new SignatureException("doFinal() failed", e); } } protected boolean engineVerify(byte[] sigBytes) throws SignatureException { try { byte[] out = cipher.doFinal(sigBytes); byte[] dataBytes = data.toByteArray(); data.reset(); return Arrays.equals(out, dataBytes); } catch (BadPaddingException e) { // e.g. wrong public key used // return false rather than throwing exception return false; } catch (IllegalBlockSizeException e) { throw new SignatureException("doFinal() failed", e); } } protected void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new InvalidParameterException("Parameters not supported"); } protected Object engineGetParameter(String param) throws InvalidParameterException { throw new InvalidParameterException("Parameters not supported"); } } }Lines 1001–1293 of 1293. Previous lines
debug.println("Further warnings of this type will " + "be suppressed"); } new Exception("Call trace").printStackTrace(); } } Exception lastException = null; while ((firstService != null) || serviceIterator.hasNext()) { Service s; if (firstService != null) { s = firstService; firstService = null; } else { s = serviceIterator.next(); } if (isSpi(s) == false) { continue; } try { sigSpi = newInstance(s); provider = s.getProvider(); // not needed any more firstService = null; serviceIterator = null; return; } catch (NoSuchAlgorithmException e) { lastException = e; } } ProviderException e = new ProviderException ("Could not construct SignatureSpi instance"); if (lastException != null) { e.initCause(lastException); } throw e; } } private void chooseProvider(int type, Key key, SecureRandom random) throws InvalidKeyException { synchronized (lock) { if (sigSpi != null) { init(sigSpi, type, key, random); return; } Exception lastException = null; while ((firstService != null) || serviceIterator.hasNext()) { Service s; if (firstService != null) { s = firstService; firstService = null; } else { s = serviceIterator.next(); } // if provider says it does not support this key, ignore it if (s.supportsParameter(key) == false) { continue; } // if instance is not a SignatureSpi, ignore it if (isSpi(s) == false) { continue; } try { SignatureSpi spi = newInstance(s); init(spi, type, key, random); provider = s.getProvider(); sigSpi = spi; firstService = null; serviceIterator = null; return; } catch (Exception e) { // NoSuchAlgorithmException from newInstance() // InvalidKeyException from init() // RuntimeException (ProviderException) from init() if (lastException == null) { lastException = e; } } } // no working provider found, fail if (lastException instanceof InvalidKeyException) { throw (InvalidKeyException)lastException; } if (lastException instanceof RuntimeException) { throw (RuntimeException)lastException; } String k = (key != null) ? key.getClass().getName() : "(null)"; throw new InvalidKeyException ("No installed provider supports this key: " + k, lastException); } } private final static int I_PUB = 1; private final static int I_PRIV = 2; private final static int I_PRIV_SR = 3; private void init(SignatureSpi spi, int type, Key key, SecureRandom random) throws InvalidKeyException { switch (type) { case I_PUB: spi.engineInitVerify((PublicKey)key); break; case I_PRIV: spi.engineInitSign((PrivateKey)key); break; case I_PRIV_SR: spi.engineInitSign((PrivateKey)key, random); break; default: throw new AssertionError("Internal error: " + type); } } protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { if (sigSpi != null) { sigSpi.engineInitVerify(publicKey); } else { chooseProvider(I_PUB, publicKey, null); } } protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { if (sigSpi != null) { sigSpi.engineInitSign(privateKey); } else { chooseProvider(I_PRIV, privateKey, null); } } protected void engineInitSign(PrivateKey privateKey, SecureRandom sr) throws InvalidKeyException { if (sigSpi != null) { sigSpi.engineInitSign(privateKey, sr); } else { chooseProvider(I_PRIV_SR, privateKey, sr); } } protected void engineUpdate(byte b) throws SignatureException { chooseFirstProvider(); sigSpi.engineUpdate(b); } protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { chooseFirstProvider(); sigSpi.engineUpdate(b, off, len); } protected void engineUpdate(ByteBuffer data) { chooseFirstProvider(); sigSpi.engineUpdate(data); } protected byte[] engineSign() throws SignatureException { chooseFirstProvider(); return sigSpi.engineSign(); } protected int engineSign(byte[] outbuf, int offset, int len) throws SignatureException { chooseFirstProvider(); return sigSpi.engineSign(outbuf, offset, len); } protected boolean engineVerify(byte[] sigBytes) throws SignatureException { chooseFirstProvider(); return sigSpi.engineVerify(sigBytes); } protected boolean engineVerify(byte[] sigBytes, int offset, int length) throws SignatureException { chooseFirstProvider(); return sigSpi.engineVerify(sigBytes, offset, length); } protected void engineSetParameter(String param, Object value) throws InvalidParameterException { chooseFirstProvider(); sigSpi.engineSetParameter(param, value); } protected void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { chooseFirstProvider(); sigSpi.engineSetParameter(params); } protected Object engineGetParameter(String param) throws InvalidParameterException { chooseFirstProvider(); return sigSpi.engineGetParameter(param); } protected AlgorithmParameters engineGetParameters() { chooseFirstProvider(); return sigSpi.engineGetParameters(); } } // adapter for RSA/ECB/PKCS1Padding ciphers private static class CipherAdapter extends SignatureSpi { private final Cipher cipher; private ByteArrayOutputStream data; CipherAdapter(Cipher cipher) { this.cipher = cipher; } protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { cipher.init(Cipher.DECRYPT_MODE, publicKey); if (data == null) { data = new ByteArrayOutputStream(128); } else { data.reset(); } } protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { cipher.init(Cipher.ENCRYPT_MODE, privateKey); data = null; } protected void engineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { cipher.init(Cipher.ENCRYPT_MODE, privateKey, random); data = null; } protected void engineUpdate(byte b) throws SignatureException { engineUpdate(new byte[] {b}, 0, 1); } protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { if (data != null) { data.write(b, off, len); return; } byte[] out = cipher.update(b, off, len); if ((out != null) && (out.length != 0)) { throw new SignatureException ("Cipher unexpectedly returned data"); } } protected byte[] engineSign() throws SignatureException { try { return cipher.doFinal(); } catch (IllegalBlockSizeException e) { throw new SignatureException("doFinal() failed", e); } catch (BadPaddingException e) { throw new SignatureException("doFinal() failed", e); } } protected boolean engineVerify(byte[] sigBytes) throws SignatureException { try { byte[] out = cipher.doFinal(sigBytes); byte[] dataBytes = data.toByteArray(); data.reset(); return Arrays.equals(out, dataBytes); } catch (BadPaddingException e) { // e.g. wrong public key used // return false rather than throwing exception return false; } catch (IllegalBlockSizeException e) { throw new SignatureException("doFinal() failed", e); } } protected void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new InvalidParameterException("Parameters not supported"); } protected Object engineGetParameter(String param) throws InvalidParameterException { throw new InvalidParameterException("Parameters not supported"); } } }