00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <string.h>
00018
00019 #include <openssl/rsa.h>
00020 #include <openssl/evp.h>
00021 #include <openssl/objects.h>
00022 #include <openssl/err.h>
00023 #include <openssl/pem.h>
00024 #include <openssl/ssl.h>
00025 #include <openssl/bio.h>
00026 #include "gethwid.h"
00027
00028 #include "sign.h"
00029
00030 #undef BUFSIZE
00031 #define BUFSIZE (1024 * 8)
00032
00033 static char keyfile[] = "/proc/keystore/private";
00034 static char pubkey[] = "/proc/keystore/public";
00035
00036
00037 int iliad_create_signature(char * infile, char * outfile)
00038 {
00039 int nRet = ERR_INVALID_PARAMETERS;
00040
00041 int err;
00042 unsigned int len;
00043 int i;
00044 unsigned char *data;
00045 char * password;
00046 char pwbuf[16];
00047 EVP_MD_CTX *md_ctx;
00048 EVP_PKEY * pkey;
00049 const EVP_MD *md = NULL;
00050 BIO * key = NULL;
00051 BIO * out = NULL;
00052 BIO * bmd = NULL;
00053 BIO * in = NULL;
00054 BIO * inp = NULL;
00055
00056
00057 if (infile == NULL || outfile == NULL)
00058 {
00059 nRet = ERR_INVALID_PARAMETERS;
00060 goto error_exit;
00061 }
00062
00063
00064 if ((data = (unsigned char *) OPENSSL_malloc(BUFSIZE)) == NULL)
00065 {
00066 nRet = ERR_OUT_OF_MEMORY;
00067 goto error_exit;
00068 }
00069
00070
00071
00072 password = (char*) malloc(sizeof(char) * 33);
00073 get_hw_id(pwbuf);
00074 for(i = 0; i < 16; i++)
00075 {
00076 sprintf(&password[i*2], "%02X", pwbuf[i]);
00077 }
00078
00079
00080
00081 ERR_load_crypto_strings();
00082
00083
00084
00085 OpenSSL_add_all_algorithms();
00086
00087
00088 md = EVP_get_digestbyname("SHA1");
00089 bmd = BIO_new(BIO_f_md());
00090 in = BIO_new(BIO_s_file());
00091
00092
00093 key = BIO_new(BIO_s_file());
00094 if (BIO_read_filename(key, keyfile) <= 0)
00095 {
00096 nRet = ERR_UNABLE_TO_READ_PRIVATE_KEY;
00097 goto error_exit;
00098 }
00099
00100 pkey = PEM_read_bio_PrivateKey(key, NULL, 0, password);
00101 BIO_free(key);
00102 free(password);
00103
00104 if (pkey == NULL)
00105 {
00106 ERR_print_errors_fp (stderr);
00107 nRet = ERR_UNABLE_TO_DECRYPT_PRIVATE_KEY;
00108 goto error_exit;
00109 }
00110
00111
00112 if (!BIO_set_md(bmd, md))
00113 {
00114 nRet = ERR_UNABLE_TO_SET_INPUT_FILTER;
00115 goto error_exit;
00116 }
00117 inp = BIO_push(bmd, in);
00118
00119
00120 if (BIO_read_filename(in, infile) <= 0)
00121 {
00122 nRet = ERR_UNABLE_TO_READ_INPUT_FILE;
00123 goto error_exit;
00124 }
00125
00126
00127 for (;;)
00128 {
00129 i = BIO_read(inp, (char *) data, BUFSIZE);
00130
00131 if (i < 0)
00132 {
00133 ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
00134 nRet = ERR_UNABLE_TO_READ_INPUT_FILE;
00135 goto error_exit;
00136 }
00137
00138 if (i == 0)
00139 {
00140 break;
00141 }
00142 }
00143
00144
00145 BIO_get_md_ctx(inp, &md_ctx);
00146 err = EVP_SignFinal(md_ctx, data, (unsigned int *)&len, pkey);
00147
00148 if (err != 1)
00149 {
00150 ERR_print_errors_fp(stderr);
00151 nRet = ERR_UNABLE_TO_CREATE_SIGNATURE;
00152 goto error_exit;
00153 }
00154
00155 EVP_PKEY_free (pkey);
00156
00157
00158
00159
00160 out = BIO_new_file(outfile, "wb");
00161
00162 i = BIO_write(out, data, len);
00163 if (i == len)
00164 {
00165 fprintf (stderr, "Written signature to file: %s (%d bytes)\n", outfile, len);
00166 nRet = ERR_SUCCESS;
00167 }
00168 else
00169 {
00170 fprintf(stderr, "BIO_write returned [%d], expected [%d]\n", i, len);
00171 nRet = ERR_UNABLE_TO_WRITE_OUTPUT_FILE;
00172 goto error_exit;
00173 }
00174
00175 error_exit:
00176 if (in) { BIO_free(in); }
00177 if (out) { BIO_free_all(out); }
00178 if (bmd) { BIO_free(bmd); }
00179
00180 return nRet;
00181 }
00182
00183
00184 int iliad_verify_signature(char * infile, char * sigfile)
00185 {
00186 int nRet = ERR_SUCCESS;
00187
00188 int err;
00189 int i;
00190 unsigned int siglen;
00191 unsigned char *sigbuf = NULL;
00192 unsigned char *data = NULL;
00193 EVP_MD_CTX *md_ctx = NULL;
00194 EVP_PKEY *pkey = NULL;
00195 const EVP_MD *md = NULL;
00196 BIO *key = NULL;
00197 BIO *sigbio = NULL;
00198 BIO *in = NULL, *inp = NULL;
00199 BIO *bmd = NULL;
00200
00201
00202 if (infile == NULL || sigfile == NULL)
00203 {
00204 nRet = ERR_INVALID_PARAMETERS;
00205 goto error_exit;
00206 }
00207
00208 if ((data = (unsigned char *) OPENSSL_malloc(BUFSIZE)) == NULL)
00209 {
00210 nRet = ERR_OUT_OF_MEMORY;
00211 goto error_exit;
00212 }
00213
00214
00215 ERR_load_crypto_strings();
00216
00217
00218
00219 OpenSSL_add_all_algorithms();
00220
00221
00222 md = EVP_get_digestbyname("SHA1");
00223 bmd = BIO_new(BIO_f_md());
00224 in = BIO_new(BIO_s_file());
00225
00226
00227 key = BIO_new(BIO_s_file());
00228 if (BIO_read_filename(key, pubkey) <= 0)
00229 {
00230 nRet = ERR_UNABLE_TO_READ_PUBLIC_KEY;
00231 goto error_exit;
00232 }
00233
00234 pkey = PEM_read_bio_PUBKEY(key, NULL, NULL, NULL);
00235 BIO_free(key);
00236
00237 if (pkey == NULL)
00238 {
00239 ERR_print_errors_fp (stderr);
00240 nRet = ERR_UNABLE_TO_READ_PUBLIC_KEY;
00241 goto error_exit;
00242 }
00243
00244
00245 if (!BIO_set_md(bmd, md))
00246 {
00247 nRet = ERR_UNABLE_TO_SET_INPUT_FILTER;
00248 goto error_exit;
00249 }
00250 inp = BIO_push(bmd, in);
00251
00252
00253 if (BIO_read_filename(in, infile) <= 0)
00254 {
00255 nRet = ERR_UNABLE_TO_READ_INPUT_FILE;
00256 goto error_exit;
00257 }
00258
00259
00260 for (;;)
00261 {
00262 i = BIO_read(inp, (char *) data, BUFSIZE);
00263
00264 if (i < 0)
00265 {
00266 nRet = ERR_UNABLE_TO_READ_INPUT_FILE;
00267 goto error_exit;
00268 }
00269
00270 if (i == 0)
00271 {
00272 break;
00273 }
00274 }
00275
00276
00277 sigbio = BIO_new_file(sigfile, "rb");
00278 siglen = EVP_PKEY_size(pkey);
00279 sigbuf = OPENSSL_malloc(siglen);
00280 if(!sigbio)
00281 {
00282 nRet = ERR_UNABLE_TO_READ_SIGNATURE_FILE;
00283 goto error_exit;
00284 }
00285
00286 siglen = BIO_read(sigbio, sigbuf, siglen);
00287 BIO_free(sigbio);
00288 if(siglen <= 0)
00289 {
00290 nRet = ERR_UNABLE_TO_READ_SIGNATURE_FILE;
00291 goto error_exit;
00292 }
00293
00294
00295
00296
00297
00298
00299 BIO_get_md_ctx(inp, &md_ctx);
00300 err = EVP_VerifyFinal (md_ctx, sigbuf, siglen, pkey);
00301
00302
00303 if (err <= 0)
00304 {
00305 ERR_print_errors_fp (stderr);
00306 nRet = ERR_VERIFICATION_FAILED;
00307 }
00308 else
00309 {
00310 fprintf (stderr, "Signature for %s Verified OK.\n", infile);
00311 nRet = ERR_SUCCESS;
00312 }
00313
00314 error_exit:
00315 if (pkey) EVP_PKEY_free (pkey);
00316 if (data) { OPENSSL_cleanse(data, BUFSIZE); OPENSSL_free(data); }
00317 if (sigbuf) OPENSSL_free(sigbuf);
00318 if (in) BIO_free(in);
00319 if (bmd) BIO_free(bmd);
00320
00321 return nRet;
00322 }
00323