Browse Source
Merge in CORE/base-third from ~ABBY/base-third:final/10.0 to final/10.0 * commit 'c9864e29818e859e7c00e3656384fa342be140b2': REPORT-31938 改进 REPORT-31938 html解析支持rgba REPORT-29654 jgit 打包的时候少了 resources REPORT-31421 间距设置导致切割后的HTML 含有line-height属性 111 DEC-13199 websocket序列化时区设置 REPORT-31053 PDF导出,<br>标签丢失 REPORT-30379 test补充注释 REPORT-30379 在third中加一个 third(不在打包范围内,需要自己添加junit依赖才能跑) REPORT-30379 bouncycastle存在安全问题,fine-itext、fine-itext-old 适配高版本 REPORT-29182 & REPORT-29600 weblogic部署导出excel报错 KERNEL-3881 状态服务器+集群锁相关代码解耦,脱离依赖redis KERNEL-3881 状态服务器+集群锁相关代码解耦,脱离依赖redis REPORT-27284 <table>标签导出pdf,含加粗字体时,边框颜色异常final/10.0
Kara
5 years ago
26 changed files with 1558 additions and 1364 deletions
@ -1,184 +1,184 @@
|
||||
/* |
||||
* $Id: OcspClientBouncyCastle.java 3959 2009-06-09 08:31:05Z blowagie $ |
||||
* |
||||
* Copyright 2009 Paulo Soares |
||||
* |
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
||||
* (the "License"); you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
* |
||||
* Software distributed under the License is distributed on an "AS IS" basis, |
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
||||
* for the specific language governing rights and limitations under the License. |
||||
* |
||||
* The Original Code is 'iText, a free JAVA-PDF library'. |
||||
* |
||||
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by |
||||
* the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. |
||||
* All Rights Reserved. |
||||
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer |
||||
* are Copyright (C) 2009 by Paulo Soares. All Rights Reserved. |
||||
* |
||||
* Contributor(s): all the names of the contributors are added in the source code |
||||
* where applicable. |
||||
* |
||||
* Alternatively, the contents of this file may be used under the terms of the |
||||
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the |
||||
* provisions of LGPL are applicable instead of those above. If you wish to |
||||
* allow use of your version of this file only under the terms of the LGPL |
||||
* License and not to allow others to use your version of this file under |
||||
* the MPL, indicate your decision by deleting the provisions above and |
||||
* replace them with the notice and other provisions required by the LGPL. |
||||
* If you do not delete the provisions above, a recipient may use your version |
||||
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. |
||||
* |
||||
* This library is free software; you can redistribute it and/or modify it |
||||
* under the terms of the MPL as stated above or under the terms of the GNU |
||||
* Library General Public License as published by the Free Software Foundation; |
||||
* either version 2 of the License, or any later version. |
||||
* |
||||
* This library is distributed in the hope that it will be useful, but WITHOUT |
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||||
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more |
||||
* details. |
||||
* |
||||
* If you didn't download this code from the following link, you should check if |
||||
* you aren't using an obsolete version: |
||||
* http://www.lowagie.com/iText/
|
||||
*/ |
||||
|
||||
package com.fr.third.com.lowagie.text.pdf; |
||||
|
||||
import com.fr.third.com.lowagie.text.ExceptionConverter; |
||||
import java.io.BufferedOutputStream; |
||||
import java.io.DataOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
import java.math.BigInteger; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.URL; |
||||
import java.security.Security; |
||||
import java.security.cert.X509Certificate; |
||||
import java.util.Vector; |
||||
import org.bouncycastle.asn1.DEROctetString; |
||||
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; |
||||
import org.bouncycastle.asn1.x509.X509Extension; |
||||
import org.bouncycastle.asn1.x509.X509Extensions; |
||||
import org.bouncycastle.ocsp.BasicOCSPResp; |
||||
import org.bouncycastle.ocsp.CertificateID; |
||||
import org.bouncycastle.ocsp.CertificateStatus; |
||||
import org.bouncycastle.ocsp.OCSPException; |
||||
import org.bouncycastle.ocsp.OCSPReq; |
||||
import org.bouncycastle.ocsp.OCSPReqGenerator; |
||||
import org.bouncycastle.ocsp.OCSPResp; |
||||
import org.bouncycastle.ocsp.SingleResp; |
||||
|
||||
/** |
||||
* OcspClient implementation using BouncyCastle. |
||||
* @author psoares |
||||
* @since 2.1.6 |
||||
*/ |
||||
public class OcspClientBouncyCastle implements OcspClient { |
||||
/** root certificate */ |
||||
private X509Certificate rootCert; |
||||
/** check certificate */ |
||||
private X509Certificate checkCert; |
||||
/** OCSP URL */ |
||||
private String url; |
||||
|
||||
/** |
||||
* Creates an instance of an OcspClient that will be using BouncyCastle. |
||||
* @param checkCert the check certificate |
||||
* @param rootCert the root certificate |
||||
* @param url the OCSP URL |
||||
*/ |
||||
public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) { |
||||
this.checkCert = checkCert; |
||||
this.rootCert = rootCert; |
||||
this.url = url; |
||||
} |
||||
|
||||
/** |
||||
* Generates an OCSP request using BouncyCastle. |
||||
* @param issuerCert certificate of the issues |
||||
* @param serialNumber serial number |
||||
* @return an OCSP request |
||||
* @throws OCSPException |
||||
* @throws IOException |
||||
*/ |
||||
private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException { |
||||
//Add provider BC
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); |
||||
|
||||
// Generate the id for the certificate we are looking for
|
||||
CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber); |
||||
|
||||
// basic request generation with nonce
|
||||
OCSPReqGenerator gen = new OCSPReqGenerator(); |
||||
|
||||
gen.addRequest(id); |
||||
|
||||
// create details for nonce extension
|
||||
Vector oids = new Vector(); |
||||
Vector values = new Vector(); |
||||
|
||||
oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); |
||||
values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded()))); |
||||
|
||||
gen.setRequestExtensions(new X509Extensions(oids, values)); |
||||
|
||||
return gen.generate(); |
||||
} |
||||
|
||||
/** |
||||
* @return a byte array |
||||
* @see com.fr.third.com.lowagie.text.pdf.OcspClient#getEncoded() |
||||
*/ |
||||
public byte[] getEncoded() { |
||||
try { |
||||
OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber()); |
||||
byte[] array = request.getEncoded(); |
||||
URL urlt = new URL(url); |
||||
HttpURLConnection con = (HttpURLConnection)urlt.openConnection(); |
||||
con.setRequestProperty("Content-Type", "application/ocsp-request"); |
||||
con.setRequestProperty("Accept", "application/ocsp-response"); |
||||
con.setDoOutput(true); |
||||
OutputStream out = con.getOutputStream(); |
||||
DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out)); |
||||
dataOut.write(array); |
||||
dataOut.flush(); |
||||
dataOut.close(); |
||||
if (con.getResponseCode() / 100 != 2) { |
||||
throw new IOException("Invalid HTTP response"); |
||||
} |
||||
//Get Response
|
||||
InputStream in = (InputStream) con.getContent(); |
||||
OCSPResp ocspResponse = new OCSPResp(in); |
||||
|
||||
if (ocspResponse.getStatus() != 0) |
||||
throw new IOException("Invalid status: " + ocspResponse.getStatus()); |
||||
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject(); |
||||
if (basicResponse != null) { |
||||
SingleResp[] responses = basicResponse.getResponses(); |
||||
if (responses.length == 1) { |
||||
SingleResp resp = responses[0]; |
||||
Object status = resp.getCertStatus(); |
||||
if (status == CertificateStatus.GOOD) { |
||||
return basicResponse.getEncoded(); |
||||
} |
||||
else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) { |
||||
throw new IOException("OCSP Status is revoked!"); |
||||
} |
||||
else { |
||||
throw new IOException("OCSP Status is unknown!"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
catch (Exception ex) { |
||||
throw new ExceptionConverter(ex); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
///*
|
||||
// * $Id: OcspClientBouncyCastle.java 3959 2009-06-09 08:31:05Z blowagie $
|
||||
// *
|
||||
// * Copyright 2009 Paulo Soares
|
||||
// *
|
||||
// * The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
// * (the "License"); you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
// *
|
||||
// * Software distributed under the License is distributed on an "AS IS" basis,
|
||||
// * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
// * for the specific language governing rights and limitations under the License.
|
||||
// *
|
||||
// * The Original Code is 'iText, a free JAVA-PDF library'.
|
||||
// *
|
||||
// * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
|
||||
// * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
|
||||
// * All Rights Reserved.
|
||||
// * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
|
||||
// * are Copyright (C) 2009 by Paulo Soares. All Rights Reserved.
|
||||
// *
|
||||
// * Contributor(s): all the names of the contributors are added in the source code
|
||||
// * where applicable.
|
||||
// *
|
||||
// * Alternatively, the contents of this file may be used under the terms of the
|
||||
// * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
|
||||
// * provisions of LGPL are applicable instead of those above. If you wish to
|
||||
// * allow use of your version of this file only under the terms of the LGPL
|
||||
// * License and not to allow others to use your version of this file under
|
||||
// * the MPL, indicate your decision by deleting the provisions above and
|
||||
// * replace them with the notice and other provisions required by the LGPL.
|
||||
// * If you do not delete the provisions above, a recipient may use your version
|
||||
// * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
|
||||
// *
|
||||
// * This library is free software; you can redistribute it and/or modify it
|
||||
// * under the terms of the MPL as stated above or under the terms of the GNU
|
||||
// * Library General Public License as published by the Free Software Foundation;
|
||||
// * either version 2 of the License, or any later version.
|
||||
// *
|
||||
// * This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
|
||||
// * details.
|
||||
// *
|
||||
// * If you didn't download this code from the following link, you should check if
|
||||
// * you aren't using an obsolete version:
|
||||
// * http://www.lowagie.com/iText/
|
||||
// */
|
||||
//
|
||||
//package com.fr.third.com.lowagie.text.pdf;
|
||||
//
|
||||
//import com.fr.third.com.lowagie.text.ExceptionConverter;
|
||||
//import java.io.BufferedOutputStream;
|
||||
//import java.io.DataOutputStream;
|
||||
//import java.io.IOException;
|
||||
//import java.io.InputStream;
|
||||
//import java.io.OutputStream;
|
||||
//import java.math.BigInteger;
|
||||
//import java.net.HttpURLConnection;
|
||||
//import java.net.URL;
|
||||
//import java.security.Security;
|
||||
//import java.security.cert.X509Certificate;
|
||||
//import java.util.Vector;
|
||||
//import org.bouncycastle.asn1.DEROctetString;
|
||||
//import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
|
||||
//import org.bouncycastle.asn1.x509.X509Extension;
|
||||
//import org.bouncycastle.asn1.x509.X509Extensions;
|
||||
//import org.bouncycastle.ocsp.BasicOCSPResp;
|
||||
//import org.bouncycastle.ocsp.CertificateID;
|
||||
//import org.bouncycastle.ocsp.CertificateStatus;
|
||||
//import org.bouncycastle.ocsp.OCSPException;
|
||||
//import org.bouncycastle.ocsp.OCSPReq;
|
||||
//import org.bouncycastle.ocsp.OCSPReqGenerator;
|
||||
//import org.bouncycastle.ocsp.OCSPResp;
|
||||
//import org.bouncycastle.ocsp.SingleResp;
|
||||
//
|
||||
///**
|
||||
// * OcspClient implementation using BouncyCastle.
|
||||
// * @author psoares
|
||||
// * @since 2.1.6
|
||||
// */
|
||||
//public class OcspClientBouncyCastle implements OcspClient {
|
||||
// /** root certificate */
|
||||
// private X509Certificate rootCert;
|
||||
// /** check certificate */
|
||||
// private X509Certificate checkCert;
|
||||
// /** OCSP URL */
|
||||
// private String url;
|
||||
//
|
||||
// /**
|
||||
// * Creates an instance of an OcspClient that will be using BouncyCastle.
|
||||
// * @param checkCert the check certificate
|
||||
// * @param rootCert the root certificate
|
||||
// * @param url the OCSP URL
|
||||
// */
|
||||
// public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) {
|
||||
// this.checkCert = checkCert;
|
||||
// this.rootCert = rootCert;
|
||||
// this.url = url;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Generates an OCSP request using BouncyCastle.
|
||||
// * @param issuerCert certificate of the issues
|
||||
// * @param serialNumber serial number
|
||||
// * @return an OCSP request
|
||||
// * @throws OCSPException
|
||||
// * @throws IOException
|
||||
// */
|
||||
// private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException {
|
||||
// //Add provider BC
|
||||
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
//
|
||||
// // Generate the id for the certificate we are looking for
|
||||
// CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber);
|
||||
//
|
||||
// // basic request generation with nonce
|
||||
// OCSPReqGenerator gen = new OCSPReqGenerator();
|
||||
//
|
||||
// gen.addRequest(id);
|
||||
//
|
||||
// // create details for nonce extension
|
||||
// Vector oids = new Vector();
|
||||
// Vector values = new Vector();
|
||||
//
|
||||
// oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
|
||||
// values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded())));
|
||||
//
|
||||
// gen.setRequestExtensions(new X509Extensions(oids, values));
|
||||
//
|
||||
// return gen.generate();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return a byte array
|
||||
// * @see com.fr.third.com.lowagie.text.pdf.OcspClient#getEncoded()
|
||||
// */
|
||||
// public byte[] getEncoded() {
|
||||
// try {
|
||||
// OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber());
|
||||
// byte[] array = request.getEncoded();
|
||||
// URL urlt = new URL(url);
|
||||
// HttpURLConnection con = (HttpURLConnection)urlt.openConnection();
|
||||
// con.setRequestProperty("Content-Type", "application/ocsp-request");
|
||||
// con.setRequestProperty("Accept", "application/ocsp-response");
|
||||
// con.setDoOutput(true);
|
||||
// OutputStream out = con.getOutputStream();
|
||||
// DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out));
|
||||
// dataOut.write(array);
|
||||
// dataOut.flush();
|
||||
// dataOut.close();
|
||||
// if (con.getResponseCode() / 100 != 2) {
|
||||
// throw new IOException("Invalid HTTP response");
|
||||
// }
|
||||
// //Get Response
|
||||
// InputStream in = (InputStream) con.getContent();
|
||||
// OCSPResp ocspResponse = new OCSPResp(in);
|
||||
//
|
||||
// if (ocspResponse.getStatus() != 0)
|
||||
// throw new IOException("Invalid status: " + ocspResponse.getStatus());
|
||||
// BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
|
||||
// if (basicResponse != null) {
|
||||
// SingleResp[] responses = basicResponse.getResponses();
|
||||
// if (responses.length == 1) {
|
||||
// SingleResp resp = responses[0];
|
||||
// Object status = resp.getCertStatus();
|
||||
// if (status == CertificateStatus.GOOD) {
|
||||
// return basicResponse.getEncoded();
|
||||
// }
|
||||
// else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) {
|
||||
// throw new IOException("OCSP Status is revoked!");
|
||||
// }
|
||||
// else {
|
||||
// throw new IOException("OCSP Status is unknown!");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex) {
|
||||
// throw new ExceptionConverter(ex);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
|
@ -1,230 +1,230 @@
|
||||
/* |
||||
* $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $ |
||||
* |
||||
* Copyright 2009 Martin Brunecky, Aiken Sam |
||||
* |
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
||||
* (the "License"); you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
* |
||||
* Software distributed under the License is distributed on an "AS IS" basis, |
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
||||
* for the specific language governing rights and limitations under the License. |
||||
* |
||||
* The Original Code is 'iText, a free JAVA-PDF library'. |
||||
* |
||||
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by |
||||
* the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. |
||||
* All Rights Reserved. |
||||
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer |
||||
* are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved. |
||||
* |
||||
* Contributor(s): all the names of the contributors are added in the source code |
||||
* where applicable. |
||||
* |
||||
* Alternatively, the contents of this file may be used under the terms of the |
||||
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the |
||||
* provisions of LGPL are applicable instead of those above. If you wish to |
||||
* allow use of your version of this file only under the terms of the LGPL |
||||
* License and not to allow others to use your version of this file under |
||||
* the MPL, indicate your decision by deleting the provisions above and |
||||
* replace them with the notice and other provisions required by the LGPL. |
||||
* If you do not delete the provisions above, a recipient may use your version |
||||
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. |
||||
* |
||||
* This library is free software; you can redistribute it and/or modify it |
||||
* under the terms of the MPL as stated above or under the terms of the GNU |
||||
* Library General Public License as published by the Free Software Foundation; |
||||
* either version 2 of the License, or any later version. |
||||
* |
||||
* This library is distributed in the hope that it will be useful, but WITHOUT |
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||||
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more |
||||
* details. |
||||
* |
||||
* If you didn't download this code from the following link, you should check if |
||||
* you aren't using an obsolete version: |
||||
* http://www.lowagie.com/iText/
|
||||
*/ |
||||
|
||||
package com.fr.third.com.lowagie.text.pdf; |
||||
|
||||
import java.io.*; |
||||
import java.math.*; |
||||
import java.net.*; |
||||
|
||||
import org.bouncycastle.asn1.cmp.*; |
||||
import org.bouncycastle.asn1.x509.*; |
||||
import org.bouncycastle.tsp.*; |
||||
|
||||
import com.fr.third.com.lowagie.text.pdf.codec.Base64; |
||||
|
||||
/** |
||||
* Time Stamp Authority Client interface implementation using Bouncy Castle |
||||
* org.bouncycastle.tsp package. |
||||
* <p> |
||||
* Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007 |
||||
* for ease of subclassing. |
||||
* </p> |
||||
* @since 2.1.6 |
||||
*/ |
||||
public class TSAClientBouncyCastle implements TSAClient { |
||||
/** URL of the Time Stamp Authority */ |
||||
protected String tsaURL; |
||||
/** TSA Username */ |
||||
protected String tsaUsername; |
||||
/** TSA password */ |
||||
protected String tsaPassword; |
||||
/** Estimate of the received time stamp token */ |
||||
protected int tokSzEstimate; |
||||
|
||||
/** |
||||
* Creates an instance of a TSAClient that will use BouncyCastle. |
||||
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") |
||||
*/ |
||||
public TSAClientBouncyCastle(String url) { |
||||
this(url, null, null, 4096); |
||||
} |
||||
|
||||
/** |
||||
* Creates an instance of a TSAClient that will use BouncyCastle. |
||||
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") |
||||
* @param username String - user(account) name |
||||
* @param password String - password |
||||
*/ |
||||
public TSAClientBouncyCastle(String url, String username, String password) { |
||||
this(url, username, password, 4096); |
||||
} |
||||
|
||||
/** |
||||
* Constructor. |
||||
* Note the token size estimate is updated by each call, as the token |
||||
* size is not likely to change (as long as we call the same TSA using |
||||
* the same imprint length). |
||||
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") |
||||
* @param username String - user(account) name |
||||
* @param password String - password |
||||
* @param tokSzEstimate int - estimated size of received time stamp token (DER encoded) |
||||
*/ |
||||
public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) { |
||||
this.tsaURL = url; |
||||
this.tsaUsername = username; |
||||
this.tsaPassword = password; |
||||
this.tokSzEstimate = tokSzEstimate; |
||||
} |
||||
|
||||
/** |
||||
* Get the token size estimate. |
||||
* Returned value reflects the result of the last succesfull call, padded |
||||
* @return an estimate of the token size |
||||
*/ |
||||
public int getTokenSizeEstimate() { |
||||
return tokSzEstimate; |
||||
} |
||||
|
||||
/** |
||||
* Get RFC 3161 timeStampToken. |
||||
* Method may return null indicating that timestamp should be skipped. |
||||
* @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it) |
||||
* @param imprint byte[] - data imprint to be time-stamped |
||||
* @return byte[] - encoded, TSA signed data of the timeStampToken |
||||
* @throws Exception - TSA request failed |
||||
* @see com.fr.third.com.lowagie.text.pdf.TSAClient#getTimeStampToken(com.fr.third.com.lowagie.text.pdf.PdfPKCS7, byte[]) |
||||
*/ |
||||
public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception { |
||||
return getTimeStampToken(imprint); |
||||
} |
||||
|
||||
/** |
||||
* Get timestamp token - Bouncy Castle request encoding / decoding layer |
||||
*/ |
||||
protected byte[] getTimeStampToken(byte[] imprint) throws Exception { |
||||
byte[] respBytes = null; |
||||
try { |
||||
// Setup the time stamp request
|
||||
TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator(); |
||||
tsqGenerator.setCertReq(true); |
||||
// tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
|
||||
BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis()); |
||||
TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce); |
||||
byte[] requestBytes = request.getEncoded(); |
||||
|
||||
// Call the communications layer
|
||||
respBytes = getTSAResponse(requestBytes); |
||||
|
||||
// Handle the TSA response
|
||||
TimeStampResponse response = new TimeStampResponse(respBytes); |
||||
|
||||
// validate communication level attributes (RFC 3161 PKIStatus)
|
||||
response.validate(request); |
||||
PKIFailureInfo failure = response.getFailInfo(); |
||||
int value = (failure == null) ? 0 : failure.intValue(); |
||||
if (value != 0) { |
||||
// @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
|
||||
throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value); |
||||
} |
||||
// @todo: validate the time stap certificate chain (if we want
|
||||
// assure we do not sign using an invalid timestamp).
|
||||
|
||||
// extract just the time stamp token (removes communication status info)
|
||||
TimeStampToken tsToken = response.getTimeStampToken(); |
||||
if (tsToken == null) { |
||||
throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString()); |
||||
} |
||||
TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details
|
||||
byte[] encoded = tsToken.getEncoded(); |
||||
long stop = System.currentTimeMillis(); |
||||
|
||||
// Update our token size estimate for the next call (padded to be safe)
|
||||
this.tokSzEstimate = encoded.length + 32; |
||||
return encoded; |
||||
} catch (Exception e) { |
||||
throw e; |
||||
} catch (Throwable t) { |
||||
throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Get timestamp token - communications layer |
||||
* @return - byte[] - TSA response, raw bytes (RFC 3161 encoded) |
||||
*/ |
||||
protected byte[] getTSAResponse(byte[] requestBytes) throws Exception { |
||||
// Setup the TSA connection
|
||||
URL url = new URL(tsaURL); |
||||
URLConnection tsaConnection; |
||||
tsaConnection = (URLConnection) url.openConnection(); |
||||
|
||||
tsaConnection.setDoInput(true); |
||||
tsaConnection.setDoOutput(true); |
||||
tsaConnection.setUseCaches(false); |
||||
tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query"); |
||||
//tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64");
|
||||
tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary"); |
||||
|
||||
if ((tsaUsername != null) && !tsaUsername.equals("") ) { |
||||
String userPassword = tsaUsername + ":" + tsaPassword; |
||||
tsaConnection.setRequestProperty("Authorization", "Basic " + |
||||
new String(Base64.encodeBytes(userPassword.getBytes()))); |
||||
} |
||||
OutputStream out = tsaConnection.getOutputStream(); |
||||
out.write(requestBytes); |
||||
out.close(); |
||||
|
||||
// Get TSA response as a byte array
|
||||
InputStream inp = tsaConnection.getInputStream(); |
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||
byte[] buffer = new byte[1024]; |
||||
int bytesRead = 0; |
||||
while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) { |
||||
baos.write(buffer, 0, bytesRead); |
||||
} |
||||
byte[] respBytes = baos.toByteArray(); |
||||
|
||||
String encoding = tsaConnection.getContentEncoding(); |
||||
if (encoding != null && encoding.equalsIgnoreCase("base64")) { |
||||
respBytes = Base64.decode(new String(respBytes)); |
||||
} |
||||
return respBytes; |
||||
} |
||||
} |
||||
///*
|
||||
// * $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $
|
||||
// *
|
||||
// * Copyright 2009 Martin Brunecky, Aiken Sam
|
||||
// *
|
||||
// * The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
// * (the "License"); you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
// *
|
||||
// * Software distributed under the License is distributed on an "AS IS" basis,
|
||||
// * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
// * for the specific language governing rights and limitations under the License.
|
||||
// *
|
||||
// * The Original Code is 'iText, a free JAVA-PDF library'.
|
||||
// *
|
||||
// * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
|
||||
// * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
|
||||
// * All Rights Reserved.
|
||||
// * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
|
||||
// * are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved.
|
||||
// *
|
||||
// * Contributor(s): all the names of the contributors are added in the source code
|
||||
// * where applicable.
|
||||
// *
|
||||
// * Alternatively, the contents of this file may be used under the terms of the
|
||||
// * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
|
||||
// * provisions of LGPL are applicable instead of those above. If you wish to
|
||||
// * allow use of your version of this file only under the terms of the LGPL
|
||||
// * License and not to allow others to use your version of this file under
|
||||
// * the MPL, indicate your decision by deleting the provisions above and
|
||||
// * replace them with the notice and other provisions required by the LGPL.
|
||||
// * If you do not delete the provisions above, a recipient may use your version
|
||||
// * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
|
||||
// *
|
||||
// * This library is free software; you can redistribute it and/or modify it
|
||||
// * under the terms of the MPL as stated above or under the terms of the GNU
|
||||
// * Library General Public License as published by the Free Software Foundation;
|
||||
// * either version 2 of the License, or any later version.
|
||||
// *
|
||||
// * This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
|
||||
// * details.
|
||||
// *
|
||||
// * If you didn't download this code from the following link, you should check if
|
||||
// * you aren't using an obsolete version:
|
||||
// * http://www.lowagie.com/iText/
|
||||
// */
|
||||
//
|
||||
//package com.fr.third.com.lowagie.text.pdf;
|
||||
//
|
||||
//import java.io.*;
|
||||
//import java.math.*;
|
||||
//import java.net.*;
|
||||
//
|
||||
//import org.bouncycastle.asn1.cmp.*;
|
||||
//import org.bouncycastle.asn1.x509.*;
|
||||
//import org.bouncycastle.tsp.*;
|
||||
//
|
||||
//import com.fr.third.com.lowagie.text.pdf.codec.Base64;
|
||||
//
|
||||
///**
|
||||
// * Time Stamp Authority Client interface implementation using Bouncy Castle
|
||||
// * org.bouncycastle.tsp package.
|
||||
// * <p>
|
||||
// * Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007
|
||||
// * for ease of subclassing.
|
||||
// * </p>
|
||||
// * @since 2.1.6
|
||||
// */
|
||||
//public class TSAClientBouncyCastle implements TSAClient {
|
||||
// /** URL of the Time Stamp Authority */
|
||||
// protected String tsaURL;
|
||||
// /** TSA Username */
|
||||
// protected String tsaUsername;
|
||||
// /** TSA password */
|
||||
// protected String tsaPassword;
|
||||
// /** Estimate of the received time stamp token */
|
||||
// protected int tokSzEstimate;
|
||||
//
|
||||
// /**
|
||||
// * Creates an instance of a TSAClient that will use BouncyCastle.
|
||||
// * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||
// */
|
||||
// public TSAClientBouncyCastle(String url) {
|
||||
// this(url, null, null, 4096);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Creates an instance of a TSAClient that will use BouncyCastle.
|
||||
// * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||
// * @param username String - user(account) name
|
||||
// * @param password String - password
|
||||
// */
|
||||
// public TSAClientBouncyCastle(String url, String username, String password) {
|
||||
// this(url, username, password, 4096);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Constructor.
|
||||
// * Note the token size estimate is updated by each call, as the token
|
||||
// * size is not likely to change (as long as we call the same TSA using
|
||||
// * the same imprint length).
|
||||
// * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||
// * @param username String - user(account) name
|
||||
// * @param password String - password
|
||||
// * @param tokSzEstimate int - estimated size of received time stamp token (DER encoded)
|
||||
// */
|
||||
// public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) {
|
||||
// this.tsaURL = url;
|
||||
// this.tsaUsername = username;
|
||||
// this.tsaPassword = password;
|
||||
// this.tokSzEstimate = tokSzEstimate;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get the token size estimate.
|
||||
// * Returned value reflects the result of the last succesfull call, padded
|
||||
// * @return an estimate of the token size
|
||||
// */
|
||||
// public int getTokenSizeEstimate() {
|
||||
// return tokSzEstimate;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get RFC 3161 timeStampToken.
|
||||
// * Method may return null indicating that timestamp should be skipped.
|
||||
// * @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it)
|
||||
// * @param imprint byte[] - data imprint to be time-stamped
|
||||
// * @return byte[] - encoded, TSA signed data of the timeStampToken
|
||||
// * @throws Exception - TSA request failed
|
||||
// * @see com.fr.third.com.lowagie.text.pdf.TSAClient#getTimeStampToken(com.fr.third.com.lowagie.text.pdf.PdfPKCS7, byte[])
|
||||
// */
|
||||
// public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception {
|
||||
// return getTimeStampToken(imprint);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get timestamp token - Bouncy Castle request encoding / decoding layer
|
||||
// */
|
||||
// protected byte[] getTimeStampToken(byte[] imprint) throws Exception {
|
||||
// byte[] respBytes = null;
|
||||
// try {
|
||||
// // Setup the time stamp request
|
||||
// TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator();
|
||||
// tsqGenerator.setCertReq(true);
|
||||
// // tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
|
||||
// BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
|
||||
// TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce);
|
||||
// byte[] requestBytes = request.getEncoded();
|
||||
//
|
||||
// // Call the communications layer
|
||||
// respBytes = getTSAResponse(requestBytes);
|
||||
//
|
||||
// // Handle the TSA response
|
||||
// TimeStampResponse response = new TimeStampResponse(respBytes);
|
||||
//
|
||||
// // validate communication level attributes (RFC 3161 PKIStatus)
|
||||
// response.validate(request);
|
||||
// PKIFailureInfo failure = response.getFailInfo();
|
||||
// int value = (failure == null) ? 0 : failure.intValue();
|
||||
// if (value != 0) {
|
||||
// // @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
|
||||
// throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value);
|
||||
// }
|
||||
// // @todo: validate the time stap certificate chain (if we want
|
||||
// // assure we do not sign using an invalid timestamp).
|
||||
//
|
||||
// // extract just the time stamp token (removes communication status info)
|
||||
// TimeStampToken tsToken = response.getTimeStampToken();
|
||||
// if (tsToken == null) {
|
||||
// throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString());
|
||||
// }
|
||||
// TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details
|
||||
// byte[] encoded = tsToken.getEncoded();
|
||||
// long stop = System.currentTimeMillis();
|
||||
//
|
||||
// // Update our token size estimate for the next call (padded to be safe)
|
||||
// this.tokSzEstimate = encoded.length + 32;
|
||||
// return encoded;
|
||||
// } catch (Exception e) {
|
||||
// throw e;
|
||||
// } catch (Throwable t) {
|
||||
// throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get timestamp token - communications layer
|
||||
// * @return - byte[] - TSA response, raw bytes (RFC 3161 encoded)
|
||||
// */
|
||||
// protected byte[] getTSAResponse(byte[] requestBytes) throws Exception {
|
||||
// // Setup the TSA connection
|
||||
// URL url = new URL(tsaURL);
|
||||
// URLConnection tsaConnection;
|
||||
// tsaConnection = (URLConnection) url.openConnection();
|
||||
//
|
||||
// tsaConnection.setDoInput(true);
|
||||
// tsaConnection.setDoOutput(true);
|
||||
// tsaConnection.setUseCaches(false);
|
||||
// tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query");
|
||||
// //tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64");
|
||||
// tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary");
|
||||
//
|
||||
// if ((tsaUsername != null) && !tsaUsername.equals("") ) {
|
||||
// String userPassword = tsaUsername + ":" + tsaPassword;
|
||||
// tsaConnection.setRequestProperty("Authorization", "Basic " +
|
||||
// new String(Base64.encodeBytes(userPassword.getBytes())));
|
||||
// }
|
||||
// OutputStream out = tsaConnection.getOutputStream();
|
||||
// out.write(requestBytes);
|
||||
// out.close();
|
||||
//
|
||||
// // Get TSA response as a byte array
|
||||
// InputStream inp = tsaConnection.getInputStream();
|
||||
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
// byte[] buffer = new byte[1024];
|
||||
// int bytesRead = 0;
|
||||
// while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) {
|
||||
// baos.write(buffer, 0, bytesRead);
|
||||
// }
|
||||
// byte[] respBytes = baos.toByteArray();
|
||||
//
|
||||
// String encoding = tsaConnection.getContentEncoding();
|
||||
// if (encoding != null && encoding.equalsIgnoreCase("base64")) {
|
||||
// respBytes = Base64.decode(new String(respBytes));
|
||||
// }
|
||||
// return respBytes;
|
||||
// }
|
||||
//}
|
@ -0,0 +1,74 @@
|
||||
package com.fr.third.com.lowagie.text.pdf; |
||||
|
||||
import com.fr.third.com.lowagie.text.Document; |
||||
import com.fr.third.com.lowagie.text.DocumentException; |
||||
import com.fr.third.com.lowagie.text.Paragraph; |
||||
import com.fr.third.com.lowagie.text.exceptions.BadPasswordException; |
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
import org.junit.Test; |
||||
|
||||
import static junit.framework.TestCase.assertTrue; |
||||
import static org.junit.Assert.fail; |
||||
|
||||
/** |
||||
* @author Hugh.C 不在打包范围内,只是留个凭证,需要自己添加junit 依赖才能跑 |
||||
* @version 1.0 |
||||
* Created by Hugh.C on 2020/4/28 |
||||
*/ |
||||
public class PdfEncryptDecryptTest { |
||||
|
||||
@Test |
||||
public void testPdfEncryption() { |
||||
|
||||
try { |
||||
byte[] bytes = createPdfEncryptionDocumentByteArray("123"); |
||||
assertTrue(bytes.length > 0); |
||||
} catch (Exception e) { |
||||
fail(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void testPdfDecrypt() { |
||||
|
||||
try { |
||||
//沒報錯,解密成功
|
||||
new PdfReader(createPdfEncryptionDocumentByteArray("123"), "123".getBytes()); |
||||
} catch (Exception e) { |
||||
fail(); |
||||
} |
||||
|
||||
boolean result = false; |
||||
try { |
||||
//報錯,解密失敗
|
||||
new PdfReader(createPdfEncryptionDocumentByteArray("123"), "234".getBytes()); |
||||
} catch (Exception e) { |
||||
assertTrue(e instanceof BadPasswordException); |
||||
result = true; |
||||
} |
||||
assertTrue(result); |
||||
} |
||||
|
||||
/** |
||||
* 創建加密過後的pdf document 數組 |
||||
* |
||||
* @param passWord pdf密碼 |
||||
* @return |
||||
* @throws DocumentException |
||||
* @throws IOException |
||||
*/ |
||||
private byte[] createPdfEncryptionDocumentByteArray(String passWord) throws DocumentException, IOException { |
||||
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream(); |
||||
Document document = new Document(); |
||||
PdfWriter write = PdfWriter.getInstance(document, byteOutputStream); |
||||
String userPassword = "老王"; |
||||
write.setEncryption(userPassword.getBytes(), passWord.getBytes(), PdfWriter.ALLOW_ASSEMBLY, PdfWriter.ENCRYPTION_AES_128); |
||||
document.open(); |
||||
document.add(new Paragraph("ABCDEFG")); |
||||
document.close(); |
||||
write.close(); |
||||
byteOutputStream.flush(); |
||||
return byteOutputStream.toByteArray(); |
||||
} |
||||
} |
@ -1,185 +1,185 @@
|
||||
/* |
||||
* $Id: OcspClientBouncyCastle.java 3959 2009-06-09 08:31:05Z blowagie $ |
||||
* |
||||
* Copyright 2009 Paulo Soares |
||||
* |
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
||||
* (the "License"); you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
* |
||||
* Software distributed under the License is distributed on an "AS IS" basis, |
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
||||
* for the specific language governing rights and limitations under the License. |
||||
* |
||||
* The Original Code is 'iText, a free JAVA-PDF library'. |
||||
* |
||||
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by |
||||
* the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. |
||||
* All Rights Reserved. |
||||
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer |
||||
* are Copyright (C) 2009 by Paulo Soares. All Rights Reserved. |
||||
* |
||||
* Contributor(s): all the names of the contributors are added in the source code |
||||
* where applicable. |
||||
* |
||||
* Alternatively, the contents of this file may be used under the terms of the |
||||
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the |
||||
* provisions of LGPL are applicable instead of those above. If you wish to |
||||
* allow use of your version of this file only under the terms of the LGPL |
||||
* License and not to allow others to use your version of this file under |
||||
* the MPL, indicate your decision by deleting the provisions above and |
||||
* replace them with the notice and other provisions required by the LGPL. |
||||
* If you do not delete the provisions above, a recipient may use your version |
||||
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. |
||||
* |
||||
* This library is free software; you can redistribute it and/or modify it |
||||
* under the terms of the MPL as stated above or under the terms of the GNU |
||||
* Library General Public License as published by the Free Software Foundation; |
||||
* either version 2 of the License, or any later version. |
||||
* |
||||
* This library is distributed in the hope that it will be useful, but WITHOUT |
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||||
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more |
||||
* details. |
||||
* |
||||
* If you didn't download this code from the following link, you should check if |
||||
* you aren't using an obsolete version: |
||||
* http://www.lowagie.com/iText/
|
||||
*/ |
||||
|
||||
package com.fr.third.v2.lowagie.text.pdf; |
||||
|
||||
import com.fr.third.v2.lowagie.text.ExceptionConverter; |
||||
|
||||
import java.io.BufferedOutputStream; |
||||
import java.io.DataOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
import java.math.BigInteger; |
||||
import java.net.HttpURLConnection; |
||||
import java.net.URL; |
||||
import java.security.Security; |
||||
import java.security.cert.X509Certificate; |
||||
import java.util.Vector; |
||||
import org.bouncycastle.asn1.DEROctetString; |
||||
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; |
||||
import org.bouncycastle.asn1.x509.X509Extension; |
||||
import org.bouncycastle.asn1.x509.X509Extensions; |
||||
import org.bouncycastle.ocsp.BasicOCSPResp; |
||||
import org.bouncycastle.ocsp.CertificateID; |
||||
import org.bouncycastle.ocsp.CertificateStatus; |
||||
import org.bouncycastle.ocsp.OCSPException; |
||||
import org.bouncycastle.ocsp.OCSPReq; |
||||
import org.bouncycastle.ocsp.OCSPReqGenerator; |
||||
import org.bouncycastle.ocsp.OCSPResp; |
||||
import org.bouncycastle.ocsp.SingleResp; |
||||
|
||||
/** |
||||
* OcspClient implementation using BouncyCastle. |
||||
* @author psoares |
||||
* @since 2.1.6 |
||||
*/ |
||||
public class OcspClientBouncyCastle implements OcspClient { |
||||
/** root certificate */ |
||||
private X509Certificate rootCert; |
||||
/** check certificate */ |
||||
private X509Certificate checkCert; |
||||
/** OCSP URL */ |
||||
private String url; |
||||
|
||||
/** |
||||
* Creates an instance of an OcspClient that will be using BouncyCastle. |
||||
* @param checkCert the check certificate |
||||
* @param rootCert the root certificate |
||||
* @param url the OCSP URL |
||||
*/ |
||||
public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) { |
||||
this.checkCert = checkCert; |
||||
this.rootCert = rootCert; |
||||
this.url = url; |
||||
} |
||||
|
||||
/** |
||||
* Generates an OCSP request using BouncyCastle. |
||||
* @param issuerCert certificate of the issues |
||||
* @param serialNumber serial number |
||||
* @return an OCSP request |
||||
* @throws OCSPException |
||||
* @throws IOException |
||||
*/ |
||||
private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException { |
||||
//Add provider BC
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); |
||||
|
||||
// Generate the id for the certificate we are looking for
|
||||
CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber); |
||||
|
||||
// basic request generation with nonce
|
||||
OCSPReqGenerator gen = new OCSPReqGenerator(); |
||||
|
||||
gen.addRequest(id); |
||||
|
||||
// create details for nonce extension
|
||||
Vector oids = new Vector(); |
||||
Vector values = new Vector(); |
||||
|
||||
oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); |
||||
values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded()))); |
||||
|
||||
gen.setRequestExtensions(new X509Extensions(oids, values)); |
||||
|
||||
return gen.generate(); |
||||
} |
||||
|
||||
/** |
||||
* @return a byte array |
||||
* @see OcspClient#getEncoded() |
||||
*/ |
||||
public byte[] getEncoded() { |
||||
try { |
||||
OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber()); |
||||
byte[] array = request.getEncoded(); |
||||
URL urlt = new URL(url); |
||||
HttpURLConnection con = (HttpURLConnection)urlt.openConnection(); |
||||
con.setRequestProperty("Content-Type", "application/ocsp-request"); |
||||
con.setRequestProperty("Accept", "application/ocsp-response"); |
||||
con.setDoOutput(true); |
||||
OutputStream out = con.getOutputStream(); |
||||
DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out)); |
||||
dataOut.write(array); |
||||
dataOut.flush(); |
||||
dataOut.close(); |
||||
if (con.getResponseCode() / 100 != 2) { |
||||
throw new IOException("Invalid HTTP response"); |
||||
} |
||||
//Get Response
|
||||
InputStream in = (InputStream) con.getContent(); |
||||
OCSPResp ocspResponse = new OCSPResp(in); |
||||
|
||||
if (ocspResponse.getStatus() != 0) |
||||
throw new IOException("Invalid status: " + ocspResponse.getStatus()); |
||||
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject(); |
||||
if (basicResponse != null) { |
||||
SingleResp[] responses = basicResponse.getResponses(); |
||||
if (responses.length == 1) { |
||||
SingleResp resp = responses[0]; |
||||
Object status = resp.getCertStatus(); |
||||
if (status == CertificateStatus.GOOD) { |
||||
return basicResponse.getEncoded(); |
||||
} |
||||
else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) { |
||||
throw new IOException("OCSP Status is revoked!"); |
||||
} |
||||
else { |
||||
throw new IOException("OCSP Status is unknown!"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
catch (Exception ex) { |
||||
throw new ExceptionConverter(ex); |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
///*
|
||||
// * $Id: OcspClientBouncyCastle.java 3959 2009-06-09 08:31:05Z blowagie $
|
||||
// *
|
||||
// * Copyright 2009 Paulo Soares
|
||||
// *
|
||||
// * The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
// * (the "License"); you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
// *
|
||||
// * Software distributed under the License is distributed on an "AS IS" basis,
|
||||
// * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
// * for the specific language governing rights and limitations under the License.
|
||||
// *
|
||||
// * The Original Code is 'iText, a free JAVA-PDF library'.
|
||||
// *
|
||||
// * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
|
||||
// * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
|
||||
// * All Rights Reserved.
|
||||
// * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
|
||||
// * are Copyright (C) 2009 by Paulo Soares. All Rights Reserved.
|
||||
// *
|
||||
// * Contributor(s): all the names of the contributors are added in the source code
|
||||
// * where applicable.
|
||||
// *
|
||||
// * Alternatively, the contents of this file may be used under the terms of the
|
||||
// * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
|
||||
// * provisions of LGPL are applicable instead of those above. If you wish to
|
||||
// * allow use of your version of this file only under the terms of the LGPL
|
||||
// * License and not to allow others to use your version of this file under
|
||||
// * the MPL, indicate your decision by deleting the provisions above and
|
||||
// * replace them with the notice and other provisions required by the LGPL.
|
||||
// * If you do not delete the provisions above, a recipient may use your version
|
||||
// * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
|
||||
// *
|
||||
// * This library is free software; you can redistribute it and/or modify it
|
||||
// * under the terms of the MPL as stated above or under the terms of the GNU
|
||||
// * Library General Public License as published by the Free Software Foundation;
|
||||
// * either version 2 of the License, or any later version.
|
||||
// *
|
||||
// * This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
|
||||
// * details.
|
||||
// *
|
||||
// * If you didn't download this code from the following link, you should check if
|
||||
// * you aren't using an obsolete version:
|
||||
// * http://www.lowagie.com/iText/
|
||||
// */
|
||||
//
|
||||
//package com.fr.third.v2.lowagie.text.pdf;
|
||||
//
|
||||
//import com.fr.third.v2.lowagie.text.ExceptionConverter;
|
||||
//
|
||||
//import java.io.BufferedOutputStream;
|
||||
//import java.io.DataOutputStream;
|
||||
//import java.io.IOException;
|
||||
//import java.io.InputStream;
|
||||
//import java.io.OutputStream;
|
||||
//import java.math.BigInteger;
|
||||
//import java.net.HttpURLConnection;
|
||||
//import java.net.URL;
|
||||
//import java.security.Security;
|
||||
//import java.security.cert.X509Certificate;
|
||||
//import java.util.Vector;
|
||||
//import org.bouncycastle.asn1.DEROctetString;
|
||||
//import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
|
||||
//import org.bouncycastle.asn1.x509.X509Extension;
|
||||
//import org.bouncycastle.asn1.x509.X509Extensions;
|
||||
//import org.bouncycastle.ocsp.BasicOCSPResp;
|
||||
//import org.bouncycastle.ocsp.CertificateID;
|
||||
//import org.bouncycastle.ocsp.CertificateStatus;
|
||||
//import org.bouncycastle.ocsp.OCSPException;
|
||||
//import org.bouncycastle.ocsp.OCSPReq;
|
||||
//import org.bouncycastle.ocsp.OCSPReqGenerator;
|
||||
//import org.bouncycastle.ocsp.OCSPResp;
|
||||
//import org.bouncycastle.ocsp.SingleResp;
|
||||
//
|
||||
///**
|
||||
// * OcspClient implementation using BouncyCastle.
|
||||
// * @author psoares
|
||||
// * @since 2.1.6
|
||||
// */
|
||||
//public class OcspClientBouncyCastle implements OcspClient {
|
||||
// /** root certificate */
|
||||
// private X509Certificate rootCert;
|
||||
// /** check certificate */
|
||||
// private X509Certificate checkCert;
|
||||
// /** OCSP URL */
|
||||
// private String url;
|
||||
//
|
||||
// /**
|
||||
// * Creates an instance of an OcspClient that will be using BouncyCastle.
|
||||
// * @param checkCert the check certificate
|
||||
// * @param rootCert the root certificate
|
||||
// * @param url the OCSP URL
|
||||
// */
|
||||
// public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) {
|
||||
// this.checkCert = checkCert;
|
||||
// this.rootCert = rootCert;
|
||||
// this.url = url;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Generates an OCSP request using BouncyCastle.
|
||||
// * @param issuerCert certificate of the issues
|
||||
// * @param serialNumber serial number
|
||||
// * @return an OCSP request
|
||||
// * @throws OCSPException
|
||||
// * @throws IOException
|
||||
// */
|
||||
// private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException {
|
||||
// //Add provider BC
|
||||
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
//
|
||||
// // Generate the id for the certificate we are looking for
|
||||
// CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber);
|
||||
//
|
||||
// // basic request generation with nonce
|
||||
// OCSPReqGenerator gen = new OCSPReqGenerator();
|
||||
//
|
||||
// gen.addRequest(id);
|
||||
//
|
||||
// // create details for nonce extension
|
||||
// Vector oids = new Vector();
|
||||
// Vector values = new Vector();
|
||||
//
|
||||
// oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
|
||||
// values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded())));
|
||||
//
|
||||
// gen.setRequestExtensions(new X509Extensions(oids, values));
|
||||
//
|
||||
// return gen.generate();
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return a byte array
|
||||
// * @see OcspClient#getEncoded()
|
||||
// */
|
||||
// public byte[] getEncoded() {
|
||||
// try {
|
||||
// OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber());
|
||||
// byte[] array = request.getEncoded();
|
||||
// URL urlt = new URL(url);
|
||||
// HttpURLConnection con = (HttpURLConnection)urlt.openConnection();
|
||||
// con.setRequestProperty("Content-Type", "application/ocsp-request");
|
||||
// con.setRequestProperty("Accept", "application/ocsp-response");
|
||||
// con.setDoOutput(true);
|
||||
// OutputStream out = con.getOutputStream();
|
||||
// DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out));
|
||||
// dataOut.write(array);
|
||||
// dataOut.flush();
|
||||
// dataOut.close();
|
||||
// if (con.getResponseCode() / 100 != 2) {
|
||||
// throw new IOException("Invalid HTTP response");
|
||||
// }
|
||||
// //Get Response
|
||||
// InputStream in = (InputStream) con.getContent();
|
||||
// OCSPResp ocspResponse = new OCSPResp(in);
|
||||
//
|
||||
// if (ocspResponse.getStatus() != 0)
|
||||
// throw new IOException("Invalid status: " + ocspResponse.getStatus());
|
||||
// BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
|
||||
// if (basicResponse != null) {
|
||||
// SingleResp[] responses = basicResponse.getResponses();
|
||||
// if (responses.length == 1) {
|
||||
// SingleResp resp = responses[0];
|
||||
// Object status = resp.getCertStatus();
|
||||
// if (status == CertificateStatus.GOOD) {
|
||||
// return basicResponse.getEncoded();
|
||||
// }
|
||||
// else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) {
|
||||
// throw new IOException("OCSP Status is revoked!");
|
||||
// }
|
||||
// else {
|
||||
// throw new IOException("OCSP Status is unknown!");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex) {
|
||||
// throw new ExceptionConverter(ex);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
|
@ -1,230 +1,230 @@
|
||||
/* |
||||
* $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $ |
||||
* |
||||
* Copyright 2009 Martin Brunecky, Aiken Sam |
||||
* |
||||
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
||||
* (the "License"); you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
* |
||||
* Software distributed under the License is distributed on an "AS IS" basis, |
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
||||
* for the specific language governing rights and limitations under the License. |
||||
* |
||||
* The Original Code is 'iText, a free JAVA-PDF library'. |
||||
* |
||||
* The Initial Developer of the Original Code is Bruno Lowagie. Portions created by |
||||
* the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. |
||||
* All Rights Reserved. |
||||
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer |
||||
* are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved. |
||||
* |
||||
* Contributor(s): all the names of the contributors are added in the source code |
||||
* where applicable. |
||||
* |
||||
* Alternatively, the contents of this file may be used under the terms of the |
||||
* LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the |
||||
* provisions of LGPL are applicable instead of those above. If you wish to |
||||
* allow use of your version of this file only under the terms of the LGPL |
||||
* License and not to allow others to use your version of this file under |
||||
* the MPL, indicate your decision by deleting the provisions above and |
||||
* replace them with the notice and other provisions required by the LGPL. |
||||
* If you do not delete the provisions above, a recipient may use your version |
||||
* of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. |
||||
* |
||||
* This library is free software; you can redistribute it and/or modify it |
||||
* under the terms of the MPL as stated above or under the terms of the GNU |
||||
* Library General Public License as published by the Free Software Foundation; |
||||
* either version 2 of the License, or any later version. |
||||
* |
||||
* This library is distributed in the hope that it will be useful, but WITHOUT |
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||||
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more |
||||
* details. |
||||
* |
||||
* If you didn't download this code from the following link, you should check if |
||||
* you aren't using an obsolete version: |
||||
* http://www.lowagie.com/iText/
|
||||
*/ |
||||
|
||||
package com.fr.third.v2.lowagie.text.pdf; |
||||
|
||||
import java.io.*; |
||||
import java.math.*; |
||||
import java.net.*; |
||||
|
||||
import org.bouncycastle.asn1.cmp.*; |
||||
import org.bouncycastle.asn1.x509.*; |
||||
import org.bouncycastle.tsp.*; |
||||
|
||||
import com.fr.third.v2.lowagie.text.pdf.codec.Base64; |
||||
|
||||
/** |
||||
* Time Stamp Authority Client interface implementation using Bouncy Castle |
||||
* org.bouncycastle.tsp package. |
||||
* <p> |
||||
* Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007 |
||||
* for ease of subclassing. |
||||
* </p> |
||||
* @since 2.1.6 |
||||
*/ |
||||
public class TSAClientBouncyCastle implements TSAClient { |
||||
/** URL of the Time Stamp Authority */ |
||||
protected String tsaURL; |
||||
/** TSA Username */ |
||||
protected String tsaUsername; |
||||
/** TSA password */ |
||||
protected String tsaPassword; |
||||
/** Estimate of the received time stamp token */ |
||||
protected int tokSzEstimate; |
||||
|
||||
/** |
||||
* Creates an instance of a TSAClient that will use BouncyCastle. |
||||
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") |
||||
*/ |
||||
public TSAClientBouncyCastle(String url) { |
||||
this(url, null, null, 4096); |
||||
} |
||||
|
||||
/** |
||||
* Creates an instance of a TSAClient that will use BouncyCastle. |
||||
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") |
||||
* @param username String - user(account) name |
||||
* @param password String - password |
||||
*/ |
||||
public TSAClientBouncyCastle(String url, String username, String password) { |
||||
this(url, username, password, 4096); |
||||
} |
||||
|
||||
/** |
||||
* Constructor. |
||||
* Note the token size estimate is updated by each call, as the token |
||||
* size is not likely to change (as long as we call the same TSA using |
||||
* the same imprint length). |
||||
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") |
||||
* @param username String - user(account) name |
||||
* @param password String - password |
||||
* @param tokSzEstimate int - estimated size of received time stamp token (DER encoded) |
||||
*/ |
||||
public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) { |
||||
this.tsaURL = url; |
||||
this.tsaUsername = username; |
||||
this.tsaPassword = password; |
||||
this.tokSzEstimate = tokSzEstimate; |
||||
} |
||||
|
||||
/** |
||||
* Get the token size estimate. |
||||
* Returned value reflects the result of the last succesfull call, padded |
||||
* @return an estimate of the token size |
||||
*/ |
||||
public int getTokenSizeEstimate() { |
||||
return tokSzEstimate; |
||||
} |
||||
|
||||
/** |
||||
* Get RFC 3161 timeStampToken. |
||||
* Method may return null indicating that timestamp should be skipped. |
||||
* @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it) |
||||
* @param imprint byte[] - data imprint to be time-stamped |
||||
* @return byte[] - encoded, TSA signed data of the timeStampToken |
||||
* @throws Exception - TSA request failed |
||||
* @see TSAClient#getTimeStampToken(PdfPKCS7, byte[]) |
||||
*/ |
||||
public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception { |
||||
return getTimeStampToken(imprint); |
||||
} |
||||
|
||||
/** |
||||
* Get timestamp token - Bouncy Castle request encoding / decoding layer |
||||
*/ |
||||
protected byte[] getTimeStampToken(byte[] imprint) throws Exception { |
||||
byte[] respBytes = null; |
||||
try { |
||||
// Setup the time stamp request
|
||||
TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator(); |
||||
tsqGenerator.setCertReq(true); |
||||
// tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
|
||||
BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis()); |
||||
TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce); |
||||
byte[] requestBytes = request.getEncoded(); |
||||
|
||||
// Call the communications layer
|
||||
respBytes = getTSAResponse(requestBytes); |
||||
|
||||
// Handle the TSA response
|
||||
TimeStampResponse response = new TimeStampResponse(respBytes); |
||||
|
||||
// validate communication level attributes (RFC 3161 PKIStatus)
|
||||
response.validate(request); |
||||
PKIFailureInfo failure = response.getFailInfo(); |
||||
int value = (failure == null) ? 0 : failure.intValue(); |
||||
if (value != 0) { |
||||
// @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
|
||||
throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value); |
||||
} |
||||
// @todo: validate the time stap certificate chain (if we want
|
||||
// assure we do not sign using an invalid timestamp).
|
||||
|
||||
// extract just the time stamp token (removes communication status info)
|
||||
TimeStampToken tsToken = response.getTimeStampToken(); |
||||
if (tsToken == null) { |
||||
throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString()); |
||||
} |
||||
TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details
|
||||
byte[] encoded = tsToken.getEncoded(); |
||||
long stop = System.currentTimeMillis(); |
||||
|
||||
// Update our token size estimate for the next call (padded to be safe)
|
||||
this.tokSzEstimate = encoded.length + 32; |
||||
return encoded; |
||||
} catch (Exception e) { |
||||
throw e; |
||||
} catch (Throwable t) { |
||||
throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Get timestamp token - communications layer |
||||
* @return - byte[] - TSA response, raw bytes (RFC 3161 encoded) |
||||
*/ |
||||
protected byte[] getTSAResponse(byte[] requestBytes) throws Exception { |
||||
// Setup the TSA connection
|
||||
URL url = new URL(tsaURL); |
||||
URLConnection tsaConnection; |
||||
tsaConnection = (URLConnection) url.openConnection(); |
||||
|
||||
tsaConnection.setDoInput(true); |
||||
tsaConnection.setDoOutput(true); |
||||
tsaConnection.setUseCaches(false); |
||||
tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query"); |
||||
//tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64");
|
||||
tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary"); |
||||
|
||||
if ((tsaUsername != null) && !tsaUsername.equals("") ) { |
||||
String userPassword = tsaUsername + ":" + tsaPassword; |
||||
tsaConnection.setRequestProperty("Authorization", "Basic " + |
||||
new String(Base64.encodeBytes(userPassword.getBytes()))); |
||||
} |
||||
OutputStream out = tsaConnection.getOutputStream(); |
||||
out.write(requestBytes); |
||||
out.close(); |
||||
|
||||
// Get TSA response as a byte array
|
||||
InputStream inp = tsaConnection.getInputStream(); |
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
||||
byte[] buffer = new byte[1024]; |
||||
int bytesRead = 0; |
||||
while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) { |
||||
baos.write(buffer, 0, bytesRead); |
||||
} |
||||
byte[] respBytes = baos.toByteArray(); |
||||
|
||||
String encoding = tsaConnection.getContentEncoding(); |
||||
if (encoding != null && encoding.equalsIgnoreCase("base64")) { |
||||
respBytes = Base64.decode(new String(respBytes)); |
||||
} |
||||
return respBytes; |
||||
} |
||||
} |
||||
///*
|
||||
// * $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $
|
||||
// *
|
||||
// * Copyright 2009 Martin Brunecky, Aiken Sam
|
||||
// *
|
||||
// * The contents of this file are subject to the Mozilla Public License Version 1.1
|
||||
// * (the "License"); you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
||||
// *
|
||||
// * Software distributed under the License is distributed on an "AS IS" basis,
|
||||
// * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
// * for the specific language governing rights and limitations under the License.
|
||||
// *
|
||||
// * The Original Code is 'iText, a free JAVA-PDF library'.
|
||||
// *
|
||||
// * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
|
||||
// * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
|
||||
// * All Rights Reserved.
|
||||
// * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
|
||||
// * are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved.
|
||||
// *
|
||||
// * Contributor(s): all the names of the contributors are added in the source code
|
||||
// * where applicable.
|
||||
// *
|
||||
// * Alternatively, the contents of this file may be used under the terms of the
|
||||
// * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
|
||||
// * provisions of LGPL are applicable instead of those above. If you wish to
|
||||
// * allow use of your version of this file only under the terms of the LGPL
|
||||
// * License and not to allow others to use your version of this file under
|
||||
// * the MPL, indicate your decision by deleting the provisions above and
|
||||
// * replace them with the notice and other provisions required by the LGPL.
|
||||
// * If you do not delete the provisions above, a recipient may use your version
|
||||
// * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
|
||||
// *
|
||||
// * This library is free software; you can redistribute it and/or modify it
|
||||
// * under the terms of the MPL as stated above or under the terms of the GNU
|
||||
// * Library General Public License as published by the Free Software Foundation;
|
||||
// * either version 2 of the License, or any later version.
|
||||
// *
|
||||
// * This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
|
||||
// * details.
|
||||
// *
|
||||
// * If you didn't download this code from the following link, you should check if
|
||||
// * you aren't using an obsolete version:
|
||||
// * http://www.lowagie.com/iText/
|
||||
// */
|
||||
//
|
||||
//package com.fr.third.v2.lowagie.text.pdf;
|
||||
//
|
||||
//import java.io.*;
|
||||
//import java.math.*;
|
||||
//import java.net.*;
|
||||
//
|
||||
//import org.bouncycastle.asn1.cmp.*;
|
||||
//import org.bouncycastle.asn1.x509.*;
|
||||
//import org.bouncycastle.tsp.*;
|
||||
//
|
||||
//import com.fr.third.v2.lowagie.text.pdf.codec.Base64;
|
||||
//
|
||||
///**
|
||||
// * Time Stamp Authority Client interface implementation using Bouncy Castle
|
||||
// * org.bouncycastle.tsp package.
|
||||
// * <p>
|
||||
// * Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007
|
||||
// * for ease of subclassing.
|
||||
// * </p>
|
||||
// * @since 2.1.6
|
||||
// */
|
||||
//public class TSAClientBouncyCastle implements TSAClient {
|
||||
// /** URL of the Time Stamp Authority */
|
||||
// protected String tsaURL;
|
||||
// /** TSA Username */
|
||||
// protected String tsaUsername;
|
||||
// /** TSA password */
|
||||
// protected String tsaPassword;
|
||||
// /** Estimate of the received time stamp token */
|
||||
// protected int tokSzEstimate;
|
||||
//
|
||||
// /**
|
||||
// * Creates an instance of a TSAClient that will use BouncyCastle.
|
||||
// * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||
// */
|
||||
// public TSAClientBouncyCastle(String url) {
|
||||
// this(url, null, null, 4096);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Creates an instance of a TSAClient that will use BouncyCastle.
|
||||
// * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||
// * @param username String - user(account) name
|
||||
// * @param password String - password
|
||||
// */
|
||||
// public TSAClientBouncyCastle(String url, String username, String password) {
|
||||
// this(url, username, password, 4096);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Constructor.
|
||||
// * Note the token size estimate is updated by each call, as the token
|
||||
// * size is not likely to change (as long as we call the same TSA using
|
||||
// * the same imprint length).
|
||||
// * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||
// * @param username String - user(account) name
|
||||
// * @param password String - password
|
||||
// * @param tokSzEstimate int - estimated size of received time stamp token (DER encoded)
|
||||
// */
|
||||
// public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) {
|
||||
// this.tsaURL = url;
|
||||
// this.tsaUsername = username;
|
||||
// this.tsaPassword = password;
|
||||
// this.tokSzEstimate = tokSzEstimate;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get the token size estimate.
|
||||
// * Returned value reflects the result of the last succesfull call, padded
|
||||
// * @return an estimate of the token size
|
||||
// */
|
||||
// public int getTokenSizeEstimate() {
|
||||
// return tokSzEstimate;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get RFC 3161 timeStampToken.
|
||||
// * Method may return null indicating that timestamp should be skipped.
|
||||
// * @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it)
|
||||
// * @param imprint byte[] - data imprint to be time-stamped
|
||||
// * @return byte[] - encoded, TSA signed data of the timeStampToken
|
||||
// * @throws Exception - TSA request failed
|
||||
// * @see TSAClient#getTimeStampToken(PdfPKCS7, byte[])
|
||||
// */
|
||||
// public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception {
|
||||
// return getTimeStampToken(imprint);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get timestamp token - Bouncy Castle request encoding / decoding layer
|
||||
// */
|
||||
// protected byte[] getTimeStampToken(byte[] imprint) throws Exception {
|
||||
// byte[] respBytes = null;
|
||||
// try {
|
||||
// // Setup the time stamp request
|
||||
// TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator();
|
||||
// tsqGenerator.setCertReq(true);
|
||||
// // tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
|
||||
// BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
|
||||
// TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce);
|
||||
// byte[] requestBytes = request.getEncoded();
|
||||
//
|
||||
// // Call the communications layer
|
||||
// respBytes = getTSAResponse(requestBytes);
|
||||
//
|
||||
// // Handle the TSA response
|
||||
// TimeStampResponse response = new TimeStampResponse(respBytes);
|
||||
//
|
||||
// // validate communication level attributes (RFC 3161 PKIStatus)
|
||||
// response.validate(request);
|
||||
// PKIFailureInfo failure = response.getFailInfo();
|
||||
// int value = (failure == null) ? 0 : failure.intValue();
|
||||
// if (value != 0) {
|
||||
// // @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
|
||||
// throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value);
|
||||
// }
|
||||
// // @todo: validate the time stap certificate chain (if we want
|
||||
// // assure we do not sign using an invalid timestamp).
|
||||
//
|
||||
// // extract just the time stamp token (removes communication status info)
|
||||
// TimeStampToken tsToken = response.getTimeStampToken();
|
||||
// if (tsToken == null) {
|
||||
// throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString());
|
||||
// }
|
||||
// TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details
|
||||
// byte[] encoded = tsToken.getEncoded();
|
||||
// long stop = System.currentTimeMillis();
|
||||
//
|
||||
// // Update our token size estimate for the next call (padded to be safe)
|
||||
// this.tokSzEstimate = encoded.length + 32;
|
||||
// return encoded;
|
||||
// } catch (Exception e) {
|
||||
// throw e;
|
||||
// } catch (Throwable t) {
|
||||
// throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get timestamp token - communications layer
|
||||
// * @return - byte[] - TSA response, raw bytes (RFC 3161 encoded)
|
||||
// */
|
||||
// protected byte[] getTSAResponse(byte[] requestBytes) throws Exception {
|
||||
// // Setup the TSA connection
|
||||
// URL url = new URL(tsaURL);
|
||||
// URLConnection tsaConnection;
|
||||
// tsaConnection = (URLConnection) url.openConnection();
|
||||
//
|
||||
// tsaConnection.setDoInput(true);
|
||||
// tsaConnection.setDoOutput(true);
|
||||
// tsaConnection.setUseCaches(false);
|
||||
// tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query");
|
||||
// //tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64");
|
||||
// tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary");
|
||||
//
|
||||
// if ((tsaUsername != null) && !tsaUsername.equals("") ) {
|
||||
// String userPassword = tsaUsername + ":" + tsaPassword;
|
||||
// tsaConnection.setRequestProperty("Authorization", "Basic " +
|
||||
// new String(Base64.encodeBytes(userPassword.getBytes())));
|
||||
// }
|
||||
// OutputStream out = tsaConnection.getOutputStream();
|
||||
// out.write(requestBytes);
|
||||
// out.close();
|
||||
//
|
||||
// // Get TSA response as a byte array
|
||||
// InputStream inp = tsaConnection.getInputStream();
|
||||
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
// byte[] buffer = new byte[1024];
|
||||
// int bytesRead = 0;
|
||||
// while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) {
|
||||
// baos.write(buffer, 0, bytesRead);
|
||||
// }
|
||||
// byte[] respBytes = baos.toByteArray();
|
||||
//
|
||||
// String encoding = tsaConnection.getContentEncoding();
|
||||
// if (encoding != null && encoding.equalsIgnoreCase("base64")) {
|
||||
// respBytes = Base64.decode(new String(respBytes));
|
||||
// }
|
||||
// return respBytes;
|
||||
// }
|
||||
//}
|
Loading…
Reference in new issue