// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2023 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . #ifdef _WIN32 #include "boinc_win.h" #else #include "config.h" #include "boinc_stdio.h" #endif #include "miofile.h" #include "error_numbers.h" #include "cert_sig.h" CERT_SIG::CERT_SIG() { this->clear(); } CERT_SIG::~CERT_SIG() { // TODO } void CERT_SIG::clear() { this->type = MD5_HASH; // md5 hash by default memset(this->subject, 0, sizeof(this->subject)); memset(this->signature, 0, sizeof(this->signature)); } CERT_SIGS::CERT_SIGS() { // TODO } CERT_SIGS::~CERT_SIGS() { // TODO } void CERT_SIGS::clear() { this->signatures.clear(); } int CERT_SIGS::count() { return (int)(this->signatures.size()); } int CERT_SIGS::parse(XML_PARSER &xp) { CERT_SIG sig; bool in_entry = false; bool in_sig = false; bool parsed_one = false; char buf[256]; while (!xp.get_tag()) { if (xp.match_tag("/signatures")) { //printf("CERT_SIGS::parse() ends.\n"); //fflush(stdout); return !in_entry && !in_sig && parsed_one; } if (in_sig) { in_sig = false; snprintf(sig.signature, sizeof(sig.signature), "%s", xp.parsed_tag); continue; } if (!xp.is_tag) { printf("(CERT_SIGS): unexpected text: %s\n", xp.parsed_tag); continue; } if (in_entry) { if (xp.match_tag("/entry")) { in_entry = false; in_sig = false; if (strlen(sig.subject) == 0) { printf("ERROR: subject is not set.\n"); return false; } if (strlen(sig.signature) == 0) { printf("ERROR: signature is not set.\n"); return false; } this->signatures.push_back(sig); parsed_one = true; sig.clear(); continue; } if (xp.match_tag("signature")) { in_sig = true; continue; } if (xp.match_tag("/signature")) { in_sig = false; continue; } if (xp.parse_str("subject", sig.subject, sizeof(sig.subject))) continue; else if (xp.parse_str("hash", sig.hash, sizeof(sig.hash))) continue; else if (xp.parse_str("type", buf, sizeof(buf))) { if ((!strcmp(buf,"md5")) || (!strcmp(buf,"MD5"))) { sig.type = MD5_HASH; } else if ((!strcmp(buf,"sha1")) || (!strcmp(buf,"SHA1"))) { sig.type = SHA1_HASH; } continue; } } else { if (strstr(xp.parsed_tag, "entry")) { in_entry = true; continue; } } } return false; } int CERT_SIGS::parse_file(const char* filename) { int retval; #ifndef _USING_FCGI_ FILE *f = fopen(filename, "r"); #else FCGI_FILE *f = FCGI::fopen(filename, "r"); #endif if (!f) return ERR_FOPEN; MIOFILE mf; mf.init_file(f); XML_PARSER xp(&mf); if (!xp.parse_start("signatures")) { fclose(f); return ERR_XML_PARSE; } retval = this->parse(xp); fclose(f); return retval; } int CERT_SIGS::parse_buffer(char* buf) { MIOFILE mf; int retval; mf.init_buf_read(buf); XML_PARSER xp(&mf); retval = this->parse(xp); return retval; } int CERT_SIGS::parse_buffer_embed(char* buf) { MIOFILE mf; char tag[4096]; bool is_tag; int s_found = false; mf.init_buf_read(buf); XML_PARSER xp(&mf); while (!xp.get(tag, sizeof(tag), is_tag)) { if (xp.match_tag("signatures")) { s_found = true; break; } } if (s_found) return this->parse(xp); else return false; } int CERT_SIGS::write(MIOFILE &f) { if (this->signatures.size()==0) return true; f.printf("\n"); for(unsigned int i=0;i < this->signatures.size(); i++) { f.printf(" \n"); f.printf(" \n%s\n", this->signatures.at(i).signature); f.printf(" \n"); f.printf(" %s\n", this->signatures.at(i).subject); f.printf(" %s\n", (this->signatures.at(i).type == MD5_HASH) ? "md5" : "sha1"); f.printf(" %s\n", this->signatures.at(i).hash); f.printf(" \n"); } f.printf("\n"); return true; }