PdfPublicKeySecurityHandler.java

1
/*
2
 * $Id: PdfPublicKeySecurityHandler.java 4055 2009-08-30 23:47:33Z psoares33 $
3
 * $Name$
4
 *
5
 * Copyright 2006 Paulo Soares
6
 *
7
 * The contents of this file are subject to the Mozilla Public License Version 1.1
8
 * (the "License"); you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
10
 *
11
 * Software distributed under the License is distributed on an "AS IS" basis,
12
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
 * for the specific language governing rights and limitations under the License.
14
 *
15
 * The Original Code is 'iText, a free JAVA-PDF library'.
16
 *
17
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
18
 * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie.
19
 * All Rights Reserved.
20
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
21
 * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved.
22
 *
23
 * Contributor(s): all the names of the contributors are added in the source code
24
 * where applicable.
25
 *
26
 * Alternatively, the contents of this file may be used under the terms of the
27
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
28
 * provisions of LGPL are applicable instead of those above.  If you wish to
29
 * allow use of your version of this file only under the terms of the LGPL
30
 * License and not to allow others to use your version of this file under
31
 * the MPL, indicate your decision by deleting the provisions above and
32
 * replace them with the notice and other provisions required by the LGPL.
33
 * If you do not delete the provisions above, a recipient may use your version
34
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
35
 *
36
 * This library is free software; you can redistribute it and/or modify it
37
 * under the terms of the MPL as stated above or under the terms of the GNU
38
 * Library General Public License as published by the Free Software Foundation;
39
 * either version 2 of the License, or any later version.
40
 *
41
 * This library is distributed in the hope that it will be useful, but WITHOUT
42
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
43
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
44
 * details.
45
 *
46
 * If you didn't download this code from the following link, you should check if
47
 * you aren't using an obsolete version:
48
 * http://www.lowagie.com/iText/
49
 */
50
51
/*
52
      The below 2 methods are from pdfbox.
53
54
      private DERObject createDERForRecipient(byte[] in, X509Certificate cert) ;
55
      private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0);
56
57
      2006-11-22 Aiken Sam.
58
 */
59
60
/*
61
  Copyright (c) 2003-2006, www.pdfbox.org
62
  All rights reserved.
63
64
  Redistribution and use in source and binary forms, with or without
65
  modification, are permitted provided that the following conditions are met:
66
67
  1. Redistributions of source code must retain the above copyright notice,
68
     this list of conditions and the following disclaimer.
69
  2. Redistributions in binary form must reproduce the above copyright notice,
70
     this list of conditions and the following disclaimer in the documentation
71
     and/or other materials provided with the distribution.
72
  3. Neither the name of pdfbox; nor the names of its
73
     contributors may be used to endorse or promote products derived from this
74
     software without specific prior written permission.
75
76
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
77
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
78
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79
  DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
80
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
81
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
82
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
83
  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
84
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
85
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
86
87
  http://www.pdfbox.org
88
89
 */
90
91
package com.lowagie.text.pdf;
92
93
import java.io.ByteArrayInputStream;
94
import java.io.ByteArrayOutputStream;
95
import java.io.IOException;
96
import java.security.AlgorithmParameterGenerator;
97
import java.security.AlgorithmParameters;
98
import java.security.GeneralSecurityException;
99
import java.security.NoSuchAlgorithmException;
100
import java.security.SecureRandom;
101
import java.security.cert.Certificate;
102
import java.security.cert.X509Certificate;
103
import java.util.ArrayList;
104
105
import javax.crypto.Cipher;
106
import javax.crypto.KeyGenerator;
107
import javax.crypto.SecretKey;
108
109
import org.bouncycastle.asn1.ASN1InputStream;
110
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
111
import org.bouncycastle.asn1.ASN1Primitive;
112
import org.bouncycastle.asn1.ASN1Set;
113
import org.bouncycastle.asn1.DEROctetString;
114
import org.bouncycastle.asn1.DEROutputStream;
115
import org.bouncycastle.asn1.DERSet;
116
import org.bouncycastle.asn1.cms.ContentInfo;
117
import org.bouncycastle.asn1.cms.EncryptedContentInfo;
118
import org.bouncycastle.asn1.cms.EnvelopedData;
119
import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
120
import org.bouncycastle.asn1.cms.KeyTransRecipientInfo;
121
import org.bouncycastle.asn1.cms.RecipientIdentifier;
122
import org.bouncycastle.asn1.cms.RecipientInfo;
123
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
124
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
125
import org.bouncycastle.asn1.x509.TBSCertificate;
126
127
/**
128
 * @author Aiken Sam (aikensam@ieee.org)
129
 */
130
public class PdfPublicKeySecurityHandler {
131
132
  static final int SEED_LENGTH = 20;
133
134
  private ArrayList recipients = null;
135
136
  private byte[] seed = new byte[SEED_LENGTH];
137
138
  public PdfPublicKeySecurityHandler() {
139
    KeyGenerator key;
140
    try {
141
      key = KeyGenerator.getInstance("AES");
142 1 1. : removed call to javax/crypto/KeyGenerator::init → NO_COVERAGE
      key.init(192, new SecureRandom());
143
      SecretKey sk = key.generateKey();
144 1 1. : removed call to java/lang/System::arraycopy → NO_COVERAGE
      System.arraycopy(sk.getEncoded(), 0, seed, 0, SEED_LENGTH); // create the
145
                                                                  // 20 bytes
146
                                                                  // seed
147
    } catch (NoSuchAlgorithmException e) {
148
      seed = SecureRandom.getSeed(SEED_LENGTH);
149
    }
150
151
    recipients = new ArrayList();
152
  }
153
154
  public void addRecipient(PdfPublicKeyRecipient recipient) {
155
    recipients.add(recipient);
156
  }
157
158
  protected byte[] getSeed() {
159 1 1. getSeed : mutated return of Object value for com/lowagie/text/pdf/PdfPublicKeySecurityHandler::getSeed to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
    return seed.clone();
160
  }
161
162
  /*
163
   * public PdfPublicKeyRecipient[] getRecipients() { recipients.toArray();
164
   * return (PdfPublicKeyRecipient[])recipients.toArray(); }
165
   */
166
167
  public int getRecipientsSize() {
168
    return recipients.size();
169
  }
170
171
  public byte[] getEncodedRecipient(int index) throws IOException,
172
      GeneralSecurityException {
173
    // Certificate certificate = recipient.getX509();
174
    PdfPublicKeyRecipient recipient = (PdfPublicKeyRecipient) recipients
175
        .get(index);
176
    byte[] cms = recipient.getCms();
177
178 1 1. getEncodedRecipient : negated conditional → NO_COVERAGE
    if (cms != null)
179 1 1. getEncodedRecipient : mutated return of Object value for com/lowagie/text/pdf/PdfPublicKeySecurityHandler::getEncodedRecipient to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
      return cms;
180
181
    Certificate certificate = recipient.getCertificate();
182
    int permission = recipient.getPermission();// PdfWriter.AllowCopy |
183
                                               // PdfWriter.AllowPrinting |
184
                                               // PdfWriter.AllowScreenReaders |
185
                                               // PdfWriter.AllowAssembly;
186
    int revision = 3;
187
188 2 1. getEncodedRecipient : Replaced bitwise OR with AND → NO_COVERAGE
2. getEncodedRecipient : negated conditional → NO_COVERAGE
    permission |= revision == 3 ? 0xfffff0c0 : 0xffffffc0;
189 1 1. getEncodedRecipient : Replaced bitwise AND with OR → NO_COVERAGE
    permission &= 0xfffffffc;
190 1 1. getEncodedRecipient : Changed increment from 1 to -1 → NO_COVERAGE
    permission += 1;
191
192
    byte[] pkcs7input = new byte[24];
193
194
    byte one = (byte) (permission);
195 1 1. getEncodedRecipient : Replaced Shift Right with Shift Left → NO_COVERAGE
    byte two = (byte) (permission >> 8);
196 1 1. getEncodedRecipient : Replaced Shift Right with Shift Left → NO_COVERAGE
    byte three = (byte) (permission >> 16);
197 1 1. getEncodedRecipient : Replaced Shift Right with Shift Left → NO_COVERAGE
    byte four = (byte) (permission >> 24);
198
199 1 1. getEncodedRecipient : removed call to java/lang/System::arraycopy → NO_COVERAGE
    System.arraycopy(seed, 0, pkcs7input, 0, 20); // put this seed in the pkcs7
200
                                                  // input
201
202
    pkcs7input[20] = four;
203
    pkcs7input[21] = three;
204
    pkcs7input[22] = two;
205
    pkcs7input[23] = one;
206
207
    ASN1Primitive obj = createDERForRecipient(pkcs7input,
208
        (X509Certificate) certificate);
209
210
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
211
212
    DEROutputStream k = new DEROutputStream(baos);
213
214
    k.writeObject(obj);
215
216
    cms = baos.toByteArray();
217
218 1 1. getEncodedRecipient : removed call to com/lowagie/text/pdf/PdfPublicKeyRecipient::setCms → NO_COVERAGE
    recipient.setCms(cms);
219
220 1 1. getEncodedRecipient : mutated return of Object value for com/lowagie/text/pdf/PdfPublicKeySecurityHandler::getEncodedRecipient to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
    return cms;
221
  }
222
223
  public PdfArray getEncodedRecipients() throws IOException {
224
    PdfArray EncodedRecipients = new PdfArray();
225
    byte[] cms = null;
226 2 1. getEncodedRecipients : changed conditional boundary → NO_COVERAGE
2. getEncodedRecipients : negated conditional → NO_COVERAGE
    for (int i = 0; i < recipients.size(); i++)
227
      try {
228
        cms = getEncodedRecipient(i);
229
        EncodedRecipients.add(new PdfLiteral(PdfContentByte.escapeString(cms)));
230
      } catch (GeneralSecurityException | IOException e) {
231
        EncodedRecipients = null;
232
      }
233
234 1 1. getEncodedRecipients : mutated return of Object value for com/lowagie/text/pdf/PdfPublicKeySecurityHandler::getEncodedRecipients to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
    return EncodedRecipients;
235
  }
236
237
  private ASN1Primitive createDERForRecipient(byte[] in, X509Certificate cert)
238
      throws IOException, GeneralSecurityException {
239
240
    String s = "1.2.840.113549.3.2";
241
242
    AlgorithmParameterGenerator algorithmparametergenerator = AlgorithmParameterGenerator
243
        .getInstance(s);
244
    AlgorithmParameters algorithmparameters = algorithmparametergenerator
245
        .generateParameters();
246
    ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(
247
        algorithmparameters.getEncoded("ASN.1"));
248
    ASN1InputStream asn1inputstream = new ASN1InputStream(bytearrayinputstream);
249
    ASN1Primitive derobject = asn1inputstream.readObject();
250
    KeyGenerator keygenerator = KeyGenerator.getInstance(s);
251 1 1. createDERForRecipient : removed call to javax/crypto/KeyGenerator::init → NO_COVERAGE
    keygenerator.init(128);
252
    SecretKey secretkey = keygenerator.generateKey();
253
    Cipher cipher = Cipher.getInstance(s);
254 1 1. createDERForRecipient : removed call to javax/crypto/Cipher::init → NO_COVERAGE
    cipher.init(1, secretkey, algorithmparameters);
255
    byte[] abyte1 = cipher.doFinal(in);
256
    DEROctetString deroctetstring = new DEROctetString(abyte1);
257
    KeyTransRecipientInfo keytransrecipientinfo = computeRecipientInfo(cert,
258
        secretkey.getEncoded());
259
    DERSet derset = new DERSet(new RecipientInfo(keytransrecipientinfo));
260
    AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier(
261
        new ASN1ObjectIdentifier(s), derobject);
262
    EncryptedContentInfo encryptedcontentinfo = new EncryptedContentInfo(
263
        PKCSObjectIdentifiers.data, algorithmidentifier, deroctetstring);
264
    ASN1Set set = null;
265
    EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo,
266
        set);
267
    ContentInfo contentinfo = new ContentInfo(
268
        PKCSObjectIdentifiers.envelopedData, env);
269
    // OJO... Modificacion de
270
    // Felix--------------------------------------------------
271
    // return contentinfo.getDERObject();
272
    return contentinfo.toASN1Primitive();
273
    // ******************************************************************************
274
  }
275
276
  private KeyTransRecipientInfo computeRecipientInfo(
277
      X509Certificate x509certificate, byte[] abyte0)
278
      throws GeneralSecurityException, IOException {
279
    ASN1InputStream asn1inputstream = new ASN1InputStream(
280
        new ByteArrayInputStream(x509certificate.getTBSCertificate()));
281
    TBSCertificate tbsCertificate = TBSCertificate.getInstance(asn1inputstream.readObject());
282
    AlgorithmIdentifier algorithmidentifier = tbsCertificate.getSubjectPublicKeyInfo().getAlgorithm();
283
    IssuerAndSerialNumber issuerandserialnumber = new IssuerAndSerialNumber(
284
            tbsCertificate.getIssuer(), tbsCertificate.getSerialNumber().getValue());
285
    Cipher cipher = Cipher.getInstance(algorithmidentifier.getAlgorithm().getId());
286 1 1. computeRecipientInfo : removed call to javax/crypto/Cipher::init → NO_COVERAGE
    cipher.init(1, x509certificate);
287
    DEROctetString deroctetstring = new DEROctetString(cipher.doFinal(abyte0));
288
    RecipientIdentifier recipId = new RecipientIdentifier(issuerandserialnumber);
289
    return new KeyTransRecipientInfo(recipId, algorithmidentifier, deroctetstring);
290
  }
291
}

Mutations

142

1.1
Location :
Killed by : none
removed call to javax/crypto/KeyGenerator::init → NO_COVERAGE

144

1.1
Location :
Killed by : none
removed call to java/lang/System::arraycopy → NO_COVERAGE

159

1.1
Location : getSeed
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/PdfPublicKeySecurityHandler::getSeed to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

178

1.1
Location : getEncodedRecipient
Killed by : none
negated conditional → NO_COVERAGE

179

1.1
Location : getEncodedRecipient
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/PdfPublicKeySecurityHandler::getEncodedRecipient to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

188

1.1
Location : getEncodedRecipient
Killed by : none
Replaced bitwise OR with AND → NO_COVERAGE

2.2
Location : getEncodedRecipient
Killed by : none
negated conditional → NO_COVERAGE

189

1.1
Location : getEncodedRecipient
Killed by : none
Replaced bitwise AND with OR → NO_COVERAGE

190

1.1
Location : getEncodedRecipient
Killed by : none
Changed increment from 1 to -1 → NO_COVERAGE

195

1.1
Location : getEncodedRecipient
Killed by : none
Replaced Shift Right with Shift Left → NO_COVERAGE

196

1.1
Location : getEncodedRecipient
Killed by : none
Replaced Shift Right with Shift Left → NO_COVERAGE

197

1.1
Location : getEncodedRecipient
Killed by : none
Replaced Shift Right with Shift Left → NO_COVERAGE

199

1.1
Location : getEncodedRecipient
Killed by : none
removed call to java/lang/System::arraycopy → NO_COVERAGE

218

1.1
Location : getEncodedRecipient
Killed by : none
removed call to com/lowagie/text/pdf/PdfPublicKeyRecipient::setCms → NO_COVERAGE

220

1.1
Location : getEncodedRecipient
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/PdfPublicKeySecurityHandler::getEncodedRecipient to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

226

1.1
Location : getEncodedRecipients
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : getEncodedRecipients
Killed by : none
negated conditional → NO_COVERAGE

234

1.1
Location : getEncodedRecipients
Killed by : none
mutated return of Object value for com/lowagie/text/pdf/PdfPublicKeySecurityHandler::getEncodedRecipients to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE

251

1.1
Location : createDERForRecipient
Killed by : none
removed call to javax/crypto/KeyGenerator::init → NO_COVERAGE

254

1.1
Location : createDERForRecipient
Killed by : none
removed call to javax/crypto/Cipher::init → NO_COVERAGE

286

1.1
Location : computeRecipientInfo
Killed by : none
removed call to javax/crypto/Cipher::init → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.4.2