Example #1
0
  // Loads one of the built-in keys (media, platform, shared, testkey)
  public void loadKeys(String name) throws IOException, GeneralSecurityException {

    keySet = loadedKeys.get(name);
    if (keySet != null) return;

    keySet = new KeySet();
    keySet.setName(name);
    loadedKeys.put(name, keySet);

    if (KEY_NONE.equals(name)) return;

    progressHelper.progress(ProgressEvent.PRORITY_IMPORTANT, "Loading certificate and private key");

    // load the private key
    URL privateKeyUrl = getClass().getResource("/keys/" + name + ".pk8");
    keySet.setPrivateKey(readPrivateKey(privateKeyUrl, null));

    // load the certificate
    URL publicKeyUrl = getClass().getResource("/keys/" + name + ".x509.pem");
    keySet.setPublicKey(readPublicKey(publicKeyUrl));

    // load the signature block template
    URL sigBlockTemplateUrl = getClass().getResource("/keys/" + name + ".sbt");
    if (sigBlockTemplateUrl != null) {
      keySet.setSigBlockTemplate(readContentAsBytes(sigBlockTemplateUrl));
    }
  }
 public static boolean hasProjectSpecificSettings(IScopeContext context, KeySet[] keySets) {
   for (int i = 0; i < keySets.length; i++) {
     KeySet keySet = keySets[i];
     IEclipsePreferences preferences = context.getNode(keySet.getNodeName());
     for (final Iterator<String> keyIter = keySet.getKeys().iterator(); keyIter.hasNext(); ) {
       final String key = keyIter.next();
       Object val = preferences.get(key, null);
       if (val != null) {
         return true;
       }
     }
   }
   return false;
 }
  @Override
  public boolean isCanonical() {
    for (ThrowConstraint c : throwConstraints) {
      if (!c.isCanonical()) {
        return false;
      }
    }

    if (!entryKeys.isCanonical()) {
      return false;
    }

    if (returnKeys != null && !returnKeys.isCanonical()) {
      return false;
    }

    return super.isCanonical();
  }
  /**
   * Only to read project specific settings to find out to what profile it matches.
   *
   * @param context The project context
   */
  private Map<String, String> readFromPreferenceStore(
      IScopeContext context, Profile workspaceProfile) {
    final Map<String, String> profileOptions = new HashMap<String, String>();
    IEclipsePreferences uiPrefs = context.getNode(JavaUI.ID_PLUGIN);

    int version = uiPrefs.getInt(fProfileVersionKey, fProfileVersioner.getFirstVersion());
    if (version != fProfileVersioner.getCurrentVersion()) {
      Map<String, String> allOptions = new HashMap<String, String>();
      for (int i = 0; i < fKeySets.length; i++) {
        addAll(context.getNode(fKeySets[i].getNodeName()), allOptions);
      }
      CustomProfile profile =
          new CustomProfile(
              "tmp", allOptions, version, fProfileVersioner.getProfileKind()); // $NON-NLS-1$
      fProfileVersioner.update(profile);
      return profile.getSettings();
    }

    boolean hasValues = false;
    for (int i = 0; i < fKeySets.length; i++) {
      KeySet keySet = fKeySets[i];
      IEclipsePreferences preferences = context.getNode(keySet.getNodeName());
      for (final Iterator<String> keyIter = keySet.getKeys().iterator(); keyIter.hasNext(); ) {
        final String key = keyIter.next();
        String val = preferences.get(key, null);
        if (val != null) {
          hasValues = true;
        } else {
          val = workspaceProfile.getSettings().get(key);
        }
        profileOptions.put(key, val);
      }
    }

    if (!hasValues) {
      return null;
    }

    setLatestCompliance(profileOptions);
    return profileOptions;
  }
Example #5
0
  /**
   * Sign the and signature block template. The signature block template parameter may be null, but
   * if so android-sun-jarsign-support.jar must be in the classpath.
   */
  public void signZip(
      Map<String, ZioEntry> zioEntries, OutputStream outputStream, String outputZipFilename)
      throws IOException, GeneralSecurityException {
    boolean debug = getLogger().isDebugEnabled();

    progressHelper.initProgress();
    if (keySet == null) {
      if (!keymode.startsWith(MODE_AUTO))
        throw new IllegalStateException("No keys configured for signing the file!");

      // Auto-determine which keys to use
      String keyName = this.autoDetectKey(keymode, zioEntries);
      if (keyName == null)
        throw new AutoKeyException(
            "Unable to auto-select key for signing " + new File(outputZipFilename).getName());

      autoKeyObservable.notifyObservers(keyName);

      loadKeys(keyName);
    }

    ZipOutput zipOutput = null;

    try {

      zipOutput = new ZipOutput(outputStream);

      if (KEY_NONE.equals(keySet.getName())) {
        progressHelper.setProgressTotalItems(zioEntries.size());
        progressHelper.setProgressCurrentItem(0);
        copyFiles(zioEntries, zipOutput);
        return;
      }

      // Calculate total steps to complete for accurate progress percentages.
      int progressTotalItems = 0;
      for (ZioEntry entry : zioEntries.values()) {
        String name = entry.getName();
        if (!entry.isDirectory()
            && !name.equals(JarFile.MANIFEST_NAME)
            && !name.equals(CERT_SF_NAME)
            && !name.equals(CERT_RSA_NAME)
            && (stripPattern == null || !stripPattern.matcher(name).matches())) {
          progressTotalItems += 3; // digest for manifest, digest in sig file, copy data
        }
      }
      progressTotalItems += 1; // CERT.RSA generation
      progressHelper.setProgressTotalItems(progressTotalItems);
      progressHelper.setProgressCurrentItem(0);

      // Assume the certificate is valid for at least an hour.
      long timestamp = keySet.getPublicKey().getNotBefore().getTime() + 3600L * 1000;

      // MANIFEST.MF
      // progress(ProgressEvent.PRORITY_NORMAL, JarFile.MANIFEST_NAME);
      Manifest manifest = addDigestsToManifest(zioEntries);
      if (canceled) return;
      ZioEntry ze = new ZioEntry(JarFile.MANIFEST_NAME);
      ze.setTime(timestamp);
      manifest.write(ze.getOutputStream());
      zipOutput.write(ze);

      // CERT.SF
      // progress( ProgressEvent.PRORITY_NORMAL, CERT_SF_NAME);

      // Can't use default Signature on Android.  Although it generates a signature that can be
      // verified by jarsigner,
      // the recovery program appears to require a specific algorithm/mode/padding.  So we use the
      // custom ZipSignature instead.
      // Signature signature = Signature.getInstance("SHA1withRSA");
      ZipSignature signature = new ZipSignature();
      signature.initSign(keySet.getPrivateKey());

      //        	if (getLogger().isDebugEnabled()) {
      //        		getLogger().debug(String.format("Signature provider=%s, alg=%s, class=%s",
      //        				signature.getProvider().getName(),
      //        				signature.getAlgorithm(),
      //        				signature.getClass().getName()));
      //        	}

      ze = new ZioEntry(CERT_SF_NAME);
      ze.setTime(timestamp);

      ByteArrayOutputStream out = new ByteArrayOutputStream();
      generateSignatureFile(manifest, out);
      if (canceled) return;
      byte[] sfBytes = out.toByteArray();
      if (debug) {
        getLogger()
            .debug(
                "Signature File: \n" + new String(sfBytes) + "\n" + HexDumpEncoder.encode(sfBytes));
      }
      ze.getOutputStream().write(sfBytes);
      zipOutput.write(ze);
      signature.update(sfBytes);
      byte[] signatureBytes = signature.sign();

      if (debug) {

        MessageDigest md = MessageDigest.getInstance("SHA1");
        md.update(sfBytes);
        byte[] sfDigest = md.digest();
        getLogger().debug("Sig File SHA1: \n" + HexDumpEncoder.encode(sfDigest));

        getLogger().debug("Signature: \n" + HexDumpEncoder.encode(signatureBytes));

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySet.getPublicKey());

        byte[] tmpData = cipher.doFinal(signatureBytes);
        getLogger().debug("Signature Decrypted: \n" + HexDumpEncoder.encode(tmpData));

        //        		getLogger().debug( "SHA1 ID: \n" +
        // HexDumpEncoder.encode(AlgorithmId.get("SHA1").encode()));

        //        		// Compute signature using low-level APIs.
        //                byte[] beforeAlgorithmIdBytes =  { 0x30, 0x21 };
        //                // byte[] algorithmIdBytes = {0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03,
        // 0x02, 0x1A, 0x05, 0x00 };
        //                byte[] algorithmIdBytes =  AlgorithmId.get("SHA1").encode();
        //                byte[] afterAlgorithmIdBytes = { 0x04, 0x14 };
        //                cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        //                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        //                getLogger().debug( "Cipher: " + cipher.getAlgorithm() + ", blockSize = " +
        // cipher.getBlockSize());
        //
        //                cipher.update( beforeAlgorithmIdBytes);
        //                cipher.update( algorithmIdBytes);
        //                cipher.update( afterAlgorithmIdBytes);
        //                cipher.update( sfDigest);
        //                byte[] tmpData2 = cipher.doFinal();
        //                getLogger().debug( "Signature : \n" + HexDumpEncoder.encode(tmpData2));

      }

      // CERT.RSA
      progressHelper.progress(ProgressEvent.PRORITY_NORMAL, "Generating signature block file");
      ze = new ZioEntry(CERT_RSA_NAME);
      ze.setTime(timestamp);
      writeSignatureBlock(
          keySet.getSigBlockTemplate(),
          signatureBytes,
          keySet.getPublicKey(),
          ze.getOutputStream());
      zipOutput.write(ze);
      if (canceled) return;

      // Everything else
      copyFiles(manifest, zioEntries, zipOutput, timestamp);
      if (canceled) return;

    } finally {
      zipOutput.close();
      if (canceled) {
        try {
          if (outputZipFilename != null) new File(outputZipFilename).delete();
        } catch (Throwable t) {
          getLogger().warning(t.getClass().getName() + ":" + t.getMessage());
        }
      }
    }
  }