4242import java .security .cert .TrustAnchor ;
4343import java .security .cert .X509Certificate ;
4444import java .util .ArrayList ;
45- import java .util .Collection ;
46- import java .util .Iterator ;
45+ import java .util .Arrays ;
46+ import java .util .LinkedHashMap ;
47+ import java .util .Map ;
4748
4849import org .jruby .Ruby ;
4950import org .jruby .ext .openssl .OpenSSL ;
@@ -333,8 +334,8 @@ public int loadDefaultJavaCACertsFile(String certsFile) throws IOException, Gene
333334 final FileInputStream fin = new FileInputStream (certsFile );
334335 int count = 0 ;
335336 try {
336- // hardcode the keystore type, as we expect cacerts to be a java
337- // keystore - especially needed for jdk9
337+ // hardcode the keystore type, as we expect cacerts to be a java keystore
338+ // especially needed since Java 9 (getDefaultType on 11/13 is "pkcs12")
338339 KeyStore keystore = SecurityHelper .getKeyStore ("jks" );
339340 // null password - as the cacerts file isn't password protected
340341 keystore .load (fin , null );
@@ -466,13 +467,13 @@ public int call(final Lookup ctx, final Integer cmd, final String argp, final Nu
466467 case X509_L_FILE_LOAD :
467468 if (arglInt == X509_FILETYPE_DEFAULT ) {
468469 try {
469- file = ctx .envEntry ( getDefaultCertificateFileEnvironment () ); // ENV['SSL_CERT_FILE']
470+ file = ctx .envEntry (X509_CERT_FILE_EVP ); // ENV['SSL_CERT_FILE']
470471 }
471472 catch (RuntimeException e ) {
472- OpenSSL .debug (ctx .runtime , "failed to read SSL_CERT_FILE" , e );
473+ OpenSSL .debug (ctx .runtime , "failed to read env " + X509_CERT_FILE_EVP , e );
473474 }
474475 if (file == null ) {
475- file = X509Utils . X509_CERT_FILE .replace ('/' , File .separatorChar );
476+ file = X509_CERT_FILE .replace ('/' , File .separatorChar );
476477 }
477478 if (file .matches (".*\\ .(crt|cer|pem)$" )) {
478479 ok = ctx .loadCertificateOrCRLFile (file , X509_FILETYPE_PEM ) != 0 ? 1 : 0 ;
@@ -498,19 +499,16 @@ public int call(final Lookup ctx, final Integer cmd, final String argp, final Nu
498499 * c: BY_DIR, lookup_dir_st
499500 */
500501 private static class LookupDir {
501- Collection < String > dirs ;
502- Collection < Integer > dirsType ;
502+ String [] dirs ;
503+ int [] dirsType ;
503504 }
504505
505506 /**
506507 * c: new_dir
507508 */
508509 private static class NewLookupDir implements LookupMethod .NewItemFunction {
509510 public int call (final Lookup lookup ) {
510- final LookupDir lookupDir = new LookupDir ();
511- lookupDir .dirs = new ArrayList <String >();
512- lookupDir .dirsType = new ArrayList <Integer >();
513- lookup .methodData = lookupDir ;
511+ lookup .methodData = new LookupDir ();
514512 return 1 ;
515513 }
516514 }
@@ -535,7 +533,7 @@ private static class LookupDirControl implements LookupMethod.ControlFunction {
535533
536534 public int call (final Lookup ctx , final Integer cmd , String argp , Number argl , String [] retp ) {
537535 int ret = 0 ;
538- final LookupDir lookupData = (LookupDir ) ctx .methodData ;
536+ final LookupDir lookupDir = (LookupDir ) ctx .methodData ;
539537 switch ( cmd ) {
540538 case X509_L_ADD_DIR :
541539 if ( argl .intValue () == X509_FILETYPE_DEFAULT ) {
@@ -546,16 +544,16 @@ public int call(final Lookup ctx, final Integer cmd, String argp, Number argl, S
546544 catch (RuntimeException e ) { }
547545
548546 if ( certDir != null ) {
549- ret = addCertificateDirectory (lookupData , certDir , X509_FILETYPE_PEM );
547+ ret = addCertificateDirectory (lookupDir , certDir , X509_FILETYPE_PEM );
550548 } else {
551- ret = addCertificateDirectory (lookupData , X509_CERT_DIR , X509_FILETYPE_PEM );
549+ ret = addCertificateDirectory (lookupDir , X509_CERT_DIR , X509_FILETYPE_PEM );
552550 }
553551 if ( ret == 0 ) {
554552 X509Error .addError (X509_R_LOADING_CERT_DIR );
555553 }
556554 }
557555 else {
558- ret = addCertificateDirectory (lookupData , argp , argl .intValue ());
556+ ret = addCertificateDirectory (lookupDir , argp , argl .intValue ());
559557 }
560558 break ;
561559 }
@@ -575,19 +573,20 @@ private int addCertificateDirectory(final LookupDir ctx, final String dir, final
575573 return 0 ;
576574 }
577575
578- String [] dirs = dir .split (File .pathSeparator );
576+ final String [] dirs = dir .split (File .pathSeparator );
579577
580- for ( int i =0 ; i <dirs .length ; i ++ ) {
581- if ( dirs [i ].length () == 0 ) {
582- continue ;
583- }
584- if ( ctx .dirs .contains (dirs [i ]) ) {
585- continue ;
586- }
587- ctx .dirsType .add (type );
588- ctx .dirs .add (dirs [i ]);
578+ final Map <String , ?> ctxDirs = new LinkedHashMap <String , Object >(dirs .length );
579+ if ( ctx .dirs != null ) for (String d : ctx .dirs ) ctxDirs .put (d , null );
580+
581+ for ( int i = 0 ; i < dirs .length ; i ++ ) {
582+ if ( dirs [i ].isEmpty () ) continue ;
583+ ctxDirs .put (dirs [i ], null ); // if key exists no-op
589584 }
590585
586+ final int len = ctxDirs .size ();
587+ ctx .dirs = ctxDirs .keySet ().toArray (new String [len ]);
588+ Arrays .fill (ctx .dirsType = new int [len ], type );
589+
591590 return 1 ;
592591 }
593592 }
@@ -618,10 +617,9 @@ else if ( type == X509_LU_CRL ) {
618617 final String hash = String .format ("%08x" , name .hash ());
619618 final StringBuilder buffer = new StringBuilder (48 );
620619
621- final Iterator <Integer > iter = context .dirsType .iterator ();
622-
623- for ( final String dir : context .dirs ) {
624- final int dirType = iter .next ();
620+ for ( int i = 0 ; i < context .dirs .length ; i ++ ) {
621+ final String dir = context .dirs [i ];
622+ final int dirType = context .dirsType [i ];
625623 for ( int k = 0 ; ; k ++ ) {
626624 buffer .setLength (0 ); // reset - clear buffer
627625 buffer .append (dir ).append (File .separatorChar );
0 commit comments