/// <summary> /// Process Message 0 /// </summary> /// <param name="Request">Client Provisioning request</param> /// <param name="sigmaSequenceCheck">Service Provider Sequence (State) Check</param> /// <returns>Message 0 response</returns> public M0ResponseMessage ProcessMessage0(HttpRequestMessage Request, SpSequenceCheck sigmaSequenceCheck) { log.Debug("ProcessMessage0(.) started."); if (Request == null) { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.BadRequest); options.LogThrownException(e); throw e; } if (sigmaSequenceCheck == null) { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(e); throw e; } // Check and parse Message 0 M0RequestMessage m0Received = VerifyMessage0IsValid(Request, sigmaSequenceCheck); if (m0Received == null) { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(e); throw e; } M0ResponseMessage msg0Response = new M0ResponseMessage(); msg0Response.respHeader.sessionNonce = m0Received.reqHeader.nonce; // Successful process of Message 0 log.Debug("ProcessMessage0(.) returning."); return(msg0Response); }
/// <summary> /// Retrieves the Client ID from the request /// </summary> /// <param name="request">Provisioning request</param> /// <returns>String ID of the requesting client</returns> public static string GetClientID(HttpRequestMessage request, string requestType) { log.DebugFormat("GetClientID({0}) started.", requestType); // Note: requestType==null case is handled in code farther down. if (request == null) { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.BadRequest); options.LogThrownException(e); throw e; } // Need to get Client state (id) information var result = request.Content.ReadAsStringAsync(); string jsonMsgRequest = result.Result; string ID = null; try { switch (requestType) { case "Provision": ProvisionRequestMessage pReceived = JsonConvert.DeserializeObject <ProvisionRequestMessage>(jsonMsgRequest); ID = BitConverter.ToString(pReceived.reqHeader.nonce); break; case "Msg0": M0RequestMessage m0Received = JsonConvert.DeserializeObject <M0RequestMessage>(jsonMsgRequest); ID = BitConverter.ToString(m0Received.reqHeader.nonce); break; case "Msg1": M1RequestMessage m1Received = JsonConvert.DeserializeObject <M1RequestMessage>(jsonMsgRequest); ID = BitConverter.ToString(m1Received.reqHeader.nonce); break; case "Msg3": M3RequestMessage m3Received = JsonConvert.DeserializeObject <M3RequestMessage>(jsonMsgRequest); ID = BitConverter.ToString(m3Received.reqHeader.nonce); break; default: { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(e); throw e; } } } catch (Exception msgError) { options.LogCaughtErrorException(msgError); log.DebugFormat("******* Message JSON Content Error: {0}\n", msgError); HttpResponseException newException = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(newException); throw newException; } if (ID != null) { ID = ID.Replace("-", "").Trim(); } else { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(e); throw e; } log.DebugFormat("GetClientID({0}) returning.", requestType); return(ID); }
/// <summary> /// Verify that Message 0 is valid /// </summary> /// <param name="Request">Client Message 0 Response</param> /// <param name="sigmaSequenceCheck">Service Provider Sequence (State) Check</param> /// <returns>Parsed and validated Message 0</returns> private M0RequestMessage VerifyMessage0IsValid(HttpRequestMessage request, SpSequenceCheck sigmaSequenceCheck) { log.Debug("VerifyMessage0IsValid(.) started."); if (request == null || sigmaSequenceCheck == null) { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(e); throw e; } // Update Client state if (!sigmaSequenceCheck.UpdateState(Constants.SequenceState.Msg0)) { HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.PreconditionFailed); options.LogThrownException(e); throw e; } // Check m0 and if valid, process var result = request.Content.ReadAsStringAsync(); string jsonMsg0Request = result.Result; M0RequestMessage m0Received = new M0RequestMessage(); try { m0Received = JsonConvert.DeserializeObject <M0RequestMessage>(jsonMsg0Request); } catch (Exception msg0reqError) { options.LogCaughtErrorException(msg0reqError); log.DebugFormat("******* Message 0 JSON Content Error: {0}", msg0reqError); HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(e); throw e; } string m0ReceivedString = m0Received.GetMsgString(); log.Info("******* Received M0 Request"); log.DebugFormat("{0}{1}", request.Headers, jsonMsg0Request); log.DebugFormat("M0 Base 16 Encoded String: {0}", m0ReceivedString); // Check the nonce and the base16 encoded length of the inbound request bool nonceCheckSuccess = false; try { log.Debug("Checking nonce"); nonceCheckSuccess = sigmaSequenceCheck.currentNonce.SequenceEqual(m0Received.reqHeader.nonce); } catch (Exception e) { options.LogCaughtErrorException(e); log.DebugFormat("****Message 0 Nonce Error: {0}", e); HttpResponseException newException = new HttpResponseException(System.Net.HttpStatusCode.InternalServerError); options.LogThrownException(newException); throw newException; } if (!nonceCheckSuccess) { log.Debug("Msg0 Nonce check failed"); HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.Forbidden); options.LogThrownException(e); throw e; } // Compare the reported length against the actual length (base16 string length/2) // Could BigEndian a replay attempt if the nonce field does not match. // Could also be other tampering if other fields do not pass checks. // Restart the session, and reject the request. if (!(BitConverter.ToUInt32(m0Received.reqHeader.msgLength, 0) == (m0ReceivedString.Length / 2))) { log.Debug("Msg0 Message length check failed"); HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.Forbidden); options.LogThrownException(e); throw e; } if (m0Received.reqM0Body.ExtGID.SequenceEqual(MsgInitValues.DS_EMPTY_BA4)) { log.Debug("Msg0: Extended GID wasn't sent"); HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.Forbidden); options.LogThrownException(e); throw e; } // NOTE: Extended GID = 0 indicates that IAS is selected for enclave verification. // This Service Provider only supports IAS for enclave verification at this time. // Note to ISV: if non-Intel Attestation Service (i.e. Extended GID != 0) is being used, replace this logic // to point to your service. if (!m0Received.reqM0Body.ExtGID.SequenceEqual(MsgInitValues.DS_ZERO_BA4)) { log.Debug("Msg0: Invalid Extended GID. This server only processes Extended GID = 0"); HttpResponseException e = new HttpResponseException(System.Net.HttpStatusCode.Unauthorized); options.LogThrownException(e); throw e; } log.Debug("VerifyMessage0IsValid(.) returning."); return(m0Received); }