00001 #include <openssl/pem.h>
00002 #include <openssl/evp.h>
00003
00004 #include "CryptoUtil.h"
00005 #include "Scheduler.h"
00006 #include "Log.h"
00007 #include "params.h"
00008
00009 pthread_mutex_t CryptoUtil::slock = PTHREAD_MUTEX_INITIALIZER;
00010 EVP_PKEY* CryptoUtil::privateKey = 0;
00011
00012 void CryptoUtil::sign(const std::string& buf, std::string& signature) {
00013 if (Scheduler::simulated()) {
00014 return;
00015 }
00016
00017 loadPrivateKey();
00018
00019 EVP_MD_CTX* ctx = new EVP_MD_CTX();
00020 EVP_MD_CTX_init(ctx);
00021 if (EVP_SignInit(ctx, EVP_sha1()) == 0) {
00022 Log::sslerror("EVP_SignInit");
00023 ABORT("EVP_SignInit");
00024 }
00025 if (EVP_SignUpdate(ctx, buf.c_str(), buf.size()) == 0) {
00026 Log::sslerror("EVP_SignUpdate");
00027 ABORT("EVP_SignUpdate");
00028 }
00029 unsigned char* sigbuf = new unsigned char[EVP_PKEY_size(privateKey)];
00030 unsigned int size;
00031 if (EVP_SignFinal(ctx, sigbuf, &size, privateKey) == 0) {
00032 Log::sslerror("EVP_SignFinal");
00033 ABORT("EVP_SignFinal");
00034 }
00035
00036 signature.clear();
00037 signature.append((const char*)sigbuf, size);
00038
00039 EVP_MD_CTX_cleanup(ctx);
00040 delete ctx;
00041 delete[] sigbuf;
00042 }
00043
00044 bool CryptoUtil::verify(const std::string& buf, const std::string& sig,
00045 EVP_PKEY* pubkey) {
00046 if (Scheduler::simulated()) {
00047 return true;
00048 }
00049 EVP_MD_CTX* ctx = new EVP_MD_CTX();
00050 EVP_MD_CTX_init(ctx);
00051 if (EVP_VerifyInit(ctx, EVP_sha1()) == 0) {
00052 Log::sslerror("EVP_VerifyInit");
00053 ABORT("EVP_VerifyInit");
00054 }
00055 if (EVP_VerifyUpdate(ctx, buf.c_str(), buf.size()) == 0) {
00056 Log::sslerror("EVP_VerifyUpdate");
00057 ABORT("EVP_VerifyUpdate");
00058 }
00059 int r = EVP_VerifyFinal(ctx, (unsigned char*)sig.c_str(), sig.size(), pubkey);
00060 if (r < 0) {
00061 Log::sslerror("EVP_SignFinal");
00062 ABORT("EVP_SignFinal");
00063 }
00064
00065 EVP_MD_CTX_cleanup(ctx);
00066 delete ctx;
00067
00068 return r;
00069 }
00070
00071 void CryptoUtil::loadPrivateKey() {
00072 ScopedLock sl(slock);
00073 if (privateKey == 0) {
00074 if (!params::containsKey(params::MACE_PRIVATE_KEY_FILE)) {
00075 Log::err() << "parameter MACE_PRIVATE_KEY_FILE not set" << Log::endl;
00076 exit(-1);
00077 }
00078 std::string keyFile = params::get<std::string>(params::MACE_PRIVATE_KEY_FILE);
00079 FILE* fp = ::fopen(keyFile.c_str(), "r");
00080 if (fp == NULL) {
00081 Log::perror("open " + keyFile);
00082 exit(-1);
00083 }
00084 privateKey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
00085 fclose(fp);
00086 if (privateKey == NULL) {
00087 Log::sslerror("PEM_read_PrivateKey " + keyFile);
00088 exit(-1);
00089 }
00090 }
00091 }