/* * CERT_LicenseVerifier.cpp * * Created by Andrew Salamon on 9/15/08. * Copyright 2008 Machine Perception Laboratory, University of California San Diego. All rights reserved. * */ #include "CERT_LicenseVerifier.h" #include #include #include namespace CERT { static const char *publicKeyString = "-----BEGIN RSA PUBLIC KEY-----\n\ MIGHAoGBAJrNQmc9hsQC1cCKqSjmQGQbPIVd+ojuk5ArCRZTx1vHyKfzfHUuqbgP\n\ T/HTxfi2qz2LfHM6wuzwgFZWqPEyPQVCnEKIwy3BrjXVKwfrp2/A0jvSGByn8JJe\n\ 9q1704WQI3jpT0IQhPPT60Mewep5Q3sUCtrASAbBDo7a/fS1rb1NAgED\n\ -----END RSA PUBLIC KEY-----\n"; LicenseVerifier::LicenseVerifier() : privateKey(NULL), publicKey(NULL) { loadPublicKey( publicKeyString ); } LicenseVerifier::LicenseVerifier( const std::string &privateKeyPath ) : privateKey(NULL), publicKey(NULL) { loadPrivateKey( privateKeyPath ); loadPublicKey( publicKeyString ); } std::string LicenseVerifier::encrypt( const std::string &plaintext ) { if( NULL == privateKey ) throw Licensing::keyException( "Missing private key. Unable to encrypt license." ); unsigned char *datain = (unsigned char*)plaintext.c_str(); int keylen = RSA_size( privateKey ); unsigned char *dataout = (unsigned char*)malloc(keylen); // std::string( keylen+1, 0 ); int number = -1; unsigned int pouetlen = plaintext.length(); if( (number = RSA_private_encrypt( pouetlen, datain, dataout, privateKey, RSA_PKCS1_PADDING )) == -1 ) { // int error = ERR_get_error(); // std::cout << ": " << ERR_lib_error_string( error ) << std::endl; // std::cout << ": " << ERR_func_error_string( error ) << std::endl; // std::cout << ": " << ERR_reason_error_string( error ) << std::endl; throw Licensing::encryptionException( "Unable to encrypt license information." ); return ""; } std::string strBase64 = encodeBase64( std::string( (char *)dataout, number ) ); free( dataout ); return strBase64; } std::string LicenseVerifier::decrypt( const std::string &cyphertext ) { int keylen = RSA_size( publicKey ); std::string newCypher = decodeBase64( cyphertext ); unsigned char *dataout = (unsigned char *)newCypher.c_str(); unsigned char *plaintext = new unsigned char[ keylen ]; int number = keylen; if( ( number = RSA_public_decrypt( number, dataout, plaintext, publicKey, RSA_PKCS1_PADDING ) ) == -1 ) { // int error = ERR_get_error(); // std::cout << ": " << ERR_lib_error_string( error )<< std::endl; // std::cout << ": " << ERR_func_error_string( error )<< std::endl; // std::cout << ": " << ERR_reason_error_string( error )<< // std::endl; throw Licensing::decryptionException( "Unable to decrypt license information." ); return ""; } return std::string( (char *)plaintext, number ); } void LicenseVerifier::setPrivateKey( RSA *key ) { if( privateKey ) { RSA_free( privateKey ); privateKey = NULL; } privateKey = key; } void LicenseVerifier::setPublicKey( RSA *key ) { if( publicKey ) { RSA_free( publicKey ); publicKey = NULL; } publicKey = key; } bool LicenseVerifier::loadPrivateKey( const std::string &path ) { RSA *key = NULL; FILE* fid = fopen( path.c_str(), "rb" ); if( fid == NULL ) { return false; } if( (key = PEM_read_RSAPrivateKey( fid, NULL, NULL, NULL )) == 0 ) { // std::cout << "PEM_read_RSAPrivateKey failed: " << ERR_get_error() << std::endl; return false; } fclose(fid); setPrivateKey( key ); return true; } bool LicenseVerifier::loadPublicKey( const std::string &keyString ) { RSA *key = NULL; int res; BIO *bp; /* Load public key from string */ bp = BIO_new_mem_buf( (void *)keyString.c_str(), -1); if( bp == NULL ) { // err_msg(); return false; } /* Convert string to internal key */ key = PEM_read_bio_RSAPublicKey(bp, NULL, NULL, NULL); if( key == NULL ) { // err_msg(); return false; } res = BIO_free(bp); if( res == 0 ) { // err_msg(); // return ; } setPublicKey( key ); return true; } std::string LicenseVerifier::encodeBase64( const std::string &str ) { // Create a memory buffer which will contain the Base64 encoded string BIO *mem = BIO_new(BIO_s_mem()); // Push on a Base64 filter so that writing to the buffer encodes the data BIO *b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); mem = BIO_push(b64, mem); // Encode all the data BIO_write( mem, str.c_str(), str.length() ); BIO_flush(mem); // Create a new string from the data in the memory buffer char *base64Pointer; long base64Length = BIO_get_mem_data(mem, &base64Pointer); std::string res( base64Pointer, base64Length ); BIO_free_all(mem); return res; } std::string LicenseVerifier::decodeBase64( const std::string &str ) { // Create a memory buffer containing Base64 encoded string data BIO *mem = BIO_new_mem_buf( (void *)str.c_str(), str.length() ); // Push a Base64 filter so that reading from the buffer decodes it BIO *b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); mem = BIO_push(b64, mem); // Decode into an NSMutableData std::string res; char inbuf[512]; int inlen; while( (inlen = BIO_read(mem, inbuf, sizeof(inbuf))) > 0 ) res += std::string( inbuf, inlen ); // Clean up and go home BIO_free_all(mem); return res; } } // end namespace CERT