1 /* crypt_rsa.c - NextIRCd
2 * Copyright (C) 2012-2013 Philipp Kreil (pk910)
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "../config.h"
18 #include "crypt_rsa.h"
26 // GnuTLS Backend not working because of gnutls_pubkey_encrypt_data doesn't exists prior to GnuTLS 3.0
27 // still searching for a replacement...
29 #if defined(HAVE_GNUTLS_GNUTLS_H)
30 #include <gnutls/gnutls.h>
31 #include <gnutls/x509.h>
32 #include <gnutls/abstract.h>
34 struct crypt_rsa_pubkey {
35 unsigned int free_crt : 1;
36 unsigned int free_pubkey : 1;
37 gnutls_x509_crt_t crt;
38 gnutls_pubkey_t pubkey;
41 struct crypt_rsa_privkey {
42 unsigned int free_key : 1;
43 unsigned int free_privkey : 1;
44 gnutls_x509_privkey_t key;
45 gnutls_privkey_t privkey;
48 void crypt_rsa_init() {
52 void crypt_rsa_deinit() {
53 gnutls_global_deinit();
56 struct crypt_rsa_pubkey *crypt_rsa_load_pubkey(const char *key) {
57 struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
59 const gnutls_datum_t key_dat = {(void *)key, strlen(key)};
64 ret = gnutls_x509_crt_init(&pubkey->crt);
66 goto crypt_rsa_load_pubkey_fail;
69 ret = gnutls_x509_crt_import(pubkey->crt, &key_dat, GNUTLS_X509_FMT_PEM);
71 goto crypt_rsa_load_pubkey_fail;
73 ret = gnutls_pubkey_init(&pubkey->pubkey);
75 goto crypt_rsa_load_pubkey_fail;
76 pubkey->free_pubkey = 1;
78 ret = gnutls_pubkey_import_x509(pubkey->pubkey, pubkey->crt, 0);
80 goto crypt_rsa_load_pubkey_fail;
83 crypt_rsa_load_pubkey_fail:
84 crypt_rsa_unload_pubkey(pubkey);
88 void crypt_rsa_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
90 gnutls_x509_crt_deinit(pubkey->crt);
91 if(pubkey->free_pubkey)
92 gnutls_pubkey_deinit(pubkey->pubkey);
96 char *crypt_rsa_export_pubkey(struct crypt_rsa_pubkey *pubkey) {
98 char *buffer = malloc(size);
101 ret = gnutls_pubkey_export(pubkey->pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
102 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
103 buffer = realloc(buffer, size);
104 ret = gnutls_pubkey_export(pubkey->pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
113 struct crypt_rsa_privkey *crypt_rsa_load_privkey(const char *key) {
114 struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
117 const gnutls_datum_t key_dat = {(void *)key, strlen(key)};
119 ret = gnutls_x509_privkey_init(&privkey->key);
121 goto crypt_rsa_load_privkey_fail;
122 privkey->free_key = 1;
124 ret = gnutls_x509_privkey_import(privkey->key, &key_dat, GNUTLS_X509_FMT_PEM);
126 goto crypt_rsa_load_privkey_fail;
128 ret = gnutls_privkey_init(&privkey->privkey);
130 goto crypt_rsa_load_privkey_fail;
131 privkey->free_privkey = 1;
133 ret = gnutls_privkey_import_x509(privkey->privkey, privkey->key, 0);
135 goto crypt_rsa_load_privkey_fail;
138 crypt_rsa_load_privkey_fail:
139 crypt_rsa_unload_privkey(privkey);
143 struct crypt_rsa_privkey *crypt_rsa_generate_privkey(const int keysize) {
144 struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
147 ret = gnutls_x509_privkey_init(&privkey->key);
149 goto crypt_rsa_generate_privkey_fail;
150 privkey->free_key = 1;
152 ret = gnutls_x509_privkey_generate(privkey->key, GNUTLS_PK_RSA, keysize, 0);
154 goto crypt_rsa_generate_privkey_fail;
156 ret = gnutls_privkey_init(&privkey->privkey);
158 goto crypt_rsa_generate_privkey_fail;
159 privkey->free_privkey = 1;
161 ret = gnutls_privkey_import_x509(privkey->privkey, privkey->key, 0);
163 goto crypt_rsa_generate_privkey_fail;
166 crypt_rsa_generate_privkey_fail:
167 crypt_rsa_unload_privkey(privkey);
171 char *crypt_rsa_export_privkey(struct crypt_rsa_privkey *privkey, int pubkey) {
173 char *buffer = malloc(size);
177 gnutls_pubkey_t pkey;
178 ret = gnutls_pubkey_init(&pkey);
183 ret = gnutls_pubkey_import_privkey(pkey, privkey->privkey, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
186 gnutls_pubkey_deinit(pkey);
189 ret = gnutls_pubkey_export(pkey, GNUTLS_X509_FMT_PEM, buffer, &size);
190 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
191 buffer = realloc(buffer, size);
192 ret = gnutls_pubkey_export(pkey, GNUTLS_X509_FMT_PEM, buffer, &size);
194 gnutls_pubkey_deinit(pkey);
196 ret = gnutls_x509_privkey_export(privkey->key, GNUTLS_X509_FMT_PEM, buffer, &size);
197 if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
198 buffer = realloc(buffer, size);
199 ret = gnutls_x509_privkey_export(privkey->key, GNUTLS_X509_FMT_PEM, buffer, &size);
209 void crypt_rsa_unload_privkey(struct crypt_rsa_privkey *privkey) {
210 if(privkey->free_key)
211 gnutls_x509_privkey_deinit(privkey->key);
212 if(privkey->free_privkey)
213 gnutls_privkey_deinit(privkey->privkey);
217 struct crypt_rsa_pubkey *crypt_rsa_get_pubkey(struct crypt_rsa_privkey *privkey) {
218 struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
223 ret = gnutls_pubkey_init(&pubkey->pubkey);
225 goto crypt_rsa_get_pubkey_fail;
226 pubkey->free_pubkey = 1;
228 ret = gnutls_pubkey_import_privkey(pubkey->pubkey, privkey->privkey, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE, 0);
230 goto crypt_rsa_get_pubkey_fail;
233 crypt_rsa_get_pubkey_fail:
234 crypt_rsa_unload_pubkey(pubkey);
238 int crypt_rsa_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char **encrypted) {
239 const gnutls_datum_t data_dat = {(void *)data, datalen};
242 int ret = gnutls_pubkey_encrypt_data(pubkey->pubkey, 0, &data_dat, &out);
246 *encrypted = out.data;
250 int crypt_rsa_decrypt_data(struct crypt_rsa_privkey *privkey, const char *encrypted, int enclen, char **data) {
251 const gnutls_datum_t enc_dat = {(void *)encrypted, enclen};
254 int ret = gnutls_privkey_decrypt_data(privkey->privkey, 0, &enc_dat, &out);
262 int crypt_rsa_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
263 //int size = (pubkey->pubkey->bits / 8) - 12;
269 void crypt_rsa_encrypt_free(char *encrypted) {
270 gnutls_free(encrypted);
273 void crypt_rsa_decrypt_free(char *data) {
277 #elif defined(HAVE_OPENSSL_SSL_H)
280 #include <openssl/pem.h>
281 #include <openssl/ssl.h>
282 #include <openssl/rsa.h>
283 #include <openssl/evp.h>
284 #include <openssl/bio.h>
285 #include <openssl/err.h>
287 struct crypt_rsa_pubkey {
291 struct crypt_rsa_privkey {
295 void crypt_rsa_init() {
299 void crypt_rsa_deinit() {
303 RSA *createRSA(unsigned char *key, int public) {
306 keybio = BIO_new_mem_buf(key, -1);
310 rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
312 rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
317 struct crypt_rsa_pubkey *crypt_rsa_load_pubkey(const char *key) {
318 struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
322 RSA *rsa = createRSA((unsigned char *) key, 1);
333 void crypt_rsa_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
334 RSA_free(pubkey->rsa);
338 char *crypt_rsa_export_pubkey(struct crypt_rsa_pubkey *pubkey) {
339 BIO *bio = BIO_new(BIO_s_mem());
340 PEM_write_bio_RSA_PUBKEY(bio, pubkey->rsa);
342 int keylen = BIO_pending(bio);
343 char *key = calloc(1, keylen+1);
344 BIO_read(bio, key, keylen);
350 struct crypt_rsa_privkey *crypt_rsa_load_privkey(const char *key) {
351 struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
355 RSA *rsa = createRSA((unsigned char *) key, 0);
366 struct crypt_rsa_privkey *crypt_rsa_generate_privkey(const int keysize) {
367 struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
371 BIGNUM *e = BN_new();
372 RSA *rsa = RSA_new();
374 BN_set_word(e, 65537);
375 if (!RSA_generate_key_ex(rsa, keysize, e, NULL)) {
386 char *crypt_rsa_export_privkey(struct crypt_rsa_privkey *privkey, int pubkey) {
387 BIO *bio = BIO_new(BIO_s_mem());
389 PEM_write_bio_RSA_PUBKEY(bio, privkey->rsa);
391 PEM_write_bio_RSAPrivateKey(bio, privkey->rsa, NULL, NULL, 0, NULL, NULL);
393 int keylen = BIO_pending(bio);
394 char *key = calloc(1, keylen+1);
395 BIO_read(bio, key, keylen);
401 void crypt_rsa_unload_privkey(struct crypt_rsa_privkey *privkey) {
402 RSA_free(privkey->rsa);
406 struct crypt_rsa_pubkey *crypt_rsa_get_pubkey(struct crypt_rsa_privkey *privkey) {
407 struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
411 RSA *rsa = RSA_new();
412 memcpy(rsa, privkey->rsa, sizeof(*rsa));
418 int crypt_rsa_encrypt_data(struct crypt_rsa_pubkey *pubkey, const unsigned char *data, int datalen, unsigned char **encrypted) {
421 if(datalen > crypt_rsa_encrypt_maxlen(pubkey))
423 *encrypted = malloc(RSA_size(pubkey->rsa));
426 int ret = RSA_public_encrypt(datalen, data, *encrypted, pubkey->rsa, RSA_PKCS1_PADDING);
432 int crypt_rsa_decrypt_data(struct crypt_rsa_privkey *privkey, const unsigned char *encrypted, int enclen, unsigned char **data) {
435 if(enclen > RSA_size(privkey->rsa))
437 *data = malloc(RSA_size(privkey->rsa));
440 int ret = RSA_private_decrypt(enclen, encrypted, *data, privkey->rsa, RSA_PKCS1_PADDING);
446 int crypt_rsa_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
447 return RSA_size(pubkey->rsa) - 12;
450 void crypt_rsa_encrypt_free(char *encrypted) {
454 void crypt_rsa_decrypt_free(char *data) {