/// <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);
        }
Exemple #7
0
 /// <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 })
 {
 }
Exemple #10
0
 /// <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())));
     }
 }