Skip to content

Commit 387ec05

Browse files
authored
OpenSSL 1.1.1 cert verification port (#239)
an attempt to port over verify_chain (build_chain) and related bits from OpenSSL 1.1.1 JOSSL's current certificate verification algorithm is rather straightforward and dates back to OpenSSL 0.9 days. Several times we tried porting over newer code to enhance verification (e.g. to consider alternate chains) but failed due the magnitude of the task. The PR is an attempt for a minimal viable product in terms of OpenSSL 1.1.1 compatible chain verification. No relevant security features should be missing - if so than they are likely not present in the legacy algorithm as well.
1 parent ca977bd commit 387ec05

21 files changed

+2191
-642
lines changed

src/main/java/org/jruby/ext/openssl/OCSPBasicResponse.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,9 @@ private boolean checkDelegated(X509Cert signerCA) {
530530
catch (CertificateParsingException e) {
531531
throw newOCSPError(getRuntime(), e);
532532
}
533+
catch (IOException e) {
534+
throw newOCSPError(getRuntime(), e);
535+
}
533536
}
534537

535538
private boolean matchIssuerId(X509Cert signerCA, CertificateID certId, List<SingleResp> singleResponses) throws IOException {

src/main/java/org/jruby/ext/openssl/SSLContext.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ StoreContext createStoreContext(final String purpose) {
945945
// for verify_cb
946946
storeContext.setExtraData(1, store.getExtraData(1));
947947
if ( purpose != null ) storeContext.setDefault(purpose);
948-
storeContext.verifyParameter.inherit(store.verifyParameter);
948+
storeContext.getParam().inherit(store.getParam());
949949
return storeContext;
950950
}
951951

@@ -1109,14 +1109,14 @@ private void verifyChain(final StoreContext storeContext) throws CertificateExce
11091109
ok = storeContext.verifyCertificate();
11101110
}
11111111
catch (Exception e) {
1112-
internalContext.setLastVerifyResult(storeContext.error);
1113-
if ( storeContext.error == X509Utils.V_OK ) {
1112+
internalContext.setLastVerifyResult(storeContext.getError());
1113+
if ( storeContext.getError() == X509Utils.V_OK ) {
11141114
internalContext.setLastVerifyResult(X509Utils.V_ERR_CERT_REJECTED);
11151115
}
11161116
throw new CertificateException("certificate verify failed", e);
11171117
}
11181118

1119-
internalContext.setLastVerifyResult(storeContext.error);
1119+
internalContext.setLastVerifyResult(storeContext.getError());
11201120
if ( ok == 0 ) {
11211121
throw new CertificateException("certificate verify failed");
11221122
}

src/main/java/org/jruby/ext/openssl/x509store/Function1.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,5 @@
3333
* @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
3434
*/
3535
interface Function1<T> {
36-
static class Empty implements Function1 {
37-
public int call(Object arg0) {
38-
return -1;
39-
}
40-
}
41-
public static final Function1.Empty EMPTY = new Empty();
4236
int call(T arg0) throws Exception;
4337
}// Function1

src/main/java/org/jruby/ext/openssl/x509store/Function2.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,5 @@
3333
* @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
3434
*/
3535
interface Function2<T, U> {
36-
static class Empty implements Function2 {
37-
public int call(Object arg0, Object arg1) {
38-
return -1;
39-
}
40-
}
41-
public static final Function2.Empty EMPTY = new Empty();
4236
int call(T arg0, U arg1) throws Exception;
4337
}// Function2

src/main/java/org/jruby/ext/openssl/x509store/Function3.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,5 @@
3333
* @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
3434
*/
3535
interface Function3<T, U, V> {
36-
static class Empty implements Function3 {
37-
public int call(Object arg0,Object arg1,Object arg2) {
38-
return -1;
39-
}
40-
}
41-
public static final Function3.Empty EMPTY = new Empty();
4236
int call(T arg0, U arg1, V arg2) throws Exception;
4337
}// Function3

src/main/java/org/jruby/ext/openssl/x509store/Function4.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,5 @@
3333
* @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
3434
*/
3535
interface Function4<T, U, V, X> {
36-
static class Empty implements Function4 {
37-
public int call(Object arg0,Object arg1,Object arg2,Object arg3) {
38-
return -1;
39-
}
40-
}
41-
public static final Function4.Empty EMPTY = new Empty();
4236
int call(T arg0, U arg1, V arg2, X arg3) throws Exception;
4337
}// Function4

src/main/java/org/jruby/ext/openssl/x509store/Function5.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,5 @@
3333
* @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
3434
*/
3535
interface Function5<T, U, V, X, Y> {
36-
static class Empty implements Function5 {
37-
public int call(Object arg0,Object arg1,Object arg2,Object arg3,Object arg4) {
38-
return -1;
39-
}
40-
}
41-
public static final Function5.Empty EMPTY = new Empty();
4236
int call(T arg0, U arg1, V arg2, X arg3, Y arg4) throws Exception;
4337
}// Function5

src/main/java/org/jruby/ext/openssl/x509store/Lookup.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public Lookup(Ruby runtime, LookupMethod method) {
8181
this.runtime = runtime;
8282

8383
final LookupMethod.NewItemFunction newItem = method.newItem;
84-
if ( newItem != null && newItem != Function1.EMPTY ) {
84+
if ( newItem != null ) {
8585
final int result;
8686
try {
8787
result = newItem.call(this);
@@ -128,7 +128,7 @@ public static LookupMethod fileLookup() {
128128
public int control(final int cmd, final String argc, final long argl, final String[] ret) throws Exception {
129129
if ( method == null ) return -1;
130130

131-
if ( method.control != null && method.control != Function5.EMPTY ) {
131+
if ( method.control != null ) {
132132
return method.control.call(this, Integer.valueOf(cmd), argc, Long.valueOf(argl), ret);
133133
}
134134
return 1;
@@ -364,7 +364,7 @@ private String envEntry(final String key) {
364364
* c: X509_LOOKUP_free
365365
*/
366366
public void free() throws Exception {
367-
if ( method != null && method.free != null && method.free != Function1.EMPTY ) {
367+
if ( method != null && method.free != null ) {
368368
method.free.call(this);
369369
}
370370
}
@@ -374,7 +374,7 @@ public void free() throws Exception {
374374
*/
375375
public int init() throws Exception {
376376
if ( method == null ) return 0;
377-
if ( method.init != null && method.init != Function1.EMPTY ) {
377+
if ( method.init != null ) {
378378
return method.init.call(this);
379379
}
380380
return 1;
@@ -384,7 +384,7 @@ public int init() throws Exception {
384384
* c: X509_LOOKUP_by_subject
385385
*/
386386
public int bySubject(final int type, final Name name, final X509Object[] ret) throws Exception {
387-
if ( method == null || method.getBySubject == null || method.getBySubject == Function4.EMPTY ) {
387+
if ( method == null || method.getBySubject == null ) {
388388
return X509_LU_FAIL;
389389
}
390390
if ( skip ) return 0;
@@ -395,7 +395,7 @@ public int bySubject(final int type, final Name name, final X509Object[] ret) th
395395
* c: X509_LOOKUP_by_issuer_serial
396396
*/
397397
public int byIssuerSerialNumber(final int type, final Name name, final BigInteger serial, final X509Object[] ret) throws Exception {
398-
if ( method == null || method.getByIssuerSerialNumber == null || method.getByIssuerSerialNumber == Function5.EMPTY ) {
398+
if ( method == null || method.getByIssuerSerialNumber == null ) {
399399
return X509_LU_FAIL;
400400
}
401401
return method.getByIssuerSerialNumber.call(this, Integer.valueOf(type), name, serial, ret);
@@ -405,7 +405,7 @@ public int byIssuerSerialNumber(final int type, final Name name, final BigIntege
405405
* c: X509_LOOKUP_by_fingerprint
406406
*/
407407
public int byFingerprint(final int type, final String bytes, final X509Object[] ret) throws Exception {
408-
if ( method == null || method.getByFingerprint == null || method.getByFingerprint == Function4.EMPTY ) {
408+
if ( method == null || method.getByFingerprint == null ) {
409409
return X509_LU_FAIL;
410410
}
411411
return method.getByFingerprint.call(this, Integer.valueOf(type), bytes, ret);
@@ -415,7 +415,7 @@ public int byFingerprint(final int type, final String bytes, final X509Object[]
415415
* c: X509_LOOKUP_by_alias
416416
*/
417417
public int byAlias(final int type, final String alias, final X509Object[] ret) throws Exception {
418-
if ( method == null || method.getByAlias == null || method.getByAlias == Function4.EMPTY ) {
418+
if ( method == null || method.getByAlias == null ) {
419419
return X509_LU_FAIL;
420420
}
421421
return method.getByAlias.call(this, Integer.valueOf(type), alias, ret);
@@ -427,7 +427,7 @@ public int byAlias(final int type, final String alias, final X509Object[] ret) t
427427
public int shutdown() throws Exception {
428428
if ( method == null ) return 0;
429429

430-
if ( method.shutdown != null && method.shutdown != Function1.EMPTY ) {
430+
if ( method.shutdown != null ) {
431431
return method.shutdown.call(this);
432432
}
433433
return 1;

0 commit comments

Comments
 (0)