2016-11-03 15:22:17 +00:00
|
|
|
/**
|
|
|
|
* an "Identity"
|
|
|
|
*/
|
2016-10-31 16:13:42 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2016-10-31 19:13:20 +00:00
|
|
|
#include <string.h>
|
2016-10-31 16:13:42 +00:00
|
|
|
|
|
|
|
#include "ipfs/repo/config/identity.h"
|
2016-11-03 15:22:17 +00:00
|
|
|
#include "libp2p/crypto/rsa.h"
|
2016-11-17 20:07:59 +00:00
|
|
|
#include "libp2p/peerutils.h"
|
|
|
|
#include "libp2p/crypto/encoding/base64.h"
|
|
|
|
#include "libp2p/crypto/encoding/x509.h"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Builds the Peer ID using the private key, and places it in the identity->peer_id
|
|
|
|
* @param identity Where to get the DER of the private key
|
|
|
|
* @returns true(1) on success
|
|
|
|
*/
|
|
|
|
int repo_config_identity_build_peer_id(struct Identity* identity) {
|
|
|
|
// ic key and PeerID
|
|
|
|
char hash[32];
|
|
|
|
ID_FromPK_non_null_terminated(hash, identity->private_key.der, identity->private_key.der_length);
|
|
|
|
|
|
|
|
// peer id is multihashed
|
|
|
|
size_t sz = 255;
|
|
|
|
char results[sz];
|
|
|
|
if (PrettyID(results, &sz, hash, 32) == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// copy it into the structure
|
2016-12-01 18:08:30 +00:00
|
|
|
if (identity->peer_id != NULL)
|
|
|
|
free(identity->peer_id);
|
2016-11-17 20:07:59 +00:00
|
|
|
identity->peer_id = (char*)malloc(sz + 1);
|
|
|
|
if (identity->peer_id == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
strncpy(identity->peer_id, results, sz);
|
|
|
|
identity->peer_id[sz] = 0;
|
|
|
|
return 1;
|
|
|
|
}
|
2016-10-31 16:13:42 +00:00
|
|
|
|
|
|
|
/***
|
|
|
|
* public methods
|
|
|
|
*/
|
|
|
|
|
|
|
|
/***
|
2016-11-17 20:07:59 +00:00
|
|
|
* Initializes a new Identity. NOTE: This builds a new private/public key pair
|
2016-10-31 16:13:42 +00:00
|
|
|
* @param identity the identity to fill
|
|
|
|
* @param num_bits_for_keypair the number of bits for the keypair
|
|
|
|
* @returns true(1) on success, false(0) otherwise
|
|
|
|
*/
|
2016-11-17 20:07:59 +00:00
|
|
|
int repo_config_identity_init(struct Identity* identity, unsigned long num_bits_for_keypair) {
|
2016-10-31 16:13:42 +00:00
|
|
|
if (num_bits_for_keypair < 1024)
|
|
|
|
return 0;
|
2016-10-31 22:19:27 +00:00
|
|
|
// generate the private key (& public)
|
2016-11-14 02:01:51 +00:00
|
|
|
if (!libp2p_crypto_rsa_generate_keypair( &(identity->private_key), num_bits_for_keypair))
|
2016-10-31 16:13:42 +00:00
|
|
|
return 0;
|
2016-11-17 20:07:59 +00:00
|
|
|
|
2016-11-28 13:09:00 +00:00
|
|
|
if (repo_config_identity_build_peer_id(identity) == 0)
|
|
|
|
return 0;
|
|
|
|
|
2016-11-17 20:07:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2016-11-10 21:36:34 +00:00
|
|
|
|
2016-11-17 20:07:59 +00:00
|
|
|
int repo_config_identity_new(struct Identity** identity) {
|
|
|
|
*identity = (struct Identity*)malloc(sizeof(struct Identity));
|
|
|
|
if (*identity == NULL)
|
|
|
|
return 0;
|
2016-11-10 21:36:34 +00:00
|
|
|
|
2016-11-17 20:07:59 +00:00
|
|
|
memset(*identity, 0, sizeof(struct Identity));
|
2016-11-28 13:09:00 +00:00
|
|
|
|
|
|
|
(*identity)->peer_id = NULL;
|
2016-12-01 18:08:30 +00:00
|
|
|
(*identity)->private_key.public_key_der = NULL;
|
|
|
|
(*identity)->private_key.der = NULL;
|
2016-11-28 13:09:00 +00:00
|
|
|
|
2016-11-02 18:09:38 +00:00
|
|
|
return 1;
|
2016-10-31 16:13:42 +00:00
|
|
|
}
|
2016-11-10 13:28:51 +00:00
|
|
|
|
|
|
|
int repo_config_identity_free(struct Identity* identity) {
|
2016-11-17 20:07:59 +00:00
|
|
|
if (identity != NULL) {
|
|
|
|
if (identity->private_key.public_key_der != NULL)
|
|
|
|
free(identity->private_key.public_key_der);
|
|
|
|
if (identity->private_key.der != NULL)
|
|
|
|
free(identity->private_key.der);
|
2016-11-28 13:09:00 +00:00
|
|
|
if (identity->peer_id != NULL)
|
|
|
|
free(identity->peer_id);
|
2016-11-17 20:07:59 +00:00
|
|
|
free(identity);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
|
|
* Build a RsaPrivateKey struct from a base64 string of the private key
|
|
|
|
* @param identity where to put the new struct
|
|
|
|
* @param base64 the null terminated base 64 encoded private key in DER format
|
|
|
|
* @returns true(1) on success
|
|
|
|
*/
|
|
|
|
int repo_config_identity_build_private_key(struct Identity* identity, const char* base64) {
|
|
|
|
size_t decoded_size = libp2p_crypto_encoding_base64_decode_size(strlen(base64));
|
|
|
|
unsigned char decoded[decoded_size];
|
|
|
|
|
|
|
|
int retVal = libp2p_crypto_encoding_base64_decode(base64, strlen(base64), decoded, decoded_size, &decoded_size);
|
|
|
|
if (retVal == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// now convert DER to RsaPrivateKey
|
|
|
|
retVal = libp2p_crypto_encoding_x509_der_to_private_key(decoded, decoded_size, &identity->private_key);
|
|
|
|
if (retVal == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// now build the private key DER
|
|
|
|
retVal = libp2p_crypto_rsa_private_key_fill_public_key(&identity->private_key);
|
|
|
|
if (retVal == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// now build PeerID
|
|
|
|
retVal = repo_config_identity_build_peer_id(identity);
|
|
|
|
|
|
|
|
return retVal;
|
2016-11-10 13:28:51 +00:00
|
|
|
}
|