ae_error_t CertificateProvisioningProtocol::SendM3_ReceiveM4 ( /*in */ const upse::Buffer& csrBuffer, /*in */ const upse::Buffer& quoteBuffer, /*out*/ std::list< upse::Buffer >& certificateChainList, /*out*/ platform_info_blob_wrapper_t& piBlobWrapper ) { ae_error_t status = AE_FAILURE; upse::Buffer serializedMsg3; upse::Buffer serializedMsg4; AESM_DBG_TRACE("start to send M3"); do { BREAK_IF_FALSE((m_is_initialized), status, AESM_PSE_PR_BACKEND_NOT_INITIALIZED); BREAK_IF_FALSE( (msg_next_state_M3 == m_nextState), status, AESM_PSE_PR_CALL_ORDER_ERROR); status = msg3_generate(csrBuffer, quoteBuffer, serializedMsg3); BREAK_IF_FAILED_ERR(status, AESM_PSE_PR_BACKEND_MSG3_GENERATE); // BREAK_IF_FAILED(status); AESM_DBG_TRACE("M3 generated"); status = sendReceive(serializedMsg3, serializedMsg4); BREAK_IF_FAILED(status); AESM_DBG_TRACE("start to process M4"); status = msg4_process(serializedMsg4, certificateChainList, piBlobWrapper); BREAK_IF_FAILED(status); AESM_DBG_TRACE("finished M4"); } while (0); m_nextState = msg_next_state_init; return status; }
ae_error_t CertificateProvisioningProtocol::SendM1_ReceiveM2 ( /*in */ const uint32_t gid, /*out*/ upse::Buffer& nonce, /*out*/ upse::Buffer& sigRLBuffer ) { ae_error_t status = AE_FAILURE; upse::Buffer serializedMsg1; upse::Buffer serializedMsg2; do { BREAK_IF_FALSE((m_is_initialized), status, AESM_PSE_PR_BACKEND_NOT_INITIALIZED); BREAK_IF_FALSE( (msg_next_state_M1 == m_nextState), status, AESM_PSE_PR_CALL_ORDER_ERROR); status = msg1_generate(*(const GroupId*)&gid, serializedMsg1); BREAK_IF_FAILED_ERR(status, AESM_PSE_PR_BACKEND_MSG1_GENERATE); // BREAK_IF_FAILED(status); status = sendReceive(serializedMsg1, serializedMsg2); if (AE_FAILED(status)) break; status = msg2_process(serializedMsg2, nonce, sigRLBuffer); if (AE_FAILED(status)) break; m_nextState = msg_next_state_M3; } while (0); return status; }
//********************************************************************* // Do the certificate chain provisioning logic //********************************************************************* static ae_error_t do_certificate_chain_provisioning ( /*in */ const endpoint_selection_infos_t& es_info, /*out*/ platform_info_blob_wrapper_t* pib_wrapper ) { if (NULL == pib_wrapper) return AESM_PSE_PR_BAD_POINTER_ERROR; ae_error_t status = AE_FAILURE; upse::Buffer target_info; uint32_t gid = 0; // GroupId gid = {0}; // Send to Server in M1 upse::Buffer nonce; // Receive from Server in M2 upse::Buffer sig_rl; // Receive from Server in M2 upse::Buffer csr_pse; // Send to Server in M3 upse::Buffer quote; // Send to Server in M3 std::list<upse::Buffer> certChain; // Receive from Server in M4 upse::Buffer report; // Received from PSE_pr upse::Buffer pairing_blob; // Received from PSE_pr upse::Buffer ocsp_req; // Created here from cert chain const char *szURL = EndpointSelectionInfo::instance().get_pse_provisioning_url(es_info); memset(pib_wrapper, 0, sizeof(platform_info_blob_wrapper_t)); // Receive from Server in M4 CertificateProvisioningProtocol cpp; SGX_DBGPRINT_PRINT_ANSI_STRING("Begin Certificate (PSE) Provisioning"); do { Helper::RemoveCertificateChain(); Helper::delete_ocsp_response_vlr(); #if defined(NO_PROVISIONING_SERVER) { //********************************************************************* // Use hardcoded Cert. //********************************************************************* SGX_DBGPRINT_PRINT_ANSI_STRING("Using Hard Coded Cert"); status = tPrepareForCertificateProvisioning_hardcoded_privatekey(pairing_blob); BREAK_IF_FAILED(status); /* Use the hardcoded "Public" Cert */ upse::Buffer Cert; Cert.Alloc(PUBLIC_PSE_CERT_LEN); upse::BufferWriter bwCert(Cert); uint8_t* pCert; status = bwCert.reserve(PUBLIC_PSE_CERT_LEN, &pCert); BREAK_IF_FAILED(status); memcpy_s(pCert, PUBLIC_PSE_CERT_LEN, PUBLIC_PSE_CERT, PUBLIC_PSE_CERT_LEN); certChain.push_back(Cert); } #else { status = cpp.init(szURL, es_info.pek); BREAK_IF_FAILED(status); //===================================================================== // Start: CERTIFICATE CHAIN PROVISIONING (3.6.7.1.1.2.1) //===================================================================== //********************************************************************* // Retrieve GID_SE from the QE SGX_DBGPRINT_PRINT_ANSI_STRING("quote init?"); //********************************************************************* status = do_quote_initialization(target_info, (GroupId*)&gid); BREAK_IF_FAILED(status);//keep reason for quoting failure including UPDATE required SGX_DBGPRINT_PRINT_ANSI_STRING("quote init success"); //********************************************************************* // Retrieve SIG_RL and Nonce from Intel Server. //********************************************************************* status = cpp.SendM1_ReceiveM2(*(uint32_t*)&gid, nonce, sig_rl); BREAK_IF_FAILED(status); SGX_DBGPRINT_PRINT_ANSI_STRING("send m1, receive m2 success"); Helper::read_ltp_blob(pairing_blob); // Note: failure during read_ltp_blob is okay, pairing_blob will be empty and get filled in by enclave //********************************************************************* // Generate ECDSA key pair, CSR_pse, and REPORT in enclave (PSE_Pr). //********************************************************************* status = tPrepareForCertificateProvisioning(nonce, target_info, csr_pse, report, pairing_blob); BREAK_IF_FAILED(status); SGX_DBGPRINT_PRINT_ANSI_STRING("prepare for cert pv success"); //********************************************************************* // Call QE to convert REPORT to name-based QUOTE using SIG_RL //********************************************************************* status = do_get_quote(report, sig_rl, quote); BREAK_IF_TRUE((AESM_AE_OUT_OF_EPC == status), status, AESM_AE_OUT_OF_EPC); BREAK_IF_FAILED_ERR(status, AESM_CP_ATTESTATION_FAILURE); SGX_DBGPRINT_PRINT_ANSI_STRING("get quote success"); //********************************************************************* // Retrieve the Certificate Chain from Intel Server. //********************************************************************* status = cpp.SendM3_ReceiveM4(csr_pse, quote, certChain, *pib_wrapper); BREAK_IF_TRUE((PSE_PRS_OK != cpp.GetProtocolResponseStatus()), status, AESM_CP_ATTESTATION_FAILURE); BREAK_IF_FAILED(status); SGX_DBGPRINT_PRINT_ANSI_STRING("send m3, receive m4 success"); } #endif //********************************************************************* // Save the Certificate Chain to persistent storage. //********************************************************************* status = Helper::SaveCertificateChain(certChain); BREAK_IF_FAILED(status); SGX_DBGPRINT_PRINT_ANSI_STRING("save cert success"); //********************************************************************* // Save the sealed pairing blob to persistent storage. //********************************************************************* status = Helper::write_ltp_blob(pairing_blob); BREAK_IF_FAILED(status); SGX_DBGPRINT_PRINT_ANSI_STRING("write blob success"); status = AE_SUCCESS; SGX_DBGPRINT_PRINT_ANSI_STRING("End of Certificate (PSE) Provisioning"); } while (0); status = ConvertBackendStatus(cpp, status); return status; }