937cc2f99da33e70930f2d1a643ad30069502e0a
[NextIRCd.git] / src / crypt_rsa.c
1 /* crypt_rsa.c - NextIRCd
2  * Copyright (C) 2012-2013  Philipp Kreil (pk910)
3  * 
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.
8  * 
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.
13  * 
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/>. 
16  */
17
18 #include "../config.h"
19 struct crypt_rsa_pubkey;
20 struct crypt_rsa_privkey;
21
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);
26
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);
32
33
34
35
36
37 #if defined(HAVE_GNUTLS_GNUTLS_H)
38 #include <gnutls/gnutls.h>
39 #include <gnutls/x509.h>
40 #include <gnutls/abstract.h>
41
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;
47 }
48
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;
54 }
55
56 static struct crypt_rsa_pubkey *crypt_load_pubkey(const char *key) {
57         struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
58         int ret;
59         const gnutls_datum_t key_dat = {(void *)key, strlen(key)};
60         
61         if(!pubkey)
62                 return NULL;
63         
64         ret = gnutls_x509_crt_init(&pubkey->crt);
65         if(ret < 0)
66                 goto crypt_load_pubkey_fail;
67         pubkey->free_crt = 1;
68         
69         ret = gnutls_x509_crt_import(pubkey->crt, &key_dat, GNUTLS_X509_FMT_PEM);
70         if (ret < 0)
71                 goto crypt_load_pubkey_fail;
72         
73         ret = gnutls_pubkey_init(&pubkey.pubkey);
74         if(ret < 0)
75                 goto crypt_load_pubkey_fail;
76         pubkey->free_pubkey = 1;
77         
78         ret = gnutls_pubkey_import_x509(pubkey->pubkey, pubkey->crt, 0);
79         if(ret < 0)
80                 goto crypt_load_pubkey_fail;
81         
82         return pubkey;
83         crypt_load_pubkey_fail:
84         crypt_unload_pubkey(pubkey);
85         return NULL;
86 }
87
88 static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
89         if(pubkey->free_key)
90                 gnutls_x509_crt_deinit(pubkey->crt);
91         if(pubkey->free_privkey)
92                 gnutls_pubkey_deinit(pubkey->pubkey);
93         free(pubkey);
94 }
95
96 static struct crypt_rsa_privkey *crypt_load_privkey(const char *key) {
97         struct crypt_rsa_privkey *privkey = calloc(1, sizeof(*privkey));
98         int ret;
99         
100         const gnutls_datum_t key_dat = {(void *)key, strlen(key)};
101         privkey.valid = 0;
102         
103         ret = gnutls_x509_privkey_init(&privkey->key);
104         if(ret < 0)
105                 goto crypt_load_privkey_fail;
106         privkey->free_key = 1;
107         
108         ret = gnutls_x509_privkey_import(privkey->key, &key_dat, GNUTLS_X509_FMT_PEM);
109         if (ret < 0)
110                 goto crypt_load_privkey_fail;
111         
112         ret = gnutls_privkey_init(&privkey.privkey);
113         if(ret < 0)
114                 goto crypt_load_privkey_fail;
115         privkey->free_privkey = 1;
116         
117         ret = gnutls_privkey_import_x509(privkey->privkey, privkey->key, 0);
118         if(ret < 0)
119                 goto crypt_load_privkey_fail;
120         
121         return privkey;
122         crypt_load_privkey_fail:
123         crypt_unload_privkey(privkey);
124         return NULL;
125 }
126
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);
132         free(privkey);
133 }
134
135
136 static void crypt_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char *encrypted) {
137         
138 }
139
140 static void crypt_decrypt_data(struct crypt_rsa_privkey *privkey, const char *encrypted, int enclen, char *data) {
141         
142 }
143
144 static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
145         int size = (pubkey->pubkey->bits / 8) - 12;
146         return size;
147 }
148
149 static void crypt_encrypt_free(char *encrypted) {
150         
151 }
152
153 static void crypt_decrypt_free(char *data) {
154         
155 }
156
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>
164
165 struct crypt_rsa_pubkey {
166         RSA *rsa;
167 }
168
169 struct crypt_rsa_privkey {
170         RSA *rsa;
171 }
172
173 static RSA *createRSA(unsigned char *key, int public) {
174     RSA *rsa= NULL;
175     BIO *keybio ;
176     keybio = BIO_new_mem_buf(key, -1);
177     if(!keybio)
178         return NULL;
179     if(public)
180         rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);
181     else
182         rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL);
183     BIO_free(keybio);
184     return rsa;
185 }
186
187 static struct crypt_rsa_pubkey *crypt_load_pubkey(const char *key) {
188         struct crypt_rsa_pubkey *pubkey = calloc(1, sizeof(*pubkey));
189         if(!pubkey)
190                 return NULL;
191         
192         RSA *rsa = createRSA((unsigned char) key, 1);
193         
194         if(!rsa) {
195                 free(pubkey);
196                 return NULL;
197         }
198         
199         pubkey->rsa = rsa;
200         return pubkey;
201 }
202
203 static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey) {
204         RSA_free(pubkey->rsa);
205         free(pubkey);
206 }
207
208 static struct crypt_rsa_privkey *crypt_load_privkey(const char *key) {
209         struct crypt_rsa_pubkey *privkey = calloc(1, sizeof(*pubkey));
210         if(!privkey)
211                 return NULL;
212         
213         RSA *rsa = createRSA((unsigned char) key, 0);
214         
215         if(!rsa) {
216                 free(privkey);
217                 return NULL;
218         }
219         
220         privkey->rsa = rsa;
221         return privkey;
222 }
223
224 static void crypt_unload_pubkey(struct crypt_rsa_privkey *privkey) {
225         RSA_free(privkey->rsa);
226         free(privkey);
227 }
228
229 static int crypt_encrypt_data(struct crypt_rsa_pubkey *pubkey, const char *data, int datalen, char **encrypted) {
230         if(!pubkey)
231                 return 0;
232         if(datalen > crypt_encrypt_maxlen(pubkey))
233                 return 0;
234         *encrypted = malloc(RSA_size(pubkey->rsa));
235         if(!*encrypted)
236                 return 0;
237         int ret = RSA_public_encrypt(datalen, data, *encrypted, pubkey->rsa, RSA_PKCS1_PADDING);
238         if(ret <= 0)
239                 free(*encrypted);
240         return ret;
241 }
242
243 static int crypt_decrypt_data(struct crypt_rsa_pubkey *privkey, const char *encrypted, int enclen, char **data) {
244         if(!privkey)
245                 return 0;
246         if(enclen > RSA_size(privkey->rsa))
247                 return 0;
248         *data = malloc(RSA_size(privkey->rsa));
249         if(!*data)
250                 return 0;
251         int ret = RSA_private_decrypt(enclen, encrypted, *data, privkey->rsa, RSA_PKCS1_PADDING);
252         if(ret <= 0)
253                 free(*data);
254         return ret;
255 }
256
257 static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) {
258         return RSA_size(pubkey->rsa) - 12;
259 }
260
261 static void crypt_encrypt_free(char *encrypted) {
262         free(encrypted);
263 }
264
265 static void crypt_decrypt_free(char *data) {
266         free(data);
267 }
268
269 #endif