org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSeedValue Maven / Gradle / Ivy
Show all versions of pdfbox Show documentation
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pdfbox.pdmodel.interactive.digitalsignature;
import java.util.ArrayList;
import java.util.List;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.common.COSArrayList;
import org.apache.pdfbox.pdmodel.common.COSObjectable;
/**
* This represents a pdf signature seed value dictionary.
*
* @author Thomas Chojecki
*/
public class PDSeedValue implements COSObjectable
{
/**
* A Ff flag.
*/
public static final int FLAG_FILTER = 1;
/**
* A Ff flag.
*/
public static final int FLAG_SUBFILTER = 1 << 1;
/**
* A Ff flag.
*/
public static final int FLAG_V = 1 << 2;
/**
* A Ff flag.
*/
public static final int FLAG_REASON = 1 << 3;
/**
* A Ff flag.
*/
public static final int FLAG_LEGAL_ATTESTATION = 1 << 4;
/**
* A Ff flag.
*/
public static final int FLAG_ADD_REV_INFO = 1 << 5;
/**
* A Ff flag.
*/
public static final int FLAG_DIGEST_METHOD = 1 << 6;
private COSDictionary dictionary;
/**
* Default constructor.
*/
public PDSeedValue()
{
dictionary = new COSDictionary();
dictionary.setItem(COSName.TYPE, COSName.SV);
dictionary.setDirect(true); // the specification claim to use direct objects
}
/**
* Constructor.
*
* @param dict The signature dictionary.
*/
public PDSeedValue(COSDictionary dict)
{
dictionary = dict;
dictionary.setDirect(true); // the specification claim to use direct objects
}
/**
* Convert this standard java object to a COS dictionary.
*
* @return The COS dictionary that matches this Java object.
*/
@Override
public COSDictionary getCOSObject()
{
return dictionary;
}
/**
*
* @return true if the Filter is required
*/
public boolean isFilterRequired()
{
return getCOSObject().getFlag( COSName.FF, FLAG_FILTER);
}
/**
* set true if the filter shall be required.
*
* @param flag if true, the specified Filter shall be used when signing.
*/
public void setFilterRequired(boolean flag)
{
getCOSObject().setFlag( COSName.FF, FLAG_FILTER, flag);
}
/**
*
* @return true if the SubFilter is required
*/
public boolean isSubFilterRequired()
{
return getCOSObject().getFlag( COSName.FF, FLAG_SUBFILTER);
}
/**
* set true if the subfilter shall be required.
*
* @param flag if true, the first supported SubFilter in the array shall be used when signing.
*/
public void setSubFilterRequired(boolean flag)
{
getCOSObject().setFlag( COSName.FF, FLAG_SUBFILTER, flag);
}
/**
*
* @return true if the DigestMethod is required
*/
public boolean isDigestMethodRequired()
{
return getCOSObject().getFlag( COSName.FF, FLAG_DIGEST_METHOD);
}
/**
* set true if the DigestMethod shall be required.
*
* @param flag if true, one digest from the array shall be used.
*/
public void setDigestMethodRequired(boolean flag)
{
getCOSObject().setFlag( COSName.FF, FLAG_DIGEST_METHOD, flag);
}
/**
*
* @return true if the V entry is required
*/
public boolean isVRequired()
{
return getCOSObject().getFlag( COSName.FF, FLAG_V);
}
/**
* set true if the V entry shall be required.
*
* @param flag if true, the V entry shall be used.
*/
public void setVRequired(boolean flag)
{
getCOSObject().setFlag( COSName.FF, FLAG_V, flag);
}
/**
*
* @return true if the Reason is required
*/
public boolean isReasonRequired()
{
return getCOSObject().getFlag( COSName.FF, FLAG_REASON);
}
/**
* set true if the Reason shall be required.
*
* @param flag if true, the Reason entry shall be used.
*/
public void setReasonRequired(boolean flag)
{
getCOSObject().setFlag( COSName.FF, FLAG_REASON, flag);
}
/**
*
* @return true if the LegalAttestation is required
*/
public boolean isLegalAttestationRequired()
{
return getCOSObject().getFlag( COSName.FF, FLAG_LEGAL_ATTESTATION);
}
/**
* set true if the LegalAttestation shall be required.
*
* @param flag if true, the LegalAttestation entry shall be used.
*/
public void setLegalAttestationRequired(boolean flag)
{
getCOSObject().setFlag( COSName.FF, FLAG_LEGAL_ATTESTATION, flag);
}
/**
*
* @return true if the AddRevInfo is required
*/
public boolean isAddRevInfoRequired()
{
return getCOSObject().getFlag( COSName.FF, FLAG_ADD_REV_INFO);
}
/**
* set true if the AddRevInfo shall be required.
*
* @param flag if true, the AddRevInfo shall be used.
*/
public void setAddRevInfoRequired(boolean flag)
{
getCOSObject().setFlag( COSName.FF, FLAG_ADD_REV_INFO, flag);
}
/**
* If Filter is not null and the {@link #isFilterRequired()} indicates this entry is a
* required constraint, then the signature handler specified by this entry shall be used when
* signing; otherwise, signing shall not take place. If {@link #isFilterRequired()} indicates
* that this is an optional constraint, this handler may be used if it is available. If it is
* not available, a different handler may be used instead.
*
* @return the filter that shall be used by the signature handler
*/
public String getFilter()
{
return dictionary.getNameAsString(COSName.FILTER);
}
/**
* (Optional) The signature handler that shall be used to sign the signature field.
*
* @param filter is the filter that shall be used by the signature handler
*/
public void setFilter(COSName filter)
{
dictionary.setItem(COSName.FILTER, filter);
}
/**
* If SubFilter is not null and the {@link #isSubFilterRequired()} indicates this
* entry is a required constraint, then the first matching encodings shall be used when
* signing; otherwise, signing shall not take place. If {@link #isSubFilterRequired()}
* indicates that this is an optional constraint, then the first matching encoding shall
* be used if it is available. If it is not available, a different encoding may be used
* instead.
*
* @return the subfilter that shall be used by the signature handler
*/
public List getSubFilter()
{
List retval = null;
COSArray fields = (COSArray)dictionary.getDictionaryObject(COSName.SUB_FILTER);
if (fields != null)
{
List actuals = new ArrayList();
for ( int i = 0; i < fields.size(); i++ )
{
String element = fields.getName(i);
if (element != null)
{
actuals.add(element);
}
}
retval = new COSArrayList(actuals, fields);
}
return retval;
}
/**
* (Optional) An array of names indicating encodings to use when signing. The first name
* in the array that matches an encoding supported by the signature handler shall be the
* encoding that is actually used for signing.
*
* @param subfilter is the name that shall be used for encoding
*/
public void setSubFilter(List subfilter)
{
dictionary.setItem(COSName.SUB_FILTER, COSArrayList.converterToCOSArray(subfilter));
}
/**
* An array of names indicating acceptable digest algorithms to use when
* signing. The value shall be one of SHA1, SHA256, SHA384,
* SHA512, RIPEMD160. The default value is implementation-specific.
*
* @return the digest method that shall be used by the signature handler
*/
public List getDigestMethod()
{
List retval = null;
COSArray fields = (COSArray)dictionary.getDictionaryObject(COSName.DIGEST_METHOD);
if (fields != null)
{
List actuals = new ArrayList();
for ( int i = 0; i < fields.size(); i++ )
{
String element = fields.getName(i);
if (element != null)
{
actuals.add(element);
}
}
retval = new COSArrayList(actuals, fields);
}
return retval;
}
/**
* (Optional, PDF 1.7) An array of names indicating acceptable digest
* algorithms to use when signing. The value shall be one of SHA1,
* SHA256, SHA384, SHA512, RIPEMD160. The default
* value is implementation-specific.
*
* This property is only applicable if the digital credential signing contains RSA
* public/privat keys
*
* @param digestMethod is a list of possible names of the digests, that should be
* used for signing.
*/
public void setDigestMethod(List digestMethod)
{
// integrity check
for ( COSName cosName : digestMethod )
{
if (!(cosName.equals(COSName.DIGEST_SHA1)
|| cosName.equals(COSName.DIGEST_SHA256)
|| cosName.equals(COSName.DIGEST_SHA384)
|| cosName.equals(COSName.DIGEST_SHA512)
|| cosName.equals(COSName.DIGEST_RIPEMD160)))
{
throw new IllegalArgumentException("Specified digest " + cosName.getName() + " isn't allowed.");
}
}
dictionary.setItem(COSName.DIGEST_METHOD, COSArrayList.converterToCOSArray(digestMethod));
}
/**
* The minimum required capability of the signature field seed value
* dictionary parser. A value of 1 specifies that the parser shall be able to
* recognize all seed value dictionary entries in a PDF 1.5 file. A value of 2
* specifies that it shall be able to recognize all seed value dictionary entries
* specified.
*
* @return the minimum required capability of the signature field seed value
* dictionary parser
*/
public float getV()
{
return dictionary.getFloat(COSName.V);
}
/**
* (Optional) The minimum required capability of the signature field seed value
* dictionary parser. A value of 1 specifies that the parser shall be able to
* recognize all seed value dictionary entries in a PDF 1.5 file. A value of 2
* specifies that it shall be able to recognize all seed value dictionary entries
* specified.
*
* @param minimumRequiredCapability is the minimum required capability of the
* signature field seed value dictionary parser
*/
public void setV(float minimumRequiredCapability)
{
dictionary.setFloat(COSName.V, minimumRequiredCapability);
}
/**
* If the Reasons array is provided and {@link #isReasonRequired()} indicates that
* Reasons is a required constraint, one of the reasons in the array shall be used
* for the signature dictionary; otherwise signing shall not take place. If the
* {@link #isReasonRequired()} indicates Reasons is an optional constraint, one of
* the reasons in the array may be chose or a custom reason can be provided.
*
* @return the reasons that should be used by the signature handler
*/
public List getReasons()
{
List retval = null;
COSArray fields = (COSArray)dictionary.getDictionaryObject(COSName.REASONS);
if (fields != null)
{
List actuals = new ArrayList();
for ( int i = 0; i < fields.size(); i++ )
{
String element = fields.getString(i);
if (element != null)
{
actuals.add(element);
}
}
retval = new COSArrayList(actuals, fields);
}
return retval;
}
/**
* (Optional) An array of text strings that specifying possible reasons for signing
* a document. If specified, the reasons supplied in this entry replace those used
* by conforming products.
*
* @param reasons is a list of possible text string that specifying possible reasons
*/
public void setReasonsd(List reasons)
{
dictionary.setItem(COSName.REASONS, COSArrayList.converterToCOSArray(reasons));
}
/**
* (Optional; PDF 1.6) A dictionary containing a single entry whose key is P
* and whose value is an integer between 0 and 3. A value of 0 defines the
* signatures as an author signature. The value 1 through 3 shall be used for
* certification signatures and correspond to the value of P in a DocMDP transform
* parameters dictionary.
*
* If this MDP key is not present or the MDP dictionary does not contain a P
* entry, no rules shall be defined regarding the type of signature or its
* permissions.
*
* @return the mdp dictionary as PDSeedValueMDP
*/
public PDSeedValueMDP getMDP()
{
COSDictionary dict = (COSDictionary)dictionary.getDictionaryObject(COSName.MDP);
PDSeedValueMDP mdp = null;
if (dict != null)
{
mdp = new PDSeedValueMDP(dict);
}
return mdp;
}
/**
* (Optional; PDF 1.6) A dictionary containing a single entry whose key is P
* and whose value is an integer between 0 and 3. A value of 0 defines the
* signatures as an author signature. The value 1 through 3 shall be used for
* certification signatures and correspond to the value of P in a DocMDP transform
* parameters dictionary.
*
* If this MDP key is not present or the MDP dictionary does not contain a P
* entry, no rules shall be defined regarding the type of signature or its
* permissions.
*
* @param mdp dictionary
*/
public void setMPD(PDSeedValueMDP mdp)
{
if (mdp != null)
{
dictionary.setItem(COSName.MDP, mdp.getCOSObject());
}
}
/**
* (Optional; PDF 1.6) A time stamp dictionary containing two entries. URL which
* is a ASCII string specifying the URL to a rfc3161 conform timestamp server and Ff
* to indicate if a timestamp is required or optional.
*
* @return the timestamp dictionary as PDSeedValueTimeStamp
*/
public PDSeedValueTimeStamp getTimeStamp()
{
COSDictionary dict = (COSDictionary)dictionary.getDictionaryObject(COSName.TIME_STAMP);
PDSeedValueTimeStamp timestamp = null;
if (dict != null)
{
timestamp = new PDSeedValueTimeStamp(dict);
}
return timestamp;
}
/**
* (Optional; PDF 1.6) A time stamp dictionary containing two entries. URL which
* is a ASCII string specifying the URL to a rfc3161 conform timestamp server and Ff
* to indicate if a timestamp is required or optional.
*
* @param timestamp dictionary
*/
public void setTimeStamp(PDSeedValueTimeStamp timestamp)
{
if (timestamp != null)
{
dictionary.setItem(COSName.TIME_STAMP, timestamp.getCOSObject());
}
}
/**
* (Optional, PDF 1.6) An array of text strings that specifying possible legal
* attestations.
*
* @return the reasons that should be used by the signature handler
*/
public List getLegalAttestation()
{
List retval = null;
COSArray fields = (COSArray)dictionary.getDictionaryObject(COSName.LEGAL_ATTESTATION);
if (fields != null)
{
List actuals = new ArrayList();
for ( int i = 0; i < fields.size(); i++ )
{
String element = fields.getString(i);
if (element != null)
{
actuals.add(element);
}
}
retval = new COSArrayList(actuals, fields);
}
return retval;
}
/**
* (Optional, PDF 1.6) An array of text strings that specifying possible legal
* attestations.
*
* @param legalAttestation is a list of possible text string that specifying possible
* legal attestations.
*/
public void setLegalAttestation(List legalAttestation)
{
dictionary.setItem(COSName.LEGAL_ATTESTATION, COSArrayList.converterToCOSArray(legalAttestation));
}
}