From: pk910 Date: Wed, 16 Jul 2014 13:28:07 +0000 (+0200) Subject: rsa crypt backend X-Git-Url: http://git.pk910.de/?p=NextIRCd.git;a=commitdiff_plain;h=466f97ae1a374de40219ab78c2d5ad622a90d126 rsa crypt backend --- diff --git a/src/crypt_rsa.c b/src/crypt_rsa.c new file mode 100644 index 0000000..937cc2f --- /dev/null +++ b/src/crypt_rsa.c @@ -0,0 +1,269 @@ +/* crypt_rsa.c - NextIRCd + * Copyright (C) 2012-2013 Philipp Kreil (pk910) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#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); + + + + + +#if defined(HAVE_GNUTLS_GNUTLS_H) +#include +#include +#include + +struct crypt_rsa_pubkey { + unsigned int free_crt : 1; + 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; +} + +static struct crypt_rsa_pubkey *crypt_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)}; + + if(!pubkey) + return NULL; + + ret = gnutls_x509_crt_init(&pubkey->crt); + if(ret < 0) + goto crypt_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; + + ret = gnutls_pubkey_init(&pubkey.pubkey); + if(ret < 0) + goto crypt_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; + + return pubkey; + crypt_load_pubkey_fail: + crypt_unload_pubkey(pubkey); + return NULL; +} + +static void crypt_unload_pubkey(struct crypt_rsa_pubkey *pubkey) { + if(pubkey->free_key) + gnutls_x509_crt_deinit(pubkey->crt); + if(pubkey->free_privkey) + gnutls_pubkey_deinit(pubkey->pubkey); + free(pubkey); +} + +static struct crypt_rsa_privkey *crypt_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; + 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; + + ret = gnutls_privkey_init(&privkey.privkey); + if(ret < 0) + goto crypt_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; + + return privkey; + crypt_load_privkey_fail: + crypt_unload_privkey(privkey); + return NULL; +} + +static void crypt_unload_privkey(struct crypt_rsa_privkey *privkey) { + if(privkey->free_key) + gnutls_x509_privkey_deinit(privkey->key); + if(privkey->free_privkey) + gnutls_privkey_deinit(privkey->privkey); + free(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) { + int size = (pubkey->pubkey->bits / 8) - 12; + return size; +} + +static void crypt_encrypt_free(char *encrypted) { + +} + +static void crypt_decrypt_free(char *data) { + +} + +#elif defined(HAVE_OPENSSL_SSL_H) +#include +#include +#include +#include +#include +#include + +struct crypt_rsa_pubkey { + RSA *rsa; +} + +struct crypt_rsa_privkey { + RSA *rsa; +} + +static RSA *createRSA(unsigned char *key, int public) { + RSA *rsa= NULL; + BIO *keybio ; + keybio = BIO_new_mem_buf(key, -1); + if(!keybio) + return NULL; + if(public) + rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL); + else + rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa,NULL, NULL); + BIO_free(keybio); + return rsa; +} + +static struct crypt_rsa_pubkey *crypt_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); + + if(!rsa) { + free(pubkey); + return NULL; + } + + pubkey->rsa = rsa; + return pubkey; +} + +static void crypt_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)); + if(!privkey) + return NULL; + + RSA *rsa = createRSA((unsigned char) key, 0); + + if(!rsa) { + free(privkey); + return NULL; + } + + privkey->rsa = rsa; + return privkey; +} + +static void crypt_unload_pubkey(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) { + if(!pubkey) + return 0; + if(datalen > crypt_encrypt_maxlen(pubkey)) + return 0; + *encrypted = malloc(RSA_size(pubkey->rsa)); + if(!*encrypted) + return 0; + int ret = RSA_public_encrypt(datalen, data, *encrypted, pubkey->rsa, RSA_PKCS1_PADDING); + if(ret <= 0) + free(*encrypted); + return ret; +} + +static int crypt_decrypt_data(struct crypt_rsa_pubkey *privkey, const char *encrypted, int enclen, char **data) { + if(!privkey) + return 0; + if(enclen > RSA_size(privkey->rsa)) + return 0; + *data = malloc(RSA_size(privkey->rsa)); + if(!*data) + return 0; + int ret = RSA_private_decrypt(enclen, encrypted, *data, privkey->rsa, RSA_PKCS1_PADDING); + if(ret <= 0) + free(*data); + return ret; +} + +static int crypt_encrypt_maxlen(struct crypt_rsa_pubkey *pubkey) { + return RSA_size(pubkey->rsa) - 12; +} + +static void crypt_encrypt_free(char *encrypted) { + free(encrypted); +} + +static void crypt_decrypt_free(char *data) { + free(data); +} + +#endif diff --git a/src/ircd_client.c b/src/ircd_client.c index 57bfb3f..9fe8181 100644 --- a/src/ircd_client.c +++ b/src/ircd_client.c @@ -56,5 +56,11 @@ void client_disconnected(struct Connection *conn) { } void client_recv(struct Connection *conn, char *line) { - + if(conn->server) { + // Server protocol + } else { + + + + } }