All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fitbur.bouncycastle.tsp.TimeStampResponseGenerator Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package com.fitbur.bouncycastle.tsp;

import java.io.IOException;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.fitbur.bouncycastle.asn1.ASN1EncodableVector;
import com.fitbur.bouncycastle.asn1.ASN1Integer;
import com.fitbur.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.fitbur.bouncycastle.asn1.DERBitString;
import com.fitbur.bouncycastle.asn1.DERSequence;
import com.fitbur.bouncycastle.asn1.DERUTF8String;
import com.fitbur.bouncycastle.asn1.cmp.PKIFailureInfo;
import com.fitbur.bouncycastle.asn1.cmp.PKIFreeText;
import com.fitbur.bouncycastle.asn1.cmp.PKIStatus;
import com.fitbur.bouncycastle.asn1.cmp.PKIStatusInfo;
import com.fitbur.bouncycastle.asn1.cms.ContentInfo;
import com.fitbur.bouncycastle.asn1.tsp.TimeStampResp;

/**
 * Generator for RFC 3161 Time Stamp Responses.
 * 

* New generate methods have been introduced to give people more control over what ends up in the message. * Unfortunately it turns out that in some cases fields like statusString must be left out otherwise a an * otherwise valid timestamp will be rejected. *

* If you're after the most control with generating a response use: *
 *    TimeStampResponse tsResp;
 *
 *    try
 *    {
 *       tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date());
 *    }
 *    catch (Exception e)
 *    {
 *        tsResp = tsRespGen.generateRejectedResponse(e);
 *    }
 * 
* The generate method does this, but provides a status string of "Operation Okay". *

* It should be pointed out that generateRejectedResponse() may also, on very rare occasions throw a TSPException. * In the event that happens, there's a serious internal problem with your responder. *

*/ public class TimeStampResponseGenerator { int status; ASN1EncodableVector statusStrings; int failInfo; private TimeStampTokenGenerator tokenGenerator; private Set acceptedAlgorithms; private Set acceptedPolicies; private Set acceptedExtensions; /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms) { this(tokenGenerator, acceptedAlgorithms, null, null); } /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. * @param acceptedPolicies if non-null a set of policies OIDs we are willing to sign under. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms, Set acceptedPolicies) { this(tokenGenerator, acceptedAlgorithms, acceptedPolicies, null); } /** * * @param tokenGenerator * @param acceptedAlgorithms a set of OIDs giving accepted algorithms. * @param acceptedPolicies if non-null a set of policies OIDs we are willing to sign under. * @param acceptedExtensions if non-null a set of extensions OIDs we are willing to accept. */ public TimeStampResponseGenerator( TimeStampTokenGenerator tokenGenerator, Set acceptedAlgorithms, Set acceptedPolicies, Set acceptedExtensions) { this.tokenGenerator = tokenGenerator; this.acceptedAlgorithms = convert(acceptedAlgorithms); this.acceptedPolicies = convert(acceptedPolicies); this.acceptedExtensions = convert(acceptedExtensions); statusStrings = new ASN1EncodableVector(); } private void addStatusString(String statusString) { statusStrings.add(new DERUTF8String(statusString)); } private void setFailInfoField(int field) { failInfo = failInfo | field; } private PKIStatusInfo getPKIStatusInfo() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(status)); if (statusStrings.size() > 0) { v.add(PKIFreeText.getInstance(new DERSequence(statusStrings))); } if (failInfo != 0) { DERBitString failInfoBitString = new FailInfo(failInfo); v.add(failInfoBitString); } return PKIStatusInfo.getInstance(new DERSequence(v)); } /** * Return an appropriate TimeStampResponse. *

* If genTime is null a timeNotAvailable error response will be returned. Calling generate() is the * equivalent of: *

     *    TimeStampResponse tsResp;
     *
     *    try
     *    {
     *       tsResp = tsRespGen.generateGrantedResponse(request, serialNumber, genTime, "Operation Okay");
     *    }
     *    catch (Exception e)
     *    {
     *        tsResp = tsRespGen.generateRejectedResponse(e);
     *    }
     * 
* @param request the request this response is for. * @param serialNumber serial number for the response token. * @param genTime generation time for the response token. * @return a TimeStampResponse. * @throws TSPException */ public TimeStampResponse generate( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { try { return this.generateGrantedResponse(request, serialNumber, genTime, "Operation Okay"); } catch (Exception e) { return this.generateRejectedResponse(e); } } /** * Return a granted response, if the passed in request passes validation. *

* If genTime is null a timeNotAvailable or a validation exception occurs a TSPValidationException will * be thrown. The parent TSPException will only occur on some sort of system failure. *

* @param request the request this response is for. * @param serialNumber serial number for the response token. * @param genTime generation time for the response token. * @return the TimeStampResponse with a status of PKIStatus.GRANTED * @throws TSPException on validation exception or internal error. */ public TimeStampResponse generateGrantedResponse( TimeStampRequest request, BigInteger serialNumber, Date genTime) throws TSPException { return generateGrantedResponse(request, serialNumber, genTime, null); } /** * Return a granted response, if the passed in request passes validation with the passed in status string. *

* If genTime is null a timeNotAvailable or a validation exception occurs a TSPValidationException will * be thrown. The parent TSPException will only occur on some sort of system failure. *

* @param request the request this response is for. * @param serialNumber serial number for the response token. * @param genTime generation time for the response token. * @return the TimeStampResponse with a status of PKIStatus.GRANTED * @throws TSPException on validation exception or internal error. */ public TimeStampResponse generateGrantedResponse( TimeStampRequest request, BigInteger serialNumber, Date genTime, String statusString) throws TSPException { if (genTime == null) { throw new TSPValidationException("The time source is not available.", PKIFailureInfo.timeNotAvailable); } request.validate(acceptedAlgorithms, acceptedPolicies, acceptedExtensions); status = PKIStatus.GRANTED; statusStrings = new ASN1EncodableVector(); if (statusString != null) { this.addStatusString(statusString); } PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); ContentInfo tstTokenContentInfo; try { tstTokenContentInfo = tokenGenerator.generate(request, serialNumber, genTime).toCMSSignedData().toASN1Structure(); } catch (TSPException e) { throw e; } catch (Exception e) { throw new TSPException( "Timestamp token received cannot be converted to ContentInfo", e); } TimeStampResp resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo); try { return new TimeStampResponse(resp); } catch (IOException e) { throw new TSPException("created badly formatted response!"); } } /** * Generate a generic rejection response based on a TSPValidationException or * an Exception. Exceptions which are not an instance of TSPValidationException * will be treated as systemFailure. The return value of exception.getMessage() will * be used as the status string for the response. * * @param exception the exception thrown on validating the request. * @return a TimeStampResponse. * @throws TSPException if a failure response cannot be generated. */ public TimeStampResponse generateRejectedResponse(Exception exception) throws TSPException { if (exception instanceof TSPValidationException) { return generateFailResponse(PKIStatus.REJECTION, ((TSPValidationException)exception).getFailureCode(), exception.getMessage()); } else { return generateFailResponse(PKIStatus.REJECTION, PKIFailureInfo.systemFailure, exception.getMessage()); } } /** * Generate a non-granted TimeStampResponse with chosen status and FailInfoField. * * @param status the PKIStatus to set. * @param failInfoField the FailInfoField to set. * @param statusString an optional string com.fitburscribing the failure. * @return a TimeStampResponse with a failInfoField and optional statusString * @throws TSPException in case the response could not be created */ public TimeStampResponse generateFailResponse(int status, int failInfoField, String statusString) throws TSPException { this.status = status; this.statusStrings = new ASN1EncodableVector(); this.setFailInfoField(failInfoField); if (statusString != null) { this.addStatusString(statusString); } PKIStatusInfo pkiStatusInfo = getPKIStatusInfo(); TimeStampResp resp = new TimeStampResp(pkiStatusInfo, null); try { return new TimeStampResponse(resp); } catch (IOException e) { throw new TSPException("created badly formatted response!"); } } private Set convert(Set orig) { if (orig == null) { return orig; } Set con = new HashSet(orig.size()); for (Iterator it = orig.iterator(); it.hasNext();) { Object o = it.next(); if (o instanceof String) { con.add(new ASN1ObjectIdentifier((String)o)); } else { con.add(o); } } return con; } class FailInfo extends DERBitString { FailInfo(int failInfoValue) { super(getBytes(failInfoValue), getPadBits(failInfoValue)); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy