1
0
mirror of https://github.com/haiwen/ccnet-server.git synced 2025-04-30 11:33:21 +00:00
ccnet-server/lib/rsa.c

216 lines
4.2 KiB
C
Raw Permalink Normal View History

2016-08-18 09:39:55 +00:00
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
#include <openssl/pem.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <string.h>
#include <glib.h>
#include "rsa.h"
#include "utils.h"
2018-05-11 10:48:17 +00:00
/* Forward compatibility functions if libssl < 1.1.0. */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
{
/* If the fields n and e in r are NULL, the corresponding input
* parameters MUST be non-NULL for n and e. d may be
* left NULL (in case only the public key is used).
*/
if ((r->n == NULL && n == NULL)
|| (r->e == NULL && e == NULL))
return 0;
if (n != NULL) {
BN_free(r->n);
r->n = n;
}
if (e != NULL) {
BN_free(r->e);
r->e = e;
}
if (d != NULL) {
BN_free(r->d);
r->d = d;
}
return 1;
}
void RSA_get0_key(const RSA *r,
const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
{
if (n != NULL)
*n = r->n;
if (e != NULL)
*e = r->e;
if (d != NULL)
*d = r->d;
}
#endif
2016-08-18 09:39:55 +00:00
RSA*
private_key_to_pub(RSA *priv)
{
RSA *pub = RSA_new();
2018-05-11 10:48:17 +00:00
const BIGNUM *n, *e;
2016-08-18 09:39:55 +00:00
2018-05-11 10:48:17 +00:00
RSA_get0_key (priv, &n, &e, NULL);
RSA_set0_key (pub, BN_dup(n), BN_dup(e), NULL);
2016-08-18 09:39:55 +00:00
return pub;
}
GString* public_key_to_gstring(const RSA *rsa)
{
GString *buf = g_string_new(NULL);
unsigned char *temp;
char *coded;
2018-05-11 10:48:17 +00:00
const BIGNUM *n, *e;
RSA_get0_key (rsa, &n, &e, NULL);
gsize len = BN_num_bytes(n);
2016-08-18 09:39:55 +00:00
temp = malloc(len);
2018-05-11 10:48:17 +00:00
BN_bn2bin(n, temp);
2016-08-18 09:39:55 +00:00
coded = g_base64_encode(temp, len);
g_string_append (buf, coded);
g_string_append_c (buf, ' ');
g_free(coded);
2018-05-11 10:48:17 +00:00
len = BN_num_bytes(e);
2016-08-18 09:39:55 +00:00
temp = realloc(temp, len);
2018-05-11 10:48:17 +00:00
BN_bn2bin(e, temp);
2016-08-18 09:39:55 +00:00
coded = g_base64_encode(temp, len);
g_string_append (buf, coded);
g_free(coded);
free(temp);
return buf;
}
void
public_key_append_to_gstring(const RSA *rsa, GString *buf)
{
unsigned char *temp;
char *coded;
2018-05-11 10:48:17 +00:00
const BIGNUM *n, *e;
2016-08-18 09:39:55 +00:00
2018-05-11 10:48:17 +00:00
RSA_get0_key (rsa, &n, &e, NULL);
gsize len = BN_num_bytes(n);
2016-08-18 09:39:55 +00:00
temp = malloc(len);
2018-05-11 10:48:17 +00:00
BN_bn2bin(n, temp);
2016-08-18 09:39:55 +00:00
coded = g_base64_encode(temp, len);
g_string_append (buf, coded);
g_string_append_c (buf, ' ');
g_free(coded);
2018-05-11 10:48:17 +00:00
len = BN_num_bytes(e);
2016-08-18 09:39:55 +00:00
temp = realloc(temp, len);
2018-05-11 10:48:17 +00:00
BN_bn2bin(e, temp);
2016-08-18 09:39:55 +00:00
coded = g_base64_encode(temp, len);
g_string_append (buf, coded);
g_free(coded);
free(temp);
}
RSA* public_key_from_string(char *str)
{
char *p;
unsigned char *num;
gsize len;
2018-05-11 10:48:17 +00:00
BIGNUM *n = NULL, *e = NULL;
2016-08-18 09:39:55 +00:00
if (!str)
return NULL;
if ( !(p = strchr(str, ' ')) )
return NULL;
*p = '\0';
RSA *key = RSA_new();
num = g_base64_decode(str, &len);
2018-05-11 10:48:17 +00:00
n = BN_bin2bn(num, len, NULL);
if (!n)
2016-08-18 09:39:55 +00:00
goto err;
g_free(num);
num = g_base64_decode(p+1, &len);
2018-05-11 10:48:17 +00:00
e = BN_bin2bn(num, len, NULL);
if (!e)
2016-08-18 09:39:55 +00:00
goto err;
g_free(num);
2018-05-11 10:48:17 +00:00
RSA_set0_key (key, n, e, NULL);
2016-08-18 09:39:55 +00:00
*p = ' ';
return key;
err:
*p = ' ';
RSA_free (key);
2018-05-11 10:48:17 +00:00
if (n)
BN_free (n);
if (e)
BN_free (e);
2016-08-18 09:39:55 +00:00
g_free(num);
return NULL;
}
unsigned char *
private_key_decrypt(RSA *key, unsigned char *data, int len, int *decrypt_len)
{
int size;
unsigned char *buf;
size = RSA_size(key);
buf = g_malloc(size);
*decrypt_len = RSA_private_decrypt(len, data, buf, key, RSA_PKCS1_PADDING);
return buf;
}
unsigned char *
public_key_encrypt(RSA *key, unsigned char *data, int len, int *encrypt_len)
{
int size;
unsigned char *buf;
size = RSA_size(key);
buf = g_malloc(size);
*encrypt_len = RSA_public_encrypt(len, data, buf, key, RSA_PKCS1_PADDING);
return buf;
}
char *
id_from_pubkey (RSA *pubkey)
{
GString *buf;
unsigned char sha1[20];
char *id = g_malloc(41);
buf = public_key_to_gstring (pubkey);
calculate_sha1 (sha1, buf->str);
sha1_to_hex (sha1, id);
g_string_free (buf, TRUE);
return id;
}
RSA *
generate_private_key(u_int bits)
{
RSA *private = NULL;
private = RSA_generate_key(bits, 35, NULL, NULL);
if (private == NULL)
g_error ("rsa_generate_private_key: key generation failed.");
return private;
}