<commit_before>/*
 * Copyright 2016 Datalogics Inc.
 */

package com.datalogics.pdf.hsm.samples;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.adobe.pdfjt.core.credentials.PrivateKeyHolder;
import com.adobe.pdfjt.core.credentials.PrivateKeyHolderFactory;
import com.adobe.pdfjt.core.credentials.impl.ByteArrayKeyHolder;
import com.adobe.pdfjt.core.credentials.impl.utils.CertUtils;

import com.datalogics.pdf.hsm.samples.mock.AbstractHsmManager;
import com.datalogics.pdf.hsm.samples.mock.MockProvider;
import com.datalogics.pdf.hsm.samples.util.LogRecordListCollector;
import com.datalogics.pdf.security.HsmManager;

import org.junit.BeforeClass;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

/**
 * Unit tests simulating a connected HSM device.
 */
public class MockedHsmTest extends SampleTest {
    private static final Logger LOGGER = Logger.getLogger(MockedHsmTest.class.getName());

    static final String FILE_NAME = "SignedField.pdf";
    static final String MESSAGE = "Fully Qualified Name: Approver";

    private static URL inputUrl;
    private static URL outputUrl;
    private static File outputFile;
    private static HsmManager connectedHsmManager;

    /**
     * Set up to try and sign a document with an unconnected HSM device.
     *
     * @throws Exception a general exception was thrown
     */
    @BeforeClass
    public static void setUpForMock() throws Exception {
        inputUrl = HsmSignDocument.class.getResource(HsmSignDocument.INPUT_UNSIGNED_PDF_PATH);
        outputFile = SampleTest.newOutputFileWithDelete(FILE_NAME);

        // The complete file name will be set in the HsmSignDocument class.
        outputUrl = outputFile.toURI().toURL();

        // Create a connected HsmManager
        connectedHsmManager = new ConnectedHsmManager();
    }

    @Test
    public void logMessageIsGenerated() throws Exception {
        final ArrayList<LogRecord> logRecords = new ArrayList<LogRecord>();
        final Logger logger = Logger.getLogger(HsmSignDocument.class.getName());
        try (LogRecordListCollector collector = new LogRecordListCollector(logger, logRecords)) {
            HsmSignDocument.signExistingSignatureFields(connectedHsmManager, inputUrl, outputUrl);
        } catch (final IllegalStateException e) {
            // Expected exception
        }

        // Verify that we got the expected log message
        assertEquals("Must have one log record", 1, logRecords.size());
        final LogRecord logRecord = logRecords.get(0);
        assertEquals(MESSAGE, logRecord.getMessage());
        assertEquals(Level.INFO, logRecord.getLevel());
    }

    @Test
    public void outputFileIsGenerated() throws Exception {
        try {
            HsmSignDocument.signExistingSignatureFields(connectedHsmManager, inputUrl, outputUrl);
        } catch (final IllegalStateException e) {
            // Expected exception
        }

        // Verify the Output file exists.
        assertTrue(outputFile.getPath() + " must exist after run", outputFile.exists());
    }

    /*
     * An HsmManager which is always connected.
     */
    private static class ConnectedHsmManager extends AbstractHsmManager {
        private static final String DER_KEY_PATH = "pdfjt-key.der";
        private static final String DER_CERT_PATH = "pdfjt-cert.der";

        final InputStream certStream = MockedHsmTest.class.getResourceAsStream(DER_CERT_PATH);
        final InputStream keyStream = MockedHsmTest.class.getResourceAsStream(DER_KEY_PATH);

        private Key key;
        private Certificate[] certificateChain;

        public ConnectedHsmManager() throws Exception {<commit_msg>Add unit test to validate the signature produced by the sample<commit_after>/*
 * Copyright 2016 Datalogics Inc.
 */

package com.datalogics.pdf.hsm.samples;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import com.adobe.pdfjt.core.credentials.PrivateKeyHolder;
import com.adobe.pdfjt.core.credentials.PrivateKeyHolderFactory;
import com.adobe.pdfjt.core.credentials.impl.ByteArrayKeyHolder;
import com.adobe.pdfjt.core.credentials.impl.utils.CertUtils;
import com.adobe.pdfjt.core.exceptions.PDFIOException;
import com.adobe.pdfjt.core.exceptions.PDFInvalidDocumentException;
import com.adobe.pdfjt.core.exceptions.PDFSecurityException;
import com.adobe.pdfjt.pdf.document.PDFDocument;
import com.adobe.pdfjt.services.digsig.SignatureFieldInterface;
import com.adobe.pdfjt.services.digsig.SignatureManager;

import com.datalogics.pdf.hsm.samples.mock.AbstractHsmManager;
import com.datalogics.pdf.hsm.samples.mock.MockProvider;
import com.datalogics.pdf.hsm.samples.util.DocumentUtils;
import com.datalogics.pdf.hsm.samples.util.LogRecordListCollector;
import com.datalogics.pdf.security.HsmManager;

import org.junit.BeforeClass;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

/**
 * Unit tests simulating a connected HSM device.
 */
public class MockedHsmTest extends SampleTest {
    private static final Logger LOGGER = Logger.getLogger(MockedHsmTest.class.getName());

    static final String FILE_NAME = "SignedField.pdf";
    static final String QUALIFIED_SIGNATURE_FIELD_NAME = "Approver";
    static final String LOG_MESSAGE = "Fully Qualified Name: " + QUALIFIED_SIGNATURE_FIELD_NAME;

    private static URL inputUrl;
    private static URL outputUrl;
    private static File outputFile;
    private static HsmManager connectedHsmManager;

    /**
     * Set up to try and sign a document with an unconnected HSM device.
     *
     * @throws Exception a general exception was thrown
     */
    @BeforeClass
    public static void setUpForMock() throws Exception {
        inputUrl = HsmSignDocument.class.getResource(HsmSignDocument.INPUT_UNSIGNED_PDF_PATH);
        outputFile = SampleTest.newOutputFileWithDelete(FILE_NAME);

        // The complete file name will be set in the HsmSignDocument class.
        outputUrl = outputFile.toURI().toURL();

        // Create a connected HsmManager
        connectedHsmManager = new ConnectedHsmManager();
    }

    @Test
    public void logMessageIsGenerated() throws Exception {
        final ArrayList<LogRecord> logRecords = new ArrayList<LogRecord>();
        final Logger logger = Logger.getLogger(HsmSignDocument.class.getName());
        try (LogRecordListCollector collector = new LogRecordListCollector(logger, logRecords)) {
            HsmSignDocument.signExistingSignatureFields(connectedHsmManager, inputUrl, outputUrl);
        } catch (final IllegalStateException e) {
            // Expected exception
        }

        // Verify that we got the expected log message
        assertEquals("Must have one log record", 1, logRecords.size());
        final LogRecord logRecord = logRecords.get(0);
        assertEquals(LOG_MESSAGE, logRecord.getMessage());
        assertEquals(Level.INFO, logRecord.getLevel());
    }

    @Test
    public void outputFileIsGenerated() throws Exception {
        try {
            HsmSignDocument.signExistingSignatureFields(connectedHsmManager, inputUrl, outputUrl);
        } catch (final IllegalStateException e) {
            // Expected exception
        }

        // Verify the Output file exists.
        assertTrue(outputFile.getPath() + " must exist after run", outputFile.exists());
    }

    @Test
    public void signatureIsValid() throws Exception {
        try {
            HsmSignDocument.signExistingSignatureFields(connectedHsmManager, inputUrl, outputUrl);
        } catch (final IllegalStateException e) {
            // Expected exception
        }

        final PDFDocument doc = DocumentUtils.openPdfDocument(outputUrl);

        try {
            // Make sure that Signature field is signed.
            final SignatureFieldInterface sigField = getSignedSignatureField(doc);
            assertTrue("Signature field must be signed", sigField.isSigned());
            assertTrue("Signature field must be visible", sigField.isVisible());
            assertEquals("Qualified field names must match", QUALIFIED_SIGNATURE_FIELD_NAME,
                         sigField.getQualifiedName());

        } finally {
            doc.close();
        }
    }

    /*
     * Retrieve the first signed signature field.
     */
    private static SignatureFieldInterface getSignedSignatureField(final PDFDocument doc)
                    throws PDFInvalidDocumentException, PDFIOException, PDFSecurityException {
        // Set up a signature service and get the first signature field.
        final SignatureManager sigService = SignatureManager.newInstance(doc);
        if (sigService.hasSignedSignatureFields()) {
            final Iterator<SignatureFieldInterface> iter = sigService.getDocSignatureFieldIterator();
            if (iter.hasNext()) {
                return iter.next();
            }
        }
        return null;
    }

    /*
     * An HsmManager which is always connected.
     */
    private static class ConnectedHsmManager extends AbstractHsmManager {
        private static final String DER_KEY_PATH = "pdfjt-key.der";
        private static final String DER_CERT_PATH = "pdfjt-cert.der";

        final InputStream certStream = MockedHsmTest.class.getResourceAsStream(DER_CERT_PATH);
        final InputStream keyStream = MockedHsmTest.class.getResourceAsStream(DER_KEY_PATH);

        private Key key;
        private Certificate[] certificateChain;

        public ConnectedHsmManager() throws Exception {
{'fraction_non_alphanumeric': 0.08332538850224044, 'fraction_numerical': 0.0017160835160644485, 'mean_word_length': 3.507950150408251, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2403558', 'n_tokens_mistral': 2857, 'n_tokens_neox': 2810, 'n_words': 693}