Example usage for java.security.cert X509Certificate getSerialNumber

List of usage examples for java.security.cert X509Certificate getSerialNumber

Introduction

In this page you can find the example usage for java.security.cert X509Certificate getSerialNumber.

Prototype

public abstract BigInteger getSerialNumber();

Source Link

Document

Gets the serialNumber value from the certificate.

Usage

From source file:org.cesecore.certificates.ocsp.CanLogCache.java

/**
 * Checks to see if a certificate is in a list of certificate. Comparison is made on SerialNumber
 * /*  w  w  w.j  a  v  a 2s  . c  om*/
 * @param cert the certificate to look for
 * @param trustedCerts the list (Hashtable) to look in
 * @return true if cert is in trustedCerts, false otherwise
 */
private boolean checkCertInList(X509Certificate cert, Map<String, X509Certificate> trustedCerts) {
    String key = cert.getIssuerDN() + ";" + cert.getSerialNumber().toString(16);
    return trustedCerts.get(key) != null;
}

From source file:org.apache.juddi.v3.client.cryptor.DigSigUtil.java

private X509Certificate FindCertByIssuer(String X509IssuerName, String X509SerialNumber) throws Exception {
    KeyStore ks = GetTrustStore();
    if (ks == null) {
        return null;
    }/*from www. ja va 2 s . c om*/
    Enumeration<String> aliases = ks.aliases();
    while (aliases.hasMoreElements()) {
        String nextElement = aliases.nextElement();
        Certificate certificate = ks.getCertificate(nextElement);
        X509Certificate x = (X509Certificate) certificate;
        if (x.getIssuerDN().getName().equals(X509IssuerName)
                && x.getSerialNumber().toString().equalsIgnoreCase(X509SerialNumber)) {
            return x;
        }
    }
    return null;
}

From source file:org.ejbca.core.protocol.cmp.CrmfRAPbeTcpRequestTest.java

public void test02CrmfTcpOkUser() throws Exception {

    byte[] nonce = CmpMessageHelper.createSenderNonce();
    byte[] transid = CmpMessageHelper.createSenderNonce();

    PKIMessage one = genCertReq(issuerDN, userDN, keys, cacert, nonce, transid, true, null, null, null, null);
    PKIMessage req = protectPKIMessage(one, false, PBEPASSWORD, 567);
    assertNotNull(req);/*from w  w w  .  j a v a  2  s.co  m*/

    int reqId = req.getBody().getIr().getCertReqMsg(0).getCertReq().getCertReqId().getValue().intValue();
    ByteArrayOutputStream bao = new ByteArrayOutputStream();
    DEROutputStream out = new DEROutputStream(bao);
    out.writeObject(req);
    byte[] ba = bao.toByteArray();
    // Send request and receive response
    byte[] resp = sendCmpTcp(ba, 5);
    checkCmpResponseGeneral(resp, issuerDN, userDN, cacert, nonce, transid, false, PBEPASSWORD);
    X509Certificate cert = checkCmpCertRepMessage(userDN, cacert, resp, reqId);
    assertNotNull(cert);

    // Send a confirm message to the CA
    String hash = "foo123";
    PKIMessage confirm = genCertConfirm(userDN, cacert, nonce, transid, hash, reqId);
    assertNotNull(confirm);
    PKIMessage req1 = protectPKIMessage(confirm, false, PBEPASSWORD, 567);
    bao = new ByteArrayOutputStream();
    out = new DEROutputStream(bao);
    out.writeObject(req1);
    ba = bao.toByteArray();
    // Send request and receive response
    resp = sendCmpTcp(ba, 5);
    checkCmpResponseGeneral(resp, issuerDN, userDN, cacert, nonce, transid, false, PBEPASSWORD);
    checkCmpPKIConfirmMessage(userDN, cacert, resp);

    // Now revoke the bastard using the CMPv2 CRL entry extension!
    PKIMessage rev = genRevReq(issuerDN, userDN, cert.getSerialNumber(), cacert, nonce, transid, true);
    PKIMessage revReq = protectPKIMessage(rev, false, PBEPASSWORD, 567);
    assertNotNull(revReq);
    bao = new ByteArrayOutputStream();
    out = new DEROutputStream(bao);
    out.writeObject(revReq);
    ba = bao.toByteArray();
    // Send request and receive response
    resp = sendCmpTcp(ba, 5);
    checkCmpResponseGeneral(resp, issuerDN, userDN, cacert, nonce, transid, false, PBEPASSWORD);
    checkCmpRevokeConfirmMessage(issuerDN, userDN, cert.getSerialNumber(), cacert, resp, true);
    int reason = checkRevokeStatus(issuerDN, cert.getSerialNumber());
    assertEquals(reason, RevokedCertInfo.REVOCATION_REASON_CESSATIONOFOPERATION);

}

From source file:net.sf.dsig.DSApplet.java

private Map<String, X509Certificate[]> createAliasX509CertificateChainPair(KeyStoreProxy ksh)
        throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException {
    Map<String, X509Certificate[]> aliasX509CertificateChainPair = new HashMap<String, X509Certificate[]>();

    Set<String> aliases = ksh.aliases();
    for (String alias : aliases) {
        X509Certificate[] certificateChain = ksh.getX509CertificateChain(alias);
        if (certificateChain == null || certificateChain.length == 0) {
            logger.warn("Null certificate chain returned; alias=" + alias);

            continue;
        }/*from   w w w.  j  av  a2 s.co m*/

        X509Certificate certificate = certificateChain[0];

        String subjectName = certificate.getSubjectX500Principal().getName();
        String issuerName = certificate.getIssuerX500Principal().getName();
        BigInteger serialNumber = certificate.getSerialNumber();

        // Filter by subject

        if (getSubjectMatchingPattern() != null
                && !getSubjectMatchingPattern().matcher(subjectName).matches()) {
            logger.info("Subject does not match; skipping" + ": certificate.subject=" + subjectName);
            continue;
        }

        // Filter by issuer

        if (getIssuerMatchingPattern() != null && !getIssuerMatchingPattern().matcher(issuerName).matches()) {
            logger.info("Issuer does not match; skipping" + ": certificate.subject=" + subjectName
                    + ", certificate.issuer=" + issuerName);
            continue;
        }

        // Filter by serial number

        if (getSerialNumbersAllowedSet() != null && !getSerialNumbersAllowedSet().contains(serialNumber)) {
            logger.info("Serial number is not allowed; skipping" + ": certificate.subject=" + subjectName
                    + ", certificate.serialNumber=" + serialNumber);
            continue;
        }

        // Filter by key usage

        if (keyUsageRestrictions != null
                && !KeyUsageHelper.validateKeyUsage(certificate, keyUsageRestrictions)) {
            logger.info("Key usage restrictions not met; skipping" + ": certificate.subject=" + subjectName
                    + ", certificate.keyUsage=" + KeyUsageHelper.printKeyUsage(certificate));
            continue;
        }

        // Filter by private key

        if (!ksh.isKeyEntry(alias)) {
            logger.info("Private key not found; skipping" + ": certificate.subject=" + subjectName);
            continue;
        }

        logger.debug("Accepting certificate" + "; certificate.alias=" + alias + ", certificate.subject="
                + subjectName + ", certificate.serialNumber=" + serialNumber);

        aliasX509CertificateChainPair.put(alias, ksh.getX509CertificateChain(alias));
    }

    return aliasX509CertificateChainPair;
}

From source file:org.syncany.plugins.webdav.WebdavTransferManager.java

private String formatCertificate(X509Certificate cert) {
    try {//from w ww  . j  av  a2  s. co m
        CipherUtil.enableUnlimitedStrength(); // Dirty!

        String checksumMd5 = formatChecksum(createChecksum(cert.getEncoded(), "MD5"));
        String checksumSha1 = formatChecksum(createChecksum(cert.getEncoded(), "SHA1"));
        String checksumSha256 = formatChecksum(createChecksum(cert.getEncoded(), "SHA256"));

        StringBuilder sb = new StringBuilder();

        sb.append(String.format("Owner: %s\n", cert.getSubjectDN().getName()));
        sb.append(String.format("Issuer: %s\n", cert.getIssuerDN().getName()));
        sb.append(String.format("Serial number: %d\n", cert.getSerialNumber()));
        sb.append(String.format("Valid from %s until: %s\n", cert.getNotBefore().toString(),
                cert.getNotAfter().toString()));
        sb.append("Certificate fingerprints:\n");
        sb.append(String.format(" MD5:  %s\n", checksumMd5));
        sb.append(String.format(" SHA1: %s\n", checksumSha1));
        sb.append(String.format(" SHA256: %s", checksumSha256));

        return sb.toString();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

From source file:dk.itst.oiosaml.sp.metadata.CRLChecker.java

public void checkCertificates(IdpMetadata metadata, Configuration conf) {
    for (String entityId : metadata.getEntityIDs()) {
        Metadata md = metadata.getMetadata(entityId);

        for (X509Certificate certificate : md.getAllCertificates()) {
            String url = getCRLUrl(conf, entityId, certificate);
            if (url == null) {
                log.debug("No CRL configured in oiosaml-sp.properties, and no CRL found in certificate");
                continue;
            }//from w  ww.  j a  v a 2s. c o m

            try {
                URL u = new URL(url);
                InputStream is = u.openStream();

                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                X509CRL crl = (X509CRL) cf.generateCRL(is);
                is.close();

                if (log.isDebugEnabled())
                    log.debug("CRL for " + url + ": " + crl);

                if (!checkCRLSignature(crl, certificate, conf)) {
                    md.setCertificateValid(certificate, false);
                } else {
                    X509CRLEntry revokedCertificate = crl.getRevokedCertificate(certificate.getSerialNumber());
                    boolean revoked = revokedCertificate != null;
                    log.debug(
                            "Certificate status for " + entityId + ": " + revoked + " - cert: " + certificate);
                    Audit.log(Operation.CRLCHECK, false, entityId, "Revoked: " + revoked);

                    md.setCertificateValid(certificate, !revoked);
                }
            } catch (MalformedURLException e) {
                log.error("Unable to parse url " + url, e);
                throw new WrappedException(Layer.BUSINESS, e);
            } catch (IOException e) {
                log.error("Unable to read CRL from " + url, e);
                throw new WrappedException(Layer.BUSINESS, e);
            } catch (GeneralSecurityException e) {
                throw new WrappedException(Layer.BUSINESS, e);
            }
        }
    }
}

From source file:com.otterca.common.crypto.acceptance.X509CertificateBuilderAcceptanceTest.java

/**
 * Test builder with issuer certificate.
 * /* w  ww  .ja v a  2  s  .c  o  m*/
 * @throws Exception
 */
@Test
public void testBuilderCertWithValidIssuer() throws GeneralSecurityException {
    // create issuer certificate
    populate(builder);
    builder.setSubject(ISSUER_NAME);
    builder.setIssuer(ISSUER_NAME);
    builder.setPublicKey(issuerKeyPair.getPublic());
    builder.setBasicConstraints(true);

    X509Certificate issuer = builder.build(issuerKeyPair.getPrivate());

    // perform basic validation.
    issuer.verify(issuerKeyPair.getPublic());

    // verify the basics
    assertEquals(issuer.getSerialNumber(), serial);
    assertEquals(issuer.getSubjectDN().getName(), ISSUER_NAME);
    assertEquals(issuer.getIssuerDN().getName(), ISSUER_NAME);
    assertEquals(issuer.getNotBefore(), notBefore.getTime());
    assertEquals(issuer.getNotAfter(), notAfter.getTime());
    // assertEquals(issuer.getPublicKey(), issuerKeyPair.getPublic());
    // FIXME: returns null

    builder.reset();

    // create subject certificate
    populate(builder);
    builder.setIssuer(issuer);

    X509Certificate cert = builder.build(keyPair.getPrivate());

    // perform basic validation.
    cert.verify(keyPair.getPublic());

    // verify the basics
    assertEquals(cert.getSerialNumber(), serial);
    assertEquals(cert.getSubjectDN().getName(), SUBJECT_NAME);
    assertEquals(cert.getIssuerDN().getName(), ISSUER_NAME);
    assertEquals(cert.getNotBefore(), notBefore.getTime());
    assertEquals(cert.getNotAfter(), notAfter.getTime());
    // assertEquals(cert.getPublicKey(), keyPair.getPublic()); FIXME:
    // returns null
}

From source file:org.wso2.carbon.security.keystore.KeyStoreAdmin.java

private CertData fillCertData(X509Certificate cert, String alise, Format formatter)
        throws CertificateEncodingException {
    CertData certData = null;//from   w w w .j a  v a 2 s  .c  om

    if (includeCert) {
        certData = new CertDataDetail();
    } else {
        certData = new CertData();
    }
    certData.setAlias(alise);
    certData.setSubjectDN(cert.getSubjectDN().getName());
    certData.setIssuerDN(cert.getIssuerDN().getName());
    certData.setSerialNumber(cert.getSerialNumber());
    certData.setVersion(cert.getVersion());
    certData.setNotAfter(formatter.format(cert.getNotAfter()));
    certData.setNotBefore(formatter.format(cert.getNotBefore()));
    certData.setPublicKey(Base64.encode(cert.getPublicKey().getEncoded()));

    if (includeCert) {
        ((CertDataDetail) certData).setCertificate(cert);
    }

    return certData;
}

From source file:org.xdi.oxauth.cert.validation.OCSPCertificateVerifier.java

@Override
public ValidationStatus validate(X509Certificate certificate, List<X509Certificate> issuers,
        Date validationDate) {//from   www. ja  v  a  2 s  . co m
    X509Certificate issuer = issuers.get(0);
    ValidationStatus status = new ValidationStatus(certificate, issuer, validationDate,
            ValidatorSourceType.OCSP, CertificateValidity.UNKNOWN);

    try {
        Principal subjectX500Principal = certificate.getSubjectX500Principal();

        String ocspUrl = getOCSPUrl(certificate);
        if (ocspUrl == null) {
            log.error("OCSP URL for '" + subjectX500Principal + "' is empty");
            return status;
        }

        log.debug("OCSP URL for '" + subjectX500Principal + "' is '" + ocspUrl + "'");

        DigestCalculator digestCalculator = new JcaDigestCalculatorProviderBuilder().build()
                .get(CertificateID.HASH_SHA1);
        CertificateID certificateId = new CertificateID(digestCalculator,
                new JcaX509CertificateHolder(certificate), certificate.getSerialNumber());

        // Generate OCSP request
        OCSPReq ocspReq = generateOCSPRequest(certificateId);

        // Get OCSP response from server
        OCSPResp ocspResp = requestOCSPResponse(ocspUrl, ocspReq);
        if (ocspResp.getStatus() != OCSPRespBuilder.SUCCESSFUL) {
            log.error("OCSP response is invalid!");
            status.setValidity(CertificateValidity.INVALID);
            return status;
        }

        boolean foundResponse = false;
        BasicOCSPResp basicOCSPResp = (BasicOCSPResp) ocspResp.getResponseObject();
        SingleResp[] singleResps = basicOCSPResp.getResponses();
        for (SingleResp singleResp : singleResps) {
            CertificateID responseCertificateId = singleResp.getCertID();
            if (!certificateId.equals(responseCertificateId)) {
                continue;
            }

            foundResponse = true;

            log.debug("OCSP validationDate: " + validationDate);
            log.debug("OCSP thisUpdate: " + singleResp.getThisUpdate());
            log.debug("OCSP nextUpdate: " + singleResp.getNextUpdate());

            status.setRevocationObjectIssuingTime(basicOCSPResp.getProducedAt());

            Object certStatus = singleResp.getCertStatus();
            if (certStatus == CertificateStatus.GOOD) {
                log.debug("OCSP status is valid for '" + certificate.getSubjectX500Principal() + "'");
                status.setValidity(CertificateValidity.VALID);
            } else {
                if (singleResp.getCertStatus() instanceof RevokedStatus) {
                    log.warn("OCSP status is revoked for: " + subjectX500Principal);
                    if (validationDate
                            .before(((RevokedStatus) singleResp.getCertStatus()).getRevocationTime())) {
                        log.warn("OCSP revocation time after the validation date, the certificate '"
                                + subjectX500Principal + "' was valid at " + validationDate);
                        status.setValidity(CertificateValidity.VALID);
                    } else {
                        Date revocationDate = ((RevokedStatus) singleResp.getCertStatus()).getRevocationTime();
                        log.info("OCSP for certificate '" + subjectX500Principal + "' is revoked since "
                                + revocationDate);
                        status.setRevocationDate(revocationDate);
                        status.setRevocationObjectIssuingTime(singleResp.getThisUpdate());
                        status.setValidity(CertificateValidity.REVOKED);
                    }
                }
            }
        }

        if (!foundResponse) {
            log.error("There is no matching OCSP response entries");
        }
    } catch (Exception ex) {
        log.error("OCSP exception: ", ex);
    }

    return status;
}

From source file:be.fedict.eid.tsl.Tsl2PdfExporter.java

/**
 * Produce a human readable export of the given tsl to the given file.
 * /* w  ww. j  av a  2s. c o  m*/
 * @param tsl
 *            the TrustServiceList to export
 * @param pdfFile
 *            the file to generate
 * @return
 * @throws IOException
 */
public void humanReadableExport(final TrustServiceList tsl, final File pdfFile) {
    Document document = new Document();
    OutputStream outputStream;
    try {
        outputStream = new FileOutputStream(pdfFile);
    } catch (FileNotFoundException e) {
        throw new RuntimeException("file not found: " + pdfFile.getAbsolutePath(), e);
    }
    try {
        final PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream);
        pdfWriter.setPDFXConformance(PdfWriter.PDFA1B);

        // title
        final EUCountry country = EUCountry.valueOf(tsl.getSchemeTerritory());
        final String title = country.getShortSrcLangName() + " (" + country.getShortEnglishName()
                + "): Trusted List";

        Phrase footerPhrase = new Phrase("PDF document generated on " + new Date().toString() + ", page ",
                headerFooterFont);
        HeaderFooter footer = new HeaderFooter(footerPhrase, true);
        document.setFooter(footer);

        Phrase headerPhrase = new Phrase(title, headerFooterFont);
        HeaderFooter header = new HeaderFooter(headerPhrase, false);
        document.setHeader(header);

        document.open();
        addTitle(title, title0Font, Paragraph.ALIGN_CENTER, 0, 20, document);

        addLongItem("Scheme name", tsl.getSchemeName(), document);
        addLongItem("Legal Notice", tsl.getLegalNotice(), document);

        // information table
        PdfPTable informationTable = createInfoTable();
        addItemRow("Scheme territory", tsl.getSchemeTerritory(), informationTable);
        addItemRow("Scheme status determination approach",
                substringAfter(tsl.getStatusDeterminationApproach(), "StatusDetn/"), informationTable);
        /*
        final List<String> schemeTypes = new ArrayList<String>();
        for (final String schemeType : tsl.getSchemeTypes()) {
           schemeTypes.add(schemeType);
        }
        */
        final List<String> schemeTypes = new ArrayList<String>();
        List<NonEmptyMultiLangURIType> uris = tsl.getSchemeTypes();
        for (NonEmptyMultiLangURIType uri : uris) {
            schemeTypes.add(uri.getValue());
        }
        addItemRow("Scheme type community rules", schemeTypes, informationTable);

        addItemRow("Issue date", tsl.getListIssueDateTime().toString(), informationTable);
        addItemRow("Next update", tsl.getNextUpdate().toString(), informationTable);
        addItemRow("Historical information period", tsl.getHistoricalInformationPeriod().toString() + " days",
                informationTable);
        addItemRow("Sequence number", tsl.getSequenceNumber().toString(), informationTable);
        addItemRow("Scheme information URIs", tsl.getSchemeInformationUris(), informationTable);

        document.add(informationTable);

        addTitle("Scheme Operator", title1Font, Paragraph.ALIGN_CENTER, 0, 10, document);

        informationTable = createInfoTable();
        addItemRow("Scheme operator name", tsl.getSchemeOperatorName(), informationTable);
        PostalAddressType schemeOperatorPostalAddress = tsl.getSchemeOperatorPostalAddress(Locale.ENGLISH);
        addItemRow("Scheme operator street address", schemeOperatorPostalAddress.getStreetAddress(),
                informationTable);
        addItemRow("Scheme operator postal code", schemeOperatorPostalAddress.getPostalCode(),
                informationTable);
        addItemRow("Scheme operator locality", schemeOperatorPostalAddress.getLocality(), informationTable);
        addItemRow("Scheme operator state", schemeOperatorPostalAddress.getStateOrProvince(), informationTable);
        addItemRow("Scheme operator country", schemeOperatorPostalAddress.getCountryName(), informationTable);

        List<String> schemeOperatorElectronicAddressess = tsl.getSchemeOperatorElectronicAddresses();
        addItemRow("Scheme operator contact", schemeOperatorElectronicAddressess, informationTable);
        document.add(informationTable);

        addTitle("Trust Service Providers", title1Font, Paragraph.ALIGN_CENTER, 10, 2, document);

        List<TrustServiceProvider> trustServiceProviders = tsl.getTrustServiceProviders();
        for (TrustServiceProvider trustServiceProvider : trustServiceProviders) {
            addTitle(trustServiceProvider.getName(), title1Font, Paragraph.ALIGN_LEFT, 10, 2, document);

            PdfPTable providerTable = createInfoTable();
            addItemRow("Service provider trade name", trustServiceProvider.getTradeNames(), providerTable);
            addItemRow("Information URI", trustServiceProvider.getInformationUris(), providerTable);
            PostalAddressType postalAddress = trustServiceProvider.getPostalAddress();
            addItemRow("Service provider street address", postalAddress.getStreetAddress(), providerTable);
            addItemRow("Service provider postal code", postalAddress.getPostalCode(), providerTable);
            addItemRow("Service provider locality", postalAddress.getLocality(), providerTable);
            addItemRow("Service provider state", postalAddress.getStateOrProvince(), providerTable);
            addItemRow("Service provider country", postalAddress.getCountryName(), providerTable);
            document.add(providerTable);

            List<TrustService> trustServices = trustServiceProvider.getTrustServices();
            for (TrustService trustService : trustServices) {
                addTitle(trustService.getName(), title2Font, Paragraph.ALIGN_LEFT, 10, 2, document);
                PdfPTable serviceTable = createInfoTable();
                addItemRow("Type", substringAfter(trustService.getType(), "Svctype/"), serviceTable);
                addItemRow("Status", substringAfter(trustService.getStatus(), "Svcstatus/"), serviceTable);
                addItemRow("Status starting time", trustService.getStatusStartingTime().toString(),
                        serviceTable);
                document.add(serviceTable);

                addTitle("Service digital identity (X509)", title3Font, Paragraph.ALIGN_LEFT, 2, 0, document);
                final X509Certificate certificate = trustService.getServiceDigitalIdentity();
                final PdfPTable serviceIdentityTable = createInfoTable();
                addItemRow("Version", Integer.toString(certificate.getVersion()), serviceIdentityTable);
                addItemRow("Serial number", certificate.getSerialNumber().toString(), serviceIdentityTable);
                addItemRow("Signature algorithm", certificate.getSigAlgName(), serviceIdentityTable);
                addItemRow("Issuer", certificate.getIssuerX500Principal().toString(), serviceIdentityTable);
                addItemRow("Valid from", certificate.getNotBefore().toString(), serviceIdentityTable);
                addItemRow("Valid to", certificate.getNotAfter().toString(), serviceIdentityTable);
                addItemRow("Subject", certificate.getSubjectX500Principal().toString(), serviceIdentityTable);
                addItemRow("Public key", certificate.getPublicKey().toString(), serviceIdentityTable);
                // TODO certificate policies
                addItemRow("Subject key identifier", toHex(getSKId(certificate)), serviceIdentityTable);
                addItemRow("CRL distribution points", getCrlDistributionPoints(certificate),
                        serviceIdentityTable);
                addItemRow("Authority key identifier", toHex(getAKId(certificate)), serviceIdentityTable);
                addItemRow("Key usage", getKeyUsage(certificate), serviceIdentityTable);
                addItemRow("Basic constraints", getBasicConstraints(certificate), serviceIdentityTable);

                byte[] encodedCertificate;
                try {
                    encodedCertificate = certificate.getEncoded();
                } catch (CertificateEncodingException e) {
                    throw new RuntimeException("cert: " + e.getMessage(), e);
                }
                addItemRow("SHA1 Thumbprint", DigestUtils.shaHex(encodedCertificate), serviceIdentityTable);
                addItemRow("SHA256 Thumbprint", DigestUtils.sha256Hex(encodedCertificate),
                        serviceIdentityTable);
                document.add(serviceIdentityTable);

                //add Scheme service definition 
                if (null != trustService.getSchemeServiceDefinitionURI()) {
                    addTitle("Scheme Service Definition URI", title3Font, Paragraph.ALIGN_LEFT, 2, 0, document);
                    final PdfPTable schemeServiceDefinitionURITabel = createInfoTable();
                    for (NonEmptyMultiLangURIType uri : trustService.getSchemeServiceDefinitionURI().getURI()) {
                        addItemRow(uri.getLang(), uri.getValue(), schemeServiceDefinitionURITabel);
                    }
                    document.add(schemeServiceDefinitionURITabel);
                }

                List<ExtensionType> extensions = trustService.getExtensions();
                for (ExtensionType extension : extensions) {
                    printExtension(extension, document);
                }

                addLongMonoItem("The decoded certificate:", certificate.toString(), document);
                addLongMonoItem("The certificate in PEM format:", toPem(certificate), document);

                ServiceHistoryType serviceHistoryType = trustService.getServiceHistoryInstanceType();

                if (null != serviceHistoryType) {

                    for (ServiceHistoryInstanceType serviceHistoryInstanceType : serviceHistoryType
                            .getServiceHistoryInstance()) {
                        PdfPTable serviceHistoryTable = createInfoTable();

                        //Service approval history information
                        addTitle("Service approval history information", title3Font, Paragraph.ALIGN_LEFT, 10,
                                2, document);

                        // service type identifier
                        //5.6.2 Service name
                        InternationalNamesType i18nServiceName = serviceHistoryInstanceType.getServiceName();
                        String servName = TrustServiceListUtils.getValue(i18nServiceName, Locale.ENGLISH);
                        addItemRow("Name", servName, serviceHistoryTable);
                        //5.6.1 Service type identifier
                        addItemRow("Type", substringAfter(serviceHistoryInstanceType.getServiceTypeIdentifier(),
                                "Svctype/"), serviceHistoryTable);
                        addItemRow("Status", serviceHistoryInstanceType.getServiceStatus(),
                                serviceHistoryTable);
                        //5.6.4 Service previous status
                        addItemRow("Previous status", serviceHistoryInstanceType.getServiceStatus(),
                                serviceHistoryTable);
                        //5.6.5 Previous status starting date and time
                        addItemRow(
                                "Previous starting time", new DateTime(serviceHistoryInstanceType
                                        .getStatusStartingTime().toGregorianCalendar()).toString(),
                                serviceHistoryTable);
                        //5.6.3 Service digital identity
                        final X509Certificate previousCertificate = trustService.getServiceDigitalIdentity(
                                serviceHistoryInstanceType.getServiceDigitalIdentity());

                        document.add(serviceHistoryTable);

                        addTitle("Service digital identity (X509)", title4Font, Paragraph.ALIGN_LEFT, 2, 0,
                                document);

                        final PdfPTable serviceIdentityTableHistory = createInfoTable();
                        addItemRow("Version", Integer.toString(previousCertificate.getVersion()),
                                serviceIdentityTableHistory);
                        addItemRow("Serial number", previousCertificate.getSerialNumber().toString(),
                                serviceIdentityTableHistory);
                        addItemRow("Signature algorithm", previousCertificate.getSigAlgName(),
                                serviceIdentityTableHistory);
                        addItemRow("Issuer", previousCertificate.getIssuerX500Principal().toString(),
                                serviceIdentityTableHistory);
                        addItemRow("Valid from", previousCertificate.getNotBefore().toString(),
                                serviceIdentityTableHistory);
                        addItemRow("Valid to", previousCertificate.getNotAfter().toString(),
                                serviceIdentityTableHistory);
                        addItemRow("Subject", previousCertificate.getSubjectX500Principal().toString(),
                                serviceIdentityTableHistory);
                        addItemRow("Public key", previousCertificate.getPublicKey().toString(),
                                serviceIdentityTableHistory);
                        // TODO certificate policies
                        addItemRow("Subject key identifier", toHex(getSKId(previousCertificate)),
                                serviceIdentityTableHistory);
                        addItemRow("CRL distribution points", getCrlDistributionPoints(previousCertificate),
                                serviceIdentityTableHistory);
                        addItemRow("Authority key identifier", toHex(getAKId(previousCertificate)),
                                serviceIdentityTableHistory);
                        addItemRow("Key usage", getKeyUsage(previousCertificate), serviceIdentityTableHistory);
                        addItemRow("Basic constraints", getBasicConstraints(previousCertificate),
                                serviceIdentityTableHistory);

                        byte[] encodedHistoryCertificate;
                        try {
                            encodedHistoryCertificate = previousCertificate.getEncoded();
                        } catch (CertificateEncodingException e) {
                            throw new RuntimeException("cert: " + e.getMessage(), e);
                        }
                        addItemRow("SHA1 Thumbprint", DigestUtils.shaHex(encodedHistoryCertificate),
                                serviceIdentityTableHistory);
                        addItemRow("SHA256 Thumbprint", DigestUtils.sha256Hex(encodedHistoryCertificate),
                                serviceIdentityTableHistory);
                        document.add(serviceIdentityTableHistory);

                        ExtensionsListType previousExtensions = serviceHistoryInstanceType
                                .getServiceInformationExtensions();
                        if (null != previousExtensions) {
                            for (ExtensionType extension : previousExtensions.getExtension()) {
                                printExtension(extension, document);
                            }
                        }

                        addLongMonoItem("The decoded certificate:", previousCertificate.toString(), document);
                        addLongMonoItem("The certificate in PEM format:", toPem(previousCertificate), document);
                    }
                }
            }
        }

        X509Certificate signerCertificate = tsl.verifySignature();
        if (null != signerCertificate) {
            Paragraph tslSignerTitle = new Paragraph("Trusted List Signer", title1Font);
            tslSignerTitle.setAlignment(Paragraph.ALIGN_CENTER);
            document.add(tslSignerTitle);

            final PdfPTable signerTable = createInfoTable();
            addItemRow("Subject", signerCertificate.getSubjectX500Principal().toString(), signerTable);
            addItemRow("Issuer", signerCertificate.getIssuerX500Principal().toString(), signerTable);
            addItemRow("Not before", signerCertificate.getNotBefore().toString(), signerTable);
            addItemRow("Not after", signerCertificate.getNotAfter().toString(), signerTable);
            addItemRow("Serial number", signerCertificate.getSerialNumber().toString(), signerTable);
            addItemRow("Version", Integer.toString(signerCertificate.getVersion()), signerTable);
            byte[] encodedPublicKey = signerCertificate.getPublicKey().getEncoded();
            addItemRow("Public key SHA1 Thumbprint", DigestUtils.shaHex(encodedPublicKey), signerTable);
            addItemRow("Public key SHA256 Thumbprint", DigestUtils.sha256Hex(encodedPublicKey), signerTable);
            document.add(signerTable);

            addLongMonoItem("The decoded certificate:", signerCertificate.toString(), document);
            addLongMonoItem("The certificate in PEM format:", toPem(signerCertificate), document);
            addLongMonoItem("The public key in PEM format:", toPem(signerCertificate.getPublicKey()), document);
        }

        document.close();
    } catch (DocumentException e) {
        throw new RuntimeException("PDF document error: " + e.getMessage(), e);
    } catch (Exception e) {
        throw new RuntimeException("Exception: " + e.getMessage(), e);
    }
}