blob: 2108b52f448e798cfacb99ea590a165990443c96 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 compeople AG 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:
* compeople AG (Stefan Liebig) - initial API and implementation
* IBM - continuing development
*******************************************************************************/
package org.eclipse.equinox.internal.p2.artifact.repository;
import java.io.*;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.processing.ProcessingStep;
import org.eclipse.osgi.signedcontent.*;
/**
* Processing step validating the signature of the artifact being downloaded
*/
public class SignatureVerifier extends ProcessingStep {
private File inputFile;
private OutputStream tempStream;
public boolean areRequirementsSatisfied() {
return true;
}
public void write(int b) throws IOException {
getOutputStream().write(b);
}
public void write(byte[] bytes, int off, int len) throws IOException {
getOutputStream().write(bytes, off, len);
}
private OutputStream getOutputStream() throws IOException {
if (tempStream != null)
return tempStream;
// store input stream in temporary file
inputFile = File.createTempFile("signatureFile", ".jar"); //$NON-NLS-1$ //$NON-NLS-2$
tempStream = new BufferedOutputStream(new FileOutputStream(inputFile));
return tempStream;
}
private void verify() throws IOException {
BufferedInputStream resultStream = null;
try {
if (tempStream == null)
// hmmm, no one wrote to this stream so there is nothing to pass on
return;
// Ok, so there is content, close the tempStream
tempStream.close();
setStatus(verifyContent());
// now write the content to the final destination
resultStream = new BufferedInputStream(new FileInputStream(inputFile));
FileUtils.copyStream(resultStream, true, getDestination(), false);
resultStream = null;
} finally {
if (inputFile != null)
inputFile.delete();
if (resultStream != null)
resultStream.close();
}
}
private IStatus verifyContent() throws IOException {
SignedContentFactory verifierFactory = (SignedContentFactory) ServiceHelper.getService(Activator.getContext(), SignedContentFactory.class.getName());
SignedContent signedContent;
try {
signedContent = verifierFactory.getSignedContent(inputFile);
} catch (GeneralSecurityException e) {
return new Status(IStatus.ERROR, Activator.ID, Messages.SignatureVerification_failedRead + inputFile, e);
}
ArrayList<IStatus> allStatus = new ArrayList<IStatus>(0);
SignedContentEntry[] entries = signedContent.getSignedEntries();
for (int i = 0; i < entries.length; i++)
try {
entries[i].verify();
} catch (InvalidContentException e) {
allStatus.add(new Status(IStatus.ERROR, Activator.ID, Messages.SignatureVerification_invalidContent + entries[i].getName(), e));
} catch (OutOfMemoryError e) {
allStatus.add(new Status(IStatus.ERROR, Activator.ID, Messages.SignatureVerifier_OutOfMemory, e));
break;
}
if (allStatus.size() > 0)
return new MultiStatus(Activator.ID, IStatus.ERROR, allStatus.toArray(new IStatus[allStatus.size()]), Messages.SignatureVerification_invalidFileContent + inputFile, null);
return Status.OK_STATUS;
}
public void close() throws IOException {
// When we go to close we must have seen all the content we are going to see
// So before closing, verify and write the result to the destination
verify();
super.close();
}
}