OcspClientBouncyCastle.java

1
/*
2
 * $Id: OcspClientBouncyCastle.java 4065 2009-09-16 23:09:11Z psoares33 $
3
 *
4
 * Copyright 2009 Paulo Soares
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * (the "License"); you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9
 *
10
 * Software distributed under the License is distributed on an "AS IS" basis,
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
 * for the specific language governing rights and limitations under the License.
13
 *
14
 * The Original Code is 'iText, a free JAVA-PDF library'.
15
 *
16
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17
 * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
18
 * All Rights Reserved.
19
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20
 * are Copyright (C) 2009 by Paulo Soares. All Rights Reserved.
21
 *
22
 * Contributor(s): all the names of the contributors are added in the source code
23
 * where applicable.
24
 *
25
 * Alternatively, the contents of this file may be used under the terms of the
26
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27
 * provisions of LGPL are applicable instead of those above.  If you wish to
28
 * allow use of your version of this file only under the terms of the LGPL
29
 * License and not to allow others to use your version of this file under
30
 * the MPL, indicate your decision by deleting the provisions above and
31
 * replace them with the notice and other provisions required by the LGPL.
32
 * If you do not delete the provisions above, a recipient may use your version
33
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34
 *
35
 * This library is free software; you can redistribute it and/or modify it
36
 * under the terms of the MPL as stated above or under the terms of the GNU
37
 * Library General Public License as published by the Free Software Foundation;
38
 * either version 2 of the License, or any later version.
39
 *
40
 * This library is distributed in the hope that it will be useful, but WITHOUT
41
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43
 * details.
44
 *
45
 * If you didn't download this code from the following link, you should check if
46
 * you aren't using an obsolete version:
47
 * http://www.lowagie.com/iText/
48
 */
49
50
package com.lowagie.text.pdf;
51
52
/*
53
 * $Id: OcspClientBouncyCastle.java 4065 2009-09-16 23:09:11Z psoares33 $
54
 *
55
 * Copyright 2009 Paulo Soares
56
 *
57
 * The contents of this file are subject to the Mozilla Public License Version 1.1
58
 * (the "License"); you may not use this file except in compliance with the License.
59
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
60
 *
61
 * Software distributed under the License is distributed on an "AS IS" basis,
62
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
63
 * for the specific language governing rights and limitations under the License.
64
 *
65
 * The Original Code is 'iText, a free JAVA-PDF library'.
66
 *
67
 * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
68
 * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
69
 * All Rights Reserved.
70
 * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
71
 * are Copyright (C) 2009 by Paulo Soares. All Rights Reserved.
72
 *
73
 * Contributor(s): all the names of the contributors are added in the source code
74
 * where applicable.
75
 *
76
 * Alternatively, the contents of this file may be used under the terms of the
77
 * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
78
 * provisions of LGPL are applicable instead of those above.  If you wish to
79
 * allow use of your version of this file only under the terms of the LGPL
80
 * License and not to allow others to use your version of this file under
81
 * the MPL, indicate your decision by deleting the provisions above and
82
 * replace them with the notice and other provisions required by the LGPL.
83
 * If you do not delete the provisions above, a recipient may use your version
84
 * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
85
 *
86
 * This library is free software; you can redistribute it and/or modify it
87
 * under the terms of the MPL as stated above or under the terms of the GNU
88
 * Library General Public License as published by the Free Software Foundation;
89
 * either version 2 of the License, or any later version.
90
 *
91
 * This library is distributed in the hope that it will be useful, but WITHOUT
92
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
93
 * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
94
 * details.
95
 *
96
 * If you didn't download this code from the following link, you should check if
97
 * you aren't using an obsolete version:
98
 * http://www.lowagie.com/iText/
99
 */
100
101
import java.io.BufferedOutputStream;
102
import java.io.DataOutputStream;
103
import java.io.IOException;
104
import java.io.InputStream;
105
import java.io.OutputStream;
106
import java.math.BigInteger;
107
import java.net.HttpURLConnection;
108
import java.net.URL;
109
import java.security.Provider;
110
import java.security.Security;
111
import java.security.cert.CertificateEncodingException;
112
import java.security.cert.X509Certificate;
113
import java.util.Random;
114
115
import com.lowagie.text.ExceptionConverter;
116
import org.bouncycastle.asn1.DEROctetString;
117
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
118
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
119
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
120
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
121
import org.bouncycastle.cert.ocsp.CertificateID;
122
import org.bouncycastle.cert.ocsp.OCSPException;
123
import org.bouncycastle.cert.ocsp.OCSPReq;
124
import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
125
import org.bouncycastle.cert.ocsp.OCSPResp;
126
import org.bouncycastle.cert.ocsp.SingleResp;
127
import org.bouncycastle.operator.DigestCalculatorProvider;
128
import org.bouncycastle.operator.OperatorCreationException;
129
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
130
131
132
import com.lowagie.text.error_messages.MessageLocalization;
133
134
/**
135
 * OcspClient implementation using BouncyCastle.
136
 * 
137
 * @author psoares
138
 * @since 2.1.6
139
 */
140
public class OcspClientBouncyCastle implements OcspClient {
141
  /** root certificate */
142
  private final X509Certificate rootCert;
143
  /** check certificate */
144
  private final X509Certificate checkCert;
145
  /** OCSP URL */
146
  private final String url;
147
148
  /**
149
   * Creates an instance of an OcspClient that will be using BouncyCastle.
150
   * 
151
   * @param checkCert
152
   *          the check certificate
153
   * @param rootCert
154
   *          the root certificate
155
   * @param url
156
   *          the OCSP URL
157
   */
158
  public OcspClientBouncyCastle(X509Certificate checkCert,
159
      X509Certificate rootCert, String url) {
160
    this.checkCert = checkCert;
161
    this.rootCert = rootCert;
162
    this.url = url;
163
  }
164
165
  /**
166
   * Generates an OCSP request using BouncyCastle.
167
   * 
168
   * @param issuerCert
169
   *          certificate of the issues
170
   * @param serialNumber
171
   *          serial number
172
   * @return an OCSP request
173
   * @throws OCSPException
174
   * @throws IOException
175
   */
176
  private static OCSPReq generateOCSPRequest(X509Certificate issuerCert,
177
      BigInteger serialNumber) throws OCSPException, IOException,
178
      OperatorCreationException, CertificateEncodingException {
179
    // Add provider BC
180
    Provider prov = new org.bouncycastle.jce.provider.BouncyCastleProvider();
181
    Security.addProvider(prov);
182
183
    // Generate the id for the certificate we are looking for
184
    // OJO... Modificacion de
185
    // Felix--------------------------------------------------
186
    // CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert,
187
    // serialNumber);
188
    // Example from
189
    // http://grepcode.com/file/repo1.maven.org/maven2/org.bouncycastle/bcmail-jdk16/1.46/org/bouncycastle/cert/ocsp/test/OCSPTest.java
190
    DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder()
191
        .setProvider(prov).build();
192
193
    CertificateID id = new CertificateID(
194
        digCalcProv.get(CertificateID.HASH_SHA1), new JcaX509CertificateHolder(
195
            issuerCert), serialNumber);
196
197
    // basic request generation with nonce
198
    OCSPReqBuilder gen = new OCSPReqBuilder();
199
200
    gen.addRequest(id);
201
202
    // create details for nonce extension
203
    // Vector oids = new Vector();
204
    // Vector values = new Vector();
205
    // oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
206
    // values.add(new X509Extension(false, new DEROctetString(new
207
    // DEROctetString(PdfEncryption.createDocumentId()).getEncoded())));
208
    // gen.setRequestExtensions(new X509Extensions(oids, values));
209
210
    // Add nonce extension
211
    ExtensionsGenerator extGen = new ExtensionsGenerator();
212
    byte[] nonce = new byte[16];
213
    Random rand = new Random();
214 1 1. generateOCSPRequest : removed call to java/util/Random::nextBytes → NO_COVERAGE
    rand.nextBytes(nonce);
215
216
    extGen.addExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false,
217
        new DEROctetString(nonce));
218
    gen.setRequestExtensions(extGen.generate());
219
220
    // Build request
221
    return gen.build();
222
    // ******************************************************************************
223
  }
224
225
  /**
226
   * @return a byte array
227
   * @see com.lowagie.text.pdf.OcspClient
228
   */
229
  @Override
230
  public byte[] getEncoded() {
231
    try {
232
      OCSPReq request = generateOCSPRequest(rootCert,
233
          checkCert.getSerialNumber());
234
      byte[] array = request.getEncoded();
235
      URL urlt = new URL(url);
236
      HttpURLConnection con = (HttpURLConnection) urlt.openConnection();
237 1 1. getEncoded : removed call to java/net/HttpURLConnection::setRequestProperty → NO_COVERAGE
      con.setRequestProperty("Content-Type", "application/ocsp-request");
238 1 1. getEncoded : removed call to java/net/HttpURLConnection::setRequestProperty → NO_COVERAGE
      con.setRequestProperty("Accept", "application/ocsp-response");
239 1 1. getEncoded : removed call to java/net/HttpURLConnection::setDoOutput → NO_COVERAGE
      con.setDoOutput(true);
240
      OutputStream out = con.getOutputStream();
241
      DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(
242
          out));
243 1 1. getEncoded : removed call to java/io/DataOutputStream::write → NO_COVERAGE
      dataOut.write(array);
244 1 1. getEncoded : removed call to java/io/DataOutputStream::flush → NO_COVERAGE
      dataOut.flush();
245 1 1. getEncoded : removed call to java/io/DataOutputStream::close → NO_COVERAGE
      dataOut.close();
246 2 1. getEncoded : Replaced integer division with multiplication → NO_COVERAGE
2. getEncoded : negated conditional → NO_COVERAGE
      if (con.getResponseCode() / 100 != 2) {
247
        throw new IOException(MessageLocalization.getComposedMessage(
248
            "invalid.http.response.1", con.getResponseCode()));
249
      }
250
      // Get Response
251
      InputStream in = (InputStream) con.getContent();
252
      OCSPResp ocspResponse = new OCSPResp(in);
253
254
      if (ocspResponse.getStatus() != 0)
255
        throw new IOException(MessageLocalization.getComposedMessage(
256
            "invalid.status.1", ocspResponse.getStatus()));
257
      BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse
258
          .getResponseObject();
259 1 1. getEncoded : negated conditional → NO_COVERAGE
      if (basicResponse != null) {
260
        SingleResp[] responses = basicResponse.getResponses();
261 1 1. getEncoded : negated conditional → NO_COVERAGE
        if (responses.length == 1) {
262
          SingleResp resp = responses[0];
263
          Object status = resp.getCertStatus();
264 1 1. getEncoded : negated conditional → NO_COVERAGE
          if (status == null) {
265
            return basicResponse.getEncoded();
266 1 1. getEncoded : negated conditional → NO_COVERAGE
          } else if (status instanceof org.bouncycastle.cert.ocsp.RevokedStatus) {
267
            throw new IOException(
268
                MessageLocalization
269
                    .getComposedMessage("ocsp.status.is.revoked"));
270
          } else {
271
            throw new IOException(
272
                MessageLocalization
273
                    .getComposedMessage("ocsp.status.is.unknown"));
274
          }
275
        }
276
      }
277
    } catch (Exception ex) {
278
      throw new ExceptionConverter(ex);
279
    }
280 1 1. getEncoded : mutated return of Object value for com/lowagie/text/pdf/OcspClientBouncyCastle::getEncoded to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE
    return null;
281
  }
282
}

Mutations

214

1.1
Location : generateOCSPRequest
Killed by : none
removed call to java/util/Random::nextBytes → NO_COVERAGE

237

1.1
Location : getEncoded
Killed by : none
removed call to java/net/HttpURLConnection::setRequestProperty → NO_COVERAGE

238

1.1
Location : getEncoded
Killed by : none
removed call to java/net/HttpURLConnection::setRequestProperty → NO_COVERAGE

239

1.1
Location : getEncoded
Killed by : none
removed call to java/net/HttpURLConnection::setDoOutput → NO_COVERAGE

243

1.1
Location : getEncoded
Killed by : none
removed call to java/io/DataOutputStream::write → NO_COVERAGE

244

1.1
Location : getEncoded
Killed by : none
removed call to java/io/DataOutputStream::flush → NO_COVERAGE

245

1.1
Location : getEncoded
Killed by : none
removed call to java/io/DataOutputStream::close → NO_COVERAGE

246

1.1
Location : getEncoded
Killed by : none
Replaced integer division with multiplication → NO_COVERAGE

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

259

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

261

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

264

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

266

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

280

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

Active mutators

Tests examined


Report generated by PIT 1.4.2