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/>.
18 #include "../config.h"
19 struct crypt_rsa_pubkey;
20 struct crypt_rsa_privkey;
22 static struct crypt_rsa_pubkey *crypt_load_pubkey(const char *key);
23 static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey);
24 static struct crypt_rsa_privkey *crypt_load_privkey(const char *key);
25 static void crypt_unload_privkey(struct crypt_rsa_privkey *privkey);
27 static void crypt_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char *encrypted);
28 static void crypt_decrypt_data(struct crypt_rsa_privkey *privkey, const char *encrypted, int enclen, char *data);
29 static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey);
30 static void crypt_encrypt_free(char *encrypted);
31 static void crypt_decrypt_free(char *data);
37 #if defined(HAVE_GNUTLS_GNUTLS_H)
38 #include <gnutls/gnutls.h>
39 #include <gnutls/x509.h>
40 #include <gnutls/abstract.h>
42 struct crypt_rsa_pubkey {
43 unsigned int free_crt : 1;
44 unsigned int free_pubkey : 1;
45 gnutls_x509_crt_t crt;
46 gnutls_pubkey_t pubkey;
49 struct crypt_rsa_privkey {
50 unsigned int free_key : 1;
51 unsigned int free_privkey : 1;
52 gnutls_x509_privkey_t key;
53 gnutls_privkey_t privkey;
56 static struct crypt_rsa_pubkey *crypt_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_load_pubkey_fail;
69 ret = gnutls_x509_crt_import(pubkey->crt, &key_dat, GNUTLS_X509_FMT_PEM);
71 goto crypt_load_pubkey_fail;
73 ret = gnutls_pubkey_init(&pubkey.pubkey);
75 goto crypt_load_pubkey_fail;
76 pubkey->free_pubkey = 1;
78 ret = gnutls_pubkey_import_x509(pubkey->pubkey, pubkey->crt, 0);
80 goto crypt_load_pubkey_fail;
83 crypt_load_pubkey_fail:
84 crypt_unload_pubkey(pubkey);
88 static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
90 gnutls_x509_crt_deinit(pubkey->crt);
91 if(pubkey->free_privkey)
92 gnutls_pubkey_deinit(pubkey->pubkey);
96 static struct crypt_rsa_privkey *crypt_load_privkey(const char *key) {
97 struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
100 const gnutls_datum_t key_dat = {(void *)key, strlen(key)};
103 ret = gnutls_x509_privkey_init(&privkey->key);
105 goto crypt_load_privkey_fail;
106 privkey->free_key = 1;
108 ret = gnutls_x509_privkey_import(privkey->key, &key_dat, GNUTLS_X509_FMT_PEM);
110 goto crypt_load_privkey_fail;
112 ret = gnutls_privkey_init(&privkey.privkey);
114 goto crypt_load_privkey_fail;
115 privkey->free_privkey = 1;
117 ret = gnutls_privkey_import_x509(privkey->privkey, privkey->key, 0);
119 goto crypt_load_privkey_fail;
122 crypt_load_privkey_fail:
123 crypt_unload_privkey(privkey);
127 static void crypt_unload_privkey(struct crypt_rsa_privkey *privkey) {
128 if(privkey->free_key)
129 gnutls_x509_privkey_deinit(privkey->key);
130 if(privkey->free_privkey)
131 gnutls_privkey_deinit(privkey->privkey);
136 static void crypt_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char *encrypted) {
140 static void crypt_decrypt_data(struct crypt_rsa_privkey *privkey, const char *encrypted, int enclen, char *data) {
144 static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
145 int size = (pubkey->pubkey->bits / 8) - 12;
149 static void crypt_encrypt_free(char *encrypted) {
153 static void crypt_decrypt_free(char *data) {
157 #elif defined(HAVE_OPENSSL_SSL_H)
158 #include <openssl/pem.h>
159 #include <openssl/ssl.h>
160 #include <openssl/rsa.h>
161 #include <openssl/evp.h>
162 #include <openssl/bio.h>
163 #include <openssl/err.h>
165 struct crypt_rsa_pubkey {
169 struct crypt_rsa_privkey {
173 static RSA *createRSA(unsigned char *key, int public) {
176 keybio = BIO_new_mem_buf(key, -1);
180 rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
182 rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
187 static struct crypt_rsa_pubkey *crypt_load_pubkey(const char *key) {
188 struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
192 RSA *rsa = createRSA((unsigned char) key, 1);
203 static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
204 RSA_free(pubkey->rsa);
208 static struct crypt_rsa_privkey *crypt_load_privkey(const char *key) {
209 struct crypt_rsa_pubkey *privkey = calloc(1, sizeof(*pubkey));
213 RSA *rsa = createRSA((unsigned char) key, 0);
224 static void crypt_unload_pubkey(struct crypt_rsa_privkey *privkey) {
225 RSA_free(privkey->rsa);
229 static int crypt_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char **encrypted) {
232 if(datalen > crypt_encrypt_maxlen(pubkey))
234 *encrypted = malloc(RSA_size(pubkey->rsa));
237 int ret = RSA_public_encrypt(datalen, data, *encrypted, pubkey->rsa, RSA_PKCS1_PADDING);
243 static int crypt_decrypt_data(struct crypt_rsa_pubkey *privkey, const char *encrypted, int enclen, char **data) {
246 if(enclen > RSA_size(privkey->rsa))
248 *data = malloc(RSA_size(privkey->rsa));
251 int ret = RSA_private_decrypt(enclen, encrypted, *data, privkey->rsa, RSA_PKCS1_PADDING);
257 static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
258 return RSA_size(pubkey->rsa) - 12;
261 static void crypt_encrypt_free(char *encrypted) {
265 static void crypt_decrypt_free(char *data) {