/// <summary> /// End get additional aggregator configuration data (async) /// </summary> /// <param name="asyncResult"></param> /// <returns>Aggregator configuration data</returns> public AggregatorConfig EndGetAggregatorConfig(IAsyncResult asyncResult) { if (_signingServiceProtocol == null) { throw new KsiServiceException("Signing service protocol is missing from service."); } KsiServiceAsyncResult serviceAsyncResult = GetKsiServiceAsyncResult(asyncResult); if (!serviceAsyncResult.IsCompleted) { serviceAsyncResult.AsyncWaitHandle.WaitOne(); } byte[] data = _signingServiceProtocol.EndGetAggregatorConfig(serviceAsyncResult); PduPayload payload = AggregatorConfigRequestResponseParser.Parse(data); AggregatorConfigResponsePayload configResponsePayload = payload as AggregatorConfigResponsePayload; if (configResponsePayload == null) { Logger.Warn("Aggregator config request failed. Invalid response payload.{0}Payload:{0}{1}", Environment.NewLine, payload); throw new KsiServiceException("Invalid config response payload. Type: " + payload.Type); } return(new AggregatorConfig(configResponsePayload)); }
/// <summary> /// GEt legacy response payload. /// </summary> /// <param name="pdu"></param> /// <param name="requestId"></param> /// <returns></returns> private PduPayload GetLegacyResponsePayload(LegacyPdu pdu, ulong?requestId) { PduPayload payload = pdu.Payload; if (payload == null && pdu.ErrorPayload == null) { throw new KsiServiceException("Invalid response payload: null."); } if (payload != null && payload.Type != GetPayloadTagType(true)) { throw new KsiServiceException("Unexpected response payload tag type. Type: " + payload.Type + "; Expected type: " + GetPayloadTagType(true)); } if (pdu.ErrorPayload != null) { if (payload != null) { // If error payload exists then Payload should be null. Log it. LogUnexpectedPayloads(pdu); } throw new KsiServiceException(FormatServerErrorStatus(pdu.ErrorPayload.Status, pdu.ErrorPayload.ErrorMessage)); } CheckMacAlgorithm(pdu.Mac, _macAlgorithm); if (!LegacyPdu.ValidateMac(pdu.Encode(), pdu.Mac, _macKey)) { throw new KsiServiceException("Invalid MAC in response PDU."); } if (requestId.HasValue) { RequestResponsePayload requestResponsePayload = payload as RequestResponsePayload; if (requestResponsePayload == null) { throw new KsiServiceException("Cannot get request ID from payload. Payload type: " + payload?.GetType()); } if (requestResponsePayload.RequestId != requestId) { throw new KsiServiceException("Unknown request ID: " + requestResponsePayload.RequestId); } } ResponsePayload responsePayload = payload as ResponsePayload; if (responsePayload == null) { throw new KsiServiceException("Cannot get status from payload. Payload type: " + payload?.GetType()); } if (responsePayload.Status != 0) { throw new KsiServiceException(FormatServerErrorStatus(responsePayload.Status, responsePayload.ErrorMessage)); } return(payload); }
/// <summary> /// Get response payload. /// </summary> /// <param name="data"></param> /// <param name="pdu"></param> /// <param name="requestId"></param> /// <returns></returns> private PduPayload GetResponsePayload(byte[] data, Pdu pdu, ulong?requestId) { PduPayload payload = GetPayload(pdu, GetPayloadTagType(false), requestId); ErrorPayload errorPayload = pdu.ErrorPayload; if (payload == null && errorPayload == null) { throw new KsiServiceException("Invalid response PDU. Could not find a valid payload. PDU: " + pdu); } if (errorPayload != null) { // There should be only one payload if an error payload exists. If not then write log. if (pdu.Payloads.Count > 0) { LogUnexpectedPayloads(pdu); } throw new KsiServiceException(FormatServerErrorStatus(errorPayload.Status, errorPayload.ErrorMessage)); } CheckMacAlgorithm(pdu.Mac, _macAlgorithm); if (!Pdu.ValidateMac(data, pdu.Mac, _macKey)) { throw new KsiServiceException("Invalid MAC in response PDU."); } if (requestId.HasValue) { RequestResponsePayload requestResponsePayload = payload as RequestResponsePayload; if (requestResponsePayload == null) { throw new KsiServiceException("Cannot get request ID from payload."); } if (requestResponsePayload.RequestId != requestId) { throw new KsiServiceException("Unknown request ID: " + requestResponsePayload.RequestId); } if (requestResponsePayload.Status != 0) { throw new KsiServiceException(FormatServerErrorStatus(requestResponsePayload.Status, requestResponsePayload.ErrorMessage)); } } if (HasUnexpectedPayload(pdu, payload, GetAdditionallyAllowedPayloadTagTypes())) { LogUnexpectedPayloads(pdu); } return(payload); }
/// <summary> /// Returns true if there are payloads in PDU that should not be there (not expected and not allowed). /// </summary> /// <param name="pdu">PDU to search unexpected payloads</param> /// <param name="expectedPayload">Expected payload</param> /// <param name="allowedPayloadTagTypes">Payload tag types that are additionally allowed in PDU</param> /// <returns></returns> private static bool HasUnexpectedPayload(Pdu pdu, PduPayload expectedPayload, uint[] allowedPayloadTagTypes) { foreach (ITlvTag child in pdu.GetChildren()) { if (child.Type == Constants.PduHeader.TagType || child.Type == Constants.Pdu.MacTagType) { continue; } if (!ReferenceEquals(child, expectedPayload) && (allowedPayloadTagTypes == null || Array.IndexOf(allowedPayloadTagTypes, child.Type) < 0)) { return(true); } } return(false); }
/// <summary> /// End extend (async). /// </summary> /// <param name="asyncResult">async result</param> /// <returns>extended calendar hash chain</returns> public CalendarHashChain EndExtend(IAsyncResult asyncResult) { if (_extendingServiceProtocol == null) { throw new KsiServiceException("Extending service protocol is missing from service."); } KsiServiceAsyncResult serviceAsyncResult = GetKsiServiceAsyncResult(asyncResult); if (!serviceAsyncResult.IsCompleted) { serviceAsyncResult.AsyncWaitHandle.WaitOne(); } byte[] data = _extendingServiceProtocol.EndExtend(serviceAsyncResult); PduPayload payload = ExtendRequestResponseParser.Parse(data, serviceAsyncResult.RequestId); if (IsLegacyPduVersion) { LegacyExtendResponsePayload legacyResponsePayload = payload as LegacyExtendResponsePayload; if (legacyResponsePayload == null) { Logger.Warn("Extend request failed. Invalid response payload.{0}Payload:{0}{1}", Environment.NewLine, payload); throw new KsiServiceException("Invalid extend response payload. Type: " + payload.Type); } return(legacyResponsePayload.CalendarHashChain); } else { ExtendResponsePayload responsePayload = payload as ExtendResponsePayload; if (responsePayload == null) { Logger.Warn("Extend request failed. Invalid response payload.{0}Payload:{0}{1}", Environment.NewLine, payload); throw new KsiServiceException("Invalid extend response payload. Type: " + payload.Type); } Logger.Debug("End extend successful (request id: {0}){1}{2}", serviceAsyncResult.RequestId, Environment.NewLine, responsePayload.CalendarHashChain); return(responsePayload.CalendarHashChain); } }
private SignRequestResponsePayload GetSignResponsePayload(KsiServiceAsyncResult serviceAsyncResult) { if (_signingServiceProtocol == null) { throw new KsiServiceException("Signing service protocol is missing from service."); } if (!serviceAsyncResult.IsCompleted) { serviceAsyncResult.AsyncWaitHandle.WaitOne(); } byte[] data = _signingServiceProtocol.EndSign(serviceAsyncResult); PduPayload payload = SignRequestResponseParser.Parse(data, serviceAsyncResult.RequestId); SignRequestResponsePayload signResponsePayload = payload as SignRequestResponsePayload; if (signResponsePayload == null) { Logger.Warn("Sign request failed. Invalid response payload.{0}Payload:{0}{1}", Environment.NewLine, payload); throw new KsiServiceException("Invalid sign response payload. Type: " + payload.Type); } return(signResponsePayload); }
/// <summary> /// Create aggregation pdu TLV element from KSI header and payload. /// </summary> /// <param name="tagType">PDU TLV tag type</param> /// <param name="header">PDU header</param> /// <param name="payload">aggregation payload</param> /// <param name="hmacAlgorithm">MAC algorithm</param> /// <param name="key">hmac key</param> protected Pdu(uint tagType, PduHeader header, PduPayload payload, HashAlgorithm hmacAlgorithm, byte[] key) : base(tagType, false, false, new ITlvTag[] { header, payload, GetEmptyMacTag(hmacAlgorithm) }) { SetMacValue(hmacAlgorithm, key); }
/// <summary> /// Create aggregation request pdu TLV element from KSI header and payload. /// </summary> /// <param name="header">PDU header</param> /// <param name="payload">aggregation payload</param> /// <param name="hmacAlgorithm">HMAC algorithm</param> /// <param name="key">hmac key</param> public AggregationRequestPdu(PduHeader header, PduPayload payload, HashAlgorithm hmacAlgorithm, byte[] key) : base(Constants.AggregationRequestPdu.TagType, header, payload, hmacAlgorithm, key) { }
public LegacyExtendPdu(PduHeader header, PduPayload payload, ImprintTag mac) : base(Constants.LegacyExtendPdu.TagType, false, false, new ITlvTag[] { header, payload, mac }) { }
/// <summary> /// Calculate MAC and attach it to PDU. /// </summary> /// <param name="macAlgorithm">MAC algorithm</param> /// <param name="key">hmac key</param> /// <param name="header">KSI header</param> /// <param name="payload">KSI payload</param> public static ImprintTag GetMacTag(HashAlgorithm macAlgorithm, byte[] key, PduHeader header, PduPayload payload) { using (TlvWriter writer = new TlvWriter(new MemoryStream())) { writer.WriteTag(header); writer.WriteTag(payload); return(new ImprintTag(Constants.Pdu.MacTagType, false, false, CalculateMac(macAlgorithm, key, ((MemoryStream)writer.BaseStream).ToArray()))); } }