//parse_key_file(): // parse the RSA key file //Parameters: // [IN] key_path: the key file name user inputs // [OUT] prsa: the rsa structure parsed from the key file // pkey_type: the key type //Return Value: // true: success // false: fail bool parse_key_file(const char *key_path, rsa_params_t *prsa, int *pkey_type) { assert(prsa != NULL && pkey_type != NULL); if(key_path == NULL) { *pkey_type = NO_KEY; return false; } //read and trim the file content std::string file_content = read_key_file(key_path); if(file_content.empty() == true) { *pkey_type = UNIDENTIFIABLE_KEY; return false; } const unsigned char *buffer = (const unsigned char *)file_content.c_str(); //decode the buffer to decoded_string size_t result = strlen((const char *)buffer); int retlen = 0; int key_type = UNIDENTIFIABLE_KEY; unsigned char *decoded_string = decode_key_body(const_cast<unsigned char*>(buffer), result, &key_type, &retlen); if(!decoded_string) { *pkey_type = key_type; return false; } //get RSA from the decoded string bool ret = false; if(key_type == PRIVATE_KEY) { ret = convert_from_pri_key(decoded_string, retlen, prsa); } else { ret = convert_from_pub_key(decoded_string, retlen, prsa); } if(ret == false) { se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR); free(decoded_string); *pkey_type = key_type; return false; } else { se_trace(SE_TRACE_DEBUG, "Parsing key file is OK.\n"); } *pkey_type = key_type; free(decoded_string); return true; }
bool CMetadata::build_layout_entries(vector<layout_t> &layouts) { uint32_t size = (uint32_t)(layouts.size() * sizeof(layout_t)); layout_t *layout_table = (layout_t *) alloc_buffer_from_metadata(size); if(layout_table == NULL) { se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR); return false; } m_metadata->dirs[DIR_LAYOUT].offset = (uint32_t)PTR_DIFF(layout_table, m_metadata); m_metadata->dirs[DIR_LAYOUT].size = size; uint64_t rva = calculate_sections_size(); for(uint32_t i = 0; i < layouts.size(); i++) { memcpy_s(layout_table, sizeof(layout_t), &layouts[i], sizeof(layout_t)); if(!IS_GROUP_ID(layouts[i].entry.id)) { layout_table->entry.rva = rva; rva += (uint64_t)layouts[i].entry.page_count << SE_PAGE_SHIFT; } else { for (uint32_t j = 0; j < layouts[i].group.entry_count; j++) { layout_table->group.load_step += (uint64_t)layouts[i-j-1].entry.page_count << SE_PAGE_SHIFT; } rva += layouts[i].group.load_times * layout_table->group.load_step; } layout_table++; } // enclave virtual size m_metadata->enclave_size = calculate_enclave_size(rva); if(m_metadata->enclave_size == (uint64_t)-1) { se_trace(SE_TRACE_ERROR, OUT_OF_EPC_ERROR); return false; } // the last guard page entry to round the enclave size to power of 2 if(m_metadata->enclave_size - rva > 0) { layout_table = (layout_t *)alloc_buffer_from_metadata(sizeof(layout_t)); if(layout_table == NULL) { se_trace(SE_TRACE_ERROR, INVALID_ENCLAVE_ERROR); return false; } layout_table->entry.id = LAYOUT_ID_GUARD; layout_table->entry.rva = rva; layout_table->entry.page_count = (uint32_t)((m_metadata->enclave_size - rva) >> SE_PAGE_SHIFT); m_metadata->dirs[DIR_LAYOUT].size += (uint32_t)sizeof(layout_t); }
extern "C" bool copy_file(const char *source_path, const char *dest_path) { std::ifstream ifs(source_path, std::ios::binary|std::ios::in); if(!ifs.good()) { se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, source_path); return false; } std::ofstream ofs(dest_path, std::ios::binary|std::ios::out); if(!ofs.good()) { se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, dest_path); return false; } ofs << ifs.rdbuf(); return true; }
int EnclaveCreatorST::create_enclave(secs_t *secs, sgx_enclave_id_t *enclave_id, void **start_addr, bool ae) { if(!secs || !enclave_id || !start_addr) { se_trace(SE_TRACE_DEBUG, "ERROR: Bad pointer.\n"); return SGX_ERROR_UNEXPECTED; } UNUSED(ae); memset(m_enclave_hash, 0, SGX_HASH_SIZE); if((m_ctx = EVP_MD_CTX_create()) == NULL) { se_trace(SE_TRACE_DEBUG, "ERROR - EVP_MD_CTX_create: %s.\n", ERR_error_string(ERR_get_error(), NULL)); return SGX_ERROR_UNEXPECTED; } if(EVP_DigestInit_ex(m_ctx, EVP_sha256(), NULL) != 1) { se_trace(SE_TRACE_DEBUG, "ERROR - EVP_DigestInit_ex: %s.\n", ERR_error_string(ERR_get_error(), NULL)); return SGX_ERROR_UNEXPECTED; } uint8_t ecreat_val[SIZE_NAMED_VALUE] = "ECREATE"; uint8_t data_block[DATA_BLOCK_SIZE]; size_t offset = 0; memset(data_block, 0, DATA_BLOCK_SIZE); memcpy_s(data_block, sizeof(data_block), ecreat_val, SIZE_NAMED_VALUE); offset += SIZE_NAMED_VALUE; memcpy_s(&data_block[offset], sizeof(data_block)-offset, &secs->ssa_frame_size, sizeof(secs->ssa_frame_size)); offset += sizeof(secs->ssa_frame_size); memcpy_s(&data_block[offset], sizeof(data_block)-offset, &secs->size, sizeof(secs->size)); if(EVP_DigestUpdate(m_ctx, &data_block, DATA_BLOCK_SIZE) != 1) { se_trace(SE_TRACE_DEBUG, "ERROR - EVP_DigestUpdate: %s.\n", ERR_error_string(ERR_get_error(), NULL)); return SGX_ERROR_UNEXPECTED; } *enclave_id = m_eid; *start_addr = secs->base; return SGX_SUCCESS; }
extern "C" bool write_data_to_file(const char *filename, std::ios_base::openmode mode, uint8_t *buf, size_t bsize, long offset) { if(filename == NULL || (buf == NULL && bsize != 0) || (buf != NULL && bsize == 0)) return false; std::ofstream ofs(filename, mode); if(!ofs.good()) { se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, filename); return false; } ofs.seekp(offset, std::ios::beg); ofs.write(reinterpret_cast<char*>(buf), bsize); if(ofs.fail()) { se_trace(SE_TRACE_ERROR, WRITE_FILE_ERROR, filename); return false; } return true; }
extern "C" long get_file_size(const char *filename) { std::ifstream ifs(filename, std::ios::in | std::ios::binary); if(!ifs.good()) { se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, filename); return -1; } ifs.seekg(0, std::ios::end); size_t size = (size_t)ifs.tellg(); return size; }
bool CMetadata::modify_metadata(const xml_parameter_t *parameter) { assert(parameter != NULL); m_metadata->version = META_DATA_MAKE_VERSION(MAJOR_VERSION,MINOR_VERSION ); m_metadata->size = offsetof(metadata_t, data); m_metadata->tcs_policy = (uint32_t)parameter[TCSPOLICY].value; m_metadata->ssa_frame_size = SSA_FRAME_SIZE; //stack/heap must be page-align if(parameter[STACKMAXSIZE].value % ALIGN_SIZE) { se_trace(SE_TRACE_ERROR, SET_STACK_SIZE_ERROR); return false; } if(parameter[HEAPMAXSIZE].value % ALIGN_SIZE) { se_trace(SE_TRACE_ERROR, SET_HEAP_SIZE_ERROR); return false; } // LE setting: HW != 0, Licensekey = 1 // Other enclave setting: HW = 0, Licensekey = 0 if((parameter[HW].value == 0 && parameter[LAUNCHKEY].value != 0) || (parameter[HW].value != 0 && parameter[LAUNCHKEY].value == 0)) { se_trace(SE_TRACE_ERROR, SET_HW_LE_ERROR); return false; } m_metadata->max_save_buffer_size = MAX_SAVE_BUF_SIZE; m_metadata->magic_num = METADATA_MAGIC; m_metadata->desired_misc_select = 0; m_metadata->enclave_css.body.misc_select = (uint32_t)parameter[MISCSELECT].value; m_metadata->enclave_css.body.misc_mask = (uint32_t)parameter[MISCMASK].value; m_create_param.heap_max_size = parameter[HEAPMAXSIZE].value; m_create_param.ssa_frame_size = SSA_FRAME_SIZE; m_create_param.stack_max_size = parameter[STACKMAXSIZE].value; m_create_param.tcs_max_num = (uint32_t)parameter[TCSNUM].value; m_create_param.tcs_policy = m_metadata->tcs_policy; return true; }
int EnclaveCreatorST::get_enclave_info(uint8_t *hash, int size, uint64_t *quota) { if(hash == NULL || size != SGX_HASH_SIZE || m_hash_valid_flag == false) { se_trace(SE_TRACE_DEBUG, "ERROR: something went wrong in the function get_enclave_hash().\n"); return SGX_ERROR_UNEXPECTED; } else { memcpy_s(hash, size, m_enclave_hash, SGX_HASH_SIZE); } *quota = m_quota; return SGX_SUCCESS; }
extern "C" bool read_file_to_buf(const char *filename, uint8_t *buf, size_t bsize) { if(filename == NULL || buf == NULL || bsize == 0) return false; std::ifstream ifs(filename, std::ios::binary|std::ios::in); if(!ifs.good()) { se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, filename); return false; } ifs.read(reinterpret_cast<char *> (buf), bsize); if(ifs.fail()) { return false; } return true; }
static bool traverser_parameter(const char *temp_name, const char *temp_text, xml_parameter_t *parameter, int parameter_count) { assert(temp_name != NULL && parameter != NULL); uint64_t temp_value=0; if(temp_text == NULL) { se_trace(SE_TRACE_ERROR, LACK_VALUE_FOR_ELEMENT_ERROR, temp_name); return false; } else { if(strchr(temp_text, '-')) { se_trace(SE_TRACE_ERROR, INVALID_VALUE_FOR_ELEMENT_ERROR, temp_name); return false; } errno = 0; char* endptr = NULL; temp_value = (uint64_t)strtoull(temp_text, &endptr, 0); if(*endptr!='\0'||errno!=0) //Invalid value or valid value but out of the representable range { se_trace(SE_TRACE_ERROR, INVALID_VALUE_FOR_ELEMENT_ERROR, temp_name); return false; } } //Look for the matched one int i=0; for(;i<parameter_count&&STRCMP(temp_name,parameter[i].name);i++); if(i>=parameter_count) //no matched, return false { se_trace(SE_TRACE_ERROR, UNREC_ELEMENT_ERROR, temp_name); return false; } //found one matched if(parameter[i].flag==1) //repeated definition of XML element, return false { se_trace(SE_TRACE_ERROR, REPEATED_DEFINE_ERROR, temp_name); return false; } parameter[i].flag = 1; if((temp_value<parameter[i].min_value)|| (temp_value>parameter[i].max_value)) // the value is invalid, return false { se_trace(SE_TRACE_ERROR, VALUE_OUT_OF_RANGE_ERROR, temp_name); return false; } parameter[i].value = temp_value; return true; }
int EnclaveCreatorST::init_enclave(sgx_enclave_id_t enclave_id, enclave_css_t *enclave_css, SGXLaunchToken *lc, le_prd_css_file_t *prd_css_file) { assert(m_ctx != NULL); UNUSED(enclave_id), UNUSED(enclave_css), UNUSED(lc), UNUSED(prd_css_file); uint8_t temp_hash[SGX_HASH_SIZE]; memset(temp_hash, 0, SGX_HASH_SIZE); unsigned int hash_len; /* Complete computation of the SHA256 digest and store the result into the hash. */ if(EVP_DigestFinal_ex(m_ctx, temp_hash, &hash_len) != 1) { se_trace(SE_TRACE_DEBUG, "ERROR - EVP_digestFinal_ex: %s.\n", ERR_error_string(ERR_get_error(), NULL)); return SGX_ERROR_UNEXPECTED; } for (int i = 0; i< SGX_HASH_SIZE; i++) { m_enclave_hash[i] = temp_hash[i]; } m_hash_valid_flag = true; return SGX_SUCCESS; }
//read_key_file // read the input file line by line and trim the blank characters for each line //Parameters // [IN] key_path: the file required to be read static std::string read_key_file(const char *key_path) { assert(key_path != NULL); std::ifstream ifs(key_path, std::ios::in | std::ios::binary); if(!ifs.good()) { se_trace(SE_TRACE_ERROR, READ_FILE_ERROR, key_path); return ""; } std::string file_content; std::string str; while(std::getline(ifs, str)) { str.erase(std::remove_if(str.begin(), str.end(), ::isspace), str.end()); if(str.length() != 0) { file_content += str; file_content += "\n"; // Add '\n' for each line } } ifs.close(); return file_content; }
static unsigned char* decode_key_body(unsigned char *buffer, size_t slen, int *key_type, int *rlen) { assert(buffer!=NULL && key_type!=NULL && rlen!=NULL); const char pri_key_header[] = "-----BEGINRSAPRIVATEKEY-----" ; const char pri_key_end[] = "-----ENDRSAPRIVATEKEY-----\n"; const char pub_key_header[] = "-----BEGINPUBLICKEY-----"; const char pub_key_end[] = "-----ENDPUBLICKEY-----\n"; int ktype = UNIDENTIFIABLE_KEY; int offset_pri = (int)(slen - strlen(pri_key_end)); int offset_pub = (int)(slen - strlen(pub_key_end)); if(offset_pub<=0 || offset_pri<=0) { se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR); *key_type = UNIDENTIFIABLE_KEY; return NULL; } //check the file header and footer to get the key type if(!strncmp((const char *)buffer, pri_key_header, strlen(pri_key_header))) { //make sure the key file isn't an emcrypted PEM private key file. if((!strncmp((const char *)(buffer+offset_pri), pri_key_end, strlen(pri_key_end))) && !strstr((const char *)buffer, "Proc-Type: 4, ENCRYPTED")) { *(buffer+offset_pri-1) = '\0'; //remove the pri_key_end string ktype = PRIVATE_KEY; } else { ktype = UNIDENTIFIABLE_KEY; } } else if(!strncmp((const char *)buffer, pub_key_header, strlen(pub_key_header))) { if(!strncmp((const char *)(buffer+offset_pub), pub_key_end, strlen(pub_key_end))) { *(buffer + offset_pub-1) = '\0'; ktype = PUBLIC_KEY; } else { ktype = UNIDENTIFIABLE_KEY; } } else { ktype = UNIDENTIFIABLE_KEY; } //get the body contents of the key file size_t body_size = 0, body_offset = 0; if(ktype == PRIVATE_KEY) { body_size = strlen((const char *)buffer) - strlen(pri_key_header); body_offset = strlen(pri_key_header)+1; } else if(ktype == PUBLIC_KEY) { body_size = strlen((const char *)buffer) - strlen(pub_key_header); body_offset = strlen(pub_key_header)+1; } else { se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR); *key_type = ktype; return NULL; } unsigned char *decoded_string = (unsigned char *)malloc(sizeof(char)*body_size); if(!decoded_string) { se_trace(SE_TRACE_ERROR, NO_MEMORY_ERROR); *key_type = ktype; return NULL; } memset(decoded_string, 0, body_size); int retlen = base64_decode(buffer+body_offset, body_size, decoded_string); if(retlen == 0) { se_trace(SE_TRACE_ERROR, KEY_FORMAT_ERROR); *key_type = ktype; free(decoded_string); return NULL; } *key_type = ktype; *rlen = retlen; return decoded_string; }
static bool convert_from_pub_key(const unsigned char *psrc, unsigned int slen, rsa_params_t *rsa) { assert(NULL != psrc && NULL != rsa); if(slen<PUB_CONPONENTS_SIZE) { return false; } //encoded OID sequence (OBJECT IDENTIFIER = 1.2.840.113549.1.1.1) unsigned char OID_str[] = {0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00}; size_t index = 0; if((unsigned int)psrc[index]==0x30 && (unsigned int)psrc[index+1] == 0x82) index += 4; else if((unsigned int)psrc[index]==0x30 && (unsigned int)psrc[index+1] == 0x81) index += 3; else return false; unsigned int i=0; for(; i<sizeof(OID_str); i++) { if((unsigned int)psrc[index+i] != (unsigned int)OID_str[i]) break; } if(i<sizeof(OID_str)) { return false; } index += sizeof(OID_str); if((unsigned int)psrc[index] == 0x03 && (unsigned int)psrc[index+1] == 0x82)//0382 index += 4; else if((unsigned int)psrc[index] == 0x03 && (unsigned int)psrc[index+1] == 0x81)//0381 index += 3; else return false; if((unsigned int)psrc[index] != 0x00) return false; index++; if((unsigned int)psrc[index] == 0x30 &&(unsigned int)psrc[index+1] == 0x82) index += 4; else if((unsigned int)psrc[index] == 0x30 &&(unsigned int)psrc[index+1] == 0x81) index += 3; else return false; if((unsigned int)psrc[index] == 0x02 &&(unsigned int)psrc[index+1] == 0x82) index += 4; else if((unsigned int)psrc[index] == 0x02 && (unsigned int)psrc[index+1] == 0x81) index += 3; if((unsigned int)psrc[index] == 0x00) index ++; //get N memset(rsa, 0, sizeof(rsa_params_t)); memcpy_s(rsa->n, sizeof(rsa->n), psrc+index, N_SIZE_IN_BYTES); convert_string((unsigned char *)rsa->n, sizeof(rsa->n)); //get EXPONENT index += N_SIZE_IN_BYTES; if(!((unsigned int)psrc[index] == 0x02 &&(unsigned int)psrc[index+1] == 0x01)) //"0x01" indicates the size of e is 1 byte { se_trace(SE_TRACE_ERROR, "Only '3' is accepted as the Exponent value.\n"); return false; } index += 2; unsigned int temp = *(psrc+index); if(temp != 0x03) { se_trace(SE_TRACE_ERROR, "Key Exponent is %#x. Only '3' is accepted as the Exponent value.\n", temp); return false; } temp = temp&0x0f; memcpy_s(rsa->e, sizeof(rsa->e), &temp, sizeof(unsigned int)); return true; }
int EnclaveCreatorST::add_enclave_page(sgx_enclave_id_t enclave_id, void *src, uint64_t offset, const sec_info_t &sinfo, uint32_t attr) { assert(m_ctx!=NULL); UNUSED(enclave_id); void* source = src; uint8_t color_page[SE_PAGE_SIZE]; if(!source) { memset(color_page, 0, SE_PAGE_SIZE); source = reinterpret_cast<void*>(&color_page); } for(unsigned int i = 0; i< sizeof(sinfo.reserved)/sizeof(sinfo.reserved[0]); i++) { if(sinfo.reserved[i] != 0) return SGX_ERROR_UNEXPECTED; } /* sinfo.flags[64:16] should be 0 */ if((sinfo.flags & (~SI_FLAGS_EXTERNAL)) != 0) { return SGX_ERROR_UNEXPECTED; } //check the page attributes if (!(attr & PAGE_ATTR_EADD)) { return SGX_SUCCESS; } uint64_t page_offset = (uint64_t)offset; uint8_t eadd_val[SIZE_NAMED_VALUE] = "EADD\0\0\0"; uint8_t data_block[DATA_BLOCK_SIZE]; size_t db_offset = 0; memset(data_block, 0, DATA_BLOCK_SIZE); memcpy_s(data_block, sizeof(data_block), eadd_val, SIZE_NAMED_VALUE); db_offset += SIZE_NAMED_VALUE; memcpy_s(data_block+db_offset, sizeof(data_block)-db_offset, &page_offset, sizeof(page_offset)); db_offset += sizeof(page_offset); memcpy_s(data_block+db_offset, sizeof(data_block)-db_offset, &sinfo, sizeof(data_block)-db_offset); if(EVP_DigestUpdate(m_ctx, data_block, DATA_BLOCK_SIZE) != 1) { se_trace(SE_TRACE_DEBUG, "ERROR - EVP_digestUpdate: %s.\n", ERR_error_string(ERR_get_error(), NULL)); return SGX_ERROR_UNEXPECTED; } /* If the page need to eextend, do eextend. */ if((attr & ADD_EXTEND_PAGE) == ADD_EXTEND_PAGE) { uint8_t *pdata = (uint8_t *)source; uint8_t eextend_val[SIZE_NAMED_VALUE] = "EEXTEND"; #define EEXTEND_TIME 4 for(int i = 0; i < SE_PAGE_SIZE; i += (DATA_BLOCK_SIZE * EEXTEND_TIME)) { db_offset = 0; memset(data_block, 0, DATA_BLOCK_SIZE); memcpy_s(data_block, sizeof(data_block), eextend_val, SIZE_NAMED_VALUE); db_offset += SIZE_NAMED_VALUE; memcpy_s(data_block+db_offset, sizeof(data_block)-db_offset, &page_offset, sizeof(page_offset)); if(EVP_DigestUpdate(m_ctx, data_block, DATA_BLOCK_SIZE) != 1) { se_trace(SE_TRACE_DEBUG, "ERROR - EVP_digestUpdate: %s.\n", ERR_error_string(ERR_get_error(), NULL)); return SGX_ERROR_UNEXPECTED; } for(int j = 0; j < EEXTEND_TIME; j++) { memcpy_s(data_block, sizeof(data_block), pdata, DATA_BLOCK_SIZE); if(EVP_DigestUpdate(m_ctx, data_block, DATA_BLOCK_SIZE) != 1) { se_trace(SE_TRACE_DEBUG, "ERROR - EVP_digestUpdate: %s.\n", ERR_error_string(ERR_get_error(), NULL)); return SGX_ERROR_UNEXPECTED; } pdata += DATA_BLOCK_SIZE; page_offset += DATA_BLOCK_SIZE; } } } m_quota += SE_PAGE_SIZE; return SGX_SUCCESS; }
static bool convert_from_pri_key(const unsigned char *psrc, unsigned int slen, rsa_params_t *rsa) { assert(NULL != psrc && NULL != rsa); if(slen<PRI_COMPONENTS_SIZE) { return false; } int index = 0; if((int)psrc[index]== 0x30 &&(int)psrc[index+1] == 0x82) index += 4; else if((int)psrc[index] == 0x30 && (int)psrc[index+1] == 0x81) index += 3; else return false; if(!((int)psrc[index] == 0x02 && (int)psrc[index+1] == 0x01))// version number must be 0x0102 { return false; } index += 2; if((int)psrc[index] != 0x00) return false; index += 6; memset(rsa, 0, sizeof(rsa_params_t)); //get the module memcpy_s(rsa->n, sizeof(rsa->n), psrc+index, N_SIZE_IN_BYTES); convert_string((unsigned char *)rsa->n, sizeof(rsa->n)); //get EXPONENT index += N_SIZE_IN_BYTES; if(!((unsigned int)psrc[index] == 0x02 &&(unsigned int)psrc[index+1] == 0x01)) //"0x01" indicates the size of e is 1 byte { se_trace(SE_TRACE_ERROR, "Only '3' is accepted as the Exponent value.\n"); return false; } index += 2; unsigned int temp = *(psrc+index); if(temp != 0x03) { se_trace(SE_TRACE_ERROR, "Key Exponent is %#x. Only '3' is accepted as the Exponent value.\n", temp); return false; } temp = temp&0x0f; memcpy_s(rsa->e, sizeof(rsa->e), &temp, sizeof(unsigned int)); //get D index += 1; if((unsigned int)psrc[index]!=0x02) { return false; } index = index+4; if((int)psrc[index] == 0) index += 1; memcpy_s(rsa->d, sizeof(rsa->d), psrc+index, D_SIZE_IN_BYTES); convert_string((unsigned char *)rsa->d, sizeof(rsa->d)); //get P index += D_SIZE_IN_BYTES; if((unsigned int)psrc[index]!=0x02) { return false; } index = index+4; if((int)psrc[index] == 0) index += 1; memcpy_s(rsa->p, sizeof(rsa->p), psrc+index, P_SIZE_IN_BYTES); convert_string((unsigned char *)rsa->p, sizeof(rsa->p)); //get Q index += P_SIZE_IN_BYTES; if((unsigned int)psrc[index]!=0x02) { return false; } index = index+4; if((int)psrc[index] == 0) index += 1; memcpy_s(rsa->q, sizeof(rsa->q), psrc+index, Q_SIZE_IN_BYTES); convert_string((unsigned char *)rsa->q, sizeof(rsa->q)); //get DMP1 index += Q_SIZE_IN_BYTES; if((unsigned int)psrc[index]!=0x02) { return false; } index += 4; if((int)psrc[index] == 0) index += 1; memcpy_s(rsa->dmp1, sizeof(rsa->dmp1), psrc+index, DMP1_SIZE_IN_BYTES); convert_string((unsigned char *)rsa->dmp1, sizeof(rsa->dmp1)); //get DMQ1 index += DMP1_SIZE_IN_BYTES; if((unsigned int)psrc[index]!=0x02) { return false; } index += 4; if((int)psrc[index] == 0) index += 1; memcpy_s(rsa->dmq1, sizeof(rsa->dmq1), psrc+index, DMQ1_SIZE_IN_BYTES); convert_string((unsigned char *)rsa->dmq1, sizeof(rsa->dmq1)); //get IQMP index += DMQ1_SIZE_IN_BYTES; if((unsigned int)psrc[index]!=0x02) { return false; } index += 3; if((int)psrc[index] == 0) index += 1; memcpy_s(rsa->iqmp, sizeof(rsa->iqmp), psrc+index, IQMP_SIZE_IN_BYTES); convert_string((unsigned char *)rsa->iqmp, sizeof(rsa->iqmp)); return true; }
bool parse_metadata_file(const char *xmlpath, xml_parameter_t *parameter, int parameter_count) { const char* temp_name=NULL; assert(parameter != NULL); if(xmlpath == NULL) // user didn't define the metadata xml file. { se_trace(SE_TRACE_NOTICE, "Use default metadata...\n"); return true; } //use the metadata file that user gives us. parse xml file TiXmlDocument doc(xmlpath); bool loadOkay = doc.LoadFile(); if(!loadOkay) { if(doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE) { se_trace(SE_TRACE_ERROR, OPEN_FILE_ERROR, xmlpath); } else { se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR); } return false; } doc.Print();//Write the document to standard out using formatted printing ("pretty print"). TiXmlNode *pmetadata_node = doc.FirstChild("EnclaveConfiguration"); if(!pmetadata_node) { se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR); return false; } TiXmlNode *sub_node = NULL; sub_node = pmetadata_node->FirstChild(); const char *temp_text = NULL; while(sub_node)//parse xml node { switch(sub_node->Type()) { case TiXmlNode::TINYXML_ELEMENT: if(sub_node->ToElement()->FirstAttribute() != NULL) { se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR); return false; } temp_name = sub_node->ToElement()->Value(); temp_text = sub_node->ToElement()->GetText(); //traverse every node. Compare with the default value. if(traverser_parameter(temp_name, temp_text, parameter, parameter_count) == false) { se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR); return false; } break; case TiXmlNode::TINYXML_DECLARATION: case TiXmlNode::TINYXML_COMMENT: break; default: se_trace(SE_TRACE_ERROR, XML_FORMAT_ERROR); return false; } sub_node=pmetadata_node->IterateChildren(sub_node); } return true; }