@ -48,12 +48,124 @@
* /
/ * *
* The below 2 methods are from pdfbox .
*
* private DERObject createDERForRecipient ( byte [ ] in , X509Certificate cert ) ;
* private KeyTransRecipientInfo computeRecipientInfo ( X509Certificate x509certificate , byte [ ] abyte0 ) ;
*
* 2006 - 11 - 22 Aiken Sam .
* The below 2 methods are from pdfbox .
* < p >
* private DERObject createDERForRecipient ( byte [ ] in , X509Certificate cert ) ;
* private KeyTransRecipientInfo computeRecipientInfo ( X509Certificate x509certificate , byte [ ] abyte0 ) ;
* < p >
* 2006 - 11 - 22 Aiken Sam .
* < p >
* Copyright ( c ) 2003 - 2006 , www . pdfbox . org
* All rights reserved .
* < p >
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* < p >
* 1 . Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
* 2 . Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
* 3 . Neither the name of pdfbox ; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission .
* < p >
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* < p >
* http : //www.pdfbox.org
* < p >
* Copyright ( c ) 2003 - 2006 , www . pdfbox . org
* All rights reserved .
* < p >
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* < p >
* 1 . Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
* 2 . Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
* 3 . Neither the name of pdfbox ; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission .
* < p >
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* < p >
* http : //www.pdfbox.org
* < p >
* Copyright ( c ) 2003 - 2006 , www . pdfbox . org
* All rights reserved .
* < p >
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* < p >
* 1 . Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
* 2 . Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
* 3 . Neither the name of pdfbox ; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission .
* < p >
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* < p >
* http : //www.pdfbox.org
* < p >
* Copyright ( c ) 2003 - 2006 , www . pdfbox . org
* All rights reserved .
* < p >
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
* < p >
* 1 . Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
* 2 . Redistributions in binary form must reproduce the above copyright notice ,
* this list of conditions and the following disclaimer in the documentation
* and / or other materials provided with the distribution .
* 3 . Neither the name of pdfbox ; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission .
* < p >
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES
* ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ;
* LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* < p >
* http : //www.pdfbox.org
* /
/ * *
@ -90,7 +202,9 @@
package com.fr.third.v2.lowagie.text.pdf ;
import com.fr.third.org.bouncycastle.asn1.ASN1Object ;
import com.fr.third.org.bouncycastle.asn1.ASN1OutputStream ;
import com.fr.third.org.bouncycastle.asn1.ASN1Set ;
import java.io.ByteArrayInputStream ;
import java.io.ByteArrayOutputStream ;
import java.io.IOException ;
@ -110,9 +224,8 @@ import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey ;
import com.fr.third.org.bouncycastle.asn1.ASN1InputStream ;
import com.fr.third.org.bouncycastle.asn1.DER ObjectIdentifier ;
import com.fr.third.org.bouncycastle.asn1.ASN1 ObjectIdentifier ;
import com.fr.third.org.bouncycastle.asn1.DEROctetString ;
import com.fr.third.org.bouncycastle.asn1.DEROutputStream ;
import com.fr.third.org.bouncycastle.asn1.DERSet ;
import com.fr.third.org.bouncycastle.asn1.cms.ContentInfo ;
import com.fr.third.org.bouncycastle.asn1.cms.EncryptedContentInfo ;
@ -129,11 +242,11 @@ import com.fr.third.org.bouncycastle.asn1.x509.TBSCertificateStructure;
* @author Aiken Sam ( aikensam @ieee.org )
* /
public class PdfPublicKeySecurityHandler {
static final int SEED_LENGTH = 20 ;
private ArrayList recipients = null ;
private byte [ ] seed = new byte [ SEED_LENGTH ] ;
public PdfPublicKeySecurityHandler ( ) {
@ -141,56 +254,57 @@ public class PdfPublicKeySecurityHandler {
try {
key = KeyGenerator . getInstance ( "AES" ) ;
key . init ( 192 , new SecureRandom ( ) ) ;
SecretKey sk = key . generateKey ( ) ;
SecretKey sk = key . generateKey ( ) ;
System . arraycopy ( sk . getEncoded ( ) , 0 , seed , 0 , SEED_LENGTH ) ; // create the 20 bytes seed
} catch ( NoSuchAlgorithmException e ) {
seed = SecureRandom . getSeed ( SEED_LENGTH ) ;
seed = SecureRandom . getSeed ( SEED_LENGTH ) ;
}
recipients = new ArrayList ( ) ;
}
/ *
/ *
* Routine for decode output of PdfContentByte . escapeString ( byte [ ] bytes ) .
* It should be moved to PdfContentByte .
* It should be moved to PdfContentByte .
* /
static public byte [ ] unescapedString ( byte [ ] bytes ) throws BadPdfFormatException {
ByteArrayOutputStream baos = new ByteArrayOutputStream ( ) ;
int index = 0 ;
if ( bytes [ 0 ] ! = '(' & & bytes [ bytes . length - 1 ] ! = ')' ) throw new BadPdfFormatException ( "Expect '(' and ')' at begin and end of the string." ) ;
if ( bytes [ 0 ] ! = '(' & & bytes [ bytes . length - 1 ] ! = ')' )
throw new BadPdfFormatException ( "Expect '(' and ')' at begin and end of the string." ) ;
while ( index < bytes . length ) {
if ( bytes [ index ] = = '\\' ) {
index + + ;
switch ( bytes [ index ] ) {
case 'b' :
baos . write ( '\b' ) ;
break ;
case 'f' :
baos . write ( '\f' ) ;
break ;
case 't' :
baos . write ( '\t' ) ;
break ;
case 'n' :
baos . write ( '\n' ) ;
break ;
case 'r' :
baos . write ( '\r' ) ;
break ;
case '(' :
case 'b' :
baos . write ( '\b' ) ;
break ;
case 'f' :
baos . write ( '\f' ) ;
break ;
case 't' :
baos . write ( '\t' ) ;
break ;
case 'n' :
baos . write ( '\n' ) ;
break ;
case 'r' :
baos . write ( '\r' ) ;
break ;
case '(' :
baos . write ( '(' ) ;
break ;
case ')' :
case ')' :
baos . write ( ')' ) ;
break ;
case '\\' :
baos . write ( '\\' ) ;
break ;
break ;
case '\\' :
baos . write ( '\\' ) ;
break ;
}
} else
baos . write ( bytes [ index ] ) ;
@ -198,92 +312,91 @@ public class PdfPublicKeySecurityHandler {
}
return baos . toByteArray ( ) ;
}
public void addRecipient ( PdfPublicKeyRecipient recipient ) {
recipients . add ( recipient ) ;
}
protected byte [ ] getSeed ( ) {
return ( byte [ ] ) seed . clone ( ) ;
return ( byte [ ] ) seed . clone ( ) ;
}
/ *
public PdfPublicKeyRecipient [ ] getRecipients ( ) {
recipients . toArray ( ) ;
return ( PdfPublicKeyRecipient [ ] ) recipients . toArray ( ) ;
} * /
public int getRecipientsSize ( ) {
return recipients . size ( ) ;
}
public byte [ ] getEncodedRecipient ( int index ) throws IOException , GeneralSecurityException {
//Certificate certificate = recipient.getX509();
PdfPublicKeyRecipient recipient = ( PdfPublicKeyRecipient ) recipients . get ( index ) ;
PdfPublicKeyRecipient recipient = ( PdfPublicKeyRecipient ) recipients . get ( index ) ;
byte [ ] cms = recipient . getCms ( ) ;
if ( cms ! = null ) return cms ;
Certificate certificate = recipient . getCertificate ( ) ;
int permission = recipient . getPermission ( ) ; //PdfWriter.AllowCopy | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders | PdfWriter.AllowAssembly;
Certificate certificate = recipient . getCertificate ( ) ;
int permission = recipient . getPermission ( ) ; //PdfWriter.AllowCopy | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders | PdfWriter.AllowAssembly;
int revision = 3 ;
permission | = revision = = 3 ? 0xfffff0c0 : 0xffffffc0 ;
permission | = revision = = 3 ? 0xfffff0c0 : 0xffffffc0 ;
permission & = 0xfffffffc ;
permission + = 1 ;
byte [ ] pkcs7input = new byte [ 24 ] ;
byte one = ( byte ) ( permission ) ;
byte two = ( byte ) ( permission > > 8 ) ;
byte three = ( byte ) ( permission > > 16 ) ;
byte four = ( byte ) ( permission > > 24 ) ;
byte one = ( byte ) ( permission ) ;
byte two = ( byte ) ( permission > > 8 ) ;
byte three = ( byte ) ( permission > > 16 ) ;
byte four = ( byte ) ( permission > > 24 ) ;
System . arraycopy ( seed , 0 , pkcs7input , 0 , 20 ) ; // put this seed in the pkcs7 input
pkcs7input [ 20 ] = four ;
pkcs7input [ 21 ] = three ;
pkcs7input [ 21 ] = three ;
pkcs7input [ 22 ] = two ;
pkcs7input [ 23 ] = one ;
ASN1Object obj = createDERForRecipient ( pkcs7input , ( X509Certificate ) certificate ) ;
ASN1Object obj = createDERForRecipient ( pkcs7input , ( X509Certificate ) certificate ) ;
ByteArrayOutputStream baos = new ByteArrayOutputStream ( ) ;
DEROutputStream k = new DEROutputStream ( baos ) ;
k . writeObject ( obj ) ;
ASN1OutputStream k = ASN1OutputStream . create ( baos ) ;
k . writeObject ( obj ) ;
cms = baos . toByteArray ( ) ;
recipient . setCms ( cms ) ;
return cms ;
return cms ;
}
public PdfArray getEncodedRecipients ( ) throws IOException ,
GeneralSecurityException {
public PdfArray getEncodedRecipients ( ) throws IOException ,
GeneralSecurityException {
PdfArray EncodedRecipients = new PdfArray ( ) ;
byte [ ] cms = null ;
for ( int i = 0 ; i < recipients . size ( ) ; i + + )
try {
cms = getEncodedRecipient ( i ) ;
EncodedRecipients . add ( new PdfLiteral ( PdfContentByte . escapeString ( cms ) ) ) ;
} catch ( GeneralSecurityException e ) {
EncodedRecipients = null ;
} catch ( IOException e ) {
EncodedRecipients = null ;
}
for ( int i = 0 ; i < recipients . size ( ) ; i + + )
try {
cms = getEncodedRecipient ( i ) ;
EncodedRecipients . add ( new PdfLiteral ( PdfContentByte . escapeString ( cms ) ) ) ;
} catch ( GeneralSecurityException e ) {
EncodedRecipients = null ;
} catch ( IOException e ) {
EncodedRecipients = null ;
}
return EncodedRecipients ;
}
private ASN1Object createDERForRecipient ( byte [ ] in , X509Certificate cert )
throws IOException ,
GeneralSecurityException
{
throws IOException ,
GeneralSecurityException {
String s = "1.2.840.113549.3.2" ;
AlgorithmParameterGenerator algorithmparametergenerator = AlgorithmParameterGenerator . getInstance ( s ) ;
AlgorithmParameters algorithmparameters = algorithmparametergenerator . generateParameters ( ) ;
ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream ( algorithmparameters . getEncoded ( "ASN.1" ) ) ;
@ -298,31 +411,30 @@ public class PdfPublicKeySecurityHandler {
DEROctetString deroctetstring = new DEROctetString ( abyte1 ) ;
KeyTransRecipientInfo keytransrecipientinfo = computeRecipientInfo ( cert , secretkey . getEncoded ( ) ) ;
DERSet derset = new DERSet ( new RecipientInfo ( keytransrecipientinfo ) ) ;
AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier ( new DER ObjectIdentifier( s ) , derobject ) ;
EncryptedContentInfo encryptedcontentinfo =
new EncryptedContentInfo ( PKCSObjectIdentifiers . data , algorithmidentifier , deroctetstring ) ;
EnvelopedData env = new EnvelopedData ( null , derset , encryptedcontentinfo , ( ASN1Set ) null ) ;
ContentInfo contentinfo =
new ContentInfo ( PKCSObjectIdentifiers . envelopedData , env ) ;
AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier ( new ASN1 ObjectIdentifier( s ) , derobject ) ;
EncryptedContentInfo encryptedcontentinfo =
new EncryptedContentInfo ( PKCSObjectIdentifiers . data , algorithmidentifier , deroctetstring ) ;
EnvelopedData env = new EnvelopedData ( null , derset , encryptedcontentinfo , ( ASN1Set ) null ) ;
ContentInfo contentinfo =
new ContentInfo ( PKCSObjectIdentifiers . envelopedData , env ) ;
return contentinfo . getContentType ( ) ;
}
private KeyTransRecipientInfo computeRecipientInfo ( X509Certificate x509certificate , byte [ ] abyte0 )
throws GeneralSecurityException , IOException
{
ASN1InputStream asn1inputstream =
new ASN1InputStream ( new ByteArrayInputStream ( x509certificate . getTBSCertificate ( ) ) ) ;
TBSCertificateStructure tbscertificatestructure =
TBSCertificateStructure . getInstance ( asn1inputstream . readObject ( ) ) ;
throws GeneralSecurityException , IOException {
ASN1InputStream asn1inputstream =
new ASN1InputStream ( new ByteArrayInputStream ( x509certificate . getTBSCertificate ( ) ) ) ;
TBSCertificateStructure tbscertificatestructure =
TBSCertificateStructure . getInstance ( asn1inputstream . readObject ( ) ) ;
AlgorithmIdentifier algorithmidentifier = tbscertificatestructure . getSubjectPublicKeyInfo ( ) . getAlgorithmId ( ) ;
IssuerAndSerialNumber issuerandserialnumber =
new IssuerAndSerialNumber (
tbscertificatestructure . getIssuer ( ) ,
tbscertificatestructure . getSerialNumber ( ) . getValue ( ) ) ;
IssuerAndSerialNumber issuerandserialnumber =
new IssuerAndSerialNumber (
tbscertificatestructure . getIssuer ( ) ,
tbscertificatestructure . getSerialNumber ( ) . getValue ( ) ) ;
Cipher cipher = Cipher . getInstance ( algorithmidentifier . getAlgorithm ( ) . getId ( ) ) ;
cipher . init ( 1 , x509certificate ) ;
DEROctetString deroctetstring = new DEROctetString ( cipher . doFinal ( abyte0 ) ) ;
RecipientIdentifier recipId = new RecipientIdentifier ( issuerandserialnumber ) ;
return new KeyTransRecipientInfo ( recipId , algorithmidentifier , deroctetstring ) ;
return new KeyTransRecipientInfo ( recipId , algorithmidentifier , deroctetstring ) ;
}
}