Package org.eclipse.osgi.internal.signedcontent

Source Code of org.eclipse.osgi.internal.signedcontent.SignedStorageHook

/*******************************************************************************
* Copyright (c) 2006, 2010 IBM Corporation and others. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors: IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.osgi.internal.signedcontent;

import java.io.*;
import java.security.cert.*;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.osgi.baseadaptor.BaseData;
import org.eclipse.osgi.baseadaptor.hooks.StorageHook;
import org.eclipse.osgi.framework.util.KeyedElement;
import org.eclipse.osgi.signedcontent.SignedContent;
import org.eclipse.osgi.signedcontent.SignerInfo;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;

public class SignedStorageHook implements StorageHook {
  public static final String KEY = SignedStorageHook.class.getName();
  public static final int HASHCODE = KEY.hashCode();
  private static final int STORAGE_VERSION = 3;
  private static ArrayList savedSignerInfo = new ArrayList(5);
  private static long firstIDSaved = -1;
  private static long lastIDSaved = -1;
  private static ArrayList loadedSignerInfo = new ArrayList(5);
  private static long lastIDLoaded;

  private BaseData bundledata;
  SignedContentImpl signedContent;

  public int getStorageVersion() {
    return STORAGE_VERSION;
  }

  public StorageHook create(BaseData bundledata) throws BundleException {
    SignedStorageHook hook = new SignedStorageHook();
    hook.bundledata = bundledata;
    return hook;
  }

  public void initialize(Dictionary manifest) throws BundleException {
    // do nothing
  }

  public StorageHook load(BaseData target, DataInputStream is) throws IOException {
    if (lastIDLoaded > target.getBundleID())
      loadedSignerInfo.clear();
    lastIDLoaded = target.getBundleID();
    SignedStorageHook hook = new SignedStorageHook();
    hook.bundledata = target;
    boolean signed = is.readBoolean();
    if (!signed)
      return hook;
    int numSigners = is.readInt();
    SignerInfo[] signerInfos = new SignerInfo[numSigners];
    for (int i = 0; i < numSigners; i++)
      signerInfos[i] = readSignerInfo(is);

    int resultsSize = is.readInt();
    HashMap contentMDResults = null;
    if (resultsSize > 0) {
      contentMDResults = new HashMap(resultsSize);
      for (int i = 0; i < resultsSize; i++) {
        String path = is.readUTF();
        int numEntrySigners = is.readInt();
        SignerInfo[] entrySigners = new SignerInfo[numEntrySigners];
        byte[][] entryResults = new byte[numEntrySigners][];
        for (int j = 0; j < numEntrySigners; j++) {
          entrySigners[j] = readSignerInfo(is);
          int resultSize = is.readInt();
          entryResults[j] = new byte[resultSize];
          is.readFully(entryResults[j]);
        }
        contentMDResults.put(path, new Object[] {entrySigners, entryResults});
      }
    }
    SignedContentImpl result = new SignedContentImpl(signerInfos, contentMDResults);
    for (int i = 0; i < numSigners; i++) {
      boolean hasTSA = is.readBoolean();
      if (!hasTSA)
        continue;
      SignerInfo tsaSigner = readSignerInfo(is);
      Date signingDate = new Date(is.readLong());
      result.addTSASignerInfo(signerInfos[i], tsaSigner, signingDate);
    }
    hook.signedContent = result;
    return hook;
  }

  public void save(DataOutputStream os) throws IOException {
    getFirstLastID();
    if (firstIDSaved == bundledata.getBundleID())
      savedSignerInfo.clear();
    if (lastIDSaved == bundledata.getBundleID())
      firstIDSaved = lastIDSaved = -1;
    os.writeBoolean(signedContent != null);
    if (signedContent == null)
      return;
    SignerInfo[] signerInfos = signedContent.getSignerInfos();
    os.writeInt(signerInfos.length);
    for (int i = 0; i < signerInfos.length; i++)
      saveSignerInfo(signerInfos[i], os);

    // keyed by entry path -> {SignerInfo[] infos, byte[][] results)}
    HashMap contentMDResults = signedContent.getContentMDResults();
    os.writeInt(contentMDResults == null ? -1 : contentMDResults.size());
    if (contentMDResults != null)
      for (Iterator iResults = contentMDResults.entrySet().iterator(); iResults.hasNext();) {
        Entry entry = (Entry) iResults.next();
        String path = (String) entry.getKey();
        os.writeUTF(path);
        Object[] signerResults = (Object[]) entry.getValue();
        SignerInfo[] entrySigners = (SignerInfo[]) signerResults[0];
        byte[][] entryResults = (byte[][]) signerResults[1];
        os.writeInt(entrySigners.length);
        for (int i = 0; i < entrySigners.length; i++) {
          saveSignerInfo(entrySigners[i], os);
          os.writeInt(entryResults[i].length);
          os.write(entryResults[i]);
        }
      }

    for (int i = 0; i < signerInfos.length; i++) {
      SignerInfo tsaInfo = signedContent.getTSASignerInfo(signerInfos[i]);
      os.writeBoolean(tsaInfo != null);
      if (tsaInfo == null)
        continue;
      saveSignerInfo(tsaInfo, os);
      Date signingTime = signedContent.getSigningTime(signerInfos[i]);
      os.writeLong(signingTime != null ? signingTime.getTime() : Long.MIN_VALUE);
    }
  }

  private void saveSignerInfo(SignerInfo signerInfo, DataOutputStream os) throws IOException {
    int cacheIdx = savedSignerInfo.indexOf(signerInfo);
    os.writeInt(cacheIdx);
    if (cacheIdx >= 0)
      return;
    Certificate[] certs = signerInfo.getCertificateChain();
    int anchorIndex = -1;
    os.writeInt(certs == null ? 0 : certs.length);
    if (certs != null)
      for (int i = 0; i < certs.length; i++) {
        if (certs[i].equals(signerInfo.getTrustAnchor()))
          anchorIndex = i;
        byte[] certBytes;
        try {
          certBytes = certs[i].getEncoded();
        } catch (CertificateEncodingException e) {
          throw (IOException) new IOException(e.getMessage()).initCause(e);
        }
        os.writeInt(certBytes.length);
        os.write(certBytes);
      }
    os.writeInt(anchorIndex);
    os.writeUTF(signerInfo.getMessageDigestAlgorithm());
    savedSignerInfo.add(signerInfo);
  }

  private SignerInfo readSignerInfo(DataInputStream is) throws IOException {
    int index = is.readInt();
    if (index >= 0)
      return (SignerInfo) loadedSignerInfo.get(index);
    int numCerts = is.readInt();
    Certificate[] certs = new Certificate[numCerts];
    for (int i = 0; i < numCerts; i++) {
      int certSize = is.readInt();
      byte[] certBytes = new byte[certSize];
      is.readFully(certBytes);
      try {
        certs[i] = PKCS7Processor.certFact.generateCertificate(new ByteArrayInputStream(certBytes));
      } catch (CertificateException e) {
        throw (IOException) new IOException(e.getMessage()).initCause(e);
      }
    }
    int anchorIdx = is.readInt();
    SignerInfoImpl result = new SignerInfoImpl(certs, anchorIdx >= 0 ? certs[anchorIdx] : null, is.readUTF());
    loadedSignerInfo.add(result);
    return result;
  }

  private void getFirstLastID() {
    if (firstIDSaved >= 0)
      return;
    Bundle[] bundles = bundledata.getAdaptor().getContext().getBundles();
    if (bundles.length > 1) {
      firstIDSaved = bundles[1].getBundleId();
      lastIDSaved = bundles[bundles.length - 1].getBundleId();
    }
  }

  public void copy(StorageHook storageHook) {
    // do nothing
  }

  public void validate() throws IllegalArgumentException {
    // do nothing
  }

  public Dictionary getManifest(boolean firstLoad) throws BundleException {
    // do nothing
    return null;
  }

  public boolean forgetStatusChange(int status) {
    // do nothing
    return false;
  }

  public boolean forgetStartLevelChange(int startlevel) {
    // do nothing
    return false;
  }

  public int getKeyHashCode() {
    return HASHCODE;
  }

  public boolean compare(KeyedElement other) {
    return other.getKey() == KEY;
  }

  public Object getKey() {
    return KEY;
  }

  public SignedContent getSignedContent() {
    return signedContent;
  }

}
TOP

Related Classes of org.eclipse.osgi.internal.signedcontent.SignedStorageHook

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.