Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allow to inject Cipher and Signature implementations
Browse files Browse the repository at this point in the history
this allows to replace certain Ciphers and Signatures with different
implementations other than what comes with BouncyCastle or JCE.

Sponsored by Lookout Inc.
mkristian committed Jul 29, 2015
1 parent 68c7757 commit 5576159
Showing 4 changed files with 157 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/main/java/org/jruby/ext/openssl/SecurityHelper.java
Original file line number Diff line number Diff line change
@@ -102,6 +102,15 @@ public abstract class SecurityHelper {
private static Boolean registerProvider = null;
private static final Map<String, Class> implEngines = new ConcurrentHashMap<String, Class>(16, 0.75f, 1);

public static void addCipher(String name, Class<? extends CipherSpi> clazz) {
implEngines.put("Cipher:" + name, clazz);
tryCipherInternal = true;
}

public static void addSignature(String name, Class<? extends SignatureSpi> clazz) {
implEngines.put("Signature:" + name, clazz);
}

public static Provider getSecurityProvider() {
if ( setBouncyCastleProvider && securityProvider == null ) {
synchronized(SecurityHelper.class) {
@@ -417,10 +426,12 @@ private static Cipher getCipherInternal(String transformation, final Provider pr
catch( IllegalStateException e ) {
// this can be due to trusted check in Cipher constructor
if (e.getCause().getClass() == NullPointerException.class) {
return newInstance(Cipher.class,
Cipher cipher = newInstance(Cipher.class,
new Class[] { CipherSpi.class, String.class },
new Object[] { spi, transformation }
);
setField(cipher, Cipher.class, "provider", provider);
return cipher;
}
throw e;
}
@@ -735,5 +746,4 @@ private static void setField(Object obj, Class<?> fieldOwner, String fieldName,
throw new IllegalStateException(e);
}
}

}
73 changes: 73 additions & 0 deletions src/test/java/org/jruby/ext/openssl/CipherSpiFake.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.jruby.ext.openssl;

import javax.crypto.*;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;

class CipherSpiFake extends CipherSpi {

@Override
protected void engineSetMode(String s) throws NoSuchAlgorithmException {

}

@Override
protected void engineSetPadding(String s) throws NoSuchPaddingException {

}

@Override
protected int engineGetBlockSize() {
return 0;
}

@Override
protected int engineGetOutputSize(int i) {
return 0;
}

@Override
protected byte[] engineGetIV() {
return new byte[0];
}

@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}

@Override
protected void engineInit(int i, Key key, SecureRandom secureRandom) throws InvalidKeyException {

}

@Override
protected void engineInit(int i, Key key, AlgorithmParameterSpec algorithmParameterSpec, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException {

}

@Override
protected void engineInit(int i, Key key, AlgorithmParameters algorithmParameters, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException {

}

@Override
protected byte[] engineUpdate(byte[] bytes, int i, int i1) {
return new byte[0];
}

@Override
protected int engineUpdate(byte[] bytes, int i, int i1, byte[] bytes1, int i2) throws ShortBufferException {
return 0;
}

@Override
protected byte[] engineDoFinal(byte[] bytes, int i, int i1) throws IllegalBlockSizeException, BadPaddingException {
return new byte[0];
}

@Override
protected int engineDoFinal(byte[] bytes, int i, int i1, byte[] bytes1, int i2) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
return 0;
}
}
19 changes: 19 additions & 0 deletions src/test/java/org/jruby/ext/openssl/SecurityHelperTest.java
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Signature;
import java.security.cert.CertificateException;

import org.junit.After;
@@ -43,6 +44,24 @@ public void disableSecurityProvider() {
SecurityHelper.setBouncyCastleProvider = false;
}

@Test
public void injectCipherImpl() throws Exception {
SecurityHelper.addCipher("fake", CipherSpiFake.class);
javax.crypto.Cipher cipher = SecurityHelper.getCipher("fake");
assertEquals(cipher.getProvider(), savedProvider);
java.lang.reflect.Field spi = cipher.getClass().getDeclaredField("spi");
spi.setAccessible(true);
assertEquals(spi.get(cipher).getClass(), CipherSpiFake.class);
}

@Test
public void injectSignatureImpl() throws Exception {
SecurityHelper.addSignature("fake", SignatureSpiFake.class);
Signature signature = SecurityHelper.getSignature("fake");
assertEquals(signature.getProvider(), savedProvider);
assertEquals(signature.getClass(), SignatureSpiFake.class);
}

@Test
public void usesBouncyCastleSecurityProviderByDefault() {
assertNotNull(SecurityHelper.getSecurityProvider());
53 changes: 53 additions & 0 deletions src/test/java/org/jruby/ext/openssl/SignatureSpiFake.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.jruby.ext.openssl;

import java.security.*;

/**
* Created by cmeier on 7/29/15.
*/
class SignatureSpiFake extends Signature {

SignatureSpiFake() {
super("fake");
}

@Override
protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {

}

@Override
protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {

}

@Override
protected void engineUpdate(byte b) throws SignatureException {

}

@Override
protected void engineUpdate(byte[] b, int off, int len) throws SignatureException {

}

@Override
protected byte[] engineSign() throws SignatureException {
return new byte[0];
}

@Override
protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
return false;
}

@Override
protected void engineSetParameter(String param, Object value) throws InvalidParameterException {

}

@Override
protected Object engineGetParameter(String param) throws InvalidParameterException {
return null;
}
}

0 comments on commit 5576159

Please sign in to comment.