Class PdfPKCS7


  • public class PdfPKCS7
    extends java.lang.Object
    This class does all the processing related to signing and verifying a PKCS#7 / CMS signature.
    • Constructor Summary

      Constructors 
      Constructor Description
      PdfPKCS7​(byte[] contentsKey, byte[] certsKey, java.lang.String provider)
      Use this constructor if you want to verify a signature using the sub-filter adbe.x509.rsa_sha1.
      PdfPKCS7​(byte[] contentsKey, PdfName filterSubtype, java.lang.String provider)
      Use this constructor if you want to verify a signature.
      PdfPKCS7​(java.security.PrivateKey privKey, java.security.cert.Certificate[] certChain, java.lang.String hashAlgorithm, java.lang.String provider, boolean hasEncapContent)
      Assembles all the elements needed to create a signature, except for the data.
      PdfPKCS7​(java.security.PrivateKey privKey, java.security.cert.Certificate[] certChain, java.lang.String hashAlgorithm, java.lang.String provider, IExternalDigest interfaceDigest, boolean hasEncapContent)
      Assembles all the elements needed to create a signature, except for the data.
    • Field Detail

      • provider

        private final java.lang.String provider
        The encryption provider, e.g. "BC" if you use BouncyCastle.
      • signName

        private java.lang.String signName
        Holds value of property signName.
      • reason

        private java.lang.String reason
        Holds value of property reason.
      • location

        private java.lang.String location
        Holds value of property location.
      • signDate

        private java.util.Calendar signDate
        Holds value of property signDate.
      • signedDataRevocationInfo

        private final java.util.Collection<IASN1Sequence> signedDataRevocationInfo
        Collection to store revocation info other than OCSP and CRL responses, e.g. SCVP Request and Response.
      • version

        private int version
        Version of the PKCS#7 object
      • signerversion

        private int signerversion
        Version of the PKCS#7 "SignerInfo" object.
      • digestAlgorithmOid

        private final java.lang.String digestAlgorithmOid
        The ID of the digest algorithm, e.g. "2.16.840.1.101.3.4.2.1".
      • messageDigest

        private java.security.MessageDigest messageDigest
        The object that will create the digest
      • digestalgos

        private java.util.Set<java.lang.String> digestalgos
        The digest algorithms
      • digestAttr

        private byte[] digestAttr
        The digest attributes
      • filterSubtype

        private PdfName filterSubtype
      • signatureMechanismOid

        private java.lang.String signatureMechanismOid
        The signature algorithm.
      • signatureMechanismParameters

        private IASN1Encodable signatureMechanismParameters
      • externalSignatureValue

        private byte[] externalSignatureValue
        The signature value or signed digest, if created outside this class
      • externalEncapMessageContent

        private byte[] externalEncapMessageContent
        Externally specified encapsulated message content.
      • sig

        private java.security.Signature sig
        Class from the Java SDK that provides the functionality of a digital signature algorithm.
      • signatureValue

        private byte[] signatureValue
        The raw signature value as calculated by this class (or extracted from an existing PDF)
      • encapMessageContent

        private byte[] encapMessageContent
        The content to which the signature applies, if encapsulated in the PKCS #7 payload.
      • sigAttr

        private byte[] sigAttr
        Signature attributes
      • sigAttrDer

        private byte[] sigAttrDer
        Signature attributes (maybe not necessary, but we use it as fallback)
      • encContDigest

        private java.security.MessageDigest encContDigest
        encrypted digest
      • verified

        private boolean verified
        Indicates if a signature has already been verified
      • verifyResult

        private boolean verifyResult
        The result of the verification
      • certs

        private final java.util.Collection<java.security.cert.Certificate> certs
        All the X.509 certificates in no particular order.
      • timestampCerts

        private java.util.Collection<java.security.cert.Certificate> timestampCerts
      • signCerts

        java.util.Collection<java.security.cert.Certificate> signCerts
        All the X.509 certificates used for the main signature.
      • signCert

        private java.security.cert.X509Certificate signCert
        The X.509 certificate that is used to sign the digest.
      • crls

        private java.util.Collection<java.security.cert.CRL> crls
      • signedDataCrls

        private final java.util.Collection<java.security.cert.CRL> signedDataCrls
      • isTsp

        private boolean isTsp
        True if there's a PAdES LTV time stamp.
      • isCades

        private boolean isCades
        True if it's a CAdES signature type.
      • timestampSignatureContainer

        private PdfPKCS7 timestampSignatureContainer
        Inner timestamp signature container.
      • timeStampTokenInfo

        private ITSTInfo timeStampTokenInfo
        BouncyCastle TSTInfo.
    • Constructor Detail

      • PdfPKCS7

        public PdfPKCS7​(java.security.PrivateKey privKey,
                        java.security.cert.Certificate[] certChain,
                        java.lang.String hashAlgorithm,
                        java.lang.String provider,
                        IExternalDigest interfaceDigest,
                        boolean hasEncapContent)
                 throws java.security.InvalidKeyException,
                        java.security.NoSuchProviderException,
                        java.security.NoSuchAlgorithmException
        Assembles all the elements needed to create a signature, except for the data.
        Parameters:
        privKey - the private key
        certChain - the certificate chain
        interfaceDigest - the interface digest
        hashAlgorithm - the hash algorithm
        provider - the provider or null for the default provider
        hasEncapContent - true if the sub-filter is adbe.pkcs7.sha1
        Throws:
        java.security.InvalidKeyException - on error
        java.security.NoSuchProviderException - on error
        java.security.NoSuchAlgorithmException - on error
      • PdfPKCS7

        public PdfPKCS7​(java.security.PrivateKey privKey,
                        java.security.cert.Certificate[] certChain,
                        java.lang.String hashAlgorithm,
                        java.lang.String provider,
                        boolean hasEncapContent)
                 throws java.security.InvalidKeyException,
                        java.security.NoSuchProviderException,
                        java.security.NoSuchAlgorithmException
        Assembles all the elements needed to create a signature, except for the data.
        Parameters:
        privKey - the private key
        certChain - the certificate chain
        hashAlgorithm - the hash algorithm
        provider - the provider or null for the default provider
        hasEncapContent - true if the sub-filter is adbe.pkcs7.sha1
        Throws:
        java.security.InvalidKeyException - on error
        java.security.NoSuchProviderException - on error
        java.security.NoSuchAlgorithmException - on error
      • PdfPKCS7

        public PdfPKCS7​(byte[] contentsKey,
                        byte[] certsKey,
                        java.lang.String provider)
        Use this constructor if you want to verify a signature using the sub-filter adbe.x509.rsa_sha1.
        Parameters:
        contentsKey - the /Contents key
        certsKey - the /Cert key
        provider - the provider or null for the default provider
      • PdfPKCS7

        public PdfPKCS7​(byte[] contentsKey,
                        PdfName filterSubtype,
                        java.lang.String provider)
        Use this constructor if you want to verify a signature.
        Parameters:
        contentsKey - the /Contents key
        filterSubtype - the filtersubtype
        provider - the provider or null for the default provider
    • Method Detail

      • getUnsignedAttributes

        public IASN1EncodableVector getUnsignedAttributes()
        Get unsigned attributes associated with this PKCS7 signature container.
        Returns:
        unsigned attributes as IASN1EncodableVector
      • setSignaturePolicy

        public void setSignaturePolicy​(SignaturePolicyInfo signaturePolicy)
        Set signature policy identifier to be used during signature creation.
        Parameters:
        signaturePolicy - SignaturePolicyInfo to be used during signature creation
      • setSignaturePolicy

        public void setSignaturePolicy​(ISignaturePolicyIdentifier signaturePolicy)
        Set signature policy identifier to be used during signature creation.
        Parameters:
        signaturePolicy - ISignaturePolicyIdentifier to be used during signature creation
      • getSignName

        public java.lang.String getSignName()
        Getter for property sigName.
        Returns:
        Value of property sigName.
      • setSignName

        public void setSignName​(java.lang.String signName)
        Setter for property sigName.
        Parameters:
        signName - New value of property sigName.
      • getReason

        public java.lang.String getReason()
        Getter for property reason.
        Returns:
        Value of property reason.
      • setReason

        public void setReason​(java.lang.String reason)
        Setter for property reason.
        Parameters:
        reason - New value of property reason.
      • getLocation

        public java.lang.String getLocation()
        Getter for property location.
        Returns:
        Value of property location.
      • setLocation

        public void setLocation​(java.lang.String location)
        Setter for property location.
        Parameters:
        location - New value of property location.
      • getSignDate

        public java.util.Calendar getSignDate()
        Getter for property signDate.
        Returns:
        Value of property signDate.
      • setSignDate

        public void setSignDate​(java.util.Calendar signDate)
        Setter for property signDate.
        Parameters:
        signDate - New value of property signDate.
      • getVersion

        public int getVersion()
        Get the version of the PKCS#7 object.
        Returns:
        the version of the PKCS#7 object.
      • getSigningInfoVersion

        public int getSigningInfoVersion()
        Get the version of the PKCS#7 "SignerInfo" object.
        Returns:
        the version of the PKCS#7 "SignerInfo" object.
      • getDigestAlgorithmOid

        public java.lang.String getDigestAlgorithmOid()
        Getter for the ID of the digest algorithm, e.g. "2.16.840.1.101.3.4.2.1". See ISO-32000-1, section 12.8.3.3 PKCS#7 Signatures as used in ISO 32000
        Returns:
        the ID of the digest algorithm
      • getDigestAlgorithmName

        public java.lang.String getDigestAlgorithmName()
        Returns the name of the digest algorithm, e.g. "SHA256".
        Returns:
        the digest algorithm name, e.g. "SHA256"
      • getSignatureMechanismOid

        public java.lang.String getSignatureMechanismOid()
        Getter for the signature algorithm OID. See ISO-32000-1, section 12.8.3.3 PKCS#7 Signatures as used in ISO 32000
        Returns:
        the signature algorithm OID
      • getSignatureMechanismName

        public java.lang.String getSignatureMechanismName()
        Get the signature mechanism identifier, including both the digest function and the signature algorithm, e.g. "SHA1withRSA". See ISO-32000-1, section 12.8.3.3 PKCS#7 Signatures as used in ISO 32000
        Returns:
        the algorithm used to calculate the signature
      • getSignatureAlgorithmName

        public java.lang.String getSignatureAlgorithmName()
        Returns the name of the signature algorithm only (disregarding the digest function, if any).
        Returns:
        the name of an encryption algorithm
      • setExternalSignatureValue

        public void setExternalSignatureValue​(byte[] signatureValue,
                                              byte[] signedMessageContent,
                                              java.lang.String signatureAlgorithm)
        Sets the signature to an externally calculated value.
        Parameters:
        signatureValue - the signature value
        signedMessageContent - the extra data that goes into the data tag in PKCS#7
        signatureAlgorithm - the signature algorithm. It must be null if the signatureValue is also null. If the signatureValue is not null, possible values include "RSA", "DSA", "ECDSA", "Ed25519" and "Ed448".
      • setExternalSignatureValue

        public void setExternalSignatureValue​(byte[] signatureValue,
                                              byte[] signedMessageContent,
                                              java.lang.String signatureAlgorithm,
                                              ISignatureMechanismParams signatureMechanismParams)
        Sets the signature to an externally calculated value.
        Parameters:
        signatureValue - the signature value
        signedMessageContent - the extra data that goes into the data tag in PKCS#7
        signatureAlgorithm - the signature algorithm. It must be null if the signatureValue is also null. If the signatureValue is not null, possible values include "RSA", "RSASSA-PSS", "DSA", "ECDSA", "Ed25519" and "Ed448".
        signatureMechanismParams - parameters for the signature mechanism, if required
      • initSignature

        private java.security.Signature initSignature​(java.security.PrivateKey key)
                                               throws java.security.NoSuchAlgorithmException,
                                                      java.security.NoSuchProviderException,
                                                      java.security.InvalidKeyException
        Throws:
        java.security.NoSuchAlgorithmException
        java.security.NoSuchProviderException
        java.security.InvalidKeyException
      • initSignature

        private java.security.Signature initSignature​(java.security.PublicKey key)
                                               throws java.security.NoSuchAlgorithmException,
                                                      java.security.NoSuchProviderException,
                                                      java.security.InvalidKeyException
        Throws:
        java.security.NoSuchAlgorithmException
        java.security.NoSuchProviderException
        java.security.InvalidKeyException
      • configureSignatureMechanismParameters

        private void configureSignatureMechanismParameters​(java.security.Signature signature)
      • update

        public void update​(byte[] buf,
                           int off,
                           int len)
                    throws java.security.SignatureException
        Update the digest with the specified bytes. This method is used both for signing and verifying
        Parameters:
        buf - the data buffer
        off - the offset in the data buffer
        len - the data length
        Throws:
        java.security.SignatureException - on error
      • getEncodedPKCS1

        public byte[] getEncodedPKCS1()
        Gets the bytes for the PKCS#1 object.
        Returns:
        a byte array
      • getEncodedPKCS7

        public byte[] getEncodedPKCS7()
        Gets the bytes for the PKCS7SignedData object.
        Returns:
        the bytes for the PKCS7SignedData object
      • getEncodedPKCS7

        public byte[] getEncodedPKCS7​(byte[] secondDigest)
        Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes in the signerInfo can also be set. If either of the parameters is null, none will be used.
        Parameters:
        secondDigest - the digest in the authenticatedAttributes
        Returns:
        the bytes for the PKCS7SignedData object
      • getEncodedPKCS7

        public byte[] getEncodedPKCS7​(byte[] secondDigest,
                                      PdfSigner.CryptoStandard sigtype,
                                      ITSAClient tsaClient,
                                      java.util.Collection<byte[]> ocsp,
                                      java.util.Collection<byte[]> crlBytes)
        Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes in the signerInfo can also be set, and/or a time-stamp-authority client may be provided.
        Parameters:
        secondDigest - the digest in the authenticatedAttributes
        sigtype - specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: either basic CMS or CAdES
        tsaClient - TSAClient - null or an optional time stamp authority client
        ocsp - collection of DER-encoded BasicOCSPResponses for the certificate in the signature certificates chain, or null if OCSP revocation data is not to be added.
        crlBytes - collection of DER-encoded CRL for certificates from the signature certificates chain, or null if CRL revocation data is not to be added.
        Returns:
        byte[] the bytes for the PKCS7SignedData object
        See Also:
        RFC 6960 § 4.2.1
      • addTimestampTokenToUnsignedAttributes

        private void addTimestampTokenToUnsignedAttributes​(byte[] timeStampToken)
                                                    throws java.io.IOException
        Added by Aiken Sam, 2006-11-15, modifed by Martin Brunecky 07/12/2007 to start with the timeStampToken (signedData 1.2.840.113549.1.7.2). Token is the TSA response without response status, which is usually handled by the (vendor supplied) TSA request/response interface).
        Parameters:
        timeStampToken - byte[] - time stamp token, DER encoded signedData
        Throws:
        java.io.IOException - if an I/O error occurs.
      • getAuthenticatedAttributeBytes

        public byte[] getAuthenticatedAttributeBytes​(byte[] secondDigest,
                                                     PdfSigner.CryptoStandard sigtype,
                                                     java.util.Collection<byte[]> ocsp,
                                                     java.util.Collection<byte[]> crlBytes)
        When using authenticatedAttributes the authentication process is different. The document digest is generated and put inside the attribute. The signing is done over the DER encoded authenticatedAttributes. This method provides that encoding and the parameters must be exactly the same as in getEncodedPKCS7(byte[]).

        Note: do not pass in the full DER-encoded OCSPResponse object obtained from the responder, only the DER-encoded IBasicOCSPResponse value contained in the response data.

        A simple example:

         Calendar cal = Calendar.getInstance();
         PdfPKCS7 pk7 = new PdfPKCS7(key, chain, null, "SHA1", null, false);
         MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
         byte[] buf = new byte[8192];
         int n;
         InputStream inp = sap.getRangeStream();
         while ((n = inp.read(buf)) > 0) {
            messageDigest.update(buf, 0, n);
         }
         byte[] hash = messageDigest.digest();
         byte[] sh = pk7.getAuthenticatedAttributeBytes(hash, cal);
         pk7.update(sh, 0, sh.length);
         byte[] sg = pk7.getEncodedPKCS7(hash, cal);
         
        Parameters:
        secondDigest - the content digest
        sigtype - specifies the PKCS7 standard flavor to which created PKCS7SignedData object will adhere: either basic CMS or CAdES
        ocsp - collection of DER-encoded BasicOCSPResponses for the certificate in the signature certificates chain, or null if OCSP revocation data is not to be added.
        crlBytes - collection of DER-encoded CRL for certificates from the signature certificates chain, or null if CRL revocation data is not to be added.
        Returns:
        the byte array representation of the authenticatedAttributes ready to be signed
        See Also:
        RFC 6960 § 4.2.1
      • getAuthenticatedAttributeSet

        private IDERSet getAuthenticatedAttributeSet​(byte[] secondDigest,
                                                     java.util.Collection<byte[]> ocsp,
                                                     java.util.Collection<byte[]> crlBytes,
                                                     PdfSigner.CryptoStandard sigtype)
        This method provides that encoding and the parameters must be exactly the same as in getEncodedPKCS7(byte[]).
        Parameters:
        secondDigest - the content digest
        Returns:
        the byte array representation of the authenticatedAttributes ready to be signed
      • verifySignatureIntegrityAndAuthenticity

        public boolean verifySignatureIntegrityAndAuthenticity()
                                                        throws java.security.GeneralSecurityException
        Verifies that signature integrity is intact (or in other words that signed data wasn't modified) by checking that embedded data digest corresponds to the calculated one. Also ensures that signature is genuine and is created by the owner of private key that corresponds to the declared public certificate.

        Even though signature can be authentic and signed data integrity can be intact, one shall also always check that signed data is not only a part of PDF contents but is actually a complete PDF file. In order to check that given signature covers the current PdfDocument please use SignatureUtil.signatureCoversWholeDocument(String) method.

        Returns:
        true if the signature checks out, false otherwise
        Throws:
        java.security.GeneralSecurityException - if this signature object is not initialized properly, the passed-in signature is improperly encoded or of the wrong type, if this signature algorithm is unable to process the input data provided, if the public key is invalid or if security provider or signature algorithm are not recognized, etc.
      • verifySigAttributes

        private boolean verifySigAttributes​(byte[] attr)
                                     throws java.security.GeneralSecurityException
        Throws:
        java.security.GeneralSecurityException
      • verifyTimestampImprint

        public boolean verifyTimestampImprint()
                                       throws java.security.GeneralSecurityException
        Checks if the timestamp refers to this document.
        Returns:
        true if it checks false otherwise
        Throws:
        java.security.GeneralSecurityException - on error
      • getCertificates

        public java.security.cert.Certificate[] getCertificates()
        Get all the X.509 certificates associated with this PKCS#7 object in no particular order. Other certificates, from OCSP for example, will also be included.
        Returns:
        the X.509 certificates associated with this PKCS#7 object
      • getTimestampCertificates

        public java.security.cert.Certificate[] getTimestampCertificates()
        Get all X.509 certificates associated with this PKCS#7 object timestamp in no particular order.
        Returns:
        Certificate array
      • getSignCertificateChain

        public java.security.cert.Certificate[] getSignCertificateChain()
        Get the X.509 sign certificate chain associated with this PKCS#7 object. Only the certificates used for the main signature will be returned, with the signing certificate first.
        Returns:
        the X.509 certificates associated with this PKCS#7 object
      • getSigningCertificate

        public java.security.cert.X509Certificate getSigningCertificate()
        Get the X.509 certificate actually used to sign the digest.
        Returns:
        the X.509 certificate actually used to sign the digest
      • signCertificateChain

        private void signCertificateChain()
        Helper method that creates the collection of certificates used for the main signature based on the complete list of certificates and the sign certificate.
      • getCRLs

        public java.util.Collection<java.security.cert.CRL> getCRLs()
        Get the X.509 certificate revocation lists associated with this PKCS#7 object (stored in Signer Info).
        Returns:
        the X.509 certificate revocation lists associated with this PKCS#7 object.
      • getSignedDataCRLs

        public java.util.Collection<java.security.cert.CRL> getSignedDataCRLs()
        Get the X.509 certificate revocation lists associated with this PKCS#7 Signed Data object.
        Returns:
        the X.509 certificate revocation lists associated with this PKCS#7 Signed Data object.
      • findCRL

        void findCRL​(IASN1Sequence seq)
        Helper method that tries to construct the CRLs.
      • getSignedDataOcsps

        public java.util.Collection<IBasicOCSPResponse> getSignedDataOcsps()
        Gets the OCSP basic response collection retrieved from SignedData structure.
        Returns:
        the OCSP basic response collection.
      • getOcsp

        public IBasicOCSPResponse getOcsp()
        Gets the OCSP basic response from the SignerInfo if there is one.
        Returns:
        the OCSP basic response or null.
      • isRevocationValid

        public boolean isRevocationValid()
        Checks if OCSP revocation refers to the document signing certificate.
        Returns:
        true if it checks, false otherwise
      • findOcsp

        private void findOcsp​(IASN1Sequence seq)
                       throws java.io.IOException
        Helper method that creates the IBasicOCSPResp object.
        Parameters:
        seq - IASN1Sequence wrapper
        Throws:
        java.io.IOException - if some I/O error occurred.
      • isTsp

        public boolean isTsp()
        Check if it's a PAdES-LTV time stamp.
        Returns:
        true if it's a PAdES-LTV time stamp, false otherwise
      • getTimestampSignatureContainer

        public PdfPKCS7 getTimestampSignatureContainer()
        Retrieves inner timestamp signature container if there is one.
        Returns:
        timestamp signature container or null.
      • getTimeStampTokenInfo

        public ITSTInfo getTimeStampTokenInfo()
        Gets the timestamp token info if there is one.
        Returns:
        the timestamp token info or null
      • getTimeStampDate

        public java.util.Calendar getTimeStampDate()
        Gets the timestamp date.

        In case the signed document doesn't contain timestamp, TimestampConstants.UNDEFINED_TIMESTAMP_DATE will be returned.

        Returns:
        the timestamp date
      • getFilterSubtype

        public PdfName getFilterSubtype()
        Getter for the filter subtype.
        Returns:
        the filter subtype