-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WFSSL-111 Add the ability to use a custom OpenSSL engine #127
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks very much for the PR @heyuanliu-intel!
We'll be taking a closer look at this and the corresponding wildfly-openssl-natives PR in January.
One thing I am wondering though is if we can get some basic tests for configuring a custom engine added to this PR. It seems like using the QAT_Engine in the tests might be tricky if there are hardware pre-requisites needed. If that's the case, is it possible to test with some other engine instead so we have the custom engine use case covered in the testsuite?
pom.xml
Outdated
<version.org.wildfly.openssl.natives>2.2.2.Final</version.org.wildfly.openssl.natives> | ||
<version.org.wildfly.openssl.wildfly-openssl-linux-x86_64>2.2.2.SP01</version.org.wildfly.openssl.wildfly-openssl-linux-x86_64> | ||
<version.org.wildfly.openssl.wildfly-openssl-linux-s390x>2.2.2.SP01</version.org.wildfly.openssl.wildfly-openssl-linux-s390x> | ||
<version.org.wildfly.openssl.natives>2.2.3.CR1-SNAPSHOT</version.org.wildfly.openssl.natives> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to note, because this PR depends on wildfly-security/wildfly-openssl-natives#16, the way we'd handle this is to merge the wildfly-openssl-natives PR first, do a wildfly-openssl-natives 2.2.3.Final release, then this PR would need to be updated with the released version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Because it depends on wildfly-openssl-natives. So we should merge the wildfly-openssl-natives PR first.
For the QAT_engine part, it provides two implementations : software one and hardware one. For my testcase, I uses the software implementation do the verification. So it doesn't have hardware pre-requisites needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok that's great. Sounds like it should be possible to add some tests here then. For reference, the existing tests are found here: https://github.com/wildfly-security/wildfly-openssl/tree/main/java/src/test/java/org/wildfly/openssl
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it doesn't have hardware pre-requisites but it needs to install a suite of software to make the test successful. From the program logic, it supports all the openssl custom engine. Let me think about how to add a testcase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use Intel RDRAND as OpenSSL custom engine to verify the function. Please review this commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks very much for working on that! We'll take a look.
I find the Intel RDRAND is a custom OpenSSL engine, so I use it to write a testcase. |
@Test | ||
public void tesRDRANDEngine() throws IOException, InterruptedException { | ||
System.setProperty(SSL.ORG_WILDFLY_OPENSSL_ENGINE, "rdrand"); | ||
SSL ssl = SSL.getInstance(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tried running this test but noticed that the configured custom engine doesn't actually get used since SSL#getInstance()
is already called during the test setup so SSL#init
doesn't get run again.
To make sure that SSL#getInstance
actually makes use of the configured property, I think we'd need to create a new test class with this test case and update the maven-surefire-plugin
configuration in the java/pom.xml file so that it sets the org.wildfly.openssl.engine
property to rdrand
for this new test class only instead of trying to set the property programmatically.
As an example, we updated the maven-surefire-plugin
configuration for a different testsuite recently, where we needed to specify some properties using the -D option when a certain test was being run:
I think we should be able to do something similar here.
Feel free to let us know if you have any questions about this or would like some help with testing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay. I will take a look at this and try to refine the testcase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have modified the code in wildfly-openssl-native, please review the code wildfly-security/wildfly-openssl-natives@e879191
The main change is to throw exceptions if any error occurs during initializing the custom engine.
So I also add the testcase to verify this function.
I think adding a new testcase class is simple than using maven-surefire-plugin method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heyuanliu-intel Great! Thanks very much for the updates here and on the wildfly-openssl-natives PR. We will take a look this week. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heyuanliu-intel Thanks for the updates! I've added some comments.
*/ | ||
public class BasicOpenSSLCustomEngineTest { | ||
|
||
@Test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something that I noticed was that the outcome of the tests depends on the order in which the test cases are run.
Because the second test below is expected to successfully use the system property and call SSL#getInstance()
, this means that if the second test happens to be run before the first test, then SSL#init
won't be run again and the first test will fail on line 33.
To fix this, you could specify that the first test must be run before the second test. This could be done by adding @InSequence(1)
and @InSequence(2)
annotations to the test methods (see org.jboss.arquillian.junit.InSequence
for more details).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your comments. I will fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arquillian isn't in project's maven dependency. Should I add this dependency or upgrade the Junit version from Junit 4 to Junit 5 (maybe there is API change to upgrade Junit5)?
Or I separate those test methods to two test classes ?
Any comments about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question, we haven't checked yet if it's easy to upgrade to JUnit 5. For now, it's fine to add the following dependency:
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-core</artifactId>
<version>1.6.0.Final</version>
<scope>test</scope>
</dependency>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still see random order issues if I launch the new test alone in my env:
mvn clean install -Dorg.wildfly.openssl.path=/home/rmartinc/apps/openssl-1.1.1f/lib -Dorg.wildfly.openssl.engine=qatengine -Dtest=org.wildfly.openssl.BasicOpenSSLCustomEngineTest
...
[INFO] Running org.wildfly.openssl.BasicOpenSSLCustomEngineTest
[ERROR] Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.093 s <<< FAILURE! - in org.wildfly.openssl.BasicOpenSSLCustomEngineTest
[ERROR] testUnknownEngine(org.wildfly.openssl.BasicOpenSSLCustomEngineTest) Time elapsed: 0.003 s <<< FAILURE!
java.lang.AssertionError: Expected ExceptionInInitializerError not thrown
My feeling is that only junit4 is being used and the arquillian InSequence
annotation is doing nothing. In junit4 (but since 4.11) we can use @FixMethodOrder(MethodSorters.NAME_ASCENDING)
and call the methods test1UnknownEngine
and test2RDRANDEngine
(or similar) to have the order we want. But that needs an upgrade of junit to last 4.13.2
(which is not bad because this project is using a very old junit 4.8.2). I just see a problem in TestAllMethodsImplemented.java
with the upgrade, but is easily fixable using MatcherAssert.assertThat
.
@heyuanliu-intel @fjuma WDYT about using FixMethodOrder
and upgrading junit4?
The rest of the PR LGTM. When I reviewed the natives PR I used this one too and everything was OK for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I will do a test and fix this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since @rmartinc has the changes for upgrading to JUnit 4.13.2 done locally, he's going to submit a PR for that and we'll get that merged.
@heyuanliu-intel You'll then be able to rebase and use the @FixMethodOrder
annotations as @rmartinc mentioned.
Thank you both!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heyuanliu-intel We just merged @rmartinc's PR that upgrades to JUnit 4.13.2 (#130) so you should be able to rebase now.
|
||
@Test | ||
public void testUnknownEngine() { | ||
System.setProperty(SSL.ORG_WILDFLY_OPENSSL_ENGINE, "unknown"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each test case should also reset this system property to its original value in a finally
block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I will fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fjuma When I set the engine to qat, I found a performance issue caused by ByteBuffer. You can get the detail info from this project ByteBufferPerformance.
And this is the Thread Dump File.
So my fix is change from the direct byte buffer allocation to byte buffer pool.
ByteBuffer buf = ByteBuffer.allocateDirect(len);
to
DefaultByteBufferPool.PooledByteBuffer pool = DefaultByteBufferPool.DIRECT_POOL.allocate(); ByteBuffer buf = pool.getBuffer(); buf.limit(len);
So the CPU utilization can boost from 10% to 50%, and the performance can boost 5X.
Should I open a new PR or just add this code change commit to this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ByteBuffer buf = ByteBuffer.allocateDirect(len);
try {
final long addr = memoryAddress(buf);
src.limit(pos + len);
buf.put(src);
src.limit(limit);
sslWrote = SSL.getInstance().writeToSSL(ssl, addr, len);
if (sslWrote > 0) {
src.position(pos + sslWrote);
return sslWrote;
} else {
src.position(pos);
}
} finally {
buf.clear();
ByteBufferUtils.cleanDirectBuffer(buf);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DefaultByteBufferPool.PooledByteBuffer pool = DefaultByteBufferPool.DIRECT_POOL.allocate();
ByteBuffer buf = pool.getBuffer();
buf.limit(len);
try {
final long addr = memoryAddress(buf);
src.limit(pos + len);
buf.put(src);
src.limit(limit);
sslWrote = SSL.getInstance().writeToSSL(ssl, addr, len);
if (sslWrote > 0) {
src.position(pos + sslWrote);
return sslWrote;
} else {
src.position(pos);
}
} finally {
pool.close();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same code change should be applied to all the ByteBuffer allocateDirect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heyuanliu-intel Please create a separate WFSSL issue and a separate PR for this and we can review that more closely and discuss there. Thanks!
public void testUnknownEngine() { | ||
String engine = System.getProperty(SSL.ORG_WILDFLY_OPENSSL_ENGINE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
System.setProperty
returns the previous value of the property so calling getProperty
isn't needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay. I will fix this.
} catch (ExceptionInInitializerError expected) { | ||
Assert.assertNotNull(expected); | ||
} finally { | ||
if (engine != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the previous value was null
, System.clearProperty
can be called to unset the value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it. I will unset the value I set if there is no value setting before.
AbstractOpenSSLTest.setup(); | ||
SSL ssl = SSL.getInstance(); | ||
Assert.assertNotNull(ssl.version()); | ||
String engine = System.getProperty(SSL.ORG_WILDFLY_OPENSSL_ENGINE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, the getProperty
call isn't needed since the value is returned from setProperty
.
SSL ssl = SSL.getInstance(); | ||
Assert.assertNotNull(ssl.version()); | ||
} finally { | ||
if (engine != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, should clear the property if it was null
before.
|
||
@Test | ||
public void testUnknownEngine() { | ||
System.setProperty(SSL.ORG_WILDFLY_OPENSSL_ENGINE, "unknown"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heyuanliu-intel Please create a separate WFSSL issue and a separate PR for this and we can review that more closely and discuss there. Thanks!
@heyuanliu-intel Thanks very much for the updates! This PR is looking good. Would you be able to squash the commits into a single commit? |
@rmartinc When you get a chance, please review. Thanks! |
2b49cbc
to
59e2a6a
Compare
I have squashed the commits into a single commit. @fjuma I have another question. I think we should change the dependency version after wildfly-openssl-natives is published.
|
@heyuanliu-intel Thank you very much for squashing the changes! Yes, once the wildfly-openssl-natives PR is merged, we will release WildFly OpenSSL Natives 2.3.0.Final. I've created WFSSL-115 to track upgrading to the new Natives version once released. For now, you could remove the above dependency changes from the WFSSL-111 commit and introduce a new commit that references WFSSL-115 instead. For now you'd have to use the SNAPSHOT versions to successfully build locally. |
@fjuma @rmartinc I have used the new Junit way to change the testcase. Please review it again. Should I remove the dependency about Arquillian from pom.xml because it isn't used by the project now ?
|
@heyuanliu-intel Yes, that part is not needed now, please remove that part. |
42ea470
to
5adf8a0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@heyuanliu-intel I see the changes OK but I need to rebase the branch to run the tests. I think that you missed that point. Nevertheless I'm going to approve the PR cos it also needs the upgrade of the natives part to run OK. So a new rebase will be needed for sure in the future.
What is the status of this PR? Was it ever accepted/merged into the main branch or did it get left lingering in PR/review? |
@bjvetter Thanks very much for the reminder about this one! @heyuanliu-intel When you get a chance, would you be able to rebase your branch (to include @rmartinc's changes that upgrade JUnit to 4.13.2)? Thanks! |
Add the ability to use a custom OpenSSL engine.
This PR depends on wildfly-security/wildfly-openssl-natives#16