/* Cert creation engine */
  private static synchronized X509Certificate createX509V3Certificate(
      PublicKey pubKey,
      PrivateKey privKey,
      int ttlMonths,
      String issuerDN,
      String subjectDN,
      long serial,
      String signAlgoritm)
      throws GeneralSecurityException {
    X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator();
    certGenerator.reset();

    certGenerator.setSerialNumber(java.math.BigInteger.valueOf(serial));
    certGenerator.setIssuerDN(new org.bouncycastle.asn1.x509.X509Name(issuerDN));
    certGenerator.setNotBefore(new java.util.Date(System.currentTimeMillis()));
    certGenerator.setNotAfter(
        new java.util.Date(System.currentTimeMillis() + ttlMonths * (1000L * 60 * 60 * 24 * 30)));
    certGenerator.setSubjectDN(new org.bouncycastle.asn1.x509.X509Name(subjectDN));
    certGenerator.setPublicKey(pubKey);
    certGenerator.setSignatureAlgorithm(signAlgoritm);

    X509Certificate cert =
        certGenerator.generateX509Certificate(privKey, "BC", new java.security.SecureRandom());
    cert.checkValidity(new java.util.Date());
    cert.verify(pubKey);

    return cert;
  }
Example #2
0
 private KeyStore createKeyStore(@Nullable String path)
     throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
   String keyStoreType = KeyStore.getDefaultType();
   char[] defaultPassword = "******".toCharArray();
   if (path != null) {
     // If the user provided path, only try to load the keystore at that path.
     KeyStore keyStore = KeyStore.getInstance(keyStoreType);
     FileInputStream is = new FileInputStream(path);
     keyStore.load(is, defaultPassword);
     return keyStore;
   }
   try {
     // Check if we are on Android.
     Class version = Class.forName("android.os.Build$VERSION");
     // Build.VERSION_CODES.ICE_CREAM_SANDWICH is 14.
     if (version.getDeclaredField("SDK_INT").getInt(version) >= 14) {
       // After ICS, Android provided this nice method for loading the keystore,
       // so we don't have to specify the location explicitly.
       KeyStore keystore = KeyStore.getInstance("AndroidCAStore");
       keystore.load(null, null);
       return keystore;
     } else {
       keyStoreType = "BKS";
       path =
           System.getProperty("java.home")
               + "/etc/security/cacerts.bks".replace('/', File.separatorChar);
     }
   } catch (ClassNotFoundException e) {
     // NOP. android.os.Build is not present, so we are not on Android. Fall through.
   } catch (NoSuchFieldException e) {
     throw new RuntimeException(e); // Should never happen.
   } catch (IllegalAccessException e) {
     throw new RuntimeException(e); // Should never happen.
   }
   if (path == null) {
     path = System.getProperty("javax.net.ssl.trustStore");
   }
   if (path == null) {
     // Try this default system location for Linux/Windows/OSX.
     path =
         System.getProperty("java.home")
             + "/lib/security/cacerts".replace('/', File.separatorChar);
   }
   try {
     KeyStore keyStore = KeyStore.getInstance(keyStoreType);
     FileInputStream is = new FileInputStream(path);
     keyStore.load(is, defaultPassword);
     return keyStore;
   } catch (FileNotFoundException e) {
     // If we failed to find a system trust store, load our own fallback trust store. This can fail
     // on Android
     // but we should never reach it there.
     KeyStore keyStore = KeyStore.getInstance("JKS");
     InputStream is = getClass().getResourceAsStream("cacerts");
     keyStore.load(is, defaultPassword);
     return keyStore;
   }
 }
Example #3
0
  private static void permissionCheck() {
    SecurityManager sec = System.getSecurityManager();

    if (sec != null) {
      sec.checkPermission(new RuntimePermission("useKeychainStore"));
    }
  }
  static HttpClient New(
      SSLSocketFactory sf,
      URL url,
      HostnameVerifier hv,
      String proxy,
      int proxyPort,
      boolean useCache)
      throws IOException {
    HttpsClient ret = null;
    if (useCache) {
      /* see if one's already around */
      ret = (HttpsClient) kac.get(url, sf);
      if (ret != null) {
        ret.cachedHttpClient = true;
      }
    }
    if (ret == null) {
      ret = new HttpsClient(sf, url, proxy, proxyPort);
    } else {
      SecurityManager security = System.getSecurityManager();
      if (security != null) {
        security.checkConnect(url.getHost(), url.getPort());
      }
      ret.url = url;
    }
    ret.setHostnameVerifier(hv);

    return ret;
  }
Example #5
0
  private CipherTest(PeerFactory peerFactory) throws IOException {
    THREADS = Integer.parseInt(System.getProperty("numThreads", "4"));
    factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
    SSLSocket socket = (SSLSocket) factory.createSocket();
    String[] cipherSuites = socket.getSupportedCipherSuites();
    String[] protocols = socket.getSupportedProtocols();
    //      String[] clientAuths = {null, "RSA", "DSA"};
    String[] clientAuths = {null};
    tests =
        new ArrayList<TestParameters>(cipherSuites.length * protocols.length * clientAuths.length);
    for (int i = 0; i < cipherSuites.length; i++) {
      String cipherSuite = cipherSuites[i];

      for (int j = 0; j < protocols.length; j++) {
        String protocol = protocols[j];

        if (!peerFactory.isSupported(cipherSuite, protocol)) {
          continue;
        }

        for (int k = 0; k < clientAuths.length; k++) {
          String clientAuth = clientAuths[k];
          if ((clientAuth != null) && (cipherSuite.indexOf("DH_anon") != -1)) {
            // no client with anonymous ciphersuites
            continue;
          }
          tests.add(new TestParameters(cipherSuite, protocol, clientAuth));
        }
      }
    }
    testIterator = tests.iterator();
  }
Example #6
0
 private static EquinoxSecurityManager getSupportedSystemSecurityManager() {
   try {
     EquinoxSecurityManager equinoxManager = (EquinoxSecurityManager) System.getSecurityManager();
     return equinoxManager != null && equinoxManager.inCheckPermission() ? equinoxManager : null;
   } catch (ClassCastException e) {
     return null;
   }
 }
  public static void main(String[] args) throws Exception {

    if (debug) System.setProperty("javax.net.debug", "all");

    /*
     * Start the tests.
     */
    new CheckMyTrustedKeystore();
  }
Example #8
0
 private TrustEngine[] getTrustEngines() {
   if (trustEngineTracker == null) {
     trustEngineTracker = new ServiceTracker(context, TrustEngine.class.getName(), null);
     trustEngineTracker.open();
   }
   final Object objs[] = trustEngineTracker.getServices();
   final TrustEngine[] result = new TrustEngine[objs.length];
   System.arraycopy(objs, 0, result, 0, objs.length);
   return result;
 }
Example #9
0
  public static void main(String[] args) throws Exception {
    HttpServer s1 = null;
    HttpsServer s2 = null;
    ExecutorService executor = null;
    try {
      String root = System.getProperty("test.src") + "/docs";
      System.out.print("Test12: ");
      InetSocketAddress addr = new InetSocketAddress(0);
      s1 = HttpServer.create(addr, 0);
      s2 = HttpsServer.create(addr, 0);
      HttpHandler h = new FileServerHandler(root);
      HttpContext c1 = s1.createContext("/test1", h);
      HttpContext c2 = s2.createContext("/test1", h);
      executor = Executors.newCachedThreadPool();
      s1.setExecutor(executor);
      s2.setExecutor(executor);
      ctx = new SimpleSSLContext(System.getProperty("test.src")).get();
      s2.setHttpsConfigurator(new HttpsConfigurator(ctx));
      s1.start();
      s2.start();

      int port = s1.getAddress().getPort();
      int httpsport = s2.getAddress().getPort();
      Runner r[] = new Runner[8];
      r[0] = new Runner(true, "http", root + "/test1", port, "smallfile.txt", 23);
      r[1] = new Runner(true, "http", root + "/test1", port, "largefile.txt", 2730088);
      r[2] = new Runner(true, "https", root + "/test1", httpsport, "smallfile.txt", 23);
      r[3] = new Runner(true, "https", root + "/test1", httpsport, "largefile.txt", 2730088);
      r[4] = new Runner(false, "http", root + "/test1", port, "smallfile.txt", 23);
      r[5] = new Runner(false, "http", root + "/test1", port, "largefile.txt", 2730088);
      r[6] = new Runner(false, "https", root + "/test1", httpsport, "smallfile.txt", 23);
      r[7] = new Runner(false, "https", root + "/test1", httpsport, "largefile.txt", 2730088);
      start(r);
      join(r);
      System.out.println("OK");
    } finally {
      delay();
      if (s1 != null) s1.stop(2);
      if (s2 != null) s2.stop(2);
      if (executor != null) executor.shutdown();
    }
  }
Example #10
0
  public static void main(PeerFactory peerFactory, KeyStore keyStore, String[] args)
      throws Exception {

    long time = System.currentTimeMillis();
    String relPath;
    if ((args != null) && (args.length > 0) && args[0].equals("sh")) {
      relPath = pathToStoresSH;
    } else {
      relPath = pathToStores;
    }
    PATH = new File(System.getProperty("test.src", "."), relPath);
    CipherTest.peerFactory = peerFactory;
    System.out.print("Initializing test '" + peerFactory.getName() + "'...");
    //      secureRandom = new SecureRandom();
    //      secureRandom.nextInt();
    //      trustStore = readKeyStore(trustStoreFile);
    CipherTest.keyStore = keyStore;
    //      keyStore = readKeyStore(keyStoreFile);
    KeyManagerFactory keyFactory =
        KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyFactory.init(keyStore, "test12".toCharArray());
    keyManager = (X509ExtendedKeyManager) keyFactory.getKeyManagers()[0];

    TrustManagerFactory tmf =
        TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);
    trustManager = (X509TrustManager) tmf.getTrustManagers()[0];

    //      trustManager = new AlwaysTrustManager();
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(new KeyManager[] {keyManager}, new TrustManager[] {trustManager}, null);
    SSLContext.setDefault(context);

    CipherTest cipherTest = new CipherTest(peerFactory);
    Thread serverThread = new Thread(peerFactory.newServer(cipherTest), "Server");
    serverThread.setDaemon(true);
    serverThread.start();
    System.out.println("Done");
    cipherTest.run();
    time = System.currentTimeMillis() - time;
    System.out.println("Done. (" + time + " ms)");
  }
 public String getClasspath() {
   final StringBuilder sb = new StringBuilder();
   boolean firstPass = true;
   final Enumeration<File> componentEnum = this.pathComponents.elements();
   while (componentEnum.hasMoreElements()) {
     if (!firstPass) {
       sb.append(System.getProperty("path.separator"));
     } else {
       firstPass = false;
     }
     sb.append(componentEnum.nextElement().getAbsolutePath());
   }
   return sb.toString();
 }
Example #12
0
 private PermissionInfoCollection getImpliedPermission(Bundle bundle) {
   if (impliedPermissionInfos == null) return null;
   // create the implied AdminPermission actions for this bundle
   PermissionInfo impliedAdminPermission =
       new PermissionInfo(
           AdminPermission.class.getName(),
           "(id=" + bundle.getBundleId() + ")",
           ADMIN_IMPLIED_ACTIONS); //$NON-NLS-1$ //$NON-NLS-2$
   PermissionInfo[] bundleImpliedInfos = new PermissionInfo[impliedPermissionInfos.length + 1];
   System.arraycopy(
       impliedPermissionInfos, 0, bundleImpliedInfos, 0, impliedPermissionInfos.length);
   bundleImpliedInfos[impliedPermissionInfos.length] = impliedAdminPermission;
   return new PermissionInfoCollection(getFileRelativeInfos(bundleImpliedInfos, bundle));
 }
  void startActivityNotification(PendingIntent intent, String certName) {
    Notification n =
        new Notification(
            android.R.drawable.ic_lock_lock,
            master.getString(R.string.mtm_notification),
            System.currentTimeMillis());
    n.setLatestEventInfo(
        master.getApplicationContext(),
        master.getString(R.string.mtm_notification),
        certName,
        intent);
    n.flags |= Notification.FLAG_AUTO_CANCEL;

    notificationManager.notify(NOTIFICATION_ID, n);
  }
  /** {@inheritDoc} */
  @Override
  public VerifyCertificateDialog createDialog(Certificate[] certs, String title, String message) {
    if (title == null)
      title = JitsiApplication.getResString(R.string.service_gui_CERT_DIALOG_TITLE);

    Long requestId = System.currentTimeMillis();

    VerifyCertDialog verifyCertDialog = new VerifyCertDialog(requestId, certs[0], title, message);

    requestMap.put(requestId, verifyCertDialog);

    logger.debug(hashCode() + " creating dialog: " + requestId);

    return verifyCertDialog;
  }
  // We can use Notification.Builder once MTM's minSDK is >= 11
  @SuppressWarnings("deprecation")
  void startActivityNotification(Intent intent, int decisionId, String certName) {
    Notification n =
        new Notification(
            android.R.drawable.ic_lock_lock,
            master.getString(R.string.mtm_notification),
            System.currentTimeMillis());
    PendingIntent call = PendingIntent.getActivity(master, 0, intent, 0);
    n.setLatestEventInfo(
        master.getApplicationContext(),
        master.getString(R.string.mtm_notification),
        certName,
        call);
    n.flags |= Notification.FLAG_AUTO_CANCEL;

    notificationManager.notify(NOTIFICATION_ID + decisionId, n);
  }
Example #16
0
  public static void main(String[] args) throws Exception {
    String keyFilename =
        System.getProperty("test.src", "./") + "/" + pathToStores + "/" + keyStoreFile;
    String trustFilename =
        System.getProperty("test.src", "./") + "/" + pathToStores + "/" + trustStoreFile;

    System.setProperty("javax.net.ssl.keyStore", keyFilename);
    System.setProperty("javax.net.ssl.keyStorePassword", passwd);
    System.setProperty("javax.net.ssl.trustStore", trustFilename);
    System.setProperty("javax.net.ssl.trustStorePassword", passwd);

    if (debug) System.setProperty("javax.net.debug", "all");

    /*
     * Start the tests.
     */
    new JavaxHTTPSConnection();
  }
Example #17
0
 public void checkServerTrusted(X509Certificate[] chain, String authType)
     throws CertificateException {
   try {
     tm.checkServerTrusted(chain, authType);
   } catch (CertificateException e) {
     Object[] answer = {"Proceed", "Exit"};
     int ret =
         JOptionPane.showOptionDialog(
             null,
             e.getCause().getLocalizedMessage() + "\n" + "Continue connecting to this host?",
             "Confirm certificate exception?",
             JOptionPane.YES_NO_OPTION,
             JOptionPane.WARNING_MESSAGE,
             null,
             answer,
             answer[0]);
     if (ret == JOptionPane.NO_OPTION) System.exit(1);
   } catch (java.lang.Exception e) {
     throw new Exception(e.toString());
   }
 }
Example #18
0
 private static void checkAllPermission() {
   SecurityManager sm = System.getSecurityManager();
   if (sm != null) sm.checkPermission(new AllPermission());
 }
Example #19
0
 /** This should always be called before attempting to call sendPayment. */
 public boolean isExpired() {
   return paymentDetails.hasExpires()
       && System.currentTimeMillis() / 1000L > paymentDetails.getExpires();
 }
public class CheckMyTrustedKeystore {

  /*
   * =============================================================
   * Set the various variables needed for the tests, then
   * specify what tests to run on each side.
   */

  /*
   * Should we run the client or server in a separate thread?
   * Both sides can throw exceptions, but do you have a preference
   * as to which side should be the main thread.
   */
  static boolean separateServerThread = true;

  /*
   * Where do we find the keystores?
   */
  static final String pathToStores = "../etc";
  static final String keyStoreFile = "keystore";
  static final String trustStoreFile = "truststore";
  static final String unknownStoreFile = "unknown_keystore";
  static final String passwd = "passphrase";
  static final char[] cpasswd = "passphrase".toCharArray();

  /*
   * Is the server ready to serve?
   */
  static volatile boolean serverReady = false;

  /*
   * Turn on SSL debugging?
   */
  static final boolean debug = false;

  /*
   * If the client or server is doing some kind of object creation
   * that the other side depends on, and that thread prematurely
   * exits, you may experience a hang.  The test harness will
   * terminate all hung threads after its timeout has expired,
   * currently 3 minutes by default, but you might try to be
   * smart about it....
   */

  /*
   * Define the server side of the test.
   *
   * If the server prematurely exits, serverReady will be set to true
   * to avoid infinite hangs.
   */
  void doServerSide() throws Exception {
    KeyStore ks = KeyStore.getInstance("JKS");
    com.sun.net.ssl.SSLContext ctx = com.sun.net.ssl.SSLContext.getInstance("TLS");
    com.sun.net.ssl.KeyManagerFactory kmf =
        com.sun.net.ssl.KeyManagerFactory.getInstance("SunX509");

    ks.load(new FileInputStream(keyFilename), cpasswd);
    kmf.init(ks, cpasswd);

    com.sun.net.ssl.TrustManager[] tms =
        new com.sun.net.ssl.TrustManager[] {new MyComX509TrustManager()};

    ctx.init(kmf.getKeyManagers(), tms, null);

    SSLServerSocketFactory sslssf = (SSLServerSocketFactory) ctx.getServerSocketFactory();

    SSLServerSocket sslServerSocket = (SSLServerSocket) sslssf.createServerSocket(serverPort);
    serverPort = sslServerSocket.getLocalPort();

    sslServerSocket.setNeedClientAuth(true);

    /*
     * Create using the other type.
     */
    SSLContext ctx1 = SSLContext.getInstance("TLS");
    KeyManagerFactory kmf1 = KeyManagerFactory.getInstance("SunX509");

    TrustManager[] tms1 = new TrustManager[] {new MyJavaxX509TrustManager()};

    kmf1.init(ks, cpasswd);

    ctx1.init(kmf1.getKeyManagers(), tms1, null);

    sslssf = (SSLServerSocketFactory) ctx1.getServerSocketFactory();

    SSLServerSocket sslServerSocket1 = (SSLServerSocket) sslssf.createServerSocket(serverPort1);
    serverPort1 = sslServerSocket1.getLocalPort();
    sslServerSocket1.setNeedClientAuth(true);

    /*
     * Signal Client, we're ready for his connect.
     */
    serverReady = true;

    SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
    sslServerSocket.close();
    serverReady = false;

    InputStream sslIS = sslSocket.getInputStream();
    OutputStream sslOS = sslSocket.getOutputStream();

    sslIS.read();
    sslOS.write(85);
    sslOS.flush();
    sslSocket.close();

    sslSocket = (SSLSocket) sslServerSocket1.accept();
    sslIS = sslSocket.getInputStream();
    sslOS = sslSocket.getOutputStream();

    sslIS.read();
    sslOS.write(85);
    sslOS.flush();
    sslSocket.close();

    System.out.println("Server exiting!");
    System.out.flush();
  }

  void doTest(SSLSocket sslSocket) throws Exception {
    InputStream sslIS = sslSocket.getInputStream();
    OutputStream sslOS = sslSocket.getOutputStream();

    System.out.println("  Writing");
    sslOS.write(280);
    sslOS.flush();
    System.out.println("  Reading");
    sslIS.read();

    sslSocket.close();
  }

  /*
   * Define the client side of the test.
   *
   * If the server prematurely exits, serverReady will be set to true
   * to avoid infinite hangs.
   */
  void doClientSide() throws Exception {

    /*
     * Wait for server to get started.
     */
    while (!serverReady) {
      Thread.sleep(50);
    }

    /*
     * See if an unknown keystore actually gets checked ok.
     */
    System.out.println("==============");
    System.out.println("Starting test0");
    KeyStore uks = KeyStore.getInstance("JKS");
    SSLContext ctx = SSLContext.getInstance("TLS");
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

    uks.load(new FileInputStream(unknownFilename), cpasswd);
    kmf.init(uks, cpasswd);

    TrustManager[] tms = new TrustManager[] {new MyJavaxX509TrustManager()};

    ctx.init(kmf.getKeyManagers(), tms, null);

    SSLSocketFactory sslsf = (SSLSocketFactory) ctx.getSocketFactory();

    System.out.println("Trying first socket " + serverPort);
    SSLSocket sslSocket = (SSLSocket) sslsf.createSocket("localhost", serverPort);

    doTest(sslSocket);

    /*
     * Now try the other way.
     */
    com.sun.net.ssl.SSLContext ctx1 = com.sun.net.ssl.SSLContext.getInstance("TLS");
    com.sun.net.ssl.KeyManagerFactory kmf1 =
        com.sun.net.ssl.KeyManagerFactory.getInstance("SunX509");
    kmf1.init(uks, cpasswd);

    com.sun.net.ssl.TrustManager[] tms1 =
        new com.sun.net.ssl.TrustManager[] {new MyComX509TrustManager()};

    ctx1.init(kmf1.getKeyManagers(), tms1, null);

    sslsf = (SSLSocketFactory) ctx1.getSocketFactory();

    System.out.println("Trying second socket " + serverPort1);
    sslSocket = (SSLSocket) sslsf.createSocket("localhost", serverPort1);

    doTest(sslSocket);
    System.out.println("Completed test1");
  }

  /*
   * =============================================================
   * The remainder is just support stuff
   */

  int serverPort = 0;
  int serverPort1 = 0;

  volatile Exception serverException = null;
  volatile Exception clientException = null;

  static final String keyFilename =
      System.getProperty("test.src", "./") + "/" + pathToStores + "/" + keyStoreFile;
  static final String unknownFilename =
      System.getProperty("test.src", "./") + "/" + pathToStores + "/" + unknownStoreFile;

  public static void main(String[] args) throws Exception {

    if (debug) System.setProperty("javax.net.debug", "all");

    /*
     * Start the tests.
     */
    new CheckMyTrustedKeystore();
  }

  Thread clientThread = null;
  Thread serverThread = null;

  /*
   * Primary constructor, used to drive remainder of the test.
   *
   * Fork off the other side, then do your work.
   */
  CheckMyTrustedKeystore() throws Exception {
    if (separateServerThread) {
      startServer(true);
      startClient(false);
    } else {
      startClient(true);
      startServer(false);
    }

    /*
     * Wait for other side to close down.
     */
    if (separateServerThread) {
      serverThread.join();
    } else {
      clientThread.join();
    }

    /*
     * When we get here, the test is pretty much over.
     *
     * If the main thread excepted, that propagates back
     * immediately.  If the other thread threw an exception, we
     * should report back.
     */
    if (serverException != null) {
      System.out.print("Server Exception:");
      throw serverException;
    }
    if (clientException != null) {
      System.out.print("Client Exception:");
      throw clientException;
    }
  }

  void startServer(boolean newThread) throws Exception {
    if (newThread) {
      serverThread =
          new Thread() {
            public void run() {
              try {
                doServerSide();
              } catch (Exception e) {
                /*
                 * Our server thread just died.
                 *
                 * Release the client, if not active already...
                 */
                System.err.println("Server died...");
                serverReady = true;
                serverException = e;
              }
            }
          };
      serverThread.start();
    } else {
      doServerSide();
    }
  }

  void startClient(boolean newThread) throws Exception {
    if (newThread) {
      clientThread =
          new Thread() {
            public void run() {
              try {
                doClientSide();
              } catch (Exception e) {
                /*
                 * Our client thread just died.
                 */
                System.err.println("Client died...");
                clientException = e;
              }
            }
          };
      clientThread.start();
    } else {
      doClientSide();
    }
  }
}
Example #21
0
  X509Certificate[] engineValidate(X509Certificate[] chain, Collection otherCerts, Object parameter)
      throws CertificateException {
    if ((chain == null) || (chain.length == 0)) {
      throw new CertificateException("null or zero-length certificate chain");
    }
    if (TRY_VALIDATOR) {
      // check that chain is in correct order and check if chain contains
      // trust anchor
      X500Principal prevIssuer = null;
      for (int i = 0; i < chain.length; i++) {
        X509Certificate cert = chain[i];
        X500Principal dn = cert.getSubjectX500Principal();
        if (i != 0 && !dn.equals(prevIssuer)) {
          // chain is not ordered correctly, call builder instead
          return doBuild(chain, otherCerts);
        }

        // Check if chain[i] is already trusted. It may be inside
        // trustedCerts, or has the same dn and public key as a cert
        // inside trustedCerts. The latter happens when a CA has
        // updated its cert with a stronger signature algorithm in JRE
        // but the weak one is still in circulation.

        if (trustedCerts.contains(cert)
            || // trusted cert
            (trustedSubjects.containsKey(dn)
                && // replacing ...
                trustedSubjects
                    .get(dn)
                    .contains( // ... weak cert
                        cert.getPublicKey()))) {
          if (i == 0) {
            return new X509Certificate[] {chain[0]};
          }
          // Remove and call validator on partial chain [0 .. i-1]
          X509Certificate[] newChain = new X509Certificate[i];
          System.arraycopy(chain, 0, newChain, 0, i);
          return doValidate(newChain);
        }
        prevIssuer = cert.getIssuerX500Principal();
      }

      // apparently issued by trust anchor?
      X509Certificate last = chain[chain.length - 1];
      X500Principal issuer = last.getIssuerX500Principal();
      X500Principal subject = last.getSubjectX500Principal();
      if (trustedSubjects.containsKey(issuer)
          && isSignatureValid(trustedSubjects.get(issuer), last)) {
        return doValidate(chain);
      }

      // don't fallback to builder if called from plugin/webstart
      if (plugin) {
        // Validate chain even if no trust anchor is found. This
        // allows plugin/webstart to make sure the chain is
        // otherwise valid
        if (chain.length > 1) {
          X509Certificate[] newChain = new X509Certificate[chain.length - 1];
          System.arraycopy(chain, 0, newChain, 0, newChain.length);
          // temporarily set last cert as sole trust anchor
          PKIXBuilderParameters params = (PKIXBuilderParameters) parameterTemplate.clone();
          try {
            params.setTrustAnchors(
                Collections.singleton(new TrustAnchor(chain[chain.length - 1], null)));
          } catch (InvalidAlgorithmParameterException iape) {
            // should never occur, but ...
            throw new CertificateException(iape);
          }
          doValidate(newChain, params);
        }
        // if the rest of the chain is valid, throw exception
        // indicating no trust anchor was found
        throw new ValidatorException(ValidatorException.T_NO_TRUST_ANCHOR);
      }
      // otherwise, fall back to builder
    }

    return doBuild(chain, otherCerts);
  }
Example #22
0
public class OCSPSingleExtensions {
  public static CertificateFactory CF;
  public static final File testDir = new File(System.getProperty("test.src", "."));
  public static final Base64.Decoder B64D = Base64.getMimeDecoder();

  public static void main(String[] args) throws Exception {
    // Get a CertificateFactory for various tests
    CF = CertificateFactory.getInstance("X509");
    ByteArrayInputStream bais = new ByteArrayInputStream(readFile("int.crt").getBytes());
    X509Certificate intCA = (X509Certificate) CF.generateCertificate(bais);
    System.out.println(
        "Successfully instantiated CA cert \"" + intCA.getSubjectX500Principal() + "\"");

    CertId cid0x1500 = new CertId(intCA, new SerialNumber(0x1500));
    boolean noFailures = true;

    OCSPResponse.SingleResponse sr = getSRByFilename("ocsp-good-nonext.resp", cid0x1500);
    noFailures &= checkSingleExts(sr, 0);

    if (sr.getRevocationTime() != null) {
      throw new RuntimeException("Oops. revocationTime is non-null " + sr.getRevocationTime());
    } else if (sr.getRevocationReason() != null) {
      throw new RuntimeException("Oops. revocationReason is non-null " + sr.getRevocationReason());
    }

    sr = getSRByFilename("ocsp-good-withnext.resp", cid0x1500);
    noFailures &= checkSingleExts(sr, 0);

    sr = getSRByFilename("ocsp-good-witharchcut.resp", cid0x1500);
    noFailures &= checkSingleExts(sr, 1);

    sr = getSRByFilename("ocsp-rev-nocerts.resp", cid0x1500);
    noFailures &= checkSingleExts(sr, 1);

    sr = getSRByFilename("ocsp-rev-nonext-noinv.resp", cid0x1500);
    noFailures &= checkSingleExts(sr, 0);

    sr = getSRByFilename("ocsp-rev-withnext-noinv.resp", cid0x1500);
    noFailures &= checkSingleExts(sr, 0);

    sr = getSRByFilename("ocsp-rev-nonext-withinv.resp", cid0x1500);
    noFailures &= checkSingleExts(sr, 1);

    sr = getSRByFilename("ocsp-rev-withnext-withinv.resp", cid0x1500);
    noFailures &= checkSingleExts(sr, 1);

    try {
      sr = getSRByFilename("ocsp-rev-twonext.resp", cid0x1500);
      System.out.println("FAIL: Allowed two nextUpdate fields");
      noFailures = false;
    } catch (IOException ioe) {
      System.out.println("Caught expected exception: " + ioe);
    }

    try {
      sr = getSRByFilename("ocsp-rev-bad-sr-tag.resp", cid0x1500);
      System.out.println("FAIL: Allowed invalid singleResponse item");
      noFailures = false;
    } catch (IOException ioe) {
      System.out.println("Caught expected exception: " + ioe);
    }

    try {
      sr = getSRByFilename("ocsp-rev-sr-cont-reverse.resp", cid0x1500);
      System.out.println("FAIL: Allowed reversed " + "nextUpdate/singleExtensions");
      noFailures = false;
    } catch (IOException ioe) {
      System.out.println("Caught expected exception: " + ioe);
    }

    if (!noFailures) {
      throw new RuntimeException("One or more tests failed");
    }
  }

  private static OCSPResponse.SingleResponse getSRByFilename(String fileName, CertId cid)
      throws IOException {
    byte[] respDER = B64D.decode(readFile(fileName));
    OCSPResponse or = new OCSPResponse(respDER);
    OCSPResponse.SingleResponse sr = or.getSingleResponse(cid);
    return sr;
  }

  private static String readFile(String fileName) throws IOException {
    String filePath = testDir + "/" + fileName;
    StringBuilder sb = new StringBuilder();

    try (FileReader fr = new FileReader(filePath);
        BufferedReader br = new BufferedReader(fr)) {
      String line;
      while ((line = br.readLine()) != null) {
        if (!line.trim().startsWith("#")) {
          sb.append(line).append("\n");
        }
      }
    }

    System.out.println("Successfully read " + fileName);
    return sb.toString();
  }

  private static boolean checkSingleExts(OCSPResponse.SingleResponse sr, int singleExtCount) {
    Map<String, Extension> singleExts;
    try {
      singleExts = sr.getSingleExtensions();
    } catch (NullPointerException npe) {
      System.out.println("Warning: Sent null singleResponse into checkSingleExts");
      return false;
    }

    for (String key : singleExts.keySet()) {
      System.out.println("singleExtension: " + singleExts.get(key));
    }

    if (singleExts.size() != singleExtCount) {
      System.out.println(
          "Single Extension count mismatch, "
              + "expected "
              + singleExtCount
              + ", got "
              + singleExts.size());
      return false;
    } else {
      return true;
    }
  }
}
Example #23
0
public final class SecurityAdmin implements PermissionAdmin, ConditionalPermissionAdmin {
  private static final PermissionCollection DEFAULT_DEFAULT;

  static {
    AllPermission allPerm = new AllPermission();
    DEFAULT_DEFAULT = allPerm.newPermissionCollection();
    if (DEFAULT_DEFAULT != null) DEFAULT_DEFAULT.add(allPerm);
  }

  private static final String ADMIN_IMPLIED_ACTIONS =
      AdminPermission.RESOURCE
          + ','
          + AdminPermission.METADATA
          + ','
          + AdminPermission.CLASS
          + ','
          + AdminPermission.CONTEXT;
  private static final PermissionInfo[] EMPTY_PERM_INFO = new PermissionInfo[0];
  /* @GuardedBy(lock) */
  private final PermissionAdminTable permAdminTable = new PermissionAdminTable();
  /* @GuardedBy(lock) */
  private SecurityTable condAdminTable;
  /* @GuardedBy(lock) */
  private PermissionInfoCollection permAdminDefaults;
  /* @GuardedBy(lock) */
  private long timeStamp = 0;
  /* @GuardedBy(lock) */
  private long nextID = System.currentTimeMillis();
  /* @GuardedBy(lock) */
  private final PermissionStorage permissionStorage;
  private final Object lock = new Object();
  private final Framework framework;
  private final PermissionInfo[] impliedPermissionInfos;
  private final EquinoxSecurityManager supportedSecurityManager;

  private SecurityAdmin(
      EquinoxSecurityManager supportedSecurityManager,
      Framework framework,
      PermissionInfo[] impliedPermissionInfos,
      PermissionInfoCollection permAdminDefaults) {
    this.supportedSecurityManager = supportedSecurityManager;
    this.framework = framework;
    this.impliedPermissionInfos = impliedPermissionInfos;
    this.permAdminDefaults = permAdminDefaults;
    this.permissionStorage = null;
  }

  public SecurityAdmin(
      EquinoxSecurityManager supportedSecurityManager,
      Framework framework,
      PermissionStorage permissionStorage)
      throws IOException {
    this.supportedSecurityManager = supportedSecurityManager;
    this.framework = framework;
    this.permissionStorage = new SecurePermissionStorage(permissionStorage);
    this.impliedPermissionInfos =
        SecurityAdmin.getPermissionInfos(
            getClass().getResource(Constants.OSGI_BASE_IMPLIED_PERMISSIONS), framework);
    String[] encodedDefaultInfos = permissionStorage.getPermissionData(null);
    PermissionInfo[] defaultInfos = getPermissionInfos(encodedDefaultInfos);
    if (defaultInfos != null) permAdminDefaults = new PermissionInfoCollection(defaultInfos);
    String[] locations = permissionStorage.getLocations();
    if (locations != null) {
      for (int i = 0; i < locations.length; i++) {
        String[] encodedLocationInfos = permissionStorage.getPermissionData(locations[i]);
        if (encodedLocationInfos != null) {
          PermissionInfo[] locationInfos = getPermissionInfos(encodedLocationInfos);
          permAdminTable.setPermissions(locations[i], locationInfos);
        }
      }
    }
    String[] encodedCondPermInfos = permissionStorage.getConditionalPermissionInfos();
    if (encodedCondPermInfos == null) condAdminTable = new SecurityTable(this, new SecurityRow[0]);
    else {
      SecurityRow[] rows = new SecurityRow[encodedCondPermInfos.length];
      try {
        for (int i = 0; i < rows.length; i++)
          rows[i] = SecurityRow.createSecurityRow(this, encodedCondPermInfos[i]);
      } catch (IllegalArgumentException e) {
        // TODO should log
        // bad format persisted in storage; start clean
        rows = new SecurityRow[0];
      }
      condAdminTable = new SecurityTable(this, rows);
    }
  }

  private static PermissionInfo[] getPermissionInfos(String[] encodedInfos) {
    if (encodedInfos == null) return null;
    PermissionInfo[] results = new PermissionInfo[encodedInfos.length];
    for (int i = 0; i < results.length; i++) results[i] = new PermissionInfo(encodedInfos[i]);
    return results;
  }

  boolean checkPermission(Permission permission, BundlePermissions bundlePermissions) {
    // check permissions by location
    PermissionInfoCollection locationCollection;
    SecurityTable curCondAdminTable;
    PermissionInfoCollection curPermAdminDefaults;
    // save off the current state of the world while holding the lock
    synchronized (lock) {
      // get location the hard way to avoid permission check
      Bundle bundle = bundlePermissions.getBundle();
      locationCollection =
          bundle instanceof AbstractBundle
              ? permAdminTable.getCollection(
                  ((AbstractBundle) bundle).getBundleData().getLocation())
              : null;
      curCondAdminTable = condAdminTable;
      curPermAdminDefaults = permAdminDefaults;
    }
    if (locationCollection != null) return locationCollection.implies(permission);
    // if conditional admin table is empty the fall back to defaults
    if (curCondAdminTable.isEmpty())
      return curPermAdminDefaults != null
          ? curPermAdminDefaults.implies(permission)
          : DEFAULT_DEFAULT.implies(permission);
    // check the condition table
    int result = curCondAdminTable.evaluate(bundlePermissions, permission);
    if ((result & SecurityTable.GRANTED) != 0) return true;
    if ((result & SecurityTable.DENIED) != 0) return false;
    if ((result & SecurityTable.POSTPONED) != 0) return true;
    return false;
  }

  public PermissionInfo[] getDefaultPermissions() {
    synchronized (lock) {
      if (permAdminDefaults == null) return null;
      return permAdminDefaults.getPermissionInfos();
    }
  }

  public String[] getLocations() {
    synchronized (lock) {
      String[] results = permAdminTable.getLocations();
      return results.length == 0 ? null : results;
    }
  }

  public PermissionInfo[] getPermissions(String location) {
    synchronized (lock) {
      return permAdminTable.getPermissions(location);
    }
  }

  public void setDefaultPermissions(PermissionInfo[] permissions) {
    checkAllPermission();
    synchronized (lock) {
      if (permissions == null) permAdminDefaults = null;
      else permAdminDefaults = new PermissionInfoCollection(permissions);
      try {
        permissionStorage.setPermissionData(null, getEncodedPermissionInfos(permissions));
      } catch (IOException e) {
        // log
        e.printStackTrace();
      }
    }
  }

  private static void checkAllPermission() {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) sm.checkPermission(new AllPermission());
  }

  private static String[] getEncodedPermissionInfos(PermissionInfo[] permissions) {
    if (permissions == null) return null;
    String[] encoded = new String[permissions.length];
    for (int i = 0; i < encoded.length; i++) encoded[i] = permissions[i].getEncoded();
    return encoded;
  }

  public void setPermissions(String location, PermissionInfo[] permissions) {
    checkAllPermission();
    synchronized (lock) {
      permAdminTable.setPermissions(location, permissions);
      try {
        permissionStorage.setPermissionData(location, getEncodedPermissionInfos(permissions));
      } catch (IOException e) {
        // TODO log
        e.printStackTrace();
      }
    }
  }

  void delete(SecurityRow securityRow, boolean firstTry) {
    ConditionalPermissionUpdate update = newConditionalPermissionUpdate();
    List rows = update.getConditionalPermissionInfos();
    for (Iterator iRows = rows.iterator(); iRows.hasNext(); ) {
      ConditionalPermissionInfo info = (ConditionalPermissionInfo) iRows.next();
      if (securityRow.getName().equals(info.getName())) {
        iRows.remove();
        synchronized (lock) {
          if (!update.commit()) {
            if (firstTry)
              // try again
              delete(securityRow, false);
          }
        }
        break;
      }
    }
  }

  /** @deprecated */
  public ConditionalPermissionInfo addConditionalPermissionInfo(
      ConditionInfo[] conds, PermissionInfo[] perms) {
    return setConditionalPermissionInfo(null, conds, perms, true);
  }

  public ConditionalPermissionInfo newConditionalPermissionInfo(
      String name, ConditionInfo[] conditions, PermissionInfo[] permissions, String decision) {
    return new SecurityRowSnapShot(name, conditions, permissions, decision);
  }

  public ConditionalPermissionInfo newConditionalPermissionInfo(String encoded) {
    return SecurityRow.createSecurityRowSnapShot(encoded);
  }

  public ConditionalPermissionUpdate newConditionalPermissionUpdate() {
    synchronized (lock) {
      return new SecurityTableUpdate(this, condAdminTable.getRows(), timeStamp);
    }
  }

  public AccessControlContext getAccessControlContext(String[] signers) {
    SecurityAdmin snapShot = getSnapShot();
    return new AccessControlContext(
        new ProtectionDomain[] {createProtectionDomain(createMockBundle(signers), snapShot)});
  }

  /** @deprecated */
  public ConditionalPermissionInfo getConditionalPermissionInfo(String name) {
    synchronized (lock) {
      return condAdminTable.getRow(name);
    }
  }

  /** @deprecated */
  public Enumeration getConditionalPermissionInfos() {
    // could implement our own Enumeration, but we don't care about performance here.  Just do
    // something simple:
    synchronized (lock) {
      SecurityRow[] rows = condAdminTable.getRows();
      Vector vRows = new Vector(rows.length);
      for (int i = 0; i < rows.length; i++) vRows.add(rows[i]);
      return vRows.elements();
    }
  }

  /** @deprecated */
  public ConditionalPermissionInfo setConditionalPermissionInfo(
      String name, ConditionInfo[] conds, PermissionInfo[] perms) {
    return setConditionalPermissionInfo(name, conds, perms, true);
  }

  private SecurityAdmin getSnapShot() {
    SecurityAdmin sa;
    synchronized (lock) {
      sa =
          new SecurityAdmin(
              supportedSecurityManager, framework, impliedPermissionInfos, permAdminDefaults);
      SecurityRow[] rows = condAdminTable.getRows();
      SecurityRow[] rowsSnapShot = new SecurityRow[rows.length];
      for (int i = 0; i < rows.length; i++)
        rowsSnapShot[i] =
            new SecurityRow(
                sa,
                rows[i].getName(),
                rows[i].getConditionInfos(),
                rows[i].getPermissionInfos(),
                rows[i].getAccessDecision());
      sa.condAdminTable = new SecurityTable(sa, rowsSnapShot);
    }
    return sa;
  }

  private ConditionalPermissionInfo setConditionalPermissionInfo(
      String name, ConditionInfo[] conds, PermissionInfo[] perms, boolean firstTry) {
    ConditionalPermissionUpdate update = newConditionalPermissionUpdate();
    List rows = update.getConditionalPermissionInfos();
    ConditionalPermissionInfo newInfo =
        newConditionalPermissionInfo(name, conds, perms, ConditionalPermissionInfo.ALLOW);
    int index = -1;
    if (name != null) {
      for (int i = 0; i < rows.size() && index < 0; i++) {
        ConditionalPermissionInfo info = (ConditionalPermissionInfo) rows.get(i);
        if (name.equals(info.getName())) {
          index = i;
        }
      }
    }
    if (index < 0) {
      // must always add to the beginning (bug 303930)
      rows.add(0, newInfo);
      index = 0;
    } else {
      rows.set(index, newInfo);
    }
    synchronized (lock) {
      if (!update.commit()) {
        if (firstTry)
          // try again
          setConditionalPermissionInfo(name, conds, perms, false);
      }
      return condAdminTable.getRow(index);
    }
  }

  boolean commit(List rows, long updateStamp) {
    checkAllPermission();
    synchronized (lock) {
      if (updateStamp != timeStamp) return false;
      SecurityRow[] newRows = new SecurityRow[rows.size()];
      Collection names = new ArrayList();
      for (int i = 0; i < newRows.length; i++) {
        Object rowObj = rows.get(i);
        if (!(rowObj instanceof ConditionalPermissionInfo))
          throw new IllegalStateException(
              "Invalid type \""
                  + rowObj.getClass().getName()
                  + "\" at row: "
                  + i); //$NON-NLS-1$//$NON-NLS-2$
        ConditionalPermissionInfo infoBaseRow = (ConditionalPermissionInfo) rowObj;
        String name = infoBaseRow.getName();
        if (name == null) name = generateName();
        if (names.contains(name))
          throw new IllegalStateException(
              "Duplicate name \"" + name + "\" at row: " + i); // $NON-NLS-1$//$NON-NLS-2$
        newRows[i] =
            new SecurityRow(
                this,
                name,
                infoBaseRow.getConditionInfos(),
                infoBaseRow.getPermissionInfos(),
                infoBaseRow.getAccessDecision());
      }
      condAdminTable = new SecurityTable(this, newRows);
      try {
        permissionStorage.saveConditionalPermissionInfos(condAdminTable.getEncodedRows());
      } catch (IOException e) {
        // TODO log
        e.printStackTrace();
      }
      timeStamp += 1;
      return true;
    }
  }

  /* GuardedBy(lock) */
  private String generateName() {
    return "generated_" + Long.toString(nextID++); // $NON-NLS-1$;
  }

  public BundleProtectionDomain createProtectionDomain(Bundle bundle) {
    return createProtectionDomain(bundle, this);
  }

  private BundleProtectionDomain createProtectionDomain(Bundle bundle, SecurityAdmin sa) {
    PermissionInfoCollection impliedPermissions = getImpliedPermission(bundle);
    PermissionInfo[] restrictedInfos =
        getFileRelativeInfos(
            SecurityAdmin.getPermissionInfos(
                bundle.getEntry("OSGI-INF/permissions.perm"), framework),
            bundle); //$NON-NLS-1$
    PermissionInfoCollection restrictedPermissions =
        restrictedInfos == null ? null : new PermissionInfoCollection(restrictedInfos);
    BundlePermissions bundlePermissions =
        new BundlePermissions(bundle, sa, impliedPermissions, restrictedPermissions);
    return new BundleProtectionDomain(bundlePermissions, null, bundle);
  }

  private PermissionInfoCollection getImpliedPermission(Bundle bundle) {
    if (impliedPermissionInfos == null) return null;
    // create the implied AdminPermission actions for this bundle
    PermissionInfo impliedAdminPermission =
        new PermissionInfo(
            AdminPermission.class.getName(),
            "(id=" + bundle.getBundleId() + ")",
            ADMIN_IMPLIED_ACTIONS); //$NON-NLS-1$ //$NON-NLS-2$
    PermissionInfo[] bundleImpliedInfos = new PermissionInfo[impliedPermissionInfos.length + 1];
    System.arraycopy(
        impliedPermissionInfos, 0, bundleImpliedInfos, 0, impliedPermissionInfos.length);
    bundleImpliedInfos[impliedPermissionInfos.length] = impliedAdminPermission;
    return new PermissionInfoCollection(getFileRelativeInfos(bundleImpliedInfos, bundle));
  }

  private PermissionInfo[] getFileRelativeInfos(PermissionInfo[] permissionInfos, Bundle bundle) {
    if (permissionInfos == null || !(bundle instanceof AbstractBundle)) return permissionInfos;
    PermissionInfo[] results = new PermissionInfo[permissionInfos.length];
    for (int i = 0; i < permissionInfos.length; i++) {
      results[i] = permissionInfos[i];
      if ("java.io.FilePermission".equals(permissionInfos[i].getType())) { // $NON-NLS-1$
        if (!"<<ALL FILES>>".equals(permissionInfos[i].getName())) { // $NON-NLS-1$
          File file = new File(permissionInfos[i].getName());
          if (!file.isAbsolute()) { // relative name
            File target =
                ((AbstractBundle) bundle).getBundleData().getDataFile(permissionInfos[i].getName());
            if (target != null)
              results[i] =
                  new PermissionInfo(
                      permissionInfos[i].getType(),
                      target.getPath(),
                      permissionInfos[i].getActions());
          }
        }
      }
    }
    return results;
  }

  public void clearCaches() {
    PermissionInfoCollection[] permAdminCollections;
    SecurityRow[] condAdminRows;
    synchronized (lock) {
      permAdminCollections = permAdminTable.getCollections();
      condAdminRows = condAdminTable.getRows();
    }
    for (int i = 0; i < permAdminCollections.length; i++)
      permAdminCollections[i].clearPermissionCache();
    for (int i = 0; i < condAdminRows.length; i++) condAdminRows[i].clearCaches();
  }

  EquinoxSecurityManager getSupportedSecurityManager() {
    return supportedSecurityManager != null
        ? supportedSecurityManager
        : getSupportedSystemSecurityManager();
  }

  private static EquinoxSecurityManager getSupportedSystemSecurityManager() {
    try {
      EquinoxSecurityManager equinoxManager = (EquinoxSecurityManager) System.getSecurityManager();
      return equinoxManager != null && equinoxManager.inCheckPermission() ? equinoxManager : null;
    } catch (ClassCastException e) {
      return null;
    }
  }

  private static PermissionInfo[] getPermissionInfos(URL resource, Framework framework) {
    if (resource == null) return null;
    PermissionInfo[] info = EMPTY_PERM_INFO;
    DataInputStream in = null;
    try {
      in = new DataInputStream(resource.openStream());
      ArrayList permissions = new ArrayList();
      BufferedReader reader;
      try {
        reader = new BufferedReader(new InputStreamReader(in, "UTF8")); // $NON-NLS-1$
      } catch (UnsupportedEncodingException e) {
        reader = new BufferedReader(new InputStreamReader(in));
      }

      while (true) {
        String line = reader.readLine();
        if (line == null) /* EOF */ break;
        line = line.trim();
        if ((line.length() == 0)
            || line.startsWith("#")
            || line.startsWith("//")) /* comments */ // $NON-NLS-1$ //$NON-NLS-2$
        continue;

        try {
          permissions.add(new PermissionInfo(line));
        } catch (IllegalArgumentException iae) {
          /* incorrectly encoded permission */
          if (framework != null)
            framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.getBundle(0), iae);
        }
      }
      int size = permissions.size();
      if (size > 0) info = (PermissionInfo[]) permissions.toArray(new PermissionInfo[size]);
    } catch (IOException e) {
      // do nothing
    } finally {
      try {
        if (in != null) in.close();
      } catch (IOException ee) {
        // do nothing
      }
    }
    return info;
  }

  private static Bundle createMockBundle(String[] signers) {
    Map /* <X509Certificate, List<X509Certificate>> */ signersMap = new HashMap();
    for (int i = 0; i < signers.length; i++) {
      List chain = parseDNchain(signers[i]);
      List /* <X509Certificate> */ signersList = new ArrayList();
      Principal subject = null, issuer = null;
      X509Certificate first = null;
      for (Iterator iChain = chain.iterator(); iChain.hasNext(); ) {
        subject = issuer == null ? new MockPrincipal((String) iChain.next()) : issuer;
        issuer = iChain.hasNext() ? new MockPrincipal((String) iChain.next()) : subject;
        X509Certificate cert = new MockX509Certificate(subject, issuer);
        if (first == null) first = cert;
        signersList.add(cert);
      }
      if (subject != issuer) signersList.add(new MockX509Certificate(issuer, issuer));
      signersMap.put(first, signersList);
    }
    return new MockBundle(signersMap);
  }

  static class MockBundle implements Bundle {
    private final Map signers;

    MockBundle(Map signers) {
      this.signers = signers;
    }

    public Enumeration findEntries(String path, String filePattern, boolean recurse) {
      return null;
    }

    public BundleContext getBundleContext() {
      return null;
    }

    public long getBundleId() {
      return -1;
    }

    public URL getEntry(String path) {
      return null;
    }

    public Enumeration getEntryPaths(String path) {
      return null;
    }

    public Dictionary getHeaders() {
      return new Hashtable();
    }

    public Dictionary getHeaders(String locale) {
      return getHeaders();
    }

    public long getLastModified() {
      return 0;
    }

    public String getLocation() {
      return ""; //$NON-NLS-1$
    }

    public ServiceReference[] getRegisteredServices() {
      return null;
    }

    public URL getResource(String name) {
      return null;
    }

    /** @throws IOException */
    public Enumeration getResources(String name) throws IOException {
      return null;
    }

    public ServiceReference[] getServicesInUse() {
      return null;
    }

    public Map getSignerCertificates(int signersType) {
      return new HashMap(signers);
    }

    public int getState() {
      return Bundle.UNINSTALLED;
    }

    public String getSymbolicName() {
      return null;
    }

    public Version getVersion() {
      return Version.emptyVersion;
    }

    public boolean hasPermission(Object permission) {
      return false;
    }

    /** @throws ClassNotFoundException */
    public Class loadClass(String name) throws ClassNotFoundException {
      throw new IllegalStateException();
    }

    /** @throws BundleException */
    public void start(int options) throws BundleException {
      throw new IllegalStateException();
    }

    /** @throws BundleException */
    public void start() throws BundleException {
      throw new IllegalStateException();
    }

    /** @throws BundleException */
    public void stop(int options) throws BundleException {
      throw new IllegalStateException();
    }

    /** @throws BundleException */
    public void stop() throws BundleException {
      throw new IllegalStateException();
    }

    /** @throws BundleException */
    public void uninstall() throws BundleException {
      throw new IllegalStateException();
    }

    /** @throws BundleException */
    public void update() throws BundleException {
      throw new IllegalStateException();
    }

    /** @throws BundleException */
    public void update(InputStream in) throws BundleException {
      throw new IllegalStateException();
    }
  }

  private static class MockX509Certificate extends X509Certificate {
    private final Principal subject;
    private final Principal issuer;

    MockX509Certificate(Principal subject, Principal issuer) {
      this.subject = subject;
      this.issuer = issuer;
    }

    public Principal getSubjectDN() {
      return subject;
    }

    public boolean equals(Object obj) {
      if (this == obj) return true;
      if (obj instanceof MockX509Certificate)
        return subject.equals(((MockX509Certificate) obj).subject)
            && issuer.equals(((MockX509Certificate) obj).issuer);
      return false;
    }

    public int hashCode() {
      return subject.hashCode() + issuer.hashCode();
    }

    public String toString() {
      return subject.toString();
    }

    /**
     * @throws CertificateExpiredException
     * @throws java.security.cert.CertificateNotYetValidException
     */
    public void checkValidity()
        throws CertificateExpiredException, java.security.cert.CertificateNotYetValidException {
      throw new UnsupportedOperationException();
    }

    /**
     * @throws java.security.cert.CertificateExpiredException
     * @throws java.security.cert.CertificateNotYetValidException
     */
    public void checkValidity(Date var0)
        throws java.security.cert.CertificateExpiredException,
            java.security.cert.CertificateNotYetValidException {
      throw new UnsupportedOperationException();
    }

    public int getBasicConstraints() {
      throw new UnsupportedOperationException();
    }

    public Principal getIssuerDN() {
      return issuer;
    }

    public boolean[] getIssuerUniqueID() {
      throw new UnsupportedOperationException();
    }

    public boolean[] getKeyUsage() {
      throw new UnsupportedOperationException();
    }

    public Date getNotAfter() {
      throw new UnsupportedOperationException();
    }

    public Date getNotBefore() {
      throw new UnsupportedOperationException();
    }

    public BigInteger getSerialNumber() {
      throw new UnsupportedOperationException();
    }

    public String getSigAlgName() {
      throw new UnsupportedOperationException();
    }

    public String getSigAlgOID() {
      throw new UnsupportedOperationException();
    }

    public byte[] getSigAlgParams() {
      throw new UnsupportedOperationException();
    }

    public byte[] getSignature() {
      throw new UnsupportedOperationException();
    }

    public boolean[] getSubjectUniqueID() {
      throw new UnsupportedOperationException();
    }

    /** @throws CertificateEncodingException */
    public byte[] getTBSCertificate() throws CertificateEncodingException {
      throw new UnsupportedOperationException();
    }

    public int getVersion() {
      throw new UnsupportedOperationException();
    }

    /** @throws CertificateEncodingException */
    public byte[] getEncoded() throws CertificateEncodingException {
      throw new UnsupportedOperationException();
    }

    public PublicKey getPublicKey() {
      throw new UnsupportedOperationException();
    }

    /**
     * @throws java.security.InvalidKeyException
     * @throws java.security.NoSuchAlgorithmException
     * @throws java.security.NoSuchProviderException
     * @throws java.security.SignatureException
     * @throws java.security.cert.CertificateException
     */
    public void verify(PublicKey var0)
        throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException,
            java.security.NoSuchProviderException, java.security.SignatureException,
            java.security.cert.CertificateException {
      throw new UnsupportedOperationException();
    }

    /**
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     * @throws SignatureException
     * @throws CertificateException
     */
    public void verify(PublicKey var0, String var1)
        throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
            SignatureException, CertificateException {
      throw new UnsupportedOperationException();
    }

    public Set getCriticalExtensionOIDs() {
      throw new UnsupportedOperationException();
    }

    public byte[] getExtensionValue(String var0) {
      throw new UnsupportedOperationException();
    }

    public Set getNonCriticalExtensionOIDs() {
      throw new UnsupportedOperationException();
    }

    public boolean hasUnsupportedCriticalExtension() {
      throw new UnsupportedOperationException();
    }
  }

  private static class MockPrincipal implements Principal {
    private final String name;

    MockPrincipal(String name) {
      this.name = name;
    }

    public String getName() {
      return name;
    }

    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj instanceof MockPrincipal) {
        return name.equals(((MockPrincipal) obj).name);
      }
      return false;
    }

    public int hashCode() {
      return name.hashCode();
    }

    public String toString() {
      return getName();
    }
  }

  private static ArrayList parseDNchain(String dnChain) {
    if (dnChain == null) {
      throw new IllegalArgumentException("The DN chain must not be null."); // $NON-NLS-1$
    }
    ArrayList parsed = new ArrayList();
    int startIndex = 0;
    startIndex = skipSpaces(dnChain, startIndex);
    while (startIndex < dnChain.length()) {
      int endIndex = startIndex;
      boolean inQuote = false;
      out:
      while (endIndex < dnChain.length()) {
        char c = dnChain.charAt(endIndex);
        switch (c) {
          case '"':
            inQuote = !inQuote;
            break;
          case '\\':
            endIndex++; // skip the escaped char
            break;
          case ';':
            if (!inQuote) break out;
        }
        endIndex++;
      }
      if (endIndex > dnChain.length()) {
        throw new IllegalArgumentException("unterminated escape");
      }
      parsed.add(dnChain.substring(startIndex, endIndex));
      startIndex = endIndex + 1;
      startIndex = skipSpaces(dnChain, startIndex);
    }
    return parsed;
  }

  private static int skipSpaces(String dnChain, int startIndex) {
    while (startIndex < dnChain.length() && dnChain.charAt(startIndex) == ' ') {
      startIndex++;
    }
    return startIndex;
  }
}