001: package org.bouncycastle.tsp;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.IOException;
005: import java.math.BigInteger;
006: import java.security.NoSuchAlgorithmException;
007: import java.security.NoSuchProviderException;
008: import java.util.Date;
009: import java.util.Set;
010:
011: import org.bouncycastle.asn1.tsp.TimeStampResp;
012: import org.bouncycastle.asn1.cms.ContentInfo;
013: import org.bouncycastle.asn1.cmp.PKIStatus;
014: import org.bouncycastle.asn1.cmp.PKIStatusInfo;
015: import org.bouncycastle.asn1.cmp.PKIFreeText;
016: import org.bouncycastle.asn1.ASN1EncodableVector;
017: import org.bouncycastle.asn1.ASN1InputStream;
018: import org.bouncycastle.asn1.DERBitString;
019: import org.bouncycastle.asn1.DERInteger;
020: import org.bouncycastle.asn1.DERSequence;
021: import org.bouncycastle.asn1.DERUTF8String;
022:
023: /**
024: * Generator for RFC 3161 Time Stamp Responses.
025: */
026: public class TimeStampResponseGenerator {
027: int status;
028:
029: ASN1EncodableVector statusStrings;
030:
031: int failInfo;
032: private TimeStampTokenGenerator tokenGenerator;
033: private Set acceptedAlgorithms;
034: private Set acceptedPolicies;
035: private Set acceptedExtensions;
036:
037: public TimeStampResponseGenerator(
038: TimeStampTokenGenerator tokenGenerator,
039: Set acceptedAlgorithms) {
040: this (tokenGenerator, acceptedAlgorithms, null, null);
041: }
042:
043: public TimeStampResponseGenerator(
044: TimeStampTokenGenerator tokenGenerator,
045: Set acceptedAlgorithms, Set acceptedPolicy) {
046: this (tokenGenerator, acceptedAlgorithms, acceptedPolicy, null);
047: }
048:
049: public TimeStampResponseGenerator(
050: TimeStampTokenGenerator tokenGenerator,
051: Set acceptedAlgorithms, Set acceptedPolicies,
052: Set acceptedExtensions) {
053: this .tokenGenerator = tokenGenerator;
054: this .acceptedAlgorithms = acceptedAlgorithms;
055: this .acceptedPolicies = acceptedPolicies;
056: this .acceptedExtensions = acceptedExtensions;
057:
058: statusStrings = new ASN1EncodableVector();
059: }
060:
061: private void addStatusString(String statusString) {
062: statusStrings.add(new DERUTF8String(statusString));
063: }
064:
065: private void setFailInfoField(int field) {
066: failInfo = failInfo | field;
067: }
068:
069: private PKIStatusInfo getPKIStatusInfo() {
070: ASN1EncodableVector v = new ASN1EncodableVector();
071:
072: v.add(new DERInteger(status));
073:
074: if (statusStrings.size() > 0) {
075: v.add(new PKIFreeText(new DERSequence(statusStrings)));
076: }
077:
078: if (failInfo != 0) {
079: DERBitString failInfoBitString = new FailInfo(failInfo);
080: v.add(failInfoBitString);
081: }
082:
083: return new PKIStatusInfo(new DERSequence(v));
084: }
085:
086: public TimeStampResponse generate(TimeStampRequest request,
087: BigInteger serialNumber, Date genTime, String provider)
088: throws NoSuchAlgorithmException, NoSuchProviderException,
089: TSPException {
090: TimeStampResp resp;
091:
092: try {
093: request.validate(acceptedAlgorithms, acceptedPolicies,
094: acceptedExtensions, provider);
095:
096: status = PKIStatus.GRANTED;
097: this .addStatusString("Operation Okay");
098:
099: PKIStatusInfo pkiStatusInfo = getPKIStatusInfo();
100:
101: ContentInfo tstTokenContentInfo = null;
102: try {
103: ByteArrayInputStream bIn = new ByteArrayInputStream(
104: tokenGenerator.generate(request, serialNumber,
105: genTime, provider).toCMSSignedData()
106: .getEncoded());
107: ASN1InputStream aIn = new ASN1InputStream(bIn);
108:
109: tstTokenContentInfo = ContentInfo.getInstance(aIn
110: .readObject());
111: } catch (java.io.IOException ioEx) {
112: throw new TSPException(
113: "Timestamp token received cannot be converted to ContentInfo",
114: ioEx);
115: }
116:
117: resp = new TimeStampResp(pkiStatusInfo, tstTokenContentInfo);
118: } catch (TSPValidationException e) {
119: status = PKIStatus.REJECTION;
120:
121: this .setFailInfoField(e.getFailureCode());
122: this .addStatusString(e.getMessage());
123:
124: PKIStatusInfo pkiStatusInfo = getPKIStatusInfo();
125:
126: resp = new TimeStampResp(pkiStatusInfo, null);
127: }
128:
129: try {
130: return new TimeStampResponse(resp);
131: } catch (IOException e) {
132: throw new TSPException("created badly formatted response!");
133: }
134: }
135:
136: class FailInfo extends DERBitString {
137: FailInfo(int failInfoValue) {
138: super(getBytes(failInfoValue), getPadBits(failInfoValue));
139: }
140: }
141: }
|