Skip to content

Commit

Permalink
'#1953 Extract signer certificate data to be parsed by
Browse files Browse the repository at this point in the history
CertificateParser. Reenable and makes some little improvements to
CertificateParser.
  • Loading branch information
patrickdalla committed Nov 14, 2023
1 parent 2914ce2 commit 9701e01
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 5 deletions.
1 change: 1 addition & 0 deletions iped-app/resources/config/conf/CategoriesToExpand.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ GDrive Synced Files
OLE files
Georeferenced Files
Peer-to-peer
Android Applications
#Event Files

# Generates registry reports:
Expand Down
1 change: 1 addition & 0 deletions iped-app/resources/config/conf/MakePreviewConfig.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ supportedMimes = application/x-msaccess; application/x-lnk; application/x-firefo
supportedMimes = application/x-sqlite3; application/sqlite-skype; application/x-win10-timeline; application/x-gdrive-cloud-graph; application/x-gdrive-snapshot
supportedMimes = application/x-whatsapp-db; application/x-whatsapp-db-f; application/x-whatsapp-chatstorage; application/x-whatsapp-chatstorage-f; application/x-shareaza-searches-dat; application/x-msie-cache
supportedMimes = application/x-prefetch; text/x-vcard; application/x-bittorrent-resume-dat; application/x-bittorrent; application/x-emule-preferences-dat; application/vnd.android.package-archive
supportedMimes = application/x-pem-file

# List of mimetypes which parsers insert links to other case items into preview
supportedMimesWithLinks = application/x-emule; application/x-emule-part-met; application/x-ares-galaxy; application/x-shareaza-library-dat
3 changes: 2 additions & 1 deletion iped-app/resources/config/conf/ParserConfig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,8 @@
<parser class="iped.parsers.mail.win10.Win10MailParser"></parser>
<parser class="iped.parsers.discord.DiscordParser"></parser>
<parser class="iped.parsers.apk.APKParser"></parser>

<parser class="iped.parsers.security.CertificateParser"></parser>

</parsers>

<encodingDetectors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -18,6 +21,8 @@
import javax.imageio.ImageIO;

import org.apache.tika.exception.TikaException;
import org.apache.tika.extractor.EmbeddedDocumentExtractor;
import org.apache.tika.extractor.ParsingEmbeddedDocumentExtractor;
import org.apache.tika.io.TemporaryResources;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.HttpHeaders;
Expand All @@ -28,10 +33,13 @@
import org.apache.tika.parser.AbstractParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.sax.XHTMLContentHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

import iped.parsers.security.CertificateParser;
import iped.parsers.standard.StandardParser;
import iped.parsers.whatsapp.Util;
import iped.utils.IOUtil;
import iped.utils.ImageUtil;
Expand All @@ -47,7 +55,8 @@ public class APKParser extends AbstractParser {
private static final long serialVersionUID = 8308661247390527209L;
private static final MediaType apkMimeType = MediaType.application("vnd.android.package-archive");
private static final Set<MediaType> SUPPORTED_TYPES = Collections.singleton(apkMimeType);

private static Logger LOGGER = LoggerFactory.getLogger(APKParser.class);

// TODO: Use another property or reuse this one from CertificateParser?
private static final Property certStartDate = CertificateParser.NOTBEFORE;

Expand All @@ -64,6 +73,9 @@ public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
CustomApkFile apkFile = null;
XHTMLContentHandler xhtml = null;
File tmpFile = null;
EmbeddedDocumentExtractor extractor = context.get(EmbeddedDocumentExtractor.class,
new ParsingEmbeddedDocumentExtractor(context));

try {
TikaInputStream tis = TikaInputStream.get(stream, tmp);
tmpFile = tis.getFile();
Expand Down Expand Up @@ -118,11 +130,13 @@ public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
if (signers != null && !signers.isEmpty()) {
for (ApkSigner s : signers) {
sb.append("Path: ").append(s.getPath()).append("\n");

for (CertificateMeta m : s.getCertificateMetas()) {
if (seenCertificates.add(m.toString())) {
sb.append(formatCertificate(m));
// TODO: Keep just one date or use a multivalued property?
metadata.set(certStartDate, m.getStartDate());
parseEmbeddedCertificate(m, extractor, xhtml);
}
}
}
Expand All @@ -141,6 +155,8 @@ public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
if (seenCertificates.add(m.toString())) {
certificates.add(m);
metadata.set(certStartDate, m.getStartDate());

parseEmbeddedCertificate(m, extractor, xhtml);
}
}
}
Expand Down Expand Up @@ -178,13 +194,29 @@ public int compare(UseFeature o1, UseFeature o2) {
} finally {
IOUtil.closeQuietly(apkFile);
tmp.close();

if (xhtml != null) {
xhtml.endElement("table");
xhtml.endDocument();
}
}
}

private void parseEmbeddedCertificate(CertificateMeta m, EmbeddedDocumentExtractor extractor,
ContentHandler xhtml) throws SAXException, IOException {
CertificateFactory cf;
try {
cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(m.getData()));
Metadata certMetadata = new Metadata();
certMetadata.add(StandardParser.INDEXER_CONTENT_TYPE, CertificateParser.PEM_MIME.toString());
certMetadata.add(TikaCoreProperties.RESOURCE_NAME_KEY, cert.getSubjectX500Principal().getName());
extractor.parseEmbedded(new ByteArrayInputStream(m.getData()), xhtml, certMetadata, true);
} catch (CertificateException e) {
// LOGGER.warn("Invalid certificate data for APK:"+apkFile.get);
}
}

private String iconToBase64(Icon icon) throws Exception {
BufferedImage img = ImageIO.read(new ByteArrayInputStream(icon.getData()));
int size = 128;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;

import iped.parsers.util.MetadataUtil;

public class CertificateParser extends AbstractParser {
/**
*
Expand All @@ -52,13 +54,18 @@ public class CertificateParser extends AbstractParser {
public static final MediaType PKCS7_SIGNATURE = MediaType.application("pkcs7-signature");
private static Set<MediaType> SUPPORTED_TYPES = null;

public static final Property NOTBEFORE = Property.internalDate("certificate:notbefore"); //$NON-NLS-1$
public static final Property NOTAFTER = Property.internalDate("certificate:notafter"); //$NON-NLS-1$
public static final Property NOTBEFORE = Property.internalDate("certificate:notBefore"); //$NON-NLS-1$
public static final Property NOTAFTER = Property.internalDate("certificate:notAfter"); //$NON-NLS-1$
public static final String ISSUER = "certificate:issuer"; //$NON-NLS-1$
public static final String SUBJECT = "certificate:subject"; //$NON-NLS-1$
public static final Property ISSUBJECTAUTHORITY = Property.internalBoolean("certificate:subjectIsCertAuthority"); //$NON-NLS-1$
public static final String NOALTNAMES = "This certificate has no alternative names.";

public CertificateParser() {
MetadataUtil.setMetadataType(NOTBEFORE.getName(), Date.class);
MetadataUtil.setMetadataType(NOTAFTER.getName(), Date.class);
}

@Override
public Set<MediaType> getSupportedTypes(ParseContext arg0) {
if (SUPPORTED_TYPES == null) {
Expand Down Expand Up @@ -92,6 +99,11 @@ public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
List certs = p.getCertificates();
XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
xhtml.startDocument();
xhtml.startElement("head"); //$NON-NLS-1$
xhtml.startElement("style"); //$NON-NLS-1$
xhtml.characters("table {border-collapse: collapse;} table, td, th {border: 1px solid black;}"); //$NON-NLS-1$
xhtml.endElement("style"); //$NON-NLS-1$
xhtml.endElement("head"); //$NON-NLS-1$
for (Iterator iterator = certs.iterator(); iterator.hasNext();) {
cert = (X509Certificate) iterator.next();
generateCertificateHtml(cert, xhtml);
Expand All @@ -110,6 +122,11 @@ public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
}
XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
xhtml.startDocument();
xhtml.startElement("head"); //$NON-NLS-1$
xhtml.startElement("style"); //$NON-NLS-1$
xhtml.characters("table {border-collapse: collapse;} table, td, th {border: 1px solid black;}"); //$NON-NLS-1$
xhtml.endElement("style"); //$NON-NLS-1$
xhtml.endElement("head"); //$NON-NLS-1$
generateCertificateHtml(cert, xhtml);
xhtml.endDocument();
}
Expand All @@ -136,7 +153,7 @@ public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
private void generateCertificateHtml(X509Certificate cert, XHTMLContentHandler xhtml)
throws UnsupportedEncodingException, SAXException {

xhtml.startElement("table");
xhtml.startElement("table border='1'");

xhtml.startElement("tr");
xhtml.startElement("th");
Expand Down

0 comments on commit 9701e01

Please sign in to comment.