open-license-manager
2014-04-14 f77e1e4d2adf4422943c10a1906854c3027391d8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * boostrap.c
 *
 *  Created on: Apr 5, 2014
 *      Author: devel
 */
 
#include <string>
#include <iostream>
#include <build_properties.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
 
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;
}