Browse Source
* commit '6554afe92b2a73ea215074b4f8d6c04920492ee0': REPORT-30379 test补充注释 REPORT-30379 在third中加一个 third(不在打包范围内,需要自己添加junit依赖才能跑) REPORT-30379 bouncycastle存在安全问题,fine-itext、fine-itext-old 适配高版本release/10.0
Hugh.C
5 years ago
13 changed files with 1268 additions and 1192 deletions
@ -1,184 +1,184 @@ |
|||||||
/* |
///*
|
||||||
* $Id: OcspClientBouncyCastle.java 3959 2009-06-09 08:31:05Z blowagie $ |
// * $Id: OcspClientBouncyCastle.java 3959 2009-06-09 08:31:05Z blowagie $
|
||||||
* |
// *
|
||||||
* Copyright 2009 Paulo Soares |
// * Copyright 2009 Paulo Soares
|
||||||
* |
// *
|
||||||
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
// * 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. |
// * (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/
|
// * 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, |
// * Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
// * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
* for the specific language governing rights and limitations under the License. |
// * for the specific language governing rights and limitations under the License.
|
||||||
* |
// *
|
||||||
* The Original Code is 'iText, a free JAVA-PDF library'. |
// * 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 of the Original Code is Bruno Lowagie. Portions created by
|
||||||
* the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. |
// * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
|
||||||
* All Rights Reserved. |
// * All Rights Reserved.
|
||||||
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer |
// * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
|
||||||
* are Copyright (C) 2009 by Paulo Soares. All Rights Reserved. |
// * are Copyright (C) 2009 by Paulo Soares. All Rights Reserved.
|
||||||
* |
// *
|
||||||
* Contributor(s): all the names of the contributors are added in the source code |
// * Contributor(s): all the names of the contributors are added in the source code
|
||||||
* where applicable. |
// * where applicable.
|
||||||
* |
// *
|
||||||
* Alternatively, the contents of this file may be used under the terms of the |
// * 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 |
// * 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 |
// * 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 |
// * 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 |
// * 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 |
// * the MPL, indicate your decision by deleting the provisions above and
|
||||||
* replace them with the notice and other provisions required by the LGPL. |
// * 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 |
// * 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. |
// * 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 |
// * 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 |
// * 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; |
// * Library General Public License as published by the Free Software Foundation;
|
||||||
* either version 2 of the License, or any later version. |
// * either version 2 of the License, or any later version.
|
||||||
* |
// *
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT |
// * 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 |
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more |
// * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
|
||||||
* details. |
// * details.
|
||||||
* |
// *
|
||||||
* If you didn't download this code from the following link, you should check if |
// * If you didn't download this code from the following link, you should check if
|
||||||
* you aren't using an obsolete version: |
// * you aren't using an obsolete version:
|
||||||
* http://www.lowagie.com/iText/
|
// * http://www.lowagie.com/iText/
|
||||||
*/ |
// */
|
||||||
|
//
|
||||||
package com.fr.third.com.lowagie.text.pdf; |
//package com.fr.third.com.lowagie.text.pdf;
|
||||||
|
//
|
||||||
import com.fr.third.com.lowagie.text.ExceptionConverter; |
//import com.fr.third.com.lowagie.text.ExceptionConverter;
|
||||||
import java.io.BufferedOutputStream; |
//import java.io.BufferedOutputStream;
|
||||||
import java.io.DataOutputStream; |
//import java.io.DataOutputStream;
|
||||||
import java.io.IOException; |
//import java.io.IOException;
|
||||||
import java.io.InputStream; |
//import java.io.InputStream;
|
||||||
import java.io.OutputStream; |
//import java.io.OutputStream;
|
||||||
import java.math.BigInteger; |
//import java.math.BigInteger;
|
||||||
import java.net.HttpURLConnection; |
//import java.net.HttpURLConnection;
|
||||||
import java.net.URL; |
//import java.net.URL;
|
||||||
import java.security.Security; |
//import java.security.Security;
|
||||||
import java.security.cert.X509Certificate; |
//import java.security.cert.X509Certificate;
|
||||||
import java.util.Vector; |
//import java.util.Vector;
|
||||||
import org.bouncycastle.asn1.DEROctetString; |
//import org.bouncycastle.asn1.DEROctetString;
|
||||||
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; |
//import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
|
||||||
import org.bouncycastle.asn1.x509.X509Extension; |
//import org.bouncycastle.asn1.x509.X509Extension;
|
||||||
import org.bouncycastle.asn1.x509.X509Extensions; |
//import org.bouncycastle.asn1.x509.X509Extensions;
|
||||||
import org.bouncycastle.ocsp.BasicOCSPResp; |
//import org.bouncycastle.ocsp.BasicOCSPResp;
|
||||||
import org.bouncycastle.ocsp.CertificateID; |
//import org.bouncycastle.ocsp.CertificateID;
|
||||||
import org.bouncycastle.ocsp.CertificateStatus; |
//import org.bouncycastle.ocsp.CertificateStatus;
|
||||||
import org.bouncycastle.ocsp.OCSPException; |
//import org.bouncycastle.ocsp.OCSPException;
|
||||||
import org.bouncycastle.ocsp.OCSPReq; |
//import org.bouncycastle.ocsp.OCSPReq;
|
||||||
import org.bouncycastle.ocsp.OCSPReqGenerator; |
//import org.bouncycastle.ocsp.OCSPReqGenerator;
|
||||||
import org.bouncycastle.ocsp.OCSPResp; |
//import org.bouncycastle.ocsp.OCSPResp;
|
||||||
import org.bouncycastle.ocsp.SingleResp; |
//import org.bouncycastle.ocsp.SingleResp;
|
||||||
|
//
|
||||||
/** |
///**
|
||||||
* OcspClient implementation using BouncyCastle. |
// * OcspClient implementation using BouncyCastle.
|
||||||
* @author psoares |
// * @author psoares
|
||||||
* @since 2.1.6 |
// * @since 2.1.6
|
||||||
*/ |
// */
|
||||||
public class OcspClientBouncyCastle implements OcspClient { |
//public class OcspClientBouncyCastle implements OcspClient {
|
||||||
/** root certificate */ |
// /** root certificate */
|
||||||
private X509Certificate rootCert; |
// private X509Certificate rootCert;
|
||||||
/** check certificate */ |
// /** check certificate */
|
||||||
private X509Certificate checkCert; |
// private X509Certificate checkCert;
|
||||||
/** OCSP URL */ |
// /** OCSP URL */
|
||||||
private String url; |
// private String url;
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Creates an instance of an OcspClient that will be using BouncyCastle. |
// * Creates an instance of an OcspClient that will be using BouncyCastle.
|
||||||
* @param checkCert the check certificate |
// * @param checkCert the check certificate
|
||||||
* @param rootCert the root certificate |
// * @param rootCert the root certificate
|
||||||
* @param url the OCSP URL |
// * @param url the OCSP URL
|
||||||
*/ |
// */
|
||||||
public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) { |
// public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) {
|
||||||
this.checkCert = checkCert; |
// this.checkCert = checkCert;
|
||||||
this.rootCert = rootCert; |
// this.rootCert = rootCert;
|
||||||
this.url = url; |
// this.url = url;
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Generates an OCSP request using BouncyCastle. |
// * Generates an OCSP request using BouncyCastle.
|
||||||
* @param issuerCert certificate of the issues |
// * @param issuerCert certificate of the issues
|
||||||
* @param serialNumber serial number |
// * @param serialNumber serial number
|
||||||
* @return an OCSP request |
// * @return an OCSP request
|
||||||
* @throws OCSPException |
// * @throws OCSPException
|
||||||
* @throws IOException |
// * @throws IOException
|
||||||
*/ |
// */
|
||||||
private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException { |
// private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException {
|
||||||
//Add provider BC
|
// //Add provider BC
|
||||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); |
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||||
|
//
|
||||||
// Generate the id for the certificate we are looking for
|
// // Generate the id for the certificate we are looking for
|
||||||
CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber); |
// CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber);
|
||||||
|
//
|
||||||
// basic request generation with nonce
|
// // basic request generation with nonce
|
||||||
OCSPReqGenerator gen = new OCSPReqGenerator(); |
// OCSPReqGenerator gen = new OCSPReqGenerator();
|
||||||
|
//
|
||||||
gen.addRequest(id); |
// gen.addRequest(id);
|
||||||
|
//
|
||||||
// create details for nonce extension
|
// // create details for nonce extension
|
||||||
Vector oids = new Vector(); |
// Vector oids = new Vector();
|
||||||
Vector values = new Vector(); |
// Vector values = new Vector();
|
||||||
|
//
|
||||||
oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); |
// oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
|
||||||
values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded()))); |
// values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded())));
|
||||||
|
//
|
||||||
gen.setRequestExtensions(new X509Extensions(oids, values)); |
// gen.setRequestExtensions(new X509Extensions(oids, values));
|
||||||
|
//
|
||||||
return gen.generate(); |
// return gen.generate();
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* @return a byte array |
// * @return a byte array
|
||||||
* @see com.fr.third.com.lowagie.text.pdf.OcspClient#getEncoded() |
// * @see com.fr.third.com.lowagie.text.pdf.OcspClient#getEncoded()
|
||||||
*/ |
// */
|
||||||
public byte[] getEncoded() { |
// public byte[] getEncoded() {
|
||||||
try { |
// try {
|
||||||
OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber()); |
// OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber());
|
||||||
byte[] array = request.getEncoded(); |
// byte[] array = request.getEncoded();
|
||||||
URL urlt = new URL(url); |
// URL urlt = new URL(url);
|
||||||
HttpURLConnection con = (HttpURLConnection)urlt.openConnection(); |
// HttpURLConnection con = (HttpURLConnection)urlt.openConnection();
|
||||||
con.setRequestProperty("Content-Type", "application/ocsp-request"); |
// con.setRequestProperty("Content-Type", "application/ocsp-request");
|
||||||
con.setRequestProperty("Accept", "application/ocsp-response"); |
// con.setRequestProperty("Accept", "application/ocsp-response");
|
||||||
con.setDoOutput(true); |
// con.setDoOutput(true);
|
||||||
OutputStream out = con.getOutputStream(); |
// OutputStream out = con.getOutputStream();
|
||||||
DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out)); |
// DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out));
|
||||||
dataOut.write(array); |
// dataOut.write(array);
|
||||||
dataOut.flush(); |
// dataOut.flush();
|
||||||
dataOut.close(); |
// dataOut.close();
|
||||||
if (con.getResponseCode() / 100 != 2) { |
// if (con.getResponseCode() / 100 != 2) {
|
||||||
throw new IOException("Invalid HTTP response"); |
// throw new IOException("Invalid HTTP response");
|
||||||
} |
// }
|
||||||
//Get Response
|
// //Get Response
|
||||||
InputStream in = (InputStream) con.getContent(); |
// InputStream in = (InputStream) con.getContent();
|
||||||
OCSPResp ocspResponse = new OCSPResp(in); |
// OCSPResp ocspResponse = new OCSPResp(in);
|
||||||
|
//
|
||||||
if (ocspResponse.getStatus() != 0) |
// if (ocspResponse.getStatus() != 0)
|
||||||
throw new IOException("Invalid status: " + ocspResponse.getStatus()); |
// throw new IOException("Invalid status: " + ocspResponse.getStatus());
|
||||||
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject(); |
// BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
|
||||||
if (basicResponse != null) { |
// if (basicResponse != null) {
|
||||||
SingleResp[] responses = basicResponse.getResponses(); |
// SingleResp[] responses = basicResponse.getResponses();
|
||||||
if (responses.length == 1) { |
// if (responses.length == 1) {
|
||||||
SingleResp resp = responses[0]; |
// SingleResp resp = responses[0];
|
||||||
Object status = resp.getCertStatus(); |
// Object status = resp.getCertStatus();
|
||||||
if (status == CertificateStatus.GOOD) { |
// if (status == CertificateStatus.GOOD) {
|
||||||
return basicResponse.getEncoded(); |
// return basicResponse.getEncoded();
|
||||||
} |
// }
|
||||||
else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) { |
// else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) {
|
||||||
throw new IOException("OCSP Status is revoked!"); |
// throw new IOException("OCSP Status is revoked!");
|
||||||
} |
// }
|
||||||
else { |
// else {
|
||||||
throw new IOException("OCSP Status is unknown!"); |
// throw new IOException("OCSP Status is unknown!");
|
||||||
} |
// }
|
||||||
} |
// }
|
||||||
} |
// }
|
||||||
} |
// }
|
||||||
catch (Exception ex) { |
// catch (Exception ex) {
|
||||||
throw new ExceptionConverter(ex); |
// throw new ExceptionConverter(ex);
|
||||||
} |
// }
|
||||||
return null; |
// return null;
|
||||||
} |
// }
|
||||||
} |
//}
|
||||||
|
@ -1,230 +1,230 @@ |
|||||||
/* |
///*
|
||||||
* $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $ |
// * $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $
|
||||||
* |
// *
|
||||||
* Copyright 2009 Martin Brunecky, Aiken Sam |
// * Copyright 2009 Martin Brunecky, Aiken Sam
|
||||||
* |
// *
|
||||||
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
// * 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. |
// * (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/
|
// * 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, |
// * Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
// * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
* for the specific language governing rights and limitations under the License. |
// * for the specific language governing rights and limitations under the License.
|
||||||
* |
// *
|
||||||
* The Original Code is 'iText, a free JAVA-PDF library'. |
// * 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 of the Original Code is Bruno Lowagie. Portions created by
|
||||||
* the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. |
// * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
|
||||||
* All Rights Reserved. |
// * All Rights Reserved.
|
||||||
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer |
// * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
|
||||||
* are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved. |
// * are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved.
|
||||||
* |
// *
|
||||||
* Contributor(s): all the names of the contributors are added in the source code |
// * Contributor(s): all the names of the contributors are added in the source code
|
||||||
* where applicable. |
// * where applicable.
|
||||||
* |
// *
|
||||||
* Alternatively, the contents of this file may be used under the terms of the |
// * 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 |
// * 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 |
// * 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 |
// * 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 |
// * 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 |
// * the MPL, indicate your decision by deleting the provisions above and
|
||||||
* replace them with the notice and other provisions required by the LGPL. |
// * 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 |
// * 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. |
// * 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 |
// * 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 |
// * 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; |
// * Library General Public License as published by the Free Software Foundation;
|
||||||
* either version 2 of the License, or any later version. |
// * either version 2 of the License, or any later version.
|
||||||
* |
// *
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT |
// * 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 |
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more |
// * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
|
||||||
* details. |
// * details.
|
||||||
* |
// *
|
||||||
* If you didn't download this code from the following link, you should check if |
// * If you didn't download this code from the following link, you should check if
|
||||||
* you aren't using an obsolete version: |
// * you aren't using an obsolete version:
|
||||||
* http://www.lowagie.com/iText/
|
// * http://www.lowagie.com/iText/
|
||||||
*/ |
// */
|
||||||
|
//
|
||||||
package com.fr.third.com.lowagie.text.pdf; |
//package com.fr.third.com.lowagie.text.pdf;
|
||||||
|
//
|
||||||
import java.io.*; |
//import java.io.*;
|
||||||
import java.math.*; |
//import java.math.*;
|
||||||
import java.net.*; |
//import java.net.*;
|
||||||
|
//
|
||||||
import org.bouncycastle.asn1.cmp.*; |
//import org.bouncycastle.asn1.cmp.*;
|
||||||
import org.bouncycastle.asn1.x509.*; |
//import org.bouncycastle.asn1.x509.*;
|
||||||
import org.bouncycastle.tsp.*; |
//import org.bouncycastle.tsp.*;
|
||||||
|
//
|
||||||
import com.fr.third.com.lowagie.text.pdf.codec.Base64; |
//import com.fr.third.com.lowagie.text.pdf.codec.Base64;
|
||||||
|
//
|
||||||
/** |
///**
|
||||||
* Time Stamp Authority Client interface implementation using Bouncy Castle |
// * Time Stamp Authority Client interface implementation using Bouncy Castle
|
||||||
* org.bouncycastle.tsp package. |
// * org.bouncycastle.tsp package.
|
||||||
* <p> |
// * <p>
|
||||||
* Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007 |
// * Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007
|
||||||
* for ease of subclassing. |
// * for ease of subclassing.
|
||||||
* </p> |
// * </p>
|
||||||
* @since 2.1.6 |
// * @since 2.1.6
|
||||||
*/ |
// */
|
||||||
public class TSAClientBouncyCastle implements TSAClient { |
//public class TSAClientBouncyCastle implements TSAClient {
|
||||||
/** URL of the Time Stamp Authority */ |
// /** URL of the Time Stamp Authority */
|
||||||
protected String tsaURL; |
// protected String tsaURL;
|
||||||
/** TSA Username */ |
// /** TSA Username */
|
||||||
protected String tsaUsername; |
// protected String tsaUsername;
|
||||||
/** TSA password */ |
// /** TSA password */
|
||||||
protected String tsaPassword; |
// protected String tsaPassword;
|
||||||
/** Estimate of the received time stamp token */ |
// /** Estimate of the received time stamp token */
|
||||||
protected int tokSzEstimate; |
// protected int tokSzEstimate;
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Creates an instance of a TSAClient that will use BouncyCastle. |
// * 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 url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||||
*/ |
// */
|
||||||
public TSAClientBouncyCastle(String url) { |
// public TSAClientBouncyCastle(String url) {
|
||||||
this(url, null, null, 4096); |
// this(url, null, null, 4096);
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Creates an instance of a TSAClient that will use BouncyCastle. |
// * 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 url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||||
* @param username String - user(account) name |
// * @param username String - user(account) name
|
||||||
* @param password String - password |
// * @param password String - password
|
||||||
*/ |
// */
|
||||||
public TSAClientBouncyCastle(String url, String username, String password) { |
// public TSAClientBouncyCastle(String url, String username, String password) {
|
||||||
this(url, username, password, 4096); |
// this(url, username, password, 4096);
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Constructor. |
// * Constructor.
|
||||||
* Note the token size estimate is updated by each call, as the token |
// * 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 |
// * size is not likely to change (as long as we call the same TSA using
|
||||||
* the same imprint length). |
// * the same imprint length).
|
||||||
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") |
// * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||||
* @param username String - user(account) name |
// * @param username String - user(account) name
|
||||||
* @param password String - password |
// * @param password String - password
|
||||||
* @param tokSzEstimate int - estimated size of received time stamp token (DER encoded) |
// * @param tokSzEstimate int - estimated size of received time stamp token (DER encoded)
|
||||||
*/ |
// */
|
||||||
public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) { |
// public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) {
|
||||||
this.tsaURL = url; |
// this.tsaURL = url;
|
||||||
this.tsaUsername = username; |
// this.tsaUsername = username;
|
||||||
this.tsaPassword = password; |
// this.tsaPassword = password;
|
||||||
this.tokSzEstimate = tokSzEstimate; |
// this.tokSzEstimate = tokSzEstimate;
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Get the token size estimate. |
// * Get the token size estimate.
|
||||||
* Returned value reflects the result of the last succesfull call, padded |
// * Returned value reflects the result of the last succesfull call, padded
|
||||||
* @return an estimate of the token size |
// * @return an estimate of the token size
|
||||||
*/ |
// */
|
||||||
public int getTokenSizeEstimate() { |
// public int getTokenSizeEstimate() {
|
||||||
return tokSzEstimate; |
// return tokSzEstimate;
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Get RFC 3161 timeStampToken. |
// * Get RFC 3161 timeStampToken.
|
||||||
* Method may return null indicating that timestamp should be skipped. |
// * Method may return null indicating that timestamp should be skipped.
|
||||||
* @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it) |
// * @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it)
|
||||||
* @param imprint byte[] - data imprint to be time-stamped |
// * @param imprint byte[] - data imprint to be time-stamped
|
||||||
* @return byte[] - encoded, TSA signed data of the timeStampToken |
// * @return byte[] - encoded, TSA signed data of the timeStampToken
|
||||||
* @throws Exception - TSA request failed |
// * @throws Exception - TSA request failed
|
||||||
* @see com.fr.third.com.lowagie.text.pdf.TSAClient#getTimeStampToken(com.fr.third.com.lowagie.text.pdf.PdfPKCS7, byte[]) |
// * @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 { |
// public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception {
|
||||||
return getTimeStampToken(imprint); |
// return getTimeStampToken(imprint);
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Get timestamp token - Bouncy Castle request encoding / decoding layer |
// * Get timestamp token - Bouncy Castle request encoding / decoding layer
|
||||||
*/ |
// */
|
||||||
protected byte[] getTimeStampToken(byte[] imprint) throws Exception { |
// protected byte[] getTimeStampToken(byte[] imprint) throws Exception {
|
||||||
byte[] respBytes = null; |
// byte[] respBytes = null;
|
||||||
try { |
// try {
|
||||||
// Setup the time stamp request
|
// // Setup the time stamp request
|
||||||
TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator(); |
// TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator();
|
||||||
tsqGenerator.setCertReq(true); |
// tsqGenerator.setCertReq(true);
|
||||||
// tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
|
// // tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
|
||||||
BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis()); |
// BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
|
||||||
TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce); |
// TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce);
|
||||||
byte[] requestBytes = request.getEncoded(); |
// byte[] requestBytes = request.getEncoded();
|
||||||
|
//
|
||||||
// Call the communications layer
|
// // Call the communications layer
|
||||||
respBytes = getTSAResponse(requestBytes); |
// respBytes = getTSAResponse(requestBytes);
|
||||||
|
//
|
||||||
// Handle the TSA response
|
// // Handle the TSA response
|
||||||
TimeStampResponse response = new TimeStampResponse(respBytes); |
// TimeStampResponse response = new TimeStampResponse(respBytes);
|
||||||
|
//
|
||||||
// validate communication level attributes (RFC 3161 PKIStatus)
|
// // validate communication level attributes (RFC 3161 PKIStatus)
|
||||||
response.validate(request); |
// response.validate(request);
|
||||||
PKIFailureInfo failure = response.getFailInfo(); |
// PKIFailureInfo failure = response.getFailInfo();
|
||||||
int value = (failure == null) ? 0 : failure.intValue(); |
// int value = (failure == null) ? 0 : failure.intValue();
|
||||||
if (value != 0) { |
// if (value != 0) {
|
||||||
// @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
|
// // @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
|
||||||
throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value); |
// throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value);
|
||||||
} |
// }
|
||||||
// @todo: validate the time stap certificate chain (if we want
|
// // @todo: validate the time stap certificate chain (if we want
|
||||||
// assure we do not sign using an invalid timestamp).
|
// // assure we do not sign using an invalid timestamp).
|
||||||
|
//
|
||||||
// extract just the time stamp token (removes communication status info)
|
// // extract just the time stamp token (removes communication status info)
|
||||||
TimeStampToken tsToken = response.getTimeStampToken(); |
// TimeStampToken tsToken = response.getTimeStampToken();
|
||||||
if (tsToken == null) { |
// if (tsToken == null) {
|
||||||
throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString()); |
// throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString());
|
||||||
} |
// }
|
||||||
TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details
|
// TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details
|
||||||
byte[] encoded = tsToken.getEncoded(); |
// byte[] encoded = tsToken.getEncoded();
|
||||||
long stop = System.currentTimeMillis(); |
// long stop = System.currentTimeMillis();
|
||||||
|
//
|
||||||
// Update our token size estimate for the next call (padded to be safe)
|
// // Update our token size estimate for the next call (padded to be safe)
|
||||||
this.tokSzEstimate = encoded.length + 32; |
// this.tokSzEstimate = encoded.length + 32;
|
||||||
return encoded; |
// return encoded;
|
||||||
} catch (Exception e) { |
// } catch (Exception e) {
|
||||||
throw e; |
// throw e;
|
||||||
} catch (Throwable t) { |
// } catch (Throwable t) {
|
||||||
throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t); |
// throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t);
|
||||||
} |
// }
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Get timestamp token - communications layer |
// * Get timestamp token - communications layer
|
||||||
* @return - byte[] - TSA response, raw bytes (RFC 3161 encoded) |
// * @return - byte[] - TSA response, raw bytes (RFC 3161 encoded)
|
||||||
*/ |
// */
|
||||||
protected byte[] getTSAResponse(byte[] requestBytes) throws Exception { |
// protected byte[] getTSAResponse(byte[] requestBytes) throws Exception {
|
||||||
// Setup the TSA connection
|
// // Setup the TSA connection
|
||||||
URL url = new URL(tsaURL); |
// URL url = new URL(tsaURL);
|
||||||
URLConnection tsaConnection; |
// URLConnection tsaConnection;
|
||||||
tsaConnection = (URLConnection) url.openConnection(); |
// tsaConnection = (URLConnection) url.openConnection();
|
||||||
|
//
|
||||||
tsaConnection.setDoInput(true); |
// tsaConnection.setDoInput(true);
|
||||||
tsaConnection.setDoOutput(true); |
// tsaConnection.setDoOutput(true);
|
||||||
tsaConnection.setUseCaches(false); |
// tsaConnection.setUseCaches(false);
|
||||||
tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query"); |
// tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query");
|
||||||
//tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64");
|
// //tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64");
|
||||||
tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary"); |
// tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary");
|
||||||
|
//
|
||||||
if ((tsaUsername != null) && !tsaUsername.equals("") ) { |
// if ((tsaUsername != null) && !tsaUsername.equals("") ) {
|
||||||
String userPassword = tsaUsername + ":" + tsaPassword; |
// String userPassword = tsaUsername + ":" + tsaPassword;
|
||||||
tsaConnection.setRequestProperty("Authorization", "Basic " + |
// tsaConnection.setRequestProperty("Authorization", "Basic " +
|
||||||
new String(Base64.encodeBytes(userPassword.getBytes()))); |
// new String(Base64.encodeBytes(userPassword.getBytes())));
|
||||||
} |
// }
|
||||||
OutputStream out = tsaConnection.getOutputStream(); |
// OutputStream out = tsaConnection.getOutputStream();
|
||||||
out.write(requestBytes); |
// out.write(requestBytes);
|
||||||
out.close(); |
// out.close();
|
||||||
|
//
|
||||||
// Get TSA response as a byte array
|
// // Get TSA response as a byte array
|
||||||
InputStream inp = tsaConnection.getInputStream(); |
// InputStream inp = tsaConnection.getInputStream();
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
byte[] buffer = new byte[1024]; |
// byte[] buffer = new byte[1024];
|
||||||
int bytesRead = 0; |
// int bytesRead = 0;
|
||||||
while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) { |
// while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) {
|
||||||
baos.write(buffer, 0, bytesRead); |
// baos.write(buffer, 0, bytesRead);
|
||||||
} |
// }
|
||||||
byte[] respBytes = baos.toByteArray(); |
// byte[] respBytes = baos.toByteArray();
|
||||||
|
//
|
||||||
String encoding = tsaConnection.getContentEncoding(); |
// String encoding = tsaConnection.getContentEncoding();
|
||||||
if (encoding != null && encoding.equalsIgnoreCase("base64")) { |
// if (encoding != null && encoding.equalsIgnoreCase("base64")) {
|
||||||
respBytes = Base64.decode(new String(respBytes)); |
// respBytes = Base64.decode(new String(respBytes));
|
||||||
} |
// }
|
||||||
return 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 $ |
// * $Id: OcspClientBouncyCastle.java 3959 2009-06-09 08:31:05Z blowagie $
|
||||||
* |
// *
|
||||||
* Copyright 2009 Paulo Soares |
// * Copyright 2009 Paulo Soares
|
||||||
* |
// *
|
||||||
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
// * 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. |
// * (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/
|
// * 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, |
// * Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
// * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
* for the specific language governing rights and limitations under the License. |
// * for the specific language governing rights and limitations under the License.
|
||||||
* |
// *
|
||||||
* The Original Code is 'iText, a free JAVA-PDF library'. |
// * 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 of the Original Code is Bruno Lowagie. Portions created by
|
||||||
* the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. |
// * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
|
||||||
* All Rights Reserved. |
// * All Rights Reserved.
|
||||||
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer |
// * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
|
||||||
* are Copyright (C) 2009 by Paulo Soares. All Rights Reserved. |
// * are Copyright (C) 2009 by Paulo Soares. All Rights Reserved.
|
||||||
* |
// *
|
||||||
* Contributor(s): all the names of the contributors are added in the source code |
// * Contributor(s): all the names of the contributors are added in the source code
|
||||||
* where applicable. |
// * where applicable.
|
||||||
* |
// *
|
||||||
* Alternatively, the contents of this file may be used under the terms of the |
// * 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 |
// * 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 |
// * 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 |
// * 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 |
// * 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 |
// * the MPL, indicate your decision by deleting the provisions above and
|
||||||
* replace them with the notice and other provisions required by the LGPL. |
// * 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 |
// * 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. |
// * 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 |
// * 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 |
// * 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; |
// * Library General Public License as published by the Free Software Foundation;
|
||||||
* either version 2 of the License, or any later version. |
// * either version 2 of the License, or any later version.
|
||||||
* |
// *
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT |
// * 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 |
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more |
// * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
|
||||||
* details. |
// * details.
|
||||||
* |
// *
|
||||||
* If you didn't download this code from the following link, you should check if |
// * If you didn't download this code from the following link, you should check if
|
||||||
* you aren't using an obsolete version: |
// * you aren't using an obsolete version:
|
||||||
* http://www.lowagie.com/iText/
|
// * http://www.lowagie.com/iText/
|
||||||
*/ |
// */
|
||||||
|
//
|
||||||
package com.fr.third.v2.lowagie.text.pdf; |
//package com.fr.third.v2.lowagie.text.pdf;
|
||||||
|
//
|
||||||
import com.fr.third.v2.lowagie.text.ExceptionConverter; |
//import com.fr.third.v2.lowagie.text.ExceptionConverter;
|
||||||
|
//
|
||||||
import java.io.BufferedOutputStream; |
//import java.io.BufferedOutputStream;
|
||||||
import java.io.DataOutputStream; |
//import java.io.DataOutputStream;
|
||||||
import java.io.IOException; |
//import java.io.IOException;
|
||||||
import java.io.InputStream; |
//import java.io.InputStream;
|
||||||
import java.io.OutputStream; |
//import java.io.OutputStream;
|
||||||
import java.math.BigInteger; |
//import java.math.BigInteger;
|
||||||
import java.net.HttpURLConnection; |
//import java.net.HttpURLConnection;
|
||||||
import java.net.URL; |
//import java.net.URL;
|
||||||
import java.security.Security; |
//import java.security.Security;
|
||||||
import java.security.cert.X509Certificate; |
//import java.security.cert.X509Certificate;
|
||||||
import java.util.Vector; |
//import java.util.Vector;
|
||||||
import org.bouncycastle.asn1.DEROctetString; |
//import org.bouncycastle.asn1.DEROctetString;
|
||||||
import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; |
//import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
|
||||||
import org.bouncycastle.asn1.x509.X509Extension; |
//import org.bouncycastle.asn1.x509.X509Extension;
|
||||||
import org.bouncycastle.asn1.x509.X509Extensions; |
//import org.bouncycastle.asn1.x509.X509Extensions;
|
||||||
import org.bouncycastle.ocsp.BasicOCSPResp; |
//import org.bouncycastle.ocsp.BasicOCSPResp;
|
||||||
import org.bouncycastle.ocsp.CertificateID; |
//import org.bouncycastle.ocsp.CertificateID;
|
||||||
import org.bouncycastle.ocsp.CertificateStatus; |
//import org.bouncycastle.ocsp.CertificateStatus;
|
||||||
import org.bouncycastle.ocsp.OCSPException; |
//import org.bouncycastle.ocsp.OCSPException;
|
||||||
import org.bouncycastle.ocsp.OCSPReq; |
//import org.bouncycastle.ocsp.OCSPReq;
|
||||||
import org.bouncycastle.ocsp.OCSPReqGenerator; |
//import org.bouncycastle.ocsp.OCSPReqGenerator;
|
||||||
import org.bouncycastle.ocsp.OCSPResp; |
//import org.bouncycastle.ocsp.OCSPResp;
|
||||||
import org.bouncycastle.ocsp.SingleResp; |
//import org.bouncycastle.ocsp.SingleResp;
|
||||||
|
//
|
||||||
/** |
///**
|
||||||
* OcspClient implementation using BouncyCastle. |
// * OcspClient implementation using BouncyCastle.
|
||||||
* @author psoares |
// * @author psoares
|
||||||
* @since 2.1.6 |
// * @since 2.1.6
|
||||||
*/ |
// */
|
||||||
public class OcspClientBouncyCastle implements OcspClient { |
//public class OcspClientBouncyCastle implements OcspClient {
|
||||||
/** root certificate */ |
// /** root certificate */
|
||||||
private X509Certificate rootCert; |
// private X509Certificate rootCert;
|
||||||
/** check certificate */ |
// /** check certificate */
|
||||||
private X509Certificate checkCert; |
// private X509Certificate checkCert;
|
||||||
/** OCSP URL */ |
// /** OCSP URL */
|
||||||
private String url; |
// private String url;
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Creates an instance of an OcspClient that will be using BouncyCastle. |
// * Creates an instance of an OcspClient that will be using BouncyCastle.
|
||||||
* @param checkCert the check certificate |
// * @param checkCert the check certificate
|
||||||
* @param rootCert the root certificate |
// * @param rootCert the root certificate
|
||||||
* @param url the OCSP URL |
// * @param url the OCSP URL
|
||||||
*/ |
// */
|
||||||
public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) { |
// public OcspClientBouncyCastle(X509Certificate checkCert, X509Certificate rootCert, String url) {
|
||||||
this.checkCert = checkCert; |
// this.checkCert = checkCert;
|
||||||
this.rootCert = rootCert; |
// this.rootCert = rootCert;
|
||||||
this.url = url; |
// this.url = url;
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Generates an OCSP request using BouncyCastle. |
// * Generates an OCSP request using BouncyCastle.
|
||||||
* @param issuerCert certificate of the issues |
// * @param issuerCert certificate of the issues
|
||||||
* @param serialNumber serial number |
// * @param serialNumber serial number
|
||||||
* @return an OCSP request |
// * @return an OCSP request
|
||||||
* @throws OCSPException |
// * @throws OCSPException
|
||||||
* @throws IOException |
// * @throws IOException
|
||||||
*/ |
// */
|
||||||
private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException { |
// private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigInteger serialNumber) throws OCSPException, IOException {
|
||||||
//Add provider BC
|
// //Add provider BC
|
||||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); |
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||||
|
//
|
||||||
// Generate the id for the certificate we are looking for
|
// // Generate the id for the certificate we are looking for
|
||||||
CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber); |
// CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber);
|
||||||
|
//
|
||||||
// basic request generation with nonce
|
// // basic request generation with nonce
|
||||||
OCSPReqGenerator gen = new OCSPReqGenerator(); |
// OCSPReqGenerator gen = new OCSPReqGenerator();
|
||||||
|
//
|
||||||
gen.addRequest(id); |
// gen.addRequest(id);
|
||||||
|
//
|
||||||
// create details for nonce extension
|
// // create details for nonce extension
|
||||||
Vector oids = new Vector(); |
// Vector oids = new Vector();
|
||||||
Vector values = new Vector(); |
// Vector values = new Vector();
|
||||||
|
//
|
||||||
oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); |
// oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
|
||||||
values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded()))); |
// values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded())));
|
||||||
|
//
|
||||||
gen.setRequestExtensions(new X509Extensions(oids, values)); |
// gen.setRequestExtensions(new X509Extensions(oids, values));
|
||||||
|
//
|
||||||
return gen.generate(); |
// return gen.generate();
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* @return a byte array |
// * @return a byte array
|
||||||
* @see OcspClient#getEncoded() |
// * @see OcspClient#getEncoded()
|
||||||
*/ |
// */
|
||||||
public byte[] getEncoded() { |
// public byte[] getEncoded() {
|
||||||
try { |
// try {
|
||||||
OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber()); |
// OCSPReq request = generateOCSPRequest(rootCert, checkCert.getSerialNumber());
|
||||||
byte[] array = request.getEncoded(); |
// byte[] array = request.getEncoded();
|
||||||
URL urlt = new URL(url); |
// URL urlt = new URL(url);
|
||||||
HttpURLConnection con = (HttpURLConnection)urlt.openConnection(); |
// HttpURLConnection con = (HttpURLConnection)urlt.openConnection();
|
||||||
con.setRequestProperty("Content-Type", "application/ocsp-request"); |
// con.setRequestProperty("Content-Type", "application/ocsp-request");
|
||||||
con.setRequestProperty("Accept", "application/ocsp-response"); |
// con.setRequestProperty("Accept", "application/ocsp-response");
|
||||||
con.setDoOutput(true); |
// con.setDoOutput(true);
|
||||||
OutputStream out = con.getOutputStream(); |
// OutputStream out = con.getOutputStream();
|
||||||
DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out)); |
// DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out));
|
||||||
dataOut.write(array); |
// dataOut.write(array);
|
||||||
dataOut.flush(); |
// dataOut.flush();
|
||||||
dataOut.close(); |
// dataOut.close();
|
||||||
if (con.getResponseCode() / 100 != 2) { |
// if (con.getResponseCode() / 100 != 2) {
|
||||||
throw new IOException("Invalid HTTP response"); |
// throw new IOException("Invalid HTTP response");
|
||||||
} |
// }
|
||||||
//Get Response
|
// //Get Response
|
||||||
InputStream in = (InputStream) con.getContent(); |
// InputStream in = (InputStream) con.getContent();
|
||||||
OCSPResp ocspResponse = new OCSPResp(in); |
// OCSPResp ocspResponse = new OCSPResp(in);
|
||||||
|
//
|
||||||
if (ocspResponse.getStatus() != 0) |
// if (ocspResponse.getStatus() != 0)
|
||||||
throw new IOException("Invalid status: " + ocspResponse.getStatus()); |
// throw new IOException("Invalid status: " + ocspResponse.getStatus());
|
||||||
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject(); |
// BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
|
||||||
if (basicResponse != null) { |
// if (basicResponse != null) {
|
||||||
SingleResp[] responses = basicResponse.getResponses(); |
// SingleResp[] responses = basicResponse.getResponses();
|
||||||
if (responses.length == 1) { |
// if (responses.length == 1) {
|
||||||
SingleResp resp = responses[0]; |
// SingleResp resp = responses[0];
|
||||||
Object status = resp.getCertStatus(); |
// Object status = resp.getCertStatus();
|
||||||
if (status == CertificateStatus.GOOD) { |
// if (status == CertificateStatus.GOOD) {
|
||||||
return basicResponse.getEncoded(); |
// return basicResponse.getEncoded();
|
||||||
} |
// }
|
||||||
else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) { |
// else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) {
|
||||||
throw new IOException("OCSP Status is revoked!"); |
// throw new IOException("OCSP Status is revoked!");
|
||||||
} |
// }
|
||||||
else { |
// else {
|
||||||
throw new IOException("OCSP Status is unknown!"); |
// throw new IOException("OCSP Status is unknown!");
|
||||||
} |
// }
|
||||||
} |
// }
|
||||||
} |
// }
|
||||||
} |
// }
|
||||||
catch (Exception ex) { |
// catch (Exception ex) {
|
||||||
throw new ExceptionConverter(ex); |
// throw new ExceptionConverter(ex);
|
||||||
} |
// }
|
||||||
return null; |
// return null;
|
||||||
} |
// }
|
||||||
} |
//}
|
||||||
|
@ -1,230 +1,230 @@ |
|||||||
/* |
///*
|
||||||
* $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $ |
// * $Id: TSAClientBouncyCastle.java 3973 2009-06-16 10:30:31Z psoares33 $
|
||||||
* |
// *
|
||||||
* Copyright 2009 Martin Brunecky, Aiken Sam |
// * Copyright 2009 Martin Brunecky, Aiken Sam
|
||||||
* |
// *
|
||||||
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
// * 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. |
// * (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/
|
// * 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, |
// * Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
// * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
* for the specific language governing rights and limitations under the License. |
// * for the specific language governing rights and limitations under the License.
|
||||||
* |
// *
|
||||||
* The Original Code is 'iText, a free JAVA-PDF library'. |
// * 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 of the Original Code is Bruno Lowagie. Portions created by
|
||||||
* the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. |
// * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie.
|
||||||
* All Rights Reserved. |
// * All Rights Reserved.
|
||||||
* Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer |
// * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
|
||||||
* are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved. |
// * are Copyright (C) 2009 by Martin Brunecky. All Rights Reserved.
|
||||||
* |
// *
|
||||||
* Contributor(s): all the names of the contributors are added in the source code |
// * Contributor(s): all the names of the contributors are added in the source code
|
||||||
* where applicable. |
// * where applicable.
|
||||||
* |
// *
|
||||||
* Alternatively, the contents of this file may be used under the terms of the |
// * 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 |
// * 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 |
// * 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 |
// * 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 |
// * 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 |
// * the MPL, indicate your decision by deleting the provisions above and
|
||||||
* replace them with the notice and other provisions required by the LGPL. |
// * 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 |
// * 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. |
// * 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 |
// * 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 |
// * 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; |
// * Library General Public License as published by the Free Software Foundation;
|
||||||
* either version 2 of the License, or any later version. |
// * either version 2 of the License, or any later version.
|
||||||
* |
// *
|
||||||
* This library is distributed in the hope that it will be useful, but WITHOUT |
// * 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 |
// * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more |
// * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
|
||||||
* details. |
// * details.
|
||||||
* |
// *
|
||||||
* If you didn't download this code from the following link, you should check if |
// * If you didn't download this code from the following link, you should check if
|
||||||
* you aren't using an obsolete version: |
// * you aren't using an obsolete version:
|
||||||
* http://www.lowagie.com/iText/
|
// * http://www.lowagie.com/iText/
|
||||||
*/ |
// */
|
||||||
|
//
|
||||||
package com.fr.third.v2.lowagie.text.pdf; |
//package com.fr.third.v2.lowagie.text.pdf;
|
||||||
|
//
|
||||||
import java.io.*; |
//import java.io.*;
|
||||||
import java.math.*; |
//import java.math.*;
|
||||||
import java.net.*; |
//import java.net.*;
|
||||||
|
//
|
||||||
import org.bouncycastle.asn1.cmp.*; |
//import org.bouncycastle.asn1.cmp.*;
|
||||||
import org.bouncycastle.asn1.x509.*; |
//import org.bouncycastle.asn1.x509.*;
|
||||||
import org.bouncycastle.tsp.*; |
//import org.bouncycastle.tsp.*;
|
||||||
|
//
|
||||||
import com.fr.third.v2.lowagie.text.pdf.codec.Base64; |
//import com.fr.third.v2.lowagie.text.pdf.codec.Base64;
|
||||||
|
//
|
||||||
/** |
///**
|
||||||
* Time Stamp Authority Client interface implementation using Bouncy Castle |
// * Time Stamp Authority Client interface implementation using Bouncy Castle
|
||||||
* org.bouncycastle.tsp package. |
// * org.bouncycastle.tsp package.
|
||||||
* <p> |
// * <p>
|
||||||
* Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007 |
// * Created by Aiken Sam, 2006-11-15, refactored by Martin Brunecky, 07/15/2007
|
||||||
* for ease of subclassing. |
// * for ease of subclassing.
|
||||||
* </p> |
// * </p>
|
||||||
* @since 2.1.6 |
// * @since 2.1.6
|
||||||
*/ |
// */
|
||||||
public class TSAClientBouncyCastle implements TSAClient { |
//public class TSAClientBouncyCastle implements TSAClient {
|
||||||
/** URL of the Time Stamp Authority */ |
// /** URL of the Time Stamp Authority */
|
||||||
protected String tsaURL; |
// protected String tsaURL;
|
||||||
/** TSA Username */ |
// /** TSA Username */
|
||||||
protected String tsaUsername; |
// protected String tsaUsername;
|
||||||
/** TSA password */ |
// /** TSA password */
|
||||||
protected String tsaPassword; |
// protected String tsaPassword;
|
||||||
/** Estimate of the received time stamp token */ |
// /** Estimate of the received time stamp token */
|
||||||
protected int tokSzEstimate; |
// protected int tokSzEstimate;
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Creates an instance of a TSAClient that will use BouncyCastle. |
// * 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 url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||||
*/ |
// */
|
||||||
public TSAClientBouncyCastle(String url) { |
// public TSAClientBouncyCastle(String url) {
|
||||||
this(url, null, null, 4096); |
// this(url, null, null, 4096);
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Creates an instance of a TSAClient that will use BouncyCastle. |
// * 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 url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||||
* @param username String - user(account) name |
// * @param username String - user(account) name
|
||||||
* @param password String - password |
// * @param password String - password
|
||||||
*/ |
// */
|
||||||
public TSAClientBouncyCastle(String url, String username, String password) { |
// public TSAClientBouncyCastle(String url, String username, String password) {
|
||||||
this(url, username, password, 4096); |
// this(url, username, password, 4096);
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Constructor. |
// * Constructor.
|
||||||
* Note the token size estimate is updated by each call, as the token |
// * 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 |
// * size is not likely to change (as long as we call the same TSA using
|
||||||
* the same imprint length). |
// * the same imprint length).
|
||||||
* @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA") |
// * @param url String - Time Stamp Authority URL (i.e. "http://tsatest1.digistamp.com/TSA")
|
||||||
* @param username String - user(account) name |
// * @param username String - user(account) name
|
||||||
* @param password String - password |
// * @param password String - password
|
||||||
* @param tokSzEstimate int - estimated size of received time stamp token (DER encoded) |
// * @param tokSzEstimate int - estimated size of received time stamp token (DER encoded)
|
||||||
*/ |
// */
|
||||||
public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) { |
// public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate) {
|
||||||
this.tsaURL = url; |
// this.tsaURL = url;
|
||||||
this.tsaUsername = username; |
// this.tsaUsername = username;
|
||||||
this.tsaPassword = password; |
// this.tsaPassword = password;
|
||||||
this.tokSzEstimate = tokSzEstimate; |
// this.tokSzEstimate = tokSzEstimate;
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Get the token size estimate. |
// * Get the token size estimate.
|
||||||
* Returned value reflects the result of the last succesfull call, padded |
// * Returned value reflects the result of the last succesfull call, padded
|
||||||
* @return an estimate of the token size |
// * @return an estimate of the token size
|
||||||
*/ |
// */
|
||||||
public int getTokenSizeEstimate() { |
// public int getTokenSizeEstimate() {
|
||||||
return tokSzEstimate; |
// return tokSzEstimate;
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Get RFC 3161 timeStampToken. |
// * Get RFC 3161 timeStampToken.
|
||||||
* Method may return null indicating that timestamp should be skipped. |
// * Method may return null indicating that timestamp should be skipped.
|
||||||
* @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it) |
// * @param caller PdfPKCS7 - calling PdfPKCS7 instance (in case caller needs it)
|
||||||
* @param imprint byte[] - data imprint to be time-stamped |
// * @param imprint byte[] - data imprint to be time-stamped
|
||||||
* @return byte[] - encoded, TSA signed data of the timeStampToken |
// * @return byte[] - encoded, TSA signed data of the timeStampToken
|
||||||
* @throws Exception - TSA request failed |
// * @throws Exception - TSA request failed
|
||||||
* @see TSAClient#getTimeStampToken(PdfPKCS7, byte[]) |
// * @see TSAClient#getTimeStampToken(PdfPKCS7, byte[])
|
||||||
*/ |
// */
|
||||||
public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception { |
// public byte[] getTimeStampToken(PdfPKCS7 caller, byte[] imprint) throws Exception {
|
||||||
return getTimeStampToken(imprint); |
// return getTimeStampToken(imprint);
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Get timestamp token - Bouncy Castle request encoding / decoding layer |
// * Get timestamp token - Bouncy Castle request encoding / decoding layer
|
||||||
*/ |
// */
|
||||||
protected byte[] getTimeStampToken(byte[] imprint) throws Exception { |
// protected byte[] getTimeStampToken(byte[] imprint) throws Exception {
|
||||||
byte[] respBytes = null; |
// byte[] respBytes = null;
|
||||||
try { |
// try {
|
||||||
// Setup the time stamp request
|
// // Setup the time stamp request
|
||||||
TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator(); |
// TimeStampRequestGenerator tsqGenerator = new TimeStampRequestGenerator();
|
||||||
tsqGenerator.setCertReq(true); |
// tsqGenerator.setCertReq(true);
|
||||||
// tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
|
// // tsqGenerator.setReqPolicy("1.3.6.1.4.1.601.10.3.1");
|
||||||
BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis()); |
// BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
|
||||||
TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce); |
// TimeStampRequest request = tsqGenerator.generate(X509ObjectIdentifiers.id_SHA1.getId() , imprint, nonce);
|
||||||
byte[] requestBytes = request.getEncoded(); |
// byte[] requestBytes = request.getEncoded();
|
||||||
|
//
|
||||||
// Call the communications layer
|
// // Call the communications layer
|
||||||
respBytes = getTSAResponse(requestBytes); |
// respBytes = getTSAResponse(requestBytes);
|
||||||
|
//
|
||||||
// Handle the TSA response
|
// // Handle the TSA response
|
||||||
TimeStampResponse response = new TimeStampResponse(respBytes); |
// TimeStampResponse response = new TimeStampResponse(respBytes);
|
||||||
|
//
|
||||||
// validate communication level attributes (RFC 3161 PKIStatus)
|
// // validate communication level attributes (RFC 3161 PKIStatus)
|
||||||
response.validate(request); |
// response.validate(request);
|
||||||
PKIFailureInfo failure = response.getFailInfo(); |
// PKIFailureInfo failure = response.getFailInfo();
|
||||||
int value = (failure == null) ? 0 : failure.intValue(); |
// int value = (failure == null) ? 0 : failure.intValue();
|
||||||
if (value != 0) { |
// if (value != 0) {
|
||||||
// @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
|
// // @todo: Translate value of 15 error codes defined by PKIFailureInfo to string
|
||||||
throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value); |
// throw new Exception("Invalid TSA '" + tsaURL + "' response, code " + value);
|
||||||
} |
// }
|
||||||
// @todo: validate the time stap certificate chain (if we want
|
// // @todo: validate the time stap certificate chain (if we want
|
||||||
// assure we do not sign using an invalid timestamp).
|
// // assure we do not sign using an invalid timestamp).
|
||||||
|
//
|
||||||
// extract just the time stamp token (removes communication status info)
|
// // extract just the time stamp token (removes communication status info)
|
||||||
TimeStampToken tsToken = response.getTimeStampToken(); |
// TimeStampToken tsToken = response.getTimeStampToken();
|
||||||
if (tsToken == null) { |
// if (tsToken == null) {
|
||||||
throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString()); |
// throw new Exception("TSA '" + tsaURL + "' failed to return time stamp token: " + response.getStatusString());
|
||||||
} |
// }
|
||||||
TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details
|
// TimeStampTokenInfo info = tsToken.getTimeStampInfo(); // to view details
|
||||||
byte[] encoded = tsToken.getEncoded(); |
// byte[] encoded = tsToken.getEncoded();
|
||||||
long stop = System.currentTimeMillis(); |
// long stop = System.currentTimeMillis();
|
||||||
|
//
|
||||||
// Update our token size estimate for the next call (padded to be safe)
|
// // Update our token size estimate for the next call (padded to be safe)
|
||||||
this.tokSzEstimate = encoded.length + 32; |
// this.tokSzEstimate = encoded.length + 32;
|
||||||
return encoded; |
// return encoded;
|
||||||
} catch (Exception e) { |
// } catch (Exception e) {
|
||||||
throw e; |
// throw e;
|
||||||
} catch (Throwable t) { |
// } catch (Throwable t) {
|
||||||
throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t); |
// throw new Exception("Failed to get TSA response from '" + tsaURL +"'", t);
|
||||||
} |
// }
|
||||||
} |
// }
|
||||||
|
//
|
||||||
/** |
// /**
|
||||||
* Get timestamp token - communications layer |
// * Get timestamp token - communications layer
|
||||||
* @return - byte[] - TSA response, raw bytes (RFC 3161 encoded) |
// * @return - byte[] - TSA response, raw bytes (RFC 3161 encoded)
|
||||||
*/ |
// */
|
||||||
protected byte[] getTSAResponse(byte[] requestBytes) throws Exception { |
// protected byte[] getTSAResponse(byte[] requestBytes) throws Exception {
|
||||||
// Setup the TSA connection
|
// // Setup the TSA connection
|
||||||
URL url = new URL(tsaURL); |
// URL url = new URL(tsaURL);
|
||||||
URLConnection tsaConnection; |
// URLConnection tsaConnection;
|
||||||
tsaConnection = (URLConnection) url.openConnection(); |
// tsaConnection = (URLConnection) url.openConnection();
|
||||||
|
//
|
||||||
tsaConnection.setDoInput(true); |
// tsaConnection.setDoInput(true);
|
||||||
tsaConnection.setDoOutput(true); |
// tsaConnection.setDoOutput(true);
|
||||||
tsaConnection.setUseCaches(false); |
// tsaConnection.setUseCaches(false);
|
||||||
tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query"); |
// tsaConnection.setRequestProperty("Content-Type", "application/timestamp-query");
|
||||||
//tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64");
|
// //tsaConnection.setRequestProperty("Content-Transfer-Encoding", "base64");
|
||||||
tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary"); |
// tsaConnection.setRequestProperty("Content-Transfer-Encoding", "binary");
|
||||||
|
//
|
||||||
if ((tsaUsername != null) && !tsaUsername.equals("") ) { |
// if ((tsaUsername != null) && !tsaUsername.equals("") ) {
|
||||||
String userPassword = tsaUsername + ":" + tsaPassword; |
// String userPassword = tsaUsername + ":" + tsaPassword;
|
||||||
tsaConnection.setRequestProperty("Authorization", "Basic " + |
// tsaConnection.setRequestProperty("Authorization", "Basic " +
|
||||||
new String(Base64.encodeBytes(userPassword.getBytes()))); |
// new String(Base64.encodeBytes(userPassword.getBytes())));
|
||||||
} |
// }
|
||||||
OutputStream out = tsaConnection.getOutputStream(); |
// OutputStream out = tsaConnection.getOutputStream();
|
||||||
out.write(requestBytes); |
// out.write(requestBytes);
|
||||||
out.close(); |
// out.close();
|
||||||
|
//
|
||||||
// Get TSA response as a byte array
|
// // Get TSA response as a byte array
|
||||||
InputStream inp = tsaConnection.getInputStream(); |
// InputStream inp = tsaConnection.getInputStream();
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
byte[] buffer = new byte[1024]; |
// byte[] buffer = new byte[1024];
|
||||||
int bytesRead = 0; |
// int bytesRead = 0;
|
||||||
while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) { |
// while ((bytesRead = inp.read(buffer, 0, buffer.length)) >= 0) {
|
||||||
baos.write(buffer, 0, bytesRead); |
// baos.write(buffer, 0, bytesRead);
|
||||||
} |
// }
|
||||||
byte[] respBytes = baos.toByteArray(); |
// byte[] respBytes = baos.toByteArray();
|
||||||
|
//
|
||||||
String encoding = tsaConnection.getContentEncoding(); |
// String encoding = tsaConnection.getContentEncoding();
|
||||||
if (encoding != null && encoding.equalsIgnoreCase("base64")) { |
// if (encoding != null && encoding.equalsIgnoreCase("base64")) {
|
||||||
respBytes = Base64.decode(new String(respBytes)); |
// respBytes = Base64.decode(new String(respBytes));
|
||||||
} |
// }
|
||||||
return respBytes; |
// return respBytes;
|
||||||
} |
// }
|
||||||
} |
//}
|
Loading…
Reference in new issue