Search in sources :

Example 36 with COSName

use of com.tom_roush.pdfbox.cos.COSName in project PdfBox-Android by TomRoush.

the class PDStream method getFilters.

/**
 * This will get the list of filters that are associated with this stream.
 * Or null if there are none.
 *
 * @return A list of all encoding filters to apply to this stream.
 */
public List<COSName> getFilters() {
    List<COSName> retval = null;
    COSBase filters = stream.getFilters();
    if (filters instanceof COSName) {
        COSName name = (COSName) filters;
        retval = new COSArrayList<COSName>(name, name, stream, COSName.FILTER);
    } else if (filters instanceof COSArray) {
        retval = (List<COSName>) ((COSArray) filters).toList();
    }
    return retval;
}
Also used : COSName(com.tom_roush.pdfbox.cos.COSName) COSArray(com.tom_roush.pdfbox.cos.COSArray) COSBase(com.tom_roush.pdfbox.cos.COSBase) ArrayList(java.util.ArrayList) List(java.util.List)

Example 37 with COSName

use of com.tom_roush.pdfbox.cos.COSName in project PdfBox-Android by TomRoush.

the class AppearanceGeneratorHelper method validateAndEnsureAcroFormResources.

/*
     * Adobe Reader/Acrobat are adding resources which are at the field/widget level
     * to the AcroForm level.
     */
private void validateAndEnsureAcroFormResources() {
    // to match Adobe Reader/Acrobat behavior
    if (field.getAcroForm().getDefaultResources() == null) {
        return;
    }
    PDResources acroFormResources = field.getAcroForm().getDefaultResources();
    for (PDAnnotationWidget widget : field.getWidgets()) {
        if (widget.getNormalAppearanceStream() != null && widget.getNormalAppearanceStream().getResources() != null) {
            PDResources widgetResources = widget.getNormalAppearanceStream().getResources();
            for (COSName fontResourceName : widgetResources.getFontNames()) {
                try {
                    if (acroFormResources.getFont(fontResourceName) == null) {
                        Log.d("PdfBox-Android", "Adding font resource " + fontResourceName + " from widget to AcroForm");
                        acroFormResources.put(fontResourceName, widgetResources.getFont(fontResourceName));
                    }
                } catch (IOException e) {
                    Log.w("PdfBox-Android", "Unable to match field level font with AcroForm font");
                }
            }
        }
    }
}
Also used : COSName(com.tom_roush.pdfbox.cos.COSName) PDResources(com.tom_roush.pdfbox.pdmodel.PDResources) PDAnnotationWidget(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget) IOException(java.io.IOException)

Example 38 with COSName

use of com.tom_roush.pdfbox.cos.COSName in project PdfBox-Android by TomRoush.

the class PDAcroForm method resolveNeedsTranslation.

/**
 * Check if there is a translation needed to place the annotations content.
 *
 * @param appearanceStream
 * @return the need for a translation transformation.
 */
private boolean resolveNeedsTranslation(PDAppearanceStream appearanceStream) {
    boolean needsTranslation = true;
    PDResources resources = appearanceStream.getResources();
    if (resources != null && resources.getXObjectNames().iterator().hasNext()) {
        Iterator<COSName> xObjectNames = resources.getXObjectNames().iterator();
        while (xObjectNames.hasNext()) {
            try {
                // if the BBox of the PDFormXObject does not start at 0,0
                // there is no need do translate as this is done by the BBox definition.
                PDXObject xObject = resources.getXObject(xObjectNames.next());
                if (xObject instanceof PDFormXObject) {
                    PDRectangle bbox = ((PDFormXObject) xObject).getBBox();
                    float llX = bbox.getLowerLeftX();
                    float llY = bbox.getLowerLeftY();
                    if (Float.compare(llX, 0) != 0 && Float.compare(llY, 0) != 0) {
                        needsTranslation = false;
                    }
                }
            } catch (IOException e) {
            // we can safely ignore the exception here
            // as this might only cause a misplacement
            }
        }
        return needsTranslation;
    }
    return true;
}
Also used : COSName(com.tom_roush.pdfbox.cos.COSName) PDResources(com.tom_roush.pdfbox.pdmodel.PDResources) PDFormXObject(com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle) IOException(java.io.IOException) PDXObject(com.tom_roush.pdfbox.pdmodel.graphics.PDXObject)

Example 39 with COSName

use of com.tom_roush.pdfbox.cos.COSName in project PdfBox-Android by TomRoush.

the class PublicKeySecurityHandler method prepareForDecryption.

/**
 * Prepares everything to decrypt the document.
 *
 * @param encryption encryption dictionary, can be retrieved via
 * {@link PDDocument#getEncryption()}
 * @param documentIDArray document id which is returned via
 * {@link com.tom_roush.pdfbox.cos.COSDocument#getDocumentID()} (not used by
 * this handler)
 * @param decryptionMaterial Information used to decrypt the document.
 *
 * @throws IOException If there is an error accessing data. If verbose mode
 * is enabled, the exception message will provide more details why the
 * match wasn't successful.
 */
@Override
public void prepareForDecryption(PDEncryption encryption, COSArray documentIDArray, DecryptionMaterial decryptionMaterial) throws IOException {
    if (!(decryptionMaterial instanceof PublicKeyDecryptionMaterial)) {
        throw new IOException("Provided decryption material is not compatible with the document");
    }
    setDecryptMetadata(encryption.isEncryptMetaData());
    if (encryption.getLength() != 0) {
        this.keyLength = encryption.getLength();
    }
    PublicKeyDecryptionMaterial material = (PublicKeyDecryptionMaterial) decryptionMaterial;
    try {
        boolean foundRecipient = false;
        X509Certificate certificate = material.getCertificate();
        X509CertificateHolder materialCert = null;
        if (certificate != null) {
            materialCert = new X509CertificateHolder(certificate.getEncoded());
        }
        // the decrypted content of the enveloped data that match
        // the certificate in the decryption material provided
        byte[] envelopedData = null;
        // the bytes of each recipient in the recipients array
        COSArray array = (COSArray) encryption.getCOSObject().getItem(COSName.RECIPIENTS);
        if (array == null) {
            PDCryptFilterDictionary defaultCryptFilterDictionary = encryption.getDefaultCryptFilterDictionary();
            array = (COSArray) defaultCryptFilterDictionary.getCOSObject().getItem(COSName.RECIPIENTS);
        }
        byte[][] recipientFieldsBytes = new byte[array.size()][];
        // TODO encryption.getRecipientsLength() and getRecipientStringAt() should be deprecated
        int recipientFieldsLength = 0;
        StringBuilder extraInfo = new StringBuilder();
        for (int i = 0; i < array.size(); i++) {
            COSString recipientFieldString = (COSString) array.getObject(i);
            byte[] recipientBytes = recipientFieldString.getBytes();
            CMSEnvelopedData data = new CMSEnvelopedData(recipientBytes);
            Collection<RecipientInformation> recipCertificatesIt = data.getRecipientInfos().getRecipients();
            int j = 0;
            for (RecipientInformation ri : recipCertificatesIt) {
                // Impl: if a matching certificate was previously found it is an error,
                // here we just don't care about it
                RecipientId rid = ri.getRID();
                if (!foundRecipient && rid.match(materialCert)) {
                    foundRecipient = true;
                    PrivateKey privateKey = (PrivateKey) material.getPrivateKey();
                    // might need to call setContentProvider() if we use PKI token, see
                    // http://bouncy-castle.1462172.n4.nabble.com/CMSException-exception-unwrapping-key-key-invalid-unknown-key-type-passed-to-RSA-td4658109.html
                    envelopedData = ri.getContent(new JceKeyTransEnvelopedRecipient(privateKey));
                    break;
                }
                j++;
                if (certificate != null) {
                    extraInfo.append('\n');
                    extraInfo.append(j);
                    extraInfo.append(": ");
                    if (rid instanceof KeyTransRecipientId) {
                        appendCertInfo(extraInfo, (KeyTransRecipientId) rid, certificate, materialCert);
                    }
                }
            }
            recipientFieldsBytes[i] = recipientBytes;
            recipientFieldsLength += recipientBytes.length;
        }
        if (!foundRecipient || envelopedData == null) {
            throw new IOException("The certificate matches none of " + array.size() + " recipient entries" + extraInfo.toString());
        }
        if (envelopedData.length != 24) {
            throw new IOException("The enveloped data does not contain 24 bytes");
        }
        // now envelopedData contains:
        // - the 20 bytes seed
        // - the 4 bytes of permission for the current user
        byte[] accessBytes = new byte[4];
        System.arraycopy(envelopedData, 20, accessBytes, 0, 4);
        AccessPermission currentAccessPermission = new AccessPermission(accessBytes);
        currentAccessPermission.setReadOnly();
        setCurrentAccessPermission(currentAccessPermission);
        // what we will put in the SHA1 = the seed + each byte contained in the recipients array
        byte[] sha1Input = new byte[recipientFieldsLength + 20];
        // put the seed in the sha1 input
        System.arraycopy(envelopedData, 0, sha1Input, 0, 20);
        // put each bytes of the recipients array in the sha1 input
        int sha1InputOffset = 20;
        for (byte[] recipientFieldsByte : recipientFieldsBytes) {
            System.arraycopy(recipientFieldsByte, 0, sha1Input, sha1InputOffset, recipientFieldsByte.length);
            sha1InputOffset += recipientFieldsByte.length;
        }
        byte[] mdResult;
        if (encryption.getVersion() == 4 || encryption.getVersion() == 5) {
            mdResult = MessageDigests.getSHA256().digest(sha1Input);
            // detect whether AES encryption is used. This assumes that the encryption algo is
            // stored in the PDCryptFilterDictionary
            // However, crypt filters are used only when V is 4 or 5.
            PDCryptFilterDictionary defaultCryptFilterDictionary = encryption.getDefaultCryptFilterDictionary();
            if (defaultCryptFilterDictionary != null) {
                COSName cryptFilterMethod = defaultCryptFilterDictionary.getCryptFilterMethod();
                setAES(COSName.AESV2.equals(cryptFilterMethod) || COSName.AESV3.equals(cryptFilterMethod));
            }
        } else {
            mdResult = MessageDigests.getSHA1().digest(sha1Input);
        }
        // we have the encryption key ...
        encryptionKey = new byte[this.keyLength / 8];
        System.arraycopy(mdResult, 0, encryptionKey, 0, this.keyLength / 8);
    } catch (CMSException e) {
        throw new IOException(e);
    } catch (KeyStoreException e) {
        throw new IOException(e);
    } catch (CertificateEncodingException e) {
        throw new IOException(e);
    }
}
Also used : CMSEnvelopedData(org.bouncycastle.cms.CMSEnvelopedData) KeyTransRecipientId(org.bouncycastle.cms.KeyTransRecipientId) RecipientId(org.bouncycastle.cms.RecipientId) PrivateKey(java.security.PrivateKey) KeyTransRecipientId(org.bouncycastle.cms.KeyTransRecipientId) JceKeyTransEnvelopedRecipient(org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient) CertificateEncodingException(java.security.cert.CertificateEncodingException) IOException(java.io.IOException) KeyStoreException(java.security.KeyStoreException) X509Certificate(java.security.cert.X509Certificate) RecipientInformation(org.bouncycastle.cms.RecipientInformation) COSArray(com.tom_roush.pdfbox.cos.COSArray) COSName(com.tom_roush.pdfbox.cos.COSName) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) COSString(com.tom_roush.pdfbox.cos.COSString) CMSException(org.bouncycastle.cms.CMSException)

Example 40 with COSName

use of com.tom_roush.pdfbox.cos.COSName in project PdfBox-Android by TomRoush.

the class PublicKeySecurityHandler method prepareDocumentForEncryption.

/**
 * Prepare the document for encryption.
 *
 * @param doc The document that will be encrypted.
 *
 * @throws IOException If there is an error while encrypting.
 */
@Override
public void prepareDocumentForEncryption(PDDocument doc) throws IOException {
    try {
        PDEncryption dictionary = doc.getEncryption();
        if (dictionary == null) {
            dictionary = new PDEncryption();
        }
        dictionary.setFilter(FILTER);
        dictionary.setLength(this.keyLength);
        int version = computeVersionNumber();
        dictionary.setVersion(version);
        // remove CF, StmF, and StrF entries that may be left from a previous encryption
        dictionary.removeV45filters();
        // create the 20 bytes seed
        byte[] seed = new byte[20];
        KeyGenerator key;
        try {
            key = KeyGenerator.getInstance("AES");
        } catch (NoSuchAlgorithmException e) {
            // should never happen
            throw new RuntimeException(e);
        }
        key.init(192, new SecureRandom());
        SecretKey sk = key.generateKey();
        // create the 20 bytes seed
        System.arraycopy(sk.getEncoded(), 0, seed, 0, 20);
        byte[][] recipientsFields = computeRecipientsField(seed);
        int shaInputLength = seed.length;
        for (byte[] field : recipientsFields) {
            shaInputLength += field.length;
        }
        byte[] shaInput = new byte[shaInputLength];
        System.arraycopy(seed, 0, shaInput, 0, 20);
        int shaInputOffset = 20;
        for (byte[] recipientsField : recipientsFields) {
            System.arraycopy(recipientsField, 0, shaInput, shaInputOffset, recipientsField.length);
            shaInputOffset += recipientsField.length;
        }
        byte[] mdResult;
        if (version == 4 || version == 5) {
            dictionary.setSubFilter(SUBFILTER5);
            mdResult = MessageDigests.getSHA256().digest(shaInput);
            COSName aesVName = version == 5 ? COSName.AESV3 : COSName.AESV2;
            prepareEncryptionDictAES(dictionary, aesVName, recipientsFields);
        } else {
            dictionary.setSubFilter(SUBFILTER4);
            mdResult = MessageDigests.getSHA1().digest(shaInput);
            dictionary.setRecipients(recipientsFields);
        }
        this.encryptionKey = new byte[this.keyLength / 8];
        System.arraycopy(mdResult, 0, this.encryptionKey, 0, this.keyLength / 8);
        doc.setEncryptionDictionary(dictionary);
        doc.getDocument().setEncryptionDictionary(dictionary.getCOSObject());
    } catch (GeneralSecurityException e) {
        throw new IOException(e);
    }
}
Also used : SecretKey(javax.crypto.SecretKey) COSName(com.tom_roush.pdfbox.cos.COSName) GeneralSecurityException(java.security.GeneralSecurityException) SecureRandom(java.security.SecureRandom) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) IOException(java.io.IOException) KeyGenerator(javax.crypto.KeyGenerator)

Aggregations

COSName (com.tom_roush.pdfbox.cos.COSName)83 COSBase (com.tom_roush.pdfbox.cos.COSBase)50 COSArray (com.tom_roush.pdfbox.cos.COSArray)27 IOException (java.io.IOException)24 COSDictionary (com.tom_roush.pdfbox.cos.COSDictionary)23 COSObject (com.tom_roush.pdfbox.cos.COSObject)11 COSString (com.tom_roush.pdfbox.cos.COSString)11 HashMap (java.util.HashMap)10 Map (java.util.Map)10 PDResources (com.tom_roush.pdfbox.pdmodel.PDResources)9 COSStream (com.tom_roush.pdfbox.cos.COSStream)7 PDFormXObject (com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject)7 MissingOperandException (com.tom_roush.pdfbox.contentstream.operator.MissingOperandException)5 COSInteger (com.tom_roush.pdfbox.cos.COSInteger)5 COSNumber (com.tom_roush.pdfbox.cos.COSNumber)5 PDXObject (com.tom_roush.pdfbox.pdmodel.graphics.PDXObject)5 PDRectangle (com.tom_roush.pdfbox.pdmodel.common.PDRectangle)4 PDTransparencyGroup (com.tom_roush.pdfbox.pdmodel.graphics.form.PDTransparencyGroup)4 OutputStream (java.io.OutputStream)4 Operator (com.tom_roush.pdfbox.contentstream.operator.Operator)3