result_t X509Cert::loadFile(const char *filename) { if (m_root) return CHECK_ERROR(CALL_E_INVALID_CALL); result_t hr; std::string data; int ret; hr = fs_base::ac_readFile(filename, data); if (hr < 0) return hr; if (qstrstr(data.c_str(), "BEGIN CERTIFICATE") || qstrstr(data.c_str(), "CKO_CERTIFICATE")) return load(data.c_str()); ret = x509_crt_parse_der(&m_crt, (const unsigned char *)data.c_str(), data.length()); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; }
result_t X509Cert::load(const char *txtCert) { if (m_root) return CHECK_ERROR(CALL_E_INVALID_CALL); int ret; if (qstrstr(txtCert, "BEGIN CERTIFICATE")) { ret = x509_crt_parse(&m_crt, (const unsigned char *)txtCert, qstrlen(txtCert)); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; } _parser p(txtCert, (int)qstrlen(txtCert)); bool is_loaded = false; while (!p.end()) { std::string cka_value; bool in_multiline = false, in_obj = false; bool is_cert = false; bool is_value = false; while (!p.end()) { std::string line; std::string cmd, type, value; p.getLine(line); _parser p1(line); p1.skipSpace(); if (p1.get() == '#') continue; if (in_multiline) { if (p1.get() == '\\') { if (is_value) { while (p1.get() == '\\') { char ch1, ch2, ch3; p1.skip(); ch1 = p1.getChar(); if (ch1 < '0' || ch1 > '7') break; ch2 = p1.getChar(); if (ch2 < '0' || ch2 > '7') break; ch3 = p1.getChar(); if (ch3 < '0' || ch3 > '7') break; ch1 = (ch1 - '0') * 64 + (ch2 - '0') * 8 + (ch3 - '0'); cka_value.append(&ch1, 1); } } continue; } p1.getWord(cmd); if (!qstrcmp(cmd.c_str(), "END")) in_multiline = false; continue; } p1.getWord(cmd); p1.skipSpace(); p1.getWord(type); if (!qstrcmp(type.c_str(), "MULTILINE_OCTAL")) { is_value = is_cert && !qstrcmp(cmd.c_str(), "CKA_VALUE"); if (is_value) cka_value.resize(0); in_multiline = true; continue; } p1.skipSpace(); p1.getLeft(value); if (!in_obj) { if (!qstrcmp(cmd.c_str(), "CKA_CLASS")) { in_obj = true; is_cert = !qstrcmp(value.c_str(), "CKO_CERTIFICATE"); } continue; } if (cmd.empty()) break; } if (!cka_value.empty()) { ret = x509_crt_parse_der(&m_crt, (const unsigned char *)cka_value.c_str(), cka_value.length()); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); is_loaded = true; } } if (!is_loaded) return CHECK_ERROR(_ssl::setError(POLARSSL_ERR_X509_INVALID_FORMAT)); return 0; }
int PPCHelper_ConvertFunction(func_t* pFunc) { ea_t start = pFunc->startEA; ea_t end = pFunc->endEA; // struc_t* p_frame = get_frame(pFunc); const int MAX_REGS = 32; bool is_reg_saved[MAX_REGS]; // r0 - r31 for(int i=0; i<MAX_REGS; i++) is_reg_saved[i] = false; bool is_arg_saved[MAX_REGS]; // r0 - r31 for(int i=0; i<MAX_REGS; i++) is_arg_saved[i] = false; // process function from start to end for(ea_t ea=start; ea<end; ea+=4) { // get mnemonic char mnem[256]; if( !ua_mnem(ea, mnem, sizeof(mnem)) ) return false; tag_remove(mnem, mnem, sizeof(mnem)); char* ptr = (char*)qstrstr(mnem, "."); if(ptr) *ptr = 0; // prepare cmd struct for this address ua_ana0(ea); // fix mnemonic for "bl" if( cmd.itype == 13 && (cmd.auxpref & 8) ) { qstrncpy(mnem, "bl", sizeof(mnem)); } // fix mnemonic for "blr" else if( cmd.itype == 320 && cmd.auxpref == 0x500 ) { qstrncpy(mnem, "blr", sizeof(mnem)); } // handle register saving if( (!qstrcmp(mnem, "stdu") || !qstrcmp(mnem, "std")) && cmd.Op1.type == o_reg && cmd.Op2.type == o_displ && !is_reg_saved[cmd.Op1.reg] && cmd.Op2.reg == 1 ) // 1 == "sp" { int src_reg = cmd.Op1.reg; int offset = cmd.Op2.addr; int dst_reg = cmd.Op2.reg; char name[256]; if( src_reg == 0 ) qsnprintf(name, sizeof(name), "save_lr"); else if( src_reg == 1 ) qsnprintf(name, sizeof(name), "save_sp"); else qsnprintf(name, sizeof(name), "save_r%d", src_reg); add_stkvar2(pFunc, name, offset, 0, NULL, 0); is_reg_saved[cmd.Op1.reg] = true; //msg("%08X : stdu %%r%d, %d(%%r%d)\n", (unsigned int)ea, src_reg, offset, dst_reg); } // handle arg saving else if( !qstrcmp(mnem, "mr") && cmd.Op1.type == o_reg && cmd.Op2.type == o_reg && !is_arg_saved[cmd.Op2.reg] && cmd.Op2.reg >= 3 ) // args begin at r3 { int dst_reg = cmd.Op1.reg; int src_reg = cmd.Op2.reg; char canon[256]; qsnprintf(canon, sizeof(canon), "%%r%d", dst_reg); char name[256]; qsnprintf(name, sizeof(name), "arg%d", src_reg-3); add_regvar(pFunc, start, end, canon, name, NULL); is_arg_saved[cmd.Op2.reg] = true; //msg("%08X : mr %%r%d, %%r%d\n", (unsigned int)ea, dst_reg, src_reg); } // if a function is called, then no more args can be saved else if( !qstrcmp(mnem, "bl") ) { break; } } // process function from start to end msg("processing end to start (%08X to %08X) - %d\n", (unsigned int)end, (unsigned int)start, PPC_balways); bool is_in_return_point = false; for(ea_t ea=end-4; ea>start; ea-=4) { // get mnemonic char mnem[256]; if( !ua_mnem(ea, mnem, sizeof(mnem)) ) return false; tag_remove(mnem, mnem, sizeof(mnem)); char* ptr = (char*)qstrstr(mnem, "."); if(ptr) *ptr = 0; // prepare cmd struct for this address ua_ana0(ea); // fix mnemonic for "bl" if( cmd.itype == 13 && (cmd.auxpref & 8) ) { qstrncpy(mnem, "bl", sizeof(mnem)); } // fix mnemonic for "blr" else if( cmd.itype == 320 && cmd.auxpref == 0x500 ) { qstrncpy(mnem, "blr", sizeof(mnem)); } // msg("%08X: %3s inst_type = %d, insgpref = %d, segpref = %d, auxpref = %d\n", (unsigned int)ea, mnem, cmd.itype, cmd.segpref, cmd.insnpref, cmd.auxpref); //qstrncpy(mnem, "bl", sizeof(mnem)); /* msg("%08X: %s %d %d %d (%d %d %d %d) (%d %d %d %d) (%d %d %d %d) : %X %X %X : %X %X %X : %X %X %X : %X %X %X : %X %X %X : %X %X %X\n", (unsigned int)ea, mnem, cmd.Op1.type, cmd.Op2.type, cmd.Op3.type, cmd.Op1.specflag1, cmd.Op1.specflag2, cmd.Op1.specflag3, cmd.Op1.specflag4, cmd.Op2.specflag1, cmd.Op2.specflag2, cmd.Op2.specflag3, cmd.Op2.specflag4, cmd.Op3.specflag1, cmd.Op3.specflag2, cmd.Op3.specflag3, cmd.Op3.specflag4, (unsigned int)cmd.Op1.specval, (unsigned int)cmd.Op2.specval, (unsigned int)cmd.Op3.specval, (unsigned int)cmd.Op1.addr, (unsigned int)cmd.Op2.addr, (unsigned int)cmd.Op3.addr, (unsigned int)cmd.Op1.value, (unsigned int)cmd.Op2.value, (unsigned int)cmd.Op3.value, (unsigned int)cmd.Op1.reg, (unsigned int)cmd.Op2.reg, (unsigned int)cmd.Op3.reg, (unsigned int)cmd.Op1.dtyp, (unsigned int)cmd.Op2.dtyp, (unsigned int)cmd.Op3.dtyp, (unsigned int)cmd.Op1.flags, (unsigned int)cmd.Op2.flags, (unsigned int)cmd.Op3.flags); } */ // if found a function return point, then look above for return register if( !qstrcmp(mnem, "blr") ) { is_in_return_point = true; //msg("%08X return point end\n", (unsigned int)ea); } // if a function is called, thenit is no longer in the return point else if( !qstrcmp(mnem, "bl") ) { is_in_return_point = false; //msg("%08X return point start\n", (unsigned int)ea); } // look for possible return register else if( is_in_return_point && !qstrcmp(mnem, "mr") && cmd.Op1.type == o_reg && cmd.Op2.type == o_reg && cmd.Op1.reg == 3 ) // return value is in r3 { int dst_reg = cmd.Op1.reg; int src_reg = cmd.Op2.reg; char canon[256]; qsnprintf(canon, sizeof(canon), "%%r%d", src_reg); add_regvar(pFunc, start, end, canon, "ret", NULL); //msg("%08X return register\n", (unsigned int)ea); } } // analyse area to refresh any changes analyze_area(start, end); return 0; }
result_t X509Cert::load(exlib::string txtCert) { if (m_root) return CHECK_ERROR(CALL_E_INVALID_CALL); int32_t ret; if (qstrstr(txtCert.c_str(), "BEGIN CERTIFICATE")) { ret = mbedtls_x509_crt_parse(&m_crt, (const unsigned char *)txtCert.c_str(), txtCert.length() + 1); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); return 0; } _parser p(txtCert); QuickArray<std::pair<exlib::string, exlib::string> > values; std::map<exlib::string, bool> verifies; std::map<exlib::string, bool> certs; while (!p.end()) { exlib::string cka_label; exlib::string cka_value; exlib::string cka_serial; exlib::string _value; bool in_multiline = false, in_obj = false; bool is_cert = false; bool is_trust = false; bool is_value = false; bool is_serial = false; bool is_ca = false; bool is_verify = false; while (!p.end()) { exlib::string line; exlib::string cmd, type, value; p.getLine(line); _parser p1(line); p1.skipSpace(); if (p1.get() == '#') continue; if (in_multiline) { if (p1.get() == '\\') { while (p1.get() == '\\') { char ch1, ch2, ch3; p1.skip(); ch1 = p1.getChar(); if (ch1 < '0' || ch1 > '7') break; ch2 = p1.getChar(); if (ch2 < '0' || ch2 > '7') break; ch3 = p1.getChar(); if (ch3 < '0' || ch3 > '7') break; ch1 = (ch1 - '0') * 64 + (ch2 - '0') * 8 + (ch3 - '0'); _value.append(&ch1, 1); } continue; } p1.getWord(cmd); if ((cmd == "END")) { if (is_value) cka_value = _value; else if (is_serial) cka_serial = _value; in_multiline = false; } continue; } p1.getWord(cmd); p1.skipSpace(); p1.getWord(type); if ((type == "MULTILINE_OCTAL")) { in_multiline = true; _value.resize(0); is_value = is_cert && (cmd == "CKA_VALUE"); is_serial = (cmd == "CKA_SERIAL_NUMBER"); continue; } p1.skipSpace(); p1.getLeft(value); if (!in_obj) { if ((cmd == "CKA_CLASS")) { in_obj = true; is_cert = (value == "CKO_CERTIFICATE"); is_trust = (value == "CKO_NSS_TRUST"); } continue; } if ((cmd == "CKA_LABEL")) cka_label = value; else if (is_trust && (cmd == "CKA_TRUST_SERVER_AUTH")) { is_ca = (value == "CKT_NSS_TRUSTED_DELEGATOR"); is_verify = (value == "CKT_NSS_MUST_VERIFY_TRUST"); } if (cmd.empty()) break; } if (!cka_label.empty()) { if (is_trust) { if (is_ca) certs.insert(std::pair<exlib::string, bool>(cka_label + cka_serial, true)); if (is_verify) verifies.insert(std::pair<exlib::string, bool>(cka_label + cka_serial, true)); } else if (is_cert && !cka_value.empty()) values.append(std::pair<exlib::string, exlib::string>(cka_label + cka_serial, cka_value)); } } bool is_loaded = false; int32_t i; for (i = 0; i < (int32_t)values.size(); i++) { std::pair<exlib::string, exlib::string> &c = values[i]; std::map<exlib::string, bool>::iterator it_trust; it_trust = verifies.find(c.first); if (it_trust != verifies.end()) { ret = mbedtls_x509_crt_parse_der(&m_crt, (const unsigned char *)c.second.c_str(), c.second.length()); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); is_loaded = true; } } for (i = 0; i < (int32_t)values.size(); i++) { std::pair<exlib::string, exlib::string> &c = values[i]; std::map<exlib::string, bool>::iterator it_trust; it_trust = certs.find(c.first); if (it_trust != certs.end()) { ret = mbedtls_x509_crt_parse_der(&m_crt, (const unsigned char *)c.second.c_str(), c.second.length() ); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); is_loaded = true; } } if (!is_loaded) return CHECK_ERROR(_ssl::setError(MBEDTLS_ERR_X509_INVALID_FORMAT)); return 0; }