* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-
#include "../config.h"
-struct crypt_rsa_pubkey;
-struct crypt_rsa_privkey;
-
-static struct crypt_rsa_pubkey *crypt_load_pubkey(const char *key);
-static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey);
-static struct crypt_rsa_privkey *crypt_load_privkey(const char *key);
-static void crypt_unload_privkey(struct crypt_rsa_privkey *privkey);
-
-static void crypt_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char *encrypted);
-static void crypt_decrypt_data(struct crypt_rsa_privkey *privkey, const char *encrypted, int enclen, char *data);
-static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey);
-static void crypt_encrypt_free(char *encrypted);
-static void crypt_decrypt_free(char *data);
-
-
+#include "crypt_rsa.h"
+#include <stdio.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+/*
+// GnuTLS Backend not working because of gnutls_pubkey_encrypt_data doesn't exists prior to GnuTLS 3.0
+// still searching for a replacement...
#if defined(HAVE_GNUTLS_GNUTLS_H)
#include <gnutls/gnutls.h>
unsigned int free_pubkey : 1;
gnutls_x509_crt_t crt;
gnutls_pubkey_t pubkey;
-}
+};
struct crypt_rsa_privkey {
unsigned int free_key : 1;
unsigned int free_privkey : 1;
gnutls_x509_privkey_t key;
gnutls_privkey_t privkey;
+};
+
+void crypt_rsa_init() {
+ gnutls_global_init();
}
-static struct crypt_rsa_pubkey *crypt_load_pubkey(const char *key) {
+void crypt_rsa_deinit() {
+ gnutls_global_deinit();
+}
+
+struct crypt_rsa_pubkey *crypt_rsa_load_pubkey(const char *key) {
struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
int ret;
const gnutls_datum_t key_dat = {(void *)key, strlen(key)};
ret = gnutls_x509_crt_init(&pubkey->crt);
if(ret < 0)
- goto crypt_load_pubkey_fail;
+ goto crypt_rsa_load_pubkey_fail;
pubkey->free_crt = 1;
ret = gnutls_x509_crt_import(pubkey->crt, &key_dat, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- goto crypt_load_pubkey_fail;
+ goto crypt_rsa_load_pubkey_fail;
- ret = gnutls_pubkey_init(&pubkey.pubkey);
+ ret = gnutls_pubkey_init(&pubkey->pubkey);
if(ret < 0)
- goto crypt_load_pubkey_fail;
+ goto crypt_rsa_load_pubkey_fail;
pubkey->free_pubkey = 1;
ret = gnutls_pubkey_import_x509(pubkey->pubkey, pubkey->crt, 0);
if(ret < 0)
- goto crypt_load_pubkey_fail;
+ goto crypt_rsa_load_pubkey_fail;
return pubkey;
- crypt_load_pubkey_fail:
- crypt_unload_pubkey(pubkey);
+ crypt_rsa_load_pubkey_fail:
+ crypt_rsa_unload_pubkey(pubkey);
return NULL;
}
-static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
- if(pubkey->free_key)
+void crypt_rsa_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
+ if(pubkey->free_crt)
gnutls_x509_crt_deinit(pubkey->crt);
- if(pubkey->free_privkey)
+ if(pubkey->free_pubkey)
gnutls_pubkey_deinit(pubkey->pubkey);
free(pubkey);
}
-static struct crypt_rsa_privkey *crypt_load_privkey(const char *key) {
+char *crypt_rsa_export_pubkey(struct crypt_rsa_pubkey *pubkey) {
+ size_t size = 1024;
+ char *buffer = malloc(size);
+ int ret;
+
+ ret = gnutls_pubkey_export(pubkey->pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
+ if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
+ buffer = realloc(buffer, size);
+ ret = gnutls_pubkey_export(pubkey->pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
+ }
+ if(ret < 0) {
+ free(buffer);
+ return NULL;
+ }
+ return buffer;
+}
+
+struct crypt_rsa_privkey *crypt_rsa_load_privkey(const char *key) {
struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
int ret;
const gnutls_datum_t key_dat = {(void *)key, strlen(key)};
- privkey.valid = 0;
ret = gnutls_x509_privkey_init(&privkey->key);
if(ret < 0)
- goto crypt_load_privkey_fail;
+ goto crypt_rsa_load_privkey_fail;
privkey->free_key = 1;
ret = gnutls_x509_privkey_import(privkey->key, &key_dat, GNUTLS_X509_FMT_PEM);
if (ret < 0)
- goto crypt_load_privkey_fail;
+ goto crypt_rsa_load_privkey_fail;
- ret = gnutls_privkey_init(&privkey.privkey);
+ ret = gnutls_privkey_init(&privkey->privkey);
if(ret < 0)
- goto crypt_load_privkey_fail;
+ goto crypt_rsa_load_privkey_fail;
privkey->free_privkey = 1;
ret = gnutls_privkey_import_x509(privkey->privkey, privkey->key, 0);
if(ret < 0)
- goto crypt_load_privkey_fail;
+ goto crypt_rsa_load_privkey_fail;
return privkey;
- crypt_load_privkey_fail:
- crypt_unload_privkey(privkey);
+ crypt_rsa_load_privkey_fail:
+ crypt_rsa_unload_privkey(privkey);
return NULL;
}
-static void crypt_unload_privkey(struct crypt_rsa_privkey *privkey) {
+struct crypt_rsa_privkey *crypt_rsa_generate_privkey(const int keysize) {
+ struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
+ int ret;
+
+ ret = gnutls_x509_privkey_init(&privkey->key);
+ if(ret < 0)
+ goto crypt_rsa_generate_privkey_fail;
+ privkey->free_key = 1;
+
+ ret = gnutls_x509_privkey_generate(privkey->key, GNUTLS_PK_RSA, keysize, 0);
+ if (ret < 0)
+ goto crypt_rsa_generate_privkey_fail;
+
+ ret = gnutls_privkey_init(&privkey->privkey);
+ if(ret < 0)
+ goto crypt_rsa_generate_privkey_fail;
+ privkey->free_privkey = 1;
+
+ ret = gnutls_privkey_import_x509(privkey->privkey, privkey->key, 0);
+ if(ret < 0)
+ goto crypt_rsa_generate_privkey_fail;
+
+ return privkey;
+ crypt_rsa_generate_privkey_fail:
+ crypt_rsa_unload_privkey(privkey);
+ return NULL;
+}
+
+char *crypt_rsa_export_privkey(struct crypt_rsa_privkey *privkey, int pubkey) {
+ size_t size = 1024;
+ char *buffer = malloc(size);
+ int ret;
+
+ if(pubkey) {
+ gnutls_pubkey_t pkey;
+ ret = gnutls_pubkey_init(&pkey);
+ if(ret < 0) {
+ free(buffer);
+ return NULL;
+ }
+ ret = gnutls_pubkey_import_privkey(pkey, privkey->privkey, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
+ if(ret < 0) {
+ free(buffer);
+ gnutls_pubkey_deinit(pkey);
+ return NULL;
+ }
+ ret = gnutls_pubkey_export(pkey, GNUTLS_X509_FMT_PEM, buffer, &size);
+ if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
+ buffer = realloc(buffer, size);
+ ret = gnutls_pubkey_export(pkey, GNUTLS_X509_FMT_PEM, buffer, &size);
+ }
+ gnutls_pubkey_deinit(pkey);
+ } else {
+ ret = gnutls_x509_privkey_export(privkey->key, GNUTLS_X509_FMT_PEM, buffer, &size);
+ if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
+ buffer = realloc(buffer, size);
+ ret = gnutls_x509_privkey_export(privkey->key, GNUTLS_X509_FMT_PEM, buffer, &size);
+ }
+ }
+ if(ret < 0) {
+ free(buffer);
+ return NULL;
+ }
+ return buffer;
+}
+
+void crypt_rsa_unload_privkey(struct crypt_rsa_privkey *privkey) {
if(privkey->free_key)
gnutls_x509_privkey_deinit(privkey->key);
if(privkey->free_privkey)
free(privkey);
}
+struct crypt_rsa_pubkey *crypt_rsa_get_pubkey(struct crypt_rsa_privkey *privkey) {
+ struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
+ if(!pubkey)
+ return NULL;
+ int ret;
+
+ ret = gnutls_pubkey_init(&pubkey->pubkey);
+ if(ret < 0)
+ goto crypt_rsa_get_pubkey_fail;
+ pubkey->free_pubkey = 1;
+
+ ret = gnutls_pubkey_import_privkey(pubkey->pubkey, privkey->privkey, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
+ if(ret < 0)
+ goto crypt_rsa_get_pubkey_fail;
+
+ return pubkey;
+ crypt_rsa_get_pubkey_fail:
+ crypt_rsa_unload_pubkey(pubkey);
+ return NULL;
+}
-static void crypt_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char *encrypted) {
+int crypt_rsa_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char **encrypted) {
+ const gnutls_datum_t data_dat = {(void *)data, datalen};
+ gnutls_datum_t out;
+ int ret = gnutls_pubkey_encrypt_data(pubkey->pubkey, 0, &data_dat, &out);
+ if(ret < 0)
+ return ret;
+
+ *encrypted = out.data;
+ return out.size;
}
-static void crypt_decrypt_data(struct crypt_rsa_privkey *privkey, const char *encrypted, int enclen, char *data) {
+int crypt_rsa_decrypt_data(struct crypt_rsa_privkey *privkey, const char *encrypted, int enclen, char **data) {
+ const gnutls_datum_t enc_dat = {(void *)encrypted, enclen};
+ gnutls_datum_t out;
+
+ int ret = gnutls_privkey_decrypt_data(privkey->privkey, 0, &enc_dat, &out);
+ if(ret < 0)
+ return ret;
+ *data = out.data;
+ return out.size;
}
-static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
- int size = (pubkey->pubkey->bits / 8) - 12;
+int crypt_rsa_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
+ //int size = (pubkey->pubkey->bits / 8) - 12;
+ //todo!
+ int size = 1024;
return size;
}
-static void crypt_encrypt_free(char *encrypted) {
-
+void crypt_rsa_encrypt_free(char *encrypted) {
+ gnutls_free(encrypted);
}
-static void crypt_decrypt_free(char *data) {
-
+void crypt_rsa_decrypt_free(char *data) {
+ gnutls_free(data);
}
#elif defined(HAVE_OPENSSL_SSL_H)
+*/
+
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
struct crypt_rsa_pubkey {
RSA *rsa;
-}
+};
struct crypt_rsa_privkey {
RSA *rsa;
+};
+
+void crypt_rsa_init() {
+
+}
+
+void crypt_rsa_deinit() {
+
}
-static RSA *createRSA(unsigned char *key, int public) {
+RSA *createRSA(unsigned char *key, int public) {
RSA *rsa= NULL;
BIO *keybio ;
keybio = BIO_new_mem_buf(key, -1);
return rsa;
}
-static struct crypt_rsa_pubkey *crypt_load_pubkey(const char *key) {
+struct crypt_rsa_pubkey *crypt_rsa_load_pubkey(const char *key) {
struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
if(!pubkey)
return NULL;
- RSA *rsa = createRSA((unsigned char) key, 1);
+ RSA *rsa = createRSA((unsigned char *) key, 1);
if(!rsa) {
free(pubkey);
return pubkey;
}
-static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
+void crypt_rsa_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
RSA_free(pubkey->rsa);
free(pubkey);
}
-static struct crypt_rsa_privkey *crypt_load_privkey(const char *key) {
- struct crypt_rsa_pubkey *privkey = calloc(1, sizeof(*pubkey));
+char *crypt_rsa_export_pubkey(struct crypt_rsa_pubkey *pubkey) {
+ BIO *bio = BIO_new(BIO_s_mem());
+ PEM_write_bio_RSA_PUBKEY(bio, pubkey->rsa);
+
+ int keylen = BIO_pending(bio);
+ char *key = calloc(1, keylen+1);
+ BIO_read(bio, key, keylen);
+
+ BIO_free_all(bio);
+ return key;
+}
+
+struct crypt_rsa_privkey *crypt_rsa_load_privkey(const char *key) {
+ struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
if(!privkey)
return NULL;
- RSA *rsa = createRSA((unsigned char) key, 0);
+ RSA *rsa = createRSA((unsigned char *) key, 0);
if(!rsa) {
free(privkey);
return privkey;
}
-static void crypt_unload_pubkey(struct crypt_rsa_privkey *privkey) {
+struct crypt_rsa_privkey *crypt_rsa_generate_privkey(const int keysize) {
+ struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
+ if(!privkey)
+ return NULL;
+
+ BIGNUM *e = BN_new();
+ RSA *rsa = RSA_new();
+
+ BN_set_word(e, 65537);
+ if (!RSA_generate_key_ex(rsa, keysize, e, NULL)) {
+ BN_free(e);
+ RSA_free(rsa);
+ free(privkey);
+ return NULL;
+ }
+
+ privkey->rsa = rsa;
+ return privkey;
+}
+
+char *crypt_rsa_export_privkey(struct crypt_rsa_privkey *privkey, int pubkey) {
+ BIO *bio = BIO_new(BIO_s_mem());
+ if(pubkey)
+ PEM_write_bio_RSA_PUBKEY(bio, privkey->rsa);
+ else
+ PEM_write_bio_RSAPrivateKey(bio, privkey->rsa, NULL, NULL, 0, NULL, NULL);
+
+ int keylen = BIO_pending(bio);
+ char *key = calloc(1, keylen+1);
+ BIO_read(bio, key, keylen);
+
+ BIO_free_all(bio);
+ return key;
+}
+
+void crypt_rsa_unload_privkey(struct crypt_rsa_privkey *privkey) {
RSA_free(privkey->rsa);
free(privkey);
}
-static int crypt_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char **encrypted) {
+struct crypt_rsa_pubkey *crypt_rsa_get_pubkey(struct crypt_rsa_privkey *privkey) {
+ struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
+ if(!pubkey)
+ return NULL;
+
+ RSA *rsa = RSA_new();
+ memcpy(rsa, privkey->rsa, sizeof(*rsa));
+
+ pubkey->rsa = rsa;
+ return pubkey;
+}
+
+int crypt_rsa_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char **encrypted) {
if(!pubkey)
return 0;
- if(datalen > crypt_encrypt_maxlen(pubkey))
+ if(datalen > crypt_rsa_encrypt_maxlen(pubkey))
return 0;
*encrypted = malloc(RSA_size(pubkey->rsa));
if(!*encrypted)
return ret;
}
-static int crypt_decrypt_data(struct crypt_rsa_pubkey *privkey, const char *encrypted, int enclen, char **data) {
+int crypt_rsa_decrypt_data(struct crypt_rsa_privkey *privkey, const char *encrypted, int enclen, char **data) {
if(!privkey)
return 0;
if(enclen > RSA_size(privkey->rsa))
return ret;
}
-static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
+int crypt_rsa_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
return RSA_size(pubkey->rsa) - 12;
}
-static void crypt_encrypt_free(char *encrypted) {
+void crypt_rsa_encrypt_free(char *encrypted) {
free(encrypted);
}
-static void crypt_decrypt_free(char *data) {
+void crypt_rsa_decrypt_free(char *data) {
free(data);
}
-#endif
+//#endif