certificate backend

This commit is contained in:
Zlatin Balevsky
2019-12-09 14:26:39 +00:00
parent 3b1349b643
commit 42c48a8e37
7 changed files with 267 additions and 7 deletions

View File

@ -10,17 +10,20 @@ import net.i2p.crypto.DSAEngine
import net.i2p.data.Signature
import net.i2p.data.SigningPrivateKey
import net.i2p.data.SigningPublicKey
import net.i2p.data.Base64
class Certificate {
private final byte version
private final InfoHash infoHash
private final Name name, comment
private final long timestamp
private final Persona issuer
final Name name, comment
final long timestamp
final Persona issuer
private final byte[] sig
private volatile byte [] payload
private String base64;
Certificate(InputStream is) {
version = (byte) (is.read() & 0xFF)
if (version > Constants.FILE_CERT_VERSION)
@ -131,6 +134,15 @@ class Certificate {
os.write(payload)
}
public String toBase64() {
if (base64 == null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream()
write(baos)
base64 = Base64.encode(baos.toByteArray())
}
return base64;
}
@Override
public int hashCode() {
version.hashCode() ^ infoHash.hashCode() ^ timestamp.hashCode() ^ name.hashCode() ^ issuer.hashCode() ^ Objects.hashCode(comment)

View File

@ -32,7 +32,8 @@ class CertificateClient {
fetcherThread.execute({
Endpoint endpoint = null
try {
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.CONNECTING))
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.CONNECTING,
user : e.host, infoHash : e.infoHash))
endpoint = connector.connect(e.host.destination)
String infoHashString = Base64.encode(e.infoHash.getRoot())
@ -62,7 +63,8 @@ class CertificateClient {
int count = Integer.parseInt(headers['Count'])
// start pulling the certs
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.FETCHING, count : count))
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.FETCHING, count : count,
user : e.host, infoHash : e.infoHash))
DataInputStream dis = new DataInputStream(is)
for (int i = 0; i < count; i++) {
@ -77,11 +79,14 @@ class CertificateClient {
continue
}
if (cert.infoHash == e.infoHash)
eventBus.publish(new CertificateFetchedEvent(certificate : cert))
eventBus.publish(new CertificateFetchedEvent(certificate : cert, user : e.host, infoHash : e.infoHash))
}
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.DONE, count : count,
user : e.host, infoHash : e.infoHash))
} catch (Exception bad) {
log.log(Level.WARNING,"Fetching certificates failed", bad)
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.FAILED))
eventBus.publish(new CertificateFetchEvent(status : CertificateFetchStatus.FAILED,
user : e.host, infoHash : e.infoHash))
} finally {
endpoint?.close()
}

View File

@ -1,8 +1,12 @@
package com.muwire.core.filecert
import com.muwire.core.Event
import com.muwire.core.InfoHash
import com.muwire.core.Persona
class CertificateFetchEvent extends Event {
CertificateFetchStatus status
int count
Persona user
InfoHash infoHash
}

View File

@ -1,7 +1,11 @@
package com.muwire.core.filecert
import com.muwire.core.Event
import com.muwire.core.InfoHash
import com.muwire.core.Persona
class CertificateFetchedEvent extends Event {
Certificate certificate
Persona user
InfoHash infoHash
}

View File

@ -0,0 +1,101 @@
package com.muwire.webui;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.muwire.core.Core;
import com.muwire.core.InfoHash;
import com.muwire.core.Persona;
import com.muwire.core.filecert.Certificate;
import com.muwire.core.filecert.CertificateFetchEvent;
import com.muwire.core.filecert.CertificateFetchStatus;
import com.muwire.core.filecert.CertificateFetchedEvent;
import com.muwire.core.filecert.UIFetchCertificatesEvent;
import com.muwire.core.filecert.UIImportCertificateEvent;
public class CertificateManager {
private final Core core;
private final Map<Persona, Map<InfoHash,CertificateRequest>> requests = new ConcurrentHashMap<>();
public CertificateManager(Core core) {
this.core = core;
}
public void onCertificateFetchEvent(CertificateFetchEvent e) {
Map<InfoHash, CertificateRequest> map = requests.get(e.getUser());
if (map == null)
return;
CertificateRequest request = map.get(e.getInfoHash());
if (request == null)
return;
request.status = e.getStatus();
if (request.status == CertificateFetchStatus.FETCHING)
request.totalCertificates = e.getCount();
}
public void onCertificateFetchedEvent(CertificateFetchedEvent e) {
Map<InfoHash, CertificateRequest> map = requests.get(e.getUser());
if (map == null)
return;
CertificateRequest request = map.get(e.getInfoHash());
if (request == null)
return;
request.certificates.add(e.getCertificate());
}
void request(Persona user, InfoHash infoHash) {
CertificateRequest request = new CertificateRequest(user, infoHash);
Map<InfoHash, CertificateRequest> requestsFromUser = requests.get(user);
if (requestsFromUser == null) {
requestsFromUser = new ConcurrentHashMap<>();
requests.put(user, requestsFromUser);
}
requestsFromUser.put(infoHash, request);
UIFetchCertificatesEvent event = new UIFetchCertificatesEvent();
event.setHost(user);
event.setInfoHash(infoHash);
core.getEventBus().publish(event);
}
CertificateRequest get(Persona user, InfoHash infoHash) {
Map<InfoHash, CertificateRequest> map = requests.get(user);
if (map == null)
return null;
return map.get(infoHash);
}
void importCertificate(Certificate certificate) {
UIImportCertificateEvent event = new UIImportCertificateEvent();
event.setCertificate(certificate);
core.getEventBus().publish(event);
}
static class CertificateRequest {
private final Persona user;
private final InfoHash infoHash;
private volatile CertificateFetchStatus status;
private volatile int totalCertificates;
private Set<Certificate> certificates;
CertificateRequest(Persona user, InfoHash infoHash) {
this.user = user;
this.infoHash = infoHash;
}
CertificateFetchStatus getStatus() {
return status;
}
int totalCertificates() {
return totalCertificates;
}
Set<Certificate> getCertificates() {
return certificates;
}
}
}

View File

@ -0,0 +1,127 @@
package com.muwire.webui;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.muwire.core.InfoHash;
import com.muwire.core.Persona;
import com.muwire.core.filecert.Certificate;
import com.muwire.webui.CertificateManager.CertificateRequest;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
public class CertificateServlet extends HttpServlet {
private CertificateManager certificateManager;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userB64 = req.getParameter("user");
Persona user;
try {
user = new Persona(new ByteArrayInputStream(Base64.decode(userB64)));
} catch (Exception bad) {
resp.sendError(403, "Bad param");
return;
}
String infoHashB64 = req.getParameter("infoHash");
InfoHash infoHash;
try {
infoHash = new InfoHash(Base64.decode(infoHashB64));
} catch (Exception bad) {
resp.sendError(403, "Bad param");
return;
}
CertificateRequest request = certificateManager.get(user, infoHash);
if (request == null) {
resp.sendError(404,"Not found");
return;
}
StringBuilder sb = new StringBuilder();
sb.append("<?xml version='1.0' encoding='UTF-8'?>");
sb.append("<CertificateRequest>");
sb.append("<Status>").append(request.getStatus().toString()).append("</Status>");
sb.append("<Total>").append(request.totalCertificates()).append("</Total>");
sb.append("<Certificates>");
for (Certificate certificate : request.getCertificates()) {
sb.append("<Certificate>");
sb.append("<Issuer>").append(certificate.getIssuer().getHumanReadableName()).append("</Issuer>");
sb.append("<Name>").append(Util.escapeHTMLinXML(certificate.getName().getName())).append("</Name>");
if (certificate.getComment() != null)
sb.append("<Comment>").append(Util.escapeHTMLinXML(certificate.getComment().getName())).append("</Comment>");
sb.append("<Timestamp>").append(DataHelper.formatTime(certificate.getTimestamp())).append("</Timestamp>");
sb.append("<Base64>").append(certificate.toBase64()).append("</Base64>");
sb.append("</Certificate>");
}
sb.append("</Certificates>");
sb.append("</CertificateRequest>");
resp.setContentType("text/xml");
resp.setCharacterEncoding("UTF-8");
resp.setDateHeader("Expires", 0);
resp.setHeader("Pragma", "no-cache");
resp.setHeader("Cache-Control", "no-store, max-age=0, no-cache, must-revalidate");
byte[] out = sb.toString().getBytes("UTF-8");
resp.setContentLength(out.length);
resp.getOutputStream().write(out);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String action = req.getParameter("action");
if (action == null) {
resp.sendError(403, "Bad param");
return;
}
if (action.equals("fetch")) {
String userB64 = req.getParameter("user");
Persona user;
try {
user = new Persona(new ByteArrayInputStream(Base64.decode(userB64)));
} catch (Exception bad) {
resp.sendError(403, "Bad param");
return;
}
String infoHashB64 = req.getParameter("infoHash");
InfoHash infoHash;
try {
infoHash = new InfoHash(Base64.decode(infoHashB64));
} catch (Exception bad) {
resp.sendError(403, "Bad param");
return;
}
certificateManager.request(user, infoHash);
} else if (action.equals("import")) {
String certB64 = req.getParameter("base64");
Certificate certificate;
try {
certificate = new Certificate(new ByteArrayInputStream(Base64.decode(certB64)));
} catch (Exception bad) {
resp.sendError(403, "Bad param");
return;
}
certificateManager.importCertificate(certificate);
}
}
@Override
public void init(ServletConfig config) throws ServletException {
certificateManager = (CertificateManager) config.getServletContext().getAttribute("certificateManager");
}
}

View File

@ -22,6 +22,8 @@ import com.muwire.core.UILoadedEvent;
import com.muwire.core.connection.ConnectionEvent;
import com.muwire.core.connection.DisconnectionEvent;
import com.muwire.core.download.DownloadStartedEvent;
import com.muwire.core.filecert.CertificateFetchEvent;
import com.muwire.core.filecert.CertificateFetchedEvent;
import com.muwire.core.files.AllFilesLoadedEvent;
import com.muwire.core.files.FileDownloadedEvent;
import com.muwire.core.files.FileHashedEvent;
@ -148,12 +150,17 @@ public class MuWireClient {
TrustManager trustManager = new TrustManager();
core.getEventBus().register(TrustEvent.class, trustManager);
CertificateManager certificateManager = new CertificateManager(core);
core.getEventBus().register(CertificateFetchedEvent.class, certificateManager);
core.getEventBus().register(CertificateFetchEvent.class, certificateManager);
servletContext.setAttribute("searchManager", searchManager);
servletContext.setAttribute("downloadManager", downloadManager);
servletContext.setAttribute("connectionCounter", connectionCounter);
servletContext.setAttribute("fileManager", fileManager);
servletContext.setAttribute("browseManager", browseManager);
servletContext.setAttribute("trustManager", trustManager);
servletContext.setAttribute("certificateManager", certificateManager);
core.getEventBus().publish(new UILoadedEvent());
}