You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
5.0 KiB
188 lines
5.0 KiB
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR) |
|
#pragma warning disable |
|
using System; |
|
using System.IO; |
|
using System.Text; |
|
|
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Tsp; |
|
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities; |
|
|
|
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tsp |
|
{ |
|
/** |
|
* Base class for an RFC 3161 Time Stamp Response object. |
|
*/ |
|
public class TimeStampResponse |
|
{ |
|
private TimeStampResp resp; |
|
private TimeStampToken timeStampToken; |
|
|
|
public TimeStampResponse( |
|
TimeStampResp resp) |
|
{ |
|
this.resp = resp; |
|
|
|
if (resp.TimeStampToken != null) |
|
{ |
|
timeStampToken = new TimeStampToken(resp.TimeStampToken); |
|
} |
|
} |
|
|
|
/** |
|
* Create a TimeStampResponse from a byte array containing an ASN.1 encoding. |
|
* |
|
* @param resp the byte array containing the encoded response. |
|
* @throws TspException if the response is malformed. |
|
* @throws IOException if the byte array doesn't represent an ASN.1 encoding. |
|
*/ |
|
public TimeStampResponse( |
|
byte[] resp) |
|
: this(readTimeStampResp(new Asn1InputStream(resp))) |
|
{ |
|
} |
|
|
|
/** |
|
* Create a TimeStampResponse from an input stream containing an ASN.1 encoding. |
|
* |
|
* @param input the input stream containing the encoded response. |
|
* @throws TspException if the response is malformed. |
|
* @throws IOException if the stream doesn't represent an ASN.1 encoding. |
|
*/ |
|
public TimeStampResponse( |
|
Stream input) |
|
: this(readTimeStampResp(new Asn1InputStream(input))) |
|
{ |
|
} |
|
|
|
private static TimeStampResp readTimeStampResp( |
|
Asn1InputStream input) |
|
{ |
|
try |
|
{ |
|
return TimeStampResp.GetInstance(input.ReadObject()); |
|
} |
|
catch (ArgumentException e) |
|
{ |
|
throw new TspException("malformed timestamp response: " + e, e); |
|
} |
|
catch (InvalidCastException e) |
|
{ |
|
throw new TspException("malformed timestamp response: " + e, e); |
|
} |
|
} |
|
|
|
public int Status |
|
{ |
|
get { return resp.Status.Status.IntValue; } |
|
} |
|
|
|
public string GetStatusString() |
|
{ |
|
if (resp.Status.StatusString == null) |
|
{ |
|
return null; |
|
} |
|
|
|
StringBuilder statusStringBuf = new StringBuilder(); |
|
PkiFreeText text = resp.Status.StatusString; |
|
for (int i = 0; i != text.Count; i++) |
|
{ |
|
statusStringBuf.Append(text[i].GetString()); |
|
} |
|
|
|
return statusStringBuf.ToString(); |
|
} |
|
|
|
public PkiFailureInfo GetFailInfo() |
|
{ |
|
if (resp.Status.FailInfo == null) |
|
{ |
|
return null; |
|
} |
|
|
|
return new PkiFailureInfo(resp.Status.FailInfo); |
|
} |
|
|
|
public TimeStampToken TimeStampToken |
|
{ |
|
get { return timeStampToken; } |
|
} |
|
|
|
/** |
|
* Check this response against to see if it a well formed response for |
|
* the passed in request. Validation will include checking the time stamp |
|
* token if the response status is GRANTED or GRANTED_WITH_MODS. |
|
* |
|
* @param request the request to be checked against |
|
* @throws TspException if the request can not match this response. |
|
*/ |
|
public void Validate( |
|
TimeStampRequest request) |
|
{ |
|
TimeStampToken tok = this.TimeStampToken; |
|
|
|
if (tok != null) |
|
{ |
|
TimeStampTokenInfo tstInfo = tok.TimeStampInfo; |
|
|
|
if (request.Nonce != null && !request.Nonce.Equals(tstInfo.Nonce)) |
|
{ |
|
throw new TspValidationException("response contains wrong nonce value."); |
|
} |
|
|
|
if (this.Status != (int) PkiStatus.Granted && this.Status != (int) PkiStatus.GrantedWithMods) |
|
{ |
|
throw new TspValidationException("time stamp token found in failed request."); |
|
} |
|
|
|
if (!Arrays.ConstantTimeAreEqual(request.GetMessageImprintDigest(), tstInfo.GetMessageImprintDigest())) |
|
{ |
|
throw new TspValidationException("response for different message imprint digest."); |
|
} |
|
|
|
if (!tstInfo.MessageImprintAlgOid.Equals(request.MessageImprintAlgOid)) |
|
{ |
|
throw new TspValidationException("response for different message imprint algorithm."); |
|
} |
|
|
|
Asn1.Cms.Attribute scV1 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificate]; |
|
Asn1.Cms.Attribute scV2 = tok.SignedAttributes[PkcsObjectIdentifiers.IdAASigningCertificateV2]; |
|
|
|
if (scV1 == null && scV2 == null) |
|
{ |
|
throw new TspValidationException("no signing certificate attribute present."); |
|
} |
|
|
|
if (scV1 != null && scV2 != null) |
|
{ |
|
/* |
|
* RFC 5035 5.4. If both attributes exist in a single message, |
|
* they are independently evaluated. |
|
*/ |
|
} |
|
|
|
if (request.ReqPolicy != null && !request.ReqPolicy.Equals(tstInfo.Policy)) |
|
{ |
|
throw new TspValidationException("TSA policy wrong for request."); |
|
} |
|
} |
|
else if (this.Status == (int) PkiStatus.Granted || this.Status == (int) PkiStatus.GrantedWithMods) |
|
{ |
|
throw new TspValidationException("no time stamp token found and one expected."); |
|
} |
|
} |
|
|
|
/** |
|
* return the ASN.1 encoded representation of this object. |
|
*/ |
|
public byte[] GetEncoded() |
|
{ |
|
return resp.GetEncoded(); |
|
} |
|
} |
|
} |
|
#pragma warning restore |
|
#endif
|
|
|