Adjustments for private key and peer id

This commit is contained in:
John Jones 2016-11-14 17:58:55 -05:00
parent 4818ac8567
commit 93dc4d558f
8 changed files with 221 additions and 19 deletions

View file

@ -91,6 +91,12 @@ int libp2p_crypto_encoding_x509_der_to_private_key(unsigned char* der, size_t de
private_key->QP = *(rsa->QP.p); private_key->QP = *(rsa->QP.p);
} }
// now put the public DER format in.
private_key->der = der;
private_key->der_length = der_length;
//NOTE: the public DER stuff is done in rsa.c
mbedtls_pk_free(&ctx); mbedtls_pk_free(&ctx);
return retVal >= 0; return retVal >= 0;

View file

@ -21,6 +21,7 @@
#include "mbedtls/rsa.h" #include "mbedtls/rsa.h"
#include "mbedtls/asn1write.h" #include "mbedtls/asn1write.h"
#include "mbedtls/oid.h" #include "mbedtls/oid.h"
#include "mbedtls/pk.h"
/** /**
* Take an rsa context and turn it into a der formatted byte stream. * Take an rsa context and turn it into a der formatted byte stream.
@ -193,6 +194,40 @@ exit:
return retVal; return retVal;
} }
/**
* Use the private key DER to fill in the public key DER
* @param private_key the private key to use
* @reutrns true(1) on success
*/
int libp2p_crypto_rsa_private_key_fill_public_key(struct RsaPrivateKey* private_key) {
// first build the rsa context
mbedtls_pk_context ctx;
mbedtls_pk_init(&ctx);
mbedtls_pk_parse_key(&ctx, private_key->der, private_key->der_length, NULL, 0);
// buffer
size_t buffer_size = 1600;
unsigned char buffer[buffer_size];
memset(buffer, 0, buffer_size);
// generate public key der
int retVal = libp2p_crypto_rsa_write_public_key_der(&ctx, buffer, &buffer_size);
if (retVal == 0) {
mbedtls_pk_free(&ctx);
return 0;
}
// allocate memory for the public key der
private_key->public_key_length = buffer_size;
private_key->public_key_der = malloc(sizeof(char) * buffer_size);
//copy it into the struct
memcpy(private_key->public_key_der, &buffer[1600-buffer_size], buffer_size);
mbedtls_pk_free(&ctx);
return 1;
}
/*** /***
* Free resources used by RsaPrivateKey * Free resources used by RsaPrivateKey
* @param private_key the resources * @param private_key the resources

View file

@ -1,10 +1,6 @@
// /**
// x509.h * Wrappers around the x509 stuff
// libp2p_xcode */
//
// Created by John Jones on 11/7/16.
// Copyright © 2016 JMJAtlanta. All rights reserved.
//
#ifndef __LIBP2P_CRYPTO_ENCODING_X509_H__ #ifndef __LIBP2P_CRYPTO_ENCODING_X509_H__
#define __LIBP2P_CRYPTO_ENCODING_X509_H__ #define __LIBP2P_CRYPTO_ENCODING_X509_H__

View file

@ -38,6 +38,14 @@ struct RsaPrivateKey {
*/ */
int libp2p_crypto_rsa_generate_keypair(struct RsaPrivateKey* private_key, unsigned long num_bits_for_keypair); int libp2p_crypto_rsa_generate_keypair(struct RsaPrivateKey* private_key, unsigned long num_bits_for_keypair);
/**
* Use the private key DER to fill in the public key DER
* @param private_key the private key to use
* @reutrns true(1) on success
*/
int libp2p_crypto_rsa_private_key_fill_public_key(struct RsaPrivateKey* private_key);
/*** /***
* Free resources used by RsaPrivateKey * Free resources used by RsaPrivateKey
* @param private_key the resources * @param private_key the resources

View file

@ -1,9 +1,12 @@
#ifndef PEERDEP #ifndef PEERDEP
#define PEERDEP #define PEERDEP
#include "stdio.h" #include "stdio.h"
#include "string.h" #include "string.h"
#include <stdio.h> #include <stdio.h>
#include "base58.h" #include "libp2p/crypto/encoding/base58.h"
#include "mh/multihash.h"
#include "mh/hashes.h"
#define uchar unsigned char // 8-bit byte #define uchar unsigned char // 8-bit byte
#define juint unsigned int // 32-bit word #define juint unsigned int // 32-bit word
@ -165,25 +168,65 @@ void a_store_hash(unsigned char * result,unsigned char hash[])
strcat(result,mimi); strcat(result,mimi);
} }
} }
int PrettyID(unsigned char * pointyaddr, size_t rezbuflen,unsigned char * ID_BUF, size_t ID_BUF_SIZE)//b58 encoded ID buf
/**
* base58 encode a string NOTE: this also puts the prefix 'Qm' in front as the ID is a multihash
* @param pointyaddr where the results will go
* @param rezbuflen the length of the results buffer. It will also put how much was used here
* @param ID_BUF the input text (usually a SHA256 hash)
* @param ID_BUF_SIZE the input size (normally a SHA256, therefore 32 bytes)
* @returns true(1) on success
*/
int PrettyID(unsigned char * pointyaddr, size_t* rezbuflen,unsigned char * ID_BUF, size_t ID_BUF_SIZE)//b58 encoded ID buf
{ {
int returnstatus = 0; int returnstatus = 0;
returnstatus = libp2p_crypto_encoding_base58_encode(ID_BUF, ID_BUF_SIZE, &pointyaddr, &rezbuflen);
unsigned char temp_buffer[*rezbuflen];
memset(temp_buffer, 0, *rezbuflen);
// wrap the base58 into a multihash
int retVal = mh_new(temp_buffer, MH_H_SHA2_256, ID_BUF, ID_BUF_SIZE);
if (retVal < 0)
return 0;
// base58 the multihash
returnstatus = libp2p_crypto_encoding_base58_encode(temp_buffer, strlen(temp_buffer), &pointyaddr, rezbuflen);
if(returnstatus == 0) if(returnstatus == 0)
{ {
printf("\nERROR!!!!!\n"); printf("\nERROR!!!!!\n");
return 0; return 0;
} }
return 1; return 1;
} }
void ID_FromPK(char * result,unsigned char * texttohash)
/****
* Make a SHA256 hash of what is usually the DER formatted private key.
* @param result where to store the result. Should be 32 chars long
* @param texttohash the text to hash
* @param text_size the size of the text
*/
void ID_FromPK_non_null_terminated(char * result,unsigned char * texttohash, size_t text_size)
{ {
unsigned char hash[32]; unsigned char hash[32];
bzero(hash,32); bzero(hash,32);
SHA256_CTX ctx; SHA256_CTX ctx;
sha256_init(&ctx); sha256_init(&ctx);
sha256_update(&ctx,texttohash,strlen(texttohash)); sha256_update(&ctx,texttohash,text_size);
sha256_final(&ctx,hash); sha256_final(&ctx,hash);
a_store_hash(result,hash); a_store_hash(result,hash);
} }
/****
* Make a SHA256 hash of what is usually the DER formatted private key.
* @param result where to store the result. Should be 32 chars long
* @param texttohash a null terminated string of the text to hash
*/
void ID_FromPK(char * result,unsigned char * texttohash)
{
ID_FromPK_non_null_terminated(result,texttohash,strlen(texttohash));
}
#endif #endif

View file

@ -1,11 +1,11 @@
CC = gcc CC = gcc
CFLAGS = -O0 -I../include -I. CFLAGS = -O0 -I../include -I. -I../../c-multihash/include
ifdef DEBUG ifdef DEBUG
CFLAGS += -g3 CFLAGS += -g3
endif endif
LFLAGS = -L../ LFLAGS = -L../ -L../../c-multihash
DEPS = crypto/test_base58.h crypto/test_rsa.h test_mbedtls.h DEPS = crypto/test_base58.h crypto/test_rsa.h test_mbedtls.h
OBJS = testit.o OBJS = testit.o
@ -13,9 +13,13 @@ OBJS = testit.o
$(CC) -c -o $@ $< $(CFLAGS) $(CC) -c -o $@ $< $(CFLAGS)
testit_libp2p: $(OBJS) $(DEPS) testit_libp2p: $(OBJS) $(DEPS)
$(CC) -o $@ $(OBJS) $(LFLAGS) -lp2p -lm $(CC) -o $@ $(OBJS) $(LFLAGS) -lp2p -lm -lmultihash
all: testit_libp2p all_others:
cd ../crypto; make all;
cd ../thirdparty; make all;
all: all_others testit_libp2p
clean: clean:
rm -f *.o rm -f *.o

View file

@ -16,6 +16,8 @@
#include "libp2p/crypto/rsa.h" #include "libp2p/crypto/rsa.h"
#include "libp2p/crypto/encoding/base64.h" #include "libp2p/crypto/encoding/base64.h"
#include "libp2p/crypto/encoding/x509.h" #include "libp2p/crypto/encoding/x509.h"
#include "libp2p/peerutils.h"
/** /**
* make sure we can get a DER formatted result * make sure we can get a DER formatted result
@ -75,6 +77,112 @@ int test_crypto_x509_der_to_private() {
return private_key.D > 0; return private_key.D > 0;
} }
int test_public_der_to_private_der() {
struct RsaPrivateKey private_key;
int retVal = libp2p_crypto_rsa_generate_keypair(&private_key, 2048);
if (retVal == 0)
return 0;
if (private_key.der_length == 0)
return 0;
if (private_key.der == NULL)
return 0;
// copy the public DER to a temporary area, then erase it, then try to generate it again.
size_t public_der_temp_length = private_key.public_key_length;
unsigned char public_der_temp[private_key.public_key_length];
memcpy(public_der_temp, private_key.public_key_der, private_key.public_key_length);
free(private_key.public_key_der);
private_key.public_key_length = 0;
retVal = libp2p_crypto_rsa_private_key_fill_public_key(&private_key);
if (retVal == 0)
return 0;
if (public_der_temp_length != private_key.public_key_length)
return 0;
/*
for(int i = 0; i < public_der_temp_length; i++)
if (public_der_temp[i] != private_key.public_key_der[i])
return 0;
*/
// that didn't work... so let's try it again, to see if it is consistent
size_t public_der_temp_length2 = private_key.public_key_length;
unsigned char public_der_temp2[public_der_temp_length2];
memcpy(public_der_temp2, private_key.public_key_der, public_der_temp_length2);
free(private_key.public_key_der);
private_key.public_key_length = 0;
retVal = libp2p_crypto_rsa_private_key_fill_public_key(&private_key);
if (retVal == 0)
return 0;
for(int i = 0; i < public_der_temp_length2; i++)
if (private_key.public_key_der[i] != public_der_temp2[i])
return 0;
// well, at least it is consistent.
return 1;
}
int test_crypto_rsa_public_key_to_peer_id() {
// this is the base64 encoded private key from the config file
char* orig_priv_key = "CAASpwkwggSjAgEAAoIBAQDTDJBWjDzS/HxDNOHazvzH2bu9CPMVHUrrvKRdBUM5ansL6/CC3MVZ6HVm4O6QHRapN6EF2CbrTgI4KBOXIL125Xo8MlROnyfXYk3O5q2tgwL/MbW8kXjtkyCfBak7MUoLOdLU7Svg0gkl3l+uDAiDcCLnwJVcFfq9ch6z4wMOhYJqE5dtx0uXxn6IuKWl1B69FTvBXCc0thw8Rw54b941FDcsBH5ttV9mRNCJym3poZ5qalNgXlxoIIB+PUx5QD+aq7KMJdpAX8HkapBntCOahP/QUceRmma0grlZLeYkH6/oi/hIrM6se3KUZ+F6tBuDFys8UAZy/X2BCUbKjbxtAgMBAAECggEANWfQfpYuLhXGPBt9q6kFPm1SnJtPJ+CpvM2XqhJS2IyhZnrl+bd0GTRBwS7aL42s1lVFYf04nAK5fQxnKK8YQqX/MIxr2RldM5ukpN6qxGWKtJkXrAgD2dqJPrRoBpqKahzPxSHfIJ0Fw5dqDtjsrpYJvyt0oEDPmnDuZAbmFx4sJqnesPNhKxtRMBx1+yxGVuRVJjHcqAgqPqwNiuoMEaYMY+G9yzT6vza8ovCpbX7BBIgM5fAT9PD8TBG//Vu9THvj/ZomiVG2qv6RL0qQyVb+DUzPZz1amBsSvahtXCl72jA3JwAZ943RxSR66P934S0ashkVwLUi46z/EAbJ4QKBgQDojGIO07BEVL2+7VxlGL9XGZQp4Y3qlhh2zDDQGwkCq/KQ+BdNYWitPwqRl9GqFLgpmeQIhyHTOa/IThx+AXGKVQ24ROH+skUs4IbO6R3qY7BKtb5lkZE/Yln09x70BBngUYAzh/rtnsXO3cl1x2XDDqUbCwlGcDAs8Jh/6UnvQwKBgQDoVSQs7Uq9MJCGIUM2bixX89tHzSxq5mn9wMD3/XRVfT5Ua8YkYBuzcmlcT39N7L5BwuyFqX3Vi7lv/Ya/qaQP6XkrZ8W1OAaTlYewfE5ZgknJqSpXcNWhABKeNmqndvqyQ/8HNCv/j8AdraGB2DGO57Xso5J0CQ43W/U9+QIyjwKBgHLL2hw3o+wXaRO3WMUPUmVM2zdRgR0suybp5a7Vqb0H5NZrohUw4NulIzJ8H6Q2VjMzJL6Q9sGu2HepF6ecTtBa7ErqtiVlG4Dr1aCOs5XhYEWBMlwxX+JKSt4Cn+UVoTB7Cy5lEhn7JurX0Xuy0ylXMWoIKKv89cs5eg6quzTBAoGAaq9eEztLjKCWXOE9SetBdYnG8aunb9cqaJlwgu/h0bfXPVDYBbAUSEyLURY4MQI7Q1tM3Pu9iqfEmUZj7/LoIV5mg6X9RX/alT6etk3+dF+9nlqN1OU9U9cCtZ/rTcb2y5EptJcidRH/eCFY/pTV/PcttOJPx/S4kHcroC+N8MUCgYEA6DA5QHxHfNN6Nxv+pEzy2DIxFe9RrBxS+KPBsra1C8jgdeMf4EmfU0Nox92V0q0bRrD5ztqQwSONI0hSRb1iiMWR6MuFnAFajUJfASjjIlZ6nIQjQslI7vjlvYyyHS/p/Codxap+yJlTLWwVEOXp2D9pWwiMq1xEyf0TH1BosvM=";
// this is the peer id from the config file
char* orig_peer_id = "QmRskXriTSRjAftYX7QG1i1jAhouz5AHaLYZKNhEWRu5Fq";
size_t orig_peer_id_size = strlen(orig_peer_id);
// if we take the private key, retrieve the public key, hash it, we should come up with the peer id
// 1) take the private key and turn it back into bytes (decode base 64)
size_t decode_base64_size = libp2p_crypto_encoding_base64_decode_size(strlen(orig_priv_key));
unsigned char decode_base64[decode_base64_size];
memset(decode_base64, 0, decode_base64_size);
unsigned char* ptr = decode_base64;
int retVal = libp2p_crypto_encoding_base64_decode(orig_priv_key, strlen(orig_priv_key), ptr, decode_base64_size, &decode_base64_size);
if (retVal == 0)
return 0;
// the first 5 bytes [0-4] are protobuf metadata before the DER encoded private key
// byte 0 is "Tag 1 which is a varint"
// byte 1 is the value of the varint
// byte 2 is "Tag 2 which is a type 2, length delimited field"
// bytes 3 & 4 is a varint with the value of 1191, which is the number of bytes that follow
// 2) take the bytes of the private key and turn it back into a private key struct
struct RsaPrivateKey private_key = {0};
retVal = libp2p_crypto_encoding_x509_der_to_private_key(&decode_base64[5], decode_base64_size - 5, &private_key);
if (retVal == 0)
return 0;
// 2b) take the private key and fill in the public key DER
retVal = libp2p_crypto_rsa_private_key_fill_public_key(&private_key);
if (retVal == 0)
return 0;
// 3) grab the public key, hash it, then base58 it
unsigned char hashed[32];
ID_FromPK_non_null_terminated(hashed, private_key.public_key_der, private_key.public_key_length);
size_t final_id_size = 1600;
unsigned char final_id[final_id_size];
memset(final_id, 0, final_id_size);
retVal = PrettyID(final_id, &final_id_size, hashed, 32);
if (retVal == 0)
return 0;
// 4) compare results
if (orig_peer_id_size != final_id_size)
return 0;
if (strncmp(orig_peer_id, final_id, final_id_size) != 0)
return 0;
return 1;
}
#endif /* test_rsa_h */ #endif /* test_rsa_h */

View file

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include "crypto/test_rsa.h" #include "crypto/test_rsa.h"
#include "crypto/test_base58.h" #include "crypto/test_base58.h"
#include "test_mbedtls.h" #include "test_mbedtls.h"
@ -16,10 +17,11 @@ int testit(const char* name, int (*func)(void)) {
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
testit("test_public_der_to_private_der", test_public_der_to_private_der);
testit("test_mbedtls_varint_128_binary", test_mbedtls_varint_128_binary); testit("test_mbedtls_varint_128_binary", test_mbedtls_varint_128_binary);
testit("test_mbedtls_varint_128_string", test_mbedtls_varint_128_string); testit("test_mbedtls_varint_128_string", test_mbedtls_varint_128_string);
testit("test_crypto_rsa_private_key_der", test_crypto_rsa_private_key_der); testit("test_crypto_rsa_private_key_der", test_crypto_rsa_private_key_der);
//testit("test_crypto_x509_private_to_der", test_crypto_x509_private_to_der); testit("test_crypto_rsa_public_key_to_peer_id", test_crypto_rsa_public_key_to_peer_id);
testit("test_crypto_x509_der_to_private2", test_crypto_x509_der_to_private2); testit("test_crypto_x509_der_to_private2", test_crypto_x509_der_to_private2);
testit("test_crypto_x509_der_to_private", test_crypto_x509_der_to_private); testit("test_crypto_x509_der_to_private", test_crypto_x509_der_to_private);
//testit("test_multihash_encode", test_multihash_encode); //testit("test_multihash_encode", test_multihash_encode);