package org.eclipse.osgi.internal.signedcontent;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.*;
import java.security.cert.*;
import java.util.Date;
import org.eclipse.osgi.signedcontent.*;
import org.eclipse.osgi.storage.bundlefile.*;
import org.eclipse.osgi.util.NLS;
public class SignedBundleFile extends BundleFileWrapper implements SignedContentConstants, SignedContent {
SignedContentImpl signedContent;
private final int supportFlags;
private final SignedBundleHook signedBundleHook;
SignedBundleFile(BundleFile bundleFile, SignedContentImpl signedContent, int supportFlags, SignedBundleHook signedBundleHook) {
super(bundleFile);
this.signedContent = signedContent;
this.supportFlags = supportFlags;
this.signedBundleHook = signedBundleHook;
}
void initializeSignedContent() throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException {
if (signedContent == null) {
SignatureBlockProcessor signatureProcessor = new SignatureBlockProcessor(this, supportFlags, signedBundleHook);
signedContent = signatureProcessor.process();
if (signedContent != null)
signedBundleHook.determineTrust(signedContent, supportFlags);
}
}
@Override
public BundleEntry getEntry(String path) {
if (path.length() > 0 && path.charAt(0) == '/')
path = path.substring(1);
BundleEntry be = getBundleFile().getEntry(path);
if ((supportFlags & SignedBundleHook.VERIFY_RUNTIME) == 0 || signedContent == null)
return be;
if (path.startsWith(META_INF)) {
int lastSlash = path.lastIndexOf('/');
if (lastSlash == META_INF.length() - 1) {
if (path.equals(META_INF_MANIFEST_MF) || path.endsWith(DOT_DSA) || path.endsWith(DOT_RSA) || path.endsWith(DOT_SF) || path.indexOf(SIG_DASH) == META_INF.length())
return be;
SignedContentEntry signedEntry = signedContent.getSignedEntry(path);
if (signedEntry == null)
return be;
}
}
if (be == null) {
SignedContentEntry signedEntry = signedContent.getSignedEntry(path);
if (signedEntry != null)
throw new SecurityException(NLS.bind(SignedContentMessages.file_is_removed_from_jar, path, getBaseFile().toString()));
return null;
}
return new SignedBundleEntry(be);
}
class SignedBundleEntry extends BundleEntry {
BundleEntry nestedEntry;
SignedBundleEntry(BundleEntry nestedEntry) {
this.nestedEntry = nestedEntry;
}
@Override
public InputStream getInputStream() throws IOException {
InputStream in = signedContent.getDigestInputStream(nestedEntry);
if (in == null)
throw new SecurityException("Corrupted file: the digest does not exist for the file " + nestedEntry.getName());
return in;
}
@Override
public long getSize() {
return nestedEntry.getSize();
}
@Override
public String getName() {
return nestedEntry.getName();
}
@Override
public long getTime() {
return nestedEntry.getTime();
}
@Override
public URL getLocalURL() {
return nestedEntry.getLocalURL();
}
@Override
public URL getFileURL() {
return nestedEntry.getFileURL();
}
}
SignedContentImpl getSignedContent() {
return signedContent;
}
@Override
public SignedContentEntry[] getSignedEntries() {
return signedContent == null ? null : signedContent.getSignedEntries();
}
@Override
public SignedContentEntry getSignedEntry(String name) {
return signedContent == null ? null : signedContent.getSignedEntry(name);
}
@Override
public SignerInfo[] getSignerInfos() {
return signedContent == null ? null : signedContent.getSignerInfos();
}
@Override
public Date getSigningTime(SignerInfo signerInfo) {
return signedContent == null ? null : signedContent.getSigningTime(signerInfo);
}
@Override
public SignerInfo getTSASignerInfo(SignerInfo signerInfo) {
return signedContent == null ? null : signedContent.getTSASignerInfo(signerInfo);
}
@Override
public boolean isSigned() {
return signedContent == null ? false : signedContent.isSigned();
}
@Override
public void checkValidity(SignerInfo signerInfo) throws CertificateExpiredException, CertificateNotYetValidException {
if (signedContent != null)
signedContent.checkValidity(signerInfo);
}
}