diff --git a/iped-app/resources/config/conf/CategoriesConfig.json b/iped-app/resources/config/conf/CategoriesConfig.json
index bdbd5eb63c..44861b5dc4 100644
--- a/iped-app/resources/config/conf/CategoriesConfig.json
+++ b/iped-app/resources/config/conf/CategoriesConfig.json
@@ -75,6 +75,7 @@
]},
{"name": "Databases", "mimes": ["application/x-edb", "application/x-edb-table", "application/irpf", "application/x-msaccess", "application/x-dbf", "application/vnd.oasis.opendocument.database", "application/x-sqlite3", "application/x-mysql-db", "application/x-berkeley-db", "application/x-mssql-data", "application/x-database-table"]},
{"name": "Compressed Archives", "mimes": ["application/x-tika-ooxml", "application/zlib", "application/applefile", "application/vnd.ms-tnef", "application/zip", "application/x-rar-compressed", "application/x-tar", "application/gzip", "application/x-gzip", "application/x-xz", "application/x-bzip", "application/x-bzip2", "application/x-7z-compressed", "application/x-arj", "application/x-gtar", "application/x-archive", "application/x-cpio", "application/x-tika-unix-dump", "application/x-snappy-framed", "application/x-snappy", "application/x-snappy-raw", "application/x-compress", "application/x-java-pack200", "application/x-lzma", "application/x-lz4", "application/x-lz4-block", "application/x-brotli", "application/zstd", "application/deflate64", "image/x-emf-compressed", "application/x-lzfse"]},
+ {"name": "Signed Archives", "mimes": ["application/pkcs7-mime", "application/pkcs7-signature"]},
{"name": "Contacts", "mimes": ["text/x-vcard", "application/x-vcard-html", "application/windows-adress-book", "application/outlook-contact", "application/x-livecontacts", "application/x-livecontacts-table", "contact/x-skype-contact", "application/x-whatsapp-wadb", "application/x-whatsapp-contactsv2", "contact/x-whatsapp-contact", "application/x-ufed-html-contacts", "application/x-ufed-contact", "contact/x-telegram-contact", "application/x-ios-addressbook-db", "application/x-win10-mail-contact"]},
{"name": "Chats", "categories":[
{"name": "WhatsApp", "mimes":["application/x-whatsapp-db", "application/x-whatsapp-chatstorage", "application/x-whatsapp-chat","application/x-ufed-chat-whatsapp","application/x-ufed-chat-preview-whatsapp"]},
@@ -89,7 +90,7 @@
{"name": "Others Chats", "mimes":["application/x-ufed-html-chats", "application/x-ufed-chats-txt", "application/x-ufed-chat", "application/x-ufed-chat-preview"]}
]},
{"name": "USN Journal", "mimes": ["application/x-usnjournal-$J", "application/x-usnjournal-report-html", "application/x-usnjournal-report-csv", "application/x-usnjournal-registry"]},
- {"name": "Programs and Libraries", "mimes": ["application/java-archive", "application/x-dosexec", "application/x-msdownload", "application/x-bat", "application/vnd.ms-cab-compressed", "application/x-font-ttf", "application/pkcs7-signature", "application/vnd.ms-htmlhelp", "application/java-vm", "application/vnd.ms-pki.seccat", "application/x-ms-installer", "application/x-ufed-html-apps", "application/x-ufed-installedapplication"]},
+ {"name": "Programs and Libraries", "mimes": ["application/java-archive", "application/x-dosexec", "application/x-msdownload", "application/x-bat", "application/vnd.ms-cab-compressed", "application/x-font-ttf", "application/vnd.ms-htmlhelp", "application/java-vm", "application/vnd.ms-pki.seccat", "application/x-ms-installer", "application/x-ufed-html-apps", "application/x-ufed-installedapplication"]},
{"name": "Unallocated", "mimes": ["application/x-unallocated"]},
{"name": "File Slacks", "mimes": ["application/x-fileslack"]},
{"name": "Plain Texts", "mimes": ["text"], "categories":[
diff --git a/iped-app/resources/config/conf/CategoriesToExpand.txt b/iped-app/resources/config/conf/CategoriesToExpand.txt
index 0ebc3d2fdb..ef5c3e394a 100644
--- a/iped-app/resources/config/conf/CategoriesToExpand.txt
+++ b/iped-app/resources/config/conf/CategoriesToExpand.txt
@@ -18,6 +18,7 @@ GDrive Synced Files
OLE files
Georeferenced Files
Peer-to-peer
+Signed Archives
#Event Files
# Generates registry reports:
diff --git a/iped-app/resources/config/conf/MakePreviewConfig.txt b/iped-app/resources/config/conf/MakePreviewConfig.txt
index 271edf63b4..09f526ec68 100644
--- a/iped-app/resources/config/conf/MakePreviewConfig.txt
+++ b/iped-app/resources/config/conf/MakePreviewConfig.txt
@@ -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
+supportedMimes = application/x-x509-cert
# 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
\ No newline at end of file
diff --git a/iped-app/resources/config/conf/ParserConfig.xml b/iped-app/resources/config/conf/ParserConfig.xml
index e613913f76..6aa7ccc680 100644
--- a/iped-app/resources/config/conf/ParserConfig.xml
+++ b/iped-app/resources/config/conf/ParserConfig.xml
@@ -347,6 +347,20 @@
+
+
+
+ application/pkcs7-mime
+ application/pkcs7-signature
+
+ PKCS7Parser
+
+ iped.parsers.security.CertificateParser;
+ org.apache.tika.parser.crypto.Pkcs7Parser;
+
+
+
+
application/skype
application/irpf
diff --git a/iped-app/resources/localization/iped-parsers-messages.properties b/iped-app/resources/localization/iped-parsers-messages.properties
index 388bc9b039..050a5da2a1 100644
--- a/iped-app/resources/localization/iped-parsers-messages.properties
+++ b/iped-app/resources/localization/iped-parsers-messages.properties
@@ -318,4 +318,17 @@ TelegramReport.joinedByRequest=User joined by Request
TelegramReport.ChannelMigratedFromGroup=This channel migrated from a group
TelegramReport.RecoveredGroup=Recovered deleted group
P2P.FoundInPedoHashDB=* Red lines mean the hashes were found in child porn alert hash databases.
-Win10Mail.NotFound=Not Found
\ No newline at end of file
+Win10Mail.NotFound=Not Found
+CertificateParser.SubjectX500=Subject(X500)
+CertificateParser.Subject=Subject
+CertificateParser.Version=Version
+CertificateParser.SerialNumber=Serial Number
+CertificateParser.SignatureAlgorithm=Signature Algorithm
+CertificateParser.IssuerX500=Issuer(X500)
+CertificateParser.Issuer=Issuer
+CertificateParser.ValidFrom=Valid from
+CertificateParser.ValidTo=Valit to
+CertificateParser.AlternativeNames=Alternative names
+CertificateParser.Details=Details
+CertificateParser.Certificate=Certificate
+CertificateParser.NOALTNAMES=This certificate has no alternative names.
diff --git a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties
index c75b7e1e40..f869ae5a77 100644
--- a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties
+++ b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties
@@ -319,3 +319,16 @@ TelegramReport.ChannelMigratedFromGroup=Dieser Kanal ist aus einer Gruppe hervor
TelegramReport.RecoveredGroup=wiederhergestellte gelöschte Gruppe
P2P.FoundInPedoHashDB=* Rote Zeile bedeutet, dass der Hash in der KiPo Hash-Datenbank gefunden wurde.
Win10Mail.NotFound=Nicht gefunden
+CertificateParser.SubjectX500=Subject(X500)(TBT)
+CertificateParser.Subject=Subject(TBT)
+CertificateParser.Version=Version(TBT)
+CertificateParser.SerialNumber=Serial Number(TBT)
+CertificateParser.SignatureAlgorithm=Signature Algorithm(TBT)
+CertificateParser.IssuerX500=Issuer(X500)(TBT)
+CertificateParser.Issuer=Issuer(TBT)
+CertificateParser.ValidFrom=Valid from(TBT)
+CertificateParser.ValidTo=Valit to(TBT)
+CertificateParser.AlternativeNames=Alternative names(TBT)
+CertificateParser.Details=Details(TBT)
+CertificateParser.Certificate=Certificate(TBT)
+CertificateParser.NOALTNAMES=This certificate has no alternative names.(TBT)
diff --git a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties
index c0596fe8cb..c1fe806c4a 100644
--- a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties
+++ b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties
@@ -319,3 +319,16 @@ TelegramReport.ChannelMigratedFromGroup=Este canal ha migrado desde un grupo
TelegramReport.RecoveredGroup=Grupo borrado recuperado
P2P.FoundInPedoHashDB=* Las líneas rojas significan que los hashtags se encontraron en bases de datos de hashtags de alertas de pornografía infantil.
Win10Mail.NotFound=No encontrado
+CertificateParser.SubjectX500=Subject(X500)(TBT)
+CertificateParser.Subject=Subject(TBT)
+CertificateParser.Version=Version(TBT)
+CertificateParser.SerialNumber=Serial Number(TBT)
+CertificateParser.SignatureAlgorithm=Signature Algorithm(TBT)
+CertificateParser.IssuerX500=Issuer(X500)(TBT)
+CertificateParser.Issuer=Issuer(TBT)
+CertificateParser.ValidFrom=Valid from(TBT)
+CertificateParser.ValidTo=Valit to(TBT)
+CertificateParser.AlternativeNames=Alternative names(TBT)
+CertificateParser.Details=Details(TBT)
+CertificateParser.Certificate=Certificate(TBT)
+CertificateParser.NOALTNAMES=This certificate has no alternative names.(TBT)
diff --git a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties
index db8a50e075..a18296efdb 100644
--- a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties
+++ b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties
@@ -319,3 +319,16 @@ TelegramReport.ChannelMigratedFromGroup=Questo canale è migrato da un gruppo
TelegramReport.RecoveredGroup=Gruppo cancellato recuperato
P2P.FoundInPedoHashDB=* Le linee rosse indicano che gli hash sono stati trovati nel child porn alert hash databases.
Win10Mail.NotFound=Non trovato
+CertificateParser.SubjectX500=Subject(X500)(TBT)
+CertificateParser.Subject=Subject(TBT)
+CertificateParser.Version=Version(TBT)
+CertificateParser.SerialNumber=Serial Number(TBT)
+CertificateParser.SignatureAlgorithm=Signature Algorithm(TBT)
+CertificateParser.IssuerX500=Issuer(X500)(TBT)
+CertificateParser.Issuer=Issuer(TBT)
+CertificateParser.ValidFrom=Valid from(TBT)
+CertificateParser.ValidTo=Valit to(TBT)
+CertificateParser.AlternativeNames=Alternative names(TBT)
+CertificateParser.Details=Details(TBT)
+CertificateParser.Certificate=Certificate(TBT)
+CertificateParser.NOALTNAMES=This certificate has no alternative names.(TBT)
diff --git a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties
index 7826525f39..bc88d2104f 100644
--- a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties
+++ b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties
@@ -319,3 +319,17 @@ TelegramReport.ChannelMigratedFromGroup=Este canal migrou de um grupo
TelegramReport.RecoveredGroup=Grupo apagado recuperado
P2P.FoundInPedoHashDB=* Linhas em vermelho indicam que os hashes foram encontrados em bases de hashes de alerta de pornografia infantil
Win10Mail.NotFound=Não Encontrado
+CertificateParser.SubjectX500=Sujeito(X500)
+CertificateParser.Subject=Sujeito
+CertificateParser.Version=Versão
+CertificateParser.SerialNumber=Número de série
+CertificateParser.SignatureAlgorithm=Algoritmo da assinature
+CertificateParser.IssuerX500=Emissor(X500)
+CertificateParser.Issuer=Emissor
+CertificateParser.ValidFrom=Válido desde
+CertificateParser.ValidTo=Válido até
+CertificateParser.AlternativeNames=Nomes alternativos
+CertificateParser.Details=Detalhes
+CertificateParser.Certificate=Certificado
+CertificateParser.NOALTNAMES=Este certificado não contém nomes alternativos.
+
diff --git a/iped-parsers/iped-parsers-impl/pom.xml b/iped-parsers/iped-parsers-impl/pom.xml
index 278c7d4f45..ef959fff31 100644
--- a/iped-parsers/iped-parsers-impl/pom.xml
+++ b/iped-parsers/iped-parsers-impl/pom.xml
@@ -28,6 +28,12 @@
3.8.0
test
+
+
+ org.bouncycastle
+ bcutil-jdk18on
+ 1.76
+
org.apache.tika
tika-parsers-standard-package
diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/security/CertificateParser.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/security/CertificateParser.java
index 1e38432717..0505261d0a 100644
--- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/security/CertificateParser.java
+++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/security/CertificateParser.java
@@ -22,6 +22,8 @@
import javax.xml.bind.DatatypeConverter;
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;
@@ -38,33 +40,63 @@
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cms.CMSException;
+import org.bouncycastle.cms.CMSSignedDataParser;
+import org.bouncycastle.cms.SignerInformation;
+import org.bouncycastle.cms.SignerInformationStore;
+import org.bouncycastle.operator.DigestCalculatorProvider;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+import org.bouncycastle.util.Store;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import iped.parsers.util.Messages;
+import iped.parsers.util.MetadataUtil;
public class CertificateParser extends AbstractParser {
/**
*
*/
private static final long serialVersionUID = 1L;
+
+ public static final MediaType X509_MIME = MediaType.application("x-x509-cert");
+
+ // these are old mimetypes before TIKA had implemented its mimetype
+ // x-x509-ca-cert
+ @Deprecated
public static final MediaType PEM_MIME = MediaType.application("x-pem-file");
+ @Deprecated
public static final MediaType DER_MIME = MediaType.application("pkix-cert");
+
private static final MediaType PKCS7_MIME = MediaType.application("pkcs7-mime");
public static final MediaType PKCS7_SIGNATURE = MediaType.application("pkcs7-signature");
private static Set 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 X500_ISSUER = "certificate:X500Issuer";
public static final String SUBJECT = "certificate:subject"; //$NON-NLS-1$
+ public static final String X500_SUBJECT = "certificate:X500Subject"; //$NON-NLS-1$
+ public static final String SIGNERS = "certificate:Signers"; //$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 getSupportedTypes(ParseContext arg0) {
if (SUPPORTED_TYPES == null) {
Set set = new HashSet<>();
set.add(PEM_MIME);
set.add(DER_MIME);
+ set.add(X509_MIME);
set.add(PKCS7_MIME);
set.add(PKCS7_SIGNATURE);
SUPPORTED_TYPES = set;
@@ -87,16 +119,50 @@ public void parse(InputStream stream, ContentHandler handler, Metadata metadata,
String mimeType = metadata.get("Indexer-Content-Type");
if (mimeType.equals(PKCS7_SIGNATURE.toString())) {
+ EmbeddedDocumentExtractor extractor = context.get(EmbeddedDocumentExtractor.class,
+ new ParsingEmbeddedDocumentExtractor(context));
try (InputStream certStream = new FileInputStream(file)) {
CertPath p = cf.generateCertPath(certStream, "PKCS7");
List certs = p.getCertificates();
- XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
- xhtml.startDocument();
+
+ // extracts certificates
for (Iterator iterator = certs.iterator(); iterator.hasNext();) {
cert = (X509Certificate) iterator.next();
- generateCertificateHtml(cert, xhtml);
+
+ Metadata certMetadata = new Metadata();
+ certMetadata.add(TikaCoreProperties.RESOURCE_NAME_KEY,
+ cert.getSubjectX500Principal().getName());
+
+ extractor.parseEmbedded(new ByteArrayInputStream(cert.getEncoded()), new DefaultHandler(),
+ certMetadata,
+ true);
}
- xhtml.endDocument();
+ }
+ try (InputStream certStream = new FileInputStream(file)) {
+ DigestCalculatorProvider digestCalculatorProvider = new JcaDigestCalculatorProviderBuilder()
+ .setProvider("BC").build();
+ CMSSignedDataParser sp = new CMSSignedDataParser(digestCalculatorProvider, certStream);
+ // extracts certificates
+ Store certStore = sp.getCertificates();
+ SignerInformationStore signers = sp.getSignerInfos();
+
+ Collection c = signers.getSigners();
+ Iterator it = c.iterator();
+
+ List certificates = new ArrayList();
+ while (it.hasNext()) {
+ SignerInformation signer = (SignerInformation) it.next();
+ Collection certCollection = certStore.getMatches(signer.getSID());
+
+ Iterator certIt = certCollection.iterator();
+ X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next();
+
+ metadata.add(SIGNERS,
+ certHolder.getSubject().toString());
+ }
+ } catch (CMSException e) {
+ // ignores as this content does not seem to hold any data (as is the case with
+ // certificates with full certification path
}
} else {
InputStream certStream = null;
@@ -110,83 +176,108 @@ 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();
- }
- metadata.set(NOTBEFORE, cert.getNotBefore());
- metadata.set(NOTAFTER, cert.getNotAfter());
- metadata.set(ISSUER, cert.getIssuerX500Principal().getName());
- metadata.set(SUBJECT, cert.getSubjectX500Principal().getName());
- if (cert.getBasicConstraints() <= -1) {
- metadata.set(ISSUBJECTAUTHORITY, Boolean.FALSE.toString());
- } else {
- metadata.set(ISSUBJECTAUTHORITY, Boolean.TRUE.toString());
+ metadata.set(NOTBEFORE, cert.getNotBefore());
+ metadata.set(NOTAFTER, cert.getNotAfter());
+
+ metadata.set(X500_ISSUER, cert.getIssuerX500Principal().getName());
+ metadata.set(ISSUER, cert.getIssuerDN().getName());
+ metadata.set(X500_SUBJECT, cert.getSubjectX500Principal().getName());
+ metadata.set(SUBJECT, cert.getSubjectDN().getName());
+ if (cert.getBasicConstraints() <= -1) {
+ metadata.set(ISSUBJECTAUTHORITY, Boolean.FALSE.toString());
+ } else {
+ metadata.set(ISSUBJECTAUTHORITY, Boolean.TRUE.toString());
+ }
+ metadata.set(HttpHeaders.CONTENT_TYPE, "text/plain");
+ metadata.set(TikaCoreProperties.TITLE, Messages.getString("CertificateParser.Certificate") + ":"
+ + cert.getSubjectX500Principal().getName());
}
- metadata.set(HttpHeaders.CONTENT_TYPE, "text/plain");
- metadata.set(TikaCoreProperties.TITLE, "Certificado:" + cert.getSubjectX500Principal().getName());
+
} catch (Exception e) {
+ e.printStackTrace();
throw new TikaException("Invalid or unkown certificate format.", e);
} finally {
tis.close();
}
}
+ static private String CSS = "th {text-align:left; font-family: Arial, sans-serif; background-color: rgb(240, 240, 240);} ";
+
private void generateCertificateHtml(X509Certificate cert, XHTMLContentHandler xhtml)
throws UnsupportedEncodingException, SAXException {
- xhtml.startElement("table");
+ xhtml.startElement("style");
+ xhtml.characters(CSS);
+ xhtml.endElement("style");
+ xhtml.startElement("table border='1'");
xhtml.startElement("tr");
xhtml.startElement("th");
- xhtml.characters("Propriedade");
- xhtml.endElement("th");
- xhtml.startElement("th");
- xhtml.characters("Valor");
+ xhtml.characters(Messages.getString("CertificateParser.SubjectX500"));// "Subject X500"
xhtml.endElement("th");
- xhtml.endElement("tr");
-
- xhtml.startElement("tr");
- xhtml.startElement("td");
- xhtml.characters("Subject");
- xhtml.endElement("td");
xhtml.startElement("td");
xhtml.characters(cert.getSubjectX500Principal().getName());
xhtml.endElement("td");
xhtml.endElement("tr");
xhtml.startElement("tr");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.Subject"));// "Subject"
+ xhtml.endElement("th");
xhtml.startElement("td");
- xhtml.characters("Version");
+ xhtml.characters(cert.getSubjectDN().getName());
xhtml.endElement("td");
+ xhtml.endElement("tr");
+
+ xhtml.startElement("tr");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.Version"));// "Version"
+ xhtml.endElement("th");
xhtml.startElement("td");
xhtml.characters(Integer.toString(cert.getVersion()));
xhtml.endElement("td");
xhtml.endElement("tr");
xhtml.startElement("tr");
- xhtml.startElement("td");
- xhtml.characters("Serial Number");
- xhtml.endElement("td");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.SerialNumber"));// "Serial Number"
+ xhtml.endElement("th");
xhtml.startElement("td");
xhtml.characters(cert.getSerialNumber().toString());
xhtml.endElement("td");
xhtml.endElement("tr");
xhtml.startElement("tr");
- xhtml.startElement("td");
- xhtml.characters("Signature Algorithm");
- xhtml.endElement("td");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.SignatureAlgorithm"));// "Signature Algorithm"
+ xhtml.endElement("th");
xhtml.startElement("td");
xhtml.characters(cert.getSigAlgName());
xhtml.endElement("td");
xhtml.endElement("tr");
xhtml.startElement("tr");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.IssuerX500"));// "Issuer X500"
+ xhtml.endElement("th");
xhtml.startElement("td");
- xhtml.characters("Issuer");
+ xhtml.characters(cert.getIssuerX500Principal().getName());
xhtml.endElement("td");
+ xhtml.endElement("tr");
+
+ xhtml.startElement("tr");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.Issuer"));// "Issuer"
+ xhtml.endElement("th");
xhtml.startElement("td");
xhtml.characters(cert.getIssuerX500Principal().getName());
xhtml.endElement("td");
@@ -194,27 +285,27 @@ private void generateCertificateHtml(X509Certificate cert, XHTMLContentHandler x
DateFormat df = DateFormat.getDateTimeInstance();
xhtml.startElement("tr");
- xhtml.startElement("td");
- xhtml.characters("Valid from");
- xhtml.endElement("td");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.ValidFrom"));// "Valid from"
+ xhtml.endElement("th");
xhtml.startElement("td");
xhtml.characters(df.format(cert.getNotBefore()));
xhtml.endElement("td");
xhtml.endElement("tr");
xhtml.startElement("tr");
- xhtml.startElement("td");
- xhtml.characters("Valid to");
- xhtml.endElement("td");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.ValidTo"));// "Valid to"
+ xhtml.endElement("th");
xhtml.startElement("td");
xhtml.characters(df.format(cert.getNotAfter()));
xhtml.endElement("td");
xhtml.endElement("tr");
xhtml.startElement("tr");
- xhtml.startElement("td");
- xhtml.characters("Alternative Names:");
- xhtml.endElement("td");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.AlternativeNames"));// "Alternative Names:"
+ xhtml.endElement("th");
xhtml.startElement("td");
List altNamesStrs = getAltNames(cert);
for (String altNameStr : altNamesStrs) {
@@ -224,6 +315,21 @@ private void generateCertificateHtml(X509Certificate cert, XHTMLContentHandler x
}
xhtml.endElement("td");
xhtml.endElement("tr");
+ xhtml.endElement("table");
+
+ xhtml.startElement("table");
+ xhtml.startElement("tr");
+ xhtml.startElement("th");
+ xhtml.characters(Messages.getString("CertificateParser.Details"));
+ xhtml.endElement("th");
+ xhtml.endElement("tr");
+ xhtml.startElement("tr");
+ xhtml.startElement("td");
+ xhtml.startElement("pre");
+ xhtml.characters(cert.toString());
+ xhtml.endElement("pre");
+ xhtml.endElement("td");
+ xhtml.endElement("tr");
xhtml.endElement("table");
@@ -242,10 +348,10 @@ private List getAltNames(X509Certificate cert) {
ASN1Sequence altNameSeq = getAltnameSequence(altNameBytes);
final ASN1TaggedObject obj = (ASN1TaggedObject) altNameSeq.getObjectAt(1);
if (obj != null) {
- ASN1Primitive prim = obj.getObject();
+ ASN1Primitive prim = obj.getLoadedObject();
// can be tagged one more time
if (prim instanceof ASN1TaggedObject) {
- prim = ASN1TaggedObject.getInstance(((ASN1TaggedObject) prim)).getObject();
+ prim = ASN1TaggedObject.getInstance(((ASN1TaggedObject) prim)).getLoadedObject();
}
if (prim instanceof ASN1OctetString) {
@@ -258,9 +364,14 @@ private List getAltNames(X509Certificate cert) {
altNamesStrs.add(altNameStr);
}
}
+ if (itemType == 1) {
+ altNamesStrs.add(sanItem.get(1).toString());
+ }
}
}
- altNamesStrs.add(NOALTNAMES);
+ if (altNamesStrs.size() == 0) {
+ altNamesStrs.add(Messages.getString("CertificateParser.NOALTNAMES"));
+ }
} catch (IOException | CertificateParsingException e) {
// ignore error.
}
diff --git a/iped-parsers/iped-parsers-impl/src/test/java/iped/parsers/security/CertificateParserTest.java b/iped-parsers/iped-parsers-impl/src/test/java/iped/parsers/security/CertificateParserTest.java
index 15a967b990..94f1291a9b 100644
--- a/iped-parsers/iped-parsers-impl/src/test/java/iped/parsers/security/CertificateParserTest.java
+++ b/iped-parsers/iped-parsers-impl/src/test/java/iped/parsers/security/CertificateParserTest.java
@@ -2,10 +2,15 @@
import java.io.IOException;
import java.io.InputStream;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
import java.text.DateFormat;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import org.apache.tika.exception.TikaException;
+import org.apache.tika.extractor.EmbeddedDocumentExtractor;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.metadata.TikaCoreProperties;
import org.apache.tika.parser.ParseContext;
@@ -17,6 +22,7 @@
import com.google.common.net.HttpHeaders;
import iped.parsers.standard.StandardParser;
+import iped.parsers.util.Messages;
import junit.framework.TestCase;
public class CertificateParserTest extends TestCase {
@@ -50,40 +56,39 @@ public void testCertificateParsingDER() throws IOException, SAXException, TikaEx
try (InputStream stream = getStream("test-files/test_serverCert.der")) {
parser.parse(stream, handler, metadata, context);
String hts = handler.toString();
- assertTrue(hts.contains("Propriedade"));
- assertTrue(hts.contains("Valor"));
- assertTrue(hts.contains("Subject"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.Subject")));
assertTrue(hts.contains(
"1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR"));
- assertTrue(hts.contains("Version"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.Version")));
assertTrue(hts.contains("3"));
- assertTrue(hts.contains("Serial Number"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.SerialNumber")));
assertTrue(hts.contains("12677675471164634689"));
- assertTrue(hts.contains("Signature Algorithm"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.SignatureAlgorithm")));
assertTrue(hts.contains("SHA1withRSA"));
- assertTrue(hts.contains("Issuer"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.Issuer")));
assertTrue(hts.contains(
"1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR"));
- assertTrue(hts.contains("Valid from"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.ValidFrom")));
DateFormat df = DateFormat.getDateTimeInstance();
assertTrue(hts.contains(df.format(new Date(1622568518000L))));
- assertTrue(hts.contains("Valid to"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.ValidTo")));
assertTrue(hts.contains(df.format(new Date(1625160518000L))));
- assertTrue(hts.contains("Alternative Names:"));
- assertTrue(hts.contains("This certificate has no alternative names."));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.AlternativeNames")));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.NOALTNAMES")));
assertEquals(
"1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
- metadata.get(CertificateParser.SUBJECT));
+ metadata.get(CertificateParser.X500_SUBJECT));
assertEquals("2021-07-01", metadata.get(CertificateParser.NOTAFTER).substring(0, 10));
assertEquals(
- "Certificado:1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
+ Messages.getString("CertificateParser.Certificate")
+ + ":1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
metadata.get(TikaCoreProperties.TITLE));
assertEquals(CertificateParser.DER_MIME.toString(), metadata.get(StandardParser.INDEXER_CONTENT_TYPE));
assertEquals("true", metadata.get(CertificateParser.ISSUBJECTAUTHORITY));
assertEquals(
"1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
- metadata.get(CertificateParser.ISSUER));
+ metadata.get(CertificateParser.X500_ISSUER));
assertEquals("2021-06-01", metadata.get(CertificateParser.NOTBEFORE).substring(0, 10));
assertEquals("text/plain", metadata.get(HttpHeaders.CONTENT_TYPE));
@@ -104,40 +109,39 @@ public void testCertificateParsingPEM() throws IOException, SAXException, TikaEx
parser.parse(stream, handler, metadata, context);
String hts = handler.toString();
- assertTrue(hts.contains("Propriedade"));
- assertTrue(hts.contains("Valor"));
- assertTrue(hts.contains("Subject"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.Subject")));
assertTrue(hts.contains(
"1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR"));
- assertTrue(hts.contains("Version"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.Version")));
assertTrue(hts.contains("3"));
- assertTrue(hts.contains("Serial Number"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.SerialNumber")));
assertTrue(hts.contains("12677675471164634689"));
- assertTrue(hts.contains("Signature Algorithm"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.SignatureAlgorithm")));
assertTrue(hts.contains("SHA1withRSA"));
- assertTrue(hts.contains("Issuer"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.Issuer")));
assertTrue(hts.contains(
"1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR"));
- assertTrue(hts.contains("Valid from"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.ValidFrom")));
DateFormat df = DateFormat.getDateTimeInstance();
assertTrue(hts.contains(df.format(new Date(1622568518000L))));
- assertTrue(hts.contains("Valid to"));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.ValidTo")));
assertTrue(hts.contains(df.format(new Date(1625160518000L))));
- assertTrue(hts.contains("Alternative Names:"));
- assertTrue(hts.contains("This certificate has no alternative names."));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.AlternativeNames")));
+ assertTrue(hts.contains(Messages.getString("CertificateParser.NOALTNAMES")));
assertEquals(
"1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
- metadata.get(CertificateParser.SUBJECT));
+ metadata.get(CertificateParser.X500_SUBJECT));
assertEquals("2021-07-01", metadata.get(CertificateParser.NOTAFTER).substring(0, 10));
assertEquals(
- "Certificado:1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
+ Messages.getString("CertificateParser.Certificate")
+ + ":1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
metadata.get(TikaCoreProperties.TITLE));
assertEquals(CertificateParser.PEM_MIME.toString(), metadata.get(StandardParser.INDEXER_CONTENT_TYPE));
assertEquals("true", metadata.get(CertificateParser.ISSUBJECTAUTHORITY));
assertEquals(
"1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
- metadata.get(CertificateParser.ISSUER));
+ metadata.get(CertificateParser.X500_ISSUER));
assertEquals("2021-06-01", metadata.get(CertificateParser.NOTBEFORE).substring(0, 10));
assertEquals("text/plain", metadata.get(HttpHeaders.CONTENT_TYPE));
@@ -154,46 +158,40 @@ public void testCertificateParsingPKCS7() throws IOException, SAXException, Tika
ContentHandler handler = new BodyContentHandler();
ParseContext context = new ParseContext();
parser.getSupportedTypes(context);
- try (InputStream stream = getStream("test-files/test_serverPKCS7.p7b")) {
- parser.parse(stream, handler, metadata, context);
- String hts = handler.toString();
- assertTrue(hts.contains("Propriedade"));
- assertTrue(hts.contains("Valor"));
- assertTrue(hts.contains("Subject"));
- assertTrue(hts.contains(
- "1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR"));
- assertTrue(hts.contains("Version"));
- assertTrue(hts.contains("3"));
- assertTrue(hts.contains("Serial Number"));
- assertTrue(hts.contains("12677675471164634689"));
- assertTrue(hts.contains("Signature Algorithm"));
- assertTrue(hts.contains("SHA1withRSA"));
- assertTrue(hts.contains("Issuer"));
- assertTrue(hts.contains(
- "1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR"));
- assertTrue(hts.contains("Valid from"));
- DateFormat df = DateFormat.getDateTimeInstance();
- assertTrue(hts.contains(df.format(new Date(1622568518000L))));
- assertTrue(hts.contains("Valid to"));
- assertTrue(hts.contains(df.format(new Date(1625160518000L))));
- assertTrue(hts.contains("Alternative Names:"));
- assertTrue(hts.contains("This certificate has no alternative names."));
+ List exceptions = new ArrayList<>();
+ List certificates = new ArrayList<>();
+ List metadatas = new ArrayList<>();
- assertEquals(
- "1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
- metadata.get(CertificateParser.SUBJECT));
- assertEquals("2021-07-01", metadata.get(CertificateParser.NOTAFTER).substring(0, 10));
- assertEquals(
- "Certificado:1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
- metadata.get(TikaCoreProperties.TITLE));
- assertEquals(CertificateParser.PKCS7_SIGNATURE.toString(), metadata.get(StandardParser.INDEXER_CONTENT_TYPE));
- assertEquals("true", metadata.get(CertificateParser.ISSUBJECTAUTHORITY));
- assertEquals(
- "1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR",
- metadata.get(CertificateParser.ISSUER));
- assertEquals("2021-06-01", metadata.get(CertificateParser.NOTBEFORE).substring(0, 10));
- assertEquals("text/plain", metadata.get(HttpHeaders.CONTENT_TYPE));
+ context.set(EmbeddedDocumentExtractor.class, new EmbeddedDocumentExtractor() {
+ @Override
+ public boolean shouldParseEmbedded(Metadata arg0) {
+ return true;
+ }
+
+ @Override
+ public void parseEmbedded(InputStream stream, ContentHandler arg1, Metadata metadata, boolean arg3)
+ throws SAXException, IOException {
+ try {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(stream);
+ certificates.add(cert);
+ } catch (Exception e) {
+ exceptions.add(e);
+ } finally {
+ }
+ }
+ });
+
+ try (InputStream stream = getStream("test-files/test_serverPKCS7.p7b")) {
+ parser.parse(stream, handler, metadata, context);
+
+ assertEquals(exceptions.size(), 0);
+ assertEquals(certificates.size(), 1);
+ assertEquals(certificates.get(0).getSubjectDN().toString(),
+ "EMAILADDRESS=guilhermeandreuce@gmail.com, CN=pf.gov.br, OU=PF, O=Polícia Federal, L=Asa Sul, ST=Brasília, C=BR");
+ assertEquals(certificates.get(0).getSubjectX500Principal().getName(),
+ "1.2.840.113549.1.9.1=#161b6775696c6865726d65616e64726575636540676d61696c2e636f6d,CN=pf.gov.br,OU=PF,O=Polícia Federal,L=Asa Sul,ST=Brasília,C=BR");
}