moved all the code using explicit EVP_KEY and RSA structures into gxssecurity (except rsrecon, still need to do)

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7371 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2014-05-17 13:50:40 +00:00
parent d3b92ddab9
commit ec031ba940
4 changed files with 2723 additions and 2792 deletions

View File

@ -33,15 +33,28 @@
* #define GXS_SECURITY_DEBUG 1 * #define GXS_SECURITY_DEBUG 1
***/ ***/
GxsSecurity::GxsSecurity() static std::string getRsaKeyFingerprint(RSA *pubkey)
{ {
int lenn = BN_num_bytes(pubkey -> n);
int lene = BN_num_bytes(pubkey -> e);
unsigned char *tmp = new unsigned char[lenn+lene];
BN_bn2bin(pubkey -> n, tmp);
BN_bn2bin(pubkey -> e, &tmp[lenn]);
Sha1CheckSum s = RsDirUtil::sha1sum(tmp,lenn+lene) ;
delete[] tmp ;
// Copy first CERTSIGNLEN bytes from the hash of the public modulus and exponent
// We should not be using strings here, but a real ID. To be done later.
assert(Sha1CheckSum::SIZE_IN_BYTES >= CERTSIGNLEN) ;
return s.toStdString().substr(0,2*CERTSIGNLEN);
} }
GxsSecurity::~GxsSecurity() static RSA *extractPublicKey(const RsTlvSecurityKey& key)
{
}
RSA *GxsSecurity::extractPublicKey(const RsTlvSecurityKey& key)
{ {
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len; long keylen = key.keyData.bin_len;
@ -51,6 +64,86 @@ RSA *GxsSecurity::extractPublicKey(const RsTlvSecurityKey& key)
return rsakey; return rsakey;
} }
static void setRSAPublicKey(RsTlvSecurityKey & key, RSA *rsa_pub)
{
unsigned char *data = NULL ; // this works for OpenSSL > 0.9.7
int reqspace = i2d_RSAPublicKey(rsa_pub, &data);
key.keyData.setBinData(data, reqspace);
key.keyId = getRsaKeyFingerprint(rsa_pub);
free(data) ;
}
static void setRSAPrivateKey(RsTlvSecurityKey & key, RSA *rsa_priv)
{
unsigned char *data = NULL ;
int reqspace = i2d_RSAPrivateKey(rsa_priv, &data);
key.keyData.setBinData(data, reqspace);
key.keyId = getRsaKeyFingerprint(rsa_priv);
free(data) ;
}
static RSA *extractPrivateKey(const RsTlvSecurityKey & key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPrivateKey(NULL, &(keyptr), keylen);
return rsakey;
}
bool GxsSecurity::generateKeyPair(RsTlvSecurityKey& public_key,RsTlvSecurityKey& private_key)
{
// admin keys
RSA *rsa = RSA_generate_key(2048, 65537, NULL, NULL);
RSA *rsa_pub = RSAPublicKey_dup(rsa);
setRSAPublicKey(public_key, rsa_pub);
setRSAPrivateKey(private_key, rsa);
public_key.startTS = time(NULL);
public_key.endTS = public_key.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
private_key.startTS = public_key.startTS;
private_key.endTS = 0; /* no end */
// clean up
RSA_free(rsa);
RSA_free(rsa_pub);
return true ;
}
bool GxsSecurity::extractPublicKey(const RsTlvSecurityKey& private_key,RsTlvSecurityKey& public_key)
{
if(!(private_key.keyFlags & RSTLV_KEY_TYPE_FULL))
return false ;
RSA *rsaPrivKey = extractPrivateKey(private_key);
if(!rsaPrivKey)
return false ;
RSA *rsaPubKey = RSAPublicKey_dup(rsaPrivKey);
RSA_free(rsaPrivKey);
if(!rsaPubKey)
return false ;
setRSAPublicKey(public_key, rsaPubKey);
RSA_free(rsaPubKey);
public_key.keyFlags = private_key.keyFlags & (RSTLV_KEY_DISTRIB_MASK) ; // keep the distrib flags
public_key.keyFlags |= RSTLV_KEY_TYPE_PUBLIC_ONLY;
public_key.endTS = public_key.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
return true ;
}
bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& privKey, RsTlvKeySignature& sign) bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& privKey, RsTlvKeySignature& sign)
{ {
@ -85,7 +178,7 @@ bool GxsSecurity::getSignature(const char *data, uint32_t data_len, const RsTlvS
bool GxsSecurity::validateSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& key, const RsTlvKeySignature& signature) bool GxsSecurity::validateSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& key, const RsTlvKeySignature& signature)
{ {
RSA *rsakey = RSAPublicKey_dup(extractPublicKey(key)) ; RSA *rsakey = RSAPublicKey_dup(::extractPublicKey(key)) ;
if(!rsakey) if(!rsakey)
{ {
@ -226,7 +319,7 @@ bool GxsSecurity::encrypt(uint8_t *& out, int & outlen, const uint8_t *in, int i
std::cerr << "GxsSecurity::encrypt() " << std::endl; std::cerr << "GxsSecurity::encrypt() " << std::endl;
#endif #endif
RSA *rsa_publish_pub = RSAPublicKey_dup(extractPublicKey(key)) ; RSA *rsa_publish_pub = RSAPublicKey_dup(::extractPublicKey(key)) ;
EVP_PKEY *public_key = NULL; EVP_PKEY *public_key = NULL;
//RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey); //RSA* rsa_publish = EVP_PKEY_get1_RSA(privateKey);
@ -398,27 +491,6 @@ bool GxsSecurity::decrypt(uint8_t *& out, int & outlen, const uint8_t *in, int i
return true; return true;
} }
std::string GxsSecurity::getRsaKeySign(RSA *pubkey)
{
int lenn = BN_num_bytes(pubkey -> n);
int lene = BN_num_bytes(pubkey -> e);
unsigned char *tmp = new unsigned char[lenn+lene];
BN_bn2bin(pubkey -> n, tmp);
BN_bn2bin(pubkey -> e, &tmp[lenn]);
Sha1CheckSum s = RsDirUtil::sha1sum(tmp,lenn+lene) ;
delete[] tmp ;
// Copy first CERTSIGNLEN bytes from the hash of the public modulus and exponent
// We should not be using strings here, but a real ID. To be done later.
assert(Sha1CheckSum::SIZE_IN_BYTES >= CERTSIGNLEN) ;
return s.toStdString().substr(0,2*CERTSIGNLEN);
}
bool GxsSecurity::validateNxsGrp(RsNxsGrp& grp, RsTlvKeySignature& sign, RsTlvSecurityKey& key) bool GxsSecurity::validateNxsGrp(RsNxsGrp& grp, RsTlvKeySignature& sign, RsTlvSecurityKey& key)
{ {
@ -524,39 +596,4 @@ bool GxsSecurity::validateNxsGrp(RsNxsGrp& grp, RsTlvKeySignature& sign, RsTlvSe
return false; return false;
} }
void GxsSecurity::setRSAPublicKey(RsTlvSecurityKey & key, RSA *rsa_pub)
{
unsigned char *data = NULL ; // this works for OpenSSL > 0.9.7
int reqspace = i2d_RSAPublicKey(rsa_pub, &data);
key.keyData.setBinData(data, reqspace);
key.keyId = getRsaKeySign(rsa_pub);
free(data) ;
}
void GxsSecurity::setRSAPrivateKey(RsTlvSecurityKey & key, RSA *rsa_priv)
{
unsigned char *data = NULL ;
int reqspace = i2d_RSAPrivateKey(rsa_priv, &data);
key.keyData.setBinData(data, reqspace);
key.keyId = getRsaKeySign(rsa_priv);
free(data) ;
}
RSA *GxsSecurity::extractPrivateKey(const RsTlvSecurityKey & key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPrivateKey(NULL, &(keyptr), keylen);
return rsakey;
}

View File

@ -39,116 +39,80 @@
* operations needed to validate data received in RsGenExchange * operations needed to validate data received in RsGenExchange
* Also has routine for creating security objects around msgs and groups * Also has routine for creating security objects around msgs and groups
*/ */
class GxsSecurity { class GxsSecurity
{
public:
/*!
* Extracts a public key from a private key.
*/
static bool extractPublicKey(const RsTlvSecurityKey& private_key,RsTlvSecurityKey& public_key) ;
public: /*!
* Generates a public/private RSA keypair. To be used for all GXS purposes.
* @param RsTlvSecurityKey public RSA key
* @param RsTlvSecurityKey private RSA key
* @return true if the generate was successful, false otherwise.
*/
static bool generateKeyPair(RsTlvSecurityKey& public_key,RsTlvSecurityKey& private_key) ;
GxsSecurity(); /*!
~GxsSecurity(); * Encrypts data using envelope encryption (taken from open ssl's evp_sealinit )
* only full publish key holders can encrypt data for given group
*@param out
*@param outlen
*@param in
*@param inlen
*/
static bool encrypt(uint8_t *&out, int &outlen, const uint8_t *in, int inlen, const RsTlvSecurityKey& key) ;
/*! /**
* extracts the public key from an RsTlvSecurityKey * Decrypts data using evelope decryption (taken from open ssl's evp_sealinit )
* @param key RsTlvSecurityKey to extract public RSA key from * only full publish key holders can decrypt data for a group
* @return pointer to the public RSA key if successful, null otherwise * @param out where decrypted data is written to
*/ * @param outlen
static RSA *extractPublicKey(const RsTlvSecurityKey &key); * @param in
* @param inlen
* @return false if encryption failed
*/
static bool decrypt(uint8_t *&out, int &outlen, const uint8_t *in, int inlen, const RsTlvSecurityKey& key) ;
/*! /*!
* extracts the public key from an RsTlvSecurityKey * uses grp signature to check if group has been
* @param key RsTlvSecurityKey to extract private RSA key from * tampered with
* @return pointer to the private RSA key if successful, null otherwise * @param newGrp the Nxs group to be validated
*/ * @param sign the signature to validdate against
static RSA *extractPrivateKey(const RsTlvSecurityKey &key); * @param key the public key to use to check signature
* @return true if group valid false otherwise
*/
static bool validateNxsGrp(RsNxsGrp& grp, RsTlvKeySignature& sign, RsTlvSecurityKey& key);
/*! /*!
* stores the rsa public key in a RsTlvSecurityKey * Validate a msg's signature using the given public key
* @param key RsTlvSecurityKey to store the public rsa key in * @param msg the Nxs message to be validated
* @param rsa_pub * @param sign the signature to validdate against
*/ * @param key the public key to use to check signature
static void setRSAPublicKey(RsTlvSecurityKey &key, RSA *rsa_pub); * @return false if verfication of signature is not passed
*/
/*! static bool validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSecurityKey& key);
* stores the rsa private key in a RsTlvSecurityKey
* @param key stores the rsa private key in a RsTlvSecurityKey
* @param rsa_priv the rsa private key to store
*/
static void setRSAPrivateKey(RsTlvSecurityKey &key, RSA *rsa_priv);
/*!
* extracts signature from RSA key
* @param pubkey
* @return signature of RSA key in hex format
*/
static std::string getRsaKeySign(RSA *pubkey);
/*!
* extracts the first CERTSIGNLEN bytes of signature and stores it in a string
* in hex format
* @param data signature
* @param len the length of the signature data
* @return returns the first CERTSIGNLEN of the signature as a string
*/
static std::string getBinDataSign(void *data, int len);
/*!
* Encrypts data using envelope encryption (taken from open ssl's evp_sealinit )
* only full publish key holders can encrypt data for given group
*@param out
*@param outlen
*@param in
*@param inlen
*/
static bool encrypt(uint8_t *&out, int &outlen, const uint8_t *in, int inlen, const RsTlvSecurityKey& key) ;
/** /*!
* Decrypts data using evelope decryption (taken from open ssl's evp_sealinit ) * @param data data to be signed
* only full publish key holders can decrypt data for a group * @param data_len length of data to be signed
* @param out where decrypted data is written to * @param privKey private key to used to make signature
* @param outlen * @param sign the signature is stored here
* @param in * @return false if signature creation failed, true is signature created
* @param inlen */
* @return false if encryption failed static bool getSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& privKey, RsTlvKeySignature& sign);
*/
static bool decrypt(uint8_t *&out, int &outlen, const uint8_t *in, int inlen, const RsTlvSecurityKey& key) ;
/*! /*!
* uses grp signature to check if group has been * @param data data that has been signed
* tampered with * @param data_len length of signed data
* @param newGrp the Nxs group to be validated * @param privKey public key to used to check signature
* @param sign the signature to validdate against * @param sign Signature for the data
* @param key the public key to use to check signature * @return true if signature checks
* @return true if group valid false otherwise */
*/ static bool validateSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& pubKey, const RsTlvKeySignature& sign);
static bool validateNxsGrp(RsNxsGrp& grp, RsTlvKeySignature& sign, RsTlvSecurityKey& key);
/*!
* Validate a msg's signature using the given public key
* @param msg the Nxs message to be validated
* @param sign the signature to validdate against
* @param key the public key to use to check signature
* @return false if verfication of signature is not passed
*/
static bool validateNxsMsg(RsNxsMsg& msg, RsTlvKeySignature& sign, RsTlvSecurityKey& key);
/*!
* @param data data to be signed
* @param data_len length of data to be signed
* @param privKey private key to used to make signature
* @param sign the signature is stored here
* @return false if signature creation failed, true is signature created
*/
static bool getSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& privKey, RsTlvKeySignature& sign);
/*!
* @param data data that has been signed
* @param data_len length of signed data
* @param privKey public key to used to check signature
* @param sign Signature for the data
* @return true if signature checks
*/
static bool validateSignature(const char *data, uint32_t data_len, const RsTlvSecurityKey& pubKey, const RsTlvKeySignature& sign);
}; };
#endif // GXSSECURITY_H #endif // GXSSECURITY_H

View File

@ -233,26 +233,11 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token,
return true; return true;
} }
void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet, bool genPublishKeys)
RsTlvSecurityKeySet& publickeySet, bool genPublishKeys)
{ {
/* create Keys */ /* create Keys */
// admin keys
RSA *rsa_admin = RSA_generate_key(2048, 65537, NULL, NULL);
RSA *rsa_admin_pub = RSAPublicKey_dup(rsa_admin);
/* set admin keys */
RsTlvSecurityKey adminKey, privAdminKey; RsTlvSecurityKey adminKey, privAdminKey;
GxsSecurity::generateKeyPair(adminKey,privAdminKey) ;
GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub);
GxsSecurity::setRSAPrivateKey(privAdminKey, rsa_admin);
adminKey.startTS = time(NULL);
adminKey.endTS = adminKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
privAdminKey.startTS = adminKey.startTS;
privAdminKey.endTS = 0; /* no end */
// for now all public // for now all public
adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY; adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY;
@ -261,27 +246,11 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet,
publickeySet.keys[adminKey.keyId] = adminKey; publickeySet.keys[adminKey.keyId] = adminKey;
privatekeySet.keys[privAdminKey.keyId] = privAdminKey; privatekeySet.keys[privAdminKey.keyId] = privAdminKey;
// clean up
RSA_free(rsa_admin);
RSA_free(rsa_admin_pub);
if(genPublishKeys) if(genPublishKeys)
{ {
// publish keys
RSA *rsa_publish = RSA_generate_key(2048, 65537, NULL, NULL);
RSA *rsa_publish_pub = RSAPublicKey_dup(rsa_publish);
/* set publish keys */ /* set publish keys */
RsTlvSecurityKey pubKey, privPubKey; RsTlvSecurityKey pubKey, privPubKey;
GxsSecurity::generateKeyPair(pubKey,privPubKey) ;
GxsSecurity::setRSAPublicKey(pubKey, rsa_publish_pub);
GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish);
pubKey.startTS = adminKey.startTS;
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
privPubKey.startTS = adminKey.startTS;
privPubKey.endTS = 0; /* no end */
// for now all public // for now all public
pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY; pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY;
@ -289,59 +258,19 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet,
publickeySet.keys[pubKey.keyId] = pubKey; publickeySet.keys[pubKey.keyId] = pubKey;
privatekeySet.keys[privPubKey.keyId] = privPubKey; privatekeySet.keys[privPubKey.keyId] = privPubKey;
RSA_free(rsa_publish);
RSA_free(rsa_publish_pub);
} }
} }
void RsGenExchange::generatePublicFromPrivateKeys(const RsTlvSecurityKeySet &privatekeySet, void RsGenExchange::generatePublicFromPrivateKeys(const RsTlvSecurityKeySet &privatekeySet, RsTlvSecurityKeySet &publickeySet)
RsTlvSecurityKeySet &publickeySet)
{ {
// actually just copy settings of one key except mark its key flags public
// actually just copy settings of one key except mark its key flags public publickeySet = RsTlvSecurityKeySet() ;
RsTlvSecurityKey pubkey ;
typedef std::map<std::string, RsTlvSecurityKey> keyMap; for(std::map<std::string, RsTlvSecurityKey>::const_iterator cit=privatekeySet.keys.begin(); cit != privatekeySet.keys.end(); ++cit)
const keyMap& allKeys = privatekeySet.keys; if(GxsSecurity::extractPublicKey(cit->second,pubkey))
keyMap::const_iterator cit = allKeys.begin(); publickeySet.keys.insert(std::make_pair(pubkey.keyId, pubkey));
for(; cit != allKeys.end(); cit++)
{
const RsTlvSecurityKey& privKey = cit->second;
if(privKey.keyFlags & RSTLV_KEY_TYPE_FULL)
{
RsTlvSecurityKey pubKey;
pubKey = privKey;
RSA *rsaPrivKey = NULL, *rsaPubKey = NULL;
rsaPrivKey = GxsSecurity::extractPrivateKey(privKey);
if(rsaPrivKey)
rsaPubKey = RSAPublicKey_dup(rsaPrivKey);
if(rsaPrivKey && rsaPubKey)
{
GxsSecurity::setRSAPublicKey(pubKey, rsaPubKey);
if(pubKey.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
pubKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY;
if(pubKey.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE)
pubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_PUBLIC_ONLY;
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
publickeySet.keys.insert(std::make_pair(pubKey.keyId, pubKey));
}
if(rsaPrivKey)
RSA_free(rsaPrivKey);
if(rsaPubKey)
RSA_free(rsaPubKey);
}
}
} }
uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet) uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet)

View File

@ -568,7 +568,8 @@ bool RsRecogn::createTagRequest(const RsTlvSecurityKey &key, const RsGxsId &id,
RsGxsRecognReqItem *item = new RsGxsRecognReqItem(); RsGxsRecognReqItem *item = new RsGxsRecognReqItem();
EVP_PKEY *signKey = EVP_PKEY_new(); EVP_PKEY *signKey = EVP_PKEY_new();
RSA *rsakey = GxsSecurity::extractPrivateKey(key); RSA *rsakey = d2i_RSAPrivateKey(NULL, (const unsigned char **)&key.keyData.bin_data, key.keyData.bin_len);
if (!rsakey) if (!rsakey)
{ {
#ifdef DEBUG_RECOGN #ifdef DEBUG_RECOGN