/* * boostrap.c * * Created on: Apr 5, 2014 * Author: devel */ #include #include #include #include #include const int kBits = 1024; const int kExp = 65537; using namespace std; std::string replaceAll(std::string subject, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } return subject; } /* * TODO: a large security bug here. PEM format included into * the executable can easily replaced thanks to its headers and * footers. Use a binary format instead * http://www.openssl.org/docs/crypto/d2i_X509.html * http://www.openssl.org/docs/crypto/d2i_RSAPublicKey.html * */ void writePublicRSAHeader(const std::string& public_fname, RSA* rsa,int random) { /* To get the C-string PEM form: */ //BIO bio_private* = BIO_new_file(const char *filename, "w") BIO* bio_private = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPublicKey(bio_private, rsa); int keylen = BIO_pending(bio_private); char* pem_key = (char*) (calloc(keylen + 1, 1)); /* Null-terminate */ BIO_read(bio_private, pem_key, keylen); std::string dest = replaceAll(string(pem_key), string("\n"), string("\\n\" \\\n\"")); FILE* fp = fopen(public_fname.c_str(), "w"); fprintf(fp, "//file generated by bootstrap.c, do not edit.\n\n"); fprintf(fp, "#ifndef PUBLIC_KEY_H_\n#define PUBLIC_KEY_H_\n"); fprintf(fp, "#define PUBLIC_KEY \"%s\";\n", dest.c_str()); fprintf(fp, "#define SHARED_RANDOM %d;\n", abs(random)); fprintf(fp, "#endif\n"); fclose(fp); BIO_free_all(bio_private); free(pem_key); } void writePrivateRSAHeader(const std::string& private_fname, RSA* rsa) { /* To get the C-string PEM form: */ //BIO bio_private* = BIO_new_file(const char *filename, "w") BIO* bio_private = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(bio_private, rsa, NULL, NULL, 0, NULL, NULL); int keylen = BIO_pending(bio_private); char* pem_key = (char*) (calloc(keylen + 1, 1)); /* Null-terminate */ BIO_read(bio_private, pem_key, keylen); std::string dest = replaceAll(string(pem_key), string("\n"), string("\\n\" \\\n\"")); FILE* fp = fopen(private_fname.c_str(), "w"); fprintf(fp, "//file generated by bootstrap.c, do not edit.\n\n"); fprintf(fp, "#ifndef PRIVATE_KEY_H_\n#define PRIVATE_KEY_H_\n"); fprintf(fp, "#define PRIVATE_KEY \"%s\";\n", dest.c_str()); fprintf(fp, "#endif\n"); fclose(fp); BIO_free_all(bio_private); free(pem_key); } void generatePk(std::string private_fname,string public_fname) { RSA *rsa = RSA_generate_key(kBits, kExp, 0, 0); srand(time(NULL)); /* seed random number generator */ int random=rand(); /* To get the C-string PEM form: */ //BIO bio_private* = BIO_new_file(const char *filename, "w") writePrivateRSAHeader(private_fname, rsa); writePublicRSAHeader(public_fname, rsa, random); RSA_free(rsa); } void print_usage() { printf("usage: bootstrap private-fname public-fname\n"); } int main(int argc, char** argv) { if (argc != 3) { print_usage(); exit(2); } else { printf("********************************************\n"); printf("* Bootstrap!!! *\n"); printf("********************************************\n"); } string private_fname = string(argv[1]); string public_fname(argv[2]); generatePk(private_fname,public_fname); return 0; }