/// <summary> /// Establishes a hosting agreement for the client's identity with specific identity type using the already opened connection to the profile server. /// </summary> /// <param name="IdentityType">Identity type of the new identity.</param> /// <returns>true if the function succeeds, false otherwise.</returns> public async Task <bool> EstablishProfileHostingAsync(string IdentityType = null) { log.Trace("()"); bool startConversationOk = await StartConversationAsync(); HostingPlanContract contract = null; if (IdentityType != null) { contract = new HostingPlanContract(); contract.IdentityType = IdentityType; } PsProtocolMessage requestMessage = messageBuilder.CreateRegisterHostingRequest(contract); await SendMessageAsync(requestMessage); PsProtocolMessage responseMessage = await ReceiveMessageAsync(); bool idOk = responseMessage.Id == requestMessage.Id; bool statusOk = responseMessage.Response.Status == Status.Ok; bool registerHostingOk = idOk && statusOk; bool res = startConversationOk && registerHostingOk; log.Trace("(-):{0}", res); return(res); }
/// <summary> /// Checks whether the contract received from user with hosting registration request is valid. /// <para>This function does not verify that the hosting plan exists.</para> /// </summary> /// <param name="IdentityPublicKey">Public key of the identity that wants to register hosting.</param> /// <param name="Contract">Description of the contract.</param> /// <param name="MessageBuilder">Client's network message builder.</param> /// <param name="RequestMessage">Full request message from client.</param> /// <param name="ErrorResponse">If the function fails, this is filled with error response message that is ready to be sent to the client.</param> /// <returns>true if the profile update request can be applied, false otherwise.</returns> public static bool ValidateRegisterHostingRequest(byte[] IdentityPublicKey, HostingPlanContract Contract, PsMessageBuilder MessageBuilder, PsProtocolMessage RequestMessage, out PsProtocolMessage ErrorResponse) { log.Trace("(IdentityPublicKey:'{0}')", IdentityPublicKey.ToHex()); bool res = false; ErrorResponse = null; string details = null; if (Contract == null) { Contract = new HostingPlanContract(); } if (!MessageBuilder.VerifySignedConversationRequestBodyPart(RequestMessage, Contract.ToByteArray(), IdentityPublicKey)) { log.Debug("Contract signature is invalid."); ErrorResponse = MessageBuilder.CreateErrorInvalidSignatureResponse(RequestMessage); details = ""; } if (details == null) { byte[] contractPubKey = Contract.IdentityPublicKey.ToByteArray(); bool publicKeyValid = ByteArrayComparer.Equals(contractPubKey, IdentityPublicKey); if (!publicKeyValid) { log.Debug("Contract public key '{0}' does not match client's public key '{1}'.", contractPubKey.ToHex(), IdentityPublicKey.ToHex()); details = "contract.identityPublicKey"; } } if (details == null) { DateTime?startTime = ProtocolHelper.UnixTimestampMsToDateTime(Contract.StartTime); bool startTimeValid = (startTime != null) && ((startTime.Value - DateTime.UtcNow).TotalMinutes >= -60); if (!startTimeValid) { if (startTime == null) { log.Debug("Invalid contract start time timestamp {0}.", Contract.StartTime); } else { log.Debug("Contract start time {0} is more than 1 hour in the past.", startTime.Value.ToString("yyyy-MM-dd HH:mm:ss")); } details = "contract.startTime"; } } if (details == null) { int typeSize = Encoding.UTF8.GetByteCount(Contract.IdentityType); bool typeValid = (0 < typeSize) && (typeSize <= IdentityBase.MaxProfileTypeLengthBytes); if (!typeValid) { log.Debug("Invalid contract identity type size in bytes {0}.", typeSize); details = "contract.identityType"; } } if (details == null) { res = true; } else { if (ErrorResponse == null) { ErrorResponse = MessageBuilder.CreateErrorInvalidValueResponse(RequestMessage, details); } } log.Trace("(-):{0}", res); return(res); }