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 |
|
237 |
1.1 |
|
238 |
1.1 |
|
239 |
1.1 |
|
243 |
1.1 |
|
244 |
1.1 |
|
245 |
1.1 |
|
246 |
1.1 2.2 |
|
259 |
1.1 |
|
261 |
1.1 |
|
264 |
1.1 |
|
266 |
1.1 |
|
280 |
1.1 |