From 3354ade01871578f021affc6015f802dc0bdae08 Mon Sep 17 00:00:00 2001 From: jmjatlanta Date: Mon, 31 Oct 2016 14:13:20 -0500 Subject: [PATCH] added base64 of pub/private key pair --- include/ipfs/repo/config/base64.h | 58 ++++++++++++++++ mbedtls/x509_crl.c | 2 +- repo/config/identity.c | 106 ++++++++++++++++++++++++++++-- 3 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 include/ipfs/repo/config/base64.h diff --git a/include/ipfs/repo/config/base64.h b/include/ipfs/repo/config/base64.h new file mode 100644 index 0000000..3e21688 --- /dev/null +++ b/include/ipfs/repo/config/base64.h @@ -0,0 +1,58 @@ +// +// base64.h +// c-ipfs +// +// Created by John Jones on 10/31/16. +// Copyright © 2016 JMJAtlanta. All rights reserved. +// + +#ifndef base64_h +#define base64_h + +#include +#include "mbedtls/base64.h" + +/** + * encode using base64 + * @param input_data the data to be encoded + * @param input_length the length of the input data + * @param output_data where the data is to be stored + * @param max_output_length the max size of the output_data + * @param bytes_written the number of bytes written to output_data + * @returns true(1) on success, otherwise false + */ +int base64_encode(const unsigned char* input_data, size_t input_length, unsigned char* output_data, size_t max_output_length, size_t* bytes_written) { + int retVal = mbedtls_base64_encode(output_data, max_output_length, bytes_written, input_data, input_length); + return retVal == 0; +} + +size_t base64_encode_length(const unsigned char* input_data, size_t input_length) { + size_t req_bytes; + int retVal = mbedtls_base64_encode(NULL, 0, &req_bytes, input_data, input_length); + if( retVal != 0) + return 0; + return req_bytes; +} + +/** + * decode something that was encoded as base64 + * @param input_data the data to decode + * @param input_length the length of the input data + * @param output_data the buffer to store the output + * @param max_output_length the length of the output buffer + * @param bytes_written the number of bytes written to output_data + * @returns a pointer to the decoded data + */ +int base64_decode(const unsigned char* input_data, size_t input_length, unsigned char* output_data, size_t max_output_length, size_t* bytes_written) { + int retVal = mbedtls_base64_decode(output_data, max_output_length, bytes_written, input_data, input_length); + return retVal == 0; +} + +size_t base64_decode_length(const unsigned char* input_data, size_t input_length) { + size_t req_bytes; + int retVal = mbedtls_base64_decode(NULL, 0, &req_bytes, input_data, input_length); + if( retVal != 0) + return 0; + return req_bytes; +} +#endif /* base64_h */ diff --git a/mbedtls/x509_crl.c b/mbedtls/x509_crl.c index 7b2b473..2b79a74 100644 --- a/mbedtls/x509_crl.c +++ b/mbedtls/x509_crl.c @@ -491,7 +491,7 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s { #if defined(MBEDTLS_PEM_PARSE_C) int ret; - size_t use_len; + size_t use_len = 0; mbedtls_pem_context pem; int is_pem = 0; diff --git a/repo/config/identity.c b/repo/config/identity.c index 61c0471..a0d7908 100644 --- a/repo/config/identity.c +++ b/repo/config/identity.c @@ -8,11 +8,107 @@ #include #include +#include #include "ipfs/repo/config/identity.h" +#include "ipfs/repo/config/base64.h" -int repo_config_identity_generate_keypair(char* private_key, char* public_key) { - return 0; +// mbedtls stuff +#include "mbedtls/config.h" +#include "mbedtls/platform.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/bignum.h" +#include "mbedtls/x509.h" +#include "mbedtls/rsa.h" + +int repo_config_identity_generate_keypair(unsigned char* private_key, unsigned char* public_key, unsigned long num_bits_for_keypair) { + + mbedtls_rsa_context rsa; + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + + int exponent = 65537; + int retVal = 1; + + const char *pers = "rsa_genkey"; + + // initialize mbedtls structs + mbedtls_ctr_drbg_init( &ctr_drbg ); + mbedtls_entropy_init( &entropy ); + + // seed the routines + if( ( retVal = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, + (const unsigned char *) pers, + strlen( pers ) ) ) != 0 ) + { + retVal = 0; + goto exit; + } + + // initialize the rsa struct + mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); + + // finally, generate the key + if( ( retVal = mbedtls_rsa_gen_key( &rsa, mbedtls_ctr_drbg_random, &ctr_drbg, (unsigned int)num_bits_for_keypair, + exponent ) ) != 0 ) + { + retVal = 0; + goto exit; + } + retVal = 1; + + struct { + unsigned long long modulus; + unsigned long long public_exponent; + } pub_key; + + pub_key.modulus = *(rsa.N.p); + pub_key.public_exponent = *(rsa.E.p); + + struct { + unsigned long long modulus; + unsigned long long public_exponent; + unsigned long long private_exponent; + unsigned long long prime1; + unsigned long long prime2; + unsigned long long exponent1; + unsigned long long exponent2; + unsigned long long coefficient; + } priv_key; + + priv_key.modulus = *(rsa.N.p); + priv_key.public_exponent = *(rsa.E.p); + priv_key.private_exponent = *(rsa.D.p); + priv_key.prime1 = *(rsa.P.p); + priv_key.prime2 = *(rsa.Q.p); + //TODO: verify these 3 + priv_key.exponent1 = *(rsa.DP.p); + priv_key.exponent2 = *(rsa.DQ.p); + priv_key.coefficient = *(rsa.QP.p); + + // convert keys to base 64 and then store + unsigned char* input_buf = malloc(sizeof(pub_key)); + memcpy(input_buf, &pub_key, sizeof(pub_key)); + size_t bufLen = base64_encode_length(input_buf, sizeof(pub_key)); + public_key = malloc(sizeof(char) * bufLen); + retVal = base64_encode(input_buf, sizeof(pub_key), public_key, bufLen, &bufLen); + free(input_buf); + + input_buf = malloc(sizeof(priv_key)); + memcpy(input_buf, &priv_key, sizeof(priv_key)); + bufLen = base64_encode_length(input_buf, sizeof(pub_key)); + private_key = malloc(sizeof(char) * bufLen); + retVal = base64_encode(input_buf, sizeof(priv_key), private_key, bufLen, &bufLen); + + retVal = 0; +exit: + + mbedtls_rsa_free( &rsa ); + mbedtls_ctr_drbg_free( &ctr_drbg ); + mbedtls_entropy_free( &entropy ); + + return retVal; } /*** @@ -29,9 +125,9 @@ int repo_config_identity_new(struct Identity* identity, unsigned long num_bits_f identity = malloc(sizeof(struct Identity)); if (num_bits_for_keypair < 1024) return 0; - char* private_key; - char* public_key; - if (!repo_config_identity_generate_keypair(private_key, public_key)) + unsigned char* private_key; + unsigned char* public_key; + if (!repo_config_identity_generate_keypair(private_key, public_key, num_bits_for_keypair)) return 0; return 0; }